# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 4b51d081378d6783cce48255ffb7655931f26d63
# Parent c4b68afe97d36b87c460d1bef3eac135f66d9fc9
# Parent 2245974798126074c31521b0903cc7e67e8aec23
merge with xen-unstable.hg
---
tools/libxc/xc_aout9.h | 30
tools/libxc/xc_load_aout9.c | 178 -
Makefile | 5
docs/Makefile | 3
linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c | 2
linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c | 134 +
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c | 43
linux-2.6-xen-sparse/drivers/xen/blkback/common.h | 1
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c | 22
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c | 73
linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c | 100
linux-2.6-xen-sparse/drivers/xen/netback/interface.c | 8
linux-2.6-xen-sparse/drivers/xen/netback/loopback.c | 5
linux-2.6-xen-sparse/drivers/xen/netback/netback.c | 65
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c | 6
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h | 11
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c | 10
linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c | 91
linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c | 37
linux-2.6-xen-sparse/include/linux/skbuff.h | 42
linux-2.6-xen-sparse/net/core/dev.c | 238 +-
linux-2.6-xen-sparse/net/core/skbuff.c | 144 +
patches/linux-2.6.16.13/net-gso.patch | 1974 +++++++++++++++++++
patches/linux-2.6.16.13/xenoprof-generic.patch | 81
tools/Makefile | 3
tools/examples/Makefile | 2
tools/examples/vtpm | 6
tools/examples/vtpm-common.sh | 36
tools/examples/vtpm-impl | 136 +
tools/libxc/Makefile | 1
tools/libxc/xc_ia64_stubs.c | 11
tools/libxc/xc_linux_build.c | 8
tools/libxc/xg_private.h | 7
tools/python/xen/lowlevel/xc/xc.c | 29
tools/python/xen/xend/XendNode.py | 4
tools/python/xen/xend/balloon.py | 71
tools/python/xen/xm/main.py | 37
tools/vtpm/Rules.mk | 3
tools/vtpm/tpm_emulator-0.3-x86_64.patch | 238 +-
tools/vtpm/tpm_emulator.patch | 1120 ++++++++++
tools/vtpm/vtpm.patch | 236 +-
tools/vtpm_manager/Rules.mk | 3
tools/vtpm_manager/manager/dmictl.c | 57
tools/vtpm_manager/manager/securestorage.c | 29
tools/vtpm_manager/manager/vtpm_manager.c | 11
tools/vtpm_manager/manager/vtpm_manager.h | 10
tools/vtpm_manager/manager/vtpm_manager_handler.c | 75
tools/vtpm_manager/manager/vtpmd.c | 40
tools/vtpm_manager/manager/vtpmpriv.h | 13
tools/vtpm_manager/manager/vtsp.c | 11
tools/vtpm_manager/manager/vtsp.h | 2
tools/vtpm_manager/tcs/tcs.c | 43
tools/vtpm_manager/tcs/tcs.h | 5
tools/vtpm_manager/tcs/transmit.c | 42
tools/vtpm_manager/util/tcg.h | 5
tools/xenstat/xentop/xentop.1 | 9
tools/xenstat/xentop/xentop.c | 84
tools/xm-test/tests/info/02_info_compiledata_pos.py | 3
xen/Makefile | 12
xen/arch/x86/dom0_ops.c | 1
xen/arch/x86/hvm/svm/svm.c | 40
xen/arch/x86/hvm/vioapic.c | 41
xen/arch/x86/hvm/vlapic.c | 38
xen/arch/x86/hvm/vmx/vmx.c | 150 -
xen/arch/x86/microcode.c | 138 -
xen/arch/x86/oprofile/nmi_int.c | 2
xen/arch/x86/oprofile/xenoprof.c | 358 ++-
xen/arch/x86/smp.c | 5
xen/arch/x86/x86_emulate.c | 9
xen/common/kernel.c | 5
xen/common/page_alloc.c | 12
xen/include/asm-x86/bitops.h | 30
xen/include/asm-x86/hvm/vcpu.h | 3
xen/include/asm-x86/hvm/vlapic.h | 62
xen/include/public/dom0_ops.h | 1
xen/include/public/hvm/ioreq.h | 5
xen/include/public/io/netif.h | 33
xen/include/public/version.h | 5
xen/include/public/xenoprof.h | 9
xen/include/xen/mm.h | 1
xen/include/xen/xenoprof.h | 1
81 files changed, 5191 insertions(+), 1463 deletions(-)
diff -r c4b68afe97d3 -r 4b51d081378d Makefile
--- a/Makefile Wed Jun 28 07:51:52 2006 -0600
+++ b/Makefile Wed Jun 28 07:52:21 2006 -0600
@@ -123,7 +123,10 @@ clean::
# clean, but blow away kernel build tree plus tarballs
.PHONY: distclean
-distclean: clean
+distclean:
+ $(MAKE) -C xen distclean
+ $(MAKE) -C tools distclean
+ $(MAKE) -C docs distclean
rm -rf dist patches/tmp
for i in $(ALLKERNELS) ; do $(MAKE) $$i-delete ; done
for i in $(ALLSPARSETREES) ; do $(MAKE) $$i-mrproper ; done
diff -r c4b68afe97d3 -r 4b51d081378d docs/Makefile
--- a/docs/Makefile Wed Jun 28 07:51:52 2006 -0600
+++ b/docs/Makefile Wed Jun 28 07:52:21 2006 -0600
@@ -80,6 +80,9 @@ clean:
rm -rf man5
rm -rf man1
+.PHONY: distclean
+distclean: clean
+
.PHONY: install
install: all
rm -rf $(DESTDIR)$(pkgdocdir)
diff -r c4b68afe97d3 -r 4b51d081378d
linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c Wed Jun 28 07:51:52
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c Wed Jun 28 07:52:21
2006 -0600
@@ -264,7 +264,7 @@ static void contiguous_bitmap_clear(
}
/* Protected by balloon_lock. */
-#define MAX_CONTIG_ORDER 7
+#define MAX_CONTIG_ORDER 9 /* 2MB */
static unsigned long discontig_frames[1<<MAX_CONTIG_ORDER];
/* Ensure multi-page extents are contiguous in machine memory. */
diff -r c4b68afe97d3 -r 4b51d081378d
linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c
--- a/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c Wed Jun 28
07:51:52 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c Wed Jun 28
07:52:21 2006 -0600
@@ -28,6 +28,7 @@
#include <xen/interface/xen.h>
#include <xen/interface/xenoprof.h>
+#include <../../../drivers/oprofile/cpu_buffer.h>
static int xenoprof_start(void);
static void xenoprof_stop(void);
@@ -50,6 +51,11 @@ int ovf_irq[NR_CPUS];
/* cpu model type string - copied from Xen memory space on XENOPROF_init
command */
char cpu_type[XENOPROF_CPU_TYPE_SIZE];
+/* Passive sample buffers shared with Xen */
+xenoprof_buf_t *p_xenoprof_buf[MAX_OPROF_DOMAINS][MAX_VIRT_CPUS];
+/* Passive shared buffer area */
+char *p_shared_buffer[MAX_OPROF_DOMAINS];
+
#ifdef CONFIG_PM
static int xenoprof_suspend(struct sys_device * dev, pm_message_t state)
@@ -102,16 +108,14 @@ static void __exit exit_driverfs(void)
#endif /* CONFIG_PM */
unsigned long long oprofile_samples = 0;
-
-static irqreturn_t
-xenoprof_ovf_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+unsigned long long p_oprofile_samples = 0;
+
+unsigned int pdomains;
+struct xenoprof_passive passive_domains[MAX_OPROF_DOMAINS];
+
+static void xenoprof_add_pc(xenoprof_buf_t *buf, int is_passive)
{
int head, tail, size;
- struct xenoprof_buf * buf;
- int cpu;
-
- cpu = smp_processor_id();
- buf = xenoprof_buf[cpu];
head = buf->event_head;
tail = buf->event_tail;
@@ -122,7 +126,10 @@ xenoprof_ovf_interrupt(int irq, void * d
oprofile_add_pc(buf->event_log[tail].eip,
buf->event_log[tail].mode,
buf->event_log[tail].event);
- oprofile_samples++;
+ if (!is_passive)
+ oprofile_samples++;
+ else
+ p_oprofile_samples++;
tail++;
}
tail = 0;
@@ -131,11 +138,47 @@ xenoprof_ovf_interrupt(int irq, void * d
oprofile_add_pc(buf->event_log[tail].eip,
buf->event_log[tail].mode,
buf->event_log[tail].event);
- oprofile_samples++;
+ if (!is_passive)
+ oprofile_samples++;
+ else
+ p_oprofile_samples++;
tail++;
}
buf->event_tail = tail;
+}
+
+static void xenoprof_handle_passive(void)
+{
+ int i, j;
+
+ for (i = 0; i < pdomains; i++)
+ for (j = 0; j < passive_domains[i].nbuf; j++) {
+ xenoprof_buf_t *buf = p_xenoprof_buf[i][j];
+ if (buf->event_head == buf->event_tail)
+ continue;
+ oprofile_add_pc(IGNORED_PC, CPU_MODE_PASSIVE_START,
passive_domains[i].domain_id);
+ xenoprof_add_pc(buf, 1);
+ oprofile_add_pc(IGNORED_PC, CPU_MODE_PASSIVE_STOP,
passive_domains[i].domain_id);
+ }
+}
+
+static irqreturn_t
+xenoprof_ovf_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+{
+ struct xenoprof_buf * buf;
+ int cpu;
+ static unsigned long flag;
+
+ cpu = smp_processor_id();
+ buf = xenoprof_buf[cpu];
+
+ xenoprof_add_pc(buf, 0);
+
+ if (is_primary && !test_and_set_bit(0, &flag)) {
+ xenoprof_handle_passive();
+ clear_bit(0, &flag);
+ }
return IRQ_HANDLED;
}
@@ -312,6 +355,63 @@ out:
return ret;
}
+static int xenoprof_set_passive(int * p_domains,
+ unsigned int pdoms)
+{
+ int ret;
+ int i, j;
+ int vm_size;
+ int npages;
+ struct xenoprof_buf *buf;
+ pgprot_t prot = __pgprot(_KERNPG_TABLE);
+
+ if (!is_primary)
+ return 0;
+
+ if (pdoms > MAX_OPROF_DOMAINS)
+ return -E2BIG;
+
+ ret = HYPERVISOR_xenoprof_op(XENOPROF_reset_passive_list, NULL);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < pdoms; i++) {
+ passive_domains[i].domain_id = p_domains[i];
+ passive_domains[i].max_samples = 2048;
+ ret = HYPERVISOR_xenoprof_op(XENOPROF_set_passive,
&passive_domains[i]);
+ if (ret)
+ return ret;
+
+ npages = (passive_domains[i].bufsize * passive_domains[i].nbuf
- 1) / PAGE_SIZE + 1;
+ vm_size = npages * PAGE_SIZE;
+
+ p_shared_buffer[i] = (char
*)vm_map_xen_pages(passive_domains[i].buf_maddr,
+ vm_size, prot);
+ if (!p_shared_buffer[i]) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ for (j = 0; j < passive_domains[i].nbuf; j++) {
+ buf = (struct xenoprof_buf *)
+ &p_shared_buffer[i][j *
passive_domains[i].bufsize];
+ BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS);
+ p_xenoprof_buf[i][buf->vcpu_id] = buf;
+ }
+
+ }
+
+ pdomains = pdoms;
+ return 0;
+
+out:
+ for (j = 0; j < i; j++) {
+ vunmap(p_shared_buffer[j]);
+ p_shared_buffer[j] = NULL;
+ }
+
+ return ret;
+}
struct op_counter_config counter_config[OP_MAX_COUNTER];
@@ -346,6 +446,7 @@ struct oprofile_operations xenoprof_ops
struct oprofile_operations xenoprof_ops = {
.create_files = xenoprof_create_files,
.set_active = xenoprof_set_active,
+ .set_passive = xenoprof_set_passive,
.setup = xenoprof_setup,
.shutdown = xenoprof_shutdown,
.start = xenoprof_start,
@@ -420,6 +521,8 @@ int __init oprofile_arch_init(struct opr
void __exit oprofile_arch_exit(void)
{
+ int i;
+
if (using_xenoprof)
exit_driverfs();
@@ -427,6 +530,13 @@ void __exit oprofile_arch_exit(void)
vunmap(shared_buffer);
shared_buffer = NULL;
}
- if (is_primary)
+ if (is_primary) {
+ for (i = 0; i < pdomains; i++)
+ if (p_shared_buffer[i]) {
+ vunmap(p_shared_buffer[i]);
+ p_shared_buffer[i] = NULL;
+ }
HYPERVISOR_xenoprof_op(XENOPROF_shutdown, NULL);
-}
+ }
+
+}
diff -r c4b68afe97d3 -r 4b51d081378d
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Wed Jun 28
07:51:52 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Wed Jun 28
07:52:21 2006 -0600
@@ -172,7 +172,7 @@ static unsigned long current_target(void
static int increase_reservation(unsigned long nr_pages)
{
- unsigned long *frame_list, pfn, i, flags;
+ unsigned long *frame_list, frame, pfn, i, flags;
struct page *page;
long rc;
struct xen_memory_reservation reservation = {
@@ -185,8 +185,11 @@ static int increase_reservation(unsigned
nr_pages = PAGE_SIZE / sizeof(unsigned long);
frame_list = (unsigned long *)__get_free_page(GFP_KERNEL);
- if (frame_list == NULL)
- return -ENOMEM;
+ if (frame_list == NULL) {
+ frame_list = &frame;
+ if (nr_pages > 1)
+ nr_pages = 1;
+ }
balloon_lock(flags);
@@ -202,14 +205,17 @@ static int increase_reservation(unsigned
rc = HYPERVISOR_memory_op(
XENMEM_populate_physmap, &reservation);
if (rc < nr_pages) {
- int ret;
- /* We hit the Xen hard limit: reprobe. */
- set_xen_guest_handle(reservation.extent_start, frame_list);
- reservation.nr_extents = rc;
- ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
- &reservation);
- BUG_ON(ret != rc);
- hard_limit = current_pages + rc - driver_pages;
+ if (rc > 0) {
+ int ret;
+
+ /* We hit the Xen hard limit: reprobe. */
+ reservation.nr_extents = rc;
+ ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
+ &reservation);
+ BUG_ON(ret != rc);
+ }
+ if (rc >= 0)
+ hard_limit = current_pages + rc - driver_pages;
goto out;
}
@@ -247,14 +253,15 @@ static int increase_reservation(unsigned
out:
balloon_unlock(flags);
- free_page((unsigned long)frame_list);
+ if (frame_list != &frame)
+ free_page((unsigned long)frame_list);
return 0;
}
static int decrease_reservation(unsigned long nr_pages)
{
- unsigned long *frame_list, pfn, i, flags;
+ unsigned long *frame_list, frame, pfn, i, flags;
struct page *page;
void *v;
int need_sleep = 0;
@@ -269,8 +276,11 @@ static int decrease_reservation(unsigned
nr_pages = PAGE_SIZE / sizeof(unsigned long);
frame_list = (unsigned long *)__get_free_page(GFP_KERNEL);
- if (frame_list == NULL)
- return -ENOMEM;
+ if (frame_list == NULL) {
+ frame_list = &frame;
+ if (nr_pages > 1)
+ nr_pages = 1;
+ }
for (i = 0; i < nr_pages; i++) {
if ((page = alloc_page(GFP_HIGHUSER)) == NULL) {
@@ -321,7 +331,8 @@ static int decrease_reservation(unsigned
balloon_unlock(flags);
- free_page((unsigned long)frame_list);
+ if (frame_list != &frame)
+ free_page((unsigned long)frame_list);
return need_sleep;
}
diff -r c4b68afe97d3 -r 4b51d081378d
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Wed Jun 28 07:51:52
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Wed Jun 28 07:52:21
2006 -0600
@@ -95,6 +95,7 @@ typedef struct blkif_st {
} blkif_t;
blkif_t *blkif_alloc(domid_t domid);
+void blkif_disconnect(blkif_t *blkif);
void blkif_free(blkif_t *blkif);
int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn);
diff -r c4b68afe97d3 -r 4b51d081378d
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Wed Jun 28
07:51:52 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Wed Jun 28
07:52:21 2006 -0600
@@ -32,6 +32,7 @@
#include "common.h"
#include <xen/evtchn.h>
+#include <linux/kthread.h>
static kmem_cache_t *blkif_cachep;
@@ -139,22 +140,33 @@ int blkif_map(blkif_t *blkif, unsigned l
return 0;
}
-void blkif_free(blkif_t *blkif)
+void blkif_disconnect(blkif_t *blkif)
{
+ if (blkif->xenblkd) {
+ kthread_stop(blkif->xenblkd);
+ blkif->xenblkd = NULL;
+ }
+
atomic_dec(&blkif->refcnt);
wait_event(blkif->waiting_to_free, atomic_read(&blkif->refcnt) == 0);
+ atomic_inc(&blkif->refcnt);
- /* Already disconnected? */
- if (blkif->irq)
+ if (blkif->irq) {
unbind_from_irqhandler(blkif->irq, blkif);
-
- vbd_free(&blkif->vbd);
+ blkif->irq = 0;
+ }
if (blkif->blk_ring.sring) {
unmap_frontend_page(blkif);
free_vm_area(blkif->blk_ring_area);
+ blkif->blk_ring.sring = NULL;
}
+}
+void blkif_free(blkif_t *blkif)
+{
+ if (!atomic_dec_and_test(&blkif->refcnt))
+ BUG();
kmem_cache_free(blkif_cachep, blkif);
}
diff -r c4b68afe97d3 -r 4b51d081378d
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Wed Jun 28 07:51:52
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Wed Jun 28 07:52:21
2006 -0600
@@ -42,7 +42,6 @@ static int connect_ring(struct backend_i
static int connect_ring(struct backend_info *);
static void backend_changed(struct xenbus_watch *, const char **,
unsigned int);
-
static void update_blkif_status(blkif_t *blkif)
{
@@ -73,6 +72,70 @@ static void update_blkif_status(blkif_t
}
+/****************************************************************
+ * sysfs interface for VBD I/O requests
+ */
+
+#ifdef CONFIG_SYSFS
+
+#define VBD_SHOW(name, format, args...)
\
+ static ssize_t show_##name(struct device *_dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+ { \
+ struct xenbus_device *dev = to_xenbus_device(_dev); \
+ struct backend_info *be = dev->dev.driver_data; \
+ \
+ return sprintf(buf, format, ##args); \
+ } \
+ DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
+
+VBD_SHOW(oo_req, "%d\n", be->blkif->st_oo_req);
+VBD_SHOW(rd_req, "%d\n", be->blkif->st_rd_req);
+VBD_SHOW(wr_req, "%d\n", be->blkif->st_wr_req);
+
+static struct attribute *vbdstat_attrs[] = {
+ &dev_attr_oo_req.attr,
+ &dev_attr_rd_req.attr,
+ &dev_attr_wr_req.attr,
+ NULL
+};
+
+static struct attribute_group vbdstat_group = {
+ .name = "statistics",
+ .attrs = vbdstat_attrs,
+};
+
+int xenvbd_sysfs_addif(struct xenbus_device *dev)
+{
+ int error = 0;
+
+ error = sysfs_create_group(&dev->dev.kobj,
+ &vbdstat_group);
+ if (error)
+ goto fail;
+
+ return 0;
+
+fail:
+ sysfs_remove_group(&dev->dev.kobj,
+ &vbdstat_group);
+ return error;
+}
+
+void xenvbd_sysfs_delif(struct xenbus_device *dev)
+{
+ sysfs_remove_group(&dev->dev.kobj,
+ &vbdstat_group);
+}
+
+#else
+
+#define xenvbd_sysfs_addif(dev) (0)
+#define xenvbd_sysfs_delif(dev) ((void)0)
+
+#endif /* CONFIG_SYSFS */
+
static ssize_t show_physical_device(struct device *_dev,
struct device_attribute *attr, char *buf)
{
@@ -105,15 +168,17 @@ static int blkback_remove(struct xenbus_
kfree(be->backend_watch.node);
be->backend_watch.node = NULL;
}
+
if (be->blkif) {
- if (be->blkif->xenblkd)
- kthread_stop(be->blkif->xenblkd);
+ blkif_disconnect(be->blkif);
+ vbd_free(&be->blkif->vbd);
blkif_free(be->blkif);
be->blkif = NULL;
}
device_remove_file(&dev->dev, &dev_attr_physical_device);
device_remove_file(&dev->dev, &dev_attr_mode);
+ xenvbd_sysfs_delif(dev);
kfree(be);
dev->dev.driver_data = NULL;
@@ -236,6 +301,7 @@ static void backend_changed(struct xenbu
device_create_file(&dev->dev, &dev_attr_physical_device);
device_create_file(&dev->dev, &dev_attr_mode);
+ xenvbd_sysfs_addif(dev);
/* We're potentially connected now */
update_blkif_status(be->blkif);
@@ -273,6 +339,7 @@ static void frontend_changed(struct xenb
break;
case XenbusStateClosing:
+ blkif_disconnect(be->blkif);
xenbus_switch_state(dev, XenbusStateClosing);
break;
diff -r c4b68afe97d3 -r 4b51d081378d
linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c Wed Jun 28 07:51:52
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c Wed Jun 28 07:52:21
2006 -0600
@@ -58,15 +58,17 @@ HYPERVISOR_ATTR_RO(minor);
static ssize_t extra_show(struct hyp_sysfs_attr *attr, char *buffer)
{
- int ret;
- char *extra = kmalloc(XEN_EXTRAVERSION_LEN, GFP_KERNEL);
+ int ret = -ENOMEM;
+ char *extra;
+
+ extra = kmalloc(XEN_EXTRAVERSION_LEN, GFP_KERNEL);
if (extra) {
ret = HYPERVISOR_xen_version(XENVER_extraversion, extra);
if (!ret)
- return sprintf(buffer, "%s\n", extra);
+ ret = sprintf(buffer, "%s\n", extra);
kfree(extra);
- } else
- ret = -ENOMEM;
+ }
+
return ret;
}
@@ -86,7 +88,8 @@ static struct attribute_group version_gr
static int __init xen_sysfs_version_init(void)
{
- return sysfs_create_group(&hypervisor_subsys.kset.kobj, &version_group);
+ return sysfs_create_group(&hypervisor_subsys.kset.kobj,
+ &version_group);
}
static void xen_sysfs_version_destroy(void)
@@ -98,16 +101,16 @@ static void xen_sysfs_version_destroy(vo
static ssize_t compiler_show(struct hyp_sysfs_attr *attr, char *buffer)
{
- int ret;
- struct xen_compile_info *info =
- kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
+ int ret = -ENOMEM;
+ struct xen_compile_info *info;
+
+ info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
if (info) {
ret = HYPERVISOR_xen_version(XENVER_compile_info, info);
if (!ret)
ret = sprintf(buffer, "%s\n", info->compiler);
kfree(info);
- } else
- ret = -ENOMEM;
+ }
return ret;
}
@@ -116,7 +119,7 @@ HYPERVISOR_ATTR_RO(compiler);
static ssize_t compiled_by_show(struct hyp_sysfs_attr *attr, char *buffer)
{
- int ret;
+ int ret = -ENOMEM;
struct xen_compile_info *info;
info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
@@ -125,8 +128,8 @@ static ssize_t compiled_by_show(struct h
if (!ret)
ret = sprintf(buffer, "%s\n", info->compile_by);
kfree(info);
- } else
- ret = -ENOMEM;
+ }
+
return ret;
}
@@ -134,7 +137,7 @@ HYPERVISOR_ATTR_RO(compiled_by);
static ssize_t compile_date_show(struct hyp_sysfs_attr *attr, char *buffer)
{
- int ret;
+ int ret = -ENOMEM;
struct xen_compile_info *info;
info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
@@ -143,8 +146,8 @@ static ssize_t compile_date_show(struct
if (!ret)
ret = sprintf(buffer, "%s\n", info->compile_date);
kfree(info);
- } else
- ret = -ENOMEM;
+ }
+
return ret;
}
@@ -178,15 +181,17 @@ static void xen_compilation_destroy(void
static ssize_t capabilities_show(struct hyp_sysfs_attr *attr, char *buffer)
{
- int ret;
- char *caps = kmalloc(XEN_CAPABILITIES_INFO_LEN, GFP_KERNEL);
+ int ret = -ENOMEM;
+ char *caps;
+
+ caps = kmalloc(XEN_CAPABILITIES_INFO_LEN, GFP_KERNEL);
if (caps) {
ret = HYPERVISOR_xen_version(XENVER_capabilities, caps);
if (!ret)
ret = sprintf(buffer, "%s\n", caps);
kfree(caps);
- } else
- ret = -ENOMEM;
+ }
+
return ret;
}
@@ -194,15 +199,17 @@ HYPERVISOR_ATTR_RO(capabilities);
static ssize_t changeset_show(struct hyp_sysfs_attr *attr, char *buffer)
{
- int ret;
- char *cset = kmalloc(XEN_CHANGESET_INFO_LEN, GFP_KERNEL);
+ int ret = -ENOMEM;
+ char *cset;
+
+ cset = kmalloc(XEN_CHANGESET_INFO_LEN, GFP_KERNEL);
if (cset) {
ret = HYPERVISOR_xen_version(XENVER_changeset, cset);
if (!ret)
ret = sprintf(buffer, "%s\n", cset);
kfree(cset);
- } else
- ret = -ENOMEM;
+ }
+
return ret;
}
@@ -210,36 +217,51 @@ HYPERVISOR_ATTR_RO(changeset);
static ssize_t virtual_start_show(struct hyp_sysfs_attr *attr, char *buffer)
{
- int ret;
- struct xen_platform_parameters *parms =
- kmalloc(sizeof(struct xen_platform_parameters), GFP_KERNEL);
+ int ret = -ENOMEM;
+ struct xen_platform_parameters *parms;
+
+ parms = kmalloc(sizeof(struct xen_platform_parameters), GFP_KERNEL);
if (parms) {
- ret = HYPERVISOR_xen_version(XENVER_platform_parameters, parms);
+ ret = HYPERVISOR_xen_version(XENVER_platform_parameters,
+ parms);
if (!ret)
ret = sprintf(buffer, "%lx\n", parms->virt_start);
kfree(parms);
- } else
- ret = -ENOMEM;
+ }
+
return ret;
}
HYPERVISOR_ATTR_RO(virtual_start);
+
+static ssize_t pagesize_show(struct hyp_sysfs_attr *attr, char *buffer)
+{
+ int ret;
+
+ ret = HYPERVISOR_xen_version(XENVER_pagesize, NULL);
+ if (ret > 0)
+ ret = sprintf(buffer, "%x\n", ret);
+
+ return ret;
+}
+
+HYPERVISOR_ATTR_RO(pagesize);
/* eventually there will be several more features to export */
static ssize_t xen_feature_show(int index, char *buffer)
{
- int ret;
-
- struct xen_feature_info *info =
- kmalloc(sizeof(struct xen_feature_info), GFP_KERNEL);
+ int ret = -ENOMEM;
+ struct xen_feature_info *info;
+
+ info = kmalloc(sizeof(struct xen_feature_info), GFP_KERNEL);
if (info) {
info->submap_idx = index;
ret = HYPERVISOR_xen_version(XENVER_get_features, info);
if (!ret)
ret = sprintf(buffer, "%d\n", info->submap);
kfree(info);
- } else
- ret = -ENOMEM;
+ }
+
return ret;
}
@@ -254,6 +276,7 @@ static struct attribute *xen_properties_
&capabilities_attr.attr,
&changeset_attr.attr,
&virtual_start_attr.attr,
+ &pagesize_attr.attr,
&writable_pt_attr.attr,
NULL
};
@@ -271,7 +294,8 @@ static int __init xen_properties_init(vo
static void xen_properties_destroy(void)
{
- sysfs_remove_group(&hypervisor_subsys.kset.kobj, &xen_properties_group);
+ sysfs_remove_group(&hypervisor_subsys.kset.kobj,
+ &xen_properties_group);
}
static int __init hyper_sysfs_init(void)
diff -r c4b68afe97d3 -r 4b51d081378d
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Wed Jun 28
07:51:52 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Wed Jun 28
07:52:21 2006 -0600
@@ -37,9 +37,9 @@ static void __netif_up(netif_t *netif)
static void __netif_up(netif_t *netif)
{
struct net_device *dev = netif->dev;
- spin_lock_bh(&dev->xmit_lock);
+ netif_tx_lock_bh(dev);
netif->active = 1;
- spin_unlock_bh(&dev->xmit_lock);
+ netif_tx_unlock_bh(dev);
enable_irq(netif->irq);
netif_schedule_work(netif);
}
@@ -48,9 +48,9 @@ static void __netif_down(netif_t *netif)
{
struct net_device *dev = netif->dev;
disable_irq(netif->irq);
- spin_lock_bh(&dev->xmit_lock);
+ netif_tx_lock_bh(dev);
netif->active = 0;
- spin_unlock_bh(&dev->xmit_lock);
+ netif_tx_unlock_bh(dev);
netif_deschedule_work(netif);
}
diff -r c4b68afe97d3 -r 4b51d081378d
linux-2.6-xen-sparse/drivers/xen/netback/loopback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Wed Jun 28
07:51:52 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Wed Jun 28
07:52:21 2006 -0600
@@ -125,6 +125,10 @@ static struct ethtool_ops network_ethtoo
{
.get_tx_csum = ethtool_op_get_tx_csum,
.set_tx_csum = ethtool_op_set_tx_csum,
+ .get_sg = ethtool_op_get_sg,
+ .set_sg = ethtool_op_set_sg,
+ .get_tso = ethtool_op_get_tso,
+ .set_tso = ethtool_op_set_tso,
};
/*
@@ -152,6 +156,7 @@ static void loopback_construct(struct ne
dev->features = (NETIF_F_HIGHDMA |
NETIF_F_LLTX |
+ NETIF_F_TSO |
NETIF_F_SG |
NETIF_F_IP_CSUM);
diff -r c4b68afe97d3 -r 4b51d081378d
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Wed Jun 28
07:51:52 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Wed Jun 28
07:52:21 2006 -0600
@@ -43,7 +43,7 @@ static void netif_idx_release(u16 pendin
static void netif_idx_release(u16 pending_idx);
static void netif_page_release(struct page *page);
static void make_tx_response(netif_t *netif,
- u16 id,
+ netif_tx_request_t *txp,
s8 st);
static int make_rx_response(netif_t *netif,
u16 id,
@@ -481,7 +481,7 @@ inline static void net_tx_action_dealloc
netif = pending_tx_info[pending_idx].netif;
- make_tx_response(netif, pending_tx_info[pending_idx].req.id,
+ make_tx_response(netif, &pending_tx_info[pending_idx].req,
NETIF_RSP_OKAY);
pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
@@ -490,14 +490,16 @@ inline static void net_tx_action_dealloc
}
}
-static void netbk_tx_err(netif_t *netif, RING_IDX end)
+static void netbk_tx_err(netif_t *netif, netif_tx_request_t *txp, RING_IDX end)
{
RING_IDX cons = netif->tx.req_cons;
do {
- netif_tx_request_t *txp = RING_GET_REQUEST(&netif->tx, cons);
- make_tx_response(netif, txp->id, NETIF_RSP_ERROR);
- } while (++cons < end);
+ make_tx_response(netif, txp, NETIF_RSP_ERROR);
+ if (++cons >= end)
+ break;
+ txp = RING_GET_REQUEST(&netif->tx, cons);
+ } while (1);
netif->tx.req_cons = cons;
netif_schedule_work(netif);
netif_put(netif);
@@ -508,7 +510,7 @@ static int netbk_count_requests(netif_t
{
netif_tx_request_t *first = txp;
RING_IDX cons = netif->tx.req_cons;
- int frags = 1;
+ int frags = 0;
while (txp->flags & NETTXF_more_data) {
if (frags >= work_to_do) {
@@ -543,7 +545,7 @@ static gnttab_map_grant_ref_t *netbk_get
skb_frag_t *frags = shinfo->frags;
netif_tx_request_t *txp;
unsigned long pending_idx = *((u16 *)skb->data);
- RING_IDX cons = netif->tx.req_cons + 1;
+ RING_IDX cons = netif->tx.req_cons;
int i, start;
/* Skip first skb fragment if it is on same page as header fragment. */
@@ -581,7 +583,7 @@ static int netbk_tx_check_mop(struct sk_
err = mop->status;
if (unlikely(err)) {
txp = &pending_tx_info[pending_idx].req;
- make_tx_response(netif, txp->id, NETIF_RSP_ERROR);
+ make_tx_response(netif, txp, NETIF_RSP_ERROR);
pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
netif_put(netif);
} else {
@@ -614,7 +616,7 @@ static int netbk_tx_check_mop(struct sk_
/* Error on this fragment: respond to client with an error. */
txp = &pending_tx_info[pending_idx].req;
- make_tx_response(netif, txp->id, NETIF_RSP_ERROR);
+ make_tx_response(netif, txp, NETIF_RSP_ERROR);
pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
netif_put(netif);
@@ -668,6 +670,7 @@ static void net_tx_action(unsigned long
struct sk_buff *skb;
netif_t *netif;
netif_tx_request_t txreq;
+ struct netif_tx_extra txtra;
u16 pending_idx;
RING_IDX i;
gnttab_map_grant_ref_t *mop;
@@ -726,22 +729,37 @@ static void net_tx_action(unsigned long
}
netif->remaining_credit -= txreq.size;
+ work_to_do--;
+ netif->tx.req_cons = ++i;
+
+ if (txreq.flags & NETTXF_extra_info) {
+ if (work_to_do-- <= 0) {
+ DPRINTK("Missing extra info\n");
+ netbk_tx_err(netif, &txreq, i);
+ continue;
+ }
+
+ memcpy(&txtra, RING_GET_REQUEST(&netif->tx, i),
+ sizeof(txtra));
+ netif->tx.req_cons = ++i;
+ }
+
ret = netbk_count_requests(netif, &txreq, work_to_do);
if (unlikely(ret < 0)) {
- netbk_tx_err(netif, i - ret);
+ netbk_tx_err(netif, &txreq, i - ret);
continue;
}
i += ret;
if (unlikely(ret > MAX_SKB_FRAGS + 1)) {
DPRINTK("Too many frags\n");
- netbk_tx_err(netif, i);
+ netbk_tx_err(netif, &txreq, i);
continue;
}
if (unlikely(txreq.size < ETH_HLEN)) {
DPRINTK("Bad packet size: %d\n", txreq.size);
- netbk_tx_err(netif, i);
+ netbk_tx_err(netif, &txreq, i);
continue;
}
@@ -750,25 +768,31 @@ static void net_tx_action(unsigned long
DPRINTK("txreq.offset: %x, size: %u, end: %lu\n",
txreq.offset, txreq.size,
(txreq.offset &~PAGE_MASK) + txreq.size);
- netbk_tx_err(netif, i);
+ netbk_tx_err(netif, &txreq, i);
continue;
}
pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
data_len = (txreq.size > PKT_PROT_LEN &&
- ret < MAX_SKB_FRAGS + 1) ?
+ ret < MAX_SKB_FRAGS) ?
PKT_PROT_LEN : txreq.size;
skb = alloc_skb(data_len+16, GFP_ATOMIC);
if (unlikely(skb == NULL)) {
DPRINTK("Can't allocate a skb in start_xmit.\n");
- netbk_tx_err(netif, i);
+ netbk_tx_err(netif, &txreq, i);
break;
}
/* Packets passed to netif_rx() must have some headroom. */
skb_reserve(skb, 16);
+
+ if (txreq.flags & NETTXF_gso) {
+ skb_shinfo(skb)->gso_size = txtra.u.gso.size;
+ skb_shinfo(skb)->gso_segs = txtra.u.gso.segs;
+ skb_shinfo(skb)->gso_type = txtra.u.gso.type;
+ }
gnttab_set_map_op(mop, MMAP_VADDR(pending_idx),
GNTMAP_host_map | GNTMAP_readonly,
@@ -782,7 +806,7 @@ static void net_tx_action(unsigned long
__skb_put(skb, data_len);
- skb_shinfo(skb)->nr_frags = ret - 1;
+ skb_shinfo(skb)->nr_frags = ret;
if (data_len < txreq.size) {
skb_shinfo(skb)->nr_frags++;
skb_shinfo(skb)->frags[0].page =
@@ -898,7 +922,7 @@ irqreturn_t netif_be_int(int irq, void *
}
static void make_tx_response(netif_t *netif,
- u16 id,
+ netif_tx_request_t *txp,
s8 st)
{
RING_IDX i = netif->tx.rsp_prod_pvt;
@@ -906,8 +930,11 @@ static void make_tx_response(netif_t *ne
int notify;
resp = RING_GET_RESPONSE(&netif->tx, i);
- resp->id = id;
+ resp->id = txp->id;
resp->status = st;
+
+ if (txp->flags & NETTXF_extra_info)
+ RING_GET_RESPONSE(&netif->tx, ++i)->status = NETIF_RSP_NULL;
netif->tx.rsp_prod_pvt = ++i;
RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netif->tx, notify);
diff -r c4b68afe97d3 -r 4b51d081378d
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Wed Jun 28 07:51:52
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Wed Jun 28 07:52:21
2006 -0600
@@ -101,6 +101,12 @@ static int netback_probe(struct xenbus_d
goto abort_transaction;
}
+ err = xenbus_printf(xbt, dev->nodename, "feature-tso", "%d", 1);
+ if (err) {
+ message = "writing feature-tso";
+ goto abort_transaction;
+ }
+
err = xenbus_transaction_end(xbt, 0);
} while (err == -EAGAIN);
diff -r c4b68afe97d3 -r 4b51d081378d
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Wed Jun 28 07:51:52
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Wed Jun 28 07:52:21
2006 -0600
@@ -21,6 +21,8 @@
pr_debug("(file=%s, line=%d) " _f, \
__FILE__ , __LINE__ , ## _a )
+struct backend_info;
+
typedef struct tpmif_st {
struct list_head tpmif_list;
/* Unique identifier for this interface. */
@@ -43,7 +45,7 @@ typedef struct tpmif_st {
struct list_head list; /* scheduling list */
atomic_t refcnt;
- long int tpm_instance;
+ struct backend_info *bi;
unsigned long mmap_vstart;
grant_handle_t shmem_handle;
@@ -54,7 +56,7 @@ typedef struct tpmif_st {
} tpmif_t;
void tpmif_disconnect_complete(tpmif_t * tpmif);
-tpmif_t *tpmif_find(domid_t domid, long int instance);
+tpmif_t *tpmif_find(domid_t domid, struct backend_info *bi);
void tpmif_interface_init(void);
void tpmif_interface_exit(void);
void tpmif_schedule_work(tpmif_t * tpmif);
@@ -63,10 +65,11 @@ void tpmif_xenbus_exit(void);
void tpmif_xenbus_exit(void);
int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn);
irqreturn_t tpmif_be_int(int irq, void *dev_id, struct pt_regs *regs);
-int tpmif_vtpm_open(tpmif_t *tpmif, domid_t domain, u32 instance);
-int tpmif_vtpm_close(u32 instance);
+
+long int tpmback_get_instance(struct backend_info *bi);
int vtpm_release_packets(tpmif_t * tpmif, int send_msgs);
+
#define tpmif_get(_b) (atomic_inc(&(_b)->refcnt))
#define tpmif_put(_b) \
diff -r c4b68afe97d3 -r 4b51d081378d
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Wed Jun 28
07:51:52 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Wed Jun 28
07:52:21 2006 -0600
@@ -20,7 +20,7 @@ int num_frontends = 0;
LIST_HEAD(tpmif_list);
-static tpmif_t *alloc_tpmif(domid_t domid, long int instance)
+static tpmif_t *alloc_tpmif(domid_t domid, struct backend_info *bi)
{
tpmif_t *tpmif;
@@ -31,7 +31,7 @@ static tpmif_t *alloc_tpmif(domid_t domi
memset(tpmif, 0, sizeof (*tpmif));
tpmif->domid = domid;
tpmif->status = DISCONNECTED;
- tpmif->tpm_instance = instance;
+ tpmif->bi = bi;
snprintf(tpmif->devname, sizeof(tpmif->devname), "tpmif%d", domid);
atomic_set(&tpmif->refcnt, 1);
@@ -54,12 +54,12 @@ static void free_tpmif(tpmif_t * tpmif)
kmem_cache_free(tpmif_cachep, tpmif);
}
-tpmif_t *tpmif_find(domid_t domid, long int instance)
+tpmif_t *tpmif_find(domid_t domid, struct backend_info *bi)
{
tpmif_t *tpmif;
list_for_each_entry(tpmif, &tpmif_list, tpmif_list) {
- if (tpmif->tpm_instance == instance) {
+ if (tpmif->bi == bi) {
if (tpmif->domid == domid) {
tpmif_get(tpmif);
return tpmif;
@@ -69,7 +69,7 @@ tpmif_t *tpmif_find(domid_t domid, long
}
}
- return alloc_tpmif(domid, instance);
+ return alloc_tpmif(domid, bi);
}
static int map_frontend_page(tpmif_t *tpmif, unsigned long shared_page)
diff -r c4b68afe97d3 -r 4b51d081378d
linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c Wed Jun 28
07:51:52 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c Wed Jun 28
07:52:21 2006 -0600
@@ -161,7 +161,7 @@ static struct packet *packet_alloc(tpmif
if (NULL != pak) {
if (tpmif) {
pak->tpmif = tpmif;
- pak->tpm_instance = tpmif->tpm_instance;
+ pak->tpm_instance = tpmback_get_instance(tpmif->bi);
tpmif_get(tpmif);
}
pak->data_len = size;
@@ -685,95 +685,6 @@ static struct miscdevice vtpms_miscdevic
};
/***************************************************************
- Virtual TPM functions and data stuctures
-***************************************************************/
-
-static u8 create_cmd[] = {
- 1, 193, /* 0: TPM_TAG_RQU_COMMAMD */
- 0, 0, 0, 19, /* 2: length */
- 0, 0, 0, 0x1, /* 6: VTPM_ORD_OPEN */
- 0, /* 10: VTPM type */
- 0, 0, 0, 0, /* 11: domain id */
- 0, 0, 0, 0 /* 15: instance id */
-};
-
-int tpmif_vtpm_open(tpmif_t * tpmif, domid_t domid, u32 instance)
-{
- int rc = 0;
- struct packet *pak;
-
- pak = packet_alloc(tpmif,
- sizeof (create_cmd),
- create_cmd[1],
- PACKET_FLAG_DISCARD_RESPONSE |
- PACKET_FLAG_CHECK_RESPONSESTATUS);
- if (pak) {
- u8 buf[sizeof (create_cmd)];
- u32 domid_no = htonl((u32) domid);
- u32 instance_no = htonl(instance);
-
- memcpy(buf, create_cmd, sizeof (create_cmd));
-
- memcpy(&buf[11], &domid_no, sizeof (u32));
- memcpy(&buf[15], &instance_no, sizeof (u32));
-
- /* copy the buffer into the packet */
- rc = packet_set(pak, buf, sizeof (buf));
-
- if (rc == 0) {
- pak->tpm_instance = 0;
- rc = vtpm_queue_packet(pak);
- }
- if (rc < 0) {
- /* could not be queued or built */
- packet_free(pak);
- }
- } else {
- rc = -ENOMEM;
- }
- return rc;
-}
-
-static u8 destroy_cmd[] = {
- 1, 193, /* 0: TPM_TAG_RQU_COMMAMD */
- 0, 0, 0, 14, /* 2: length */
- 0, 0, 0, 0x2, /* 6: VTPM_ORD_CLOSE */
- 0, 0, 0, 0 /* 10: instance id */
-};
-
-int tpmif_vtpm_close(u32 instid)
-{
- int rc = 0;
- struct packet *pak;
-
- pak = packet_alloc(NULL,
- sizeof (destroy_cmd),
- destroy_cmd[1], PACKET_FLAG_DISCARD_RESPONSE);
- if (pak) {
- u8 buf[sizeof (destroy_cmd)];
- u32 instid_no = htonl(instid);
-
- memcpy(buf, destroy_cmd, sizeof (destroy_cmd));
- memcpy(&buf[10], &instid_no, sizeof (u32));
-
- /* copy the buffer into the packet */
- rc = packet_set(pak, buf, sizeof (buf));
-
- if (rc == 0) {
- pak->tpm_instance = 0;
- rc = vtpm_queue_packet(pak);
- }
- if (rc < 0) {
- /* could not be queued or built */
- packet_free(pak);
- }
- } else {
- rc = -ENOMEM;
- }
- return rc;
-}
-
-/***************************************************************
Utility functions
***************************************************************/
diff -r c4b68afe97d3 -r 4b51d081378d
linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Wed Jun 28 07:51:52
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Wed Jun 28 07:52:21
2006 -0600
@@ -45,6 +45,14 @@ static void frontend_changed(struct xenb
static void frontend_changed(struct xenbus_device *dev,
enum xenbus_state frontend_state);
+long int tpmback_get_instance(struct backend_info *bi)
+{
+ long int res = -1;
+ if (bi && bi->is_instance_set)
+ res = bi->instance;
+ return res;
+}
+
static int tpmback_remove(struct xenbus_device *dev)
{
struct backend_info *be = dev->dev.driver_data;
@@ -57,6 +65,7 @@ static int tpmback_remove(struct xenbus_
be->backend_watch.node = NULL;
}
if (be->tpmif) {
+ be->tpmif->bi = NULL;
vtpm_release_packets(be->tpmif, 0);
tpmif_put(be->tpmif);
be->tpmif = NULL;
@@ -150,15 +159,10 @@ static void frontend_changed(struct xenb
break;
case XenbusStateClosing:
- be->tpmif->tpm_instance = -1;
+ be->instance = -1;
break;
case XenbusStateClosed:
- /*
- * Notify the vTPM manager about the front-end
- * having left.
- */
- tpmif_vtpm_close(be->instance);
device_unregister(&be->dev->dev);
tpmback_remove(dev);
break;
@@ -177,28 +181,10 @@ static void frontend_changed(struct xenb
static void maybe_connect(struct backend_info *be)
{
- int err;
-
if (be->tpmif == NULL || be->tpmif->status == CONNECTED)
return;
connect(be);
-
- /*
- * Notify the vTPM manager about a new front-end.
- */
- err = tpmif_vtpm_open(be->tpmif,
- be->frontend_id,
- be->instance);
- if (err) {
- xenbus_dev_error(be->dev, err,
- "queueing vtpm open packet");
- /*
- * Should close down this device and notify FE
- * about closure.
- */
- return;
- }
}
@@ -256,8 +242,7 @@ static int connect_ring(struct backend_i
}
if (!be->tpmif) {
- be->tpmif = tpmif_find(dev->otherend_id,
- be->instance);
+ be->tpmif = tpmif_find(dev->otherend_id, be);
if (IS_ERR(be->tpmif)) {
err = PTR_ERR(be->tpmif);
be->tpmif = NULL;
diff -r c4b68afe97d3 -r 4b51d081378d linux-2.6-xen-sparse/include/linux/skbuff.h
--- a/linux-2.6-xen-sparse/include/linux/skbuff.h Wed Jun 28 07:51:52
2006 -0600
+++ b/linux-2.6-xen-sparse/include/linux/skbuff.h Wed Jun 28 07:52:21
2006 -0600
@@ -134,9 +134,10 @@ struct skb_shared_info {
struct skb_shared_info {
atomic_t dataref;
unsigned short nr_frags;
- unsigned short tso_size;
- unsigned short tso_segs;
- unsigned short ufo_size;
+ unsigned short gso_size;
+ /* Warning: this field is not always filled in (UFO)! */
+ unsigned short gso_segs;
+ unsigned short gso_type;
unsigned int ip6_frag_id;
struct sk_buff *frag_list;
skb_frag_t frags[MAX_SKB_FRAGS];
@@ -166,6 +167,14 @@ enum {
SKB_FCLONE_UNAVAILABLE,
SKB_FCLONE_ORIG,
SKB_FCLONE_CLONE,
+};
+
+enum {
+ SKB_GSO_TCPV4 = 1 << 0,
+ SKB_GSO_UDPV4 = 1 << 1,
+
+ /* This indicates the skb is from an untrusted source. */
+ SKB_GSO_DODGY = 1 << 2,
};
/**
@@ -1157,18 +1166,34 @@ static inline int skb_can_coalesce(struc
return 0;
}
+static inline int __skb_linearize(struct sk_buff *skb)
+{
+ return __pskb_pull_tail(skb, skb->data_len) ? 0 : -ENOMEM;
+}
+
/**
* skb_linearize - convert paged skb to linear one
* @skb: buffer to linarize
- * @gfp: allocation mode
*
* If there is no free memory -ENOMEM is returned, otherwise zero
* is returned and the old skb data released.
*/
-extern int __skb_linearize(struct sk_buff *skb, gfp_t gfp);
-static inline int skb_linearize(struct sk_buff *skb, gfp_t gfp)
-{
- return __skb_linearize(skb, gfp);
+static inline int skb_linearize(struct sk_buff *skb)
+{
+ return skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0;
+}
+
+/**
+ * skb_linearize_cow - make sure skb is linear and writable
+ * @skb: buffer to process
+ *
+ * If there is no free memory -ENOMEM is returned, otherwise zero
+ * is returned and the old skb data released.
+ */
+static inline int skb_linearize_cow(struct sk_buff *skb)
+{
+ return skb_is_nonlinear(skb) || skb_cloned(skb) ?
+ __skb_linearize(skb) : 0;
}
/**
@@ -1263,6 +1288,7 @@ extern void skb_split(struct sk_b
struct sk_buff *skb1, const u32 len);
extern void skb_release_data(struct sk_buff *skb);
+extern struct sk_buff *skb_segment(struct sk_buff *skb, int features);
static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
int len, void *buffer)
diff -r c4b68afe97d3 -r 4b51d081378d linux-2.6-xen-sparse/net/core/dev.c
--- a/linux-2.6-xen-sparse/net/core/dev.c Wed Jun 28 07:51:52 2006 -0600
+++ b/linux-2.6-xen-sparse/net/core/dev.c Wed Jun 28 07:52:21 2006 -0600
@@ -115,6 +115,7 @@
#include <net/iw_handler.h>
#endif /* CONFIG_NET_RADIO */
#include <asm/current.h>
+#include <linux/err.h>
#ifdef CONFIG_XEN
#include <net/ip.h>
@@ -1038,7 +1039,7 @@ static inline void net_timestamp(struct
* taps currently in use.
*/
-void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
+static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
{
struct packet_type *ptype;
@@ -1112,6 +1113,45 @@ out:
return ret;
}
+/**
+ * skb_gso_segment - Perform segmentation on skb.
+ * @skb: buffer to segment
+ * @features: features for the output path (see dev->features)
+ *
+ * This function segments the given skb and returns a list of segments.
+ *
+ * It may return NULL if the skb requires no segmentation. This is
+ * only possible when GSO is used for verifying header integrity.
+ */
+struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
+{
+ struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
+ struct packet_type *ptype;
+ int type = skb->protocol;
+
+ BUG_ON(skb_shinfo(skb)->frag_list);
+ BUG_ON(skb->ip_summed != CHECKSUM_HW);
+
+ skb->mac.raw = skb->data;
+ skb->mac_len = skb->nh.raw - skb->data;
+ __skb_pull(skb, skb->mac_len);
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) {
+ if (ptype->type == type && !ptype->dev && ptype->gso_segment) {
+ segs = ptype->gso_segment(skb, features);
+ break;
+ }
+ }
+ rcu_read_unlock();
+
+ __skb_push(skb, skb->data - skb->mac.raw);
+
+ return segs;
+}
+
+EXPORT_SYMBOL(skb_gso_segment);
+
/* Take action when hardware reception checksum errors are detected. */
#ifdef CONFIG_BUG
void netdev_rx_csum_fault(struct net_device *dev)
@@ -1148,75 +1188,108 @@ static inline int illegal_highdma(struct
#define illegal_highdma(dev, skb) (0)
#endif
-/* Keep head the same: replace data */
-int __skb_linearize(struct sk_buff *skb, gfp_t gfp_mask)
-{
- unsigned int size;
- u8 *data;
- long offset;
- struct skb_shared_info *ninfo;
- int headerlen = skb->data - skb->head;
- int expand = (skb->tail + skb->data_len) - skb->end;
-
- if (skb_shared(skb))
- BUG();
-
- if (expand <= 0)
- expand = 0;
-
- size = skb->end - skb->head + expand;
- size = SKB_DATA_ALIGN(size);
- data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
- if (!data)
- return -ENOMEM;
-
- /* Copy entire thing */
- if (skb_copy_bits(skb, -headerlen, data, headerlen + skb->len))
- BUG();
-
- /* Set up shinfo */
- ninfo = (struct skb_shared_info*)(data + size);
- atomic_set(&ninfo->dataref, 1);
- ninfo->tso_size = skb_shinfo(skb)->tso_size;
- ninfo->tso_segs = skb_shinfo(skb)->tso_segs;
- ninfo->nr_frags = 0;
- ninfo->frag_list = NULL;
-
- /* Offset between the two in bytes */
- offset = data - skb->head;
-
- /* Free old data. */
- skb_release_data(skb);
-
- skb->head = data;
- skb->end = data + size;
-
- /* Set up new pointers */
- skb->h.raw += offset;
- skb->nh.raw += offset;
- skb->mac.raw += offset;
- skb->tail += offset;
- skb->data += offset;
-
- /* We are no longer a clone, even if we were. */
- skb->cloned = 0;
-
- skb->tail += skb->data_len;
- skb->data_len = 0;
+struct dev_gso_cb {
+ void (*destructor)(struct sk_buff *skb);
+};
+
+#define DEV_GSO_CB(skb) ((struct dev_gso_cb *)(skb)->cb)
+
+static void dev_gso_skb_destructor(struct sk_buff *skb)
+{
+ struct dev_gso_cb *cb;
+
+ do {
+ struct sk_buff *nskb = skb->next;
+
+ skb->next = nskb->next;
+ nskb->next = NULL;
+ kfree_skb(nskb);
+ } while (skb->next);
+
+ cb = DEV_GSO_CB(skb);
+ if (cb->destructor)
+ cb->destructor(skb);
+}
+
+/**
+ * dev_gso_segment - Perform emulated hardware segmentation on skb.
+ * @skb: buffer to segment
+ *
+ * This function segments the given skb and stores the list of segments
+ * in skb->next.
+ */
+static int dev_gso_segment(struct sk_buff *skb)
+{
+ struct net_device *dev = skb->dev;
+ struct sk_buff *segs;
+ int features = dev->features & ~(illegal_highdma(dev, skb) ?
+ NETIF_F_SG : 0);
+
+ segs = skb_gso_segment(skb, features);
+
+ /* Verifying header integrity only. */
+ if (!segs)
+ return 0;
+
+ if (unlikely(IS_ERR(segs)))
+ return PTR_ERR(segs);
+
+ skb->next = segs;
+ DEV_GSO_CB(skb)->destructor = skb->destructor;
+ skb->destructor = dev_gso_skb_destructor;
+
+ return 0;
+}
+
+int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ if (likely(!skb->next)) {
+ if (netdev_nit)
+ dev_queue_xmit_nit(skb, dev);
+
+ if (netif_needs_gso(dev, skb)) {
+ if (unlikely(dev_gso_segment(skb)))
+ goto out_kfree_skb;
+ if (skb->next)
+ goto gso;
+ }
+
+ return dev->hard_start_xmit(skb, dev);
+ }
+
+gso:
+ do {
+ struct sk_buff *nskb = skb->next;
+ int rc;
+
+ skb->next = nskb->next;
+ nskb->next = NULL;
+ rc = dev->hard_start_xmit(nskb, dev);
+ if (unlikely(rc)) {
+ nskb->next = skb->next;
+ skb->next = nskb;
+ return rc;
+ }
+ if (unlikely(netif_queue_stopped(dev) && skb->next))
+ return NETDEV_TX_BUSY;
+ } while (skb->next);
+
+ skb->destructor = DEV_GSO_CB(skb)->destructor;
+
+out_kfree_skb:
+ kfree_skb(skb);
return 0;
}
#define HARD_TX_LOCK(dev, cpu) { \
if ((dev->features & NETIF_F_LLTX) == 0) { \
- spin_lock(&dev->xmit_lock); \
- dev->xmit_lock_owner = cpu; \
+ netif_tx_lock(dev); \
} \
}
#define HARD_TX_UNLOCK(dev) { \
if ((dev->features & NETIF_F_LLTX) == 0) { \
- dev->xmit_lock_owner = -1; \
- spin_unlock(&dev->xmit_lock); \
+ netif_tx_unlock(dev); \
} \
}
@@ -1289,9 +1362,19 @@ int dev_queue_xmit(struct sk_buff *skb)
struct Qdisc *q;
int rc = -ENOMEM;
+ /* If a checksum-deferred packet is forwarded to a device that needs a
+ * checksum, correct the pointers and force checksumming.
+ */
+ if (skb_checksum_setup(skb))
+ goto out_kfree_skb;
+
+ /* GSO will handle the following emulations directly. */
+ if (netif_needs_gso(dev, skb))
+ goto gso;
+
if (skb_shinfo(skb)->frag_list &&
!(dev->features & NETIF_F_FRAGLIST) &&
- __skb_linearize(skb, GFP_ATOMIC))
+ __skb_linearize(skb))
goto out_kfree_skb;
/* Fragmented skb is linearized if device does not support SG,
@@ -1300,31 +1383,26 @@ int dev_queue_xmit(struct sk_buff *skb)
*/
if (skb_shinfo(skb)->nr_frags &&
(!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
- __skb_linearize(skb, GFP_ATOMIC))
+ __skb_linearize(skb))
goto out_kfree_skb;
- /* If a checksum-deferred packet is forwarded to a device that needs a
- * checksum, correct the pointers and force checksumming.
- */
- if(skb_checksum_setup(skb))
- goto out_kfree_skb;
-
/* If packet is not checksummed and device does not support
* checksumming for this protocol, complete checksumming here.
*/
if (skb->ip_summed == CHECKSUM_HW &&
- (!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) &&
+ (!(dev->features & NETIF_F_GEN_CSUM) &&
(!(dev->features & NETIF_F_IP_CSUM) ||
skb->protocol != htons(ETH_P_IP))))
if (skb_checksum_help(skb, 0))
goto out_kfree_skb;
+gso:
spin_lock_prefetch(&dev->queue_lock);
/* Disable soft irqs for various locks below. Also
* stops preemption for RCU.
*/
- local_bh_disable();
+ rcu_read_lock_bh();
/* Updates of qdisc are serialized by queue_lock.
* The struct Qdisc which is pointed to by qdisc is now a
@@ -1358,8 +1436,8 @@ int dev_queue_xmit(struct sk_buff *skb)
/* The device has no queue. Common case for software devices:
loopback, all the sorts of tunnels...
- Really, it is unlikely that xmit_lock protection is necessary here.
- (f.e. loopback and IP tunnels are clean ignoring statistics
+ Really, it is unlikely that netif_tx_lock protection is necessary
+ here. (f.e. loopback and IP tunnels are clean ignoring statistics
counters.)
However, it is possible, that they rely on protection
made by us here.
@@ -1375,11 +1453,8 @@ int dev_queue_xmit(struct sk_buff *skb)
HARD_TX_LOCK(dev, cpu);
if (!netif_queue_stopped(dev)) {
- if (netdev_nit)
- dev_queue_xmit_nit(skb, dev);
-
rc = 0;
- if (!dev->hard_start_xmit(skb, dev)) {
+ if (!dev_hard_start_xmit(skb, dev)) {
HARD_TX_UNLOCK(dev);
goto out;
}
@@ -1398,13 +1473,13 @@ int dev_queue_xmit(struct sk_buff *skb)
}
rc = -ENETDOWN;
- local_bh_enable();
+ rcu_read_unlock_bh();
out_kfree_skb:
kfree_skb(skb);
return rc;
out:
- local_bh_enable();
+ rcu_read_unlock_bh();
return rc;
}
@@ -2732,7 +2807,7 @@ int register_netdevice(struct net_device
BUG_ON(dev->reg_state != NETREG_UNINITIALIZED);
spin_lock_init(&dev->queue_lock);
- spin_lock_init(&dev->xmit_lock);
+ spin_lock_init(&dev->_xmit_lock);
dev->xmit_lock_owner = -1;
#ifdef CONFIG_NET_CLS_ACT
spin_lock_init(&dev->ingress_lock);
@@ -2776,9 +2851,7 @@ int register_netdevice(struct net_device
/* Fix illegal SG+CSUM combinations. */
if ((dev->features & NETIF_F_SG) &&
- !(dev->features & (NETIF_F_IP_CSUM |
- NETIF_F_NO_CSUM |
- NETIF_F_HW_CSUM))) {
+ !(dev->features & NETIF_F_ALL_CSUM)) {
printk("%s: Dropping NETIF_F_SG since no checksum feature.\n",
dev->name);
dev->features &= ~NETIF_F_SG;
@@ -3330,7 +3403,6 @@ EXPORT_SYMBOL(__dev_get_by_index);
EXPORT_SYMBOL(__dev_get_by_index);
EXPORT_SYMBOL(__dev_get_by_name);
EXPORT_SYMBOL(__dev_remove_pack);
-EXPORT_SYMBOL(__skb_linearize);
EXPORT_SYMBOL(dev_valid_name);
EXPORT_SYMBOL(dev_add_pack);
EXPORT_SYMBOL(dev_alloc_name);
diff -r c4b68afe97d3 -r 4b51d081378d linux-2.6-xen-sparse/net/core/skbuff.c
--- a/linux-2.6-xen-sparse/net/core/skbuff.c Wed Jun 28 07:51:52 2006 -0600
+++ b/linux-2.6-xen-sparse/net/core/skbuff.c Wed Jun 28 07:52:21 2006 -0600
@@ -165,9 +165,9 @@ struct sk_buff *__alloc_skb(unsigned int
shinfo = skb_shinfo(skb);
atomic_set(&shinfo->dataref, 1);
shinfo->nr_frags = 0;
- shinfo->tso_size = 0;
- shinfo->tso_segs = 0;
- shinfo->ufo_size = 0;
+ shinfo->gso_size = 0;
+ shinfo->gso_segs = 0;
+ shinfo->gso_type = 0;
shinfo->ip6_frag_id = 0;
shinfo->frag_list = NULL;
@@ -237,9 +237,9 @@ struct sk_buff *alloc_skb_from_cache(kme
shinfo = skb_shinfo(skb);
atomic_set(&shinfo->dataref, 1);
shinfo->nr_frags = 0;
- shinfo->tso_size = 0;
- shinfo->tso_segs = 0;
- shinfo->ufo_size = 0;
+ shinfo->gso_size = 0;
+ shinfo->gso_segs = 0;
+ shinfo->gso_type = 0;
shinfo->ip6_frag_id = 0;
shinfo->frag_list = NULL;
@@ -524,8 +524,9 @@ static void copy_skb_header(struct sk_bu
new->tc_index = old->tc_index;
#endif
atomic_set(&new->users, 1);
- skb_shinfo(new)->tso_size = skb_shinfo(old)->tso_size;
- skb_shinfo(new)->tso_segs = skb_shinfo(old)->tso_segs;
+ skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size;
+ skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs;
+ skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type;
}
/**
@@ -1799,6 +1800,133 @@ int skb_append_datato_frags(struct sock
return 0;
}
+
+/**
+ * skb_segment - Perform protocol segmentation on skb.
+ * @skb: buffer to segment
+ * @features: features for the output path (see dev->features)
+ *
+ * This function performs segmentation on the given skb. It returns
+ * the segment at the given position. It returns NULL if there are
+ * no more segments to generate, or when an error is encountered.
+ */
+struct sk_buff *skb_segment(struct sk_buff *skb, int features)
+{
+ struct sk_buff *segs = NULL;
+ struct sk_buff *tail = NULL;
+ unsigned int mss = skb_shinfo(skb)->gso_size;
+ unsigned int doffset = skb->data - skb->mac.raw;
+ unsigned int offset = doffset;
+ unsigned int headroom;
+ unsigned int len;
+ int sg = features & NETIF_F_SG;
+ int nfrags = skb_shinfo(skb)->nr_frags;
+ int err = -ENOMEM;
+ int i = 0;
+ int pos;
+
+ __skb_push(skb, doffset);
+ headroom = skb_headroom(skb);
+ pos = skb_headlen(skb);
+
+ do {
+ struct sk_buff *nskb;
+ skb_frag_t *frag;
+ int hsize, nsize;
+ int k;
+ int size;
+
+ len = skb->len - offset;
+ if (len > mss)
+ len = mss;
+
+ hsize = skb_headlen(skb) - offset;
+ if (hsize < 0)
+ hsize = 0;
+ nsize = hsize + doffset;
+ if (nsize > len + doffset || !sg)
+ nsize = len + doffset;
+
+ nskb = alloc_skb(nsize + headroom, GFP_ATOMIC);
+ if (unlikely(!nskb))
+ goto err;
+
+ if (segs)
+ tail->next = nskb;
+ else
+ segs = nskb;
+ tail = nskb;
+
+ nskb->dev = skb->dev;
+ nskb->priority = skb->priority;
+ nskb->protocol = skb->protocol;
+ nskb->dst = dst_clone(skb->dst);
+ memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
+ nskb->pkt_type = skb->pkt_type;
+ nskb->mac_len = skb->mac_len;
+
+ skb_reserve(nskb, headroom);
+ nskb->mac.raw = nskb->data;
+ nskb->nh.raw = nskb->data + skb->mac_len;
+ nskb->h.raw = nskb->nh.raw + (skb->h.raw - skb->nh.raw);
+ memcpy(skb_put(nskb, doffset), skb->data, doffset);
+
+ if (!sg) {
+ nskb->csum = skb_copy_and_csum_bits(skb, offset,
+ skb_put(nskb, len),
+ len, 0);
+ continue;
+ }
+
+ frag = skb_shinfo(nskb)->frags;
+ k = 0;
+
+ nskb->ip_summed = CHECKSUM_HW;
+ nskb->csum = skb->csum;
+ memcpy(skb_put(nskb, hsize), skb->data + offset, hsize);
+
+ while (pos < offset + len) {
+ BUG_ON(i >= nfrags);
+
+ *frag = skb_shinfo(skb)->frags[i];
+ get_page(frag->page);
+ size = frag->size;
+
+ if (pos < offset) {
+ frag->page_offset += offset - pos;
+ frag->size -= offset - pos;
+ }
+
+ k++;
+
+ if (pos + size <= offset + len) {
+ i++;
+ pos += size;
+ } else {
+ frag->size -= pos + size - (offset + len);
+ break;
+ }
+
+ frag++;
+ }
+
+ skb_shinfo(nskb)->nr_frags = k;
+ nskb->data_len = len - hsize;
+ nskb->len += nskb->data_len;
+ nskb->truesize += nskb->data_len;
+ } while ((offset += len) < skb->len);
+
+ return segs;
+
+err:
+ while ((skb = segs)) {
+ segs = skb->next;
+ kfree(skb);
+ }
+ return ERR_PTR(err);
+}
+
+EXPORT_SYMBOL_GPL(skb_segment);
void __init skb_init(void)
{
diff -r c4b68afe97d3 -r 4b51d081378d
patches/linux-2.6.16.13/xenoprof-generic.patch
--- a/patches/linux-2.6.16.13/xenoprof-generic.patch Wed Jun 28 07:51:52
2006 -0600
+++ b/patches/linux-2.6.16.13/xenoprof-generic.patch Wed Jun 28 07:52:21
2006 -0600
@@ -1,6 +1,6 @@ diff -pruN ../pristine-linux-2.6.16.13/d
-diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c
./drivers/oprofile/buffer_sync.c
---- ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c 2006-05-02
22:38:44.000000000 +0100
-+++ ./drivers/oprofile/buffer_sync.c 2006-05-04 17:41:51.000000000 +0100
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c
./drivers/oprofile/buffer_sync.c
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c 2006-05-03
05:38:44.000000000 +0800
++++ ./drivers/oprofile/buffer_sync.c 2006-06-27 12:14:53.000000000 +0800
@@ -6,6 +6,10 @@
*
* @author John Levon <levon@xxxxxxxxxxxxxxxxx>
@@ -12,7 +12,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d
* This is the core of the buffer management. Each
* CPU buffer is processed and entered into the
* global event buffer. Such processing is necessary
-@@ -275,15 +279,24 @@ static void add_cpu_switch(int i)
+@@ -275,15 +279,30 @@ static void add_cpu_switch(int i)
last_cookie = INVALID_COOKIE;
}
@@ -33,7 +33,13 @@ diff -pruN ../pristine-linux-2.6.16.13/d
+ break;
+ case CPU_MODE_XEN:
+ add_event_entry(XEN_ENTER_SWITCH_CODE);
-+ break;
++ break;
++ case CPU_MODE_PASSIVE_START:
++ add_event_entry(PASSIVE_START_CODE);
++ break;
++ case CPU_MODE_PASSIVE_STOP:
++ add_event_entry(PASSIVE_STOP_CODE);
++ break;
+ default:
+ break;
+ }
@@ -43,7 +49,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d
static void
add_user_ctx_switch(struct task_struct const * task, unsigned long cookie)
{
-@@ -348,9 +361,9 @@ static int add_us_sample(struct mm_struc
+@@ -348,9 +367,9 @@ static int add_us_sample(struct mm_struc
* for later lookup from userspace.
*/
static int
@@ -55,7 +61,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d
add_sample_entry(s->eip, s->event);
return 1;
} else if (mm) {
-@@ -496,7 +509,7 @@ void sync_buffer(int cpu)
+@@ -496,10 +515,11 @@ void sync_buffer(int cpu)
struct mm_struct *mm = NULL;
struct task_struct * new;
unsigned long cookie = 0;
@@ -64,34 +70,62 @@ diff -pruN ../pristine-linux-2.6.16.13/d
unsigned int i;
sync_buffer_state state = sb_buffer_start;
unsigned long available;
-@@ -513,12 +526,12 @@ void sync_buffer(int cpu)
++ int domain_switch = NO_DOMAIN_SWITCH;
+
+ down(&buffer_sem);
+
+@@ -513,12 +533,19 @@ void sync_buffer(int cpu)
struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos];
if (is_code(s->eip)) {
- if (s->event <= CPU_IS_KERNEL) {
-+ if (s->event <= CPU_MODE_XEN) {
++ if (s->event < CPU_TRACE_BEGIN) {
/* kernel/userspace switch */
- in_kernel = s->event;
+ cpu_mode = s->event;
if (state == sb_buffer_start)
state = sb_sample_start;
- add_kernel_ctx_switch(s->event);
-+ add_cpu_mode_switch(s->event);
++
++ if (s->event == CPU_MODE_PASSIVE_START)
++ domain_switch =
DOMAIN_SWITCH_START_EVENT1;
++ else if (s->event == CPU_MODE_PASSIVE_STOP)
++ domain_switch =
DOMAIN_SWITCH_STOP_EVENT1;
++
++ if (domain_switch != DOMAIN_SWITCH_START_EVENT2)
++ add_cpu_mode_switch(s->event);
} else if (s->event == CPU_TRACE_BEGIN) {
state = sb_bt_start;
add_trace_begin();
-@@ -536,7 +549,7 @@ void sync_buffer(int cpu)
+@@ -535,11 +562,20 @@ void sync_buffer(int cpu)
+ add_user_ctx_switch(new, cookie);
}
} else {
- if (state >= sb_bt_start &&
+- if (state >= sb_bt_start &&
- !add_sample(mm, s, in_kernel)) {
-+ !add_sample(mm, s, cpu_mode)) {
- if (state == sb_bt_start) {
- state = sb_bt_ignore;
-
atomic_inc(&oprofile_stats.bt_lost_no_mapping);
-diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c
./drivers/oprofile/cpu_buffer.c
---- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c 2006-05-02
22:38:44.000000000 +0100
-+++ ./drivers/oprofile/cpu_buffer.c 2006-05-04 17:41:51.000000000 +0100
+- if (state == sb_bt_start) {
+- state = sb_bt_ignore;
+-
atomic_inc(&oprofile_stats.bt_lost_no_mapping);
++ if (domain_switch == DOMAIN_SWITCH_START_EVENT1) {
++ add_event_entry(s->event);
++ domain_switch = DOMAIN_SWITCH_START_EVENT2;
++ } else if (domain_switch == DOMAIN_SWITCH_START_EVENT1)
{
++ add_sample_entry(s->eip, s->event);
++ } else if (domain_switch == DOMAIN_SWITCH_STOP_EVENT1) {
++ domain_switch = NO_DOMAIN_SWITCH;
++ } else {
++ if (state >= sb_bt_start &&
++ !add_sample(mm, s, cpu_mode)) {
++ if (state == sb_bt_start) {
++ state = sb_bt_ignore;
++
atomic_inc(&oprofile_stats.bt_lost_no_mapping);
++ }
+ }
+ }
+ }
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c
./drivers/oprofile/cpu_buffer.c
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c 2006-05-03
05:38:44.000000000 +0800
++++ ./drivers/oprofile/cpu_buffer.c 2006-06-19 22:43:53.000000000 +0800
@@ -6,6 +6,10 @@
*
* @author John Levon <levon@xxxxxxxxxxxxxxxxx>
@@ -139,13 +173,12 @@ diff -pruN ../pristine-linux-2.6.16.13/d
{
struct task_struct * task;
-@@ -181,16 +185,16 @@ static int log_sample(struct oprofile_cp
+@@ -181,16 +185,14 @@ static int log_sample(struct oprofile_cp
return 0;
}
- is_kernel = !!is_kernel;
-+ WARN_ON(cpu_mode > CPU_MODE_XEN);
-
+-
task = current;
/* notice a switch from user->kernel or vice versa */
@@ -161,9 +194,9 @@ diff -pruN ../pristine-linux-2.6.16.13/d
/* notice a task switch */
if (cpu_buf->last_task != task) {
cpu_buf->last_task = task;
-diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h
./drivers/oprofile/cpu_buffer.h
---- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h 2006-05-02
22:38:44.000000000 +0100
-+++ ./drivers/oprofile/cpu_buffer.h 2006-05-04 17:41:51.000000000 +0100
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h
./drivers/oprofile/cpu_buffer.h
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h 2006-05-03
05:38:44.000000000 +0800
++++ ./drivers/oprofile/cpu_buffer.h 2006-06-27 10:38:08.000000000 +0800
@@ -36,7 +36,7 @@ struct oprofile_cpu_buffer {
volatile unsigned long tail_pos;
unsigned long buffer_size;
@@ -173,22 +206,26 @@ diff -pruN ../pristine-linux-2.6.16.13/d
int tracing;
struct op_sample * buffer;
unsigned long sample_received;
-@@ -51,7 +51,9 @@ extern struct oprofile_cpu_buffer cpu_bu
+@@ -51,7 +51,13 @@ extern struct oprofile_cpu_buffer cpu_bu
void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf);
/* transient events for the CPU buffer -> event buffer */
-#define CPU_IS_KERNEL 1
-#define CPU_TRACE_BEGIN 2
-+#define CPU_MODE_USER 0
-+#define CPU_MODE_KERNEL 1
-+#define CPU_MODE_XEN 2
-+#define CPU_TRACE_BEGIN 3
++#define CPU_MODE_USER 0
++#define CPU_MODE_KERNEL 1
++#define CPU_MODE_XEN 2
++#define CPU_MODE_PASSIVE_START 3
++#define CPU_MODE_PASSIVE_STOP 4
++#define CPU_TRACE_BEGIN 5
++
++#define IGNORED_PC 0
#endif /* OPROFILE_CPU_BUFFER_H */
-diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h
./drivers/oprofile/event_buffer.h
---- ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h
2006-05-02 22:38:44.000000000 +0100
-+++ ./drivers/oprofile/event_buffer.h 2006-05-04 17:41:51.000000000 +0100
-@@ -29,11 +29,12 @@ void wake_up_buffer_waiter(void);
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h
./drivers/oprofile/event_buffer.h
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h
2006-05-03 05:38:44.000000000 +0800
++++ ./drivers/oprofile/event_buffer.h 2006-06-19 22:43:53.000000000 +0800
+@@ -29,11 +29,14 @@ void wake_up_buffer_waiter(void);
#define CPU_SWITCH_CODE 2
#define COOKIE_SWITCH_CODE 3
#define KERNEL_ENTER_SWITCH_CODE 4
@@ -199,12 +236,14 @@ diff -pruN ../pristine-linux-2.6.16.13/d
#define TRACE_BEGIN_CODE 8
#define TRACE_END_CODE 9
+#define XEN_ENTER_SWITCH_CODE 10
++#define PASSIVE_START_CODE 11
++#define PASSIVE_STOP_CODE 12
#define INVALID_COOKIE ~0UL
#define NO_COOKIE 0UL
-diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c
./drivers/oprofile/oprof.c
---- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c 2006-05-02
22:38:44.000000000 +0100
-+++ ./drivers/oprofile/oprof.c 2006-05-04 17:41:51.000000000 +0100
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c
./drivers/oprofile/oprof.c
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c 2006-05-03
05:38:44.000000000 +0800
++++ ./drivers/oprofile/oprof.c 2006-06-19 23:45:17.000000000 +0800
@@ -5,6 +5,10 @@
* @remark Read the file COPYING
*
@@ -225,7 +264,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d
struct oprofile_operations oprofile_ops;
unsigned long oprofile_started;
-@@ -33,6 +37,19 @@ static DECLARE_MUTEX(start_sem);
+@@ -33,6 +37,32 @@ static DECLARE_MUTEX(start_sem);
*/
static int timer = 0;
@@ -242,23 +281,37 @@ diff -pruN ../pristine-linux-2.6.16.13/d
+ return err;
+}
+
++int oprofile_set_passive(int passive_domains[], unsigned int pdomains)
++{
++ int err;
++
++ if (!oprofile_ops.set_passive)
++ return -EINVAL;
++
++ down(&start_sem);
++ err = oprofile_ops.set_passive(passive_domains, pdomains);
++ up(&start_sem);
++ return err;
++}
++
int oprofile_setup(void)
{
int err;
-diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h
./drivers/oprofile/oprof.h
---- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h 2006-05-02
22:38:44.000000000 +0100
-+++ ./drivers/oprofile/oprof.h 2006-05-04 17:41:51.000000000 +0100
-@@ -35,5 +35,7 @@ void oprofile_create_files(struct super_
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h
./drivers/oprofile/oprof.h
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h 2006-05-03
05:38:44.000000000 +0800
++++ ./drivers/oprofile/oprof.h 2006-06-19 23:42:36.000000000 +0800
+@@ -35,5 +35,8 @@ void oprofile_create_files(struct super_
void oprofile_timer_init(struct oprofile_operations * ops);
int oprofile_set_backtrace(unsigned long depth);
+
+int oprofile_set_active(int active_domains[], unsigned int adomains);
++int oprofile_set_passive(int passive_domains[], unsigned int pdomains);
#endif /* OPROF_H */
-diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c
./drivers/oprofile/oprofile_files.c
---- ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c
2006-05-02 22:38:44.000000000 +0100
-+++ ./drivers/oprofile/oprofile_files.c 2006-05-04 17:41:51.000000000
+0100
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c
./drivers/oprofile/oprofile_files.c
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c
2006-05-03 05:38:44.000000000 +0800
++++ ./drivers/oprofile/oprofile_files.c 2006-06-19 23:29:07.000000000
+0800
@@ -5,15 +5,21 @@
* @remark Read the file COPYING
*
@@ -282,7 +335,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d
unsigned long fs_buffer_size = 131072;
unsigned long fs_cpu_buffer_size = 8192;
unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */
-@@ -117,11 +123,108 @@ static ssize_t dump_write(struct file *
+@@ -117,11 +123,202 @@ static ssize_t dump_write(struct file *
static struct file_operations dump_fops = {
.write = dump_write,
};
@@ -384,17 +437,110 @@ diff -pruN ../pristine-linux-2.6.16.13/d
+ .write = adomain_write,
+};
+
++static unsigned int pdomains = 0;
++static int passive_domains[MAX_OPROF_DOMAINS];
++static DEFINE_MUTEX(pdom_mutex);
++
++static ssize_t pdomain_write(struct file * file, char const __user * buf,
++ size_t count, loff_t * offset)
++{
++ char *tmpbuf;
++ char *startp, *endp;
++ int i;
++ unsigned long val;
++ ssize_t retval = count;
++
++ if (*offset)
++ return -EINVAL;
++ if (count > TMPBUFSIZE - 1)
++ return -EINVAL;
++
++ if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
++ return -ENOMEM;
++
++ if (copy_from_user(tmpbuf, buf, count)) {
++ kfree(tmpbuf);
++ return -EFAULT;
++ }
++ tmpbuf[count] = 0;
++
++ mutex_lock(&pdom_mutex);
++
++ startp = tmpbuf;
++ /* Parse one more than MAX_OPROF_DOMAINS, for easy error checking */
++ for (i = 0; i <= MAX_OPROF_DOMAINS; i++) {
++ val = simple_strtoul(startp, &endp, 0);
++ if (endp == startp)
++ break;
++ while (ispunct(*endp) || isspace(*endp))
++ endp++;
++ passive_domains[i] = val;
++ if (passive_domains[i] != val)
++ /* Overflow, force error below */
++ i = MAX_OPROF_DOMAINS + 1;
++ startp = endp;
++ }
++ /* Force error on trailing junk */
++ pdomains = *startp ? MAX_OPROF_DOMAINS + 1 : i;
++
++ kfree(tmpbuf);
++
++ if (pdomains > MAX_OPROF_DOMAINS
++ || oprofile_set_passive(passive_domains, pdomains)) {
++ pdomains = 0;
++ retval = -EINVAL;
++ }
++
++ mutex_unlock(&pdom_mutex);
++ return retval;
++}
++
++static ssize_t pdomain_read(struct file * file, char __user * buf,
++ size_t count, loff_t * offset)
++{
++ char * tmpbuf;
++ size_t len;
++ int i;
++ ssize_t retval;
++
++ if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
++ return -ENOMEM;
++
++ mutex_lock(&pdom_mutex);
++
++ len = 0;
++ for (i = 0; i < pdomains; i++)
++ len += snprintf(tmpbuf + len,
++ len < TMPBUFSIZE ? TMPBUFSIZE - len : 0,
++ "%u ", passive_domains[i]);
++ WARN_ON(len > TMPBUFSIZE);
++ if (len != 0 && len <= TMPBUFSIZE)
++ tmpbuf[len-1] = '\n';
++
++ mutex_unlock(&pdom_mutex);
++
++ retval = simple_read_from_buffer(buf, count, offset, tmpbuf, len);
++
++ kfree(tmpbuf);
++ return retval;
++}
++
++static struct file_operations passive_domain_ops = {
++ .read = pdomain_read,
++ .write = pdomain_write,
++};
++
void oprofile_create_files(struct super_block * sb, struct dentry * root)
{
oprofilefs_create_file(sb, root, "enable", &enable_fops);
oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666);
+ oprofilefs_create_file(sb, root, "active_domains", &active_domain_ops);
++ oprofilefs_create_file(sb, root, "passive_domains",
&passive_domain_ops);
oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops);
oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size);
oprofilefs_create_ulong(sb, root, "buffer_watershed",
&fs_buffer_watershed);
-diff -pruN ../pristine-linux-2.6.16.13/include/linux/oprofile.h
./include/linux/oprofile.h
---- ../pristine-linux-2.6.16.13/include/linux/oprofile.h 2006-05-02
22:38:44.000000000 +0100
-+++ ./include/linux/oprofile.h 2006-05-04 17:41:51.000000000 +0100
+--- ../pristine-linux-2.6.16.13/include/linux/oprofile.h 2006-05-03
05:38:44.000000000 +0800
++++ ./include/linux/oprofile.h 2006-06-19 23:52:00.000000000 +0800
@@ -16,6 +16,8 @@
#include <linux/types.h>
#include <linux/spinlock.h>
@@ -404,12 +550,15 @@ diff -pruN ../pristine-linux-2.6.16.13/i
struct super_block;
struct dentry;
-@@ -27,6 +29,8 @@ struct oprofile_operations {
+@@ -27,6 +29,11 @@ struct oprofile_operations {
/* create any necessary configuration files in the oprofile fs.
* Optional. */
int (*create_files)(struct super_block * sb, struct dentry * root);
+ /* setup active domains with Xen */
+ int (*set_active)(int *active_domains, unsigned int adomains);
++ /* setup passive domains with Xen */
++ int (*set_passive)(int *passive_domains, unsigned int pdomains);
++
/* Do any necessary interrupt setup. Optional. */
int (*setup)(void);
/* Do any necessary interrupt shutdown. Optional. */
diff -r c4b68afe97d3 -r 4b51d081378d tools/Makefile
--- a/tools/Makefile Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/Makefile Wed Jun 28 07:52:21 2006 -0600
@@ -45,6 +45,9 @@ clean: check_clean
done
$(MAKE) ioemuclean
+.PHONY: distclean
+distclean: clean
+
.PHONY: check
check:
$(MAKE) -C check
diff -r c4b68afe97d3 -r 4b51d081378d tools/examples/Makefile
--- a/tools/examples/Makefile Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/examples/Makefile Wed Jun 28 07:52:21 2006 -0600
@@ -32,7 +32,7 @@ XEN_SCRIPT_DATA = xen-script-common.sh l
XEN_SCRIPT_DATA = xen-script-common.sh locking.sh logging.sh
XEN_SCRIPT_DATA += xen-hotplug-common.sh xen-network-common.sh vif-common.sh
XEN_SCRIPT_DATA += block-common.sh vtpm-common.sh vtpm-hotplug-common.sh
-XEN_SCRIPT_DATA += vtpm-migration.sh
+XEN_SCRIPT_DATA += vtpm-migration.sh vtpm-impl
XEN_HOTPLUG_DIR = /etc/hotplug
XEN_HOTPLUG_SCRIPTS = xen-backend.agent
diff -r c4b68afe97d3 -r 4b51d081378d tools/examples/vtpm
--- a/tools/examples/vtpm Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/examples/vtpm Wed Jun 28 07:52:21 2006 -0600
@@ -9,13 +9,7 @@ case "$command" in
add)
vtpm_create_instance
;;
- online)
- vtpm_create_instance
- ;;
remove)
- vtpm_remove_instance
- ;;
- offline)
vtpm_remove_instance
;;
esac
diff -r c4b68afe97d3 -r 4b51d081378d tools/examples/vtpm-common.sh
--- a/tools/examples/vtpm-common.sh Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/examples/vtpm-common.sh Wed Jun 28 07:52:21 2006 -0600
@@ -23,7 +23,7 @@ VTPMDB="/etc/xen/vtpm.db"
VTPMDB="/etc/xen/vtpm.db"
#In the vtpm-impl file some commands should be defined:
-# vtpm_create, vtpm_setup, vtpm_reset, etc. (see below)
+# vtpm_create, vtpm_setup, vtpm_start, etc. (see below)
#This should be indicated by setting VTPM_IMPL_DEFINED.
if [ -r "$dir/vtpm-impl" ]; then
. "$dir/vtpm-impl"
@@ -36,7 +36,7 @@ if [ -z "$VTPM_IMPL_DEFINED" ]; then
function vtpm_setup() {
true
}
- function vtpm_reset() {
+ function vtpm_start() {
true
}
function vtpm_suspend() {
@@ -256,22 +256,22 @@ function vtpm_create_instance () {
else
instance=$(vtpmdb_get_free_instancenum)
fi
- if [ "$reason" == "create" ]; then
- vtpm_create $instance
- else
- vtpm_resume $instance $domname
- fi
+
+ vtpm_create $instance
+
if [ $vtpm_fatal_error -eq 0 ]; then
vtpmdb_add_instance $domname $instance
fi
+ else
+ if [ "$reason" == "resume" ]; then
+ vtpm_resume $instance
+ else
+ vtpm_start $instance
+ fi
fi
release_lock vtpmdb
- if [ $vtpm_fatal_error -eq 0 -a \
- "$reason" == "create" ]; then
- vtpm_reset $instance
- fi
xenstore_write $XENBUS_PATH/instance $instance
}
@@ -283,19 +283,17 @@ function vtpm_remove_instance () {
local instance reason domname
domname=$(xenstore_read "$XENBUS_PATH"/domain)
- if [ "$doname" != "" ]; then
+ if [ "$domname" != "" ]; then
claim_lock vtpmdb
instance=$(vtpmdb_find_instance $domname)
if [ "$instance" != "0" ]; then
- if [ "$reason" == "suspend" ]; then
- vtpm_suspend $instance
- fi
- fi
- fi
-
- release_lock vtpmdb
+ vtpm_suspend $instance
+ fi
+
+ release_lock vtpmdb
+ fi
}
diff -r c4b68afe97d3 -r 4b51d081378d tools/libxc/Makefile
--- a/tools/libxc/Makefile Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/libxc/Makefile Wed Jun 28 07:52:21 2006 -0600
@@ -31,7 +31,6 @@ GUEST_SRCS-y += xc_load_elf.c
GUEST_SRCS-y += xc_load_elf.c
GUEST_SRCS-y += xg_private.c
GUEST_SRCS-$(CONFIG_IA64) += xc_ia64_stubs.c
-GUEST_SRCS-$(CONFIG_PLAN9) += xc_load_aout9.c
GUEST_SRCS-$(CONFIG_MIGRATE) += xc_linux_restore.c xc_linux_save.c
GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c
diff -r c4b68afe97d3 -r 4b51d081378d tools/libxc/xc_ia64_stubs.c
--- a/tools/libxc/xc_ia64_stubs.c Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/libxc/xc_ia64_stubs.c Wed Jun 28 07:52:21 2006 -0600
@@ -38,23 +38,12 @@ int xc_linux_restore(int xc_handle, int
return -1;
}
-int
-xc_plan9_build(int xc_handle,
- uint32_t domid,
- const char *image_name,
- const char *cmdline,
- unsigned int control_evtchn, unsigned long flags)
-{
- PERROR("xc_plan9_build not implemented\n");
- return -1;
-}
/*
VMM uses put_user to copy pfn_list to guest buffer, this maybe fail,
VMM doesn't handle this now.
This method will touch guest buffer to make sure the buffer's mapping
is tracked by VMM,
*/
-
int xc_ia64_get_pfn_list(int xc_handle,
uint32_t domid,
xen_pfn_t *pfn_buf,
diff -r c4b68afe97d3 -r 4b51d081378d tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/libxc/xc_linux_build.c Wed Jun 28 07:52:21 2006 -0600
@@ -7,7 +7,6 @@
#include <xenctrl.h>
#include "xc_elf.h"
-#include "xc_aout9.h"
#include <stdlib.h>
#include <unistd.h>
#include <inttypes.h>
@@ -34,10 +33,6 @@
#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
#define round_pgdown(_p) ((_p)&PAGE_MASK)
-
-#ifdef __ia64__
-#define probe_aout9(image,image_size,load_funcs) 1
-#endif
struct initrd_info {
enum { INITRD_none, INITRD_file, INITRD_mem } type;
@@ -124,8 +119,7 @@ static int probeimageformat(const char *
struct load_funcs *load_funcs)
{
if ( probe_elf(image, image_size, load_funcs) &&
- probe_bin(image, image_size, load_funcs) &&
- probe_aout9(image, image_size, load_funcs) )
+ probe_bin(image, image_size, load_funcs) )
{
ERROR( "Unrecognized image format" );
return -EINVAL;
diff -r c4b68afe97d3 -r 4b51d081378d tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/libxc/xg_private.h Wed Jun 28 07:52:21 2006 -0600
@@ -196,8 +196,5 @@ int probe_elf(const char *image, unsigne
struct load_funcs *funcs);
int probe_bin(const char *image, unsigned long image_size,
struct load_funcs *funcs);
-int probe_aout9(const char *image, unsigned long image_size,
- struct load_funcs *funcs);
-
-#endif
-
+
+#endif /* XG_PRIVATE_H */
diff -r c4b68afe97d3 -r 4b51d081378d tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/python/xen/lowlevel/xc/xc.c Wed Jun 28 07:52:21 2006 -0600
@@ -582,6 +582,12 @@ static PyObject *pyxc_readconsolering(Xc
}
+static unsigned long pages_to_kib(unsigned long pages)
+{
+ return pages * (XC_PAGE_SIZE / 1024);
+}
+
+
static PyObject *pyxc_pages_to_kib(XcObject *self, PyObject *args)
{
unsigned long pages;
@@ -589,13 +595,7 @@ static PyObject *pyxc_pages_to_kib(XcObj
if (!PyArg_ParseTuple(args, "l", &pages))
return NULL;
- return PyLong_FromUnsignedLong(pages * (XC_PAGE_SIZE / 1024));
-}
-
-
-static unsigned long pages_to_mb(unsigned long pages)
-{
- return (pages * (XC_PAGE_SIZE / 1024) + 1023) / 1024;
+ return PyLong_FromUnsignedLong(pages_to_kib(pages));
}
@@ -618,13 +618,14 @@ static PyObject *pyxc_physinfo(XcObject
if(q>cpu_cap)
*(q-1)=0;
- return Py_BuildValue("{s:i,s:i,s:i,s:i,s:l,s:l,s:i,s:s}",
+ return Py_BuildValue("{s:i,s:i,s:i,s:i,s:l,s:l,s:l,s:i,s:s}",
"threads_per_core", info.threads_per_core,
"cores_per_socket", info.cores_per_socket,
"sockets_per_node", info.sockets_per_node,
"nr_nodes", info.nr_nodes,
- "total_memory", pages_to_mb(info.total_pages),
- "free_memory", pages_to_mb(info.free_pages),
+ "total_memory", pages_to_kib(info.total_pages),
+ "free_memory", pages_to_kib(info.free_pages),
+ "scrub_memory", pages_to_kib(info.scrub_pages),
"cpu_khz", info.cpu_khz,
"hw_caps", cpu_cap);
}
@@ -637,6 +638,7 @@ static PyObject *pyxc_xeninfo(XcObject *
xen_capabilities_info_t xen_caps;
xen_platform_parameters_t p_parms;
long xen_version;
+ long xen_pagesize;
char str[128];
xen_version = xc_version(self->xc_handle, XENVER_version, NULL);
@@ -658,11 +660,16 @@ static PyObject *pyxc_xeninfo(XcObject *
sprintf(str, "virt_start=0x%lx", p_parms.virt_start);
- return Py_BuildValue("{s:i,s:i,s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:s}",
+ xen_pagesize = xc_version(self->xc_handle, XENVER_pagesize, NULL);
+ if (xen_pagesize < 0 )
+ return PyErr_SetFromErrno(xc_error);
+
+ 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}",
"xen_major", xen_version >> 16,
"xen_minor", (xen_version & 0xffff),
"xen_extra", xen_extra,
"xen_caps", xen_caps,
+ "xen_pagesize", xen_pagesize,
"platform_params", str,
"xen_changeset", xen_chgset,
"cc_compiler", xen_cc.compiler,
diff -r c4b68afe97d3 -r 4b51d081378d tools/python/xen/xend/XendNode.py
--- a/tools/python/xen/xend/XendNode.py Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/python/xen/xend/XendNode.py Wed Jun 28 07:52:21 2006 -0600
@@ -64,6 +64,9 @@ class XendNode:
info['cores_per_socket'] *
info['threads_per_core'])
info['cpu_mhz'] = info['cpu_khz'] / 1000
+ # physinfo is in KiB
+ info['total_memory'] = info['total_memory'] / 1024
+ info['free_memory'] = info['free_memory'] / 1024
ITEM_ORDER = ['nr_cpus',
'nr_nodes',
@@ -86,6 +89,7 @@ class XendNode:
'xen_minor',
'xen_extra',
'xen_caps',
+ 'xen_pagesize',
'platform_params',
'xen_changeset',
'cc_compiler',
diff -r c4b68afe97d3 -r 4b51d081378d tools/python/xen/xend/balloon.py
--- a/tools/python/xen/xend/balloon.py Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/python/xen/xend/balloon.py Wed Jun 28 07:52:21 2006 -0600
@@ -29,9 +29,7 @@ from XendError import VmError
PROC_XEN_BALLOON = '/proc/xen/balloon'
-BALLOON_OUT_SLACK = 1 # MiB. We need this because the physinfo details are
- # rounded.
-RETRY_LIMIT = 10
+RETRY_LIMIT = 20
RETRY_LIMIT_INCR = 5
##
# The time to sleep between retries grows linearly, using this value (in
@@ -68,22 +66,22 @@ def _get_proc_balloon(label):
f.close()
def get_dom0_current_alloc():
- """Returns the current memory allocation (in MiB) of dom0."""
+ """Returns the current memory allocation (in KiB) of dom0."""
kb = _get_proc_balloon(labels['current'])
if kb == None:
raise VmError('Failed to query current memory allocation of dom0.')
- return kb / 1024
+ return kb
def get_dom0_target_alloc():
- """Returns the target memory allocation (in MiB) of dom0."""
+ """Returns the target memory allocation (in KiB) of dom0."""
kb = _get_proc_balloon(labels['target'])
if kb == None:
raise VmError('Failed to query target memory allocation of dom0.')
- return kb / 1024
+ return kb
-def free(required):
+def free(need_mem):
"""Balloon out memory from the privileged domain so that there is the
specified required amount (in KiB) free.
"""
@@ -92,9 +90,10 @@ def free(required):
# to balloon out to free some up. Memory freed by a destroyed domain may
# not appear in the free_memory field immediately, because it needs to be
# scrubbed before it can be released to the free list, which is done
- # asynchronously by Xen; ballooning is asynchronous also. No matter where
- # we expect the free memory to come from, therefore, we need to wait for
- # it to become available.
+ # asynchronously by Xen; ballooning is asynchronous also. Such memory
+ # does, however, need to be accounted for when calculating how much dom0
+ # needs to balloon. No matter where we expect the free memory to come
+ # from, we need to wait for it to become available.
#
# We are not allowed to balloon below dom0_min_mem, or if dom0_min_mem
# is 0, we cannot balloon at all. Memory can still become available
@@ -108,43 +107,49 @@ def free(required):
# usage, so we recheck the required alloc each time around the loop, but
# track the last used value so that we don't trigger too many watches.
- need_mem = (required + 1023) / 1024 + BALLOON_OUT_SLACK
-
xroot = XendRoot.instance()
xc = xen.lowlevel.xc.xc()
try:
- dom0_min_mem = xroot.get_dom0_min_mem()
+ dom0_min_mem = xroot.get_dom0_min_mem() * 1024
retries = 0
sleep_time = SLEEP_TIME_GROWTH
last_new_alloc = None
rlimit = RETRY_LIMIT
while retries < rlimit:
- free_mem = xc.physinfo()['free_memory']
+ physinfo = xc.physinfo()
+ free_mem = physinfo['free_memory']
+ scrub_mem = physinfo['scrub_memory']
if free_mem >= need_mem:
- log.debug("Balloon: free %d; need %d; done.", free_mem,
- need_mem)
+ log.debug("Balloon: %d KiB free; need %d; done.",
+ free_mem, need_mem)
return
if retries == 0:
- rlimit += ((need_mem - free_mem)/1024) * RETRY_LIMIT_INCR
- log.debug("Balloon: free %d; need %d; retries: %d.",
- free_mem, need_mem, rlimit)
+ rlimit += ((need_mem - free_mem)/1024/1024) * RETRY_LIMIT_INCR
+ log.debug("Balloon: %d KiB free; %d to scrub; need %d;
retries: %d.",
+ free_mem, scrub_mem, need_mem, rlimit)
if dom0_min_mem > 0:
dom0_alloc = get_dom0_current_alloc()
- new_alloc = dom0_alloc - (need_mem - free_mem)
+ new_alloc = dom0_alloc - (need_mem - free_mem - scrub_mem)
- if (new_alloc >= dom0_min_mem and
- new_alloc != last_new_alloc):
- log.debug("Balloon: setting dom0 target to %d.",
- new_alloc)
- dom0 = XendDomain.instance().privilegedDomain()
- dom0.setMemoryTarget(new_alloc)
- last_new_alloc = new_alloc
- # Continue to retry, waiting for ballooning.
+ if free_mem + scrub_mem >= need_mem:
+ if last_new_alloc == None:
+ log.debug("Balloon: waiting on scrubbing")
+ last_new_alloc = dom0_alloc
+ else:
+ if (new_alloc >= dom0_min_mem and
+ new_alloc != last_new_alloc):
+ new_alloc_mb = new_alloc / 1024 # Round down
+ log.debug("Balloon: setting dom0 target to %d MiB.",
+ new_alloc_mb)
+ dom0 = XendDomain.instance().privilegedDomain()
+ dom0.setMemoryTarget(new_alloc_mb)
+ last_new_alloc = new_alloc
+ # Continue to retry, waiting for ballooning or scrubbing.
time.sleep(sleep_time)
if retries < 2 * RETRY_LIMIT:
@@ -154,15 +159,15 @@ def free(required):
# Not enough memory; diagnose the problem.
if dom0_min_mem == 0:
raise VmError(('Not enough free memory and dom0_min_mem is 0, so '
- 'I cannot release any more. I need %d MiB but '
+ 'I cannot release any more. I need %d KiB but '
'only have %d.') %
(need_mem, free_mem))
elif new_alloc < dom0_min_mem:
raise VmError(
- ('I need %d MiB, but dom0_min_mem is %d and shrinking to '
- '%d MiB would leave only %d MiB free.') %
+ ('I need %d KiB, but dom0_min_mem is %d and shrinking to '
+ '%d KiB would leave only %d KiB free.') %
(need_mem, dom0_min_mem, dom0_min_mem,
- free_mem + dom0_alloc - dom0_min_mem))
+ free_mem + scrub_mem + dom0_alloc - dom0_min_mem))
else:
raise VmError('The privileged domain did not balloon!')
diff -r c4b68afe97d3 -r 4b51d081378d tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/python/xen/xm/main.py Wed Jun 28 07:52:21 2006 -0600
@@ -887,7 +887,7 @@ def parse_dev_info(info):
'ring-ref' : get_info('ring-ref', int, -1),
}
-def has_long_option(args):
+def arg_check_for_resource_list(args, name):
use_long = 0
try:
(options, params) = getopt.gnu_getopt(args, 'l', ['long'])
@@ -898,16 +898,19 @@ def has_long_option(args):
for (k, v) in options:
if k in ['-l', '--long']:
use_long = 1
- return (use_long, params)
-
-def xm_network_list(args):
- arg_check(args, "network-list", 1, 2)
-
- (use_long, params) = has_long_option(args)
if len(params) == 0:
print 'No domain parameter given'
- sys.exit(1)
+ usage(name)
+ if len(params) > 1:
+ print 'No multiple domain parameters allowed'
+ usage(name)
+
+ return (use_long, params)
+
+def xm_network_list(args):
+ (use_long, params) = arg_check_for_resource_list(args, "network-list")
+
dom = params[0]
if use_long:
devs = server.xend.domain.getDeviceSxprs(dom, 'vif')
@@ -931,13 +934,8 @@ def xm_network_list(args):
% ni)
def xm_block_list(args):
- arg_check(args, "block-list", 1, 2)
-
- (use_long, params) = has_long_option(args)
-
- if len(params) == 0:
- print 'No domain parameter given'
- sys.exit(1)
+ (use_long, params) = arg_check_for_resource_list(args, "block-list")
+
dom = params[0]
if use_long:
devs = server.xend.domain.getDeviceSxprs(dom, 'vbd')
@@ -960,13 +958,8 @@ def xm_block_list(args):
% ni)
def xm_vtpm_list(args):
- arg_check(args, "vtpm-list", 1, 2)
-
- (use_long, params) = has_long_option(args)
-
- if len(params) == 0:
- print 'No domain parameter given'
- sys.exit(1)
+ (use_long, params) = arg_check_for_resource_list(args, "vtpm-list")
+
dom = params[0]
if use_long:
devs = server.xend.domain.getDeviceSxprs(dom, 'vtpm')
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm/Rules.mk
--- a/tools/vtpm/Rules.mk Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm/Rules.mk Wed Jun 28 07:52:21 2006 -0600
@@ -33,8 +33,7 @@ OBJS = $(patsubst %.c,%.o,$(SRCS))
-include $(DEP_FILES)
-# Emulator does not work on 64-bit systems, and may be broken on 32 right now
-BUILD_EMULATOR = n
+BUILD_EMULATOR = y
# Make sure these are just rules
.PHONY : all build install clean
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm/tpm_emulator-0.3-x86_64.patch
--- a/tools/vtpm/tpm_emulator-0.3-x86_64.patch Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm/tpm_emulator-0.3-x86_64.patch Wed Jun 28 07:52:21 2006 -0600
@@ -1,6 +1,49 @@ diff -uprN tpm_emulator-0.3/crypto/gmp_k
-diff -uprN tpm_emulator-0.3/crypto/gmp_kernel_wrapper.c
tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c
---- tpm_emulator-0.3/crypto/gmp_kernel_wrapper.c 2006-01-10
04:21:45.000000000 -0800
-+++ tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c 2006-05-26
11:26:02.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3/Makefile tpm_emulator-0.3-x86_64/Makefile
+--- orig/tpm_emulator-0.3/Makefile 2006-01-10 04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/Makefile 2006-08-29 15:08:20.532342768 -0700
+@@ -7,6 +7,7 @@
+ KERNEL_RELEASE := $(shell uname -r)
+ KERNEL_BUILD := /lib/modules/$(KERNEL_RELEASE)/build
+ MOD_SUBDIR := misc
++COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/)
+
+ # module settings
+ MODULE_NAME := tpm_emulator
+@@ -17,8 +18,14 @@ VERSION_BUILD := $(shell date +"%s")
+ # enable/disable DEBUG messages
+ EXTRA_CFLAGS += -Wall -DDEBUG -g
+
++ifeq ($(COMPILE_ARCH),x86_64)
++LIBDIR = lib64
++else
++LIBDIR = lib
++endif
++
+ # GNU MP configuration
+-GMP_LIB := /usr/lib/libgmp.a
++GMP_LIB := /usr/$(LIBDIR)/libgmp.a
+ GMP_HEADER := /usr/include/gmp.h
+
+ # sources and objects
+diff -uprN orig/tpm_emulator-0.3/README tpm_emulator-0.3-x86_64/README
+--- orig/tpm_emulator-0.3/README 2006-01-10 04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/README 2006-08-29 15:07:43.530967832 -0700
+@@ -43,6 +43,12 @@ Example:
+ GMP_LIB := /usr/lib/libgmp.a
+ GMP_HEADER := /usr/include/gmp.h
+
++GNU MP Library on 64 bit Systems
++--------------------------------------------------------------------------
++Some 64-bit kernels have problems with importing the user-space gmp
++library (/usr/lib*/libgmp.a) into kernel space. These kernels will require
++that the gmp library be recompiled for kernel space with -mcmodel=kernel.
++
+ Installation
+ --------------------------------------------------------------------------
+ The compilation and installation process uses the build environment for
+diff -uprN orig/tpm_emulator-0.3/crypto/gmp_kernel_wrapper.c
tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c
+--- orig/tpm_emulator-0.3/crypto/gmp_kernel_wrapper.c 2006-01-10
04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c 2006-08-29
15:07:43.525968592 -0700
@@ -79,7 +79,7 @@ void __attribute__ ((regparm(0))) *kerne
{
void *ret = (void*)kmalloc(size, GFP_KERNEL);
@@ -19,9 +62,9 @@ diff -uprN tpm_emulator-0.3/crypto/gmp_k
memcpy(ret, oldptr, old_size);
kfree(oldptr);
return ret;
-diff -uprN tpm_emulator-0.3/linux_module.c
tpm_emulator-0.3-x86_64/linux_module.c
---- tpm_emulator-0.3/linux_module.c 2006-01-10 04:21:45.000000000 -0800
-+++ tpm_emulator-0.3-x86_64/linux_module.c 2006-05-26 11:26:02.000000000
-0700
+diff -uprN orig/tpm_emulator-0.3/linux_module.c
tpm_emulator-0.3-x86_64/linux_module.c
+--- orig/tpm_emulator-0.3/linux_module.c 2006-01-10 04:21:45.000000000
-0800
++++ tpm_emulator-0.3-x86_64/linux_module.c 2006-08-29 15:07:43.526968440
-0700
@@ -72,7 +72,7 @@ static int tpm_release(struct inode *ino
static ssize_t tpm_read(struct file *file, char *buf, size_t count, loff_t
*ppos)
@@ -40,9 +83,9 @@ diff -uprN tpm_emulator-0.3/linux_module
down(&tpm_mutex);
*ppos = 0;
if (tpm_response.data != NULL) kfree(tpm_response.data);
-diff -uprN tpm_emulator-0.3/linux_module.h
tpm_emulator-0.3-x86_64/linux_module.h
---- tpm_emulator-0.3/linux_module.h 2006-01-10 04:21:45.000000000 -0800
-+++ tpm_emulator-0.3-x86_64/linux_module.h 2006-05-26 11:26:02.000000000
-0700
+diff -uprN orig/tpm_emulator-0.3/linux_module.h
tpm_emulator-0.3-x86_64/linux_module.h
+--- orig/tpm_emulator-0.3/linux_module.h 2006-01-10 04:21:45.000000000
-0800
++++ tpm_emulator-0.3-x86_64/linux_module.h 2006-08-29 15:07:43.527968288
-0700
@@ -28,8 +28,10 @@
/* module settings */
@@ -54,52 +97,9 @@ diff -uprN tpm_emulator-0.3/linux_module
#include "tpm_version.h"
#define TPM_DEVICE_MINOR 224
-diff -uprN tpm_emulator-0.3/Makefile tpm_emulator-0.3-x86_64/Makefile
---- tpm_emulator-0.3/Makefile 2006-01-10 04:21:45.000000000 -0800
-+++ tpm_emulator-0.3-x86_64/Makefile 2006-05-26 11:26:02.000000000 -0700
-@@ -7,6 +7,7 @@
- KERNEL_RELEASE := $(shell uname -r)
- KERNEL_BUILD := /lib/modules/$(KERNEL_RELEASE)/build
- MOD_SUBDIR := misc
-+COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/)
-
- # module settings
- MODULE_NAME := tpm_emulator
-@@ -17,8 +18,14 @@ VERSION_BUILD := $(shell date +"%s")
- # enable/disable DEBUG messages
- EXTRA_CFLAGS += -Wall -DDEBUG -g
-
-+ifeq ($(COMPILE_ARCH),x86_64)
-+LIBDIR = lib64
-+else
-+LIBDIR = lib
-+endif
-+
- # GNU MP configuration
--GMP_LIB := /usr/lib/libgmp.a
-+GMP_LIB := /usr/$(LIBDIR)/libgmp.a
- GMP_HEADER := /usr/include/gmp.h
-
- # sources and objects
-diff -uprN tpm_emulator-0.3/README tpm_emulator-0.3-x86_64/README
---- tpm_emulator-0.3/README 2006-01-10 04:21:45.000000000 -0800
-+++ tpm_emulator-0.3-x86_64/README 2006-05-26 11:26:02.000000000 -0700
-@@ -43,6 +43,12 @@ Example:
- GMP_LIB := /usr/lib/libgmp.a
- GMP_HEADER := /usr/include/gmp.h
-
-+GNU MP Library on 64 bit Systems
-+--------------------------------------------------------------------------
-+Some 64-bit kernels have problems with importing the user-space gmp
-+library (/usr/lib*/libgmp.a) into kernel space. These kernels will require
-+that the gmp library be recompiled for kernel space with -mcmodel=kernel.
-+
- Installation
- --------------------------------------------------------------------------
- The compilation and installation process uses the build environment for
-diff -uprN tpm_emulator-0.3/tpm/tpm_credentials.c
tpm_emulator-0.3-x86_64/tpm/tpm_credentials.c
---- tpm_emulator-0.3/tpm/tpm_credentials.c 2006-01-10 04:21:45.000000000
-0800
-+++ tpm_emulator-0.3-x86_64/tpm/tpm_credentials.c 2006-05-26
11:26:02.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3/tpm/tpm_credentials.c
tpm_emulator-0.3-x86_64/tpm/tpm_credentials.c
+--- orig/tpm_emulator-0.3/tpm/tpm_credentials.c 2006-01-10
04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_credentials.c 2006-08-29
15:07:43.530967832 -0700
@@ -47,16 +47,16 @@ int tpm_compute_pubkey_checksum(TPM_NONC
TPM_RESULT tpm_get_pubek(TPM_PUBKEY *pubEndorsementKey)
@@ -140,9 +140,9 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_cred
publicPortion->algorithmParms.algorithmID = TPM_ALG_RSA;
publicPortion->algorithmParms.encScheme = srk->encScheme;
publicPortion->algorithmParms.sigScheme = srk->sigScheme;
-diff -uprN tpm_emulator-0.3/tpm/tpm_crypto.c
tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c
---- tpm_emulator-0.3/tpm/tpm_crypto.c 2006-01-10 04:21:45.000000000 -0800
-+++ tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c 2006-05-26 11:26:02.000000000
-0700
+diff -uprN orig/tpm_emulator-0.3/tpm/tpm_crypto.c
tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c
+--- orig/tpm_emulator-0.3/tpm/tpm_crypto.c 2006-01-10 04:21:45.000000000
-0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c 2006-08-29 15:07:43.531967680
-0700
@@ -182,7 +182,8 @@ TPM_RESULT TPM_CertifyKey(TPM_KEY_HANDLE
TPM_KEY_DATA *cert, *key;
sha1_ctx_t sha1_ctx;
@@ -192,10 +192,10 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_cryp
free_TPM_KEY_PARMS(certifyInfo->algorithmParms);
return TPM_FAIL;
}
-diff -uprN tpm_emulator-0.3/tpm/tpm_data.c
tpm_emulator-0.3-x86_64/tpm/tpm_data.c
---- tpm_emulator-0.3/tpm/tpm_data.c 2006-01-10 04:21:45.000000000 -0800
-+++ tpm_emulator-0.3-x86_64/tpm/tpm_data.c 2006-05-26 11:26:02.000000000
-0700
-@@ -214,7 +214,7 @@ static int read_from_file(uint8_t **data
+diff -uprN orig/tpm_emulator-0.3/tpm/tpm_data.c
tpm_emulator-0.3-x86_64/tpm/tpm_data.c
+--- orig/tpm_emulator-0.3/tpm/tpm_data.c 2006-01-10 04:21:45.000000000
-0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_data.c 2006-08-29 15:08:20.535342312
-0700
+@@ -214,23 +214,30 @@ static int read_from_file(uint8_t **data
int tpm_store_permanent_data(void)
{
uint8_t *buf, *ptr;
@@ -203,8 +203,35 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_data
+ UINT32 buf_length, len;
/* marshal data */
- buf_length = len = sizeof_TPM_STCLEAR_FLAGS(tpmData.stclear.flags)
-@@ -242,13 +242,14 @@ int tpm_store_permanent_data(void)
+- buf_length = len = sizeof_TPM_STCLEAR_FLAGS(tpmData.stclear.flags)
+- + sizeof_TPM_PERMANENT_FLAGS(tpmData.permanent.flags) + 2
+- + sizeof_TPM_PERMANENT_DATA(tpmData.permanent.data);
++ buf_length = len = 4 + sizeof_TPM_STCLEAR_FLAGS(tpmData.stclear.flags)
++ + sizeof_TPM_PERMANENT_FLAGS(tpmData.permanent.flags)
++ + sizeof_TPM_STANY_FLAGS(tpmData.stany.flags) + 2
++ + sizeof_TPM_STCLEAR_DATA(tpmData.stclear.data)
++ + sizeof_TPM_PERMANENT_DATA(tpmData.permanent.data)
++ + sizeof_TPM_STANY_DATA(tpmData.stany.data);
+ buf = ptr = tpm_malloc(buf_length);
+ if (buf == NULL
+ || tpm_marshal_TPM_VERSION(&ptr, &len, &tpmData.permanent.data.version)
+ || tpm_marshal_TPM_STCLEAR_FLAGS(&ptr, &len, &tpmData.stclear.flags)
+ || tpm_marshal_TPM_PERMANENT_FLAGS(&ptr, &len, &tpmData.permanent.flags)
++ || tpm_marshal_TPM_STANY_FLAGS(&ptr, &len, &tpmData.stany.flags)
+ || tpm_marshal_BOOL(&ptr, &len,
tpmData.permanent.flags.selfTestSucceeded)
+ || tpm_marshal_BOOL(&ptr, &len, tpmData.permanent.flags.owned)
+- || tpm_marshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data))
{
++ || tpm_marshal_TPM_STCLEAR_DATA(&ptr, &len, &tpmData.stclear.data)
++ || tpm_marshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data)
++ || tpm_marshal_TPM_STANY_DATA(&ptr, &len, &tpmData.stany.data)) {
+ tpm_free(buf);
+ return -1;
+ }
++
+ if (write_to_file(buf, buf_length - len)) {
+ tpm_free(buf);
+ return -1;
+@@ -242,24 +249,29 @@ int tpm_store_permanent_data(void)
int tpm_restore_permanent_data(void)
{
uint8_t *buf, *ptr;
@@ -221,9 +248,25 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_data
/* unmarshal data */
if (tpm_unmarshal_TPM_VERSION(&ptr, &len, &ver)
|| memcmp(&ver, &tpmData.permanent.data.version, sizeof(TPM_VERSION))
-diff -uprN tpm_emulator-0.3/tpm/tpm_marshalling.c
tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.c
---- tpm_emulator-0.3/tpm/tpm_marshalling.c 2006-01-10 04:21:45.000000000
-0800
-+++ tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.c 2006-05-26
11:26:02.000000000 -0700
+ || tpm_unmarshal_TPM_STCLEAR_FLAGS(&ptr, &len, &tpmData.stclear.flags)
+ || tpm_unmarshal_TPM_PERMANENT_FLAGS(&ptr, &len,
&tpmData.permanent.flags)
++ || tpm_unmarshal_TPM_STANY_FLAGS(&ptr, &len, &tpmData.stany.flags)
+ || tpm_unmarshal_BOOL(&ptr, &len,
&tpmData.permanent.flags.selfTestSucceeded)
+ || tpm_unmarshal_BOOL(&ptr, &len, &tpmData.permanent.flags.owned)
+- || tpm_unmarshal_TPM_PERMANENT_DATA(&ptr, &len,
&tpmData.permanent.data)) {
++ || tpm_unmarshal_TPM_STCLEAR_DATA(&ptr, &len, &tpmData.stclear.data)
++ || tpm_unmarshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data)
++ || tpm_unmarshal_TPM_STANY_DATA(&ptr, &len, &tpmData.stany.data)) {
+ tpm_free(buf);
+ return -1;
+ }
++
+ tpm_free(buf);
+ return 0;
+ }
+diff -uprN orig/tpm_emulator-0.3/tpm/tpm_marshalling.c
tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.c
+--- orig/tpm_emulator-0.3/tpm/tpm_marshalling.c 2006-01-10
04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.c 2006-08-29
15:08:20.537342008 -0700
@@ -1212,7 +1212,7 @@ int tpm_unmarshal_TPM_STANY_FLAGS(BYTE *
int tpm_marshal_RSA(BYTE **ptr, UINT32 *length, rsa_private_key_t *v)
@@ -233,9 +276,92 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_mars
if (*length < sizeof_RSA((*v))) return -1;
if (v->size > 0) {
rsa_export_modulus(v, &(*ptr)[6], &m_len);
-diff -uprN tpm_emulator-0.3/tpm/tpm_owner.c
tpm_emulator-0.3-x86_64/tpm/tpm_owner.c
---- tpm_emulator-0.3/tpm/tpm_owner.c 2006-01-10 04:21:45.000000000 -0800
-+++ tpm_emulator-0.3-x86_64/tpm/tpm_owner.c 2006-05-26 11:26:02.000000000
-0700
+@@ -1356,6 +1356,66 @@ int tpm_unmarshal_TPM_PERMANENT_DATA(BYT
+ return 0;
+ }
+
++int tpm_marshal_TPM_STCLEAR_DATA(BYTE **ptr, UINT32 *length, TPM_STCLEAR_DATA
*v)
++{
++ if (tpm_marshal_TPM_STRUCTURE_TAG(ptr, length, v->tag)
++ || tpm_marshal_TPM_NONCE(ptr, length, &v->contextNonceKey)
++ || tpm_marshal_TPM_COUNT_ID(ptr, length, v->countID) ) return -1;
++
++ return 0;
++}
++
++int tpm_unmarshal_TPM_STCLEAR_DATA(BYTE **ptr, UINT32 *length,
TPM_STCLEAR_DATA *v)
++{
++ if (tpm_unmarshal_TPM_STRUCTURE_TAG(ptr, length, &v->tag)
++ || tpm_unmarshal_TPM_NONCE(ptr, length, &v->contextNonceKey)
++ || tpm_unmarshal_TPM_COUNT_ID(ptr, length, &v->countID) ) return -1;
++
++ return 0;
++}
++
++int tpm_marshal_TPM_STANY_DATA(BYTE **ptr, UINT32 *length, TPM_STANY_DATA *v)
++{
++ UINT32 i;
++ if (tpm_marshal_TPM_STRUCTURE_TAG(ptr, length, v->tag)
++ || tpm_marshal_TPM_NONCE(ptr, length, &v->contextNonceSession)
++ || tpm_marshal_TPM_DIGEST(ptr, length, &v->auditDigest)
++ || tpm_marshal_BOOL(ptr, length, v->auditSession)
++ || tpm_marshal_TPM_CURRENT_TICKS(ptr, length, &v->currentTicks)
++ || tpm_marshal_UINT32(ptr, length, v->contextCount)
++ || tpm_marshal_UINT32_ARRAY(ptr, length, v->contextList,
TPM_MAX_SESSION_LIST)) return -1;
++ for (i = 0; i < TPM_MAX_SESSIONS; i++) {
++ if (tpm_marshal_TPM_SESSION_DATA(ptr, length, &v->sessions[i])) return -1;
++ }
++ for (i = 0; i < TPM_MAX_SESSIONS_DAA; i++) {
++ if (tpm_marshal_TPM_DAA_SESSION_DATA(ptr, length, &v->sessionsDAA[i]))
return -1;
++ }
++ if (tpm_marshal_TPM_TRANSHANDLE(ptr, length, v->transExclusive)) return -1;
++
++ return 0;
++}
++
++int tpm_unmarshal_TPM_STANY_DATA(BYTE **ptr, UINT32 *length, TPM_STANY_DATA
*v)
++{
++ UINT32 i;
++ if (tpm_unmarshal_TPM_STRUCTURE_TAG(ptr, length, &v->tag)
++ || tpm_unmarshal_TPM_NONCE(ptr, length, &v->contextNonceSession)
++ || tpm_unmarshal_TPM_DIGEST(ptr, length, &v->auditDigest)
++ || tpm_unmarshal_BOOL(ptr, length, &v->auditSession)
++ || tpm_unmarshal_TPM_CURRENT_TICKS(ptr, length, &v->currentTicks)
++ || tpm_unmarshal_UINT32(ptr, length, &v->contextCount)
++ || tpm_unmarshal_UINT32_ARRAY(ptr, length, v->contextList,
TPM_MAX_SESSION_LIST)) return -1;
++ for (i = 0; i < TPM_MAX_SESSIONS; i++) {
++ if (tpm_unmarshal_TPM_SESSION_DATA(ptr, length, &v->sessions[i])) return
-1;
++ }
++ for (i = 0; i < TPM_MAX_SESSIONS_DAA; i++) {
++ if (tpm_unmarshal_TPM_DAA_SESSION_DATA(ptr, length, &v->sessionsDAA[i]))
return -1;
++ }
++ if (tpm_unmarshal_TPM_TRANSHANDLE(ptr, length, &v->transExclusive)) return
-1;
++
++ return 0;
++}
++
+ int tpm_marshal_TPM_SESSION_DATA(BYTE **ptr, UINT32 *length, TPM_SESSION_DATA
*v)
+ {
+ if (tpm_marshal_BYTE(ptr, length, v->type)
+diff -uprN orig/tpm_emulator-0.3/tpm/tpm_marshalling.h
tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.h
+--- orig/tpm_emulator-0.3/tpm/tpm_marshalling.h 2006-01-10
04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.h 2006-08-29
15:08:20.538341856 -0700
+@@ -420,6 +420,12 @@ int tpm_unmarshal_TPM_KEY_DATA(BYTE **pt
+ int tpm_marshal_TPM_PERMANENT_DATA(BYTE **ptr, UINT32 *length,
TPM_PERMANENT_DATA *);
+ int tpm_unmarshal_TPM_PERMANENT_DATA(BYTE **ptr, UINT32 *length,
TPM_PERMANENT_DATA *);
+
++int tpm_marshal_TPM_STCLEAR_DATA(BYTE **ptr, UINT32 *length, TPM_STCLEAR_DATA
*v);
++int tpm_unmarshal_TPM_STCLEAR_DATA(BYTE **ptr, UINT32 *length,
TPM_STCLEAR_DATA *v);
++
++int tpm_marshal_TPM_STANY_DATA(BYTE **ptr, UINT32 *length, TPM_STANY_DATA *v);
++int tpm_unmarshal_TPM_STANY_DATA(BYTE **ptr, UINT32 *length, TPM_STANY_DATA
*v);
++
+ int tpm_marshal_TPM_SESSION_DATA(BYTE **ptr, UINT32 *length, TPM_SESSION_DATA
*v);
+ int tpm_unmarshal_TPM_SESSION_DATA(BYTE **ptr, UINT32 *length,
TPM_SESSION_DATA *v);
+
+diff -uprN orig/tpm_emulator-0.3/tpm/tpm_owner.c
tpm_emulator-0.3-x86_64/tpm/tpm_owner.c
+--- orig/tpm_emulator-0.3/tpm/tpm_owner.c 2006-01-10 04:21:45.000000000
-0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_owner.c 2006-08-29 15:07:43.535967072
-0700
@@ -108,7 +108,7 @@ TPM_RESULT TPM_TakeOwnership(TPM_PROTOCO
TPM_RESULT res;
rsa_private_key_t *ek = &tpmData.permanent.data.endorsementKey;
@@ -255,9 +381,63 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_owne
/* setup tpmProof and set state to owned */
tpm_get_random_bytes(tpmData.permanent.data.tpmProof.nonce,
sizeof(tpmData.permanent.data.tpmProof.nonce));
-diff -uprN tpm_emulator-0.3/tpm/tpm_storage.c
tpm_emulator-0.3-x86_64/tpm/tpm_storage.c
---- tpm_emulator-0.3/tpm/tpm_storage.c 2006-01-10 04:21:45.000000000 -0800
-+++ tpm_emulator-0.3-x86_64/tpm/tpm_storage.c 2006-05-26 14:33:18.000000000
-0700
+diff -uprN orig/tpm_emulator-0.3/tpm/tpm_startup.c
tpm_emulator-0.3-x86_64/tpm/tpm_startup.c
+--- orig/tpm_emulator-0.3/tpm/tpm_startup.c 2006-01-10 04:21:45.000000000
-0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_startup.c 2006-08-29 15:08:20.538341856
-0700
+@@ -41,24 +41,29 @@ void TPM_Init(TPM_STARTUP_TYPE startupTy
+ TPM_RESULT TPM_Startup(TPM_STARTUP_TYPE startupType)
+ {
+ int i;
++ int restore_fail;
+ info("TPM_Startup(%d)", startupType);
+ if (tpmData.stany.flags.postInitialise == FALSE) return
TPM_INVALID_POSTINIT;
+- /* reset STANY_FLAGS */
+- SET_TO_ZERO(&tpmData.stany.flags);
+- tpmData.stany.flags.tag = TPM_TAG_STANY_FLAGS;
+- /* reset STANY_DATA (invalidates ALL sessions) */
+- SET_TO_ZERO(&tpmData.stany.data);
+- tpmData.stany.data.tag = TPM_TAG_STANY_DATA;
+- /* init session-context nonce */
+- SET_TO_RAND(&tpmData.stany.data.contextNonceSession);
++
++ /* try and restore state to get EK, SRK, etc */
++ restore_fail = tpm_restore_permanent_data();
++
+ /* set data and flags according to the given startup type */
+ if (startupType == TPM_ST_CLEAR) {
++ /* reset STANY_FLAGS */
++ SET_TO_ZERO(&tpmData.stany.flags);
++ tpmData.stany.flags.tag = TPM_TAG_STANY_FLAGS;
++ /* reset STANY_DATA (invalidates ALL sessions) */
++ SET_TO_ZERO(&tpmData.stany.data);
++ tpmData.stany.data.tag = TPM_TAG_STANY_DATA;
++ /* init session-context nonce */
++ SET_TO_RAND(&tpmData.stany.data.contextNonceSession);
+ /* reset PCR values */
+ for (i = 0; i < TPM_NUM_PCR; i++) {
+- if (tpmData.permanent.data.pcrAttrib[i].pcrReset)
+- SET_TO_ZERO(tpmData.permanent.data.pcrValue[i].digest);
++ if (!tpmData.permanent.data.pcrAttrib[i].pcrReset)
++ SET_TO_ZERO(&tpmData.permanent.data.pcrValue[i].digest);
+ else
+- SET_TO_0xFF(tpmData.permanent.data.pcrValue[i].digest);
++ SET_TO_0xFF(&tpmData.permanent.data.pcrValue[i].digest);
+ }
+ /* reset STCLEAR_FLAGS */
+ SET_TO_ZERO(&tpmData.stclear.flags);
+@@ -77,7 +82,8 @@ TPM_RESULT TPM_Startup(TPM_STARTUP_TYPE
+ /* init key-context nonce */
+ SET_TO_RAND(&tpmData.stclear.data.contextNonceKey);
+ } else if (startupType == TPM_ST_STATE) {
+- if (tpm_restore_permanent_data()) {
++ /* restore must have been successful for TPM_ST_STATE */
++ if (restore_fail) {
+ error("restoring permanent data failed");
+ tpmData.permanent.data.testResult = "tpm_restore_permanent_data()
failed";
+ tpmData.permanent.flags.selfTestSucceeded = FALSE;
+diff -uprN orig/tpm_emulator-0.3/tpm/tpm_storage.c
tpm_emulator-0.3-x86_64/tpm/tpm_storage.c
+--- orig/tpm_emulator-0.3/tpm/tpm_storage.c 2006-01-10 04:21:45.000000000
-0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_storage.c 2006-08-29 15:07:43.537966768
-0700
@@ -58,6 +58,7 @@ int encrypt_sealed_data(TPM_KEY_DATA *ke
BYTE *enc, UINT32 *enc_size)
{
@@ -482,3 +662,76 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_stor
if (tpm_setup_key_parms(key, &pubKey->algorithmParms) != 0) {
tpm_free(pubKey->pubKey.key);
return TPM_FAIL;
+diff -uprN orig/tpm_emulator-0.3/tpm/tpm_structures.h
tpm_emulator-0.3-x86_64/tpm/tpm_structures.h
+--- orig/tpm_emulator-0.3/tpm/tpm_structures.h 2006-01-10 04:21:45.000000000
-0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_structures.h 2006-08-29
15:08:20.545340792 -0700
+@@ -1723,6 +1723,7 @@ typedef struct tdTPM_DAA_ISSUER {
+ TPM_DIGEST DAA_digest_gamma;
+ BYTE DAA_generic_q[26];
+ } TPM_DAA_ISSUER;
++#define sizeof_TPM_DAA_ISSUER(s) (2 + (20 * 6) + 26 )
+
+ /*
+ * TPM_DAA_TPM ([TPM_Part2], Section 22.8)
+@@ -1738,6 +1739,7 @@ typedef struct tdTPM_DAA_TPM {
+ TPM_DIGEST DAA_rekey;
+ UINT32 DAA_count;
+ } TPM_DAA_TPM;
++#define sizeof_TPM_DAA_TPM(s) (2 + (4 * 20) + 4)
+
+ /*
+ * TPM_DAA_CONTEXT ([TPM_Part2], Section 22.9)
+@@ -1752,6 +1754,7 @@ typedef struct tdTPM_DAA_CONTEXT {
+ BYTE DAA_scratch[256];
+ BYTE DAA_stage;
+ } TPM_DAA_CONTEXT;
++#define sizeof_TPM_DAA_CONTEXT(s) (2 + (3 * 20) + 256 + 1)
+
+ /*
+ * TPM_DAA_JOINDATA ([TPM_Part2], Section 22.10)
+@@ -1763,6 +1766,7 @@ typedef struct tdTPM_DAA_JOINDATA {
+ BYTE DAA_join_u1[138]; /* WATCH: 138 (v1.2 rev 85) */
+ TPM_DIGEST DAA_digest_n0;
+ } TPM_DAA_JOINDATA;
++#define sizeof_TPM_DAA_JOINDATA(s) (1 + 1 + 20)
+
+ /*
+ * TPM_DAA_BLOB ([TPM_Part2], Section 22.12)
+@@ -2033,6 +2037,7 @@ typedef struct tdTPM_STCLEAR_DATA {
+ TPM_COUNT_ID countID;
+ //UINT32 ownerReference;
+ } TPM_STCLEAR_DATA;
++#define sizeof_TPM_STCLEAR_DATA(s) (2 + 20 + 4)
+
+ /*
+ * TPM_SESSION_DATA
+@@ -2069,6 +2074,11 @@ typedef struct tdTPM_DAA_SESSION_DATA {
+ TPM_DAA_JOINDATA DAA_joinSession;
+ TPM_HANDLE handle;
+ } TPM_DAA_SESSION_DATA;
++#define sizeof_TPM_DAA_SESSION_DATA(s) ( 1 \
++ + sizeof_TPM_DAA_ISSUER(s.DAA_issuerSettings) \
++ + sizeof_TPM_DAA_TPM(s.DAA_tpmSpecific) \
++ + sizeof_TPM_DAA_CONTEXT(s.DAA_session) \
++ + sizeof_TPM_DAA_JOINDATA(s.DAA_joinSession) + 4)
+
+ /*
+ * TPM_STANY_DATA ([TPM_Part2], Section 7.6)
+@@ -2095,6 +2105,17 @@ typedef struct tdTPM_STANY_DATA {
+ TPM_DAA_SESSION_DATA sessionsDAA[TPM_MAX_SESSIONS_DAA];
+ TPM_TRANSHANDLE transExclusive;
+ } TPM_STANY_DATA;
++#define sizeof_TPM_STANY_DATA(s) (2 + 20 + 20 + 1 \
++ + sizeof_TPM_CURRENT_TICKS(s.currentTicks) \
++ + 4 + (4 * TPM_MAX_SESSION_LIST) \
++ + (sizeof_TPM_SESSION_DATA(s.sessions[0]) * TPM_MAX_SESSION_LIST) \
++ + (sizeof_TPM_DAA_SESSION_DATA(s.sessionsDAA[0]) * TPM_MAX_SESSIONS_DAA) +
4)
++
++#define sizeof_TPM_PERMANENT_DATA(s) (2 + 4 + 4*20 \
++ + sizeof_RSA(s.endorsementKey) + TPM_ORD_MAX/8 \
++ + (1+TPM_MAX_KEYS)*sizeof_TPM_KEY_DATA(s.srk) \
++ + TPM_NUM_PCR*(sizeof_TPM_PCR_ATTRIBUTES(x)+20) \
++ + TPM_MAX_COUNTERS*sizeof_TPM_COUNTER_VALUE2(x) + 1 + 4 + 20)
+
+ /*
+ * TPM_DATA
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm/tpm_emulator.patch
--- a/tools/vtpm/tpm_emulator.patch Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm/tpm_emulator.patch Wed Jun 28 07:52:21 2006 -0600
@@ -1,68 +1,63 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
-diff -uprN orig/tpm_emulator-0.2-x86_64/AUTHORS tpm_emulator/AUTHORS
---- orig/tpm_emulator-0.2-x86_64/AUTHORS 2005-08-15 00:58:57.000000000
-0700
-+++ tpm_emulator/AUTHORS 2005-09-14 20:27:22.000000000 -0700
-@@ -1 +1,2 @@
+diff -uprN tpm_emulator-0.3-x86_64/AUTHORS tpm_emulator/AUTHORS
+--- tpm_emulator-0.3-x86_64/AUTHORS 2006-08-29 15:07:21.618299064 -0700
++++ tpm_emulator/AUTHORS 2006-08-29 15:26:17.099679656 -0700
+@@ -1,2 +1,3 @@
Mario Strasser <mast@xxxxxxx>
-+INTEL Corp <>
-diff -uprN orig/tpm_emulator-0.2-x86_64/ChangeLog tpm_emulator/ChangeLog
---- orig/tpm_emulator-0.2-x86_64/ChangeLog 2005-08-15 00:58:57.000000000
-0700
-+++ tpm_emulator/ChangeLog 2005-09-14 20:27:22.000000000 -0700
-@@ -1,3 +1,7 @@
-+2005-08-16: INTEL Corp
-+ * Set default permissions to PCRs
-+ * Changed device to /dev/tpm0
-+
- 2005-08-15 Mario Strasser <mast@xxxxxxx>
- * all: some typos corrected
- * tpm_integrity.c: bug in TPM_Extend fixed
-diff -uprN orig/tpm_emulator-0.2-x86_64/linux_module.h
tpm_emulator/linux_module.h
---- orig/tpm_emulator-0.2-x86_64/linux_module.h 2005-09-15
19:21:14.844078720 -0700
-+++ tpm_emulator/linux_module.h 2005-09-14 20:27:22.000000000 -0700
-@@ -1,5 +1,6 @@
- /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
- * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
-+ * Copyright (C) 2005 INTEL Corp.
- *
- * This module is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
-@@ -35,7 +36,7 @@
- #include "tpm_version.h"
-
- #define TPM_DEVICE_MINOR 224
--#define TPM_DEVICE_NAME "tpm"
-+#define TPM_DEVICE_NAME "tpm0"
- #define TPM_MODULE_NAME "tpm_emulator"
-
- /* debug and log output functions */
-diff -uprN orig/tpm_emulator-0.2-x86_64/Makefile tpm_emulator/Makefile
---- orig/tpm_emulator-0.2-x86_64/Makefile 2005-09-15 19:21:14.845078568
-0700
-+++ tpm_emulator/Makefile 2005-09-14 20:27:22.000000000 -0700
-@@ -1,16 +1,22 @@
+ Heiko Stamer <stamer@xxxxxxxx> [DAA]
++INTEL Corp <> [Dropped to Ring3]
+diff -uprN tpm_emulator-0.3-x86_64/ChangeLog tpm_emulator/ChangeLog
+--- tpm_emulator-0.3-x86_64/ChangeLog 2006-08-29 15:07:21.618299064 -0700
++++ tpm_emulator/ChangeLog 2006-08-29 15:26:17.100679504 -0700
+@@ -1,3 +1,6 @@
++2005-08-16 Intel Corp
++ * Moved module out of kernel to run as a ring 3 app
++
+ 2005-12-24 Mario Strasser <mast@xxxxxxx>
+ * tpm_transport.c, tpm_marshalling.c, tpm_structures.h:
+ Transport session functionality added
+diff -uprN tpm_emulator-0.3-x86_64/Makefile tpm_emulator/Makefile
+--- tpm_emulator-0.3-x86_64/Makefile 2006-08-29 15:08:20.532342768 -0700
++++ tpm_emulator/Makefile 2006-08-29 15:27:39.559143912 -0700
+@@ -1,22 +1,31 @@
# Software-Based Trusted Platform Module (TPM) Emulator for Linux
# Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>
-+# Copyright (C) 2005 INTEL Corp.
++# Copyright (C) 2006 INTEL Corp.
#
- # $Id: Makefile 10 2005-04-26 20:59:50Z mast $
-
-+XEN_ROOT := ../../..
-+EUID := $(shell id -u)
-+
- # kernel settings
- KERNEL_RELEASE := $(shell uname -r)
+ # $Id: Makefile 69 2005-12-13 12:55:52Z mast $
+
+-# kernel settings
+-KERNEL_RELEASE := $(shell uname -r)
-KERNEL_BUILD := /lib/modules/$(KERNEL_RELEASE)/build
-+CUR_DIR := $(shell pwd)
-+LINUX_VERSION := $(shell cat
$(CUR_DIR)/$(XEN_ROOT)/buildconfigs/mk.linux-2.6-xen | grep "LINUX_VER" | grep
"2.6" | gawk '{ print $$3 }' )
-+KERNEL_BUILD := $(XEN_ROOT)/linux-$(LINUX_VERSION)-xen
- MOD_SUBDIR := misc
+-MOD_SUBDIR := misc
COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/)
# module settings
-MODULE_NAME := tpm_emulator
+BIN := tpm_emulator
VERSION_MAJOR := 0
- VERSION_MINOR := 2
+ VERSION_MINOR := 3
VERSION_BUILD := $(shell date +"%s")
-@@ -34,11 +38,9 @@ DIRS := . crypto tpm
+
+-# enable/disable DEBUG messages
+-EXTRA_CFLAGS += -Wall -DDEBUG -g
++# Installation program and options
++INSTALL = install
++INSTALL_PROG = $(INSTALL) -m0755
++INSTALL_DIR = $(INSTALL) -d -m0755
++
++# Xen tools installation directory
++TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
++
++CC := gcc
++CFLAGS += -g -Wall $(INCLUDE) -DDEBUG
++CFLAGS += -I. -Itpm
++
++# Is the simulator running in it's own vm?
++#CFLAGS += -DVTPM_MULTI_VM
+
+ ifeq ($(COMPILE_ARCH),x86_64)
+ LIBDIR = lib64
+@@ -34,38 +43,31 @@ DIRS := . crypto tpm
SRCS := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c))
OBJS := $(patsubst %.c, %.o, $(SRCS))
SRCS += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h))
@@ -71,29 +66,37 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
-obj-m := $(MODULE_NAME).o
-$(MODULE_NAME)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
-+obj-m := $(BIN).o
++obj-m := $(BIN)
+$(BIN)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
EXTRA_CFLAGS += -I$(src) -I$(src)/crypto -I$(src)/tpm
-@@ -49,23 +51,17 @@ all: $(src)/crypto/gmp.h $(src)/crypto/l
- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
-
- install:
+ # do not print "Entering directory ..."
+ MAKEFLAGS += --no-print-directory
+
+-all: $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version
+- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
++all: $(BIN)
++
++$(BIN): $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version $(SRCS)
$(OBJS)
++ $(CC) $(CFLAGS) $(OBJS) $(src)/crypto/libgmp.a -o $(BIN)
++
++%.o: %.c
++ $(CC) $(CFLAGS) -c $< -o $@
+
+-install:
- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules_install
- test -d /var/tpm || mkdir /var/tpm
- test -c /dev/tpm || mknod /dev/tpm c 10 224
- chmod 666 /dev/tpm
- depmod -a
-+ @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) INSTALL_MOD_PATH=$(DESTDIR)
modules_install
-+ test -d $(DESTDIR)/var/tpm || mkdir $(DESTDIR)/var/tpm
-+ test -d $(DESTDIR)/dev || mkdir $(DESTDIR)/dev
-+ test -c $(DESTDIR)/dev/tpm0 || [ $(EUID) -ne 0 ] || mknod
$(DESTDIR)/dev/tpm0 c 10 224
-+ [ $(EUID) -ne 0 ] || chmod 666 $(DESTDIR)/dev/tpm0
++install: $(BIN)
++ $(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR)
clean:
- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
- rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a
+- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
+- rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a
++ rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a $(OBJS)
-dist: $(DISTSRC)
- rm -rf $(DISTDIR)
@@ -103,25 +106,421 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
- tar -chzf $(DISTDIR).tar.gz $(DISTDIR)
- rm -rf $(DISTDIR)
+mrproper: clean
++ rm -f $(BIN) tpm_version.h
$(src)/crypto/libgmp.a:
test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB)
$(src)/crypto/libgmp.a
-diff -uprN orig/tpm_emulator-0.2-x86_64/README tpm_emulator/README
---- orig/tpm_emulator-0.2-x86_64/README 2005-08-15 00:58:57.000000000
-0700
-+++ tpm_emulator/README 2005-09-14 20:27:22.000000000 -0700
-@@ -13,7 +13,8 @@ $Id: README 8 2005-01-25 21:11:45Z jmoli
+diff -uprN tpm_emulator-0.3-x86_64/README tpm_emulator/README
+--- tpm_emulator-0.3-x86_64/README 2006-08-29 15:07:43.530967832 -0700
++++ tpm_emulator/README 2006-08-29 15:26:17.105678744 -0700
+@@ -13,7 +13,8 @@ $Id: README 78 2006-01-07 10:45:39Z mast
Copyright
--------------------------------------------------------------------------
Copyright (C) 2004 Mario Strasser <mast@xxxxxxx> and Swiss Federal
-Institute of Technology (ETH) Zurich.
+ Institute of Technology (ETH) Zurich.
-+Copyright (C) 2005
++Copyright (C) 2005 INTEL Corp
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c
tpm_emulator/tpm/tpm_data.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c 2005-09-15
19:21:14.847078264 -0700
-+++ tpm_emulator/tpm/tpm_data.c 2005-09-14 20:27:22.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/README.1st tpm_emulator/README.1st
+--- tpm_emulator-0.3-x86_64/README.1st 1969-12-31 16:00:00.000000000 -0800
++++ tpm_emulator/README.1st 2006-08-29 15:26:17.105678744 -0700
+@@ -0,0 +1 @@
++Note that you must manually create /tmp/tpm_in.fifo and /tmp/tpm_out.fifo for
this emulator to work.
+diff -uprN tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c
tpm_emulator/crypto/gmp_kernel_wrapper.c
+--- tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c 2006-08-29
15:07:43.525968592 -0700
++++ tpm_emulator/crypto/gmp_kernel_wrapper.c 2006-08-29 15:26:17.101679352
-0700
+@@ -1,5 +1,6 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
++ * Copyright (C) 2005 INTEL Corp
+ *
+ * This module is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+@@ -24,15 +25,10 @@ int __gmp_junk;
+ void __attribute__ ((regparm(0))) __gmp_assert_fail(const char *filename,
+ int linenum, const char *expr)
+ {
+- panic(KERN_CRIT TPM_MODULE_NAME "%s:%d: GNU MP assertion failed: %s\n",
++ error("%s:%d: GNU MP assertion failed: %s\n",
+ filename, linenum, expr);
+ }
+
+-void __attribute__ ((regparm(0))) abort(void)
+-{
+- panic(KERN_CRIT TPM_MODULE_NAME "GNU MP abort() was called\n");
+-}
+-
+ /* overwrite GNU MP random functions (used by mpz/millerrabin.c) */
+
+ void __attribute__ ((regparm(0))) gmp_randinit(gmp_randstate_t rstate,
+@@ -77,20 +73,19 @@ void __attribute__ ((regparm(0))) mpz_ur
+
+ void __attribute__ ((regparm(0))) *kernel_allocate(size_t size)
+ {
+- void *ret = (void*)kmalloc(size, GFP_KERNEL);
+- if (!ret) panic(KERN_CRIT TPM_MODULE_NAME
+- "GMP: cannot allocate memory (size=%Zu)\n", size);
++ void *ret = (void*)malloc(size);
++ if (!ret) error("GMP: cannot allocate memory (size=%Zu)\n", size);
+ return ret;
+ }
+
+ void __attribute__ ((regparm(0))) *kernel_reallocate(void *oldptr,
+ size_t old_size, size_t new_size)
+ {
+- void *ret = (void*)kmalloc(new_size, GFP_KERNEL);
+- if (!ret) panic(KERN_CRIT TPM_MODULE_NAME "GMP: Cannot reallocate memory "
++ void *ret = (void*)malloc(new_size);
++ if (!ret) error("GMP: Cannot reallocate memory "
+ "(old_size=%Zu new_size=%Zu)\n", old_size, new_size);
+ memcpy(ret, oldptr, old_size);
+- kfree(oldptr);
++ free(oldptr);
+ return ret;
+ }
+
+@@ -99,7 +94,7 @@ void __attribute__ ((regparm(0))) kernel
+ /* overwrite used memory */
+ if (blk_ptr != NULL) {
+ memset(blk_ptr, 0, blk_size);
+- kfree(blk_ptr);
++ free(blk_ptr);
+ }
+ }
+
+diff -uprN tpm_emulator-0.3-x86_64/crypto/rsa.c tpm_emulator/crypto/rsa.c
+--- tpm_emulator-0.3-x86_64/crypto/rsa.c 2006-08-29 15:07:21.618299064
-0700
++++ tpm_emulator/crypto/rsa.c 2006-08-29 15:26:17.102679200 -0700
+@@ -1,5 +1,6 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
++ * Copyright (C) 2005 INTEL Corp
+ *
+ * This module is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+@@ -381,7 +382,7 @@ static int encode_message(int type, uint
+ msg[0] = 0x00;
+ get_random_bytes(&msg[1], SHA1_DIGEST_LENGTH);
+ sha1_init(&ctx);
+- sha1_update(&ctx, "TCPA", 4);
++ sha1_update(&ctx, (uint8_t *) "TCPA", 4);
+ sha1_final(&ctx, &msg[1 + SHA1_DIGEST_LENGTH]);
+ memset(&msg[1 + 2 * SHA1_DIGEST_LENGTH], 0x00,
+ msg_len - data_len - 2 * SHA1_DIGEST_LENGTH - 2);
+@@ -429,7 +430,7 @@ static int decode_message(int type, uint
+ mask_generation(&msg[1], SHA1_DIGEST_LENGTH,
+ &msg[1 + SHA1_DIGEST_LENGTH], msg_len - SHA1_DIGEST_LENGTH - 1);
+ sha1_init(&ctx);
+- sha1_update(&ctx, "TCPA", 4);
++ sha1_update(&ctx, (uint8_t *) "TCPA", 4);
+ sha1_final(&ctx, &msg[1]);
+ if (memcmp(&msg[1], &msg[1 + SHA1_DIGEST_LENGTH],
+ SHA1_DIGEST_LENGTH) != 0) return -1;
+diff -uprN tpm_emulator-0.3-x86_64/linux_module.c tpm_emulator/linux_module.c
+--- tpm_emulator-0.3-x86_64/linux_module.c 2006-08-29 15:07:43.526968440
-0700
++++ tpm_emulator/linux_module.c 1969-12-31 16:00:00.000000000 -0800
+@@ -1,194 +0,0 @@
+-/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+- * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+- *
+- * This module is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published
+- * by the Free Software Foundation; either version 2 of the License,
+- * or (at your option) any later version.
+- *
+- * This module is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * $Id: linux_module.c 76 2006-01-02 22:17:58Z hstamer $
+- */
+-
+-#include <linux/module.h>
+-#include <linux/kernel.h>
+-#include <linux/init.h>
+-#include <linux/miscdevice.h>
+-#include <linux/poll.h>
+-#include "linux_module.h"
+-#include "tpm/tpm_emulator.h"
+-
+-MODULE_LICENSE("GPL");
+-MODULE_AUTHOR("Mario Strasser <mast@xxxxxxx>");
+-MODULE_DESCRIPTION("Trusted Platform Module (TPM) Emulator");
+-MODULE_SUPPORTED_DEVICE(TPM_DEVICE_NAME);
+-
+-/* module startup parameters */
+-char *startup = "save";
+-module_param(startup, charp, 0444);
+-MODULE_PARM_DESC(startup, " Sets the startup mode of the TPM. "
+- "Possible values are 'clear', 'save' (default) and 'deactivated.");
+-char *storage_file = "/var/tpm/tpm_emulator-1.2.0.2";
+-module_param(storage_file, charp, 0644);
+-MODULE_PARM_DESC(storage_file, " Sets the persistent-data storage "
+- "file of the TPM.");
+-
+-/* TPM lock */
+-static struct semaphore tpm_mutex;
+-
+-/* TPM command response */
+-static struct {
+- uint8_t *data;
+- uint32_t size;
+-} tpm_response;
+-
+-/* module state */
+-#define STATE_IS_OPEN 0
+-static uint32_t module_state;
+-
+-static int tpm_open(struct inode *inode, struct file *file)
+-{
+- debug("%s()", __FUNCTION__);
+- if (test_and_set_bit(STATE_IS_OPEN, (void*)&module_state)) return -EBUSY;
+- return 0;
+-}
+-
+-static int tpm_release(struct inode *inode, struct file *file)
+-{
+- debug("%s()", __FUNCTION__);
+- clear_bit(STATE_IS_OPEN, (void*)&module_state);
+- down(&tpm_mutex);
+- if (tpm_response.data != NULL) {
+- kfree(tpm_response.data);
+- tpm_response.data = NULL;
+- }
+- up(&tpm_mutex);
+- return 0;
+-}
+-
+-static ssize_t tpm_read(struct file *file, char *buf, size_t count, loff_t
*ppos)
+-{
+- debug("%s(%Zu)", __FUNCTION__, count);
+- down(&tpm_mutex);
+- if (tpm_response.data != NULL) {
+- count = min(count, (size_t)tpm_response.size - (size_t)*ppos);
+- count -= copy_to_user(buf, &tpm_response.data[*ppos], count);
+- *ppos += count;
+- if ((size_t)tpm_response.size == (size_t)*ppos) {
+- kfree(tpm_response.data);
+- tpm_response.data = NULL;
+- }
+- } else {
+- count = 0;
+- }
+- up(&tpm_mutex);
+- return count;
+-}
+-
+-static ssize_t tpm_write(struct file *file, const char *buf, size_t count,
loff_t *ppos)
+-{
+- debug("%s(%Zu)", __FUNCTION__, count);
+- down(&tpm_mutex);
+- *ppos = 0;
+- if (tpm_response.data != NULL) kfree(tpm_response.data);
+- if (tpm_handle_command(buf, count, &tpm_response.data,
+- &tpm_response.size) != 0) {
+- count = -EILSEQ;
+- tpm_response.data = NULL;
+- }
+- up(&tpm_mutex);
+- return count;
+-}
+-
+-#define TPMIOC_CANCEL _IO('T', 0x00)
+-#define TPMIOC_TRANSMIT _IO('T', 0x01)
+-
+-static int tpm_ioctl(struct inode *inode, struct file *file, unsigned int
cmd, unsigned long arg)
+-{
+- debug("%s(%d, %p)", __FUNCTION__, cmd, (char*)arg);
+- if (cmd == TPMIOC_TRANSMIT) {
+- uint32_t count = ntohl(*(uint32_t*)(arg + 2));
+- down(&tpm_mutex);
+- if (tpm_response.data != NULL) kfree(tpm_response.data);
+- if (tpm_handle_command((char*)arg, count, &tpm_response.data,
+- &tpm_response.size) == 0) {
+- tpm_response.size -= copy_to_user((char*)arg, tpm_response.data,
+- tpm_response.size);
+- kfree(tpm_response.data);
+- tpm_response.data = NULL;
+- } else {
+- tpm_response.size = 0;
+- tpm_response.data = NULL;
+- }
+- up(&tpm_mutex);
+- return tpm_response.size;
+- }
+- return -1;
+-}
+-
+-struct file_operations fops = {
+- .owner = THIS_MODULE,
+- .open = tpm_open,
+- .release = tpm_release,
+- .read = tpm_read,
+- .write = tpm_write,
+- .ioctl = tpm_ioctl,
+-};
+-
+-static struct miscdevice tpm_dev = {
+- .minor = TPM_DEVICE_MINOR,
+- .name = TPM_DEVICE_NAME,
+- .fops = &fops,
+-};
+-
+-int __init init_tpm_module(void)
+-{
+- int res = misc_register(&tpm_dev);
+- if (res != 0) {
+- error("misc_register() failed for minor %d\n", TPM_DEVICE_MINOR);
+- return res;
+- }
+- /* initialize variables */
+- sema_init(&tpm_mutex, 1);
+- module_state = 0;
+- tpm_response.data = NULL;
+- /* initialize TPM emulator */
+- if (!strcmp(startup, "clear")) {
+- tpm_emulator_init(1);
+- } else if (!strcmp(startup, "save")) {
+- tpm_emulator_init(2);
+- } else if (!strcmp(startup, "deactivated")) {
+- tpm_emulator_init(3);
+- } else {
+- error("invalid startup mode '%s'; must be 'clear', "
+- "'save' (default) or 'deactivated", startup);
+- misc_deregister(&tpm_dev);
+- return -EINVAL;
+- }
+- return 0;
+-}
+-
+-void __exit cleanup_tpm_module(void)
+-{
+- tpm_emulator_shutdown();
+- misc_deregister(&tpm_dev);
+- if (tpm_response.data != NULL) kfree(tpm_response.data);
+-}
+-
+-module_init(init_tpm_module);
+-module_exit(cleanup_tpm_module);
+-
+-uint64_t tpm_get_ticks(void)
+-{
+- static struct timespec old_time = {0, 0};
+- struct timespec new_time = current_kernel_time();
+- uint64_t ticks = (uint64_t)(old_time.tv_sec - new_time.tv_sec) * 1000000
+- + (old_time.tv_nsec - new_time.tv_nsec) / 1000;
+- old_time = new_time;
+- return (ticks > 0) ? ticks : 1;
+-}
+-
+diff -uprN tpm_emulator-0.3-x86_64/linux_module.h tpm_emulator/linux_module.h
+--- tpm_emulator-0.3-x86_64/linux_module.h 2006-08-29 15:07:43.527968288
-0700
++++ tpm_emulator/linux_module.h 2006-08-29 15:26:17.103679048 -0700
+@@ -1,5 +1,6 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
++ * Copyright (C) 2005 INTEL Corp
+ *
+ * This module is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+@@ -17,17 +18,22 @@
+ #ifndef _LINUX_MODULE_H_
+ #define _LINUX_MODULE_H_
+
+-#include <linux/version.h>
+-#include <linux/kernel.h>
+-#include <linux/slab.h>
++#include <malloc.h>
++#include <stdint.h>
++#include <stdio.h>
++#include <string.h>
+ #include <linux/types.h>
+-#include <linux/string.h>
+-#include <linux/random.h>
+-#include <linux/time.h>
+-#include <asm/byteorder.h>
+
+-/* module settings */
++#include <endian.h>
++#define __BYTEORDER_HAS_U64__
++#ifdef LITTLE_ENDIAN
++ #include <linux/byteorder/little_endian.h>
++#else
++ #include <linux/byteorder/big_endian.h>
++#endif
+
++/* module settings */
++#define min(A,B) ((A)<(B)?(A):(B))
+ #ifndef STR
+ #define STR(s) __STR__(s)
+ #define __STR__(s) #s
+@@ -38,35 +44,36 @@
+ #define TPM_DEVICE_NAME "tpm"
+ #define TPM_MODULE_NAME "tpm_emulator"
+
+-/* debug and log output functions */
+-
+ #ifdef DEBUG
+-#define debug(fmt, ...) printk(KERN_DEBUG "%s %s:%d: Debug: " fmt "\n", \
+- TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
++#define debug(fmt, ...) printf("TPMD: %s:%d: Debug: " fmt "\n", \
++ __FILE__, __LINE__, ## __VA_ARGS__)
+ #else
+ #define debug(fmt, ...)
+ #endif
+-#define info(fmt, ...) printk(KERN_INFO "%s %s:%d: Info: " fmt "\n", \
+- TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
+-#define error(fmt, ...) printk(KERN_ERR "%s %s:%d: Error: " fmt "\n", \
+- TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
+-#define alert(fmt, ...) printk(KERN_ALERT "%s %s:%d: Alert: " fmt "\n", \
+- TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
++#define info(fmt, ...) printf("TPMD: %s:%d: Info: " fmt "\n", \
++ __FILE__, __LINE__, ## __VA_ARGS__)
++#define error(fmt, ...) printf("TPMD: %s:%d: Error: " fmt "\n", \
++ __FILE__, __LINE__, ## __VA_ARGS__)
++#define alert(fmt, ...) printf("TPMD: %s:%d: Alert: " fmt "\n", \
++ __FILE__, __LINE__, ## __VA_ARGS__)
+
+ /* memory allocation */
+
+ static inline void *tpm_malloc(size_t size)
+ {
+- return kmalloc(size, GFP_KERNEL);
++ return malloc(size);
+ }
+
+ static inline void tpm_free(const void *ptr)
+ {
+- if (ptr != NULL) kfree(ptr);
++ if (ptr != NULL) free( (void *) ptr);
+ }
+
+ /* random numbers */
+
++//FIXME;
++void get_random_bytes(void *buf, int nbytes);
++
+ static inline void tpm_get_random_bytes(void *buf, int nbytes)
+ {
+ get_random_bytes(buf, nbytes);
+@@ -86,9 +93,9 @@ uint64_t tpm_get_ticks(void);
+ #define CPU_TO_LE16(x) __cpu_to_le16(x)
+
+ #define BE64_TO_CPU(x) __be64_to_cpu(x)
+-#define LE64_TO_CPU(x) __be64_to_cpu(x)
++#define LE64_TO_CPU(x) __le64_to_cpu(x)
+ #define BE32_TO_CPU(x) __be32_to_cpu(x)
+-#define LE32_TO_CPU(x) __be32_to_cpu(x)
++#define LE32_TO_CPU(x) __le32_to_cpu(x)
+ #define BE16_TO_CPU(x) __be16_to_cpu(x)
+ #define LE16_TO_CPU(x) __le16_to_cpu(x)
+
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_audit.c tpm_emulator/tpm/tpm_audit.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_audit.c 2006-08-29 15:07:21.620298760
-0700
++++ tpm_emulator/tpm/tpm_audit.c 2006-08-29 15:26:17.107678440 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -130,15 +529,1213 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
*
* This module is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
-@@ -85,6 +86,11 @@ void tpm_init_data(void)
- tpmData.permanent.data.version.revMinor = VERSION_MINOR;
- /* setup PCR attributes */
- for (i = 0; i < TPM_NUM_PCR; i++) {
-+ int j;
-+ for (j=0; j < TPM_NUM_LOCALITY; j++) {
-+ tpmData.permanent.data.pcrAttrib[i].pcrExtendLocal[j] = TRUE;
+@@ -45,14 +46,14 @@ void tpm_audit_request(TPM_COMMAND_CODE
+ tpmData.permanent.data.auditMonotonicCounter++;
+ }
+ /* update audit digest */
+- *((UINT16*)&buf[0]) = cpu_to_be16(TPM_TAG_AUDIT_EVENT_IN);
+- *((UINT32*)&buf[2]) = cpu_to_be32(ordinal);
++ *((UINT16*)&buf[0]) = CPU_TO_BE16(TPM_TAG_AUDIT_EVENT_IN);
++ *((UINT32*)&buf[2]) = CPU_TO_BE32(ordinal);
+ sha1_init(&sha1_ctx);
+ sha1_update(&sha1_ctx, req->param, req->paramSize);
+ sha1_final(&sha1_ctx, &buf[6]);
+- *((UINT16*)&buf[26]) = cpu_to_be16(TPM_TAG_COUNTER_VALUE);
++ *((UINT16*)&buf[26]) = CPU_TO_BE16(TPM_TAG_COUNTER_VALUE);
+ memset(&buf[30], 0, 4);
+- *((UINT32*)&buf[34]) =
cpu_to_be32(tpmData.permanent.data.auditMonotonicCounter);
++ *((UINT32*)&buf[34]) =
CPU_TO_BE32(tpmData.permanent.data.auditMonotonicCounter);
+ sha1_init(&sha1_ctx);
+ sha1_update(&sha1_ctx, tpmData.stany.data.auditDigest.digest,
+ sizeof(TPM_DIGEST));
+@@ -70,15 +71,15 @@ void tpm_audit_response(TPM_COMMAND_CODE
+ && (AUDIT_STATUS[ord / 8] & (1 << (ord & 0x07)))) {
+ info("tpm_audit_response()");
+ /* update audit digest */
+- *((UINT16*)&buf[0]) = cpu_to_be16(TPM_TAG_AUDIT_EVENT_OUT);
+- *((UINT32*)&buf[2]) = cpu_to_be32(ordinal);
++ *((UINT16*)&buf[0]) = CPU_TO_BE16(TPM_TAG_AUDIT_EVENT_OUT);
++ *((UINT32*)&buf[2]) = CPU_TO_BE32(ordinal);
+ sha1_init(&sha1_ctx);
+ sha1_update(&sha1_ctx, rsp->param, rsp->paramSize);
+ sha1_final(&sha1_ctx, &buf[6]);
+- *((UINT16*)&buf[26]) = cpu_to_be16(TPM_TAG_COUNTER_VALUE);
++ *((UINT16*)&buf[26]) = CPU_TO_BE16(TPM_TAG_COUNTER_VALUE);
+ memset(&buf[30], 0, 4);
+- *((UINT32*)&buf[34]) =
cpu_to_be32(tpmData.permanent.data.auditMonotonicCounter);
+- *((UINT32*)&buf[34]) = cpu_to_be32(rsp->result);
++ *((UINT32*)&buf[34]) =
CPU_TO_BE32(tpmData.permanent.data.auditMonotonicCounter);
++ *((UINT32*)&buf[34]) = CPU_TO_BE32(rsp->result);
+ sha1_init(&sha1_ctx);
+ sha1_update(&sha1_ctx, tpmData.stany.data.auditDigest.digest,
+ sizeof(TPM_DIGEST));
+@@ -158,7 +159,7 @@ TPM_RESULT TPM_GetAuditDigestSigned(TPM_
+ }
+ memcpy(&buf[0], "\x05\x00ADIG", 6);
+ memcpy(&buf[6], antiReplay->nonce, 20);
+- *(UINT32*)&buf[26] = cpu_to_be32(buf_size - 30);
++ *(UINT32*)&buf[26] = CPU_TO_BE32(buf_size - 30);
+ memcpy(&buf[30], auditDigest->digest, 20);
+ ptr = &buf[50];
+ len = buf_size - 50;
+@@ -198,4 +199,3 @@ TPM_RESULT TPM_SetOrdinalAuditStatus(TPM
+ }
+ return TPM_SUCCESS;
+ }
+-
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c
tpm_emulator/tpm/tpm_authorization.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c 2006-08-29
15:07:21.620298760 -0700
++++ tpm_emulator/tpm/tpm_authorization.c 2006-08-29 15:26:17.108678288
-0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+ * Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+ *
+ * This module is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+@@ -279,7 +280,7 @@ TPM_RESULT tpm_verify_auth(TPM_AUTH *aut
+ {
+ hmac_ctx_t ctx;
+ TPM_SESSION_DATA *session;
+- UINT32 auth_handle = cpu_to_be32(auth->authHandle);
++ UINT32 auth_handle = CPU_TO_BE32(auth->authHandle);
+
+ info("tpm_verify_auth(%08x)", auth->authHandle);
+ /* get dedicated authorization or transport session */
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_capability.c
tpm_emulator/tpm/tpm_capability.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_capability.c 2006-08-29
15:07:21.620298760 -0700
++++ tpm_emulator/tpm/tpm_capability.c 2006-08-29 15:26:17.109678136 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+ * Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+ *
+ * This module is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+@@ -406,7 +407,7 @@ TPM_RESULT TPM_GetCapability(TPM_CAPABIL
+
+ case TPM_CAP_KEY_HANDLE:
+ debug("[TPM_CAP_KEY_HANDLE]");
+- subCapSize = cpu_to_be32(TPM_RT_KEY);
++ subCapSize = CPU_TO_BE32(TPM_RT_KEY);
+ return cap_handle(4, (BYTE*)&subCapSize, respSize, resp);
+
+ case TPM_CAP_CHECK_LOADED:
+@@ -480,4 +481,3 @@ TPM_RESULT TPM_GetCapability(TPM_CAPABIL
+ return TPM_BAD_MODE;
+ }
+ }
+-
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c
tpm_emulator/tpm/tpm_cmd_handler.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c 2006-08-29
15:07:21.621298608 -0700
++++ tpm_emulator/tpm/tpm_cmd_handler.c 2006-08-29 15:26:17.113677528 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+ * Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+ *
+ * This module is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+@@ -73,7 +74,7 @@ void tpm_compute_in_param_digest(TPM_REQ
+ {
+ sha1_ctx_t sha1;
+ UINT32 offset = tpm_get_param_offset(req->ordinal);
+- UINT32 ord = cpu_to_be32(req->ordinal);
++ UINT32 ord = CPU_TO_BE32(req->ordinal);
+
+ /* compute SHA1 hash */
+ if (offset <= req->paramSize) {
+@@ -89,8 +90,8 @@ void tpm_compute_in_param_digest(TPM_REQ
+ void tpm_compute_out_param_digest(TPM_COMMAND_CODE ordinal, TPM_RESPONSE *rsp)
+ {
+ sha1_ctx_t sha1;
+- UINT32 res = cpu_to_be32(rsp->result);
+- UINT32 ord = cpu_to_be32(ordinal);
++ UINT32 res = CPU_TO_BE32(rsp->result);
++ UINT32 ord = CPU_TO_BE32(ordinal);
+
+ /* compute SHA1 hash */
+ sha1_init(&sha1);
+@@ -3123,7 +3124,7 @@ static void tpm_setup_rsp_auth(TPM_COMMA
+ hmac_update(&hmac, rsp->auth2->digest, sizeof(rsp->auth2->digest));
+ #if 0
+ if (tpm_get_auth(rsp->auth2->authHandle)->type == TPM_ST_OIAP) {
+- UINT32 handle = cpu_to_be32(rsp->auth2->authHandle);
++ UINT32 handle = CPU_TO_BE32(rsp->auth2->authHandle);
+ hmac_update(&hmac, (BYTE*)&handle, 4);
+ }
+ #endif
+@@ -3138,7 +3139,7 @@ static void tpm_setup_rsp_auth(TPM_COMMA
+ hmac_update(&hmac, rsp->auth1->digest, sizeof(rsp->auth1->digest));
+ #if 0
+ if (tpm_get_auth(rsp->auth1->authHandle)->type == TPM_ST_OIAP) {
+- UINT32 handle = cpu_to_be32(rsp->auth1->authHandle);
++ UINT32 handle = CPU_TO_BE32(rsp->auth1->authHandle);
+ hmac_update(&hmac, (BYTE*)&handle, 4);
+ }
+ #endif
+@@ -3221,7 +3222,9 @@ extern const char *tpm_error_to_string(T
+ void tpm_execute_command(TPM_REQUEST *req, TPM_RESPONSE *rsp)
+ {
+ TPM_RESULT res;
+-
++
++ req->tag = (BYTE) req->tag; // FIXME: Why is this here
++
+ /* setup authorisation as well as response tag and size */
+ memset(rsp, 0, sizeof(*rsp));
+ switch (req->tag) {
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c
tpm_emulator/tpm/tpm_crypto.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c 2006-08-29 15:07:43.531967680
-0700
++++ tpm_emulator/tpm/tpm_crypto.c 2006-08-29 15:26:17.114677376 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+ * Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+ *
+ * This module is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+@@ -106,7 +107,7 @@ TPM_RESULT tpm_sign(TPM_KEY_DATA *key, T
+ /* setup TPM_SIGN_INFO structure */
+ memcpy(&buf[0], "\x05\x00SIGN", 6);
+ memcpy(&buf[6], auth->nonceOdd.nonce, 20);
+- *(UINT32*)&buf[26] = cpu_to_be32(areaToSignSize);
++ *(UINT32*)&buf[26] = CPU_TO_BE32(areaToSignSize);
+ memcpy(&buf[30], areaToSign, areaToSignSize);
+ if (rsa_sign(&key->key, RSA_SSA_PKCS1_SHA1,
+ buf, areaToSignSize + 30, *sig)) {
+@@ -383,4 +384,3 @@ TPM_RESULT TPM_CertifyKey2(TPM_KEY_HANDL
+ }
+ return TPM_SUCCESS;
+ }
+-
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_daa.c tpm_emulator/tpm/tpm_daa.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_daa.c 2006-08-29 15:07:21.622298456
-0700
++++ tpm_emulator/tpm/tpm_daa.c 2006-08-29 15:26:17.119676616 -0700
+@@ -700,14 +700,14 @@ info("tested until here");
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x00", 1);
++ sha1_update(&sha1, (BYTE *) "\x00", 1);
+ sha1_final(&sha1, scratch);
+ sha1_init(&sha1);
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x01", 1);
++ sha1_update(&sha1, (BYTE *) "\x01", 1);
+ sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+ mpz_init(f), mpz_init(q);
+ mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -787,14 +787,14 @@ info("tested until here");
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x00", 1);
++ sha1_update(&sha1, (BYTE *) "\x00", 1);
+ sha1_final(&sha1, scratch);
+ sha1_init(&sha1);
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x01", 1);
++ sha1_update(&sha1, (BYTE *) "\x01", 1);
+ sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+ mpz_init(f), mpz_init(q);
+ mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -1440,14 +1440,14 @@ info("tested until here");
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x00", 1);
++ sha1_update(&sha1, (BYTE *) "\x00", 1);
+ sha1_final(&sha1, scratch);
+ sha1_init(&sha1);
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x01", 1);
++ sha1_update(&sha1, (BYTE *) "\x01", 1);
+ sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+ mpz_init(f), mpz_init(q);
+ mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -1660,14 +1660,14 @@ info("tested until here");
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x00", 1);
++ sha1_update(&sha1, (BYTE *) "\x00", 1);
+ sha1_final(&sha1, scratch);
+ sha1_init(&sha1);
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x01", 1);
++ sha1_update(&sha1, (BYTE *) "\x01", 1);
+ sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+ mpz_init(f), mpz_init(q);
+ mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -1740,14 +1740,14 @@ info("tested until here");
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x00", 1);
++ sha1_update(&sha1, (BYTE *) "\x00", 1);
+ sha1_final(&sha1, scratch);
+ sha1_init(&sha1);
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x01", 1);
++ sha1_update(&sha1, (BYTE *) "\x01", 1);
+ sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+ mpz_init(f), mpz_init(q);
+ mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -2828,14 +2828,14 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x00", 1);
++ sha1_update(&sha1, (BYTE *) "\x00", 1);
+ sha1_final(&sha1, scratch);
+ sha1_init(&sha1);
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x01", 1);
++ sha1_update(&sha1, (BYTE *) "\x01", 1);
+ sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+ mpz_init(f), mpz_init(q);
+ mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -3050,7 +3050,7 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
+ sha1_init(&sha1);
+ sha1_update(&sha1, (BYTE*) &session->DAA_session.DAA_digest,
+ sizeof(session->DAA_session.DAA_digest));
+- sha1_update(&sha1, "\x01", 1);
++ sha1_update(&sha1, (BYTE *) "\x01", 1);
+ sha1_update(&sha1, inputData1, inputSize1);
+ sha1_final(&sha1, (BYTE*) &session->DAA_session.DAA_digest);
+ }
+@@ -3078,7 +3078,7 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
+ sha1_init(&sha1);
+ sha1_update(&sha1, (BYTE*) &session->DAA_session.DAA_digest,
+ sizeof(session->DAA_session.DAA_digest));
+- sha1_update(&sha1, "\x01", 1);
++ sha1_update(&sha1, (BYTE *) "\x01", 1);
+ rsa_export_modulus(&aikData->key, scratch, &size);
+ sha1_update(&sha1, scratch, size);
+ sha1_final(&sha1, (BYTE*) &session->DAA_session.DAA_digest);
+@@ -3134,14 +3134,14 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x00", 1);
++ sha1_update(&sha1, (BYTE *) "\x00", 1);
+ sha1_final(&sha1, scratch);
+ sha1_init(&sha1);
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x01", 1);
++ sha1_update(&sha1, (BYTE *) "\x01", 1);
+ sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+ mpz_init(f), mpz_init(q);
+ mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -3213,14 +3213,14 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x00", 1);
++ sha1_update(&sha1, (BYTE *) "\x00", 1);
+ sha1_final(&sha1, scratch);
+ sha1_init(&sha1);
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey,
+ sizeof(session->DAA_tpmSpecific.DAA_rekey));
+ sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
+ sizeof(session->DAA_tpmSpecific.DAA_count));
+- sha1_update(&sha1, "\x01", 1);
++ sha1_update(&sha1, (BYTE *) "\x01", 1);
+ sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+ mpz_init(f), mpz_init(q);
+ mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_data.c tpm_emulator/tpm/tpm_data.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_data.c 2006-08-29 15:08:20.535342312
-0700
++++ tpm_emulator/tpm/tpm_data.c 2006-08-29 15:26:17.121676312 -0700
+@@ -150,44 +150,43 @@ void tpm_release_data(void)
+
+ #ifdef TPM_STORE_TO_FILE
+
+-#include <linux/fs.h>
+-#include <linux/unistd.h>
+-#include <asm/uaccess.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <unistd.h>
+
+ #define TPM_STORAGE_FILE "/var/tpm/tpm_emulator-1.2." STR(VERSION_MAJOR) "."
STR(VERSION_MINOR)
+
+ static int write_to_file(uint8_t *data, size_t data_length)
+ {
+ int res;
+- struct file *fp;
+- mm_segment_t old_fs = get_fs();
+- fp = filp_open(TPM_STORAGE_FILE, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR |
S_IWUSR);
+- if (IS_ERR(fp)) return -1;
+- set_fs(get_ds());
+- res = fp->f_op->write(fp, data, data_length, &fp->f_pos);
+- set_fs(old_fs);
+- filp_close(fp, NULL);
++ int fp;
++ fp = open(TPM_STORAGE_FILE, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR |
S_IWUSR);
++ res = write(fp, data, data_length);
++ close(fp);
+ return (res == data_length) ? 0 : -1;
+ }
+
+ static int read_from_file(uint8_t **data, size_t *data_length)
+ {
+ int res;
+- struct file *fp;
+- mm_segment_t old_fs = get_fs();
+- fp = filp_open(TPM_STORAGE_FILE, O_RDONLY, 0);
+- if (IS_ERR(fp)) return -1;
+- *data_length = (size_t)fp->f_dentry->d_inode->i_size;
+- /* *data_length = i_size_read(fp->f_dentry->d_inode); */
++ int fp, file_status;
++ struct stat file_info;
++ fp = open(TPM_STORAGE_FILE, O_RDONLY, 0);
++ file_status = fstat(fp, &file_info);
++ if (file_status < 0) {
++ close(fp);
++ return -1;
++ }
++
++ *data_length = file_info.st_size;
+ *data = tpm_malloc(*data_length);
+ if (*data == NULL) {
+- filp_close(fp, NULL);
++ close(fp);
+ return -1;
+ }
+- set_fs(get_ds());
+- res = fp->f_op->read(fp, *data, *data_length, &fp->f_pos);
+- set_fs(old_fs);
+- filp_close(fp, NULL);
++ res = read(fp, *data, *data_length);
++ close(fp);
+ if (res != *data_length) {
+ tpm_free(*data);
+ return -1;
+@@ -278,7 +277,7 @@ int tpm_restore_permanent_data(void)
+
+ int tpm_erase_permanent_data(void)
+ {
+- int res = write_to_file("", 0);
++ int res = write_to_file((uint8_t *) "", 0);
+ return res;
+ }
+
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_data.c.orig
tpm_emulator/tpm/tpm_data.c.orig
+--- tpm_emulator-0.3-x86_64/tpm/tpm_data.c.orig 1969-12-31
16:00:00.000000000 -0800
++++ tpm_emulator/tpm/tpm_data.c.orig 2006-08-29 15:26:08.469991568 -0700
+@@ -0,0 +1,284 @@
++/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
++ * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
++ * Swiss Federal Institute of Technology (ETH) Zurich
++ *
++ * This module is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published
++ * by the Free Software Foundation; either version 2 of the License,
++ * or (at your option) any later version.
++ *
++ * This module is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * $Id: tpm_data.c 36 2005-10-26 20:31:19Z hstamer $
++ */
++
++#include "tpm_emulator.h"
++#include "tpm_structures.h"
++#include "tpm_marshalling.h"
++#include "linux_module.h"
++
++TPM_DATA tpmData;
++
++BOOL tpm_get_physical_presence(void)
++{
++ return (tpmData.stclear.flags.physicalPresence || TRUE);
++}
++
++static inline void init_pcr_attr(int pcr, BOOL reset, BYTE rl, BYTE el)
++{
++ int i;
++ tpmData.permanent.data.pcrAttrib[pcr].pcrReset = reset;
++ for (i = 0; i < TPM_NUM_LOCALITY; i++) {
++ tpmData.permanent.data.pcrAttrib[pcr].pcrResetLocal[i] = (rl & (1 << i));
++ tpmData.permanent.data.pcrAttrib[pcr].pcrExtendLocal[i] = (el & (1 << i));
++ }
++}
++
++void tpm_init_data(void)
++{
++ /* endorsement key */
++ uint8_t ek_n[] = "\xa8\xdb\xa9\x42\xa8\xf3\xb8\x06\x85\x90\x76\x93\xad\xf7"
++ "\x74\xec\x3f\xd3\x3d\x9d\xe8\x2e\xff\x15\xed\x0e\xce\x5f\x93"
++ "\x92\xeb\xd1\x96\x2b\x72\x18\x81\x79\x12\x9d\x9c\x40\xd7\x1a"
++ "\x21\xda\x5f\x56\xe0\xc9\x48\x31\xdd\x96\xdc\xbb\x45\xc6\x8e"
++ "\xad\x58\x23\xcb\xbe\xbb\x13\x2d\x6b\x86\xc5\x57\xf5\xdd\x48"
++ "\xc1\x3d\xcd\x4d\xda\x81\xc4\x43\x17\xaa\x05\x40\x33\x62\x0a"
++ "\x59\xdb\x28\xcd\xb5\x08\x31\xbb\x06\xf5\xf7\x71\xae\x21\xa8"
++ "\xf2\x2f\x0e\x17\x80\x5d\x9c\xdf\xaa\xe9\x89\x09\x54\x65\x2b"
++ "\x46\xfb\x9d\xb2\x00\x70\x63\x0d\x9a\x6d\x3d\x5e\x11\x78\x65"
++ "\x90\xe6\x26\xee\x77\xbe\x08\xff\x07\x60\x5a\xcc\xf1\x0a\xbd"
++ "\x44\x92\x6b\xca\xb6\xce\x66\xf9\x93\x40\xae\xf3\x3e\x53\x02"
++ "\x3c\xa6\x81\xb3\xbe\xad\x6e\x6c\xa6\xf0\xeb\xdf\xe9\xa2\x83"
++ "\x36\x0e\x52\x0d\x64\x17\xd9\xff\xa1\x74\x7c\x2b\xbc\x6a\xcc"
++ "\xe5\x4e\xb4\x52\xd9\xec\x43\xbd\x26\x6a\x2b\x19\x19\x6e\x97"
++ "\xb8\x1d\x9f\x7b\xe7\x32\x2d\xdd\x7c\x51\xc8\xe4\xf3\x02\xd4"
++ "\x7c\x90\x44\xa0\x33\x72\x81\x75\xa9\x16\x27\x5c\x00\x1d\x07"
++ "\x81\xd4\xf7\xac\xcb\xfe\xd6\x60\x03\x6f\x7a\xcc\x00\xd1\xc4"
++ "\x85\x37";
++ uint8_t ek_e[] = "\x01\x00\x01";
++ uint8_t ek_p[] = "\xd7\xea\x61\x15\x8b\xa3\x71\xdf\xa8\x74\x77\xca\x88\x95"
++ "\xd0\x76\x17\x43\x2c\xf6\x23\x27\x44\xb9\x0e\x18\x35\x7e\xe4"
++ "\xc3\xcb\x13\x6e\xfc\x38\x02\x1e\x77\x26\x40\x9d\x17\xb2\x39"
++ "\x9c\x7f\x5f\x98\xe6\xf2\x55\x0c\x12\x05\x4c\xb3\x51\xae\x29"
++ "\xe7\xcd\xce\x41\x0b\x28\x4d\x97\x13\x4b\x60\xc8\xd8\x70\x81"
++ "\xf9\x1c\x12\x44\xdf\x53\x0a\x87\x9d\x33\x92\x4a\x34\x69\xf0"
++ "\x70\x5e\x1b\x5d\x65\xc7\x84\x90\xa2\x62\xdf\x83\x14\x10\x69"
++ "\xe2\xa7\x18\x43\xd7\x1f\x60\xc9\x03\x8f\xd6\xa4\xce\xb2\x9d"
++ "\x40\x37\x70\x17\x4c\xe3\x69\xd4\x59";
++ uint8_t ek_q[] = "\xc8\x34\xd2\xd0\x7c\xfa\xdc\x68\xe2\x72\xd7\x92\xe2\x50"
++ "\x93\xfc\xbb\x72\x55\x4d\x6b\x7a\x0c\x0b\xcf\x87\x66\x1f\x81"
++ "\x71\xf3\x50\xcb\xaa\xe6\x43\x7e\xbe\x11\xc4\xec\x00\x53\xf4"
++ "\x78\x13\x2b\x59\x26\x4a\x9f\x91\x61\x8f\xa7\x07\x64\x11\x5a"
++ "\xf4\xaf\x9c\x9b\x5a\x5d\x69\x20\x17\x55\x74\xba\xd8\xe4\x59"
++ "\x39\x1a\x0a\x7b\x4a\x30\xf0\xc8\x7f\xd9\xaf\x72\xc5\xb6\x71"
++ "\xd1\xc0\x8b\x5b\xa2\x2e\xa7\x15\xca\x50\x75\x10\x48\x9c\x2b"
++ "\x18\xb9\x67\x8f\x5d\x64\xc3\x28\x9f\x2f\x16\x2f\x08\xda\x47"
++ "\xec\x86\x43\x0c\x80\x99\x07\x34\x0f";
++ int i;
++ /* reset all data to NULL, FALSE or 0 */
++ memset(&tpmData, 0, sizeof(tpmData));
++ tpmData.permanent.data.tag = TPM_TAG_PERMANENT_DATA;
++ /* set permanent flags */
++ tpmData.permanent.flags.tag = TPM_TAG_PERMANENT_FLAGS;
++ tpmData.permanent.flags.disable = FALSE;
++ tpmData.permanent.flags.deactivated = FALSE;
++ tpmData.permanent.flags.ownership = TRUE;
++ tpmData.permanent.flags.readPubek = TRUE;
++ tpmData.permanent.flags.allowMaintenance = TRUE;
++ tpmData.permanent.flags.enableRevokeEK = TRUE;
++ /* set TPM vision */
++ tpmData.permanent.data.version.major = 1;
++ tpmData.permanent.data.version.minor = 2;
++ tpmData.permanent.data.version.revMajor = VERSION_MAJOR;
++ tpmData.permanent.data.version.revMinor = VERSION_MINOR;
++ /* setup PCR attributes */
++ for (i = 0; i < min(16, TPM_NUM_PCR); i++) {
++ init_pcr_attr(i, FALSE, 0x00, 0x1f);
++ }
++ if (TPM_NUM_PCR >= 24) {
++ init_pcr_attr(16, TRUE, 0x1f, 0x1f);
++ init_pcr_attr(17, TRUE, 0x10, 0x1c);
++ init_pcr_attr(18, TRUE, 0x10, 0x1c);
++ init_pcr_attr(19, TRUE, 0x10, 0x0c);
++ init_pcr_attr(20, TRUE, 0x14, 0x0e);
++ init_pcr_attr(21, TRUE, 0x04, 0x04);
++ init_pcr_attr(22, TRUE, 0x04, 0x04);
++ init_pcr_attr(23, TRUE, 0x1f, 0x1f);
++ }
++ for (i = 24; i < TPM_NUM_PCR; i++) {
++ init_pcr_attr(i, TRUE, 0x00, 0x00);
++ }
++ /* set tick type */
++ tpmData.permanent.data.tickType = TICK_INC;
++#ifdef TPM_GENERATE_EK
++ /* generate a new endorsement key */
++ rsa_generate_key(&tpmData.permanent.data.endorsementKey, 2048);
++#else
++ /* setup endorsement key */
++ rsa_import_key(&tpmData.permanent.data.endorsementKey,
++ RSA_MSB_FIRST, ek_n, 256, ek_e, 3, ek_p, ek_q);
++#endif
++#ifdef TPM_GENERATE_SEED_DAA
++ /* generate the DAA seed (cf. [TPM_Part2], v1.2 rev 85, Section 7.4) */
++ tpm_get_random_bytes(tpmData.permanent.data.tpmDAASeed.digest,
++ sizeof(tpmData.permanent.data.tpmDAASeed.digest));
++#else
++ /* FIXME: setup DAA seed */
++ memcpy(tpmData.permanent.data.tpmDAASeed.digest,
++ "\x77\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
++ "\x00\x00\x00\x77", 20);
++#endif
++
++ memcpy(tpmData.permanent.data.ekReset.nonce, "\xde\xad\xbe\xef", 4);
++}
++
++void tpm_release_data(void)
++{
++ int i;
++ /* release the EK, SRK as well as all other rsa keys */
++ if (tpmData.permanent.data.endorsementKey.size > 0)
++ rsa_release_private_key(&tpmData.permanent.data.endorsementKey);
++ if (tpmData.permanent.data.srk.valid)
++ rsa_release_private_key(&tpmData.permanent.data.srk.key);
++ for (i = 0; i < TPM_MAX_KEYS; i++)
++ if (tpmData.permanent.data.keys[i].valid)
++ rsa_release_private_key(&tpmData.permanent.data.keys[i].key);
++}
++
++#ifdef TPM_STORE_TO_FILE
++
++#include <linux/fs.h>
++#include <linux/unistd.h>
++#include <asm/uaccess.h>
++
++#define TPM_STORAGE_FILE "/var/tpm/tpm_emulator-1.2." STR(VERSION_MAJOR) "."
STR(VERSION_MINOR)
++
++static int write_to_file(uint8_t *data, size_t data_length)
++{
++ int res;
++ struct file *fp;
++ mm_segment_t old_fs = get_fs();
++ fp = filp_open(TPM_STORAGE_FILE, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR |
S_IWUSR);
++ if (IS_ERR(fp)) return -1;
++ set_fs(get_ds());
++ res = fp->f_op->write(fp, data, data_length, &fp->f_pos);
++ set_fs(old_fs);
++ filp_close(fp, NULL);
++ return (res == data_length) ? 0 : -1;
++}
++
++static int read_from_file(uint8_t **data, size_t *data_length)
++{
++ int res;
++ struct file *fp;
++ mm_segment_t old_fs = get_fs();
++ fp = filp_open(TPM_STORAGE_FILE, O_RDONLY, 0);
++ if (IS_ERR(fp)) return -1;
++ *data_length = (size_t)fp->f_dentry->d_inode->i_size;
++ /* *data_length = i_size_read(fp->f_dentry->d_inode); */
++ *data = tpm_malloc(*data_length);
++ if (*data == NULL) {
++ filp_close(fp, NULL);
++ return -1;
++ }
++ set_fs(get_ds());
++ res = fp->f_op->read(fp, *data, *data_length, &fp->f_pos);
++ set_fs(old_fs);
++ filp_close(fp, NULL);
++ if (res != *data_length) {
++ tpm_free(*data);
++ return -1;
++ }
++ return 0;
++}
++
++#else
++
++static int write_to_file(uint8_t *data, size_t data_length)
++{
++ info("TPM_STORE_TO_FILE disabled, no data written");
++ return 0;
++}
++
++static int read_from_file(uint8_t **data, size_t *data_length)
++{
++ info("TPM_STORE_TO_FILE disabled, no data read");
++ return 0;
++}
++
++#endif /* TPM_STORE_TO_FILE */
++
++int tpm_store_permanent_data(void)
++{
++ uint8_t *buf, *ptr;
++ UINT32 buf_length, len;
++
++ /* marshal data */
++ buf_length = len = 4 + sizeof_TPM_STCLEAR_FLAGS(tpmData.stclear.flags)
++ + sizeof_TPM_PERMANENT_FLAGS(tpmData.permanent.flags)
++ + sizeof_TPM_STANY_FLAGS(tpmData.stany.flags) + 2
++ + sizeof_TPM_STCLEAR_DATA(tpmData.stclear.data)
++ + sizeof_TPM_PERMANENT_DATA(tpmData.permanent.data)
++ + sizeof_TPM_STANY_DATA(tpmData.stany.data);
++ buf = ptr = tpm_malloc(buf_length);
++ if (buf == NULL
++ || tpm_marshal_TPM_VERSION(&ptr, &len, &tpmData.permanent.data.version)
++ || tpm_marshal_TPM_STCLEAR_FLAGS(&ptr, &len, &tpmData.stclear.flags)
++ || tpm_marshal_TPM_PERMANENT_FLAGS(&ptr, &len, &tpmData.permanent.flags)
++ || tpm_marshal_TPM_STANY_FLAGS(&ptr, &len, &tpmData.stany.flags)
++ || tpm_marshal_BOOL(&ptr, &len,
tpmData.permanent.flags.selfTestSucceeded)
++ || tpm_marshal_BOOL(&ptr, &len, tpmData.permanent.flags.owned)
++ || tpm_marshal_TPM_STCLEAR_DATA(&ptr, &len, &tpmData.stclear.data)
++ || tpm_marshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data)
++ || tpm_marshal_TPM_STANY_DATA(&ptr, &len, &tpmData.stany.data)) {
++ tpm_free(buf);
++ return -1;
++ }
++
++ if (write_to_file(buf, buf_length - len)) {
++ tpm_free(buf);
++ return -1;
++ }
++ tpm_free(buf);
++ return 0;
++}
++
++int tpm_restore_permanent_data(void)
++{
++ uint8_t *buf, *ptr;
++ size_t buf_length;
++ UINT32 len;
++ TPM_VERSION ver;
++
++ /* read data */
++ if (read_from_file(&buf, &buf_length)) return -1;
++ ptr = buf;
++ len = (uint32_t) buf_length;
++ /* unmarshal data */
++ if (tpm_unmarshal_TPM_VERSION(&ptr, &len, &ver)
++ || memcmp(&ver, &tpmData.permanent.data.version, sizeof(TPM_VERSION))
++ || tpm_unmarshal_TPM_STCLEAR_FLAGS(&ptr, &len, &tpmData.stclear.flags)
++ || tpm_unmarshal_TPM_PERMANENT_FLAGS(&ptr, &len,
&tpmData.permanent.flags)
++ || tpm_unmarshal_TPM_STANY_FLAGS(&ptr, &len, &tpmData.stany.flags)
++ || tpm_unmarshal_BOOL(&ptr, &len,
&tpmData.permanent.flags.selfTestSucceeded)
++ || tpm_unmarshal_BOOL(&ptr, &len, &tpmData.permanent.flags.owned)
++ || tpm_unmarshal_TPM_STCLEAR_DATA(&ptr, &len, &tpmData.stclear.data)
++ || tpm_unmarshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data)
++ || tpm_unmarshal_TPM_STANY_DATA(&ptr, &len, &tpmData.stany.data)) {
++ tpm_free(buf);
++ return -1;
++ }
++
++ tpm_free(buf);
++ return 0;
++}
++
++int tpm_erase_permanent_data(void)
++{
++ int res = write_to_file("", 0);
++ return res;
++}
++
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c
tpm_emulator/tpm/tpm_deprecated.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c 2006-08-29
15:07:21.622298456 -0700
++++ tpm_emulator/tpm/tpm_deprecated.c 2006-08-29 15:26:17.122676160 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+ * Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+ *
+ * This module is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+@@ -50,7 +51,7 @@ TPM_RESULT TPM_SaveKeyContext(TPM_KEY_HA
+ BYTE *ptr;
+ UINT32 len;
+ info("TPM_SaveKeyContext()");
+- res = TPM_SaveContext(keyHandle, TPM_RT_KEY, "SaveKeyContext..",
++ res = TPM_SaveContext(keyHandle, TPM_RT_KEY, (BYTE*)"SaveKeyContext..",
+ keyContextSize, &contextBlob);
+ if (res != TPM_SUCCESS) return res;
+ len = *keyContextSize;
+@@ -82,7 +83,7 @@ TPM_RESULT TPM_SaveAuthContext(TPM_AUTHH
+ BYTE *ptr;
+ UINT32 len;
+ info("TPM_SaveAuthContext()");
+- res = TPM_SaveContext(authHandle, TPM_RT_KEY, "SaveAuthContext.",
++ res = TPM_SaveContext(authHandle, TPM_RT_KEY, (BYTE*)"SaveAuthContext.",
+ authContextSize, &contextBlob);
+ if (res != TPM_SUCCESS) return res;
+ len = *authContextSize;
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h
tpm_emulator/tpm/tpm_emulator.h
+--- tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h 2006-08-29 15:07:21.648294504
-0700
++++ tpm_emulator/tpm/tpm_emulator.h 2006-08-29 15:26:17.122676160 -0700
+@@ -1,5 +1,6 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
++ * Copyright (C) 2005 INTEL Corp
+ *
+ * This module is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+@@ -22,7 +23,8 @@
+ /* TPM configuration */
+ #define TPM_STORE_TO_FILE 1
+ #undef TPM_STRONG_PERSISTENCE
+-#undef TPM_GENERATE_EK
++//#undef TPM_GENERATE_EK
++#define TPM_GENERATE_EK
+ #undef TPM_GENERATE_SEED_DAA
+
+ #define TPM_MANUFACTURER 0x4554485A /* 'ETHZ' */
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c
tpm_emulator/tpm/tpm_integrity.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c 2006-08-29
15:07:21.645294960 -0700
++++ tpm_emulator/tpm/tpm_integrity.c 2006-08-29 15:26:17.123676008 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+ * Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+ *
+ * This module is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+@@ -194,4 +195,3 @@ TPM_RESULT tpm_verify_pcr(TPM_KEY_DATA *
+ }
+ return TPM_SUCCESS;
+ }
+-
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_structures.h
tpm_emulator/tpm/tpm_structures.h
+--- tpm_emulator-0.3-x86_64/tpm/tpm_structures.h 2006-08-29
15:08:20.545340792 -0700
++++ tpm_emulator/tpm/tpm_structures.h 2006-08-29 15:26:17.125675704 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+ * Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+ *
+ * This module is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+@@ -18,7 +19,7 @@
+ #ifndef _TPM_STRUCTURES_H_
+ #define _TPM_STRUCTURES_H_
+
+-#include <linux/types.h>
++//#include <linux/types.h>
+ #include "crypto/rsa.h"
+
+ /*
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_testing.c
tpm_emulator/tpm/tpm_testing.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_testing.c 2006-08-29 15:07:21.646294808
-0700
++++ tpm_emulator/tpm/tpm_testing.c 2006-08-29 15:26:17.127675400 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+ * Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+ *
+ * This module is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+@@ -95,24 +96,24 @@ static int tpm_test_sha1(void)
+ struct {
+ uint8_t *data; uint32_t repetitions; uint8_t *digest;
+ } test_cases[] = {{
+- "abc", 1,
+-
"\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D"
++ (uint8_t*)"abc", 1,
++
(uint8_t*)"\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D"
+ }, {
+- "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
+-
"\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1"
++ (uint8_t*)"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
++
(uint8_t*)"\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1"
+ }, {
+- "a", 1000000,
+-
"\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F"
++ (uint8_t*)"a", 1000000,
++
(uint8_t*)"\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F"
+ }, {
+- "0123456701234567012345670123456701234567012345670123456701234567", 10,
+-
"\xDE\xA3\x56\xA2\xCD\xDD\x90\xC7\xA7\xEC\xED\xC5\xEB\xB5\x63\x93\x4F\x46\x04\x52"
++
(uint8_t*)"0123456701234567012345670123456701234567012345670123456701234567",
10,
++
(uint8_t*)"\xDE\xA3\x56\xA2\xCD\xDD\x90\xC7\xA7\xEC\xED\xC5\xEB\xB5\x63\x93\x4F\x46\x04\x52"
+ }};
+
+ debug("tpm_test_sha1()");
+ for (i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); i++) {
+ sha1_init(&ctx);
+ for (j = 0; j < test_cases[i].repetitions; j++)
+- sha1_update(&ctx, test_cases[i].data, strlen(test_cases[i].data));
++ sha1_update(&ctx, test_cases[i].data,
strlen((char*)test_cases[i].data));
+ sha1_final(&ctx, digest);
+ if (memcmp(digest, test_cases[i].digest, SHA1_DIGEST_LENGTH) != 0) return
-1;
+ }
+@@ -128,41 +129,41 @@ static int tpm_test_hmac(void)
+ struct {
+ uint8_t *key, key_len, *data, data_len, *digest;
+ } test_cases[] = {{
+- "\x0b", 20, "Hi There", 8,
+-
"\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00"
++ (uint8_t*)"\x0b", 20, (uint8_t*)"Hi There", 8,
++
(uint8_t*)"\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00"
+ }, {
+- "Jefe", 4, "what do ya want for nothing?", 28,
+-
"\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79"
++ (uint8_t*)"Jefe", 4, (uint8_t*)"what do ya want for nothing?", 28,
++
(uint8_t*)"\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79"
+ }, {
+- "\xaa", 20, "\xdd", 50,
+-
"\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3"
++ (uint8_t*)"\xaa", 20, (uint8_t*)"\xdd", 50,
++
(uint8_t*)"\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3"
+ }, {
+-
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+- "\x15\x16\x17\x18\x19", 25, "\xcd", 50,
+-
"\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda"
++
(uint8_t*)"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
++ "\x15\x16\x17\x18\x19", 25, (uint8_t*)"\xcd", 50,
++
(uint8_t*)"\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda"
+ }, {
+- "\x0c", 20, "Test With Truncation", 20,
+-
"\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04"
++ (uint8_t*)"\x0c", 20, (uint8_t*)"Test With Truncation", 20,
++
(uint8_t*)"\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04"
+ }, {
+- "\xaa", 80, "Test Using Larger Than Block-Size Key - Hash Key First", 54,
+-
"\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12"
++ (uint8_t*)"\xaa", 80, (uint8_t*)"Test Using Larger Than Block-Size Key -
Hash Key First", 54,
++
(uint8_t*)"\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12"
+ }, {
+- "\xaa", 80,
+- "Test Using Larger Than Block-Size Key and Larger Than One Block-Size
Data", 73,
+-
"\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91"
++ (uint8_t*)"\xaa", 80,
++ (uint8_t*)"Test Using Larger Than Block-Size Key and Larger Than One
Block-Size Data", 73,
++
(uint8_t*)"\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91"
+ }};
+
+ debug("tpm_test_hmac()");
+ for (i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); i++) {
+- if (strlen(test_cases[i].key) < test_cases[i].key_len) {
++ if (strlen((char*)test_cases[i].key) < test_cases[i].key_len) {
+ uint8_t key[test_cases[i].key_len];
+ memset(key, test_cases[i].key[0], test_cases[i].key_len);
+ hmac_init(&ctx, key, test_cases[i].key_len);
+ } else {
+ hmac_init(&ctx, test_cases[i].key, test_cases[i].key_len);
+ }
+- for (j = 0; j < test_cases[i].data_len; j += strlen(test_cases[i].data)) {
+- hmac_update(&ctx, test_cases[i].data, strlen(test_cases[i].data));
++ for (j = 0; j < test_cases[i].data_len; j +=
strlen((char*)test_cases[i].data)) {
++ hmac_update(&ctx, test_cases[i].data,
strlen((char*)test_cases[i].data));
+ }
+ hmac_final(&ctx, digest);
+ if (memcmp(digest, test_cases[i].digest, SHA1_DIGEST_LENGTH) != 0) return
-1;
+@@ -173,9 +174,9 @@ static int tpm_test_hmac(void)
+ static int tpm_test_rsa_EK(void)
+ {
+ int res = 0;
+- char *data = "RSA PKCS #1 v1.5 Test-String";
++ uint8_t *data = (uint8_t*)"RSA PKCS #1 v1.5 Test-String";
+ uint8_t buf[256];
+- size_t buf_len, data_len = strlen(data);
++ size_t buf_len, data_len = strlen((char*)data);
+ rsa_private_key_t priv_key;
+ rsa_public_key_t pub_key;
+
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c tpm_emulator/tpm/tpm_ticks.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c 2006-08-29 15:07:21.646294808
-0700
++++ tpm_emulator/tpm/tpm_ticks.c 2006-08-29 15:26:17.128675248 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+ * Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+ *
+ * This module is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+@@ -37,9 +38,7 @@ TPM_RESULT TPM_SetTickType(TPM_TICKTYPE
+ TPM_RESULT TPM_GetTicks(TPM_CURRENT_TICKS *currentTime)
+ {
+ info("TPM_GetTicks()");
+- memcpy(currentTime, &tpmData.stany.data.currentTicks,
+- sizeof(TPM_CURRENT_TICKS));
+- return TPM_SUCCESS;
++ return TPM_DISABLED_CMD;
+ }
+
+ TPM_RESULT TPM_TickStampBlob(TPM_KEY_HANDLE keyHandle, TPM_NONCE *antiReplay,
+@@ -47,61 +46,12 @@ TPM_RESULT TPM_TickStampBlob(TPM_KEY_HAN
+ TPM_CURRENT_TICKS *currentTicks,
+ UINT32 *sigSize, BYTE **sig)
+ {
+- TPM_RESULT res;
+- TPM_KEY_DATA *key;
+- BYTE *info, *p;
+- UINT32 info_length, length;
+ info("TPM_TickStampBlob()");
+- /* get key */
+- key = tpm_get_key(keyHandle);
+- if (key == NULL) return TPM_INVALID_KEYHANDLE;
+- /* verify authorization */
+- res = tpm_verify_auth(auth1, key->usageAuth, keyHandle);
+- if (res != TPM_SUCCESS) return res;
+- if (key->keyUsage != TPM_KEY_SIGNING && key->keyUsage != TPM_KEY_LEGACY
+- && key->keyUsage != TPM_KEY_IDENTITY) return TPM_INVALID_KEYUSAGE;
+- /* get current ticks */
+- TPM_GetTicks(currentTicks);
+- /* sign data using signature scheme PKCS1_SHA1 and TPM_SIGN_INFO container
*/
+- *sigSize = key->key.size >> 3;
+- *sig = tpm_malloc(*sigSize);
+- if (*sig == NULL) return TPM_FAIL;
+- /* setup TPM_SIGN_INFO structure */
+- info_length = 30 + sizeof(TPM_DIGEST) +
sizeof_TPM_CURRENT_TICKS(currentTicks);
+- info = tpm_malloc(info_length);
+- if (info == NULL) {
+- tpm_free(*sig);
+- return TPM_FAIL;
+- }
+- memcpy(&info[0], "\x05\x00TSTP", 6);
+- memcpy(&info[6], antiReplay->nonce, 20);
+- *(UINT32*)&info[26] = cpu_to_be32(20
+- + sizeof_TPM_CURRENT_TICKS(currentTicks));
+- memcpy(&info[30], digestToStamp->digest, sizeof(TPM_DIGEST));
+- p = &info[30 + sizeof(TPM_DIGEST)];
+- length = sizeof_TPM_CURRENT_TICKS(currentTicks);
+- if (tpm_marshal_TPM_CURRENT_TICKS(&p, &length, currentTicks)
+- || rsa_sign(&key->key, RSA_SSA_PKCS1_SHA1, info, info_length, *sig)) {
+- tpm_free(*sig);
+- tpm_free(info);
+- return TPM_FAIL;
+- }
+- return TPM_SUCCESS;
++ return TPM_DISABLED_CMD;
+ }
+
+ void tpm_update_ticks(void)
+ {
+- if (tpmData.stany.data.currentTicks.tag == 0) {
+- tpmData.stany.data.currentTicks.tag = TPM_TAG_CURRENT_TICKS;
+- tpmData.stany.data.currentTicks.currentTicks += tpm_get_ticks();
+- tpmData.stany.data.currentTicks.tickType =
tpmData.permanent.data.tickType;
+- tpm_get_random_bytes(tpmData.stany.data.currentTicks.tickNonce.nonce,
+- sizeof(TPM_NONCE));
+- tpmData.stany.data.currentTicks.tickRate = 1;
+- tpmData.stany.data.currentTicks.tickSecurity = TICK_SEC_NO_CHECK;
+- } else {
+- tpmData.stany.data.currentTicks.currentTicks += tpm_get_ticks();
+- }
+ }
+
+
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_transport.c
tpm_emulator/tpm/tpm_transport.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_transport.c 2006-08-29
15:07:21.647294656 -0700
++++ tpm_emulator/tpm/tpm_transport.c 2006-08-29 15:26:17.129675096 -0700
+@@ -59,7 +59,7 @@ static int decrypt_transport_auth(TPM_KE
+ static void transport_log_in(TPM_COMMAND_CODE ordinal, BYTE parameters[20],
+ BYTE pubKeyHash[20], TPM_DIGEST *transDigest)
+ {
+- UINT32 tag = cpu_to_be32(TPM_TAG_TRANSPORT_LOG_IN);
++ UINT32 tag = CPU_TO_BE32(TPM_TAG_TRANSPORT_LOG_IN);
+ BYTE *ptr, buf[sizeof_TPM_TRANSPORT_LOG_IN(x)];
+ UINT32 len = sizeof(buf);
+ sha1_ctx_t sha1;
+@@ -76,7 +76,7 @@ static void transport_log_in(TPM_COMMAND
+ static void transport_log_out(TPM_CURRENT_TICKS *currentTicks, BYTE
parameters[20],
+ TPM_MODIFIER_INDICATOR locality, TPM_DIGEST
*transDigest)
+ {
+- UINT32 tag = cpu_to_be32(TPM_TAG_TRANSPORT_LOG_OUT);
++ UINT32 tag = CPU_TO_BE32(TPM_TAG_TRANSPORT_LOG_OUT);
+ BYTE *ptr, buf[sizeof_TPM_TRANSPORT_LOG_OUT(x)];
+ UINT32 len = sizeof(buf);
+ sha1_ctx_t sha1;
+@@ -191,7 +191,7 @@ static void decrypt_wrapped_command(BYTE
+ sha1_update(&sha1, auth->nonceOdd.nonce, sizeof(auth->nonceOdd.nonce));
+ sha1_update(&sha1, "in", 2);
+ sha1_update(&sha1, secret, sizeof(TPM_SECRET));
+- j = cpu_to_be32(i);
++ j = CPU_TO_BE32(i);
+ sha1_update(&sha1, (BYTE*)&j, 4);
+ sha1_final(&sha1, mask);
+ for (j = 0; j < sizeof(mask) && buf_len > 0; j++) {
+@@ -213,7 +213,7 @@ static void encrypt_wrapped_command(BYTE
+ sha1_update(&sha1, auth->nonceOdd.nonce, sizeof(auth->nonceOdd.nonce));
+ sha1_update(&sha1, "out", 3);
+ sha1_update(&sha1, secret, sizeof(TPM_SECRET));
+- j = cpu_to_be32(i);
++ j = CPU_TO_BE32(i);
+ sha1_update(&sha1, (BYTE*)&j, 4);
+ sha1_final(&sha1, mask);
+ for (j = 0; j < sizeof(mask) && buf_len > 0; j++) {
+@@ -253,9 +253,9 @@ TPM_RESULT TPM_ExecuteTransport(UINT32 i
+ /* verify authorization */
+ tpm_compute_in_param_digest(&req);
+ sha1_init(&sha1);
+- res = cpu_to_be32(TPM_ORD_ExecuteTransport);
++ res = CPU_TO_BE32(TPM_ORD_ExecuteTransport);
+ sha1_update(&sha1, (BYTE*)&res, 4);
+- res = cpu_to_be32(inWrappedCmdSize);
++ res = CPU_TO_BE32(inWrappedCmdSize);
+ sha1_update(&sha1, (BYTE*)&res, 4);
+ sha1_update(&sha1, req.auth1.digest, sizeof(req.auth1.digest));
+ sha1_final(&sha1, auth1->digest);
+@@ -357,7 +357,7 @@ TPM_RESULT TPM_ReleaseTransportSigned(TP
+ /* setup a TPM_SIGN_INFO structure */
+ memcpy(&buf[0], "\x05\x00TRAN", 6);
+ memcpy(&buf[6], antiReplay->nonce, 20);
+- *(UINT32*)&buf[26] = cpu_to_be32(20);
++ *(UINT32*)&buf[26] = CPU_TO_BE32(20);
+ memcpy(&buf[30], session->transInternal.transDigest.digest, 20);
+ /* sign info structure */
+ res = tpm_sign(key, auth1, TRUE, buf, sizeof(buf), signature, signSize);
+diff -uprN tpm_emulator-0.3-x86_64/tpm_version.h tpm_emulator/tpm_version.h
+--- tpm_emulator-0.3-x86_64/tpm_version.h 2006-08-29 15:07:21.649294352
-0700
++++ tpm_emulator/tpm_version.h 1969-12-31 16:00:00.000000000 -0800
+@@ -1,6 +0,0 @@
+-#ifndef _TPM_VERSION_H_
+-#define _TPM_VERSION_H_
+-#define VERSION_MAJOR 0
+-#define VERSION_MINOR 3
+-#define VERSION_BUILD 1136893683
+-#endif /* _TPM_VERSION_H_ */
+diff -uprN tpm_emulator-0.3-x86_64/tpmd.c tpm_emulator/tpmd.c
+--- tpm_emulator-0.3-x86_64/tpmd.c 1969-12-31 16:00:00.000000000 -0800
++++ tpm_emulator/tpmd.c 2006-08-29 15:26:17.130674944 -0700
+@@ -0,0 +1,141 @@
++/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
++ * Copyright (C) 2005 INTEL Corp
++ *
++ * This module is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published
++ * by the Free Software Foundation; either version 2 of the License,
++ * or (at your option) any later version.
++ *
++ * This module is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <string.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <sys/time.h>
++
++#include "tpm_emulator.h"
++
++#define TPM_RX_FNAME "/tmp/tpm_in.fifo"
++#define TPM_TX_FNAME "/tmp/tpm_out.fifo"
++
++#define BUFFER_SIZE 2048
++
++static int devurandom=0;
++
++void get_random_bytes(void *buf, int nbytes) {
++
++ if (devurandom == 0) {
++ devurandom = open("/dev/urandom", O_RDONLY);
++ }
++
++ if (read(devurandom, buf, nbytes) != nbytes) {
++ printf("Can't get random number.\n");
++ exit(-1);
++ }
++}
++
++uint64_t tpm_get_ticks(void)
++{
++ //struct timeval tv;
++ //int gettimeofday(&tv, struct timezone *tz);
++ return 0;
++}
++
++int main(int argc, char **argv)
++{
++ uint8_t in[BUFFER_SIZE], *out;
++ uint32_t out_size;
++ int in_size, written;
++ int i;
++
++ int tpm_tx_fh=-1, tpm_rx_fh=-1;
++ if (argc < 2) {
++ printf("Usage: tpmd clear|save|deactivated\n" );
++ return -1;
++ }
++
++ /* initialize TPM emulator */
++ if (!strcmp(argv[1], "clear")) {
++ printf("Initializing tpm: %s\n", argv[1]);
++ tpm_emulator_init(1);
++ } else if (!strcmp(argv[1], "save")) {
++ printf("Initializing tpm: %s\n", argv[1]);
++ tpm_emulator_init(2);
++ } else if (!strcmp(argv[1], "deactivated")) {
++ printf("Initializing tpm: %s\n", argv[1]);
++ tpm_emulator_init(3);
++ } else {
++ printf("invalid startup mode '%s'; must be 'clear', "
++ "'save' (default) or 'deactivated", argv[1]);
++ return -1;
++ }
++
++ while (1) {
++abort_command:
++ if (tpm_rx_fh < 0) {
++ tpm_rx_fh = open(TPM_RX_FNAME, O_RDONLY);
+ }
-+
- tpmData.permanent.data.pcrAttrib[i].pcrReset = TRUE;
- }
- /* set tick type */
++
++ if (tpm_rx_fh < 0) {
++ printf("ERROR: failed to open devices to listen to guest.\n");
++ return -1;
++ }
++
++ if (tpm_tx_fh < 0) {
++ tpm_tx_fh = open(TPM_TX_FNAME, O_WRONLY);
++ }
++
++ if (tpm_tx_fh < 0) {
++ printf("ERROR: failed to open devices to respond to guest.\n");
++ return -1;
++ }
++
++ in_size = read(tpm_rx_fh, in, BUFFER_SIZE);
++ if (in_size < 6) { // Magic size of minium TPM command
++ printf("Recv[%d] to small: 0x", in_size);
++ if (in_size <= 0) {
++ close(tpm_rx_fh);
++ tpm_rx_fh = -1;
++ goto abort_command;
++ }
++ } else {
++ printf("Recv[%d]: 0x", in_size);
++ for (i=0; i< in_size; i++)
++ printf("%x ", in[i]);
++ printf("\n");
++ }
++
++
++ if (tpm_handle_command(in, in_size, &out, &out_size) != 0) {
++ printf("ERROR: Handler Failed.\n");
++ }
++
++ written = write(tpm_tx_fh, out, out_size);
++
++ if (written != out_size ) {
++ printf("ERROR: Part of response not written %d/%d.\nAttempt: ",
written, out_size);
++ } else {
++ printf("Sent[%Zu]: ", out_size);
++ }
++ for (i=0; i< out_size; i++)
++ printf("%x ", out[i]);
++ printf("\n");
++ tpm_free(out);
++
++ } // loop
++
++ tpm_emulator_shutdown();
++
++ close(tpm_tx_fh);
++ close(tpm_rx_fh);
++
++}
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm/vtpm.patch
--- a/tools/vtpm/vtpm.patch Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm/vtpm.patch Wed Jun 28 07:52:21 2006 -0600
@@ -1,13 +1,13 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
-diff -uprN orig/tpm_emulator-0.3-x86_64/AUTHORS vtpm/AUTHORS
---- orig/tpm_emulator-0.3-x86_64/AUTHORS 2006-01-10 04:21:45.000000000
-0800
-+++ vtpm/AUTHORS 2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/AUTHORS vtpm/AUTHORS
+--- tpm_emulator-0.3-x86_64/AUTHORS 2006-08-29 15:07:21.618299064 -0700
++++ vtpm/AUTHORS 2006-08-29 15:12:07.184886344 -0700
@@ -1,2 +1,3 @@
Mario Strasser <mast@xxxxxxx>
Heiko Stamer <stamer@xxxxxxxx> [DAA]
+INTEL Corp <> [VTPM Extensions]
-diff -uprN orig/tpm_emulator-0.3-x86_64/ChangeLog vtpm/ChangeLog
---- orig/tpm_emulator-0.3-x86_64/ChangeLog 2006-01-10 04:21:45.000000000
-0800
-+++ vtpm/ChangeLog 2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/ChangeLog vtpm/ChangeLog
+--- tpm_emulator-0.3-x86_64/ChangeLog 2006-08-29 15:07:21.618299064 -0700
++++ vtpm/ChangeLog 2006-08-29 15:12:07.185886192 -0700
@@ -1,3 +1,7 @@
+2005-08-16 Intel Corp
+ * Moved module out of kernel to run as a ring 3 app
@@ -16,9 +16,117 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
2005-12-24 Mario Strasser <mast@xxxxxxx>
* tpm_transport.c, tpm_marshalling.c, tpm_structures.h:
Transport session functionality added
-diff -uprN orig/tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c
vtpm/crypto/gmp_kernel_wrapper.c
---- orig/tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c 2006-05-30
12:28:02.000000000 -0700
-+++ vtpm/crypto/gmp_kernel_wrapper.c 2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/Makefile vtpm/Makefile
+--- tpm_emulator-0.3-x86_64/Makefile 2006-08-29 15:08:20.532342768 -0700
++++ vtpm/Makefile 2006-08-29 15:13:53.023796384 -0700
+@@ -1,22 +1,31 @@
+ # Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ # Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>
++# Copyright (C) 2006 INTEL Corp.
+ #
+ # $Id: Makefile 69 2005-12-13 12:55:52Z mast $
+
+-# kernel settings
+-KERNEL_RELEASE := $(shell uname -r)
+-KERNEL_BUILD := /lib/modules/$(KERNEL_RELEASE)/build
+-MOD_SUBDIR := misc
+ COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/)
+
+ # module settings
+-MODULE_NAME := tpm_emulator
++BIN := vtpmd
+ VERSION_MAJOR := 0
+ VERSION_MINOR := 3
+ VERSION_BUILD := $(shell date +"%s")
+
+-# enable/disable DEBUG messages
+-EXTRA_CFLAGS += -Wall -DDEBUG -g
++# Installation program and options
++INSTALL = install
++INSTALL_PROG = $(INSTALL) -m0755
++INSTALL_DIR = $(INSTALL) -d -m0755
++
++# Xen tools installation directory
++TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
++
++CC := gcc
++CFLAGS += -g -Wall $(INCLUDE) -DDEBUG
++CFLAGS += -I. -Itpm -I../../vtpm_manager/manager
++
++# Is the simulator running in it's own vm?
++#CFLAGS += -DVTPM_MULTI_VM
+
+ ifeq ($(COMPILE_ARCH),x86_64)
+ LIBDIR = lib64
+@@ -34,38 +43,31 @@ DIRS := . crypto tpm
+ SRCS := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c))
+ OBJS := $(patsubst %.c, %.o, $(SRCS))
+ SRCS += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h))
+-DISTSRC := ./README ./AUTHORS ./ChangeLog ./Makefile $(SRCS)
+-DISTDIR := tpm_emulator-$(VERSION_MAJOR).$(VERSION_MINOR)
+
+-obj-m := $(MODULE_NAME).o
+-$(MODULE_NAME)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
++obj-m := $(BIN)
++$(BIN)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
+
+ EXTRA_CFLAGS += -I$(src) -I$(src)/crypto -I$(src)/tpm
+
+ # do not print "Entering directory ..."
+ MAKEFLAGS += --no-print-directory
+
+-all: $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version
+- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
++all: $(BIN)
++
++$(BIN): $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version $(SRCS)
$(OBJS)
++ $(CC) $(CFLAGS) $(OBJS) $(src)/crypto/libgmp.a -o $(BIN)
++
++%.o: %.c
++ $(CC) $(CFLAGS) -c $< -o $@
+
+-install:
+- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules_install
+- test -d /var/tpm || mkdir /var/tpm
+- test -c /dev/tpm || mknod /dev/tpm c 10 224
+- chmod 666 /dev/tpm
+- depmod -a
++install: $(BIN)
++ $(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR)
+
+ clean:
+- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
+- rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a
++ rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a $(OBJS)
+
+-dist: $(DISTSRC)
+- rm -rf $(DISTDIR)
+- mkdir $(DISTDIR)
+- cp --parents $(DISTSRC) $(DISTDIR)/
+- rm -f $(DISTDIR)/crypto/gmp.h
+- tar -chzf $(DISTDIR).tar.gz $(DISTDIR)
+- rm -rf $(DISTDIR)
++mrproper: clean
++ rm -f $(BIN) tpm_version.h
+
+ $(src)/crypto/libgmp.a:
+ test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB)
$(src)/crypto/libgmp.a
+diff -uprN tpm_emulator-0.3-x86_64/README vtpm/README
+--- tpm_emulator-0.3-x86_64/README 2006-08-29 15:07:43.530967832 -0700
++++ vtpm/README 2006-08-29 15:12:07.190885432 -0700
+@@ -13,7 +13,8 @@ $Id: README 78 2006-01-07 10:45:39Z mast
+ Copyright
+ --------------------------------------------------------------------------
+ Copyright (C) 2004 Mario Strasser <mast@xxxxxxx> and Swiss Federal
+-Institute of Technology (ETH) Zurich.
++ Institute of Technology (ETH) Zurich.
++Copyright (C) 2005 INTEL Corp
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+diff -uprN tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c
vtpm/crypto/gmp_kernel_wrapper.c
+--- tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c 2006-08-29
15:07:43.525968592 -0700
++++ vtpm/crypto/gmp_kernel_wrapper.c 2006-08-29 15:12:07.186886040 -0700
@@ -1,5 +1,6 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -78,9 +186,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
}
}
-diff -uprN orig/tpm_emulator-0.3-x86_64/crypto/rsa.c vtpm/crypto/rsa.c
---- orig/tpm_emulator-0.3-x86_64/crypto/rsa.c 2006-01-10 04:21:45.000000000
-0800
-+++ vtpm/crypto/rsa.c 2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/crypto/rsa.c vtpm/crypto/rsa.c
+--- tpm_emulator-0.3-x86_64/crypto/rsa.c 2006-08-29 15:07:21.618299064
-0700
++++ vtpm/crypto/rsa.c 2006-08-29 15:12:07.187885888 -0700
@@ -1,5 +1,6 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -106,8 +214,8 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
sha1_final(&ctx, &msg[1]);
if (memcmp(&msg[1], &msg[1 + SHA1_DIGEST_LENGTH],
SHA1_DIGEST_LENGTH) != 0) return -1;
-diff -uprN orig/tpm_emulator-0.3-x86_64/linux_module.c vtpm/linux_module.c
---- orig/tpm_emulator-0.3-x86_64/linux_module.c 2006-05-30
12:28:02.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/linux_module.c vtpm/linux_module.c
+--- tpm_emulator-0.3-x86_64/linux_module.c 2006-08-29 15:07:43.526968440
-0700
+++ vtpm/linux_module.c 1969-12-31 16:00:00.000000000 -0800
@@ -1,194 +0,0 @@
-/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
@@ -304,9 +412,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
- return (ticks > 0) ? ticks : 1;
-}
-
-diff -uprN orig/tpm_emulator-0.3-x86_64/linux_module.h vtpm/linux_module.h
---- orig/tpm_emulator-0.3-x86_64/linux_module.h 2006-05-30
12:28:02.000000000 -0700
-+++ vtpm/linux_module.h 2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/linux_module.h vtpm/linux_module.h
+--- tpm_emulator-0.3-x86_64/linux_module.h 2006-08-29 15:07:43.527968288
-0700
++++ vtpm/linux_module.h 2006-08-29 15:12:07.189885584 -0700
@@ -1,5 +1,6 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -406,116 +514,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
#define BE16_TO_CPU(x) __be16_to_cpu(x)
#define LE16_TO_CPU(x) __le16_to_cpu(x)
-diff -uprN orig/tpm_emulator-0.3-x86_64/Makefile vtpm/Makefile
---- orig/tpm_emulator-0.3-x86_64/Makefile 2006-05-30 12:28:02.000000000
-0700
-+++ vtpm/Makefile 2006-05-30 12:23:26.000000000 -0700
-@@ -1,22 +1,31 @@
- # Software-Based Trusted Platform Module (TPM) Emulator for Linux
- # Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>
-+# Copyright (C) 2006 INTEL Corp.
- #
- # $Id: Makefile 69 2005-12-13 12:55:52Z mast $
-
--# kernel settings
--KERNEL_RELEASE := $(shell uname -r)
--KERNEL_BUILD := /lib/modules/$(KERNEL_RELEASE)/build
--MOD_SUBDIR := misc
- COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/)
-
- # module settings
--MODULE_NAME := tpm_emulator
-+BIN := vtpmd
- VERSION_MAJOR := 0
- VERSION_MINOR := 3
- VERSION_BUILD := $(shell date +"%s")
-
--# enable/disable DEBUG messages
--EXTRA_CFLAGS += -Wall -DDEBUG -g
-+# Installation program and options
-+INSTALL = install
-+INSTALL_PROG = $(INSTALL) -m0755
-+INSTALL_DIR = $(INSTALL) -d -m0755
-+
-+# Xen tools installation directory
-+TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
-+
-+CC := gcc
-+CFLAGS += -g -Wall $(INCLUDE) -DDEBUG
-+CFLAGS += -I. -Itpm -I../../vtpm_manager/manager
-+
-+# Is the simulator running in it's own vm?
-+#CFLAGS += -DVTPM_MULTI_VM
-
- ifeq ($(COMPILE_ARCH),x86_64)
- LIBDIR = lib64
-@@ -34,38 +43,31 @@ DIRS := . crypto tpm
- SRCS := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c))
- OBJS := $(patsubst %.c, %.o, $(SRCS))
- SRCS += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h))
--DISTSRC := ./README ./AUTHORS ./ChangeLog ./Makefile $(SRCS)
--DISTDIR := tpm_emulator-$(VERSION_MAJOR).$(VERSION_MINOR)
-
--obj-m := $(MODULE_NAME).o
--$(MODULE_NAME)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
-+obj-m := $(BIN)
-+$(BIN)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
-
- EXTRA_CFLAGS += -I$(src) -I$(src)/crypto -I$(src)/tpm
-
- # do not print "Entering directory ..."
- MAKEFLAGS += --no-print-directory
-
--all: $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version
-- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
-+all: $(BIN)
-+
-+$(BIN): $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version $(SRCS)
$(OBJS)
-+ $(CC) $(CFLAGS) $(OBJS) $(src)/crypto/libgmp.a -o $(BIN)
-+
-+%.o: %.c
-+ $(CC) $(CFLAGS) -c $< -o $@
-
- install:
-- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules_install
-- test -d /var/tpm || mkdir /var/tpm
-- test -c /dev/tpm || mknod /dev/tpm c 10 224
-- chmod 666 /dev/tpm
-- depmod -a
-+ $(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR)
-
- clean:
-- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
-- rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a
-+ rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a $(OBJS)
-
--dist: $(DISTSRC)
-- rm -rf $(DISTDIR)
-- mkdir $(DISTDIR)
-- cp --parents $(DISTSRC) $(DISTDIR)/
-- rm -f $(DISTDIR)/crypto/gmp.h
-- tar -chzf $(DISTDIR).tar.gz $(DISTDIR)
-- rm -rf $(DISTDIR)
-+mrproper: clean
-+ rm -f $(BIN) tpm_version.h
-
- $(src)/crypto/libgmp.a:
- test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB)
$(src)/crypto/libgmp.a
-diff -uprN orig/tpm_emulator-0.3-x86_64/README vtpm/README
---- orig/tpm_emulator-0.3-x86_64/README 2006-05-30 12:28:02.000000000
-0700
-+++ vtpm/README 2006-05-30 12:23:26.000000000 -0700
-@@ -13,7 +13,8 @@ $Id: README 78 2006-01-07 10:45:39Z mast
- Copyright
- --------------------------------------------------------------------------
- Copyright (C) 2004 Mario Strasser <mast@xxxxxxx> and Swiss Federal
--Institute of Technology (ETH) Zurich.
-+ Institute of Technology (ETH) Zurich.
-+Copyright (C) 2005 INTEL Corp
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_audit.c vtpm/tpm/tpm_audit.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_audit.c 2006-01-10
04:21:45.000000000 -0800
-+++ vtpm/tpm/tpm_audit.c 2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_audit.c vtpm/tpm/tpm_audit.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_audit.c 2006-08-29 15:07:21.620298760
-0700
++++ vtpm/tpm/tpm_audit.c 2006-08-29 15:12:07.191885280 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -578,9 +579,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
return TPM_SUCCESS;
}
-
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c
vtpm/tpm/tpm_authorization.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c 2006-01-10
04:21:45.000000000 -0800
-+++ vtpm/tpm/tpm_authorization.c 2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c
vtpm/tpm/tpm_authorization.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c 2006-08-29
15:07:21.620298760 -0700
++++ vtpm/tpm/tpm_authorization.c 2006-08-29 15:12:07.192885128 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -598,9 +599,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
info("tpm_verify_auth(%08x)", auth->authHandle);
/* get dedicated authorization or transport session */
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_capability.c
vtpm/tpm/tpm_capability.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_capability.c 2006-01-10
04:21:45.000000000 -0800
-+++ vtpm/tpm/tpm_capability.c 2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_capability.c
vtpm/tpm/tpm_capability.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_capability.c 2006-08-29
15:07:21.620298760 -0700
++++ vtpm/tpm/tpm_capability.c 2006-08-29 15:12:07.193884976 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -623,9 +624,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
}
}
-
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c
vtpm/tpm/tpm_cmd_handler.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c 2006-01-10
04:21:45.000000000 -0800
-+++ vtpm/tpm/tpm_cmd_handler.c 2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c
vtpm/tpm/tpm_cmd_handler.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c 2006-08-29
15:07:21.621298608 -0700
++++ vtpm/tpm/tpm_cmd_handler.c 2006-08-29 15:12:07.197884368 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -683,9 +684,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
/* setup authorisation as well as response tag and size */
memset(rsp, 0, sizeof(*rsp));
switch (req->tag) {
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c vtpm/tpm/tpm_crypto.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c 2006-05-30
12:28:02.000000000 -0700
-+++ vtpm/tpm/tpm_crypto.c 2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c vtpm/tpm/tpm_crypto.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c 2006-08-29 15:07:43.531967680
-0700
++++ vtpm/tpm/tpm_crypto.c 2006-08-29 15:12:07.198884216 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -708,9 +709,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
return TPM_SUCCESS;
}
-
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_daa.c vtpm/tpm/tpm_daa.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_daa.c 2006-01-10 04:21:45.000000000
-0800
-+++ vtpm/tpm/tpm_daa.c 2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_daa.c vtpm/tpm/tpm_daa.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_daa.c 2006-08-29 15:07:21.622298456
-0700
++++ vtpm/tpm/tpm_daa.c 2006-08-29 15:12:07.203883456 -0700
@@ -700,14 +700,14 @@ info("tested until here");
sizeof(session->DAA_tpmSpecific.DAA_rekey));
sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count,
@@ -865,9 +866,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
mpz_init(f), mpz_init(q);
mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_data.c vtpm/tpm/tpm_data.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_data.c 2006-05-30
12:28:02.000000000 -0700
-+++ vtpm/tpm/tpm_data.c 2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_data.c vtpm/tpm/tpm_data.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_data.c 2006-08-29 15:08:20.535342312
-0700
++++ vtpm/tpm/tpm_data.c 2006-08-29 15:12:07.206883000 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1177,7 +1178,7 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
}
#else
-@@ -267,7 +462,6 @@ int tpm_restore_permanent_data(void)
+@@ -278,7 +473,6 @@ int tpm_restore_permanent_data(void)
int tpm_erase_permanent_data(void)
{
@@ -1186,9 +1187,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
return res;
}
-
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c
vtpm/tpm/tpm_deprecated.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c 2006-01-10
04:21:45.000000000 -0800
-+++ vtpm/tpm/tpm_deprecated.c 2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c
vtpm/tpm/tpm_deprecated.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c 2006-08-29
15:07:21.622298456 -0700
++++ vtpm/tpm/tpm_deprecated.c 2006-08-29 15:12:07.207882848 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1215,9 +1216,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
authContextSize, &contextBlob);
if (res != TPM_SUCCESS) return res;
len = *authContextSize;
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h
vtpm/tpm/tpm_emulator.h
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h 2006-01-10
04:21:45.000000000 -0800
-+++ vtpm/tpm/tpm_emulator.h 2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h vtpm/tpm/tpm_emulator.h
+--- tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h 2006-08-29 15:07:21.648294504
-0700
++++ vtpm/tpm/tpm_emulator.h 2006-08-29 15:12:07.208882696 -0700
@@ -1,5 +1,6 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1235,9 +1236,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
#undef TPM_GENERATE_SEED_DAA
#define TPM_MANUFACTURER 0x4554485A /* 'ETHZ' */
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c
vtpm/tpm/tpm_integrity.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c 2006-01-10
04:21:45.000000000 -0800
-+++ vtpm/tpm/tpm_integrity.c 2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c vtpm/tpm/tpm_integrity.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c 2006-08-29
15:07:21.645294960 -0700
++++ vtpm/tpm/tpm_integrity.c 2006-08-29 15:12:07.208882696 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1251,9 +1252,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
return TPM_SUCCESS;
}
-
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_structures.h
vtpm/tpm/tpm_structures.h
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_structures.h 2006-01-10
04:21:45.000000000 -0800
-+++ vtpm/tpm/tpm_structures.h 2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_structures.h
vtpm/tpm/tpm_structures.h
+--- tpm_emulator-0.3-x86_64/tpm/tpm_structures.h 2006-08-29
15:08:20.545340792 -0700
++++ vtpm/tpm/tpm_structures.h 2006-08-29 15:12:07.211882240 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1271,9 +1272,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
#include "crypto/rsa.h"
/*
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_testing.c
vtpm/tpm/tpm_testing.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_testing.c 2006-01-10
04:21:45.000000000 -0800
-+++ vtpm/tpm/tpm_testing.c 2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_testing.c vtpm/tpm/tpm_testing.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_testing.c 2006-08-29 15:07:21.646294808
-0700
++++ vtpm/tpm/tpm_testing.c 2006-08-29 15:12:07.213881936 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1389,9 +1390,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
rsa_private_key_t priv_key;
rsa_public_key_t pub_key;
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c vtpm/tpm/tpm_ticks.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c 2006-01-10
04:21:45.000000000 -0800
-+++ vtpm/tpm/tpm_ticks.c 2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c vtpm/tpm/tpm_ticks.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c 2006-08-29 15:07:21.646294808
-0700
++++ vtpm/tpm/tpm_ticks.c 2006-08-29 15:12:07.235878592 -0700
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1474,9 +1475,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
}
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_transport.c
vtpm/tpm/tpm_transport.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_transport.c 2006-01-10
04:21:45.000000000 -0800
-+++ vtpm/tpm/tpm_transport.c 2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_transport.c vtpm/tpm/tpm_transport.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_transport.c 2006-08-29
15:07:21.647294656 -0700
++++ vtpm/tpm/tpm_transport.c 2006-08-29 15:12:07.239877984 -0700
@@ -59,7 +59,7 @@ static int decrypt_transport_auth(TPM_KE
static void transport_log_in(TPM_COMMAND_CODE ordinal, BYTE parameters[20],
BYTE pubKeyHash[20], TPM_DIGEST *transDigest)
@@ -1534,9 +1535,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
memcpy(&buf[30], session->transInternal.transDigest.digest, 20);
/* sign info structure */
res = tpm_sign(key, auth1, TRUE, buf, sizeof(buf), signature, signSize);
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpmd.c vtpm/tpmd.c
---- orig/tpm_emulator-0.3-x86_64/tpmd.c 1969-12-31 16:00:00.000000000
-0800
-+++ vtpm/tpmd.c 2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpmd.c vtpm/tpmd.c
+--- tpm_emulator-0.3-x86_64/tpmd.c 1969-12-31 16:00:00.000000000 -0800
++++ vtpm/tpmd.c 2006-08-29 15:12:07.240877832 -0700
@@ -0,0 +1,207 @@
+/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ * Copyright (C) 2005 INTEL Corp
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/Rules.mk
--- a/tools/vtpm_manager/Rules.mk Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/Rules.mk Wed Jun 28 07:52:21 2006 -0600
@@ -56,6 +56,9 @@ CFLAGS += -DLOGGING_MODULES="(BITMASK(VT
# vtpm_manager listens on fifo's rather than backend
#CFLAGS += -DDUMMY_BACKEND
+# TCS talks to fifo's rather than /dev/tpm. TPM Emulator assumed on fifos
+#CFLAGS += -DDUMMY_TPM
+
# Do not have manager launch DMs.
#CFLAGS += -DMANUAL_DM_LAUNCH
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/manager/dmictl.c
--- a/tools/vtpm_manager/manager/dmictl.c Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/manager/dmictl.c Wed Jun 28 07:52:21 2006 -0600
@@ -76,14 +76,13 @@ TPM_RESULT VTPM_Handle_New_DMI(const buf
VTPM_DMI_RESOURCE *new_dmi=NULL;
TPM_RESULT status=TPM_FAIL;
- BYTE type;
- UINT32 dmi_id, domain_id, *dmi_id_key;
+ BYTE type, startup_mode;
+ UINT32 dmi_id, *dmi_id_key=NULL;
if (param_buf == NULL) { // Assume creation of Dom 0 control
- type = 0;
- domain_id = VTPM_CTL_DM;
+ type = VTPM_TYPE_NON_MIGRATABLE;
dmi_id = VTPM_CTL_DM;
- } else if (buffer_len(param_buf) != sizeof(BYTE) + sizeof(UINT32) *2) {
+ } else if (buffer_len(param_buf) != sizeof(BYTE) + sizeof(BYTE) +
sizeof(UINT32)) {
vtpmloginfo(VTPM_LOG_VTPM, "New DMI command wrong length: %d.\n",
buffer_len(param_buf));
status = TPM_BAD_PARAMETER;
goto abort_egress;
@@ -91,13 +90,13 @@ TPM_RESULT VTPM_Handle_New_DMI(const buf
vtpm_globals->connected_dmis++; // Put this here so we don't count Dom0
BSG_UnpackList( param_buf->bytes, 3,
BSG_TYPE_BYTE, &type,
- BSG_TYPE_UINT32, &domain_id,
+ BSG_TYPE_BYTE, &startup_mode,
BSG_TYPE_UINT32, &dmi_id);
}
-
+
new_dmi = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map,
&dmi_id);
if (new_dmi == NULL) {
- vtpmloginfo(VTPM_LOG_VTPM, "Creating new DMI instance %d attached on
domain %d.\n", dmi_id, domain_id);
+ vtpmloginfo(VTPM_LOG_VTPM, "Creating new DMI instance %d attached.\n",
dmi_id );
// Brand New DMI. Initialize the persistent pieces
if ((new_dmi = (VTPM_DMI_RESOURCE *) malloc (sizeof(VTPM_DMI_RESOURCE)))
== NULL) {
status = TPM_RESOURCES;
@@ -106,32 +105,44 @@ TPM_RESULT VTPM_Handle_New_DMI(const buf
memset(new_dmi, 0, sizeof(VTPM_DMI_RESOURCE));
new_dmi->dmi_id = dmi_id;
new_dmi->connected = FALSE;
+
+ if (type != VTPM_TYPE_MIGRATED) {
+ new_dmi->dmi_type = type;
+ } else {
+ vtpmlogerror(VTPM_LOG_VTPM, "Creation of VTPM with illegal type.\n");
+ status = TPM_BAD_PARAMETER;
+ goto free_egress;
+ }
if ((dmi_id_key = (UINT32 *) malloc (sizeof(UINT32))) == NULL) {
status = TPM_RESOURCES;
- goto abort_egress;
+ goto free_egress;
}
*dmi_id_key = new_dmi->dmi_id;
// install into map
if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, new_dmi)){
- free(new_dmi);
- free(dmi_id_key);
+ vtpmlogerror(VTPM_LOG_VTPM, "Failed to insert instance into table.
Aborting.\n", dmi_id);
status = TPM_FAIL;
- goto egress;
+ goto free_egress;
}
} else
- vtpmloginfo(VTPM_LOG_VTPM, "Re-attaching DMI instance %d on domain %d
.\n", dmi_id, domain_id);
+ vtpmloginfo(VTPM_LOG_VTPM, "Re-attaching DMI instance %d.\n", dmi_id);
if (new_dmi->connected) {
vtpmlogerror(VTPM_LOG_VTPM, "Attempt to re-attach, currently attached
instance %d. Ignoring\n", dmi_id);
status = TPM_BAD_PARAMETER;
- goto egress;
- }
-
+ goto abort_egress;
+ }
+
+ if (type == VTPM_TYPE_MIGRATED) {
+ vtpmlogerror(VTPM_LOG_VTPM, "Attempt to re-attach previously migrated
instance %d without recovering first. Ignoring\n", dmi_id);
+ status = TPM_BAD_PARAMETER;
+ goto abort_egress;
+ }
+
// Initialize the Non-persistent pieces
- new_dmi->dmi_domain_id = domain_id;
new_dmi->NVMLocation = NULL;
new_dmi->TCSContext = 0;
@@ -144,9 +155,13 @@ TPM_RESULT VTPM_Handle_New_DMI(const buf
// Design specific new DMI code.
// Includes: create IPCs, Measuring DMI, and maybe launching DMI
- status = VTPM_New_DMI_Extra(new_dmi);
- goto egress;
-
+ status = VTPM_New_DMI_Extra(new_dmi, startup_mode);
+ goto egress;
+
+ free_egress: // Error that requires freeing of newly allocated dmi
+ free(new_dmi);
+ free(dmi_id_key);
+
abort_egress:
vtpmlogerror(VTPM_LOG_VTPM, "Failed to create DMI id=%d due to status=%s.
Cleaning.\n", dmi_id, tpm_get_error_name(status));
close_dmi(new_dmi );
@@ -221,7 +236,7 @@ TPM_RESULT VTPM_Handle_Delete_DMI( const
goto abort_egress;
}
- //TODO: Automatically delete file dmi_res->NVMLocation
+ //vtpm scripts delete file dmi_res->NVMLocation for us
// Close DMI first
TPMTRYRETURN(close_dmi( dmi_res ));
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/manager/securestorage.c
--- a/tools/vtpm_manager/manager/securestorage.c Wed Jun 28 07:51:52
2006 -0600
+++ b/tools/vtpm_manager/manager/securestorage.c Wed Jun 28 07:52:21
2006 -0600
@@ -190,8 +190,7 @@ TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI
long bytes_written;
buffer_t sealed_NVM;
-
- vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Save_NVMing[%d]: 0x\n", buffer_len(inbuf));
+ vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Saving %d bytes of NVM.\n",
buffer_len(inbuf));
TPMTRYRETURN( envelope_encrypt(inbuf,
&vtpm_globals->storageKey,
@@ -310,6 +309,7 @@ TPM_RESULT VTPM_SaveManagerData(void) {
UINT32 bootKeySize = buffer_len(&vtpm_globals->bootKeyWrap);
struct pack_buf_t storage_key_pack = {storageKeySize,
vtpm_globals->storageKeyWrap.bytes};
struct pack_buf_t boot_key_pack = {bootKeySize,
vtpm_globals->bootKeyWrap.bytes};
+ BYTE vtpm_manager_gen = VTPM_MANAGER_GEN;
struct hashtable_itr *dmi_itr;
VTPM_DMI_RESOURCE *dmi_res;
@@ -321,7 +321,8 @@ TPM_RESULT VTPM_SaveManagerData(void) {
boot_key_size = sizeof(UINT32) + // bootkeysize
bootKeySize; // boot key
- TPMTRYRETURN(buffer_init(&clear_flat_global, 3*sizeof(TPM_DIGEST) + // Auths
+ TPMTRYRETURN(buffer_init(&clear_flat_global,sizeof(BYTE) + // manager version
+ 3*sizeof(TPM_DIGEST) + // Auths
sizeof(UINT32) +// storagekeysize
storageKeySize, NULL) ); //
storage key
@@ -332,7 +333,8 @@ TPM_RESULT VTPM_SaveManagerData(void) {
boot_key_size = BSG_PackList(flat_boot_key, 1,
BSG_TPM_SIZE32_DATA, &boot_key_pack);
- BSG_PackList(clear_flat_global.bytes, 3,
+ BSG_PackList(clear_flat_global.bytes, 4,
+ BSG_TYPE_BYTE, &vtpm_manager_gen,
BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
BSG_TPM_SECRET, &vtpm_globals->storage_key_usage_auth,
BSG_TPM_SIZE32_DATA, &storage_key_pack);
@@ -348,7 +350,7 @@ TPM_RESULT VTPM_SaveManagerData(void) {
flat_dmis = (BYTE *) malloc(
(hashtable_count(vtpm_globals->dmi_map) - 1) * // num
DMIS (-1 for Dom0)
- (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)) ); // Per DMI info
+ (sizeof(UINT32) +sizeof(BYTE) + 2*sizeof(TPM_DIGEST)) );
// Per DMI info
dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
do {
@@ -360,8 +362,9 @@ TPM_RESULT VTPM_SaveManagerData(void) {
continue;
- flat_dmis_size += BSG_PackList( flat_dmis + flat_dmis_size, 3,
+ flat_dmis_size += BSG_PackList( flat_dmis + flat_dmis_size, 4,
BSG_TYPE_UINT32, &dmi_res->dmi_id,
+ BSG_TYPE_BYTE, &dmi_res->dmi_type,
BSG_TPM_DIGEST,
&dmi_res->NVM_measurement,
BSG_TPM_DIGEST,
&dmi_res->DMI_measurement);
@@ -408,6 +411,7 @@ TPM_RESULT VTPM_LoadManagerData(void) {
buffer_t unsealed_data;
struct pack_buf_t storage_key_pack, boot_key_pack;
UINT32 *dmi_id_key, enc_size;
+ BYTE vtpm_manager_gen;
VTPM_DMI_RESOURCE *dmi_res;
struct stat file_stat;
@@ -458,8 +462,14 @@ TPM_RESULT VTPM_LoadManagerData(void) {
&unsealed_data) );
step_size += enc_size;
+ if (*unsealed_data.bytes != VTPM_MANAGER_GEN) {
+ // Once there is more than one gen, this will include some compatability
stuff
+ vtpmlogerror(VTPM_LOG_VTPM, "Warning: Manager Data file is gen %d, which
this manager is gen %d.\n", vtpm_manager_gen, VTPM_MANAGER_GEN);
+ }
+
// Global Values needing to be saved
- BSG_UnpackList( unsealed_data.bytes, 3,
+ BSG_UnpackList( unsealed_data.bytes, 4,
+ BSG_TYPE_BYTE, &vtpm_manager_gen,
BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
BSG_TPM_SECRET, &vtpm_globals->storage_key_usage_auth,
BSG_TPM_SIZE32_DATA, &storage_key_pack);
@@ -469,7 +479,7 @@ TPM_RESULT VTPM_LoadManagerData(void) {
// Per DMI values to be saved
while ( step_size < fh_size ){
- if (fh_size - step_size < (long) (sizeof(UINT32) + 2*sizeof(TPM_DIGEST))) {
+ if (fh_size - step_size < (long) (sizeof(UINT32) + sizeof(BYTE) +
2*sizeof(TPM_DIGEST))) {
vtpmlogerror(VTPM_LOG_VTPM, "Encountered %ld extra bytes at end of
manager state.\n", fh_size-step_size);
step_size = fh_size;
} else {
@@ -478,8 +488,9 @@ TPM_RESULT VTPM_LoadManagerData(void) {
dmi_res->connected = FALSE;
- step_size += BSG_UnpackList(flat_table + step_size, 3,
+ step_size += BSG_UnpackList(flat_table + step_size, 4,
BSG_TYPE_UINT32, &dmi_res->dmi_id,
+ BSG_TYPE_BYTE, &dmi_res->dmi_type,
BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/manager/vtpm_manager.c
--- a/tools/vtpm_manager/manager/vtpm_manager.c Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/manager/vtpm_manager.c Wed Jun 28 07:52:21 2006 -0600
@@ -92,8 +92,9 @@ TPM_RESULT VTPM_Create_Manager(){
status = VTSP_ReadPubek(vtpm_globals->manager_tcs_handle, &ek_cryptoInfo);
// If we can read PubEK then there is no owner and we should take it.
+ // We use the abilty to read the pubEK to flag that the TPM is owned.
+ // FIXME: Change to just trying to take ownership and react to the status
if (status == TPM_SUCCESS) {
- vtpmloginfo(VTPM_LOG_VTPM, "Failed to readEK meaning TPM has an owner.
Creating Keys off existing SRK.\n");
TPMTRYRETURN(VTSP_TakeOwnership(vtpm_globals->manager_tcs_handle,
(const
TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth,
&SRK_AUTH,
@@ -103,6 +104,8 @@ TPM_RESULT VTPM_Create_Manager(){
TPMTRYRETURN(VTSP_DisablePubekRead(vtpm_globals->manager_tcs_handle,
(const
TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth,
&vtpm_globals->keyAuth));
+ } else {
+ vtpmloginfo(VTPM_LOG_VTPM, "Failed to readEK meaning TPM has an owner.
Creating Keys off existing SRK.\n");
}
// Generate storage key's auth
@@ -165,7 +168,7 @@ TPM_RESULT VTPM_Create_Manager(){
&vtpm_globals->bootKey,
TRUE ) );
- printf("***************************** FIXME: SAVE NEW STATE *******\n");
+ TPMTRYRETURN( VTSP_SaveState(vtpm_globals->manager_tcs_handle) );
goto egress;
abort_egress:
@@ -181,7 +184,7 @@ TPM_RESULT VTPM_Init_Manager() {
TPM_RESULT VTPM_Init_Manager() {
TPM_RESULT status = TPM_FAIL, serviceStatus;
BYTE *randomsead;
- UINT32 randomsize;
+ UINT32 randomsize=256;
if ((vtpm_globals = (VTPM_GLOBALS *) malloc(sizeof(VTPM_GLOBALS))) == NULL){
status = TPM_FAIL;
@@ -216,7 +219,7 @@ TPM_RESULT VTPM_Init_Manager() {
&vtpm_globals->keyAuth) );
vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
- // If failed, create new Manager.
+ // If failed, create new Manager.
serviceStatus = VTPM_LoadManagerData();
if (serviceStatus == TPM_IOERROR) {
vtpmloginfo(VTPM_LOG_VTPM, "Failed to read manager file. Assuming first
time initialization.\n");
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/manager/vtpm_manager.h
--- a/tools/vtpm_manager/manager/vtpm_manager.h Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/manager/vtpm_manager.h Wed Jun 28 07:52:21 2006 -0600
@@ -73,6 +73,12 @@
#define VTPM_RESTORE_CONTEXT_FAILED 4
#define VTPM_INVALID_REQUEST 5
+//*********************** Parameter Values *************************
+#define VTPM_TYPE_NON_MIGRATABLE 0x00
+#define VTPM_TYPE_MIGRATABLE 0x01
+#define VTPM_TYPE_MIGRATED 0xFF // VTPM has been migrated.
+ // VTPM can be recovered or deleted only
+
/******************* Command Parameter API *************************
VTPM Command Format
@@ -94,8 +100,8 @@ VTPM Response Format
VTPM_Open:
Input Parameters:
- Domain_type: 1 byte
- domain_id: 4 bytes
+ Domain_type: 1 byte
+ startup_mode: 1 byte // Cold Boot = 1, resume = 2, deactive = 3
instance_id: 4 bytes
Output Parameters:
None
diff -r c4b68afe97d3 -r 4b51d081378d
tools/vtpm_manager/manager/vtpm_manager_handler.c
--- a/tools/vtpm_manager/manager/vtpm_manager_handler.c Wed Jun 28 07:51:52
2006 -0600
+++ b/tools/vtpm_manager/manager/vtpm_manager_handler.c Wed Jun 28 07:52:21
2006 -0600
@@ -78,13 +78,14 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip
BOOL is_priv,
char *thread_name) {
TPM_RESULT status = TPM_FAIL; // Should never return
- UINT32 dmi, in_param_size, cmd_size, out_param_size,
out_message_size, out_message_size_full;
- BYTE *cmd_header, *in_param, *out_message;
+ UINT32 dmi, in_param_size, cmd_size, out_param_size,
out_message_size, reply_size;
+ BYTE *cmd_header=NULL, *in_param=NULL, *out_message=NULL, *reply;
buffer_t *command_buf=NULL, *result_buf=NULL;
TPM_TAG tag;
TPM_COMMAND_CODE ord;
VTPM_DMI_RESOURCE *dmi_res;
int size_read, size_write, i;
+ BOOL add_header=TRUE; // This indicates to prepend a header on result_buf
before sending
cmd_header = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV);
command_buf = (buffer_t *) malloc(sizeof(buffer_t));
@@ -100,7 +101,7 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip
// Read command header
size_read = vtpm_ipc_read(rx_ipc_h, NULL, cmd_header,
VTPM_COMMAND_HEADER_SIZE_SRV);
if (size_read > 0) {
- vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV[%d}: 0x", size_read);
+ vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV[%d]: 0x", size_read);
for (i=0; i<size_read; i++)
vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
} else {
@@ -165,6 +166,7 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip
(!dmi_res->connected) ) {
vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempted access to non-existent or
disconnected DMI %d. Aborting...\n", dmi);
status = TPM_BAD_PARAMETER;
+ goto abort_with_error;
}
if (tag == VTPM_TAG_REQ) {
@@ -176,9 +178,14 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip
status = vtpm_manager_handle_tpm_cmd(fw_tx_ipc_h, fw_rx_ipc_h,
dmi_res, cmd_header, command_buf, result_buf, thread_name);
// This means calling the DMI failed, not that the cmd failed in the
DMI
+ // Since the return will be interpretted by a TPM app, all errors are
IO_ERRORs to the app
if (status != TPM_SUCCESS) {
+ status = TPM_IOERROR;
goto abort_with_error;
}
+ // Unlike all other commands, forwarded commands yield a result_buf
that includes the DMI's status. This
+ // should be forwarded to the caller VM
+ add_header = FALSE;
} else {
// We are not supposed to forward TPM commands at all.
int i;
@@ -205,38 +212,43 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip
#ifndef VTPM_MULTI_VM
abort_with_error:
#endif
-
- // Prepend VTPM header with destination DM stamped
- out_param_size = buffer_len(result_buf);
- out_message_size = VTPM_COMMAND_HEADER_SIZE_CLT + out_param_size;
- out_message_size_full = VTPM_COMMAND_HEADER_SIZE_SRV + out_param_size;
- out_message = (BYTE *) malloc (out_message_size_full);
-
- BSG_PackList(out_message, 4,
- BSG_TYPE_UINT32, (BYTE *) &dmi,
- BSG_TPM_TAG, (BYTE *) &tag,
- BSG_TYPE_UINT32, (BYTE *) &out_message_size,
- BSG_TPM_RESULT, (BYTE *) &status);
-
- if (buffer_len(result_buf) > 0)
- memcpy(out_message + VTPM_COMMAND_HEADER_SIZE_SRV, result_buf->bytes,
out_param_size);
-
- //Note: Send message + dmi_id
- size_write = vtpm_ipc_write(tx_ipc_h, dmi_res->tx_vtpm_ipc_h, out_message,
out_message_size_full );
+
+ if (add_header) {
+ // Prepend VTPM header with destination DM stamped
+ out_param_size = buffer_len(result_buf);
+ out_message_size = VTPM_COMMAND_HEADER_SIZE_CLT + out_param_size;
+ reply_size = VTPM_COMMAND_HEADER_SIZE_SRV + out_param_size;
+ out_message = (BYTE *) malloc (reply_size);
+ reply = out_message;
+
+ BSG_PackList(out_message, 4,
+ BSG_TYPE_UINT32, (BYTE *) &dmi,
+ BSG_TPM_TAG, (BYTE *) &tag,
+ BSG_TYPE_UINT32, (BYTE *) &out_message_size,
+ BSG_TPM_RESULT, (BYTE *) &status);
+
+ if (buffer_len(result_buf) > 0)
+ memcpy(out_message + VTPM_COMMAND_HEADER_SIZE_SRV, result_buf->bytes,
out_param_size);
+ //Note: Send message + dmi_id
+ } else {
+ reply = result_buf->bytes;
+ reply_size = buffer_len(result_buf);
+ }
+ size_write = vtpm_ipc_write(tx_ipc_h, (dmi_res ? dmi_res->tx_vtpm_ipc_h :
NULL), reply, reply_size );
if (size_write > 0) {
vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT: 0x");
- for (i=0; i < out_message_size_full; i++)
- vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", out_message[i]);
+ for (i=0; i < reply_size; i++)
+ vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", reply[i]);
vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
} else {
vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s had error writing to ipc.
Aborting... \n", thread_name);
goto abort_command;
}
- free(out_message);
-
- if (size_write < (int)out_message_size_full) {
- vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s unable to write full command to
ipc (%d/%d)\n", thread_name, size_write, out_message_size_full);
+ free(out_message); out_message=NULL;
+
+ if (size_write < (int)reply_size) {
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s unable to write full command to
ipc (%d/%d)\n", thread_name, size_write, reply_size);
goto abort_command;
}
@@ -246,9 +258,7 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip
//free buffers
bzero(cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
//free(in_param); // This was converted to command_buf. No need to free
- if (command_buf != result_buf)
- buffer_free(result_buf);
-
+ buffer_free(result_buf);
buffer_free(command_buf);
// If we have a write lock, save the manager table
@@ -258,6 +268,7 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip
}
vtpm_lock_unlock();
+ add_header = TRUE; // Reset to the default
} // End while(1)
}
@@ -369,6 +380,7 @@ TPM_RESULT vtpm_manager_handle_tpm_cmd(v
dmi_cmd_size = VTPM_COMMAND_HEADER_SIZE_SRV;
size_write = vtpm_ipc_write(tx_ipc_h, dmi_res->tx_tpm_ipc_h, cmd_header,
VTPM_COMMAND_HEADER_SIZE_SRV );
if (size_write > 0) {
+ vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT (DMI): 0x");
for (i=0; i<VTPM_COMMAND_HEADER_SIZE_SRV; i++)
vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
@@ -438,7 +450,8 @@ TPM_RESULT vtpm_manager_handle_tpm_cmd(v
vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n");
}
- if (buffer_init_convert(result_buf, adj_param_size, in_param) !=
TPM_SUCCESS) {
+ if ( (buffer_init(result_buf, VTPM_COMMAND_HEADER_SIZE_SRV, cmd_header) !=
TPM_SUCCESS) ||
+ (buffer_append_raw(result_buf, adj_param_size, in_param) !=
TPM_SUCCESS) ) {
vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers.
Aborting...\n");
status = TPM_FAIL;
goto abort_with_error;
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/manager/vtpmd.c
--- a/tools/vtpm_manager/manager/vtpmd.c Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/manager/vtpmd.c Wed Jun 28 07:52:21 2006 -0600
@@ -64,14 +64,6 @@
#define VTPM_TX_HP_FNAME "/var/vtpm/fifos/to_console.fifo"
#define VTPM_RX_HP_FNAME "/var/vtpm/fifos/from_console.fifo"
-
-#define GUEST_TX_FIFO "/var/vtpm/fifos/guest-to-%d.fifo"
-#define GUEST_RX_FIFO "/var/vtpm/fifos/guest-from-all.fifo"
-
-#define VTPM_TX_FIFO "/var/vtpm/fifos/vtpm-to-%d.fifo"
-#define VTPM_RX_FIFO "/var/vtpm/fifos/vtpm-from-all.fifo"
-
-
struct vtpm_thread_params_s {
vtpm_ipc_handle_t *tx_ipc_h;
vtpm_ipc_handle_t *rx_ipc_h;
@@ -113,7 +105,7 @@ void signal_handler(int reason) {
struct sigaction ctl_c_handler;
-TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res) {
+TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res, BYTE startup_mode) {
TPM_RESULT status = TPM_SUCCESS;
int fh;
@@ -150,14 +142,14 @@ TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_R
// Measure DMI
// FIXME: This will measure DMI. Until then use a fixed DMI_Measurement
value
- // Also, this mechanism is specific to 1 VM.
+ // Also, this mechanism is specific to 1 VM architecture.
/*
fh = open(TPM_EMULATOR_PATH, O_RDONLY);
stat_ret = fstat(fh, &file_stat);
if (stat_ret == 0)
dmi_size = file_stat.st_size;
else {
- vtpmlogerror(VTPM_LOG_VTPM, "Could not open tpm_emulator!!\n");
+ vtpmlogerror(VTPM_LOG_VTPM, "Could not open vtpmd!!\n");
status = TPM_IOERROR;
goto abort_egress;
}
@@ -179,10 +171,20 @@ TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_R
status = TPM_RESOURCES;
goto abort_egress;
} else if (pid == 0) {
- if ( stat(dmi_res->NVMLocation, &file_info) == -1)
+ switch (startup_mode) {
+ case TPM_ST_CLEAR:
execl (TPM_EMULATOR_PATH, "vtmpd", "clear", dmi_id_str, NULL);
- else
+ break;
+ case TPM_ST_STATE:
execl (TPM_EMULATOR_PATH, "vtpmd", "save", dmi_id_str, NULL);
+ break;
+ case TPM_ST_DEACTIVATED:
+ execl (TPM_EMULATOR_PATH, "vtpmd", "deactivated", dmi_id_str, NULL);
+ break;
+ default:
+ status = TPM_BAD_PARAMETER;
+ goto abort_egress;
+ }
// Returning from these at all is an error.
vtpmlogerror(VTPM_LOG_VTPM, "Could not exec to launch vtpm\n");
@@ -309,7 +311,7 @@ int main(int argc, char **argv) {
be_thread_params.fw_tpm = TRUE;
be_thread_params.fw_tx_ipc_h = NULL;
be_thread_params.fw_rx_ipc_h = &rx_tpm_ipc_h;
- be_thread_params.is_priv = TRUE; //FIXME: Change when HP
is up
+ be_thread_params.is_priv = FALSE;
be_thread_params.thread_name = "Backend Listener";
dmi_thread_params.tx_ipc_h = NULL;
@@ -318,7 +320,7 @@ int main(int argc, char **argv) {
dmi_thread_params.fw_tx_ipc_h = NULL;
dmi_thread_params.fw_rx_ipc_h = NULL;
dmi_thread_params.is_priv = FALSE;
- dmi_thread_params.thread_name = "VTPM Listeners";
+ dmi_thread_params.thread_name = "VTPM Listener";
hp_thread_params.tx_ipc_h = &tx_hp_ipc_h;
hp_thread_params.rx_ipc_h = &rx_hp_ipc_h;
@@ -345,10 +347,10 @@ int main(int argc, char **argv) {
}
-// if (pthread_create(&hp_thread, NULL, vtpm_manager_thread,
&hp_thread_params) != 0) {
-// vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch HP Thread.\n");
-// exit(-1);
-// }
+ if (pthread_create(&hp_thread, NULL, vtpm_manager_thread, &hp_thread_params)
!= 0) {
+ vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch HP Thread.\n");
+ exit(-1);
+ }
//Join the other threads until exit time.
pthread_join(be_thread, NULL);
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/manager/vtpmpriv.h
--- a/tools/vtpm_manager/manager/vtpmpriv.h Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/manager/vtpmpriv.h Wed Jun 28 07:52:21 2006 -0600
@@ -40,15 +40,19 @@
#ifndef __VTPMPRIV_H__
#define __VTPMPRIV_H__
+#include "vtpm_manager.h"
#include "tcg.h"
#include "tcs.h"
#include "buffer.h"
#include "crypto.h"
#include "vtpm_ipc.h"
-#define STATE_FILE "/var/vtpm/VTPM"
-#define DMI_NVM_FILE "/var/vtpm/vtpm_dm_%d.data"
-#define VTPM_CTL_DM 0
+#define VTPM_MANAGER_GEN 2 // This is incremented when the manager's
table
+ // is changed. It's used for backwards
compatability
+
+#define STATE_FILE "/var/vtpm/VTPM"
+#define DMI_NVM_FILE "/var/vtpm/vtpm_dm_%d.data"
+#define VTPM_CTL_DM 0
// ------------------------ Private Structures -----------------------
typedef struct VTPM_DMI_RESOURCE_T {
@@ -70,6 +74,7 @@ typedef struct VTPM_DMI_RESOURCE_T {
// of NVM.
// Persistent Information about DMI
UINT32 dmi_id;
+ BYTE dmi_type;
TPM_DIGEST NVM_measurement; // Equal to the SHA1 of the blob
TPM_DIGEST DMI_measurement; // Correct measurement of the owning
DMI
} VTPM_DMI_RESOURCE;
@@ -138,7 +143,7 @@ TPM_RESULT VTPM_SaveManagerData(void);
TPM_RESULT VTPM_SaveManagerData(void);
TPM_RESULT VTPM_LoadManagerData(void);
-TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res);
+TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res, BYTE startup_mode);
TPM_RESULT VTPM_Close_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res);
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/manager/vtsp.c
--- a/tools/vtpm_manager/manager/vtsp.c Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/manager/vtsp.c Wed Jun 28 07:52:21 2006 -0600
@@ -971,6 +971,17 @@ TPM_RESULT VTSP_Unseal(const TCS_CONTEXT
return status;
}
+TPM_RESULT VTSP_SaveState( const TCS_CONTEXT_HANDLE hContext) {
+
+ vtpmloginfo(VTPM_LOG_VTSP, "Calling TPM_SaveState.\n");
+
+ TPM_RESULT status = TPM_SUCCESS;
+
+ // Call TCS
+ return ( TCSP_SaveState ( hContext ) );
+
+}
+
// Function Reaches into unsupported TCS command, beware.
TPM_RESULT VTSP_RawTransmit(const TCS_CONTEXT_HANDLE hContext,
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/manager/vtsp.h
--- a/tools/vtpm_manager/manager/vtsp.h Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/manager/vtsp.h Wed Jun 28 07:52:21 2006 -0600
@@ -118,4 +118,6 @@ TPM_RESULT VTSP_Unseal(const TCS_CONTEXT
TCS_AUTH *auth,
TCS_AUTH *dataAuth);
+TPM_RESULT VTSP_SaveState( const TCS_CONTEXT_HANDLE hContext);
+
#endif //_VTSP_H_
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/tcs/tcs.c
--- a/tools/vtpm_manager/tcs/tcs.c Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/tcs/tcs.c Wed Jun 28 07:52:21 2006 -0600
@@ -1126,6 +1126,49 @@ TPM_RESULT TCSP_ReadPubek(TCS_CONTEXT_HA
return(returnCode);
}
+
+TPM_RESULT TCSP_SaveState(TCS_CONTEXT_HANDLE hContext) // in
+{
+ // setup input/output parameters block
+ TPM_TAG tag = TPM_TAG_RQU_COMMAND;
+ UINT32 paramSize = 0;
+ TPM_COMMAND_CODE ordinal = TPM_ORD_SaveState;
+ TPM_RESULT returnCode = TPM_SUCCESS;
+
+ // setup the TPM driver input and output buffers
+ TDDL_RESULT hRes = TDDL_E_FAIL;
+ TDDL_UINT32 InLength = TCPA_MAX_BUFFER_LENGTH;
+ TDDL_UINT32 OutLength = TCPA_MAX_BUFFER_LENGTH;
+
+ // Convert Byte Input parameter in the input byte stream InBuf
+ InLength = BSG_PackList(InBuf, 3,
+ BSG_TPM_TAG, &tag,
+ BSG_TYPE_UINT32, ¶mSize,
+ BSG_TPM_COMMAND_CODE, &ordinal);
+ // fill paramSize again as we now have the correct size
+ BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2);
+
+ vtpmloginfo(VTPM_LOG_TCS_DEEP, "Sending paramSize = %d\n", InLength);
+
+ // call the TPM driver
+ if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) ==
TDDL_SUCCESS) {
+ // unpack OutBuf to get the tag, paramSize, & returnCode
+ BSG_UnpackList(OutBuf, 3,
+ BSG_TPM_TAG, &tag,
+ BSG_TYPE_UINT32, ¶mSize,
+ BSG_TPM_COMMAND_CODE, &returnCode);
+
+ if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_COMMAND) {
+ vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n", paramSize);
+ } else {
+ vtpmlogerror(VTPM_LOG_TCS, "TCSP_SaveState Failed with return code
%s\n", tpm_get_error_name(returnCode));
+ }
+ }
+
+ return(returnCode);
+}
+
+
TPM_RESULT TCSP_RawTransmitData( UINT32 inDataSize, // in
BYTE *inData, // in
UINT32 *outDataSize,// in/out
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/tcs/tcs.h
--- a/tools/vtpm_manager/tcs/tcs.h Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/tcs/tcs.h Wed Jun 28 07:52:21 2006 -0600
@@ -229,7 +229,10 @@ TPM_RESULT TCSP_ReadPubek ( TCS_CONTEXT
);
-// Non-Standard TCSP call to give direct access to TransmitData.
+// Non-Standard TCSP calls
+TPM_RESULT TCSP_SaveState(TCS_CONTEXT_HANDLE hContext); // in
+
+//Give direct access to TransmitData.
// Key and Auth Management is done before transfering command to TDDL.
TPM_RESULT TCSP_RawTransmitData(UINT32 inDataSize, // in
BYTE *inData, // in
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/tcs/transmit.c
--- a/tools/vtpm_manager/tcs/transmit.c Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/tcs/transmit.c Wed Jun 28 07:52:21 2006 -0600
@@ -43,7 +43,17 @@
// flag to track whether TDDL has been opened
static int g_TDDL_open = 0;
-static int g_fd = -1; // the fd to the TPM
+static int g_tx_fd = -1; // the fd to the TPM
+
+#ifndef DUMMY_TPM
+ #define TPM_TX_FNAME "/dev/tpm0"
+ static int *g_rx_fdp = &g_tx_fd;
+#else
+ #define TPM_TX_FNAME "/tmp/tpm_in.fifo"
+ #define TPM_RX_FNAME "/tmp/tpm_out.fifo"
+ static int g_rx_fd = -1;
+ static int *g_rx_fdp = &g_rx_fd; // the fd to the TPM
+#endif
TPM_RESULT
TDDL_TransmitData( TDDL_BYTE* in,
@@ -60,10 +70,9 @@ TDDL_TransmitData( TDDL_BYTE* in,
vtpmloginfomore(VTPM_LOG_TXDATA, "\n");
ssize_t size = 0;
- int fd = g_fd;
// send the request
- size = write (fd, in, insize);
+ size = write (g_tx_fd, in, insize);
if (size < 0) {
vtpmlogerror(VTPM_LOG_TXDATA, "write() failed");
ERRORDIE (TPM_IOERROR);
@@ -74,7 +83,7 @@ TDDL_TransmitData( TDDL_BYTE* in,
}
// read the response
- size = read (fd, out, TCPA_MAX_BUFFER_LENGTH);
+ size = read (*g_rx_fdp, out, TCPA_MAX_BUFFER_LENGTH);
if (size < 0) {
vtpmlogerror(VTPM_LOG_TXDATA, "read() failed");
ERRORDIE (TPM_IOERROR);
@@ -98,18 +107,20 @@ TPM_RESULT TDDL_Open() {
TPM_RESULT TDDL_Open() {
TDDL_RESULT status = TDDL_SUCCESS;
- int fd = -1;
if (g_TDDL_open)
return TPM_FAIL;
-
- fd = open ("/dev/tpm0", O_RDWR);
- if (fd < 0) {
+
+#ifdef DUMMY_TPM
+ *g_rx_fdp = open (TPM_RX_FNAME, O_RDWR);
+#endif
+
+ g_tx_fd = open (TPM_TX_FNAME, O_RDWR);
+ if (g_tx_fd < 0) {
vtpmlogerror(VTPM_LOG_TXDATA, "TPM open failed");
return TPM_IOERROR;
}
- g_fd = fd;
g_TDDL_open = 1;
return status;
@@ -119,13 +130,18 @@ void TDDL_Close() {
if (! g_TDDL_open)
return;
- if (g_fd>= 0) {
- if (close(g_fd) < 0)
+ if (g_tx_fd>= 0) {
+ if (close(g_tx_fd) < 0)
vtpmlogerror(VTPM_LOG_TXDATA, "closeing tpm failed");
-
- g_fd = -1;
+ g_tx_fd = -1;
}
+ if (*g_rx_fdp>= 0) {
+ if (close(*g_rx_fdp) < 0)
+ vtpmlogerror(VTPM_LOG_TXDATA, "closeing tpm failed");
+ *g_rx_fdp = -1;
+ }
+
g_TDDL_open = 0;
}
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/util/tcg.h
--- a/tools/vtpm_manager/util/tcg.h Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/util/tcg.h Wed Jun 28 07:52:21 2006 -0600
@@ -389,6 +389,11 @@ typedef struct pack_constbuf_t {
#define TPM_DELEGATE_ADMIN TPM_BASE + 77 // Delegation table management
not enabled
#define TPM_TRANSPORT_EXCLUSIVE TPM_BASE + 78 // There was a command
executed outside of an exclusive transport session
+// TPM_STARTUP_TYPE values
+#define TPM_ST_CLEAR 0x0001
+#define TPM_ST_STATE 0x0002
+#define TPM_ST_DEACTIVATED 0x003
+
// TPM_TAG values
#define TPM_TAG_RQU_COMMAND 0x00c1
#define TPM_TAG_RQU_AUTH1_COMMAND 0x00c2
diff -r c4b68afe97d3 -r 4b51d081378d tools/xenstat/xentop/xentop.1
--- a/tools/xenstat/xentop/xentop.1 Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/xenstat/xentop/xentop.1 Wed Jun 28 07:52:21 2006 -0600
@@ -25,6 +25,8 @@
[\fB\-n\fR]
[\fB\-r\fR]
[\fB\-v\fR]
+[\fB\-b\fR]
+[\fB\-i\fRITERATIONS]
.SH DESCRIPTION
\fBxentop\fR displays information about the Xen system and domains, in a
@@ -50,6 +52,13 @@ repeat table header before each domain
.TP
\fB\-v\fR, \fB\-\-vcpus\fR
output VCPU data
+.TP
+\fB\-b\fR, \fB\-\-batch\fR
+output data in batch mode (to stdout)
+.TP
+\fB\-i\fR, \fB\-\-iterations\fR=\fIITERATIONS\fR
+maximum number of iterations xentop should produce before ending
+
.SH "INTERACTIVE COMMANDS"
All interactive commands are case-insensitive.
diff -r c4b68afe97d3 -r 4b51d081378d tools/xenstat/xentop/xentop.c
--- a/tools/xenstat/xentop/xentop.c Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/xenstat/xentop/xentop.c Wed Jun 28 07:52:21 2006 -0600
@@ -153,6 +153,9 @@ field_id sort_field = FIELD_DOMID;
field_id sort_field = FIELD_DOMID;
unsigned int first_domain_index = 0;
unsigned int delay = 3;
+unsigned int batch = 0;
+unsigned int loop = 1;
+unsigned int iterations = 0;
int show_vcpus = 0;
int show_networks = 0;
int repeat_header = 0;
@@ -179,6 +182,8 @@ static void usage(const char *program)
"-n, --networks output vif network data\n"
"-r, --repeat-header repeat table header before each domain\n"
"-v, --vcpus output vcpu data\n"
+ "-b, --batch output in batch mode, no user input
accepted\n"
+ "-i, --iterations number of iterations before exiting\n"
"\n" XENTOP_BUGSTO,
program);
return;
@@ -236,9 +241,15 @@ static void print(const char *fmt, ...)
{
va_list args;
- if(current_row() < lines()-1) {
+ if (!batch) {
+ if((current_row() < lines()-1)) {
+ va_start(args, fmt);
+ vw_printw(stdscr, fmt, args);
+ va_end(args);
+ }
+ } else {
va_start(args, fmt);
- vw_printw(stdscr, fmt, args);
+ vprintf(fmt, args);
va_end(args);
}
}
@@ -803,6 +814,7 @@ static void top(void)
do_network(domains[i]);
}
+ if(!batch)
do_bottom_line();
}
@@ -818,9 +830,11 @@ int main(int argc, char **argv)
{ "repeat-header", no_argument, NULL, 'r' },
{ "vcpus", no_argument, NULL, 'v' },
{ "delay", required_argument, NULL, 'd' },
+ { "batch", no_argument, NULL, 'b' },
+ { "iterations", required_argument, NULL, 'i' },
{ 0, 0, 0, 0 },
};
- const char *sopts = "hVbnvd:";
+ const char *sopts = "hVbnvd:bi:";
if (atexit(cleanup) != 0)
fail("Failed to install cleanup handler.\n");
@@ -847,6 +861,13 @@ int main(int argc, char **argv)
case 'd':
delay = atoi(optarg);
break;
+ case 'b':
+ batch = 1;
+ break;
+ case 'i':
+ iterations = atoi(optarg);
+ loop = 0;
+ break;
}
}
@@ -855,28 +876,41 @@ int main(int argc, char **argv)
if (xhandle == NULL)
fail("Failed to initialize xenstat library\n");
- /* Begin curses stuff */
- initscr();
- start_color();
- cbreak();
- noecho();
- nonl();
- keypad(stdscr, TRUE);
- halfdelay(5);
- use_default_colors();
- init_pair(1, -1, COLOR_YELLOW);
-
- do {
- gettimeofday(&curtime, NULL);
- if(ch != ERR || (curtime.tv_sec - oldtime.tv_sec) >= delay) {
- clear();
- top();
- oldtime = curtime;
- refresh();
- }
- ch = getch();
- } while (handle_key(ch));
-
+ if (!batch) {
+ /* Begin curses stuff */
+ initscr();
+ start_color();
+ cbreak();
+ noecho();
+ nonl();
+ keypad(stdscr, TRUE);
+ halfdelay(5);
+ use_default_colors();
+ init_pair(1, -1, COLOR_YELLOW);
+
+ do {
+ gettimeofday(&curtime, NULL);
+ if(ch != ERR || (curtime.tv_sec - oldtime.tv_sec) >=
delay) {
+ clear();
+ top();
+ oldtime = curtime;
+ refresh();
+ if ((!loop) && !(--iterations))
+ break;
+ }
+ ch = getch();
+ } while (handle_key(ch));
+ } else {
+ do {
+ gettimeofday(&curtime, NULL);
+ top();
+ oldtime = curtime;
+ sleep(delay);
+ if ((!loop) && !(--iterations))
+ break;
+ } while (1);
+ }
+
/* Cleanup occurs in cleanup(), so no work to do here. */
return 0;
diff -r c4b68afe97d3 -r 4b51d081378d
tools/xm-test/tests/info/02_info_compiledata_pos.py
--- a/tools/xm-test/tests/info/02_info_compiledata_pos.py Wed Jun 28
07:51:52 2006 -0600
+++ b/tools/xm-test/tests/info/02_info_compiledata_pos.py Wed Jun 28
07:52:21 2006 -0600
@@ -24,7 +24,8 @@ for line in lines:
map[pieces[0]] = pieces[1]
for field in ["cores_per_socket", "threads_per_core", "cpu_mhz",
- "total_memory", "free_memory", "xen_major", "xen_minor"]:
+ "total_memory", "free_memory", "xen_major", "xen_minor",
+ "xen_pagesize"]:
val = map[field]
if not val.isdigit():
FAIL("Numeric field %s not all-numbers: %s" % (field, val))
diff -r c4b68afe97d3 -r 4b51d081378d xen/Makefile
--- a/xen/Makefile Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/Makefile Wed Jun 28 07:52:21 2006 -0600
@@ -14,8 +14,8 @@ default: build
.PHONY: dist
dist: install
-.PHONY: build install clean cscope TAGS tags
-build install debug clean cscope TAGS tags::
+.PHONY: build install clean distclean cscope TAGS tags
+build install debug clean distclean cscope TAGS tags::
make -f Rules.mk _$@
.PHONY: _build
@@ -49,6 +49,10 @@ _clean: delete-unfresh-files
rm -f include/asm *.o $(TARGET)* *~ core
rm -f include/asm-*/asm-offsets.h
rm -f include/xen/acm_policy.h
+
+.PHONY: _distclean
+_distclean: clean
+ rm -f tags TAGS cscope.files cscope.in.out cscope.out cscope.po.out
$(TARGET).gz: $(TARGET)
gzip -f -9 < $< > $@.new
@@ -132,11 +136,11 @@ endef
.PHONY: _TAGS
_TAGS:
- $(all_sources) | etags -
+ rm -f TAGS && $(all_sources) | xargs etags -a
.PHONY: _tags
_tags:
- $(all_sources) | xargs ctags
+ rm -f TAGS && $(all_sources) | xargs ctags -a
.PHONY: _cscope
_cscope:
diff -r c4b68afe97d3 -r 4b51d081378d xen/arch/x86/dom0_ops.c
--- a/xen/arch/x86/dom0_ops.c Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/arch/x86/dom0_ops.c Wed Jun 28 07:52:21 2006 -0600
@@ -194,6 +194,7 @@ long arch_do_dom0_op(struct dom0_op *op,
pi->nr_nodes = 1;
pi->total_pages = total_pages;
pi->free_pages = avail_domheap_pages();
+ pi->scrub_pages = avail_scrub_pages();
pi->cpu_khz = cpu_khz;
memset(pi->hw_cap, 0, sizeof(pi->hw_cap));
memcpy(pi->hw_cap, boot_cpu_data.x86_capability, NCAPINTS*4);
diff -r c4b68afe97d3 -r 4b51d081378d xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/arch/x86/hvm/svm/svm.c Wed Jun 28 07:52:21 2006 -0600
@@ -47,7 +47,6 @@
#include <asm/shadow_64.h>
#endif
#include <public/sched.h>
-#include <public/hvm/ioreq.h>
#define SVM_EXTRA_DEBUG
@@ -66,8 +65,6 @@ extern int svm_instrlen(struct cpu_user_
extern int svm_instrlen(struct cpu_user_regs *regs, int mode);
extern void svm_dump_inst(unsigned long eip);
extern int svm_dbg_on;
-void svm_manual_event_injection32(struct vcpu *v, struct cpu_user_regs *regs,
- int vector, int has_code);
void svm_dump_regs(const char *from, struct cpu_user_regs *regs);
static void svm_relinquish_guest_resources(struct domain *d);
@@ -215,17 +212,6 @@ static void svm_store_cpu_guest_regs(
if ( regs != NULL )
{
-#if defined (__x86_64__)
- regs->rip = vmcb->rip;
- regs->rsp = vmcb->rsp;
- regs->rflags = vmcb->rflags;
- regs->cs = vmcb->cs.sel;
- regs->ds = vmcb->ds.sel;
- regs->es = vmcb->es.sel;
- regs->ss = vmcb->ss.sel;
- regs->gs = vmcb->gs.sel;
- regs->fs = vmcb->fs.sel;
-#elif defined (__i386__)
regs->eip = vmcb->rip;
regs->esp = vmcb->rsp;
regs->eflags = vmcb->rflags;
@@ -235,14 +221,14 @@ static void svm_store_cpu_guest_regs(
regs->ss = vmcb->ss.sel;
regs->gs = vmcb->gs.sel;
regs->fs = vmcb->fs.sel;
-#endif
}
if ( crs != NULL )
{
- crs[0] = vmcb->cr0;
- crs[3] = vmcb->cr3;
- crs[4] = vmcb->cr4;
+ /* Returning the guest's regs */
+ crs[0] = v->arch.hvm_svm.cpu_shadow_cr0;
+ crs[3] = v->arch.hvm_svm.cpu_cr3;
+ crs[4] = v->arch.hvm_svm.cpu_shadow_cr4;
}
}
@@ -258,13 +244,11 @@ static inline int long_mode_do_msr_read(
{
u64 msr_content = 0;
struct vcpu *vc = current;
- // struct svm_msr_state *msr = &vc->arch.hvm_svm.msr_content;
struct vmcb_struct *vmcb = vc->arch.hvm_svm.vmcb;
switch (regs->ecx)
{
case MSR_EFER:
- // msr_content = msr->msr_items[SVM_INDEX_MSR_EFER];
msr_content = vmcb->efer;
msr_content &= ~EFER_SVME;
break;
@@ -813,7 +797,8 @@ void arch_svm_do_resume(struct vcpu *v)
reset_stack_and_jump( svm_asm_do_resume );
}
else {
- printk("VCPU core pinned: %d to %d\n",
+ if (svm_dbg_on)
+ printk("VCPU core pinned: %d to %d\n",
v->arch.hvm_svm.launch_core, smp_processor_id() );
v->arch.hvm_svm.launch_core = smp_processor_id();
svm_migrate_timers( v );
@@ -1008,6 +993,10 @@ static void svm_vmexit_do_cpuid(struct v
clear_bit(X86_FEATURE_HT, &edx); /* clear the hyperthread bit */
ebx &= 0xFF00FFFF; /* clear the logical processor count when HTT=0 */
ebx |= 0x00010000; /* set to 1 just for precaution */
+
+ /* Disable machine check architecture */
+ clear_bit(X86_FEATURE_MCA, &edx);
+ clear_bit(X86_FEATURE_MCE, &edx);
}
else if ( ( input > 0x00000005 ) && ( input < 0x80000000 ) )
{
@@ -2582,7 +2571,7 @@ void walk_shadow_and_guest_pt(unsigned l
spte = l1e_empty();
- // This is actually overkill - we only need to make sure the hl2 is
in-sync.
+ /* This is actually overkill - we only need to make sure the hl2 is
in-sync. */
shadow_sync_va(v, gva);
gpte.l1 = 0;
@@ -2812,8 +2801,11 @@ asmlinkage void svm_vmexit_handler(struc
}
case VMEXIT_EXCEPTION_DF:
- printk("Guest double fault");
- BUG();
+ /* Debug info to hopefully help debug WHY the guest double-faulted. */
+ svm_dump_vmcb(__func__, vmcb);
+ svm_dump_regs(__func__, ®s);
+ svm_dump_inst(svm_rip2pointer(vmcb));
+ svm_inject_exception(v, TRAP_double_fault, 1, 0);
break;
case VMEXIT_INTR:
diff -r c4b68afe97d3 -r 4b51d081378d xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/arch/x86/hvm/vioapic.c Wed Jun 28 07:52:21 2006 -0600
@@ -40,6 +40,9 @@
#include <asm/hvm/support.h>
#include <asm/current.h>
+/* HACK: Route IRQ0 only to VCPU0 to prevent time jumps. */
+#define IRQ0_SPECIAL_ROUTING 1
+
#if defined(__ia64__)
#define opt_hvm_debug_level opt_vmx_debug_level
#endif
@@ -392,12 +395,12 @@ static void ioapic_deliver(hvm_vioapic_t
uint8_t trig_mode = s->redirtbl[irqno].RedirForm.trigmod;
uint32_t deliver_bitmask;
- HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "IOAPIC deliver: "
+ HVM_DBG_LOG(DBG_LEVEL_IOAPIC,
"dest %x dest_mode %x delivery_mode %x vector %x trig_mode %x\n",
dest, dest_mode, delivery_mode, vector, trig_mode);
- deliver_bitmask =
- ioapic_get_delivery_bitmask(s, dest, dest_mode, vector, delivery_mode);
+ deliver_bitmask = ioapic_get_delivery_bitmask(
+ s, dest, dest_mode, vector, delivery_mode);
if (!deliver_bitmask) {
HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic deliver "
@@ -411,15 +414,19 @@ static void ioapic_deliver(hvm_vioapic_t
{
struct vlapic* target;
- target = apic_round_robin(
- s->domain, dest_mode, vector, deliver_bitmask);
+#ifdef IRQ0_SPECIAL_ROUTING
+ if (irqno == 0)
+ target = s->lapic_info[0];
+ else
+#endif
+ target = apic_round_robin(s->domain, dest_mode,
+ vector, deliver_bitmask);
if (target)
ioapic_inj_irq(s, target, vector, trig_mode, delivery_mode);
- else{
- HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic deliver "
+ else
+ HVM_DBG_LOG(DBG_LEVEL_IOAPIC,
"null round robin mask %x vector %x delivery_mode %x\n",
deliver_bitmask, vector, deliver_bitmask);
- }
break;
}
@@ -429,6 +436,13 @@ static void ioapic_deliver(hvm_vioapic_t
uint8_t bit;
for (bit = 0; bit < s->lapic_count; bit++) {
if (deliver_bitmask & (1 << bit)) {
+#ifdef IRQ0_SPECIAL_ROUTING
+ if ( (irqno == 0) && (bit !=0) )
+ {
+ printk("PIT irq to bit %x\n", bit);
+ domain_crash_synchronous();
+ }
+#endif
if (s->lapic_info[bit]) {
ioapic_inj_irq(s, s->lapic_info[bit],
vector, trig_mode, delivery_mode);
@@ -450,14 +464,9 @@ static void ioapic_deliver(hvm_vioapic_t
static int ioapic_get_highest_irq(hvm_vioapic_t *s)
{
- uint32_t irqs;
-
- ASSERT(s);
-
- irqs = s->irr & ~s->isr & ~s->imr;
- return __fls(irqs);
-}
-
+ uint32_t irqs = s->irr & ~s->isr & ~s->imr;
+ return fls(irqs) - 1;
+}
static void service_ioapic(hvm_vioapic_t *s)
{
diff -r c4b68afe97d3 -r 4b51d081378d xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/arch/x86/hvm/vlapic.c Wed Jun 28 07:52:21 2006 -0600
@@ -50,7 +50,7 @@ int vlapic_find_highest_irr(struct vlapi
{
int result;
- result = find_highest_bit((uint32_t *)&vlapic->irr[0], INTR_LEN_32);
+ result = find_highest_bit(vlapic->irr, MAX_VECTOR);
if ( result != -1 && result < 16 )
{
@@ -79,14 +79,14 @@ int vlapic_find_highest_isr(struct vlapi
{
int result;
- result = find_highest_bit((uint32_t *)&vlapic->isr[0], INTR_LEN_32);
+ result = find_highest_bit(vlapic->isr, MAX_VECTOR);
if ( result != -1 && result < 16 )
{
int i = 0;
printk("VLAPIC: isr on reserved bits %d, isr is\n ", result);
- for ( i = 0; i < INTR_LEN_32; i += 2 )
- printk("%d: 0x%08x%08x\n", i, vlapic->isr[i], vlapic->isr[i+1]);
+ for ( i = 0; i < ARRAY_SIZE(vlapic->isr); i++ )
+ printk("%d: %p\n", i, (void *)vlapic->isr[i]);
return -1;
}
@@ -212,18 +212,19 @@ static int vlapic_accept_irq(struct vcpu
if ( test_and_set_bit(vector, &vlapic->irr[0]) )
{
- printk("<vlapic_accept_irq>"
- "level trig mode repeatedly for vector %d\n", vector);
+ HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
+ "level trig mode repeatedly for vector %d\n", vector);
break;
}
if ( level )
{
- printk("<vlapic_accept_irq> level trig mode for vector %d\n",
- vector);
+ HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
+ "level trig mode for vector %d\n", vector);
set_bit(vector, &vlapic->tmr[0]);
}
evtchn_set_pending(v, iopacket_port(v));
+
result = 1;
break;
@@ -308,8 +309,15 @@ struct vlapic* apic_round_robin(struct d
old = next = d->arch.hvm_domain.round_info[vector];
- do {
- /* the vcpu array is arranged according to vcpu_id */
+ /* the vcpu array is arranged according to vcpu_id */
+ do
+ {
+ next++;
+ if ( !d->vcpu[next] ||
+ !test_bit(_VCPUF_initialised, &d->vcpu[next]->vcpu_flags) ||
+ next == MAX_VIRT_CPUS )
+ next = 0;
+
if ( test_bit(next, &bitmap) )
{
target = d->vcpu[next]->arch.hvm_vcpu.vlapic;
@@ -321,12 +329,6 @@ struct vlapic* apic_round_robin(struct d
}
break;
}
-
- next ++;
- if ( !d->vcpu[next] ||
- !test_bit(_VCPUF_initialised, &d->vcpu[next]->vcpu_flags) ||
- next == MAX_VIRT_CPUS )
- next = 0;
} while ( next != old );
d->arch.hvm_domain.round_info[vector] = next;
@@ -896,7 +898,7 @@ vlapic_check_direct_intr(struct vcpu *v,
struct vlapic *vlapic = VLAPIC(v);
int type;
- type = __fls(vlapic->direct_intr.deliver_mode);
+ type = fls(vlapic->direct_intr.deliver_mode) - 1;
if ( type == -1 )
return -1;
@@ -956,7 +958,7 @@ int cpu_has_apic_interrupt(struct vcpu*
}
return 0;
}
-
+
void vlapic_post_injection(struct vcpu *v, int vector, int deliver_mode)
{
struct vlapic *vlapic = VLAPIC(v);
diff -r c4b68afe97d3 -r 4b51d081378d xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/arch/x86/hvm/vmx/vmx.c Wed Jun 28 07:52:21 2006 -0600
@@ -337,6 +337,7 @@ static void vmx_restore_msrs(struct vcpu
clear_bit(i, &guest_flags);
}
}
+
#else /* __i386__ */
#define vmx_save_segments(v) ((void)0)
@@ -355,6 +356,63 @@ static inline int long_mode_do_msr_write
}
#endif /* __i386__ */
+
+#define loaddebug(_v,_reg) \
+ __asm__ __volatile__ ("mov %0,%%db" #_reg : : "r" ((_v)->debugreg[_reg]))
+#define savedebug(_v,_reg) \
+ __asm__ __volatile__ ("mov %%db" #_reg ",%0" : : "r"
((_v)->debugreg[_reg]))
+
+static inline void vmx_save_dr(struct vcpu *v)
+{
+ if ( v->arch.hvm_vcpu.flag_dr_dirty )
+ {
+ savedebug(&v->arch.guest_context, 0);
+ savedebug(&v->arch.guest_context, 1);
+ savedebug(&v->arch.guest_context, 2);
+ savedebug(&v->arch.guest_context, 3);
+ savedebug(&v->arch.guest_context, 6);
+
+ v->arch.hvm_vcpu.flag_dr_dirty = 0;
+
+ v->arch.hvm_vcpu.u.vmx.exec_control |= CPU_BASED_MOV_DR_EXITING;
+ __vmwrite(CPU_BASED_VM_EXEC_CONTROL,
+ v->arch.hvm_vcpu.u.vmx.exec_control);
+ }
+}
+
+static inline void __restore_debug_registers(struct vcpu *v)
+{
+ loaddebug(&v->arch.guest_context, 0);
+ loaddebug(&v->arch.guest_context, 1);
+ loaddebug(&v->arch.guest_context, 2);
+ loaddebug(&v->arch.guest_context, 3);
+ /* No 4 and 5 */
+ loaddebug(&v->arch.guest_context, 6);
+ /* DR7 is loaded from the vmcs. */
+}
+
+/*
+ * DR7 is saved and restored on every vmexit. Other debug registers only
+ * need to be restored if their value is going to affect execution -- i.e.,
+ * if one of the breakpoints is enabled. So mask out all bits that don't
+ * enable some breakpoint functionality.
+ *
+ * This is in part necessary because bit 10 of DR7 is hardwired to 1, so a
+ * simple if( guest_dr7 ) will always return true. As long as we're masking,
+ * we might as well do it right.
+ */
+#define DR7_ACTIVE_MASK 0xff
+
+static inline void vmx_restore_dr(struct vcpu *v)
+{
+ unsigned long guest_dr7;
+
+ __vmread(GUEST_DR7, &guest_dr7);
+
+ /* Assumes guest does not have DR access at time of context switch. */
+ if ( unlikely(guest_dr7 & DR7_ACTIVE_MASK) )
+ __restore_debug_registers(v);
+}
static void vmx_freeze_time(struct vcpu *v)
{
@@ -371,11 +429,13 @@ static void vmx_ctxt_switch_from(struct
vmx_freeze_time(v);
vmx_save_segments(v);
vmx_load_msrs();
+ vmx_save_dr(v);
}
static void vmx_ctxt_switch_to(struct vcpu *v)
{
vmx_restore_msrs(v);
+ vmx_restore_dr(v);
}
void stop_vmx(void)
@@ -866,55 +926,20 @@ static void vmx_vmexit_do_cpuid(struct c
CASE_GET_REG_P(R15, r15)
#endif
-static void vmx_dr_access (unsigned long exit_qualification, struct
cpu_user_regs *regs)
-{
- unsigned int reg;
- unsigned long *reg_p = 0;
+static void vmx_dr_access(unsigned long exit_qualification,
+ struct cpu_user_regs *regs)
+{
struct vcpu *v = current;
- unsigned long eip;
-
- __vmread(GUEST_RIP, &eip);
-
- reg = exit_qualification & DEBUG_REG_ACCESS_NUM;
-
- HVM_DBG_LOG(DBG_LEVEL_1,
- "vmx_dr_access : eip=%lx, reg=%d, exit_qualification = %lx",
- eip, reg, exit_qualification);
-
- switch ( exit_qualification & DEBUG_REG_ACCESS_REG ) {
- CASE_GET_REG_P(EAX, eax);
- CASE_GET_REG_P(ECX, ecx);
- CASE_GET_REG_P(EDX, edx);
- CASE_GET_REG_P(EBX, ebx);
- CASE_GET_REG_P(EBP, ebp);
- CASE_GET_REG_P(ESI, esi);
- CASE_GET_REG_P(EDI, edi);
- CASE_EXTEND_GET_REG_P;
- case REG_ESP:
- break;
- default:
- __hvm_bug(regs);
- }
-
- switch (exit_qualification & DEBUG_REG_ACCESS_TYPE) {
- case TYPE_MOV_TO_DR:
- /* don't need to check the range */
- if (reg != REG_ESP)
- v->arch.guest_context.debugreg[reg] = *reg_p;
- else {
- unsigned long value;
- __vmread(GUEST_RSP, &value);
- v->arch.guest_context.debugreg[reg] = value;
- }
- break;
- case TYPE_MOV_FROM_DR:
- if (reg != REG_ESP)
- *reg_p = v->arch.guest_context.debugreg[reg];
- else {
- __vmwrite(GUEST_RSP, v->arch.guest_context.debugreg[reg]);
- }
- break;
- }
+
+ v->arch.hvm_vcpu.flag_dr_dirty = 1;
+
+ /* We could probably be smarter about this */
+ __restore_debug_registers(v);
+
+ /* Allow guest direct access to DR registers */
+ v->arch.hvm_vcpu.u.vmx.exec_control &= ~CPU_BASED_MOV_DR_EXITING;
+ __vmwrite(CPU_BASED_VM_EXEC_CONTROL,
+ v->arch.hvm_vcpu.u.vmx.exec_control);
}
/*
@@ -2080,10 +2105,19 @@ asmlinkage void vmx_vmexit_handler(struc
{
void store_cpu_user_regs(struct cpu_user_regs *regs);
- store_cpu_user_regs(®s);
- __vm_clear_bit(GUEST_PENDING_DBG_EXCEPTIONS, PENDING_DEBUG_EXC_BS);
-
- domain_pause_for_debugger();
+ if ( test_bit(_DOMF_debugging, &v->domain->domain_flags) )
+ {
+ store_cpu_user_regs(®s);
+ domain_pause_for_debugger();
+ __vm_clear_bit(GUEST_PENDING_DBG_EXCEPTIONS,
+ PENDING_DEBUG_EXC_BS);
+ }
+ else
+ {
+ vmx_reflect_exception(v);
+ __vm_clear_bit(GUEST_PENDING_DBG_EXCEPTIONS,
+ PENDING_DEBUG_EXC_BS);
+ }
break;
}
@@ -2139,9 +2173,17 @@ asmlinkage void vmx_vmexit_handler(struc
vmx_vmexit_do_extint(®s);
break;
case EXIT_REASON_PENDING_INTERRUPT:
+ /*
+ * Not sure exactly what the purpose of this is. The only bits set
+ * and cleared at this point are CPU_BASED_VIRTUAL_INTR_PENDING.
+ * (in io.c:{enable,disable}_irq_window(). So presumably we want to
+ * set it to the original value...
+ */
+ v->arch.hvm_vcpu.u.vmx.exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
+ v->arch.hvm_vcpu.u.vmx.exec_control |=
+ (MONITOR_CPU_BASED_EXEC_CONTROLS & CPU_BASED_VIRTUAL_INTR_PENDING);
__vmwrite(CPU_BASED_VM_EXEC_CONTROL,
- MONITOR_CPU_BASED_EXEC_CONTROLS);
- v->arch.hvm_vcpu.u.vmx.exec_control = MONITOR_CPU_BASED_EXEC_CONTROLS;
+ v->arch.hvm_vcpu.u.vmx.exec_control);
break;
case EXIT_REASON_TASK_SWITCH:
__hvm_bug(®s);
diff -r c4b68afe97d3 -r 4b51d081378d xen/arch/x86/microcode.c
--- a/xen/arch/x86/microcode.c Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/arch/x86/microcode.c Wed Jun 28 07:52:21 2006 -0600
@@ -83,9 +83,9 @@
#include <asm/processor.h>
#define pr_debug(x...) ((void)0)
-#define DECLARE_MUTEX(_m) DEFINE_SPINLOCK(_m)
-#define down(_m) spin_lock(_m)
-#define up(_m) spin_unlock(_m)
+#define DEFINE_MUTEX(_m) DEFINE_SPINLOCK(_m)
+#define mutex_lock(_m) spin_lock(_m)
+#define mutex_unlock(_m) spin_unlock(_m)
#define vmalloc(_s) xmalloc_bytes(_s)
#define vfree(_p) xfree(_p)
@@ -95,7 +95,10 @@ MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL");
#endif
-#define MICROCODE_VERSION "1.14"
+static int verbose;
+boolean_param("microcode.verbose", verbose);
+
+#define MICROCODE_VERSION "1.14a"
#define DEFAULT_UCODE_DATASIZE (2000) /* 2000 bytes */
#define MC_HEADER_SIZE (sizeof (microcode_header_t)) /* 48 bytes */
@@ -119,21 +122,22 @@ static DEFINE_SPINLOCK(microcode_update_
static DEFINE_SPINLOCK(microcode_update_lock);
/* no concurrent ->write()s are allowed on /dev/cpu/microcode */
-static DECLARE_MUTEX(microcode_sem);
+static DEFINE_MUTEX(microcode_mutex);
static void __user *user_buffer; /* user area microcode data buffer */
static unsigned int user_buffer_size; /* it's size */
typedef enum mc_error_code {
MC_SUCCESS = 0,
- MC_NOTFOUND = 1,
- MC_MARKED = 2,
- MC_ALLOCATED = 3,
+ MC_IGNORED = 1,
+ MC_NOTFOUND = 2,
+ MC_MARKED = 3,
+ MC_ALLOCATED = 4,
} mc_error_code_t;
static struct ucode_cpu_info {
unsigned int sig;
- unsigned int pf;
+ unsigned int pf, orig_pf;
unsigned int rev;
unsigned int cksum;
mc_error_code_t err;
@@ -163,6 +167,7 @@ static void collect_cpu_info (void *unus
rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
uci->pf = 1 << ((val[1] >> 18) & 7);
}
+ uci->orig_pf = uci->pf;
}
wrmsr(MSR_IA32_UCODE_REV, 0, 0);
@@ -196,23 +201,34 @@ static inline void mark_microcode_update
pr_debug(" Checksum 0x%x\n", cksum);
if (mc_header->rev < uci->rev) {
- printk(KERN_ERR "microcode: CPU%d not 'upgrading' to earlier
revision"
- " 0x%x (current=0x%x)\n", cpu_num, mc_header->rev,
uci->rev);
- goto out;
+ if (uci->err == MC_NOTFOUND) {
+ uci->err = MC_IGNORED;
+ uci->cksum = mc_header->rev;
+ } else if (uci->err == MC_IGNORED && uci->cksum <
mc_header->rev)
+ uci->cksum = mc_header->rev;
} else if (mc_header->rev == uci->rev) {
- /* notify the caller of success on this cpu */
- uci->err = MC_SUCCESS;
- printk(KERN_ERR "microcode: CPU%d already at revision"
- " 0x%x (current=0x%x)\n", cpu_num, mc_header->rev,
uci->rev);
- goto out;
- }
-
- pr_debug("microcode: CPU%d found a matching microcode update with "
- " revision 0x%x (current=0x%x)\n", cpu_num, mc_header->rev,
uci->rev);
- uci->cksum = cksum;
- uci->pf = pf; /* keep the original mc pf for cksum calculation */
- uci->err = MC_MARKED; /* found the match */
-out:
+ if (uci->err < MC_MARKED) {
+ /* notify the caller of success on this cpu */
+ uci->err = MC_SUCCESS;
+ }
+ } else if (uci->err != MC_ALLOCATED || mc_header->rev >
uci->mc->hdr.rev) {
+ pr_debug("microcode: CPU%d found a matching microcode update
with "
+ " revision 0x%x (current=0x%x)\n", cpu_num,
mc_header->rev, uci->rev);
+ uci->cksum = cksum;
+ uci->pf = pf; /* keep the original mc pf for cksum calculation
*/
+ uci->err = MC_MARKED; /* found the match */
+ for_each_online_cpu(cpu_num) {
+ if (ucode_cpu_info + cpu_num != uci
+ && ucode_cpu_info[cpu_num].mc == uci->mc) {
+ uci->mc = NULL;
+ break;
+ }
+ }
+ if (uci->mc != NULL) {
+ vfree(uci->mc);
+ uci->mc = NULL;
+ }
+ }
return;
}
@@ -251,13 +267,11 @@ static int find_matching_ucodes (void)
error = -EINVAL;
goto out;
}
-
- for (cpu_num = 0; cpu_num < num_online_cpus(); cpu_num++) {
+
+ for_each_online_cpu(cpu_num) {
struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
- if (uci->err != MC_NOTFOUND) /* already found a match
or not an online cpu*/
- continue;
-
- if (sigmatch(mc_header.sig, uci->sig, mc_header.pf,
uci->pf))
+
+ if (sigmatch(mc_header.sig, uci->sig, mc_header.pf,
uci->orig_pf))
mark_microcode_update(cpu_num, &mc_header,
mc_header.sig, mc_header.pf, mc_header.cksum);
}
@@ -294,18 +308,19 @@ static int find_matching_ucodes (void)
error = -EFAULT;
goto out;
}
- for (cpu_num = 0; cpu_num < num_online_cpus();
cpu_num++) {
+ for_each_online_cpu(cpu_num) {
struct ucode_cpu_info *uci =
ucode_cpu_info + cpu_num;
- if (uci->err != MC_NOTFOUND) /* already
found a match or not an online cpu*/
- continue;
- if (sigmatch(ext_sig.sig, uci->sig,
ext_sig.pf, uci->pf)) {
+
+ if (sigmatch(ext_sig.sig, uci->sig,
ext_sig.pf, uci->orig_pf)) {
mark_microcode_update(cpu_num,
&mc_header, ext_sig.sig, ext_sig.pf, ext_sig.cksum);
}
}
}
}
/* now check if any cpu has matched */
- for (cpu_num = 0, allocated_flag = 0, sum = 0; cpu_num <
num_online_cpus(); cpu_num++) {
+ allocated_flag = 0;
+ sum = 0;
+ for_each_online_cpu(cpu_num) {
if (ucode_cpu_info[cpu_num].err == MC_MARKED) {
struct ucode_cpu_info *uci = ucode_cpu_info +
cpu_num;
if (!allocated_flag) {
@@ -367,7 +382,13 @@ static void do_update_one (void * unused
struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
if (uci->mc == NULL) {
- printk(KERN_INFO "microcode: No new microcode data for
CPU%d\n", cpu_num);
+ if (verbose) {
+ if (uci->err == MC_SUCCESS)
+ printk(KERN_INFO "microcode: CPU%d already at
revision 0x%x\n",
+ cpu_num, uci->rev);
+ else
+ printk(KERN_INFO "microcode: No new microcode
data for CPU%d\n", cpu_num);
+ }
return;
}
@@ -416,16 +437,19 @@ static int do_microcode_update (void)
}
out_free:
- for (i = 0; i < num_online_cpus(); i++) {
+ for_each_online_cpu(i) {
if (ucode_cpu_info[i].mc) {
int j;
void *tmp = ucode_cpu_info[i].mc;
vfree(tmp);
- for (j = i; j < num_online_cpus(); j++) {
+ for_each_online_cpu(j) {
if (ucode_cpu_info[j].mc == tmp)
ucode_cpu_info[j].mc = NULL;
}
}
+ if (ucode_cpu_info[i].err == MC_IGNORED && verbose)
+ printk(KERN_WARNING "microcode: CPU%d not 'upgrading'
to earlier revision"
+ " 0x%x (current=0x%x)\n", i,
ucode_cpu_info[i].cksum, ucode_cpu_info[i].rev);
}
out:
return error;
@@ -433,21 +457,21 @@ out:
int microcode_update(void *buf, unsigned long len)
{
- int ret;
-
- if (len < DEFAULT_UCODE_TOTALSIZE) {
- printk(KERN_ERR "microcode: not enough data\n");
- return -EINVAL;
- }
-
- down(µcode_sem);
-
- user_buffer = (void __user *) buf;
- user_buffer_size = (int) len;
-
- ret = do_microcode_update();
-
- up(µcode_sem);
-
- return ret;
-}
+ int ret;
+
+ if (len < DEFAULT_UCODE_TOTALSIZE) {
+ printk(KERN_ERR "microcode: not enough data\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(µcode_mutex);
+
+ user_buffer = (void __user *) buf;
+ user_buffer_size = (int) len;
+
+ ret = do_microcode_update();
+
+ mutex_unlock(µcode_mutex);
+
+ return ret;
+}
diff -r c4b68afe97d3 -r 4b51d081378d xen/arch/x86/oprofile/nmi_int.c
--- a/xen/arch/x86/oprofile/nmi_int.c Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/arch/x86/oprofile/nmi_int.c Wed Jun 28 07:52:21 2006 -0600
@@ -269,7 +269,7 @@ static int __init p4_init(char * cpu_typ
{
__u8 cpu_model = current_cpu_data.x86_model;
- if (cpu_model > 4)
+ if ((cpu_model > 6) || (cpu_model == 5))
return 0;
#ifndef CONFIG_SMP
diff -r c4b68afe97d3 -r 4b51d081378d xen/arch/x86/oprofile/xenoprof.c
--- a/xen/arch/x86/oprofile/xenoprof.c Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/arch/x86/oprofile/xenoprof.c Wed Jun 28 07:52:21 2006 -0600
@@ -13,9 +13,13 @@
/* Limit amount of pages used for shared buffer (per domain) */
#define MAX_OPROF_SHARED_PAGES 32
-domid_t active_domains[MAX_OPROF_DOMAINS];
+struct domain *active_domains[MAX_OPROF_DOMAINS];
int active_ready[MAX_OPROF_DOMAINS];
unsigned int adomains;
+
+struct domain *passive_domains[MAX_OPROF_DOMAINS];
+unsigned int pdomains;
+
unsigned int activated;
struct domain *primary_profiler;
int xenoprof_state = XENOPROF_IDLE;
@@ -25,6 +29,7 @@ u64 corrupted_buffer_samples;
u64 corrupted_buffer_samples;
u64 lost_samples;
u64 active_samples;
+u64 passive_samples;
u64 idle_samples;
u64 others_samples;
@@ -44,9 +49,15 @@ int is_active(struct domain *d)
return ((x != NULL) && (x->domain_type == XENOPROF_DOMAIN_ACTIVE));
}
+int is_passive(struct domain *d)
+{
+ struct xenoprof *x = d->xenoprof;
+ return ((x != NULL) && (x->domain_type == XENOPROF_DOMAIN_PASSIVE));
+}
+
int is_profiled(struct domain *d)
{
- return is_active(d);
+ return (is_active(d) || is_passive(d));
}
static void xenoprof_reset_stat(void)
@@ -56,6 +67,7 @@ static void xenoprof_reset_stat(void)
corrupted_buffer_samples = 0;
lost_samples = 0;
active_samples = 0;
+ passive_samples = 0;
idle_samples = 0;
others_samples = 0;
}
@@ -83,13 +95,122 @@ static void xenoprof_reset_buf(struct do
}
}
+char *alloc_xenoprof_buf(struct domain *d, int npages)
+{
+ char *rawbuf;
+ int i, order;
+
+ /* allocate pages to store sample buffer shared with domain */
+ order = get_order_from_pages(npages);
+ rawbuf = alloc_xenheap_pages(order);
+ if ( rawbuf == NULL )
+ {
+ printk("alloc_xenoprof_buf(): memory allocation failed\n");
+ return 0;
+ }
+
+ /* Share pages so that kernel can map it */
+ for ( i = 0; i < npages; i++ )
+ share_xen_page_with_guest(
+ virt_to_page(rawbuf + i * PAGE_SIZE),
+ d, XENSHARE_writable);
+
+ return rawbuf;
+}
+
+int alloc_xenoprof_struct(struct domain *d, int max_samples, int is_passive)
+{
+ struct vcpu *v;
+ int nvcpu, npages, bufsize, max_bufsize;
+ int i;
+
+ d->xenoprof = xmalloc(struct xenoprof);
+
+ if ( d->xenoprof == NULL )
+ {
+ printk ("alloc_xenoprof_struct(): memory "
+ "allocation (xmalloc) failed\n");
+ return -ENOMEM;
+ }
+
+ memset(d->xenoprof, 0, sizeof(*d->xenoprof));
+
+ nvcpu = 0;
+ for_each_vcpu ( d, v )
+ nvcpu++;
+
+ /* reduce buffer size if necessary to limit pages allocated */
+ bufsize = sizeof(struct xenoprof_buf) +
+ (max_samples - 1) * sizeof(struct event_log);
+ max_bufsize = (MAX_OPROF_SHARED_PAGES * PAGE_SIZE) / nvcpu;
+ if ( bufsize > max_bufsize )
+ {
+ bufsize = max_bufsize;
+ max_samples = ( (max_bufsize - sizeof(struct xenoprof_buf)) /
+ sizeof(struct event_log) ) + 1;
+ }
+
+ npages = (nvcpu * bufsize - 1) / PAGE_SIZE + 1;
+
+ d->xenoprof->rawbuf = alloc_xenoprof_buf(is_passive ? dom0 : d, npages);
+
+ if ( d->xenoprof->rawbuf == NULL )
+ {
+ xfree(d->xenoprof);
+ d->xenoprof = NULL;
+ return -ENOMEM;
+ }
+
+ d->xenoprof->npages = npages;
+ d->xenoprof->nbuf = nvcpu;
+ d->xenoprof->bufsize = bufsize;
+ d->xenoprof->domain_ready = 0;
+ d->xenoprof->domain_type = XENOPROF_DOMAIN_IGNORED;
+
+ /* Update buffer pointers for active vcpus */
+ i = 0;
+ for_each_vcpu ( d, v )
+ {
+ d->xenoprof->vcpu[v->vcpu_id].event_size = max_samples;
+ d->xenoprof->vcpu[v->vcpu_id].buffer =
+ (struct xenoprof_buf *)&d->xenoprof->rawbuf[i * bufsize];
+ d->xenoprof->vcpu[v->vcpu_id].buffer->event_size = max_samples;
+ d->xenoprof->vcpu[v->vcpu_id].buffer->vcpu_id = v->vcpu_id;
+
+ i++;
+ /* in the unlikely case that the number of active vcpus changes */
+ if ( i >= nvcpu )
+ break;
+ }
+
+ return 0;
+}
+
+void free_xenoprof_pages(struct domain *d)
+{
+ struct xenoprof *x;
+ int order;
+
+ x = d->xenoprof;
+ if ( x == NULL )
+ return;
+
+ if ( x->rawbuf != NULL )
+ {
+ order = get_order_from_pages(x->npages);
+ free_xenheap_pages(x->rawbuf, order);
+ }
+
+ xfree(x);
+ d->xenoprof = NULL;
+}
+
int active_index(struct domain *d)
{
int i;
- domid_t id = d->domain_id;
for ( i = 0; i < adomains; i++ )
- if ( active_domains[i] == id )
+ if ( active_domains[i] == d )
return i;
return -1;
@@ -132,47 +253,116 @@ int reset_active(struct domain *d)
x->domain_ready = 0;
x->domain_type = XENOPROF_DOMAIN_IGNORED;
active_ready[ind] = 0;
+ active_domains[ind] = NULL;
activated--;
+ put_domain(d);
+
if ( activated <= 0 )
adomains = 0;
return 0;
}
-int reset_active_list(void)
+void reset_passive(struct domain *d)
+{
+ struct xenoprof *x;
+
+ if (d==0)
+ return;
+
+ x = d->xenoprof;
+ if ( x == NULL )
+ return;
+
+ x->domain_type = XENOPROF_DOMAIN_IGNORED;
+
+ return;
+}
+
+void reset_active_list(void)
{
int i;
- struct domain *d;
for ( i = 0; i < adomains; i++ )
{
if ( active_ready[i] )
{
- d = find_domain_by_id(active_domains[i]);
- if ( d != NULL )
- {
- reset_active(d);
- put_domain(d);
- }
+ reset_active(active_domains[i]);
}
}
adomains = 0;
activated = 0;
-
- return 0;
+}
+
+void reset_passive_list(void)
+{
+ int i;
+
+ for ( i = 0; i < pdomains; i++ )
+ {
+ reset_passive(passive_domains[i]);
+ put_domain(passive_domains[i]);
+ passive_domains[i] = NULL;
+ }
+
+ pdomains = 0;
}
int add_active_list (domid_t domid)
{
+ struct domain *d;
+
if ( adomains >= MAX_OPROF_DOMAINS )
return -E2BIG;
- active_domains[adomains] = domid;
+ d = find_domain_by_id(domid);
+ if ( d == NULL )
+ return -EINVAL;
+
+ active_domains[adomains] = d;
active_ready[adomains] = 0;
adomains++;
return 0;
+}
+
+int add_passive_list(XEN_GUEST_HANDLE(void) arg)
+{
+ struct xenoprof_passive passive;
+ struct domain *d;
+ int ret = 0;
+
+ if ( pdomains >= MAX_OPROF_DOMAINS )
+ return -E2BIG;
+
+ if ( copy_from_guest(&passive, arg, 1) )
+ return -EFAULT;
+
+ d = find_domain_by_id(passive.domain_id);
+ if ( d == NULL )
+ return -EINVAL;
+
+ if ( (d->xenoprof == NULL) &&
+ ((ret = alloc_xenoprof_struct(d, passive.max_samples, 1)) < 0) ) {
+ put_domain(d);
+ return -ENOMEM;
+ }
+
+ d->xenoprof->domain_type = XENOPROF_DOMAIN_PASSIVE;
+ passive.nbuf = d->xenoprof->nbuf;
+ passive.bufsize = d->xenoprof->bufsize;
+ passive.buf_maddr = __pa(d->xenoprof->rawbuf);
+
+ if ( copy_to_guest(arg, &passive, 1) ) {
+ put_domain(d);
+ return -EFAULT;
+ }
+
+ passive_domains[pdomains] = d;
+ pdomains++;
+
+ return ret;
}
void xenoprof_log_event(
@@ -231,7 +421,10 @@ void xenoprof_log_event(
if ( head >= size )
head = 0;
buf->event_head = head;
- active_samples++;
+ if ( is_active(vcpu->domain) )
+ active_samples++;
+ else
+ passive_samples++;
if ( mode == 0 )
buf->user_samples++;
else if ( mode == 1 )
@@ -241,114 +434,6 @@ void xenoprof_log_event(
}
}
-char *alloc_xenoprof_buf(struct domain *d, int npages)
-{
- char *rawbuf;
- int i, order;
-
- /* allocate pages to store sample buffer shared with domain */
- order = get_order_from_pages(npages);
- rawbuf = alloc_xenheap_pages(order);
- if ( rawbuf == NULL )
- {
- printk("alloc_xenoprof_buf(): memory allocation failed\n");
- return 0;
- }
-
- /* Share pages so that kernel can map it */
- for ( i = 0; i < npages; i++ )
- share_xen_page_with_guest(
- virt_to_page(rawbuf + i * PAGE_SIZE),
- d, XENSHARE_writable);
-
- return rawbuf;
-}
-
-int alloc_xenoprof_struct(struct domain *d, int max_samples)
-{
- struct vcpu *v;
- int nvcpu, npages, bufsize, max_bufsize;
- int i;
-
- d->xenoprof = xmalloc(struct xenoprof);
-
- if ( d->xenoprof == NULL )
- {
- printk ("alloc_xenoprof_struct(): memory "
- "allocation (xmalloc) failed\n");
- return -ENOMEM;
- }
-
- memset(d->xenoprof, 0, sizeof(*d->xenoprof));
-
- nvcpu = 0;
- for_each_vcpu ( d, v )
- nvcpu++;
-
- /* reduce buffer size if necessary to limit pages allocated */
- bufsize = sizeof(struct xenoprof_buf) +
- (max_samples - 1) * sizeof(struct event_log);
- max_bufsize = (MAX_OPROF_SHARED_PAGES * PAGE_SIZE) / nvcpu;
- if ( bufsize > max_bufsize )
- {
- bufsize = max_bufsize;
- max_samples = ( (max_bufsize - sizeof(struct xenoprof_buf)) /
- sizeof(struct event_log) ) + 1;
- }
-
- npages = (nvcpu * bufsize - 1) / PAGE_SIZE + 1;
- d->xenoprof->rawbuf = alloc_xenoprof_buf(d, npages);
- if ( d->xenoprof->rawbuf == NULL )
- {
- xfree(d->xenoprof);
- d->xenoprof = NULL;
- return -ENOMEM;
- }
-
- d->xenoprof->npages = npages;
- d->xenoprof->nbuf = nvcpu;
- d->xenoprof->bufsize = bufsize;
- d->xenoprof->domain_ready = 0;
- d->xenoprof->domain_type = XENOPROF_DOMAIN_IGNORED;
-
- /* Update buffer pointers for active vcpus */
- i = 0;
- for_each_vcpu ( d, v )
- {
- d->xenoprof->vcpu[v->vcpu_id].event_size = max_samples;
- d->xenoprof->vcpu[v->vcpu_id].buffer =
- (struct xenoprof_buf *)&d->xenoprof->rawbuf[i * bufsize];
- d->xenoprof->vcpu[v->vcpu_id].buffer->event_size = max_samples;
- d->xenoprof->vcpu[v->vcpu_id].buffer->vcpu_id = v->vcpu_id;
-
- i++;
- /* in the unlikely case that the number of active vcpus changes */
- if ( i >= nvcpu )
- break;
- }
-
- return 0;
-}
-
-void free_xenoprof_pages(struct domain *d)
-{
- struct xenoprof *x;
- int order;
-
- x = d->xenoprof;
- if ( x == NULL )
- return;
-
- if ( x->rawbuf != NULL )
- {
- order = get_order_from_pages(x->npages);
- free_xenheap_pages(x->rawbuf, order);
- }
-
- xfree(x);
- d->xenoprof = NULL;
-}
-
int xenoprof_op_init(XEN_GUEST_HANDLE(void) arg)
{
struct xenoprof_init xenoprof_init;
@@ -373,7 +458,7 @@ int xenoprof_op_init(XEN_GUEST_HANDLE(vo
* is called. Memory is then kept until domain is destroyed.
*/
if ( (d->xenoprof == NULL) &&
- ((ret = alloc_xenoprof_struct(d, xenoprof_init.max_samples)) < 0) )
+ ((ret = alloc_xenoprof_struct(d, xenoprof_init.max_samples, 0)) < 0) )
goto err;
xenoprof_reset_buf(d);
@@ -429,7 +514,14 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
case XENOPROF_reset_active_list:
{
- ret = reset_active_list();
+ reset_active_list();
+ ret = 0;
+ break;
+ }
+ case XENOPROF_reset_passive_list:
+ {
+ reset_passive_list();
+ ret = 0;
break;
}
case XENOPROF_set_active:
@@ -440,6 +532,13 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
if ( copy_from_guest(&domid, arg, 1) )
return -EFAULT;
ret = add_active_list(domid);
+ break;
+ }
+ case XENOPROF_set_passive:
+ {
+ if ( xenoprof_state != XENOPROF_IDLE )
+ return -EPERM;
+ ret = add_passive_list(arg);
break;
}
case XENOPROF_reserve_counters:
@@ -484,14 +583,20 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
break;
case XENOPROF_enable_virq:
+ {
+ int i;
if ( current->domain == primary_profiler )
{
nmi_enable_virq();
xenoprof_reset_stat();
+ for ( i = 0; i < pdomains; i++ ) {
+ xenoprof_reset_buf(passive_domains[i]);
+ }
}
xenoprof_reset_buf(current->domain);
ret = set_active(current->domain);
break;
+ }
case XENOPROF_start:
ret = -EPERM;
@@ -525,6 +630,7 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
xenoprof_state = XENOPROF_IDLE;
nmi_release_counters();
nmi_disable_virq();
+ reset_passive_list();
ret = 0;
}
break;
diff -r c4b68afe97d3 -r 4b51d081378d xen/arch/x86/smp.c
--- a/xen/arch/x86/smp.c Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/arch/x86/smp.c Wed Jun 28 07:52:21 2006 -0600
@@ -302,8 +302,9 @@ int on_selected_cpus(
static void stop_this_cpu (void *dummy)
{
- clear_bit(smp_processor_id(), &cpu_online_map);
-
+ cpu_clear(smp_processor_id(), cpu_online_map);
+
+ local_irq_disable();
disable_local_APIC();
for ( ; ; )
diff -r c4b68afe97d3 -r 4b51d081378d xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/arch/x86/x86_emulate.c Wed Jun 28 07:52:21 2006 -0600
@@ -374,9 +374,8 @@ do{ __asm__ __volatile__ (
/* Access/update address held in a register, based on addressing mode. */
#define register_address(sel, reg) \
- ((ad_bytes == sizeof(unsigned long)) ? (reg) : \
- ((mode == X86EMUL_MODE_REAL) ? /* implies ad_bytes == 2 */ \
- (((unsigned long)(sel) << 4) + ((reg) & 0xffff)) : \
+ (((mode == X86EMUL_MODE_REAL) ? ((unsigned long)(sel) << 4) : 0) + \
+ ((ad_bytes == sizeof(unsigned long)) ? (reg) : \
((reg) & ((1UL << (ad_bytes << 3)) - 1))))
#define register_address_increment(reg, inc) \
do { \
@@ -510,10 +509,6 @@ x86_emulate_memop(
}
done_prefixes:
- /* Note quite the same as 80386 real mode, but hopefully good enough. */
- if ( (mode == X86EMUL_MODE_REAL) && (ad_bytes != 2) )
- goto cannot_emulate;
-
/* REX prefix. */
if ( (mode == X86EMUL_MODE_PROT64) && ((b & 0xf0) == 0x40) )
{
diff -r c4b68afe97d3 -r 4b51d081378d xen/common/kernel.c
--- a/xen/common/kernel.c Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/common/kernel.c Wed Jun 28 07:52:21 2006 -0600
@@ -212,6 +212,11 @@ long do_xen_version(int cmd, XEN_GUEST_H
return 0;
}
+ case XENVER_pagesize:
+ {
+ return (!guest_handle_is_null(arg) ? -EINVAL : PAGE_SIZE);
+ }
+
}
return -ENOSYS;
diff -r c4b68afe97d3 -r 4b51d081378d xen/common/page_alloc.c
--- a/xen/common/page_alloc.c Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/common/page_alloc.c Wed Jun 28 07:52:21 2006 -0600
@@ -61,6 +61,7 @@ custom_param("lowmem_emergency_pool", pa
static DEFINE_SPINLOCK(page_scrub_lock);
LIST_HEAD(page_scrub_list);
+static unsigned long scrub_pages;
/*********************
* ALLOCATION BITMAP
@@ -696,6 +697,7 @@ void free_domheap_pages(struct page_info
{
spin_lock(&page_scrub_lock);
list_add(&pg[i].list, &page_scrub_list);
+ scrub_pages++;
spin_unlock(&page_scrub_lock);
}
}
@@ -784,9 +786,10 @@ static void page_scrub_softirq(void)
/* Remove peeled pages from the list. */
ent->next->prev = &page_scrub_list;
page_scrub_list.next = ent->next;
-
+ scrub_pages -= (i+1);
+
spin_unlock(&page_scrub_lock);
-
+
/* Working backwards, scrub each page in turn. */
while ( ent != &page_scrub_list )
{
@@ -798,6 +801,11 @@ static void page_scrub_softirq(void)
free_heap_pages(pfn_dom_zone_type(page_to_mfn(pg)), pg, 0);
}
} while ( (NOW() - start) < MILLISECS(1) );
+}
+
+unsigned long avail_scrub_pages(void)
+{
+ return scrub_pages;
}
static __init int page_scrub_init(void)
diff -r c4b68afe97d3 -r 4b51d081378d xen/include/asm-x86/bitops.h
--- a/xen/include/asm-x86/bitops.h Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/include/asm-x86/bitops.h Wed Jun 28 07:52:21 2006 -0600
@@ -335,8 +335,6 @@ static inline unsigned long ffz(unsigned
return word;
}
-#define fls64(x) generic_fls64(x)
-
/**
* ffs - find first bit set
* @x: the word to search
@@ -345,15 +343,15 @@ static inline unsigned long ffz(unsigned
* the libc and compiler builtin ffs routines, therefore
* differs in spirit from the above ffz (man ffs).
*/
-static inline int ffs(int x)
-{
- int r;
-
- __asm__("bsfl %1,%0\n\t"
+static inline int ffs(unsigned long x)
+{
+ long r;
+
+ __asm__("bsf %1,%0\n\t"
"jnz 1f\n\t"
- "movl $-1,%0\n"
+ "mov $-1,%0\n"
"1:" : "=r" (r) : "rm" (x));
- return r+1;
+ return (int)r+1;
}
/**
@@ -362,15 +360,15 @@ static inline int ffs(int x)
*
* This is defined the same way as ffs.
*/
-static inline int fls(int x)
-{
- int r;
-
- __asm__("bsrl %1,%0\n\t"
+static inline int fls(unsigned long x)
+{
+ long r;
+
+ __asm__("bsr %1,%0\n\t"
"jnz 1f\n\t"
- "movl $-1,%0\n"
+ "mov $-1,%0\n"
"1:" : "=r" (r) : "rm" (x));
- return r+1;
+ return (int)r+1;
}
/**
diff -r c4b68afe97d3 -r 4b51d081378d xen/include/asm-x86/hvm/vcpu.h
--- a/xen/include/asm-x86/hvm/vcpu.h Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/include/asm-x86/hvm/vcpu.h Wed Jun 28 07:52:21 2006 -0600
@@ -38,6 +38,9 @@ struct hvm_vcpu {
/* For AP startup */
unsigned long init_sipi_sipi_state;
+ /* Flags */
+ int flag_dr_dirty;
+
union {
struct arch_vmx_struct vmx;
struct arch_svm_struct svm;
diff -r c4b68afe97d3 -r 4b51d081378d xen/include/asm-x86/hvm/vlapic.h
--- a/xen/include/asm-x86/hvm/vlapic.h Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/include/asm-x86/hvm/vlapic.h Wed Jun 28 07:52:21 2006 -0600
@@ -23,52 +23,12 @@
#include <asm/msr.h>
#include <public/hvm/ioreq.h>
-#if defined(__i386__) || defined(__x86_64__)
-static inline int __fls(uint32_t word)
+static __inline__ int find_highest_bit(unsigned long *data, int nr_bits)
{
- int bit;
-
- __asm__("bsrl %1,%0"
- :"=r" (bit)
- :"rm" (word));
- return word ? bit : -1;
-}
-#else
-#define __fls(x) generic_fls(x)
-static __inline__ int generic_fls(uint32_t x)
-{
- int r = 31;
-
- if (!x)
- return -1;
- if (!(x & 0xffff0000u)) {
- x <<= 16;
- r -= 16;
- }
- if (!(x & 0xff000000u)) {
- x <<= 8;
- r -= 8;
- }
- if (!(x & 0xf0000000u)) {
- x <<= 4;
- r -= 4;
- }
- if (!(x & 0xc0000000u)) {
- x <<= 2;
- r -= 2;
- }
- if (!(x & 0x80000000u)) {
- x <<= 1;
- r -= 1;
- }
- return r;
-}
-#endif
-
-static __inline__ int find_highest_bit(uint32_t *data, int length)
-{
- while(length && !data[--length]);
- return __fls(data[length]) + 32 * length;
+ int length = BITS_TO_LONGS(nr_bits);
+ while ( length && !data[--length] )
+ continue;
+ return (fls(data[length]) - 1) + (length * BITS_PER_LONG);
}
#define VLAPIC(v) (v->arch.hvm_vcpu.vlapic)
@@ -146,17 +106,17 @@ typedef struct direct_intr_info {
int source[6];
} direct_intr_info_t;
-struct vlapic
-{
- //FIXME check what would be 64 bit on EM64T
+#define MAX_VECTOR 256
+
+struct vlapic {
uint32_t version;
uint32_t status;
uint32_t id;
uint32_t vcpu_id;
unsigned long base_address;
- uint32_t isr[8];
- uint32_t irr[INTR_LEN_32];
- uint32_t tmr[INTR_LEN_32];
+ unsigned long isr[BITS_TO_LONGS(MAX_VECTOR)];
+ unsigned long irr[BITS_TO_LONGS(MAX_VECTOR)];
+ unsigned long tmr[BITS_TO_LONGS(MAX_VECTOR)];
uint32_t task_priority;
uint32_t processor_priority;
uint32_t logical_dest;
diff -r c4b68afe97d3 -r 4b51d081378d xen/include/public/dom0_ops.h
--- a/xen/include/public/dom0_ops.h Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/include/public/dom0_ops.h Wed Jun 28 07:52:21 2006 -0600
@@ -231,6 +231,7 @@ struct dom0_physinfo {
uint32_t cpu_khz;
uint64_t total_pages;
uint64_t free_pages;
+ uint64_t scrub_pages;
uint32_t hw_cap[8];
};
typedef struct dom0_physinfo dom0_physinfo_t;
diff -r c4b68afe97d3 -r 4b51d081378d xen/include/public/hvm/ioreq.h
--- a/xen/include/public/hvm/ioreq.h Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/include/public/hvm/ioreq.h Wed Jun 28 07:52:21 2006 -0600
@@ -58,11 +58,6 @@ struct ioreq {
};
typedef struct ioreq ioreq_t;
-#define MAX_VECTOR 256
-#define BITS_PER_BYTE 8
-#define INTR_LEN (MAX_VECTOR/(BITS_PER_BYTE * sizeof(uint64_t)))
-#define INTR_LEN_32 (MAX_VECTOR/(BITS_PER_BYTE * sizeof(uint32_t)))
-
struct global_iodata {
uint16_t pic_elcr;
uint16_t pic_irr;
diff -r c4b68afe97d3 -r 4b51d081378d xen/include/public/io/netif.h
--- a/xen/include/public/io/netif.h Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/include/public/io/netif.h Wed Jun 28 07:52:21 2006 -0600
@@ -19,6 +19,16 @@
* the appropriate req_event or rsp_event field in the shared ring.
*/
+/*
+ * This is the 'wire' format for packets:
+ * Request 1: netif_tx_request -- NETTXF_* (any flags)
+ * [Request 2: netif_tx_extra] (only if request 1 has NETTXF_extra_info)
+ * Request 3: netif_tx_request -- NETTXF_more_data
+ * Request 4: netif_tx_request -- NETTXF_more_data
+ * ...
+ * Request N: netif_tx_request -- 0
+ */
+
/* Protocol checksum field is blank in the packet (hardware offload)? */
#define _NETTXF_csum_blank (0)
#define NETTXF_csum_blank (1U<<_NETTXF_csum_blank)
@@ -27,9 +37,16 @@
#define _NETTXF_data_validated (1)
#define NETTXF_data_validated (1U<<_NETTXF_data_validated)
-/* Packet continues in the request. */
+/* Packet continues in the next request descriptor. */
#define _NETTXF_more_data (2)
#define NETTXF_more_data (1U<<_NETTXF_more_data)
+
+/* Packet has GSO fields in the following descriptor (netif_tx_extra.u.gso). */
+#define _NETTXF_gso (3)
+#define NETTXF_gso (1U<<_NETTXF_gso)
+
+/* This descriptor is followed by an extra-info descriptor (netif_tx_extra). */
+#define NETTXF_extra_info (NETTXF_gso)
struct netif_tx_request {
grant_ref_t gref; /* Reference to buffer page */
@@ -39,6 +56,18 @@ struct netif_tx_request {
uint16_t size; /* Packet size in bytes. */
};
typedef struct netif_tx_request netif_tx_request_t;
+
+/* This structure needs to fit within netif_tx_request for compatibility. */
+struct netif_tx_extra {
+ union {
+ /* NETTXF_gso: Generic Segmentation Offload. */
+ struct netif_tx_gso {
+ uint16_t size; /* GSO MSS. */
+ uint16_t segs; /* GSO segment count. */
+ uint16_t type; /* GSO type. */
+ } gso;
+ } u;
+};
struct netif_tx_response {
uint16_t id;
@@ -78,6 +107,8 @@ DEFINE_RING_TYPES(netif_rx, struct netif
#define NETIF_RSP_DROPPED -2
#define NETIF_RSP_ERROR -1
#define NETIF_RSP_OKAY 0
+/* No response: used for auxiliary requests (e.g., netif_tx_extra). */
+#define NETIF_RSP_NULL 1
#endif
diff -r c4b68afe97d3 -r 4b51d081378d xen/include/public/version.h
--- a/xen/include/public/version.h Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/include/public/version.h Wed Jun 28 07:52:21 2006 -0600
@@ -10,7 +10,7 @@
#ifndef __XEN_PUBLIC_VERSION_H__
#define __XEN_PUBLIC_VERSION_H__
-/* NB. All ops return zero on success, except XENVER_version. */
+/* NB. All ops return zero on success, except XENVER_{version,pagesize} */
/* arg == NULL; returns major:minor (16:16). */
#define XENVER_version 0
@@ -54,6 +54,9 @@ typedef struct xen_feature_info xen_feat
/* Declares the features reported by XENVER_get_features. */
#include "features.h"
+/* arg == NULL; returns host memory page size. */
+#define XENVER_pagesize 7
+
#endif /* __XEN_PUBLIC_VERSION_H__ */
/*
diff -r c4b68afe97d3 -r 4b51d081378d xen/include/public/xenoprof.h
--- a/xen/include/public/xenoprof.h Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/include/public/xenoprof.h Wed Jun 28 07:52:21 2006 -0600
@@ -80,6 +80,15 @@ typedef struct xenoprof_counter xenoprof
typedef struct xenoprof_counter xenoprof_counter_t;
DEFINE_XEN_GUEST_HANDLE(xenoprof_counter_t);
+typedef struct xenoprof_passive {
+ uint16_t domain_id;
+ int32_t max_samples;
+ int32_t nbuf;
+ int32_t bufsize;
+ uint64_t buf_maddr;
+} xenoprof_passive_t;
+DEFINE_XEN_GUEST_HANDLE(xenoprof_passive_t);
+
#endif /* __XEN_PUBLIC_XENOPROF_H__ */
diff -r c4b68afe97d3 -r 4b51d081378d xen/include/xen/mm.h
--- a/xen/include/xen/mm.h Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/include/xen/mm.h Wed Jun 28 07:52:21 2006 -0600
@@ -91,6 +91,7 @@ extern struct list_head page_scrub_list;
if ( !list_empty(&page_scrub_list) ) \
raise_softirq(PAGE_SCRUB_SOFTIRQ); \
} while ( 0 )
+unsigned long avail_scrub_pages(void);
#include <asm/mm.h>
diff -r c4b68afe97d3 -r 4b51d081378d xen/include/xen/xenoprof.h
--- a/xen/include/xen/xenoprof.h Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/include/xen/xenoprof.h Wed Jun 28 07:52:21 2006 -0600
@@ -14,6 +14,7 @@
#define XENOPROF_DOMAIN_IGNORED 0
#define XENOPROF_DOMAIN_ACTIVE 1
+#define XENOPROF_DOMAIN_PASSIVE 2
#define XENOPROF_IDLE 0
#define XENOPROF_COUNTERS_RESERVED 1
diff -r c4b68afe97d3 -r 4b51d081378d patches/linux-2.6.16.13/net-gso.patch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.16.13/net-gso.patch Wed Jun 28 07:52:21 2006 -0600
@@ -0,0 +1,2907 @@
+diff --git a/Documentation/networking/netdevices.txt
b/Documentation/networking/netdevices.txt
+index 3c0a5ba..847cedb 100644
+--- a/Documentation/networking/netdevices.txt
++++ b/Documentation/networking/netdevices.txt
+@@ -42,9 +42,9 @@ dev->get_stats:
+ Context: nominally process, but don't sleep inside an rwlock
+
+ dev->hard_start_xmit:
+- Synchronization: dev->xmit_lock spinlock.
++ Synchronization: netif_tx_lock spinlock.
+ When the driver sets NETIF_F_LLTX in dev->features this will be
+- called without holding xmit_lock. In this case the driver
++ called without holding netif_tx_lock. In this case the driver
+ has to lock by itself when needed. It is recommended to use a try lock
+ for this and return -1 when the spin lock fails.
+ The locking there should also properly protect against
+@@ -62,12 +62,12 @@ dev->hard_start_xmit:
+ Only valid when NETIF_F_LLTX is set.
+
+ dev->tx_timeout:
+- Synchronization: dev->xmit_lock spinlock.
++ Synchronization: netif_tx_lock spinlock.
+ Context: BHs disabled
+ Notes: netif_queue_stopped() is guaranteed true
+
+ dev->set_multicast_list:
+- Synchronization: dev->xmit_lock spinlock.
++ Synchronization: netif_tx_lock spinlock.
+ Context: BHs disabled
+
+ dev->poll:
+diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
+index 4be9769..2e7cac7 100644
+--- a/drivers/block/aoe/aoenet.c
++++ b/drivers/block/aoe/aoenet.c
+@@ -95,9 +95,8 @@ mac_addr(char addr[6])
+ static struct sk_buff *
+ skb_check(struct sk_buff *skb)
+ {
+- if (skb_is_nonlinear(skb))
+ if ((skb = skb_share_check(skb, GFP_ATOMIC)))
+- if (skb_linearize(skb, GFP_ATOMIC) < 0) {
++ if (skb_linearize(skb)) {
+ dev_kfree_skb(skb);
+ return NULL;
+ }
+diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+index a2408d7..c90e620 100644
+--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+@@ -821,7 +821,8 @@ void ipoib_mcast_restart_task(void *dev_
+
+ ipoib_mcast_stop_thread(dev, 0);
+
+- spin_lock_irqsave(&dev->xmit_lock, flags);
++ local_irq_save(flags);
++ netif_tx_lock(dev);
+ spin_lock(&priv->lock);
+
+ /*
+@@ -896,7 +897,8 @@ void ipoib_mcast_restart_task(void *dev_
+ }
+
+ spin_unlock(&priv->lock);
+- spin_unlock_irqrestore(&dev->xmit_lock, flags);
++ netif_tx_unlock(dev);
++ local_irq_restore(flags);
+
+ /* We have to cancel outside of the spinlock */
+ list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
+diff --git a/drivers/media/dvb/dvb-core/dvb_net.c
b/drivers/media/dvb/dvb-core/dvb_net.c
+index 6711eb6..8d2351f 100644
+--- a/drivers/media/dvb/dvb-core/dvb_net.c
++++ b/drivers/media/dvb/dvb-core/dvb_net.c
+@@ -1052,7 +1052,7 @@ static void wq_set_multicast_list (void
+
+ dvb_net_feed_stop(dev);
+ priv->rx_mode = RX_MODE_UNI;
+- spin_lock_bh(&dev->xmit_lock);
++ netif_tx_lock_bh(dev);
+
+ if (dev->flags & IFF_PROMISC) {
+ dprintk("%s: promiscuous mode\n", dev->name);
+@@ -1077,7 +1077,7 @@ static void wq_set_multicast_list (void
+ }
+ }
+
+- spin_unlock_bh(&dev->xmit_lock);
++ netif_tx_unlock_bh(dev);
+ dvb_net_feed_start(dev);
+ }
+
+diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
+index dd41049..6615583 100644
+--- a/drivers/net/8139cp.c
++++ b/drivers/net/8139cp.c
+@@ -794,7 +794,7 @@ #endif
+ entry = cp->tx_head;
+ eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
+ if (dev->features & NETIF_F_TSO)
+- mss = skb_shinfo(skb)->tso_size;
++ mss = skb_shinfo(skb)->gso_size;
+
+ if (skb_shinfo(skb)->nr_frags == 0) {
+ struct cp_desc *txd = &cp->tx_ring[entry];
+diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
+index a24200d..b5e39a1 100644
+--- a/drivers/net/bnx2.c
++++ b/drivers/net/bnx2.c
+@@ -1593,7 +1593,7 @@ bnx2_tx_int(struct bnx2 *bp)
+ skb = tx_buf->skb;
+ #ifdef BCM_TSO
+ /* partial BD completions possible with TSO packets */
+- if (skb_shinfo(skb)->tso_size) {
++ if (skb_shinfo(skb)->gso_size) {
+ u16 last_idx, last_ring_idx;
+
+ last_idx = sw_cons +
+@@ -1948,7 +1948,7 @@ bnx2_poll(struct net_device *dev, int *b
+ return 1;
+ }
+
+-/* Called with rtnl_lock from vlan functions and also dev->xmit_lock
++/* Called with rtnl_lock from vlan functions and also netif_tx_lock
+ * from set_multicast.
+ */
+ static void
+@@ -4403,7 +4403,7 @@ bnx2_vlan_rx_kill_vid(struct net_device
+ }
+ #endif
+
+-/* Called with dev->xmit_lock.
++/* Called with netif_tx_lock.
+ * hard_start_xmit is pseudo-lockless - a lock is only required when
+ * the tx queue is full. This way, we get the benefit of lockless
+ * operations most of the time without the complexities to handle
+@@ -4441,7 +4441,7 @@ bnx2_start_xmit(struct sk_buff *skb, str
+ (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16));
+ }
+ #ifdef BCM_TSO
+- if ((mss = skb_shinfo(skb)->tso_size) &&
++ if ((mss = skb_shinfo(skb)->gso_size) &&
+ (skb->len > (bp->dev->mtu + ETH_HLEN))) {
+ u32 tcp_opt_len, ip_tcp_len;
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index bcf9f17..e970921 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -1145,8 +1145,7 @@ int bond_sethwaddr(struct net_device *bo
+ }
+
+ #define BOND_INTERSECT_FEATURES \
+- (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM|\
+- NETIF_F_TSO|NETIF_F_UFO)
++ (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_TSO | NETIF_F_UFO)
+
+ /*
+ * Compute the common dev->feature set available to all slaves. Some
+@@ -1164,9 +1163,7 @@ static int bond_compute_features(struct
+ features &= (slave->dev->features & BOND_INTERSECT_FEATURES);
+
+ if ((features & NETIF_F_SG) &&
+- !(features & (NETIF_F_IP_CSUM |
+- NETIF_F_NO_CSUM |
+- NETIF_F_HW_CSUM)))
++ !(features & NETIF_F_ALL_CSUM))
+ features &= ~NETIF_F_SG;
+
+ /*
+@@ -4147,7 +4144,7 @@ static int bond_init(struct net_device *
+ */
+ bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
+
+- /* don't acquire bond device's xmit_lock when
++ /* don't acquire bond device's netif_tx_lock when
+ * transmitting */
+ bond_dev->features |= NETIF_F_LLTX;
+
+diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
+index 30ff8ea..7b7d360 100644
+--- a/drivers/net/chelsio/sge.c
++++ b/drivers/net/chelsio/sge.c
+@@ -1419,7 +1419,7 @@ int t1_start_xmit(struct sk_buff *skb, s
+ struct cpl_tx_pkt *cpl;
+
+ #ifdef NETIF_F_TSO
+- if (skb_shinfo(skb)->tso_size) {
++ if (skb_shinfo(skb)->gso_size) {
+ int eth_type;
+ struct cpl_tx_pkt_lso *hdr;
+
+@@ -1434,7 +1434,7 @@ #ifdef NETIF_F_TSO
+ hdr->ip_hdr_words = skb->nh.iph->ihl;
+ hdr->tcp_hdr_words = skb->h.th->doff;
+ hdr->eth_type_mss = htons(MK_ETH_TYPE_MSS(eth_type,
+- skb_shinfo(skb)->tso_size));
++ skb_shinfo(skb)->gso_size));
+ hdr->len = htonl(skb->len - sizeof(*hdr));
+ cpl = (struct cpl_tx_pkt *)hdr;
+ sge->stats.tx_lso_pkts++;
+diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
+index fa29402..681d284 100644
+--- a/drivers/net/e1000/e1000_main.c
++++ b/drivers/net/e1000/e1000_main.c
+@@ -2526,7 +2526,7 @@ #ifdef NETIF_F_TSO
+ uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
+ int err;
+
+- if (skb_shinfo(skb)->tso_size) {
++ if (skb_shinfo(skb)->gso_size) {
+ if (skb_header_cloned(skb)) {
+ err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+ if (err)
+@@ -2534,7 +2534,7 @@ #ifdef NETIF_F_TSO
+ }
+
+ hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
+- mss = skb_shinfo(skb)->tso_size;
++ mss = skb_shinfo(skb)->gso_size;
+ if (skb->protocol == ntohs(ETH_P_IP)) {
+ skb->nh.iph->tot_len = 0;
+ skb->nh.iph->check = 0;
+@@ -2651,7 +2651,7 @@ #ifdef NETIF_F_TSO
+ * tso gets written back prematurely before the data is fully
+ * DMAd to the controller */
+ if (!skb->data_len && tx_ring->last_tx_tso &&
+- !skb_shinfo(skb)->tso_size) {
++ !skb_shinfo(skb)->gso_size) {
+ tx_ring->last_tx_tso = 0;
+ size -= 4;
+ }
+@@ -2893,7 +2893,7 @@ #endif
+ }
+
+ #ifdef NETIF_F_TSO
+- mss = skb_shinfo(skb)->tso_size;
++ mss = skb_shinfo(skb)->gso_size;
+ /* The controller does a simple calculation to
+ * make sure there is enough room in the FIFO before
+ * initiating the DMA for each buffer. The calc is:
+@@ -2935,7 +2935,7 @@ #endif
+ #ifdef NETIF_F_TSO
+ /* Controller Erratum workaround */
+ if (!skb->data_len && tx_ring->last_tx_tso &&
+- !skb_shinfo(skb)->tso_size)
++ !skb_shinfo(skb)->gso_size)
+ count++;
+ #endif
+
+diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
+index 3682ec6..c35f16e 100644
+--- a/drivers/net/forcedeth.c
++++ b/drivers/net/forcedeth.c
+@@ -482,9 +482,9 @@ #define LPA_1000HALF 0x0400
+ * critical parts:
+ * - rx is (pseudo-) lockless: it relies on the single-threading provided
+ * by the arch code for interrupts.
+- * - tx setup is lockless: it relies on dev->xmit_lock. Actual submission
++ * - tx setup is lockless: it relies on netif_tx_lock. Actual submission
+ * needs dev->priv->lock :-(
+- * - set_multicast_list: preparation lockless, relies on dev->xmit_lock.
++ * - set_multicast_list: preparation lockless, relies on netif_tx_lock.
+ */
+
+ /* in dev: base, irq */
+@@ -1016,7 +1016,7 @@ static void drain_ring(struct net_device
+
+ /*
+ * nv_start_xmit: dev->hard_start_xmit function
+- * Called with dev->xmit_lock held.
++ * Called with netif_tx_lock held.
+ */
+ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+@@ -1105,8 +1105,8 @@ static int nv_start_xmit(struct sk_buff
+ np->tx_skbuff[nr] = skb;
+
+ #ifdef NETIF_F_TSO
+- if (skb_shinfo(skb)->tso_size)
+- tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->tso_size <<
NV_TX2_TSO_SHIFT);
++ if (skb_shinfo(skb)->gso_size)
++ tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->gso_size <<
NV_TX2_TSO_SHIFT);
+ else
+ #endif
+ tx_flags_extra = (skb->ip_summed == CHECKSUM_HW ?
(NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0);
+@@ -1203,7 +1203,7 @@ static void nv_tx_done(struct net_device
+
+ /*
+ * nv_tx_timeout: dev->tx_timeout function
+- * Called with dev->xmit_lock held.
++ * Called with netif_tx_lock held.
+ */
+ static void nv_tx_timeout(struct net_device *dev)
+ {
+@@ -1524,7 +1524,7 @@ static int nv_change_mtu(struct net_devi
+ * Changing the MTU is a rare event, it shouldn't matter.
+ */
+ disable_irq(dev->irq);
+- spin_lock_bh(&dev->xmit_lock);
++ netif_tx_lock_bh(dev);
+ spin_lock(&np->lock);
+ /* stop engines */
+ nv_stop_rx(dev);
+@@ -1559,7 +1559,7 @@ static int nv_change_mtu(struct net_devi
+ nv_start_rx(dev);
+ nv_start_tx(dev);
+ spin_unlock(&np->lock);
+- spin_unlock_bh(&dev->xmit_lock);
++ netif_tx_unlock_bh(dev);
+ enable_irq(dev->irq);
+ }
+ return 0;
+@@ -1594,7 +1594,7 @@ static int nv_set_mac_address(struct net
+ memcpy(dev->dev_addr, macaddr->sa_data, ETH_ALEN);
+
+ if (netif_running(dev)) {
+- spin_lock_bh(&dev->xmit_lock);
++ netif_tx_lock_bh(dev);
+ spin_lock_irq(&np->lock);
+
+ /* stop rx engine */
+@@ -1606,7 +1606,7 @@ static int nv_set_mac_address(struct net
+ /* restart rx engine */
+ nv_start_rx(dev);
+ spin_unlock_irq(&np->lock);
+- spin_unlock_bh(&dev->xmit_lock);
++ netif_tx_unlock_bh(dev);
+ } else {
+ nv_copy_mac_to_hw(dev);
+ }
+@@ -1615,7 +1615,7 @@ static int nv_set_mac_address(struct net
+
+ /*
+ * nv_set_multicast: dev->set_multicast function
+- * Called with dev->xmit_lock held.
++ * Called with netif_tx_lock held.
+ */
+ static void nv_set_multicast(struct net_device *dev)
+ {
+diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
+index 102c1f0..d12605f 100644
+--- a/drivers/net/hamradio/6pack.c
++++ b/drivers/net/hamradio/6pack.c
+@@ -308,9 +308,9 @@ static int sp_set_mac_address(struct net
+ {
+ struct sockaddr_ax25 *sa = addr;
+
+- spin_lock_irq(&dev->xmit_lock);
++ netif_tx_lock_bh(dev);
+ memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
+- spin_unlock_irq(&dev->xmit_lock);
++ netif_tx_unlock_bh(dev);
+
+ return 0;
+ }
+@@ -767,9 +767,9 @@ static int sixpack_ioctl(struct tty_stru
+ break;
+ }
+
+- spin_lock_irq(&dev->xmit_lock);
++ netif_tx_lock_bh(dev);
+ memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN);
+- spin_unlock_irq(&dev->xmit_lock);
++ netif_tx_unlock_bh(dev);
+
+ err = 0;
+ break;
+diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
+index dc5e9d5..5c66f5a 100644
+--- a/drivers/net/hamradio/mkiss.c
++++ b/drivers/net/hamradio/mkiss.c
+@@ -357,9 +357,9 @@ static int ax_set_mac_address(struct net
+ {
+ struct sockaddr_ax25 *sa = addr;
+
+- spin_lock_irq(&dev->xmit_lock);
++ netif_tx_lock_bh(dev);
+ memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
+- spin_unlock_irq(&dev->xmit_lock);
++ netif_tx_unlock_bh(dev);
+
+ return 0;
+ }
+@@ -886,9 +886,9 @@ static int mkiss_ioctl(struct tty_struct
+ break;
+ }
+
+- spin_lock_irq(&dev->xmit_lock);
++ netif_tx_lock_bh(dev);
+ memcpy(dev->dev_addr, addr, AX25_ADDR_LEN);
+- spin_unlock_irq(&dev->xmit_lock);
++ netif_tx_unlock_bh(dev);
+
+ err = 0;
+ break;
+diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
+index 31fb2d7..2e222ef 100644
+--- a/drivers/net/ifb.c
++++ b/drivers/net/ifb.c
+@@ -76,13 +76,13 @@ static void ri_tasklet(unsigned long dev
+ dp->st_task_enter++;
+ if ((skb = skb_peek(&dp->tq)) == NULL) {
+ dp->st_txq_refl_try++;
+- if (spin_trylock(&_dev->xmit_lock)) {
++ if (netif_tx_trylock(_dev)) {
+ dp->st_rxq_enter++;
+ while ((skb = skb_dequeue(&dp->rq)) != NULL) {
+ skb_queue_tail(&dp->tq, skb);
+ dp->st_rx2tx_tran++;
+ }
+- spin_unlock(&_dev->xmit_lock);
++ netif_tx_unlock(_dev);
+ } else {
+ /* reschedule */
+ dp->st_rxq_notenter++;
+@@ -110,7 +110,7 @@ static void ri_tasklet(unsigned long dev
+ }
+ }
+
+- if (spin_trylock(&_dev->xmit_lock)) {
++ if (netif_tx_trylock(_dev)) {
+ dp->st_rxq_check++;
+ if ((skb = skb_peek(&dp->rq)) == NULL) {
+ dp->tasklet_pending = 0;
+@@ -118,10 +118,10 @@ static void ri_tasklet(unsigned long dev
+ netif_wake_queue(_dev);
+ } else {
+ dp->st_rxq_rsch++;
+- spin_unlock(&_dev->xmit_lock);
++ netif_tx_unlock(_dev);
+ goto resched;
+ }
+- spin_unlock(&_dev->xmit_lock);
++ netif_tx_unlock(_dev);
+ } else {
+ resched:
+ dp->tasklet_pending = 1;
+diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
+index a9f49f0..339d4a7 100644
+--- a/drivers/net/irda/vlsi_ir.c
++++ b/drivers/net/irda/vlsi_ir.c
+@@ -959,7 +959,7 @@ static int vlsi_hard_start_xmit(struct s
+ || (now.tv_sec==ready.tv_sec &&
now.tv_usec>=ready.tv_usec))
+ break;
+ udelay(100);
+- /* must not sleep here - we are called under xmit_lock!
*/
++ /* must not sleep here - called under netif_tx_lock! */
+ }
+ }
+
+diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
+index f9f77e4..bdab369 100644
+--- a/drivers/net/ixgb/ixgb_main.c
++++ b/drivers/net/ixgb/ixgb_main.c
+@@ -1163,7 +1163,7 @@ #ifdef NETIF_F_TSO
+ uint16_t ipcse, tucse, mss;
+ int err;
+
+- if(likely(skb_shinfo(skb)->tso_size)) {
++ if(likely(skb_shinfo(skb)->gso_size)) {
+ if (skb_header_cloned(skb)) {
+ err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+ if (err)
+@@ -1171,7 +1171,7 @@ #ifdef NETIF_F_TSO
+ }
+
+ hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
+- mss = skb_shinfo(skb)->tso_size;
++ mss = skb_shinfo(skb)->gso_size;
+ skb->nh.iph->tot_len = 0;
+ skb->nh.iph->check = 0;
+ skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr,
+diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
+index 690a1aa..9bcaa80 100644
+--- a/drivers/net/loopback.c
++++ b/drivers/net/loopback.c
+@@ -74,7 +74,7 @@ static void emulate_large_send_offload(s
+ struct iphdr *iph = skb->nh.iph;
+ struct tcphdr *th = (struct tcphdr*)(skb->nh.raw + (iph->ihl * 4));
+ unsigned int doffset = (iph->ihl + th->doff) * 4;
+- unsigned int mtu = skb_shinfo(skb)->tso_size + doffset;
++ unsigned int mtu = skb_shinfo(skb)->gso_size + doffset;
+ unsigned int offset = 0;
+ u32 seq = ntohl(th->seq);
+ u16 id = ntohs(iph->id);
+@@ -139,7 +139,7 @@ #ifndef LOOPBACK_MUST_CHECKSUM
+ #endif
+
+ #ifdef LOOPBACK_TSO
+- if (skb_shinfo(skb)->tso_size) {
++ if (skb_shinfo(skb)->gso_size) {
+ BUG_ON(skb->protocol != htons(ETH_P_IP));
+ BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP);
+
+diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
+index c0998ef..0fac9d5 100644
+--- a/drivers/net/mv643xx_eth.c
++++ b/drivers/net/mv643xx_eth.c
+@@ -1107,7 +1107,7 @@ static int mv643xx_eth_start_xmit(struct
+
+ #ifdef MV643XX_CHECKSUM_OFFLOAD_TX
+ if (has_tiny_unaligned_frags(skb)) {
+- if ((skb_linearize(skb, GFP_ATOMIC) != 0)) {
++ if (__skb_linearize(skb)) {
+ stats->tx_dropped++;
+ printk(KERN_DEBUG "%s: failed to linearize tiny "
+ "unaligned fragment\n", dev->name);
+diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
+index 9d6d254..c9ed624 100644
+--- a/drivers/net/natsemi.c
++++ b/drivers/net/natsemi.c
+@@ -323,12 +323,12 @@ performance critical codepaths:
+ The rx process only runs in the interrupt handler. Access from outside
+ the interrupt handler is only permitted after disable_irq().
+
+-The rx process usually runs under the dev->xmit_lock. If np->intr_tx_reap
++The rx process usually runs under the netif_tx_lock. If np->intr_tx_reap
+ is set, then access is permitted under spin_lock_irq(&np->lock).
+
+ Thus configuration functions that want to access everything must call
+ disable_irq(dev->irq);
+- spin_lock_bh(dev->xmit_lock);
++ netif_tx_lock_bh(dev);
+ spin_lock_irq(&np->lock);
+
+ IV. Notes
+diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
+index 8cc0d0b..e53b313 100644
+--- a/drivers/net/r8169.c
++++ b/drivers/net/r8169.c
+@@ -2171,7 +2171,7 @@ static int rtl8169_xmit_frags(struct rtl
+ static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device
*dev)
+ {
+ if (dev->features & NETIF_F_TSO) {
+- u32 mss = skb_shinfo(skb)->tso_size;
++ u32 mss = skb_shinfo(skb)->gso_size;
+
+ if (mss)
+ return LargeSend | ((mss & MSSMask) << MSSShift);
+diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
+index b7f00d6..439f45f 100644
+--- a/drivers/net/s2io.c
++++ b/drivers/net/s2io.c
+@@ -3522,8 +3522,8 @@ #endif
+ txdp->Control_1 = 0;
+ txdp->Control_2 = 0;
+ #ifdef NETIF_F_TSO
+- mss = skb_shinfo(skb)->tso_size;
+- if (mss) {
++ mss = skb_shinfo(skb)->gso_size;
++ if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV4) {
+ txdp->Control_1 |= TXD_TCP_LSO_EN;
+ txdp->Control_1 |= TXD_TCP_LSO_MSS(mss);
+ }
+@@ -3543,10 +3543,10 @@ #endif
+ }
+
+ frg_len = skb->len - skb->data_len;
+- if (skb_shinfo(skb)->ufo_size) {
++ if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) {
+ int ufo_size;
+
+- ufo_size = skb_shinfo(skb)->ufo_size;
++ ufo_size = skb_shinfo(skb)->gso_size;
+ ufo_size &= ~7;
+ txdp->Control_1 |= TXD_UFO_EN;
+ txdp->Control_1 |= TXD_UFO_MSS(ufo_size);
+@@ -3572,7 +3572,7 @@ #endif
+ txdp->Host_Control = (unsigned long) skb;
+ txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len);
+
+- if (skb_shinfo(skb)->ufo_size)
++ if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
+ txdp->Control_1 |= TXD_UFO_EN;
+
+ frg_cnt = skb_shinfo(skb)->nr_frags;
+@@ -3587,12 +3587,12 @@ #endif
+ (sp->pdev, frag->page, frag->page_offset,
+ frag->size, PCI_DMA_TODEVICE);
+ txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size);
+- if (skb_shinfo(skb)->ufo_size)
++ if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
+ txdp->Control_1 |= TXD_UFO_EN;
+ }
+ txdp->Control_1 |= TXD_GATHER_CODE_LAST;
+
+- if (skb_shinfo(skb)->ufo_size)
++ if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
+ frg_cnt++; /* as Txd0 was used for inband header */
+
+ tx_fifo = mac_control->tx_FIFO_start[queue];
+@@ -3606,7 +3606,7 @@ #ifdef NETIF_F_TSO
+ if (mss)
+ val64 |= TX_FIFO_SPECIAL_FUNC;
+ #endif
+- if (skb_shinfo(skb)->ufo_size)
++ if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
+ val64 |= TX_FIFO_SPECIAL_FUNC;
+ writeq(val64, &tx_fifo->List_Control);
+
+diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
+index 0618cd5..2a55eb3 100644
+--- a/drivers/net/sky2.c
++++ b/drivers/net/sky2.c
+@@ -1125,7 +1125,7 @@ static unsigned tx_le_req(const struct s
+ count = sizeof(dma_addr_t) / sizeof(u32);
+ count += skb_shinfo(skb)->nr_frags * count;
+
+- if (skb_shinfo(skb)->tso_size)
++ if (skb_shinfo(skb)->gso_size)
+ ++count;
+
+ if (skb->ip_summed == CHECKSUM_HW)
+@@ -1197,7 +1197,7 @@ static int sky2_xmit_frame(struct sk_buf
+ }
+
+ /* Check for TCP Segmentation Offload */
+- mss = skb_shinfo(skb)->tso_size;
++ mss = skb_shinfo(skb)->gso_size;
+ if (mss != 0) {
+ /* just drop the packet if non-linear expansion fails */
+ if (skb_header_cloned(skb) &&
+diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
+index caf4102..fc9164a 100644
+--- a/drivers/net/tg3.c
++++ b/drivers/net/tg3.c
+@@ -3664,7 +3664,7 @@ static int tg3_start_xmit(struct sk_buff
+ #if TG3_TSO_SUPPORT != 0
+ mss = 0;
+ if (skb->len > (tp->dev->mtu + ETH_HLEN) &&
+- (mss = skb_shinfo(skb)->tso_size) != 0) {
++ (mss = skb_shinfo(skb)->gso_size) != 0) {
+ int tcp_opt_len, ip_tcp_len;
+
+ if (skb_header_cloned(skb) &&
+diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
+index 5b1af39..11de5af 100644
+--- a/drivers/net/tulip/winbond-840.c
++++ b/drivers/net/tulip/winbond-840.c
+@@ -1605,11 +1605,11 @@ #ifdef CONFIG_PM
+ * - get_stats:
+ * spin_lock_irq(np->lock), doesn't touch hw if not present
+ * - hard_start_xmit:
+- * netif_stop_queue + spin_unlock_wait(&dev->xmit_lock);
++ * synchronize_irq + netif_tx_disable;
+ * - tx_timeout:
+- * netif_device_detach + spin_unlock_wait(&dev->xmit_lock);
++ * netif_device_detach + netif_tx_disable;
+ * - set_multicast_list
+- * netif_device_detach + spin_unlock_wait(&dev->xmit_lock);
++ * netif_device_detach + netif_tx_disable;
+ * - interrupt handler
+ * doesn't touch hw if not present, synchronize_irq waits for
+ * running instances of the interrupt handler.
+@@ -1635,11 +1635,10 @@ static int w840_suspend (struct pci_dev
+ netif_device_detach(dev);
+ update_csr6(dev, 0);
+ iowrite32(0, ioaddr + IntrEnable);
+- netif_stop_queue(dev);
+ spin_unlock_irq(&np->lock);
+
+- spin_unlock_wait(&dev->xmit_lock);
+ synchronize_irq(dev->irq);
++ netif_tx_disable(dev);
+
+ np->stats.rx_missed_errors += ioread32(ioaddr + RxMissed) &
0xffff;
+
+diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
+index 4c76cb7..30c48c9 100644
+--- a/drivers/net/typhoon.c
++++ b/drivers/net/typhoon.c
+@@ -340,7 +340,7 @@ #define typhoon_synchronize_irq(x) synch
+ #endif
+
+ #if defined(NETIF_F_TSO)
+-#define skb_tso_size(x) (skb_shinfo(x)->tso_size)
++#define skb_tso_size(x) (skb_shinfo(x)->gso_size)
+ #define TSO_NUM_DESCRIPTORS 2
+ #define TSO_OFFLOAD_ON TYPHOON_OFFLOAD_TCP_SEGMENT
+ #else
+diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
+index ed1f837..2eb6b5f 100644
+--- a/drivers/net/via-velocity.c
++++ b/drivers/net/via-velocity.c
+@@ -1899,6 +1899,13 @@ static int velocity_xmit(struct sk_buff
+
+ int pktlen = skb->len;
+
++#ifdef VELOCITY_ZERO_COPY_SUPPORT
++ if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) {
++ kfree_skb(skb);
++ return 0;
++ }
++#endif
++
+ spin_lock_irqsave(&vptr->lock, flags);
+
+ index = vptr->td_curr[qnum];
+@@ -1914,8 +1921,6 @@ static int velocity_xmit(struct sk_buff
+ */
+ if (pktlen < ETH_ZLEN) {
+ /* Cannot occur until ZC support */
+- if(skb_linearize(skb, GFP_ATOMIC))
+- return 0;
+ pktlen = ETH_ZLEN;
+ memcpy(tdinfo->buf, skb->data, skb->len);
+ memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len);
+@@ -1933,7 +1938,6 @@ #ifdef VELOCITY_ZERO_COPY_SUPPORT
+ int nfrags = skb_shinfo(skb)->nr_frags;
+ tdinfo->skb = skb;
+ if (nfrags > 6) {
+- skb_linearize(skb, GFP_ATOMIC);
+ memcpy(tdinfo->buf, skb->data, skb->len);
+ tdinfo->skb_dma[0] = tdinfo->buf_dma;
+ td_ptr->tdesc0.pktsize =
+diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
+index 6fd0bf7..75237c1 100644
+--- a/drivers/net/wireless/orinoco.c
++++ b/drivers/net/wireless/orinoco.c
+@@ -1835,7 +1835,9 @@ static int __orinoco_program_rids(struct
+ /* Set promiscuity / multicast*/
+ priv->promiscuous = 0;
+ priv->mc_count = 0;
+- __orinoco_set_multicast_list(dev); /* FIXME: what about the xmit_lock */
++
++ /* FIXME: what about netif_tx_lock */
++ __orinoco_set_multicast_list(dev);
+
+ return 0;
+ }
+diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c
+index 82cb4af..57cec40 100644
+--- a/drivers/s390/net/qeth_eddp.c
++++ b/drivers/s390/net/qeth_eddp.c
+@@ -421,7 +421,7 @@ #endif /* CONFIG_QETH_VLAN */
+ }
+ tcph = eddp->skb->h.th;
+ while (eddp->skb_offset < eddp->skb->len) {
+- data_len = min((int)skb_shinfo(eddp->skb)->tso_size,
++ data_len = min((int)skb_shinfo(eddp->skb)->gso_size,
+ (int)(eddp->skb->len - eddp->skb_offset));
+ /* prepare qdio hdr */
+ if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2){
+@@ -516,20 +516,20 @@ qeth_eddp_calc_num_pages(struct qeth_edd
+
+ QETH_DBF_TEXT(trace, 5, "eddpcanp");
+ /* can we put multiple skbs in one page? */
+- skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->tso_size + hdr_len);
++ skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->gso_size + hdr_len);
+ if (skbs_per_page > 1){
+- ctx->num_pages = (skb_shinfo(skb)->tso_segs + 1) /
++ ctx->num_pages = (skb_shinfo(skb)->gso_segs + 1) /
+ skbs_per_page + 1;
+ ctx->elements_per_skb = 1;
+ } else {
+ /* no -> how many elements per skb? */
+- ctx->elements_per_skb = (skb_shinfo(skb)->tso_size + hdr_len +
++ ctx->elements_per_skb = (skb_shinfo(skb)->gso_size + hdr_len +
+ PAGE_SIZE) >> PAGE_SHIFT;
+ ctx->num_pages = ctx->elements_per_skb *
+- (skb_shinfo(skb)->tso_segs + 1);
++ (skb_shinfo(skb)->gso_segs + 1);
+ }
+ ctx->num_elements = ctx->elements_per_skb *
+- (skb_shinfo(skb)->tso_segs + 1);
++ (skb_shinfo(skb)->gso_segs + 1);
+ }
+
+ static inline struct qeth_eddp_context *
+diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
+index dba7f7f..d9cc997 100644
+--- a/drivers/s390/net/qeth_main.c
++++ b/drivers/s390/net/qeth_main.c
+@@ -4454,7 +4454,7 @@ qeth_send_packet(struct qeth_card *card,
+ queue = card->qdio.out_qs
+ [qeth_get_priority_queue(card, skb, ipv, cast_type)];
+
+- if (skb_shinfo(skb)->tso_size)
++ if (skb_shinfo(skb)->gso_size)
+ large_send = card->options.large_send;
+
+ /*are we able to do TSO ? If so ,prepare and send it from here */
+@@ -4501,7 +4501,7 @@ qeth_send_packet(struct qeth_card *card,
+ card->stats.tx_packets++;
+ card->stats.tx_bytes += skb->len;
+ #ifdef CONFIG_QETH_PERF_STATS
+- if (skb_shinfo(skb)->tso_size &&
++ if (skb_shinfo(skb)->gso_size &&
+ !(large_send == QETH_LARGE_SEND_NO)) {
+ card->perf_stats.large_send_bytes += skb->len;
+ card->perf_stats.large_send_cnt++;
+diff --git a/drivers/s390/net/qeth_tso.h b/drivers/s390/net/qeth_tso.h
+index 1286dde..89cbf34 100644
+--- a/drivers/s390/net/qeth_tso.h
++++ b/drivers/s390/net/qeth_tso.h
+@@ -51,7 +51,7 @@ qeth_tso_fill_header(struct qeth_card *c
+ hdr->ext.hdr_version = 1;
+ hdr->ext.hdr_len = 28;
+ /*insert non-fix values */
+- hdr->ext.mss = skb_shinfo(skb)->tso_size;
++ hdr->ext.mss = skb_shinfo(skb)->gso_size;
+ hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4);
+ hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len -
+ sizeof(struct qeth_hdr_tso));
+diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
+index 93535f0..9269df7 100644
+--- a/include/linux/ethtool.h
++++ b/include/linux/ethtool.h
+@@ -408,6 +408,8 @@ #define ETHTOOL_STSO 0x0000001f /* Set
+ #define ETHTOOL_GPERMADDR 0x00000020 /* Get permanent hardware address */
+ #define ETHTOOL_GUFO 0x00000021 /* Get UFO enable (ethtool_value) */
+ #define ETHTOOL_SUFO 0x00000022 /* Set UFO enable (ethtool_value) */
++#define ETHTOOL_GGSO 0x00000023 /* Get GSO enable (ethtool_value) */
++#define ETHTOOL_SGSO 0x00000024 /* Set GSO enable (ethtool_value) */
+
+ /* compatibility with older code */
+ #define SPARC_ETH_GSET ETHTOOL_GSET
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index 7fda03d..47b0965 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -230,7 +230,8 @@ enum netdev_state_t
+ __LINK_STATE_SCHED,
+ __LINK_STATE_NOCARRIER,
+ __LINK_STATE_RX_SCHED,
+- __LINK_STATE_LINKWATCH_PENDING
++ __LINK_STATE_LINKWATCH_PENDING,
++ __LINK_STATE_QDISC_RUNNING,
+ };
+
+
+@@ -306,9 +307,17 @@ #define NETIF_F_HW_VLAN_TX 128 /* Transm
+ #define NETIF_F_HW_VLAN_RX 256 /* Receive VLAN hw acceleration */
+ #define NETIF_F_HW_VLAN_FILTER 512 /* Receive filtering on VLAN */
+ #define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN
packets */
+-#define NETIF_F_TSO 2048 /* Can offload TCP/IP segmentation */
++#define NETIF_F_GSO 2048 /* Enable software GSO. */
+ #define NETIF_F_LLTX 4096 /* LockLess TX */
+-#define NETIF_F_UFO 8192 /* Can offload UDP Large Send*/
++
++ /* Segmentation offload features */
++#define NETIF_F_GSO_SHIFT 16
++#define NETIF_F_TSO (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)
++#define NETIF_F_UFO (SKB_GSO_UDPV4 << NETIF_F_GSO_SHIFT)
++#define NETIF_F_GSO_ROBUST (SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)
++
++#define NETIF_F_GEN_CSUM (NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
++#define NETIF_F_ALL_CSUM (NETIF_F_IP_CSUM | NETIF_F_GEN_CSUM)
+
+ struct net_device *next_sched;
+
+@@ -394,6 +403,9 @@ #define NETIF_F_UFO 8192
+ struct list_head qdisc_list;
+ unsigned long tx_queue_len; /* Max frames per queue allowed
*/
+
++ /* Partially transmitted GSO packet. */
++ struct sk_buff *gso_skb;
++
+ /* ingress path synchronizer */
+ spinlock_t ingress_lock;
+ struct Qdisc *qdisc_ingress;
+@@ -402,7 +414,7 @@ #define NETIF_F_UFO 8192
+ * One part is mostly used on xmit path (device)
+ */
+ /* hard_start_xmit synchronizer */
+- spinlock_t xmit_lock ____cacheline_aligned_in_smp;
++ spinlock_t _xmit_lock ____cacheline_aligned_in_smp;
+ /* cpu id of processor entered to hard_start_xmit or -1,
+ if nobody entered there.
+ */
+@@ -527,6 +539,8 @@ struct packet_type {
+ struct net_device *,
+ struct packet_type *,
+ struct net_device *);
++ struct sk_buff *(*gso_segment)(struct sk_buff *skb,
++ int features);
+ void *af_packet_priv;
+ struct list_head list;
+ };
+@@ -693,7 +707,8 @@ extern int dev_change_name(struct net_d
+ extern int dev_set_mtu(struct net_device *, int);
+ extern int dev_set_mac_address(struct net_device *,
+ struct sockaddr *);
+-extern void dev_queue_xmit_nit(struct sk_buff *skb, struct
net_device *dev);
++extern int dev_hard_start_xmit(struct sk_buff *skb,
++ struct net_device *dev);
+
+ extern void dev_init(void);
+
+@@ -900,11 +915,43 @@ static inline void __netif_rx_complete(s
+ clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
+ }
+
++static inline void netif_tx_lock(struct net_device *dev)
++{
++ spin_lock(&dev->_xmit_lock);
++ dev->xmit_lock_owner = smp_processor_id();
++}
++
++static inline void netif_tx_lock_bh(struct net_device *dev)
++{
++ spin_lock_bh(&dev->_xmit_lock);
++ dev->xmit_lock_owner = smp_processor_id();
++}
++
++static inline int netif_tx_trylock(struct net_device *dev)
++{
++ int err = spin_trylock(&dev->_xmit_lock);
++ if (!err)
++ dev->xmit_lock_owner = smp_processor_id();
++ return err;
++}
++
++static inline void netif_tx_unlock(struct net_device *dev)
++{
++ dev->xmit_lock_owner = -1;
++ spin_unlock(&dev->_xmit_lock);
++}
++
++static inline void netif_tx_unlock_bh(struct net_device *dev)
++{
++ dev->xmit_lock_owner = -1;
++ spin_unlock_bh(&dev->_xmit_lock);
++}
++
+ static inline void netif_tx_disable(struct net_device *dev)
+ {
+- spin_lock_bh(&dev->xmit_lock);
++ netif_tx_lock_bh(dev);
+ netif_stop_queue(dev);
+- spin_unlock_bh(&dev->xmit_lock);
++ netif_tx_unlock_bh(dev);
+ }
+
+ /* These functions live elsewhere (drivers/net/net_init.c, but related) */
+@@ -932,6 +979,7 @@ extern int netdev_max_backlog;
+ extern int weight_p;
+ extern int netdev_set_master(struct net_device *dev, struct
net_device *master);
+ extern int skb_checksum_help(struct sk_buff *skb, int inward);
++extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features);
+ #ifdef CONFIG_BUG
+ extern void netdev_rx_csum_fault(struct net_device *dev);
+ #else
+@@ -951,6 +999,18 @@ #endif
+
+ extern void linkwatch_run_queue(void);
+
++static inline int skb_gso_ok(struct sk_buff *skb, int features)
++{
++ int feature = skb_shinfo(skb)->gso_size ?
++ skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT : 0;
++ return (features & feature) == feature;
++}
++
++static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
++{
++ return !skb_gso_ok(skb, dev->features);
++}
++
+ #endif /* __KERNEL__ */
+
+ #endif /* _LINUX_DEV_H */
+diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
+index ad7cc22..b19d45d 100644
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -134,9 +134,10 @@ struct skb_frag_struct {
+ struct skb_shared_info {
+ atomic_t dataref;
+ unsigned short nr_frags;
+- unsigned short tso_size;
+- unsigned short tso_segs;
+- unsigned short ufo_size;
++ unsigned short gso_size;
++ /* Warning: this field is not always filled in (UFO)! */
++ unsigned short gso_segs;
++ unsigned short gso_type;
+ unsigned int ip6_frag_id;
+ struct sk_buff *frag_list;
+ skb_frag_t frags[MAX_SKB_FRAGS];
+@@ -168,6 +169,14 @@ enum {
+ SKB_FCLONE_CLONE,
+ };
+
++enum {
++ SKB_GSO_TCPV4 = 1 << 0,
++ SKB_GSO_UDPV4 = 1 << 1,
++
++ /* This indicates the skb is from an untrusted source. */
++ SKB_GSO_DODGY = 1 << 2,
++};
++
+ /**
+ * struct sk_buff - socket buffer
+ * @next: Next buffer in list
+@@ -1148,18 +1157,34 @@ static inline int skb_can_coalesce(struc
+ return 0;
+ }
+
++static inline int __skb_linearize(struct sk_buff *skb)
++{
++ return __pskb_pull_tail(skb, skb->data_len) ? 0 : -ENOMEM;
++}
++
+ /**
+ * skb_linearize - convert paged skb to linear one
+ * @skb: buffer to linarize
+- * @gfp: allocation mode
+ *
+ * If there is no free memory -ENOMEM is returned, otherwise zero
+ * is returned and the old skb data released.
+ */
+-extern int __skb_linearize(struct sk_buff *skb, gfp_t gfp);
+-static inline int skb_linearize(struct sk_buff *skb, gfp_t gfp)
++static inline int skb_linearize(struct sk_buff *skb)
++{
++ return skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0;
++}
++
++/**
++ * skb_linearize_cow - make sure skb is linear and writable
++ * @skb: buffer to process
++ *
++ * If there is no free memory -ENOMEM is returned, otherwise zero
++ * is returned and the old skb data released.
++ */
++static inline int skb_linearize_cow(struct sk_buff *skb)
+ {
+- return __skb_linearize(skb, gfp);
++ return skb_is_nonlinear(skb) || skb_cloned(skb) ?
++ __skb_linearize(skb) : 0;
+ }
+
+ /**
+@@ -1254,6 +1279,7 @@ extern void skb_split(struct sk_b
+ struct sk_buff *skb1, const u32 len);
+
+ extern void skb_release_data(struct sk_buff *skb);
++extern struct sk_buff *skb_segment(struct sk_buff *skb, int features);
+
+ static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
+ int len, void *buffer)
+diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
+index b94d1ad..75b5b93 100644
+--- a/include/net/pkt_sched.h
++++ b/include/net/pkt_sched.h
+@@ -218,12 +218,13 @@ extern struct qdisc_rate_table *qdisc_ge
+ struct rtattr *tab);
+ extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
+
+-extern int qdisc_restart(struct net_device *dev);
++extern void __qdisc_run(struct net_device *dev);
+
+ static inline void qdisc_run(struct net_device *dev)
+ {
+- while (!netif_queue_stopped(dev) && qdisc_restart(dev) < 0)
+- /* NOTHING */;
++ if (!netif_queue_stopped(dev) &&
++ !test_and_set_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
++ __qdisc_run(dev);
+ }
+
+ extern int tc_classify(struct sk_buff *skb, struct tcf_proto *tp,
+diff --git a/include/net/protocol.h b/include/net/protocol.h
+index 6dc5970..0d2dcdb 100644
+--- a/include/net/protocol.h
++++ b/include/net/protocol.h
+@@ -37,6 +37,8 @@ #define MAX_INET_PROTOS 256 /* Must be
+ struct net_protocol {
+ int (*handler)(struct sk_buff *skb);
+ void (*err_handler)(struct sk_buff *skb, u32 info);
++ struct sk_buff *(*gso_segment)(struct sk_buff *skb,
++ int features);
+ int no_policy;
+ };
+
+diff --git a/include/net/sock.h b/include/net/sock.h
+index f63d0d5..a8e8d21 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1064,9 +1064,13 @@ static inline void sk_setup_caps(struct
+ {
+ __sk_dst_set(sk, dst);
+ sk->sk_route_caps = dst->dev->features;
++ if (sk->sk_route_caps & NETIF_F_GSO)
++ sk->sk_route_caps |= NETIF_F_TSO;
+ if (sk->sk_route_caps & NETIF_F_TSO) {
+ if (sock_flag(sk, SOCK_NO_LARGESEND) || dst->header_len)
+ sk->sk_route_caps &= ~NETIF_F_TSO;
++ else
++ sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
+ }
+ }
+
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index 77f21c6..70e1d5f 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -552,13 +552,13 @@ #include <net/tcp_ecn.h>
+ */
+ static inline int tcp_skb_pcount(const struct sk_buff *skb)
+ {
+- return skb_shinfo(skb)->tso_segs;
++ return skb_shinfo(skb)->gso_segs;
+ }
+
+ /* This is valid iff tcp_skb_pcount() > 1. */
+ static inline int tcp_skb_mss(const struct sk_buff *skb)
+ {
+- return skb_shinfo(skb)->tso_size;
++ return skb_shinfo(skb)->gso_size;
+ }
+
+ static inline void tcp_dec_pcount_approx(__u32 *count,
+@@ -1063,6 +1063,8 @@ extern struct request_sock_ops tcp_reque
+
+ extern int tcp_v4_destroy_sock(struct sock *sk);
+
++extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features);
++
+ #ifdef CONFIG_PROC_FS
+ extern int tcp4_proc_init(void);
+ extern void tcp4_proc_exit(void);
+diff --git a/net/atm/clip.c b/net/atm/clip.c
+index 1842a4e..6dc21a7 100644
+--- a/net/atm/clip.c
++++ b/net/atm/clip.c
+@@ -101,7 +101,7 @@ static void unlink_clip_vcc(struct clip_
+ printk(KERN_CRIT "!clip_vcc->entry (clip_vcc %p)\n",clip_vcc);
+ return;
+ }
+- spin_lock_bh(&entry->neigh->dev->xmit_lock); /* block
clip_start_xmit() */
++ netif_tx_lock_bh(entry->neigh->dev); /* block clip_start_xmit() */
+ entry->neigh->used = jiffies;
+ for (walk = &entry->vccs; *walk; walk = &(*walk)->next)
+ if (*walk == clip_vcc) {
+@@ -125,7 +125,7 @@ static void unlink_clip_vcc(struct clip_
+ printk(KERN_CRIT "ATMARP: unlink_clip_vcc failed (entry %p, vcc "
+ "0x%p)\n",entry,clip_vcc);
+ out:
+- spin_unlock_bh(&entry->neigh->dev->xmit_lock);
++ netif_tx_unlock_bh(entry->neigh->dev);
+ }
+
+ /* The neighbour entry n->lock is held. */
+diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
+index 0b33a7b..180e79b 100644
+--- a/net/bridge/br_device.c
++++ b/net/bridge/br_device.c
+@@ -146,9 +146,9 @@ static int br_set_tx_csum(struct net_dev
+ struct net_bridge *br = netdev_priv(dev);
+
+ if (data)
+- br->feature_mask |= NETIF_F_IP_CSUM;
++ br->feature_mask |= NETIF_F_NO_CSUM;
+ else
+- br->feature_mask &= ~NETIF_F_IP_CSUM;
++ br->feature_mask &= ~NETIF_F_ALL_CSUM;
+
+ br_features_recompute(br);
+ return 0;
+@@ -185,6 +185,6 @@ void br_dev_setup(struct net_device *dev
+ dev->set_mac_address = br_set_mac_address;
+ dev->priv_flags = IFF_EBRIDGE;
+
+- dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
+- | NETIF_F_HIGHDMA | NETIF_F_TSO | NETIF_F_IP_CSUM;
++ dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
++ NETIF_F_TSO | NETIF_F_NO_CSUM | NETIF_F_GSO_ROBUST;
+ }
+diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
+index 2d24fb4..00b1128 100644
+--- a/net/bridge/br_forward.c
++++ b/net/bridge/br_forward.c
+@@ -32,7 +32,7 @@ static inline int should_deliver(const s
+ int br_dev_queue_push_xmit(struct sk_buff *skb)
+ {
+ /* drop mtu oversized packets except tso */
+- if (skb->len > skb->dev->mtu && !skb_shinfo(skb)->tso_size)
++ if (skb->len > skb->dev->mtu && !skb_shinfo(skb)->gso_size)
+ kfree_skb(skb);
+ else {
+ #ifdef CONFIG_BRIDGE_NETFILTER
+diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
+index f36b35e..0617146 100644
+--- a/net/bridge/br_if.c
++++ b/net/bridge/br_if.c
+@@ -385,17 +385,28 @@ void br_features_recompute(struct net_br
+ struct net_bridge_port *p;
+ unsigned long features, checksum;
+
+- features = br->feature_mask &~ NETIF_F_IP_CSUM;
+- checksum = br->feature_mask & NETIF_F_IP_CSUM;
++ checksum = br->feature_mask & NETIF_F_ALL_CSUM ? NETIF_F_NO_CSUM : 0;
++ features = br->feature_mask & ~NETIF_F_ALL_CSUM;
+
+ list_for_each_entry(p, &br->port_list, list) {
+- if (!(p->dev->features
+- & (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)))
++ unsigned long feature = p->dev->features;
++
++ if (checksum & NETIF_F_NO_CSUM && !(feature & NETIF_F_NO_CSUM))
++ checksum ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM;
++ if (checksum & NETIF_F_HW_CSUM && !(feature & NETIF_F_HW_CSUM))
++ checksum ^= NETIF_F_HW_CSUM | NETIF_F_IP_CSUM;
++ if (!(feature & NETIF_F_IP_CSUM))
+ checksum = 0;
+- features &= p->dev->features;
++
++ if (feature & NETIF_F_GSO)
++ feature |= NETIF_F_TSO;
++ feature |= NETIF_F_GSO;
++
++ features &= feature;
+ }
+
+- br->dev->features = features | checksum | NETIF_F_LLTX;
++ br->dev->features = features | checksum | NETIF_F_LLTX |
++ NETIF_F_GSO_ROBUST;
+ }
+
+ /* called with RTNL */
+diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
+index 9e27373..588207f 100644
+--- a/net/bridge/br_netfilter.c
++++ b/net/bridge/br_netfilter.c
+@@ -743,7 +743,7 @@ static int br_nf_dev_queue_xmit(struct s
+ {
+ if (skb->protocol == htons(ETH_P_IP) &&
+ skb->len > skb->dev->mtu &&
+- !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
++ !skb_shinfo(skb)->gso_size)
+ return ip_fragment(skb, br_dev_queue_push_xmit);
+ else
+ return br_dev_queue_push_xmit(skb);
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 12a214c..32e1056 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -115,6 +115,7 @@ #include <linux/wireless.h> /* Note : w
+ #include <net/iw_handler.h>
+ #endif /* CONFIG_NET_RADIO */
+ #include <asm/current.h>
++#include <linux/err.h>
+
+ /*
+ * The list of packet types we will receive (as opposed to discard)
+@@ -1032,7 +1033,7 @@ static inline void net_timestamp(struct
+ * taps currently in use.
+ */
+
+-void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
++static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
+ {
+ struct packet_type *ptype;
+
+@@ -1106,6 +1107,45 @@ out:
+ return ret;
+ }
+
++/**
++ * skb_gso_segment - Perform segmentation on skb.
++ * @skb: buffer to segment
++ * @features: features for the output path (see dev->features)
++ *
++ * This function segments the given skb and returns a list of segments.
++ *
++ * It may return NULL if the skb requires no segmentation. This is
++ * only possible when GSO is used for verifying header integrity.
++ */
++struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
++{
++ struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
++ struct packet_type *ptype;
++ int type = skb->protocol;
++
++ BUG_ON(skb_shinfo(skb)->frag_list);
++ BUG_ON(skb->ip_summed != CHECKSUM_HW);
++
++ skb->mac.raw = skb->data;
++ skb->mac_len = skb->nh.raw - skb->data;
++ __skb_pull(skb, skb->mac_len);
++
++ rcu_read_lock();
++ list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) {
++ if (ptype->type == type && !ptype->dev && ptype->gso_segment) {
++ segs = ptype->gso_segment(skb, features);
++ break;
++ }
++ }
++ rcu_read_unlock();
++
++ __skb_push(skb, skb->data - skb->mac.raw);
++
++ return segs;
++}
++
++EXPORT_SYMBOL(skb_gso_segment);
++
+ /* Take action when hardware reception checksum errors are detected. */
+ #ifdef CONFIG_BUG
+ void netdev_rx_csum_fault(struct net_device *dev)
+@@ -1142,75 +1182,108 @@ #else
+ #define illegal_highdma(dev, skb) (0)
+ #endif
+
+-/* Keep head the same: replace data */
+-int __skb_linearize(struct sk_buff *skb, gfp_t gfp_mask)
+-{
+- unsigned int size;
+- u8 *data;
+- long offset;
+- struct skb_shared_info *ninfo;
+- int headerlen = skb->data - skb->head;
+- int expand = (skb->tail + skb->data_len) - skb->end;
+-
+- if (skb_shared(skb))
+- BUG();
+-
+- if (expand <= 0)
+- expand = 0;
+-
+- size = skb->end - skb->head + expand;
+- size = SKB_DATA_ALIGN(size);
+- data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
+- if (!data)
+- return -ENOMEM;
+-
+- /* Copy entire thing */
+- if (skb_copy_bits(skb, -headerlen, data, headerlen + skb->len))
+- BUG();
+-
+- /* Set up shinfo */
+- ninfo = (struct skb_shared_info*)(data + size);
+- atomic_set(&ninfo->dataref, 1);
+- ninfo->tso_size = skb_shinfo(skb)->tso_size;
+- ninfo->tso_segs = skb_shinfo(skb)->tso_segs;
+- ninfo->nr_frags = 0;
+- ninfo->frag_list = NULL;
+-
+- /* Offset between the two in bytes */
+- offset = data - skb->head;
+-
+- /* Free old data. */
+- skb_release_data(skb);
+-
+- skb->head = data;
+- skb->end = data + size;
+-
+- /* Set up new pointers */
+- skb->h.raw += offset;
+- skb->nh.raw += offset;
+- skb->mac.raw += offset;
+- skb->tail += offset;
+- skb->data += offset;
+-
+- /* We are no longer a clone, even if we were. */
+- skb->cloned = 0;
+-
+- skb->tail += skb->data_len;
+- skb->data_len = 0;
++struct dev_gso_cb {
++ void (*destructor)(struct sk_buff *skb);
++};
++
++#define DEV_GSO_CB(skb) ((struct dev_gso_cb *)(skb)->cb)
++
++static void dev_gso_skb_destructor(struct sk_buff *skb)
++{
++ struct dev_gso_cb *cb;
++
++ do {
++ struct sk_buff *nskb = skb->next;
++
++ skb->next = nskb->next;
++ nskb->next = NULL;
++ kfree_skb(nskb);
++ } while (skb->next);
++
++ cb = DEV_GSO_CB(skb);
++ if (cb->destructor)
++ cb->destructor(skb);
++}
++
++/**
++ * dev_gso_segment - Perform emulated hardware segmentation on skb.
++ * @skb: buffer to segment
++ *
++ * This function segments the given skb and stores the list of segments
++ * in skb->next.
++ */
++static int dev_gso_segment(struct sk_buff *skb)
++{
++ struct net_device *dev = skb->dev;
++ struct sk_buff *segs;
++ int features = dev->features & ~(illegal_highdma(dev, skb) ?
++ NETIF_F_SG : 0);
++
++ segs = skb_gso_segment(skb, features);
++
++ /* Verifying header integrity only. */
++ if (!segs)
++ return 0;
++
++ if (unlikely(IS_ERR(segs)))
++ return PTR_ERR(segs);
++
++ skb->next = segs;
++ DEV_GSO_CB(skb)->destructor = skb->destructor;
++ skb->destructor = dev_gso_skb_destructor;
++
++ return 0;
++}
++
++int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++ if (likely(!skb->next)) {
++ if (netdev_nit)
++ dev_queue_xmit_nit(skb, dev);
++
++ if (netif_needs_gso(dev, skb)) {
++ if (unlikely(dev_gso_segment(skb)))
++ goto out_kfree_skb;
++ if (skb->next)
++ goto gso;
++ }
++
++ return dev->hard_start_xmit(skb, dev);
++ }
++
++gso:
++ do {
++ struct sk_buff *nskb = skb->next;
++ int rc;
++
++ skb->next = nskb->next;
++ nskb->next = NULL;
++ rc = dev->hard_start_xmit(nskb, dev);
++ if (unlikely(rc)) {
++ nskb->next = skb->next;
++ skb->next = nskb;
++ return rc;
++ }
++ if (unlikely(netif_queue_stopped(dev) && skb->next))
++ return NETDEV_TX_BUSY;
++ } while (skb->next);
++
++ skb->destructor = DEV_GSO_CB(skb)->destructor;
++
++out_kfree_skb:
++ kfree_skb(skb);
+ return 0;
+ }
+
+ #define HARD_TX_LOCK(dev, cpu) { \
+ if ((dev->features & NETIF_F_LLTX) == 0) { \
+- spin_lock(&dev->xmit_lock); \
+- dev->xmit_lock_owner = cpu; \
++ netif_tx_lock(dev); \
+ } \
+ }
+
+ #define HARD_TX_UNLOCK(dev) { \
+ if ((dev->features & NETIF_F_LLTX) == 0) { \
+- dev->xmit_lock_owner = -1; \
+- spin_unlock(&dev->xmit_lock); \
++ netif_tx_unlock(dev); \
+ } \
+ }
+
+@@ -1246,9 +1319,13 @@ int dev_queue_xmit(struct sk_buff *skb)
+ struct Qdisc *q;
+ int rc = -ENOMEM;
+
++ /* GSO will handle the following emulations directly. */
++ if (netif_needs_gso(dev, skb))
++ goto gso;
++
+ if (skb_shinfo(skb)->frag_list &&
+ !(dev->features & NETIF_F_FRAGLIST) &&
+- __skb_linearize(skb, GFP_ATOMIC))
++ __skb_linearize(skb))
+ goto out_kfree_skb;
+
+ /* Fragmented skb is linearized if device does not support SG,
+@@ -1257,25 +1334,26 @@ int dev_queue_xmit(struct sk_buff *skb)
+ */
+ if (skb_shinfo(skb)->nr_frags &&
+ (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
+- __skb_linearize(skb, GFP_ATOMIC))
++ __skb_linearize(skb))
+ goto out_kfree_skb;
+
+ /* If packet is not checksummed and device does not support
+ * checksumming for this protocol, complete checksumming here.
+ */
+ if (skb->ip_summed == CHECKSUM_HW &&
+- (!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) &&
++ (!(dev->features & NETIF_F_GEN_CSUM) &&
+ (!(dev->features & NETIF_F_IP_CSUM) ||
+ skb->protocol != htons(ETH_P_IP))))
+ if (skb_checksum_help(skb, 0))
+ goto out_kfree_skb;
+
++gso:
+ spin_lock_prefetch(&dev->queue_lock);
+
+ /* Disable soft irqs for various locks below. Also
+ * stops preemption for RCU.
+ */
+- local_bh_disable();
++ rcu_read_lock_bh();
+
+ /* Updates of qdisc are serialized by queue_lock.
+ * The struct Qdisc which is pointed to by qdisc is now a
+@@ -1309,8 +1387,8 @@ #endif
+ /* The device has no queue. Common case for software devices:
+ loopback, all the sorts of tunnels...
+
+- Really, it is unlikely that xmit_lock protection is necessary here.
+- (f.e. loopback and IP tunnels are clean ignoring statistics
++ Really, it is unlikely that netif_tx_lock protection is necessary
++ here. (f.e. loopback and IP tunnels are clean ignoring statistics
+ counters.)
+ However, it is possible, that they rely on protection
+ made by us here.
+@@ -1326,11 +1404,8 @@ #endif
+ HARD_TX_LOCK(dev, cpu);
+
+ if (!netif_queue_stopped(dev)) {
+- if (netdev_nit)
+- dev_queue_xmit_nit(skb, dev);
+-
+ rc = 0;
+- if (!dev->hard_start_xmit(skb, dev)) {
++ if (!dev_hard_start_xmit(skb, dev)) {
+ HARD_TX_UNLOCK(dev);
+ goto out;
+ }
+@@ -1349,13 +1424,13 @@ #endif
+ }
+
+ rc = -ENETDOWN;
+- local_bh_enable();
++ rcu_read_unlock_bh();
+
+ out_kfree_skb:
+ kfree_skb(skb);
+ return rc;
+ out:
+- local_bh_enable();
++ rcu_read_unlock_bh();
+ return rc;
+ }
+
+@@ -2670,7 +2745,7 @@ int register_netdevice(struct net_device
+ BUG_ON(dev->reg_state != NETREG_UNINITIALIZED);
+
+ spin_lock_init(&dev->queue_lock);
+- spin_lock_init(&dev->xmit_lock);
++ spin_lock_init(&dev->_xmit_lock);
+ dev->xmit_lock_owner = -1;
+ #ifdef CONFIG_NET_CLS_ACT
+ spin_lock_init(&dev->ingress_lock);
+@@ -2714,9 +2789,7 @@ #endif
+
+ /* Fix illegal SG+CSUM combinations. */
+ if ((dev->features & NETIF_F_SG) &&
+- !(dev->features & (NETIF_F_IP_CSUM |
+- NETIF_F_NO_CSUM |
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|