ia64/xen-unstable

changeset 6586:dd668f7527cb

merge?
author cl349@firebug.cl.cam.ac.uk
date Thu Sep 01 10:16:14 2005 +0000 (2005-09-01)
parents 84ab93e1ee05 e02a45b91043
children d387866584e2
files .hgignore Config.mk MSG Makefile buildconfigs/Rules.mk buildconfigs/mk.linux-2.6-xen buildconfigs/mk.linux-2.6-xen0 buildconfigs/mk.linux-2.6-xenU docs/misc/vtpm.txt docs/src/user.tex extras/mini-os/include/hypervisor.h extras/mini-os/include/lib.h extras/mini-os/include/mm.h extras/mini-os/include/time.h extras/mini-os/include/types.h extras/mini-os/include/xmalloc.h extras/mini-os/kernel.c extras/mini-os/lib/xmalloc.c extras/mini-os/mm.c extras/mini-os/time.c linux-2.4-xen-sparse/Makefile linux-2.4-xen-sparse/arch/xen/Makefile linux-2.4-xen-sparse/arch/xen/boot/Makefile linux-2.4-xen-sparse/arch/xen/config.in linux-2.4-xen-sparse/arch/xen/defconfig-xen0 linux-2.4-xen-sparse/arch/xen/defconfig-xenU linux-2.4-xen-sparse/arch/xen/drivers/balloon/Makefile linux-2.4-xen-sparse/arch/xen/drivers/blkif/Makefile linux-2.4-xen-sparse/arch/xen/drivers/blkif/backend/Makefile linux-2.4-xen-sparse/arch/xen/drivers/blkif/frontend/Makefile linux-2.4-xen-sparse/arch/xen/drivers/blkif/frontend/common.h linux-2.4-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c linux-2.4-xen-sparse/arch/xen/drivers/console/Makefile linux-2.4-xen-sparse/arch/xen/drivers/dom0/Makefile linux-2.4-xen-sparse/arch/xen/drivers/evtchn/Makefile linux-2.4-xen-sparse/arch/xen/drivers/netif/Makefile linux-2.4-xen-sparse/arch/xen/drivers/netif/backend/Makefile linux-2.4-xen-sparse/arch/xen/drivers/netif/frontend/Makefile linux-2.4-xen-sparse/arch/xen/kernel/Makefile linux-2.4-xen-sparse/arch/xen/kernel/entry.S linux-2.4-xen-sparse/arch/xen/kernel/head.S linux-2.4-xen-sparse/arch/xen/kernel/i386_ksyms.c linux-2.4-xen-sparse/arch/xen/kernel/irq.c linux-2.4-xen-sparse/arch/xen/kernel/ldt.c linux-2.4-xen-sparse/arch/xen/kernel/pci-pc.c linux-2.4-xen-sparse/arch/xen/kernel/process.c linux-2.4-xen-sparse/arch/xen/kernel/setup.c linux-2.4-xen-sparse/arch/xen/kernel/signal.c linux-2.4-xen-sparse/arch/xen/kernel/time.c linux-2.4-xen-sparse/arch/xen/kernel/traps.c linux-2.4-xen-sparse/arch/xen/lib/Makefile linux-2.4-xen-sparse/arch/xen/lib/delay.c linux-2.4-xen-sparse/arch/xen/mm/Makefile linux-2.4-xen-sparse/arch/xen/mm/fault.c linux-2.4-xen-sparse/arch/xen/mm/init.c linux-2.4-xen-sparse/arch/xen/mm/ioremap.c linux-2.4-xen-sparse/arch/xen/vmlinux.lds linux-2.4-xen-sparse/drivers/block/ll_rw_blk.c linux-2.4-xen-sparse/drivers/char/Makefile linux-2.4-xen-sparse/drivers/char/mem.c linux-2.4-xen-sparse/drivers/char/tty_io.c linux-2.4-xen-sparse/drivers/scsi/aic7xxx/Makefile linux-2.4-xen-sparse/include/asm-xen/bugs.h linux-2.4-xen-sparse/include/asm-xen/desc.h linux-2.4-xen-sparse/include/asm-xen/fixmap.h linux-2.4-xen-sparse/include/asm-xen/highmem.h linux-2.4-xen-sparse/include/asm-xen/hw_irq.h linux-2.4-xen-sparse/include/asm-xen/io.h linux-2.4-xen-sparse/include/asm-xen/irq.h linux-2.4-xen-sparse/include/asm-xen/keyboard.h linux-2.4-xen-sparse/include/asm-xen/mmu_context.h linux-2.4-xen-sparse/include/asm-xen/module.h linux-2.4-xen-sparse/include/asm-xen/page.h linux-2.4-xen-sparse/include/asm-xen/pci.h linux-2.4-xen-sparse/include/asm-xen/pgalloc.h linux-2.4-xen-sparse/include/asm-xen/pgtable-2level.h linux-2.4-xen-sparse/include/asm-xen/pgtable.h linux-2.4-xen-sparse/include/asm-xen/processor.h linux-2.4-xen-sparse/include/asm-xen/queues.h linux-2.4-xen-sparse/include/asm-xen/segment.h linux-2.4-xen-sparse/include/asm-xen/smp.h linux-2.4-xen-sparse/include/asm-xen/system.h linux-2.4-xen-sparse/include/asm-xen/vga.h linux-2.4-xen-sparse/include/asm-xen/xor.h linux-2.4-xen-sparse/include/linux/blk.h linux-2.4-xen-sparse/include/linux/highmem.h linux-2.4-xen-sparse/include/linux/irq.h linux-2.4-xen-sparse/include/linux/mm.h linux-2.4-xen-sparse/include/linux/sched.h linux-2.4-xen-sparse/include/linux/skbuff.h linux-2.4-xen-sparse/include/linux/timer.h linux-2.4-xen-sparse/kernel/time.c linux-2.4-xen-sparse/kernel/timer.c linux-2.4-xen-sparse/mkbuildtree linux-2.4-xen-sparse/mm/highmem.c linux-2.4-xen-sparse/mm/memory.c linux-2.4-xen-sparse/mm/mprotect.c linux-2.4-xen-sparse/mm/mremap.c linux-2.4-xen-sparse/mm/page_alloc.c linux-2.4-xen-sparse/net/core/skbuff.c linux-2.6-xen-sparse/arch/xen/Kconfig linux-2.6-xen-sparse/arch/xen/Kconfig.drivers linux-2.6-xen-sparse/arch/xen/Makefile linux-2.6-xen-sparse/arch/xen/boot/Makefile linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64 linux-2.6-xen-sparse/arch/xen/i386/Kconfig linux-2.6-xen-sparse/arch/xen/i386/Makefile linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile linux-2.6-xen-sparse/arch/xen/i386/kernel/acpi/Makefile linux-2.6-xen-sparse/arch/xen/i386/kernel/acpi/boot.c linux-2.6-xen-sparse/arch/xen/i386/kernel/apic.c linux-2.6-xen-sparse/arch/xen/i386/kernel/cpu/Makefile linux-2.6-xen-sparse/arch/xen/i386/kernel/cpu/common.c linux-2.6-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/Makefile linux-2.6-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/main.c linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S linux-2.6-xen-sparse/arch/xen/i386/kernel/head.S linux-2.6-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c linux-2.6-xen-sparse/arch/xen/i386/kernel/init_task.c linux-2.6-xen-sparse/arch/xen/i386/kernel/io_apic.c linux-2.6-xen-sparse/arch/xen/i386/kernel/ioport.c linux-2.6-xen-sparse/arch/xen/i386/kernel/irq.c linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c linux-2.6-xen-sparse/arch/xen/i386/kernel/microcode.c linux-2.6-xen-sparse/arch/xen/i386/kernel/mpparse.c linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c linux-2.6-xen-sparse/arch/xen/i386/kernel/signal.c linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c linux-2.6-xen-sparse/arch/xen/i386/kernel/vsyscall.S linux-2.6-xen-sparse/arch/xen/i386/mach-default/Makefile linux-2.6-xen-sparse/arch/xen/i386/mm/Makefile linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c linux-2.6-xen-sparse/arch/xen/i386/mm/highmem.c linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c linux-2.6-xen-sparse/arch/xen/i386/mm/init.c linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c linux-2.6-xen-sparse/arch/xen/i386/pci/Makefile linux-2.6-xen-sparse/arch/xen/i386/pci/irq.c linux-2.6-xen-sparse/arch/xen/kernel/Makefile linux-2.6-xen-sparse/arch/xen/kernel/ctrl_if.c linux-2.6-xen-sparse/arch/xen/kernel/devmem.c linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c linux-2.6-xen-sparse/arch/xen/kernel/fixup.c linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c linux-2.6-xen-sparse/arch/xen/kernel/reboot.c linux-2.6-xen-sparse/arch/xen/kernel/skbuff.c linux-2.6-xen-sparse/arch/xen/kernel/smp.c linux-2.6-xen-sparse/arch/xen/kernel/xen_proc.c linux-2.6-xen-sparse/arch/xen/x86_64/Kconfig linux-2.6-xen-sparse/arch/xen/x86_64/Makefile linux-2.6-xen-sparse/arch/xen/x86_64/ia32/Makefile linux-2.6-xen-sparse/arch/xen/x86_64/ia32/ia32entry.S linux-2.6-xen-sparse/arch/xen/x86_64/ia32/syscall32.c linux-2.6-xen-sparse/arch/xen/x86_64/ia32/vsyscall-int80.S linux-2.6-xen-sparse/arch/xen/x86_64/kernel/Makefile linux-2.6-xen-sparse/arch/xen/x86_64/kernel/acpi/Makefile linux-2.6-xen-sparse/arch/xen/x86_64/kernel/apic.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/early_printk.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/entry.S linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic_xen.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head.S linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head64.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/io_apic.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/ioport.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/irq.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/ldt.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/mpparse.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/pci-nommu.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/process.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/signal.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smp.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/vsyscall.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/x8664_ksyms.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/xen_entry.S linux-2.6-xen-sparse/arch/xen/x86_64/mm/Makefile linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c linux-2.6-xen-sparse/arch/xen/x86_64/mm/pageattr.c linux-2.6-xen-sparse/arch/xen/x86_64/pci/Makefile linux-2.6-xen-sparse/arch/xen/x86_64/pci/Makefile-BUS linux-2.6-xen-sparse/drivers/Makefile linux-2.6-xen-sparse/drivers/acpi/tables.c linux-2.6-xen-sparse/drivers/char/mem.c linux-2.6-xen-sparse/drivers/char/tpm/Kconfig.domU linux-2.6-xen-sparse/drivers/char/tpm/Makefile linux-2.6-xen-sparse/drivers/char/tpm/tpm.c linux-2.6-xen-sparse/drivers/char/tpm/tpm.h linux-2.6-xen-sparse/drivers/char/tpm/tpm_atmel.c linux-2.6-xen-sparse/drivers/char/tpm/tpm_nopci.c linux-2.6-xen-sparse/drivers/char/tpm/tpm_nopci.h linux-2.6-xen-sparse/drivers/char/tpm/tpm_nsc.c linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c linux-2.6-xen-sparse/drivers/char/tty_io.c linux-2.6-xen-sparse/drivers/xen/Makefile linux-2.6-xen-sparse/drivers/xen/balloon/Makefile linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c linux-2.6-xen-sparse/drivers/xen/blkback/Makefile linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c linux-2.6-xen-sparse/drivers/xen/blkback/common.h linux-2.6-xen-sparse/drivers/xen/blkback/interface.c linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c linux-2.6-xen-sparse/drivers/xen/blkfront/Kconfig linux-2.6-xen-sparse/drivers/xen/blkfront/Makefile linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c linux-2.6-xen-sparse/drivers/xen/blkfront/block.h linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c linux-2.6-xen-sparse/drivers/xen/blktap/Makefile linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c linux-2.6-xen-sparse/drivers/xen/blktap/blktap.h linux-2.6-xen-sparse/drivers/xen/blktap/blktap_controlmsg.c linux-2.6-xen-sparse/drivers/xen/blktap/blktap_datapath.c linux-2.6-xen-sparse/drivers/xen/blktap/blktap_userdev.c linux-2.6-xen-sparse/drivers/xen/console/Makefile linux-2.6-xen-sparse/drivers/xen/console/console.c linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.h linux-2.6-xen-sparse/drivers/xen/evtchn/Makefile linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c linux-2.6-xen-sparse/drivers/xen/netback/Makefile linux-2.6-xen-sparse/drivers/xen/netback/common.h linux-2.6-xen-sparse/drivers/xen/netback/interface.c linux-2.6-xen-sparse/drivers/xen/netback/loopback.c linux-2.6-xen-sparse/drivers/xen/netback/netback.c linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c linux-2.6-xen-sparse/drivers/xen/netfront/Kconfig linux-2.6-xen-sparse/drivers/xen/netfront/Makefile linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c linux-2.6-xen-sparse/drivers/xen/privcmd/Makefile linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c linux-2.6-xen-sparse/drivers/xen/tpmback/Makefile linux-2.6-xen-sparse/drivers/xen/tpmback/common.h linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c linux-2.6-xen-sparse/drivers/xen/tpmfront/Makefile linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h linux-2.6-xen-sparse/drivers/xen/usbback/common.h linux-2.6-xen-sparse/drivers/xen/usbback/control.c linux-2.6-xen-sparse/drivers/xen/usbback/interface.c linux-2.6-xen-sparse/drivers/xen/usbback/usbback.c linux-2.6-xen-sparse/drivers/xen/usbfront/usbfront.c linux-2.6-xen-sparse/drivers/xen/usbfront/xhci.h linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c linux-2.6-xen-sparse/include/asm-generic/pgtable.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/agp.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/desc.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/fixmap.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/floppy.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/highmem.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/hw_irq.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/io.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/kmap_types.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_pre.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/mmu.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/mmu_context.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/page.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/param.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/pci.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgalloc.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable-3level.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/processor.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/ptrace.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/scatterlist.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/segment.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/setup.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/spinlock.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/swiotlb.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/synch_bitops.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/tlbflush.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/vga.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/arch_hooks.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/bootsetup.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/desc.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/dma-mapping.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/fixmap.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/floppy.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hw_irq.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/io.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/irq.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/io_ports.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/mach_timer.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/setup_arch_post.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/setup_arch_pre.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mmu.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mmu_context.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/page.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/param.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pci.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgalloc.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/processor.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/ptrace.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/segment.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/smp.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/timer.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/tlbflush.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/vga.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/xor.h linux-2.6-xen-sparse/include/asm-xen/balloon.h linux-2.6-xen-sparse/include/asm-xen/ctrl_if.h linux-2.6-xen-sparse/include/asm-xen/evtchn.h linux-2.6-xen-sparse/include/asm-xen/foreign_page.h linux-2.6-xen-sparse/include/asm-xen/gnttab.h linux-2.6-xen-sparse/include/asm-xen/hypervisor.h linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h linux-2.6-xen-sparse/include/asm-xen/linux-public/suspend.h linux-2.6-xen-sparse/include/asm-xen/queues.h linux-2.6-xen-sparse/include/asm-xen/synch_bitops.h linux-2.6-xen-sparse/include/asm-xen/xen_proc.h linux-2.6-xen-sparse/include/asm-xen/xenbus.h linux-2.6-xen-sparse/include/linux/gfp.h linux-2.6-xen-sparse/include/linux/highmem.h linux-2.6-xen-sparse/include/linux/irq.h linux-2.6-xen-sparse/include/linux/mm.h linux-2.6-xen-sparse/include/linux/skbuff.h linux-2.6-xen-sparse/include/linux/tpmfe.h linux-2.6-xen-sparse/kernel/irq/manage.c linux-2.6-xen-sparse/mkbuildtree linux-2.6-xen-sparse/mm/highmem.c linux-2.6-xen-sparse/mm/memory.c linux-2.6-xen-sparse/mm/mmap.c linux-2.6-xen-sparse/mm/page_alloc.c linux-2.6-xen-sparse/net/core/dev.c linux-2.6-xen-sparse/net/core/skbuff.c patches/linux-2.6.12/i386-cpu-hotplug-updated-for-mm.patch patches/linux-2.6.12/net-csum.patch patches/linux-2.6.12/patch-2.6.12.5 patches/linux-2.6.12/rcu-nohz.patch patches/linux-2.6.12/smp-alts.patch tools/Makefile tools/Rules.mk tools/blktap/blktaplib.c tools/blktap/blktaplib.h tools/blktap/parallax/Makefile tools/blktap/parallax/block-async.h tools/blktap/parallax/blockstore.h tools/console/Makefile tools/console/client/main.c tools/console/daemon/io.c tools/console/daemon/io.h tools/console/daemon/main.c tools/console/daemon/utils.c tools/console/daemon/utils.h tools/console/testsuite/Makefile tools/console/testsuite/README tools/console/testsuite/console-dom0.c tools/console/testsuite/console-domU.c tools/console/testsuite/procpipe.c tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c tools/debugger/gdb/gdbbuild tools/debugger/libxendebug/Makefile tools/debugger/libxendebug/xendebug.c tools/debugger/libxendebug/xendebug.h tools/debugger/pdb/Domain.ml tools/debugger/pdb/Domain.mli tools/debugger/pdb/Makefile tools/debugger/pdb/PDB.ml tools/debugger/pdb/Process.ml tools/debugger/pdb/Process.mli tools/debugger/pdb/Util.ml tools/debugger/pdb/Xen_domain.ml tools/debugger/pdb/Xen_domain.mli tools/debugger/pdb/debugger.ml tools/debugger/pdb/linux-2.6-module/Makefile tools/debugger/pdb/linux-2.6-module/debug.c tools/debugger/pdb/linux-2.6-module/module.c tools/debugger/pdb/linux-2.6-module/pdb_debug.h tools/debugger/pdb/linux-2.6-module/pdb_module.h tools/debugger/pdb/linux-2.6-patches/Makefile tools/debugger/pdb/linux-2.6-patches/i386_ksyms.patch tools/debugger/pdb/linux-2.6-patches/kdebug.patch tools/debugger/pdb/linux-2.6-patches/makefile.patch tools/debugger/pdb/linux-2.6-patches/ptrace.patch tools/debugger/pdb/linux-2.6-patches/traps.patch tools/debugger/pdb/pdb_caml_domain.c tools/debugger/pdb/pdb_caml_evtchn.c tools/debugger/pdb/pdb_caml_process.c tools/debugger/pdb/pdb_caml_xc.c tools/debugger/pdb/pdb_caml_xcs.c tools/debugger/pdb/pdb_caml_xen.h tools/debugger/pdb/pdb_xen.c tools/debugger/pdb/readme tools/debugger/pdb/server.ml tools/examples/Makefile tools/examples/README tools/examples/backend.hotplug tools/examples/network-bridge tools/examples/vif-bridge tools/examples/xend-config.sxp tools/examples/xmexample.vmx tools/examples/xmexample1 tools/examples/xmexample2 tools/examples/xmexample3 tools/firmware/acpi/acpi2_0.h tools/firmware/rombios/rombios.c tools/firmware/vmxassist/vm86.c tools/ioemu/cpu-all.h tools/ioemu/exec.c tools/ioemu/hw/i8254.c tools/ioemu/hw/i8259.c tools/ioemu/hw/ide.c tools/ioemu/hw/ioapic.h tools/ioemu/hw/pc.c tools/ioemu/hw/pckbd.c tools/ioemu/hw/pcnet.c tools/ioemu/hw/pcnet.h tools/ioemu/hw/vga.c tools/ioemu/monitor.c tools/ioemu/target-i386-dm/Makefile tools/ioemu/target-i386-dm/helper2.c tools/ioemu/target-i386-dm/qemu-dm.debug tools/ioemu/vl.c tools/ioemu/vl.h tools/ioemu/vnc.c tools/libxc/Makefile tools/libxc/linux_boot_params.h tools/libxc/xc_core.c tools/libxc/xc_domain.c tools/libxc/xc_gnttab.c tools/libxc/xc_linux_build.c tools/libxc/xc_linux_restore.c tools/libxc/xc_linux_save.c tools/libxc/xc_load_aout9.c tools/libxc/xc_load_bin.c tools/libxc/xc_load_elf.c tools/libxc/xc_private.c tools/libxc/xc_private.h tools/libxc/xc_ptrace.c tools/libxc/xc_vmx_build.c tools/libxc/xenctrl.h tools/libxc/xenguest.h tools/libxc/xg_private.c tools/libxc/xg_private.h tools/misc/Makefile tools/misc/cpuperf/Makefile tools/misc/cpuperf/cpuperf.c tools/misc/cpuperf/cpuperf_xeno.h tools/misc/mbootpack/Makefile tools/misc/mbootpack/buildimage.c tools/misc/mbootpack/mbootpack.c tools/misc/mbootpack/mbootpack.h tools/misc/xc_shadow.c tools/misc/xend tools/misc/xenperf.c tools/python/setup.py tools/python/xen/lowlevel/xc/xc.c tools/python/xen/lowlevel/xs/xs.c tools/python/xen/lowlevel/xu/xu.c tools/python/xen/sv/CreateDomain.py tools/python/xen/sv/DomInfo.py tools/python/xen/sv/GenTabbed.py tools/python/xen/sv/HTMLBase.py tools/python/xen/sv/Main.py tools/python/xen/sv/NodeInfo.py tools/python/xen/sv/RestoreDomain.py tools/python/xen/sv/Wizard.py tools/python/xen/sv/__init__.py tools/python/xen/sv/util.py tools/python/xen/util/Brctl.py tools/python/xen/web/SrvBase.py tools/python/xen/web/SrvDir.py tools/python/xen/web/__init__.py tools/python/xen/web/connection.py tools/python/xen/web/httpserver.py tools/python/xen/web/protocol.py tools/python/xen/web/reactor.py tools/python/xen/web/resource.py tools/python/xen/web/static.py tools/python/xen/web/tcp.py tools/python/xen/web/unix.py tools/python/xen/xend/Args.py tools/python/xen/xend/EventServer.py tools/python/xen/xend/PrettyPrint.py tools/python/xen/xend/Vifctl.py tools/python/xen/xend/XendCheckpoint.py tools/python/xen/xend/XendClient.py tools/python/xen/xend/XendDB.py tools/python/xen/xend/XendDmesg.py tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/XendError.py tools/python/xen/xend/XendLogging.py tools/python/xen/xend/XendNode.py tools/python/xen/xend/XendProtocol.py tools/python/xen/xend/XendRoot.py tools/python/xen/xend/XendVnet.py tools/python/xen/xend/encode.py tools/python/xen/xend/image.py tools/python/xen/xend/scheduler.py tools/python/xen/xend/server/SrvDaemon.py tools/python/xen/xend/server/SrvDmesg.py tools/python/xen/xend/server/SrvDomain.py tools/python/xen/xend/server/SrvDomainDir.py tools/python/xen/xend/server/SrvNode.py tools/python/xen/xend/server/SrvRoot.py tools/python/xen/xend/server/SrvServer.py tools/python/xen/xend/server/SrvVnetDir.py tools/python/xen/xend/server/SrvXendLog.py tools/python/xen/xend/server/blkif.py tools/python/xen/xend/server/channel.py tools/python/xen/xend/server/controller.py tools/python/xen/xend/server/event.py tools/python/xen/xend/server/messages.py tools/python/xen/xend/server/netif.py tools/python/xen/xend/server/params.py tools/python/xen/xend/server/pciif.py tools/python/xen/xend/server/relocate.py tools/python/xen/xend/server/tpmif.py tools/python/xen/xend/sxp.py tools/python/xen/xend/uuid.py tools/python/xen/xend/xenstore/__init__.py tools/python/xen/xend/xenstore/xsnode.py tools/python/xen/xend/xenstore/xsobj.py tools/python/xen/xend/xenstore/xsresource.py tools/python/xen/xm/create.py tools/python/xen/xm/destroy.py tools/python/xen/xm/help.py tools/python/xen/xm/main.py tools/python/xen/xm/migrate.py tools/python/xen/xm/opts.py tools/python/xen/xm/shutdown.py tools/python/xen/xm/sysrq.py tools/security/Makefile tools/security/example.txt tools/security/install.txt tools/security/policies/chwall/chwall-security_label_template.xml tools/security/policies/chwall/chwall-security_policy.xml tools/security/policies/chwall_ste/chwall_ste-security_label_template.xml tools/security/policies/chwall_ste/chwall_ste-security_policy.xml tools/security/policies/null/null-security_label_template.xml tools/security/policies/null/null-security_policy.xml tools/security/policies/security_policy.xsd tools/security/policies/ste/ste-security_label_template.xml tools/security/policies/ste/ste-security_policy.xml tools/security/policy.txt tools/security/readme.txt tools/security/secpol_compat.h tools/security/secpol_tool.c tools/security/secpol_xml2bin.c tools/security/secpol_xml2bin.h tools/security/setlabel.sh tools/security/updategrub.sh tools/sv/Makefile tools/sv/images/destroy.png tools/sv/images/finish.png tools/sv/images/next.png tools/sv/images/pause.png tools/sv/images/previous.png tools/sv/images/reboot.png tools/sv/images/shutdown.png tools/sv/images/small-destroy.png tools/sv/images/small-pause.png tools/sv/images/small-unpause.png tools/sv/images/unpause.png tools/sv/images/xen.png tools/sv/inc/script.js tools/sv/inc/style.css tools/sv/index.psp tools/vnet/00INSTALL tools/vnet/Makefile tools/vnet/doc/vnet-module.txt tools/vnet/doc/vnet-xend.txt tools/vnet/examples/Makefile tools/vnet/examples/network-vnet tools/vnet/examples/vnet97.sxp tools/vnet/examples/vnet98.sxp tools/vnet/examples/vnet99.sxp tools/vnet/libxutil/Makefile tools/vnet/libxutil/debug.h tools/vnet/libxutil/sxpr.c tools/vnet/libxutil/sxpr.h tools/vnet/libxutil/sxpr_parser.c tools/vnet/libxutil/sxpr_parser.h tools/vnet/libxutil/sys_string.c tools/vnet/libxutil/sys_string.h tools/vnet/vnet-module/00README tools/vnet/vnet-module/Makefile tools/vnet/vnet-module/Makefile-2.4 tools/vnet/vnet-module/Makefile-2.6 tools/vnet/vnet-module/Makefile.ver tools/vnet/vnet-module/Makefile.vnet tools/vnet/vnet-module/etherip.c tools/vnet/vnet-module/if_etherip.h tools/vnet/vnet-module/if_varp.h tools/vnet/vnet-module/skb_util.h tools/vnet/vnet-module/tunnel.c tools/vnet/vnet-module/tunnel.h tools/vnet/vnet-module/varp.c tools/vnet/vnet-module/varp.h tools/vnet/vnet-module/varp_socket.c tools/vnet/vnet-module/vif.c tools/vnet/vnet-module/vif.h tools/vnet/vnet-module/vnet.c tools/vnet/vnet-module/vnet.h tools/vnet/vnet-module/vnet_dev.c tools/vnet/vnet-module/vnet_dev.h tools/vnet/vnet-module/vnet_ioctl.c tools/vnet/vnetd/Makefile tools/vnet/vnetd/vcache.c tools/vnet/vnetd/vcache.h tools/vnet/vnetd/vnetd.c tools/vnet/vnetd/vnetd.h tools/vtpm/Makefile tools/vtpm/README tools/vtpm/Rules.mk tools/vtpm/tpm_emulator.patch tools/vtpm/vtpm.patch tools/vtpm_manager/COPYING tools/vtpm_manager/Makefile tools/vtpm_manager/README tools/vtpm_manager/Rules.mk tools/vtpm_manager/crypto/Makefile tools/vtpm_manager/crypto/crypto.c tools/vtpm_manager/crypto/crypto.h tools/vtpm_manager/crypto/hash.c tools/vtpm_manager/crypto/rsa.c tools/vtpm_manager/crypto/sym_crypto.c tools/vtpm_manager/crypto/sym_crypto.h tools/vtpm_manager/manager/Makefile tools/vtpm_manager/manager/dmictl.c tools/vtpm_manager/manager/securestorage.c tools/vtpm_manager/manager/tpmpassthrough.c tools/vtpm_manager/manager/vtpm_manager.c tools/vtpm_manager/manager/vtpm_manager.h tools/vtpm_manager/manager/vtpmd.c tools/vtpm_manager/manager/vtpmpriv.h tools/vtpm_manager/manager/vtsp.c tools/vtpm_manager/manager/vtsp.h tools/vtpm_manager/tcs/Makefile tools/vtpm_manager/tcs/contextmgr.c tools/vtpm_manager/tcs/contextmgr.h tools/vtpm_manager/tcs/tcs.c tools/vtpm_manager/tcs/tcs.h tools/vtpm_manager/tcs/tpmddl.h tools/vtpm_manager/tcs/transmit.c tools/vtpm_manager/util/Makefile tools/vtpm_manager/util/bsg.c tools/vtpm_manager/util/bsg.h tools/vtpm_manager/util/buffer.c tools/vtpm_manager/util/buffer.h tools/vtpm_manager/util/depend tools/vtpm_manager/util/hashtable.c tools/vtpm_manager/util/hashtable.h tools/vtpm_manager/util/hashtable_itr.c tools/vtpm_manager/util/hashtable_itr.h tools/vtpm_manager/util/hashtable_private.h tools/vtpm_manager/util/log.c tools/vtpm_manager/util/log.h tools/vtpm_manager/util/tcg.h tools/xcs/Makefile tools/xcs/dump.h tools/xcs/xcs.h tools/xcs/xcsdump.c tools/xcutils/Makefile tools/xcutils/xc_restore.c tools/xcutils/xc_save.c tools/xenstat/Makefile tools/xenstat/libxenstat/COPYING tools/xenstat/libxenstat/Makefile tools/xenstat/libxenstat/bindings/swig/perl/.empty tools/xenstat/libxenstat/bindings/swig/python/.empty tools/xenstat/libxenstat/bindings/swig/xenstat.i tools/xenstat/libxenstat/src/xen-interface.c tools/xenstat/libxenstat/src/xen-interface.h tools/xenstat/libxenstat/src/xenstat.c tools/xenstat/libxenstat/src/xenstat.h tools/xenstat/xentop/Makefile tools/xenstat/xentop/TODO tools/xenstat/xentop/xentop.1 tools/xenstat/xentop/xentop.c tools/xenstore/COPYING tools/xenstore/Makefile tools/xenstore/TODO tools/xenstore/testsuite/01simple.test tools/xenstore/testsuite/02directory.test tools/xenstore/testsuite/03write.test tools/xenstore/testsuite/04rm.test tools/xenstore/testsuite/05filepermissions.test tools/xenstore/testsuite/06dirpermissions.test tools/xenstore/testsuite/07watch.test tools/xenstore/testsuite/08transaction.slowtest tools/xenstore/testsuite/08transaction.test tools/xenstore/testsuite/09domain.test tools/xenstore/testsuite/10domain-homedir.test tools/xenstore/testsuite/11domain-watch.test tools/xenstore/testsuite/12readonly.test tools/xenstore/testsuite/13watch-ack.test tools/xenstore/testsuite/14complexperms.test tools/xenstore/testsuite/15nowait.test tools/xenstore/testsuite/test.sh tools/xenstore/testsuite/vg-suppressions tools/xenstore/utils.c tools/xenstore/utils.h tools/xenstore/xenstored.h tools/xenstore/xenstored_core.c tools/xenstore/xenstored_core.h tools/xenstore/xenstored_domain.c tools/xenstore/xenstored_domain.h tools/xenstore/xenstored_transaction.c tools/xenstore/xenstored_transaction.h tools/xenstore/xenstored_watch.c tools/xenstore/xenstored_watch.h tools/xenstore/xs.c tools/xenstore/xs.h tools/xenstore/xs_crashme.c tools/xenstore/xs_dom0_test.c tools/xenstore/xs_lib.c tools/xenstore/xs_lib.h tools/xenstore/xs_random.c tools/xenstore/xs_test.c tools/xentrace/Makefile tools/xentrace/formats tools/xentrace/xenctx.c tools/xentrace/xentrace.c xen/Makefile xen/Rules.mk xen/acm/acm_core.c xen/acm/acm_policy.c xen/arch/ia64/Makefile xen/arch/ia64/Rules.mk xen/arch/ia64/asm-offsets.c xen/arch/ia64/asm-xsi-offsets.c xen/arch/ia64/dom_fw.c xen/arch/ia64/domain.c xen/arch/ia64/grant_table.c xen/arch/ia64/hypercall.c xen/arch/ia64/hyperprivop.S xen/arch/ia64/ivt.S xen/arch/ia64/linux-xen/entry.S xen/arch/ia64/linux-xen/head.S xen/arch/ia64/linux-xen/irq_ia64.c xen/arch/ia64/linux-xen/setup.c xen/arch/ia64/linux/minstate.h xen/arch/ia64/mmio.c xen/arch/ia64/pal_emul.c xen/arch/ia64/pcdp.c xen/arch/ia64/process.c xen/arch/ia64/regionreg.c xen/arch/ia64/tools/mkbuildtree xen/arch/ia64/vcpu.c xen/arch/ia64/vlsapic.c xen/arch/ia64/vmmu.c xen/arch/ia64/vmx_hypercall.c xen/arch/ia64/vmx_init.c xen/arch/ia64/vmx_ivt.S xen/arch/ia64/vmx_phy_mode.c xen/arch/ia64/vmx_support.c xen/arch/ia64/vmx_vcpu.c xen/arch/ia64/vmx_virt.c xen/arch/ia64/vtlb.c xen/arch/ia64/xenasm.S xen/arch/ia64/xenirq.c xen/arch/ia64/xenmem.c xen/arch/ia64/xenmisc.c xen/arch/ia64/xensetup.c xen/arch/ia64/xentime.c xen/arch/x86/Makefile xen/arch/x86/acpi/boot.c xen/arch/x86/apic.c xen/arch/x86/audit.c xen/arch/x86/cdb.c xen/arch/x86/cpu/amd.c xen/arch/x86/cpu/common.c xen/arch/x86/dom0_ops.c xen/arch/x86/domain.c xen/arch/x86/domain_build.c xen/arch/x86/genapic/es7000plat.c xen/arch/x86/i8259.c xen/arch/x86/io_apic.c xen/arch/x86/mm.c xen/arch/x86/mpparse.c xen/arch/x86/physdev.c xen/arch/x86/setup.c xen/arch/x86/shadow.c xen/arch/x86/shadow32.c xen/arch/x86/shadow_public.c xen/arch/x86/smpboot.c xen/arch/x86/time.c xen/arch/x86/traps.c xen/arch/x86/vmx.c xen/arch/x86/vmx_intercept.c xen/arch/x86/vmx_io.c xen/arch/x86/vmx_platform.c xen/arch/x86/vmx_vmcs.c xen/arch/x86/x86_32/asm-offsets.c xen/arch/x86/x86_32/entry.S xen/arch/x86/x86_32/mm.c xen/arch/x86/x86_32/traps.c xen/arch/x86/x86_64/asm-offsets.c xen/arch/x86/x86_64/entry.S xen/arch/x86/x86_64/mm.c xen/arch/x86/x86_64/traps.c xen/common/Makefile xen/common/ac_timer.c xen/common/dom0_ops.c xen/common/domain.c xen/common/event_channel.c xen/common/grant_table.c xen/common/kernel.c xen/common/lib.c xen/common/memory.c xen/common/multicall.c xen/common/page_alloc.c xen/common/perfc.c xen/common/sched_sedf.c xen/common/schedule.c xen/common/symbols.c xen/common/trace.c xen/common/xmalloc.c xen/drivers/char/console.c xen/drivers/char/ns16550.c xen/include/acm/acm_core.h xen/include/acm/acm_hooks.h xen/include/asm-ia64/config.h xen/include/asm-ia64/domain.h xen/include/asm-ia64/event.h xen/include/asm-ia64/ia64_int.h xen/include/asm-ia64/linux-xen/asm/pal.h xen/include/asm-ia64/linux-xen/asm/processor.h xen/include/asm-ia64/mm.h xen/include/asm-ia64/mmu_context.h xen/include/asm-ia64/privop.h xen/include/asm-ia64/regionreg.h xen/include/asm-ia64/regs.h xen/include/asm-ia64/serial.h xen/include/asm-ia64/tlb.h xen/include/asm-ia64/vcpu.h xen/include/asm-ia64/vmmu.h xen/include/asm-ia64/vmx.h xen/include/asm-ia64/vmx_uaccess.h xen/include/asm-ia64/vmx_vcpu.h xen/include/asm-ia64/vmx_vpd.h xen/include/asm-ia64/xenprocessor.h xen/include/asm-ia64/xensystem.h xen/include/asm-x86/apicdef.h xen/include/asm-x86/asm_defns.h xen/include/asm-x86/bitops.h xen/include/asm-x86/config.h xen/include/asm-x86/e820.h xen/include/asm-x86/event.h xen/include/asm-x86/fixmap.h xen/include/asm-x86/genapic.h xen/include/asm-x86/hpet.h xen/include/asm-x86/io.h xen/include/asm-x86/mach-bigsmp/mach_apic.h xen/include/asm-x86/mach-default/mach_apic.h xen/include/asm-x86/mach-es7000/mach_apic.h xen/include/asm-x86/mach-generic/mach_apic.h xen/include/asm-x86/mach-summit/mach_apic.h xen/include/asm-x86/mach-summit/mach_mpparse.h xen/include/asm-x86/mm.h xen/include/asm-x86/page.h xen/include/asm-x86/shadow.h xen/include/asm-x86/shadow_64.h xen/include/asm-x86/shadow_public.h xen/include/asm-x86/time.h xen/include/asm-x86/types.h xen/include/asm-x86/uaccess.h xen/include/asm-x86/vmx.h xen/include/asm-x86/vmx_platform.h xen/include/asm-x86/vmx_virpit.h xen/include/asm-x86/vmx_vmcs.h xen/include/asm-x86/x86_32/asm_defns.h xen/include/asm-x86/x86_32/page-3level.h xen/include/asm-x86/x86_32/uaccess.h xen/include/asm-x86/x86_64/asm_defns.h xen/include/asm-x86/x86_64/page.h xen/include/public/arch-ia64.h xen/include/public/arch-x86_32.h xen/include/public/arch-x86_64.h xen/include/public/dom0_ops.h xen/include/public/grant_table.h xen/include/public/io/blkif.h xen/include/public/io/domain_controller.h xen/include/public/io/netif.h xen/include/public/io/tpmif.h xen/include/public/memory.h xen/include/public/physdev.h xen/include/public/trace.h xen/include/public/version.h xen/include/public/xen.h xen/include/xen/ac_timer.h xen/include/xen/config.h xen/include/xen/domain.h xen/include/xen/event.h xen/include/xen/grant_table.h xen/include/xen/mm.h xen/include/xen/perfc.h xen/include/xen/perfc_defn.h xen/include/xen/sched.h xen/include/xen/serial.h xen/include/xen/symbols.h xen/include/xen/time.h xen/include/xen/trace.h xen/tools/Makefile xen/tools/symbols.c
line diff
     1.1 --- a/.hgignore	Thu Sep 01 10:08:53 2005 +0000
     1.2 +++ b/.hgignore	Thu Sep 01 10:16:14 2005 +0000
     1.3 @@ -141,6 +141,9 @@
     1.4  ^tools/vnet/vnet-module/\.tmp_versions/.*$
     1.5  ^tools/vnet/vnet-module/vnet_module\.mod\..*$
     1.6  ^tools/vnetd/vnetd$
     1.7 +^tools/vtpm/vtpm*
     1.8 +^tools/vtpm/tpm_emulator-*
     1.9 +^tools/vtpm_manager/manager/vtpm_managerd
    1.10  ^tools/web-shutdown\.tap$
    1.11  ^tools/x2d2/minixend$
    1.12  ^tools/xcs/xcs$
     2.1 --- a/Config.mk	Thu Sep 01 10:08:53 2005 +0000
     2.2 +++ b/Config.mk	Thu Sep 01 10:16:14 2005 +0000
     2.3 @@ -48,3 +48,4 @@ ACM_USE_SECURITY_POLICY ?= ACM_NULL_POLI
     2.4  # Optional components
     2.5  XENSTAT_XENTOP ?= y
     2.6  
     2.7 +VTPM_TOOLS ?= n
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/MSG	Thu Sep 01 10:16:14 2005 +0000
     3.3 @@ -0,0 +1,7 @@
     3.4 +TPM FE/BE code using xenbus (some control message stuff still there; to 
     3.5 +be removed soon). 
     3.6 +
     3.7 +Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
     3.8 +Signed-off-by: Kylene Hall <kjhall@us.ibm.com>
     3.9 +Signed-off-by: Mahadevan Gomathisankaran <gmdev@iastate.edu>
    3.10 +Signed-off-by: Steven Hand <steven@xensource.com>
     4.1 --- a/Makefile	Thu Sep 01 10:08:53 2005 +0000
     4.2 +++ b/Makefile	Thu Sep 01 10:16:14 2005 +0000
     4.3 @@ -35,11 +35,11 @@ ifeq ($(XEN_TARGET_X86_PAE),y)
     4.4  export pae=y
     4.5  endif
     4.6  
     4.7 -.PHONY:	all dist install xen tools kernels docs world clean mkpatches mrproper
     4.8 +.PHONY:	all dist install xen kernels tools docs world clean mkpatches mrproper
     4.9  .PHONY:	kbuild kdelete kclean
    4.10  
    4.11  # build and install everything into the standard system directories
    4.12 -install: install-xen install-tools install-kernels install-docs
    4.13 +install: install-xen install-kernels install-tools install-docs
    4.14  
    4.15  build: kernels
    4.16  	$(MAKE) -C xen build
    4.17 @@ -47,7 +47,7 @@ build: kernels
    4.18  	$(MAKE) -C docs build
    4.19  
    4.20  # build and install everything into local dist directory
    4.21 -dist: xen tools kernels docs
    4.22 +dist: xen kernels tools docs
    4.23  	$(INSTALL_DIR) $(DISTDIR)/check
    4.24  	$(INSTALL_DATA) ./COPYING $(DISTDIR)
    4.25  	$(INSTALL_DATA) ./README $(DISTDIR)
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/docs/misc/vtpm.txt	Thu Sep 01 10:16:14 2005 +0000
     9.3 @@ -0,0 +1,122 @@
     9.4 +Copyright: IBM Corporation (C), Intel Corporation
     9.5 +17 August 2005
     9.6 +Authors: Stefan Berger <stefanb@us.ibm.com> (IBM), 
     9.7 +         Employees of Intel Corp
     9.8 +
     9.9 +This document gives a short introduction to the virtual TPM support
    9.10 +in XEN and goes as far as connecting a user domain to a virtual TPM
    9.11 +instance and doing a short test to verify success. It is assumed
    9.12 +that the user is fairly familiar with compiling and installing XEN
    9.13 +and Linux on a machine. 
    9.14 + 
    9.15 +Production Prerequisites: An x86-based machine machine with an ATMEL or
    9.16 +National Semiconductor (NSC) TPM on the motherboard.
    9.17 +Development Prerequisites: An emulator for TESTING ONLY is provided
    9.18 +
    9.19 +
    9.20 +Compiling XEN tree:
    9.21 +-------------------
    9.22 +
    9.23 +Compile the XEN tree as usual.
    9.24 +
    9.25 +make uninstall; make mrproper; make install 
    9.26 +
    9.27 +After compiling the tree, verify that in the linux-2.6.XX-xen0/.config 
    9.28 +file at least the following entries are set as below (they should be set
    9.29 +by default):
    9.30 +
    9.31 +CONFIG_XEN_TPMDEV_BACKEND=y
    9.32 +CONFIG_XEN_TPMDEV_GRANT=y
    9.33 +
    9.34 +CONFIG_TCG_TPM=m
    9.35 +CONFIG_TCG_NSC=m
    9.36 +CONFIG_TCG_ATMEL=m
    9.37 +
    9.38 +
    9.39 +Verify that in the linux-2.6.XX-xenU/.config file at least the 
    9.40 +Following entries are set as below (they should be set by default):
    9.41 +
    9.42 +CONFIG_XEN_TPMDEV_FRONTEND=y
    9.43 +CONFIG_XEN_TPMDEV_GRANT=y
    9.44 +
    9.45 +CONFIG_TCG_TPM=y
    9.46 +CONFIG_TCG_XEN=y
    9.47 +
    9.48 +
    9.49 +Reboot the machine with the created XEN-0 kernel.
    9.50 +
    9.51 +Note: If you do not want any TPM-related code compiled into your
    9.52 +kernel or built as module then comment all the above lines like
    9.53 +this example:
    9.54 +# CONFIG_TCG_TPM is not set
    9.55 +
    9.56 +
    9.57 +Modifying VM Configuration files:
    9.58 +---------------------------------
    9.59 +
    9.60 +VM configuration files need to be adapted to make a TPM instance
    9.61 +available to a user domain. The following VM configuration file is
    9.62 +an example of how a user domain can be configured to have a TPM
    9.63 +available. It works similar to making a network interface
    9.64 +available to a domain.
    9.65 +
    9.66 +kernel = "/boot/vmlinuz-2.6.12-xenU"
    9.67 +ramdisk = "/xen/initrd_domU/U1_ramdisk.img"
    9.68 +memory = 32
    9.69 +name = "TPMUserDomain0"
    9.70 +vtpm = ['instance=1,backend=0']
    9.71 +root = "/dev/ram0 cosole=tty ro"
    9.72 +vif = ['backend=0']
    9.73 +
    9.74 +In the above configuration file the line 'vtpm = ...' provides
    9.75 +information about the domain where the virtual TPM is running and
    9.76 +where the TPM backend has been compiled into - this has to be 
    9.77 +domain 0  at the moment - and which TPM instance the user domain
    9.78 +is supposed to talk to. Note that each running VM must use a 
    9.79 +different instance and that using instance 0 is NOT allowed.
    9.80 +
    9.81 +Note: If you do not want TPM functionality for your user domain simply
    9.82 +leave out the 'vtpm' line in the configuration file.
    9.83 +
    9.84 +
    9.85 +Running the TPM:
    9.86 +----------------
    9.87 +
    9.88 +To run the vTPM, dev device /dev/vtpm must be available.
    9.89 +Verify that 'ls -l /dev/vtpm' shows the following output:
    9.90 +
    9.91 +crw-------  1 root root 10, 225 Aug 11 06:58 /dev/vtpm
    9.92 +
    9.93 +If it is not available, run the following command as 'root'.
    9.94 +mknod /dev/vtpm c 10 225
    9.95 +
    9.96 +Make sure that the vTPM is running in domain 0. To do this run the
    9.97 +following
    9.98 +
    9.99 +/usr/bin/vtpm_managerd
   9.100 +
   9.101 +Start a user domain using the 'xm create' command. Once you are in the
   9.102 +shell of the user domain, you should be able to do the following:
   9.103 +
   9.104 +> cd /sys/devices/vtpm
   9.105 +> ls
   9.106 +cancel  caps   pcrs    pubek
   9.107 +> cat pcrs
   9.108 +PCR-00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   9.109 +PCR-01: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   9.110 +PCR-02: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   9.111 +PCR-03: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   9.112 +PCR-04: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   9.113 +PCR-05: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   9.114 +PCR-06: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   9.115 +PCR-07: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   9.116 +PCR-08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   9.117 +[...]
   9.118 +
   9.119 +At this point the user domain has been sucessfully connected to its
   9.120 +virtual TPM instance.
   9.121 +
   9.122 +For further information please read the documentation in 
   9.123 +tools/vtpm_manager/README and tools/vtpm/README
   9.124 +
   9.125 +Stefan Berger and Employees of the Intel Corp
   101.1 --- a/linux-2.6-xen-sparse/arch/xen/Kconfig	Thu Sep 01 10:08:53 2005 +0000
   101.2 +++ b/linux-2.6-xen-sparse/arch/xen/Kconfig	Thu Sep 01 10:16:14 2005 +0000
   101.3 @@ -70,6 +70,27 @@ config XEN_NETDEV_BACKEND
   101.4  	  network devices to other guests via a high-performance shared-memory
   101.5  	  interface.
   101.6  
   101.7 +config XEN_TPMDEV_FRONTEND
   101.8 +        bool "TPM-device frontend driver"
   101.9 +        default n
  101.10 +        help
  101.11 +          The TPM-device frontend driver.
  101.12 +
  101.13 +config XEN_TPMDEV_BACKEND
  101.14 +        bool "TPM-device backend driver"
  101.15 +        default n
  101.16 +        help
  101.17 +          The TPM-device backend driver
  101.18 +
  101.19 +config XEN_TPMDEV_CLOSE_IF_VTPM_FAILS
  101.20 +        bool "TPM backend closes upon vTPM failure"
  101.21 +        depends on XEN_TPMDEV_BACKEND
  101.22 +        default n
  101.23 +        help
  101.24 +          The TPM backend closes the channel if the vTPM in userspace indicates
  101.25 +          a failure. The corresponding domain's channel will be closed.
  101.26 +          Say Y if you want this feature.
  101.27 +
  101.28  config XEN_BLKDEV_FRONTEND
  101.29  	bool "Block-device frontend driver"
  101.30  	default y
   102.1 --- a/linux-2.6-xen-sparse/arch/xen/Kconfig.drivers	Thu Sep 01 10:08:53 2005 +0000
   102.2 +++ b/linux-2.6-xen-sparse/arch/xen/Kconfig.drivers	Thu Sep 01 10:16:14 2005 +0000
   102.3 @@ -49,6 +49,10 @@ source "drivers/infiniband/Kconfig"
   102.4  endif
   102.5  
   102.6  if !XEN_PHYSDEV_ACCESS
   102.7 +source "drivers/char/tpm/Kconfig.domU"
   102.8 +endif
   102.9 +
  102.10 +if !XEN_PHYSDEV_ACCESS
  102.11  
  102.12  menu "Character devices"
  102.13  
   105.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32	Thu Sep 01 10:08:53 2005 +0000
   105.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32	Thu Sep 01 10:16:14 2005 +0000
   105.3 @@ -15,6 +15,8 @@ CONFIG_XEN_PHYSDEV_ACCESS=y
   105.4  CONFIG_XEN_BLKDEV_BACKEND=y
   105.5  # CONFIG_XEN_BLKDEV_TAP_BE is not set
   105.6  CONFIG_XEN_NETDEV_BACKEND=y
   105.7 +# CONFIG_XEN_TPMDEV_FRONTEND is not set
   105.8 +# CONFIG_XEN_TPMDEV_BACKEND is not set
   105.9  CONFIG_XEN_BLKDEV_FRONTEND=y
  105.10  CONFIG_XEN_NETDEV_FRONTEND=y
  105.11  CONFIG_XEN_NETDEV_GRANT_TX=y
   106.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64	Thu Sep 01 10:08:53 2005 +0000
   106.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64	Thu Sep 01 10:16:14 2005 +0000
   106.3 @@ -15,6 +15,8 @@ CONFIG_XEN_PHYSDEV_ACCESS=y
   106.4  CONFIG_XEN_BLKDEV_BACKEND=y
   106.5  # CONFIG_XEN_BLKDEV_TAP_BE is not set
   106.6  CONFIG_XEN_NETDEV_BACKEND=y
   106.7 +# CONFIG_XEN_TPMDEV_FRONTEND is not set
   106.8 +# CONFIG_XEN_TPMDEV_BACKEND is not set
   106.9  CONFIG_XEN_BLKDEV_FRONTEND=y
  106.10  CONFIG_XEN_NETDEV_FRONTEND=y
  106.11  CONFIG_XEN_NETDEV_GRANT_TX=y
   107.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32	Thu Sep 01 10:08:53 2005 +0000
   107.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32	Thu Sep 01 10:16:14 2005 +0000
   107.3 @@ -12,6 +12,8 @@ CONFIG_NO_IDLE_HZ=y
   107.4  #
   107.5  # CONFIG_XEN_PRIVILEGED_GUEST is not set
   107.6  # CONFIG_XEN_PHYSDEV_ACCESS is not set
   107.7 +# CONFIG_XEN_TPMDEV_FRONTEND is not set
   107.8 +# CONFIG_XEN_TPMDEV_BACKEND is not set
   107.9  CONFIG_XEN_BLKDEV_FRONTEND=y
  107.10  CONFIG_XEN_NETDEV_FRONTEND=y
  107.11  CONFIG_XEN_NETDEV_GRANT_TX=y
  107.12 @@ -336,6 +338,7 @@ CONFIG_NETDEVICES=y
  107.13  CONFIG_UNIX98_PTYS=y
  107.14  CONFIG_LEGACY_PTYS=y
  107.15  CONFIG_LEGACY_PTY_COUNT=256
  107.16 +# CONFIG_TCG_TPM is not set
  107.17  
  107.18  #
  107.19  # Character devices
   108.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64	Thu Sep 01 10:08:53 2005 +0000
   108.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64	Thu Sep 01 10:16:14 2005 +0000
   108.3 @@ -12,6 +12,8 @@ CONFIG_NO_IDLE_HZ=y
   108.4  #
   108.5  # CONFIG_XEN_PRIVILEGED_GUEST is not set
   108.6  # CONFIG_XEN_PHYSDEV_ACCESS is not set
   108.7 +# CONFIG_XEN_TPMDEV_FRONTEND is not set
   108.8 +# CONFIG_XEN_TPMDEV_BACKEND is not set
   108.9  CONFIG_XEN_BLKDEV_FRONTEND=y
  108.10  CONFIG_XEN_NETDEV_FRONTEND=y
  108.11  CONFIG_XEN_NETDEV_GRANT_TX=y
  108.12 @@ -662,6 +664,7 @@ CONFIG_NETCONSOLE=m
  108.13  CONFIG_INPUT=m
  108.14  CONFIG_UNIX98_PTYS=y
  108.15  # CONFIG_LEGACY_PTYS is not set
  108.16 +# CONFIG_TCG_TPM is not set
  108.17  
  108.18  #
  108.19  # Character devices
   109.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32	Thu Sep 01 10:08:53 2005 +0000
   109.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32	Thu Sep 01 10:16:14 2005 +0000
   109.3 @@ -15,6 +15,8 @@ CONFIG_XEN_PHYSDEV_ACCESS=y
   109.4  CONFIG_XEN_BLKDEV_BACKEND=y
   109.5  # CONFIG_XEN_BLKDEV_TAP_BE is not set
   109.6  CONFIG_XEN_NETDEV_BACKEND=y
   109.7 +# CONFIG_XEN_TPMDEV_FRONTEND is not set
   109.8 +# CONFIG_XEN_TPMDEV_BACKEND is not set
   109.9  CONFIG_XEN_BLKDEV_FRONTEND=y
  109.10  CONFIG_XEN_NETDEV_FRONTEND=y
  109.11  CONFIG_XEN_NETDEV_GRANT_TX=y
  109.12 @@ -1855,9 +1857,7 @@ CONFIG_HANGCHECK_TIMER=m
  109.13  #
  109.14  # TPM devices
  109.15  #
  109.16 -CONFIG_TCG_TPM=m
  109.17 -CONFIG_TCG_NSC=m
  109.18 -CONFIG_TCG_ATMEL=m
  109.19 +# CONFIG_TCG_TPM is not set
  109.20  
  109.21  #
  109.22  # I2C support
   110.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64	Thu Sep 01 10:08:53 2005 +0000
   110.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64	Thu Sep 01 10:16:14 2005 +0000
   110.3 @@ -15,6 +15,8 @@ CONFIG_XEN_PHYSDEV_ACCESS=y
   110.4  CONFIG_XEN_BLKDEV_BACKEND=y
   110.5  # CONFIG_XEN_BLKDEV_TAP_BE is not set
   110.6  CONFIG_XEN_NETDEV_BACKEND=y
   110.7 +# CONFIG_XEN_TPMDEV_FRONTEND is not set
   110.8 +# CONFIG_XEN_TPMDEV_BACKEND is not set
   110.9  CONFIG_XEN_BLKDEV_FRONTEND=y
  110.10  CONFIG_XEN_NETDEV_FRONTEND=y
  110.11  CONFIG_XEN_NETDEV_GRANT_TX=y
   202.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   202.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig.domU	Thu Sep 01 10:16:14 2005 +0000
   202.3 @@ -0,0 +1,30 @@
   202.4 +#
   202.5 +# TPM device configuration
   202.6 +#
   202.7 +
   202.8 +menu "TPM devices"
   202.9 +
  202.10 +config TCG_TPM
  202.11 +	tristate "TPM Support for XEN"
  202.12 +	depends on ARCH_XEN && !XEN_PHYSDEV_ACCESS
  202.13 +	---help---
  202.14 +	  If you want to make TPM security available in your system,
  202.15 +	  say Yes and it will be accessible from within a user domain.  For
  202.16 +	  more information see <http://www.trustedcomputinggroup.org>.
  202.17 +	  An implementation of the Trusted Software Stack (TSS), the
  202.18 +	  userspace enablement piece of the specification, can be
  202.19 +	  obtained at: <http://sourceforge.net/projects/trousers>.  To
  202.20 +	  compile this driver as a module, choose M here; the module
  202.21 +	  will be called tpm. If unsure, say N.
  202.22 +
  202.23 +config TCG_XEN
  202.24 +	tristate "XEN TPM Interface"
  202.25 +	depends on TCG_TPM && ARCH_XEN
  202.26 +	---help---
  202.27 +	  If you want to make TPM support available to a Xen
  202.28 +	  user domain, say Yes and it will
  202.29 +          be accessible from within Linux. To compile this driver
  202.30 +          as a module, choose M here; the module will be called
  202.31 +          tpm_xen.
  202.32 +
  202.33 +endmenu
   203.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   203.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/Makefile	Thu Sep 01 10:16:14 2005 +0000
   203.3 @@ -0,0 +1,12 @@
   203.4 +#
   203.5 +# Makefile for the kernel tpm device drivers.
   203.6 +#
   203.7 +ifeq ($(CONFIG_XEN_PHYSDEV_ACCESS),y)
   203.8 +obj-$(CONFIG_TCG_TPM) += tpm.o
   203.9 +obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
  203.10 +obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
  203.11 +obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
  203.12 +else
  203.13 +obj-$(CONFIG_TCG_TPM) += tpm_nopci.o
  203.14 +obj-$(CONFIG_TCG_XEN) += tpm_xen.o
  203.15 +endif
   204.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   204.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c	Thu Sep 01 10:16:14 2005 +0000
   204.3 @@ -0,0 +1,627 @@
   204.4 +/*
   204.5 + * Copyright (C) 2004 IBM Corporation
   204.6 + *
   204.7 + * Authors:
   204.8 + * Leendert van Doorn <leendert@watson.ibm.com>
   204.9 + * Dave Safford <safford@watson.ibm.com>
  204.10 + * Reiner Sailer <sailer@watson.ibm.com>
  204.11 + * Kylene Hall <kjhall@us.ibm.com>
  204.12 + *
  204.13 + * Maintained by: <tpmdd_devel@lists.sourceforge.net>
  204.14 + *
  204.15 + * Device driver for TCG/TCPA TPM (trusted platform module).
  204.16 + * Specifications at www.trustedcomputinggroup.org
  204.17 + *
  204.18 + * This program is free software; you can redistribute it and/or
  204.19 + * modify it under the terms of the GNU General Public License as
  204.20 + * published by the Free Software Foundation, version 2 of the
  204.21 + * License.
  204.22 + *
  204.23 + * Note, the TPM chip is not interrupt driven (only polling)
  204.24 + * and can have very long timeouts (minutes!). Hence the unusual
  204.25 + * calls to schedule_timeout.
  204.26 + *
  204.27 + */
  204.28 +
  204.29 +#include <linux/sched.h>
  204.30 +#include <linux/poll.h>
  204.31 +#include <linux/spinlock.h>
  204.32 +#include "tpm.h"
  204.33 +
  204.34 +#define	TPM_MINOR			224	/* officially assigned */
  204.35 +
  204.36 +#define	TPM_BUFSIZE			2048
  204.37 +
  204.38 +static LIST_HEAD(tpm_chip_list);
  204.39 +static DEFINE_SPINLOCK(driver_lock);
  204.40 +static int dev_mask[32];
  204.41 +
  204.42 +static void user_reader_timeout(unsigned long ptr)
  204.43 +{
  204.44 +	struct tpm_chip *chip = (struct tpm_chip *) ptr;
  204.45 +
  204.46 +	down(&chip->buffer_mutex);
  204.47 +	atomic_set(&chip->data_pending, 0);
  204.48 +	memset(chip->data_buffer, 0, TPM_BUFSIZE);
  204.49 +	up(&chip->buffer_mutex);
  204.50 +}
  204.51 +
  204.52 +void tpm_time_expired(unsigned long ptr)
  204.53 +{
  204.54 +	int *exp = (int *) ptr;
  204.55 +	*exp = 1;
  204.56 +}
  204.57 +
  204.58 +EXPORT_SYMBOL_GPL(tpm_time_expired);
  204.59 +
  204.60 +/*
  204.61 + * Internal kernel interface to transmit TPM commands
  204.62 + */
  204.63 +static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
  204.64 +			    size_t bufsiz)
  204.65 +{
  204.66 +	ssize_t len;
  204.67 +	u32 count;
  204.68 +	__be32 *native_size;
  204.69 +
  204.70 +	native_size = (__force __be32 *) (buf + 2);
  204.71 +	count = be32_to_cpu(*native_size);
  204.72 +
  204.73 +	if (count == 0)
  204.74 +		return -ENODATA;
  204.75 +	if (count > bufsiz) {
  204.76 +		dev_err(&chip->pci_dev->dev,
  204.77 +			"invalid count value %x %zx \n", count, bufsiz);
  204.78 +		return -E2BIG;
  204.79 +	}
  204.80 +
  204.81 +	down(&chip->tpm_mutex);
  204.82 +
  204.83 +	if ((len = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
  204.84 +		dev_err(&chip->pci_dev->dev,
  204.85 +			"tpm_transmit: tpm_send: error %zd\n", len);
  204.86 +		return len;
  204.87 +	}
  204.88 +
  204.89 +	down(&chip->timer_manipulation_mutex);
  204.90 +	chip->time_expired = 0;
  204.91 +	init_timer(&chip->device_timer);
  204.92 +	chip->device_timer.function = tpm_time_expired;
  204.93 +	chip->device_timer.expires = jiffies + 2 * 60 * HZ;
  204.94 +	chip->device_timer.data = (unsigned long) &chip->time_expired;
  204.95 +	add_timer(&chip->device_timer);
  204.96 +	up(&chip->timer_manipulation_mutex);
  204.97 +
  204.98 +	do {
  204.99 +		u8 status = inb(chip->vendor->base + 1);
 204.100 +		if ((status & chip->vendor->req_complete_mask) ==
 204.101 +		    chip->vendor->req_complete_val) {
 204.102 +			down(&chip->timer_manipulation_mutex);
 204.103 +			del_singleshot_timer_sync(&chip->device_timer);
 204.104 +			up(&chip->timer_manipulation_mutex);
 204.105 +			goto out_recv;
 204.106 +		}
 204.107 +		set_current_state(TASK_UNINTERRUPTIBLE);
 204.108 +		schedule_timeout(TPM_TIMEOUT);
 204.109 +		rmb();
 204.110 +	} while (!chip->time_expired);
 204.111 +
 204.112 +
 204.113 +	chip->vendor->cancel(chip);
 204.114 +	dev_err(&chip->pci_dev->dev, "Time expired\n");
 204.115 +	up(&chip->tpm_mutex);
 204.116 +	return -EIO;
 204.117 +
 204.118 +out_recv:
 204.119 +	len = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
 204.120 +	if (len < 0)
 204.121 +		dev_err(&chip->pci_dev->dev,
 204.122 +			"tpm_transmit: tpm_recv: error %zd\n", len);
 204.123 +	up(&chip->tpm_mutex);
 204.124 +	return len;
 204.125 +}
 204.126 +
 204.127 +#define TPM_DIGEST_SIZE 20
 204.128 +#define CAP_PCR_RESULT_SIZE 18
 204.129 +static u8 cap_pcr[] = {
 204.130 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
 204.131 +	0, 0, 0, 22,		/* length */
 204.132 +	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
 204.133 +	0, 0, 0, 5,
 204.134 +	0, 0, 0, 4,
 204.135 +	0, 0, 1, 1
 204.136 +};
 204.137 +
 204.138 +#define READ_PCR_RESULT_SIZE 30
 204.139 +static u8 pcrread[] = {
 204.140 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
 204.141 +	0, 0, 0, 14,		/* length */
 204.142 +	0, 0, 0, 21,		/* TPM_ORD_PcrRead */
 204.143 +	0, 0, 0, 0		/* PCR index */
 204.144 +};
 204.145 +
 204.146 +static ssize_t show_pcrs(struct device *dev, char *buf)
 204.147 +{
 204.148 +	u8 data[READ_PCR_RESULT_SIZE];
 204.149 +	ssize_t len;
 204.150 +	int i, j, index, num_pcrs;
 204.151 +	char *str = buf;
 204.152 +
 204.153 +	struct tpm_chip *chip =
 204.154 +	    pci_get_drvdata(container_of(dev, struct pci_dev, dev));
 204.155 +	if (chip == NULL)
 204.156 +		return -ENODEV;
 204.157 +
 204.158 +	memcpy(data, cap_pcr, sizeof(cap_pcr));
 204.159 +	if ((len = tpm_transmit(chip, data, sizeof(data)))
 204.160 +	    < CAP_PCR_RESULT_SIZE)
 204.161 +		return len;
 204.162 +
 204.163 +	num_pcrs = be32_to_cpu(*((__force __be32 *) (data + 14)));
 204.164 +
 204.165 +	for (i = 0; i < num_pcrs; i++) {
 204.166 +		memcpy(data, pcrread, sizeof(pcrread));
 204.167 +		index = cpu_to_be32(i);
 204.168 +		memcpy(data + 10, &index, 4);
 204.169 +		if ((len = tpm_transmit(chip, data, sizeof(data)))
 204.170 +		    < READ_PCR_RESULT_SIZE)
 204.171 +			return len;
 204.172 +		str += sprintf(str, "PCR-%02d: ", i);
 204.173 +		for (j = 0; j < TPM_DIGEST_SIZE; j++)
 204.174 +			str += sprintf(str, "%02X ", *(data + 10 + j));
 204.175 +		str += sprintf(str, "\n");
 204.176 +	}
 204.177 +	return str - buf;
 204.178 +}
 204.179 +
 204.180 +static DEVICE_ATTR(pcrs, S_IRUGO, show_pcrs, NULL);
 204.181 +
 204.182 +#define  READ_PUBEK_RESULT_SIZE 314
 204.183 +static u8 readpubek[] = {
 204.184 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
 204.185 +	0, 0, 0, 30,		/* length */
 204.186 +	0, 0, 0, 124,		/* TPM_ORD_ReadPubek */
 204.187 +};
 204.188 +
 204.189 +static ssize_t show_pubek(struct device *dev, char *buf)
 204.190 +{
 204.191 +	u8 data[READ_PUBEK_RESULT_SIZE];
 204.192 +	ssize_t len;
 204.193 +	__be32 *native_val;
 204.194 +	int i;
 204.195 +	char *str = buf;
 204.196 +
 204.197 +	struct tpm_chip *chip =
 204.198 +	    pci_get_drvdata(container_of(dev, struct pci_dev, dev));
 204.199 +	if (chip == NULL)
 204.200 +		return -ENODEV;
 204.201 +
 204.202 +	memcpy(data, readpubek, sizeof(readpubek));
 204.203 +	memset(data + sizeof(readpubek), 0, 20);	/* zero nonce */
 204.204 +
 204.205 +	if ((len = tpm_transmit(chip, data, sizeof(data))) <
 204.206 +	    READ_PUBEK_RESULT_SIZE)
 204.207 +		return len;
 204.208 +
 204.209 +	/*
 204.210 +	   ignore header 10 bytes
 204.211 +	   algorithm 32 bits (1 == RSA )
 204.212 +	   encscheme 16 bits
 204.213 +	   sigscheme 16 bits
 204.214 +	   parameters (RSA 12->bytes: keybit, #primes, expbit)
 204.215 +	   keylenbytes 32 bits
 204.216 +	   256 byte modulus
 204.217 +	   ignore checksum 20 bytes
 204.218 +	 */
 204.219 +
 204.220 +	native_val = (__force __be32 *) (data + 34);
 204.221 +
 204.222 +	str +=
 204.223 +	    sprintf(str,
 204.224 +		    "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
 204.225 +		    "Sigscheme: %02X %02X\nParameters: %02X %02X %02X %02X"
 204.226 +		    " %02X %02X %02X %02X %02X %02X %02X %02X\n"
 204.227 +		    "Modulus length: %d\nModulus: \n",
 204.228 +		    data[10], data[11], data[12], data[13], data[14],
 204.229 +		    data[15], data[16], data[17], data[22], data[23],
 204.230 +		    data[24], data[25], data[26], data[27], data[28],
 204.231 +		    data[29], data[30], data[31], data[32], data[33],
 204.232 +		    be32_to_cpu(*native_val)
 204.233 +	    );
 204.234 +
 204.235 +	for (i = 0; i < 256; i++) {
 204.236 +		str += sprintf(str, "%02X ", data[i + 39]);
 204.237 +		if ((i + 1) % 16 == 0)
 204.238 +			str += sprintf(str, "\n");
 204.239 +	}
 204.240 +	return str - buf;
 204.241 +}
 204.242 +
 204.243 +static DEVICE_ATTR(pubek, S_IRUGO, show_pubek, NULL);
 204.244 +
 204.245 +#define CAP_VER_RESULT_SIZE 18
 204.246 +static u8 cap_version[] = {
 204.247 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
 204.248 +	0, 0, 0, 18,		/* length */
 204.249 +	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
 204.250 +	0, 0, 0, 6,
 204.251 +	0, 0, 0, 0
 204.252 +};
 204.253 +
 204.254 +#define CAP_MANUFACTURER_RESULT_SIZE 18
 204.255 +static u8 cap_manufacturer[] = {
 204.256 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
 204.257 +	0, 0, 0, 22,		/* length */
 204.258 +	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
 204.259 +	0, 0, 0, 5,
 204.260 +	0, 0, 0, 4,
 204.261 +	0, 0, 1, 3
 204.262 +};
 204.263 +
 204.264 +static ssize_t show_caps(struct device *dev, char *buf)
 204.265 +{
 204.266 +	u8 data[READ_PUBEK_RESULT_SIZE];
 204.267 +	ssize_t len;
 204.268 +	char *str = buf;
 204.269 +
 204.270 +	struct tpm_chip *chip =
 204.271 +	    pci_get_drvdata(container_of(dev, struct pci_dev, dev));
 204.272 +	if (chip == NULL)
 204.273 +		return -ENODEV;
 204.274 +
 204.275 +	memcpy(data, cap_manufacturer, sizeof(cap_manufacturer));
 204.276 +
 204.277 +	if ((len = tpm_transmit(chip, data, sizeof(data))) <
 204.278 +	    CAP_MANUFACTURER_RESULT_SIZE)
 204.279 +		return len;
 204.280 +
 204.281 +	str += sprintf(str, "Manufacturer: 0x%x\n",
 204.282 +		       be32_to_cpu(*(data + 14)));
 204.283 +
 204.284 +	memcpy(data, cap_version, sizeof(cap_version));
 204.285 +
 204.286 +	if ((len = tpm_transmit(chip, data, sizeof(data))) <
 204.287 +	    CAP_VER_RESULT_SIZE)
 204.288 +		return len;
 204.289 +
 204.290 +	str +=
 204.291 +	    sprintf(str, "TCG version: %d.%d\nFirmware version: %d.%d\n",
 204.292 +		    (int) data[14], (int) data[15], (int) data[16],
 204.293 +		    (int) data[17]);
 204.294 +
 204.295 +	return str - buf;
 204.296 +}
 204.297 +
 204.298 +static DEVICE_ATTR(caps, S_IRUGO, show_caps, NULL);
 204.299 +
 204.300 +/*
 204.301 + * Device file system interface to the TPM
 204.302 + */
 204.303 +int tpm_open(struct inode *inode, struct file *file)
 204.304 +{
 204.305 +	int rc = 0, minor = iminor(inode);
 204.306 +	struct tpm_chip *chip = NULL, *pos;
 204.307 +
 204.308 +	spin_lock(&driver_lock);
 204.309 +
 204.310 +	list_for_each_entry(pos, &tpm_chip_list, list) {
 204.311 +		if (pos->vendor->miscdev.minor == minor) {
 204.312 +			chip = pos;
 204.313 +			break;
 204.314 +		}
 204.315 +	}
 204.316 +
 204.317 +	if (chip == NULL) {
 204.318 +		rc = -ENODEV;
 204.319 +		goto err_out;
 204.320 +	}
 204.321 +
 204.322 +	if (chip->num_opens) {
 204.323 +		dev_dbg(&chip->pci_dev->dev,
 204.324 +			"Another process owns this TPM\n");
 204.325 +		rc = -EBUSY;
 204.326 +		goto err_out;
 204.327 +	}
 204.328 +
 204.329 +	chip->num_opens++;
 204.330 +	pci_dev_get(chip->pci_dev);
 204.331 +
 204.332 +	spin_unlock(&driver_lock);
 204.333 +
 204.334 +	chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
 204.335 +	if (chip->data_buffer == NULL) {
 204.336 +		chip->num_opens--;
 204.337 +		pci_dev_put(chip->pci_dev);
 204.338 +		return -ENOMEM;
 204.339 +	}
 204.340 +
 204.341 +	atomic_set(&chip->data_pending, 0);
 204.342 +
 204.343 +	file->private_data = chip;
 204.344 +	return 0;
 204.345 +
 204.346 +err_out:
 204.347 +	spin_unlock(&driver_lock);
 204.348 +	return rc;
 204.349 +}
 204.350 +
 204.351 +EXPORT_SYMBOL_GPL(tpm_open);
 204.352 +
 204.353 +int tpm_release(struct inode *inode, struct file *file)
 204.354 +{
 204.355 +	struct tpm_chip *chip = file->private_data;
 204.356 +
 204.357 +	file->private_data = NULL;
 204.358 +
 204.359 +	spin_lock(&driver_lock);
 204.360 +	chip->num_opens--;
 204.361 +	spin_unlock(&driver_lock);
 204.362 +
 204.363 +	down(&chip->timer_manipulation_mutex);
 204.364 +	if (timer_pending(&chip->user_read_timer))
 204.365 +		del_singleshot_timer_sync(&chip->user_read_timer);
 204.366 +	else if (timer_pending(&chip->device_timer))
 204.367 +		del_singleshot_timer_sync(&chip->device_timer);
 204.368 +	up(&chip->timer_manipulation_mutex);
 204.369 +
 204.370 +	kfree(chip->data_buffer);
 204.371 +	atomic_set(&chip->data_pending, 0);
 204.372 +
 204.373 +	pci_dev_put(chip->pci_dev);
 204.374 +	return 0;
 204.375 +}
 204.376 +
 204.377 +EXPORT_SYMBOL_GPL(tpm_release);
 204.378 +
 204.379 +ssize_t tpm_write(struct file * file, const char __user * buf,
 204.380 +		  size_t size, loff_t * off)
 204.381 +{
 204.382 +	struct tpm_chip *chip = file->private_data;
 204.383 +	int in_size = size, out_size;
 204.384 +
 204.385 +	/* cannot perform a write until the read has cleared
 204.386 +	   either via tpm_read or a user_read_timer timeout */
 204.387 +	while (atomic_read(&chip->data_pending) != 0) {
 204.388 +		set_current_state(TASK_UNINTERRUPTIBLE);
 204.389 +		schedule_timeout(TPM_TIMEOUT);
 204.390 +	}
 204.391 +
 204.392 +	down(&chip->buffer_mutex);
 204.393 +
 204.394 +	if (in_size > TPM_BUFSIZE)
 204.395 +		in_size = TPM_BUFSIZE;
 204.396 +
 204.397 +	if (copy_from_user
 204.398 +	    (chip->data_buffer, (void __user *) buf, in_size)) {
 204.399 +		up(&chip->buffer_mutex);
 204.400 +		return -EFAULT;
 204.401 +	}
 204.402 +
 204.403 +	/* atomic tpm command send and result receive */
 204.404 +	out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
 204.405 +
 204.406 +	atomic_set(&chip->data_pending, out_size);
 204.407 +	atomic_set(&chip->data_position, 0);
 204.408 +	up(&chip->buffer_mutex);
 204.409 +
 204.410 +	/* Set a timeout by which the reader must come claim the result */
 204.411 +	down(&chip->timer_manipulation_mutex);
 204.412 +	init_timer(&chip->user_read_timer);
 204.413 +	chip->user_read_timer.function = user_reader_timeout;
 204.414 +	chip->user_read_timer.data = (unsigned long) chip;
 204.415 +	chip->user_read_timer.expires = jiffies + (60 * HZ);
 204.416 +	add_timer(&chip->user_read_timer);
 204.417 +	up(&chip->timer_manipulation_mutex);
 204.418 +
 204.419 +	return in_size;
 204.420 +}
 204.421 +
 204.422 +EXPORT_SYMBOL_GPL(tpm_write);
 204.423 +
 204.424 +ssize_t tpm_read(struct file * file, char __user * buf,
 204.425 +		 size_t size, loff_t * off)
 204.426 +{
 204.427 +	struct tpm_chip *chip = file->private_data;
 204.428 +	int ret_size = -ENODATA;
 204.429 +	int pos, pending = 0;
 204.430 +
 204.431 +	down(&chip->buffer_mutex);
 204.432 +	ret_size = atomic_read(&chip->data_pending);
 204.433 +	if ( ret_size > 0 ) {	/* Result available */
 204.434 +		if (size < ret_size)
 204.435 +			ret_size = size;
 204.436 +
 204.437 +		pos = atomic_read(&chip->data_position);
 204.438 +
 204.439 +		if (copy_to_user((void __user *) buf,
 204.440 +				 &chip->data_buffer[pos], ret_size)) {
 204.441 +			ret_size = -EFAULT;
 204.442 +		} else {
 204.443 +			pending = atomic_read(&chip->data_pending) - ret_size;
 204.444 +			if ( pending ) {
 204.445 +				atomic_set( &chip->data_pending, pending );
 204.446 +				atomic_set( &chip->data_position, pos+ret_size );
 204.447 +			}
 204.448 +		}
 204.449 +	}
 204.450 +	up(&chip->buffer_mutex);
 204.451 +
 204.452 +	if ( ret_size <= 0 || pending == 0 ) {
 204.453 +		atomic_set( &chip->data_pending, 0 );
 204.454 +		down(&chip->timer_manipulation_mutex);
 204.455 +		del_singleshot_timer_sync(&chip->user_read_timer);
 204.456 +		up(&chip->timer_manipulation_mutex);
 204.457 +	}
 204.458 +
 204.459 +	return ret_size;
 204.460 +}
 204.461 +
 204.462 +EXPORT_SYMBOL_GPL(tpm_read);
 204.463 +
 204.464 +void __devexit tpm_remove(struct pci_dev *pci_dev)
 204.465 +{
 204.466 +	struct tpm_chip *chip = pci_get_drvdata(pci_dev);
 204.467 +
 204.468 +	if (chip == NULL) {
 204.469 +		dev_err(&pci_dev->dev, "No device data found\n");
 204.470 +		return;
 204.471 +	}
 204.472 +
 204.473 +	spin_lock(&driver_lock);
 204.474 +
 204.475 +	list_del(&chip->list);
 204.476 +
 204.477 +	spin_unlock(&driver_lock);
 204.478 +
 204.479 +	pci_set_drvdata(pci_dev, NULL);
 204.480 +	misc_deregister(&chip->vendor->miscdev);
 204.481 +
 204.482 +	device_remove_file(&pci_dev->dev, &dev_attr_pubek);
 204.483 +	device_remove_file(&pci_dev->dev, &dev_attr_pcrs);
 204.484 +	device_remove_file(&pci_dev->dev, &dev_attr_caps);
 204.485 +
 204.486 +	pci_disable_device(pci_dev);
 204.487 +
 204.488 +	dev_mask[chip->dev_num / 32] &= !(1 << (chip->dev_num % 32));
 204.489 +
 204.490 +	kfree(chip);
 204.491 +
 204.492 +	pci_dev_put(pci_dev);
 204.493 +}
 204.494 +
 204.495 +EXPORT_SYMBOL_GPL(tpm_remove);
 204.496 +
 204.497 +static u8 savestate[] = {
 204.498 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
 204.499 +	0, 0, 0, 10,		/* blob length (in bytes) */
 204.500 +	0, 0, 0, 152		/* TPM_ORD_SaveState */
 204.501 +};
 204.502 +
 204.503 +/*
 204.504 + * We are about to suspend. Save the TPM state
 204.505 + * so that it can be restored.
 204.506 + */
 204.507 +int tpm_pm_suspend(struct pci_dev *pci_dev, pm_message_t pm_state)
 204.508 +{
 204.509 +	struct tpm_chip *chip = pci_get_drvdata(pci_dev);
 204.510 +	if (chip == NULL)
 204.511 +		return -ENODEV;
 204.512 +
 204.513 +	tpm_transmit(chip, savestate, sizeof(savestate));
 204.514 +	return 0;
 204.515 +}
 204.516 +
 204.517 +EXPORT_SYMBOL_GPL(tpm_pm_suspend);
 204.518 +
 204.519 +/*
 204.520 + * Resume from a power safe. The BIOS already restored
 204.521 + * the TPM state.
 204.522 + */
 204.523 +int tpm_pm_resume(struct pci_dev *pci_dev)
 204.524 +{
 204.525 +	struct tpm_chip *chip = pci_get_drvdata(pci_dev);
 204.526 +
 204.527 +	if (chip == NULL)
 204.528 +		return -ENODEV;
 204.529 +
 204.530 +	return 0;
 204.531 +}
 204.532 +
 204.533 +EXPORT_SYMBOL_GPL(tpm_pm_resume);
 204.534 +
 204.535 +/*
 204.536 + * Called from tpm_<specific>.c probe function only for devices
 204.537 + * the driver has determined it should claim.  Prior to calling
 204.538 + * this function the specific probe function has called pci_enable_device
 204.539 + * upon errant exit from this function specific probe function should call
 204.540 + * pci_disable_device
 204.541 + */
 204.542 +int tpm_register_hardware(struct pci_dev *pci_dev,
 204.543 +			  struct tpm_vendor_specific *entry)
 204.544 +{
 204.545 +	char devname[7];
 204.546 +	struct tpm_chip *chip;
 204.547 +	int i, j;
 204.548 +
 204.549 +	/* Driver specific per-device data */
 204.550 +	chip = kmalloc(sizeof(*chip), GFP_KERNEL);
 204.551 +	if (chip == NULL)
 204.552 +		return -ENOMEM;
 204.553 +
 204.554 +	memset(chip, 0, sizeof(struct tpm_chip));
 204.555 +
 204.556 +	init_MUTEX(&chip->buffer_mutex);
 204.557 +	init_MUTEX(&chip->tpm_mutex);
 204.558 +	init_MUTEX(&chip->timer_manipulation_mutex);
 204.559 +	INIT_LIST_HEAD(&chip->list);
 204.560 +
 204.561 +	chip->vendor = entry;
 204.562 +
 204.563 +	chip->dev_num = -1;
 204.564 +
 204.565 +	for (i = 0; i < 32; i++)
 204.566 +		for (j = 0; j < 8; j++)
 204.567 +			if ((dev_mask[i] & (1 << j)) == 0) {
 204.568 +				chip->dev_num = i * 32 + j;
 204.569 +				dev_mask[i] |= 1 << j;
 204.570 +				goto dev_num_search_complete;
 204.571 +			}
 204.572 +
 204.573 +dev_num_search_complete:
 204.574 +	if (chip->dev_num < 0) {
 204.575 +		dev_err(&pci_dev->dev,
 204.576 +			"No available tpm device numbers\n");
 204.577 +		kfree(chip);
 204.578 +		return -ENODEV;
 204.579 +	} else if (chip->dev_num == 0)
 204.580 +		chip->vendor->miscdev.minor = TPM_MINOR;
 204.581 +	else
 204.582 +		chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
 204.583 +
 204.584 +	snprintf(devname, sizeof(devname), "%s%d", "tpm", chip->dev_num);
 204.585 +	chip->vendor->miscdev.name = devname;
 204.586 +
 204.587 +	chip->vendor->miscdev.dev = &(pci_dev->dev);
 204.588 +	chip->pci_dev = pci_dev_get(pci_dev);
 204.589 +
 204.590 +	if (misc_register(&chip->vendor->miscdev)) {
 204.591 +		dev_err(&chip->pci_dev->dev,
 204.592 +			"unable to misc_register %s, minor %d\n",
 204.593 +			chip->vendor->miscdev.name,
 204.594 +			chip->vendor->miscdev.minor);
 204.595 +		pci_dev_put(pci_dev);
 204.596 +		kfree(chip);
 204.597 +		dev_mask[i] &= !(1 << j);
 204.598 +		return -ENODEV;
 204.599 +	}
 204.600 +
 204.601 +	pci_set_drvdata(pci_dev, chip);
 204.602 +
 204.603 +	list_add(&chip->list, &tpm_chip_list);
 204.604 +
 204.605 +	device_create_file(&pci_dev->dev, &dev_attr_pubek);
 204.606 +	device_create_file(&pci_dev->dev, &dev_attr_pcrs);
 204.607 +	device_create_file(&pci_dev->dev, &dev_attr_caps);
 204.608 +
 204.609 +	return 0;
 204.610 +}
 204.611 +
 204.612 +EXPORT_SYMBOL_GPL(tpm_register_hardware);
 204.613 +
 204.614 +static int __init init_tpm(void)
 204.615 +{
 204.616 +	return 0;
 204.617 +}
 204.618 +
 204.619 +static void __exit cleanup_tpm(void)
 204.620 +{
 204.621 +
 204.622 +}
 204.623 +
 204.624 +module_init(init_tpm);
 204.625 +module_exit(cleanup_tpm);
 204.626 +
 204.627 +MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
 204.628 +MODULE_DESCRIPTION("TPM Driver");
 204.629 +MODULE_VERSION("2.0");
 204.630 +MODULE_LICENSE("GPL");
   205.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   205.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h	Thu Sep 01 10:16:14 2005 +0000
   205.3 @@ -0,0 +1,92 @@
   205.4 +/*
   205.5 + * Copyright (C) 2004 IBM Corporation
   205.6 + *
   205.7 + * Authors:
   205.8 + * Leendert van Doorn <leendert@watson.ibm.com>
   205.9 + * Dave Safford <safford@watson.ibm.com>
  205.10 + * Reiner Sailer <sailer@watson.ibm.com>
  205.11 + * Kylene Hall <kjhall@us.ibm.com>
  205.12 + *
  205.13 + * Maintained by: <tpmdd_devel@lists.sourceforge.net>
  205.14 + *
  205.15 + * Device driver for TCG/TCPA TPM (trusted platform module).
  205.16 + * Specifications at www.trustedcomputinggroup.org
  205.17 + *
  205.18 + * This program is free software; you can redistribute it and/or
  205.19 + * modify it under the terms of the GNU General Public License as
  205.20 + * published by the Free Software Foundation, version 2 of the
  205.21 + * License.
  205.22 + *
  205.23 + */
  205.24 +#include <linux/module.h>
  205.25 +#include <linux/version.h>
  205.26 +#include <linux/pci.h>
  205.27 +#include <linux/delay.h>
  205.28 +#include <linux/fs.h>
  205.29 +#include <linux/miscdevice.h>
  205.30 +
  205.31 +#define TPM_TIMEOUT msecs_to_jiffies(5)
  205.32 +
  205.33 +/* TPM addresses */
  205.34 +#define	TPM_ADDR			0x4E
  205.35 +#define	TPM_DATA			0x4F
  205.36 +
  205.37 +struct tpm_chip;
  205.38 +
  205.39 +struct tpm_vendor_specific {
  205.40 +	u8 req_complete_mask;
  205.41 +	u8 req_complete_val;
  205.42 +	u16 base;		/* TPM base address */
  205.43 +
  205.44 +	int (*recv) (struct tpm_chip *, u8 *, size_t);
  205.45 +	int (*send) (struct tpm_chip *, u8 *, size_t);
  205.46 +	void (*cancel) (struct tpm_chip *);
  205.47 +	struct miscdevice miscdev;
  205.48 +};
  205.49 +
  205.50 +struct tpm_chip {
  205.51 +	struct pci_dev *pci_dev;	/* PCI device stuff */
  205.52 +
  205.53 +	int dev_num;		/* /dev/tpm# */
  205.54 +	int num_opens;		/* only one allowed */
  205.55 +	int time_expired;
  205.56 +
  205.57 +	/* Data passed to and from the tpm via the read/write calls */
  205.58 +	u8 *data_buffer;
  205.59 +	atomic_t data_pending;
  205.60 +	atomic_t data_position;
  205.61 +	struct semaphore buffer_mutex;
  205.62 +
  205.63 +	struct timer_list user_read_timer;	/* user needs to claim result */
  205.64 +	struct semaphore tpm_mutex;	/* tpm is processing */
  205.65 +	struct timer_list device_timer;	/* tpm is processing */
  205.66 +	struct semaphore timer_manipulation_mutex;
  205.67 +
  205.68 +	struct tpm_vendor_specific *vendor;
  205.69 +
  205.70 +	struct list_head list;
  205.71 +};
  205.72 +
  205.73 +static inline int tpm_read_index(int index)
  205.74 +{
  205.75 +	outb(index, TPM_ADDR);
  205.76 +	return inb(TPM_DATA) & 0xFF;
  205.77 +}
  205.78 +
  205.79 +static inline void tpm_write_index(int index, int value)
  205.80 +{
  205.81 +	outb(index, TPM_ADDR);
  205.82 +	outb(value & 0xFF, TPM_DATA);
  205.83 +}
  205.84 +
  205.85 +extern void tpm_time_expired(unsigned long);
  205.86 +extern int tpm_register_hardware(struct pci_dev *,
  205.87 +				 struct tpm_vendor_specific *);
  205.88 +extern int tpm_open(struct inode *, struct file *);
  205.89 +extern int tpm_release(struct inode *, struct file *);
  205.90 +extern ssize_t tpm_write(struct file *, const char __user *, size_t,
  205.91 +			 loff_t *);
  205.92 +extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *);
  205.93 +extern void __devexit tpm_remove(struct pci_dev *);
  205.94 +extern int tpm_pm_suspend(struct pci_dev *, pm_message_t);
  205.95 +extern int tpm_pm_resume(struct pci_dev *);
   206.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   206.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_atmel.c	Thu Sep 01 10:16:14 2005 +0000
   206.3 @@ -0,0 +1,220 @@
   206.4 +/*
   206.5 + * Copyright (C) 2004 IBM Corporation
   206.6 + *
   206.7 + * Authors:
   206.8 + * Leendert van Doorn <leendert@watson.ibm.com>
   206.9 + * Dave Safford <safford@watson.ibm.com>
  206.10 + * Reiner Sailer <sailer@watson.ibm.com>
  206.11 + * Kylene Hall <kjhall@us.ibm.com>
  206.12 + *
  206.13 + * Maintained by: <tpmdd_devel@lists.sourceforge.net>
  206.14 + *
  206.15 + * Device driver for TCG/TCPA TPM (trusted platform module).
  206.16 + * Specifications at www.trustedcomputinggroup.org
  206.17 + *
  206.18 + * This program is free software; you can redistribute it and/or
  206.19 + * modify it under the terms of the GNU General Public License as
  206.20 + * published by the Free Software Foundation, version 2 of the
  206.21 + * License.
  206.22 + *
  206.23 + */
  206.24 +
  206.25 +#include "tpm.h"
  206.26 +
  206.27 +/* Atmel definitions */
  206.28 +enum tpm_atmel_addr {
  206.29 +	TPM_ATMEL_BASE_ADDR_LO = 0x08,
  206.30 +	TPM_ATMEL_BASE_ADDR_HI = 0x09
  206.31 +};
  206.32 +
  206.33 +/* write status bits */
  206.34 +#define	ATML_STATUS_ABORT		0x01
  206.35 +#define	ATML_STATUS_LASTBYTE		0x04
  206.36 +
  206.37 +/* read status bits */
  206.38 +#define	ATML_STATUS_BUSY		0x01
  206.39 +#define	ATML_STATUS_DATA_AVAIL		0x02
  206.40 +#define	ATML_STATUS_REWRITE		0x04
  206.41 +
  206.42 +
  206.43 +static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
  206.44 +{
  206.45 +	u8 status, *hdr = buf;
  206.46 +	u32 size;
  206.47 +	int i;
  206.48 +	__be32 *native_size;
  206.49 +
  206.50 +	/* start reading header */
  206.51 +	if (count < 6)
  206.52 +		return -EIO;
  206.53 +
  206.54 +	for (i = 0; i < 6; i++) {
  206.55 +		status = inb(chip->vendor->base + 1);
  206.56 +		if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
  206.57 +			dev_err(&chip->pci_dev->dev,
  206.58 +				"error reading header\n");
  206.59 +			return -EIO;
  206.60 +		}
  206.61 +		*buf++ = inb(chip->vendor->base);
  206.62 +	}
  206.63 +
  206.64 +	/* size of the data received */
  206.65 +	native_size = (__force __be32 *) (hdr + 2);
  206.66 +	size = be32_to_cpu(*native_size);
  206.67 +
  206.68 +	if (count < size) {
  206.69 +		dev_err(&chip->pci_dev->dev,
  206.70 +			"Recv size(%d) less than available space\n", size);
  206.71 +		for (; i < size; i++) {	/* clear the waiting data anyway */
  206.72 +			status = inb(chip->vendor->base + 1);
  206.73 +			if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
  206.74 +				dev_err(&chip->pci_dev->dev,
  206.75 +					"error reading data\n");
  206.76 +				return -EIO;
  206.77 +			}
  206.78 +		}
  206.79 +		return -EIO;
  206.80 +	}
  206.81 +
  206.82 +	/* read all the data available */
  206.83 +	for (; i < size; i++) {
  206.84 +		status = inb(chip->vendor->base + 1);
  206.85 +		if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
  206.86 +			dev_err(&chip->pci_dev->dev,
  206.87 +				"error reading data\n");
  206.88 +			return -EIO;
  206.89 +		}
  206.90 +		*buf++ = inb(chip->vendor->base);
  206.91 +	}
  206.92 +
  206.93 +	/* make sure data available is gone */
  206.94 +	status = inb(chip->vendor->base + 1);
  206.95 +	if (status & ATML_STATUS_DATA_AVAIL) {
  206.96 +		dev_err(&chip->pci_dev->dev, "data available is stuck\n");
  206.97 +		return -EIO;
  206.98 +	}
  206.99 +
 206.100 +	return size;
 206.101 +}
 206.102 +
 206.103 +static int tpm_atml_send(struct tpm_chip *chip, u8 * buf, size_t count)
 206.104 +{
 206.105 +	int i;
 206.106 +
 206.107 +	dev_dbg(&chip->pci_dev->dev, "tpm_atml_send: ");
 206.108 +	for (i = 0; i < count; i++) {
 206.109 +		dev_dbg(&chip->pci_dev->dev, "0x%x(%d) ", buf[i], buf[i]);
 206.110 +		outb(buf[i], chip->vendor->base);
 206.111 +	}
 206.112 +
 206.113 +	return count;
 206.114 +}
 206.115 +
 206.116 +static void tpm_atml_cancel(struct tpm_chip *chip)
 206.117 +{
 206.118 +	outb(ATML_STATUS_ABORT, chip->vendor->base + 1);
 206.119 +}
 206.120 +
 206.121 +static struct file_operations atmel_ops = {
 206.122 +	.owner = THIS_MODULE,
 206.123 +	.llseek = no_llseek,
 206.124 +	.open = tpm_open,
 206.125 +	.read = tpm_read,
 206.126 +	.write = tpm_write,
 206.127 +	.release = tpm_release,
 206.128 +};
 206.129 +
 206.130 +static struct tpm_vendor_specific tpm_atmel = {
 206.131 +	.recv = tpm_atml_recv,
 206.132 +	.send = tpm_atml_send,
 206.133 +	.cancel = tpm_atml_cancel,
 206.134 +	.req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL,
 206.135 +	.req_complete_val = ATML_STATUS_DATA_AVAIL,
 206.136 +	.miscdev = { .fops = &atmel_ops, },
 206.137 +};
 206.138 +
 206.139 +static int __devinit tpm_atml_init(struct pci_dev *pci_dev,
 206.140 +				   const struct pci_device_id *pci_id)
 206.141 +{
 206.142 +	u8 version[4];
 206.143 +	int rc = 0;
 206.144 +	int lo, hi;
 206.145 +
 206.146 +	if (pci_enable_device(pci_dev))
 206.147 +		return -EIO;
 206.148 +
 206.149 +	lo = tpm_read_index( TPM_ATMEL_BASE_ADDR_LO );
 206.150 +	hi = tpm_read_index( TPM_ATMEL_BASE_ADDR_HI );
 206.151 +
 206.152 +	tpm_atmel.base = (hi<<8)|lo;
 206.153 +	dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base);
 206.154 +
 206.155 +	/* verify that it is an Atmel part */
 206.156 +	if (tpm_read_index(4) != 'A' || tpm_read_index(5) != 'T'
 206.157 +	    || tpm_read_index(6) != 'M' || tpm_read_index(7) != 'L') {
 206.158 +		rc = -ENODEV;
 206.159 +		goto out_err;
 206.160 +	}
 206.161 +
 206.162 +	/* query chip for its version number */
 206.163 +	if ((version[0] = tpm_read_index(0x00)) != 0xFF) {
 206.164 +		version[1] = tpm_read_index(0x01);
 206.165 +		version[2] = tpm_read_index(0x02);
 206.166 +		version[3] = tpm_read_index(0x03);
 206.167 +	} else {
 206.168 +		dev_info(&pci_dev->dev, "version query failed\n");
 206.169 +		rc = -ENODEV;
 206.170 +		goto out_err;
 206.171 +	}
 206.172 +
 206.173 +	if ((rc = tpm_register_hardware(pci_dev, &tpm_atmel)) < 0)
 206.174 +		goto out_err;
 206.175 +
 206.176 +	dev_info(&pci_dev->dev,
 206.177 +		 "Atmel TPM version %d.%d.%d.%d\n", version[0], version[1],
 206.178 +		 version[2], version[3]);
 206.179 +
 206.180 +	return 0;
 206.181 +out_err:
 206.182 +	pci_disable_device(pci_dev);
 206.183 +	return rc;
 206.184 +}
 206.185 +
 206.186 +static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
 206.187 +	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
 206.188 +	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
 206.189 +	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
 206.190 +	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
 206.191 +	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
 206.192 +	{PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
 206.193 +	{0,}
 206.194 +};
 206.195 +
 206.196 +MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
 206.197 +
 206.198 +static struct pci_driver atmel_pci_driver = {
 206.199 +	.name = "tpm_atmel",
 206.200 +	.id_table = tpm_pci_tbl,
 206.201 +	.probe = tpm_atml_init,
 206.202 +	.remove = __devexit_p(tpm_remove),
 206.203 +	.suspend = tpm_pm_suspend,
 206.204 +	.resume = tpm_pm_resume,
 206.205 +};
 206.206 +
 206.207 +static int __init init_atmel(void)
 206.208 +{
 206.209 +	return pci_register_driver(&atmel_pci_driver);
 206.210 +}
 206.211 +
 206.212 +static void __exit cleanup_atmel(void)
 206.213 +{
 206.214 +	pci_unregister_driver(&atmel_pci_driver);
 206.215 +}
 206.216 +
 206.217 +module_init(init_atmel);
 206.218 +module_exit(cleanup_atmel);
 206.219 +
 206.220 +MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
 206.221 +MODULE_DESCRIPTION("TPM Driver");
 206.222 +MODULE_VERSION("2.0");
 206.223 +MODULE_LICENSE("GPL");
   207.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   207.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_nopci.c	Thu Sep 01 10:16:14 2005 +0000
   207.3 @@ -0,0 +1,741 @@
   207.4 +/*
   207.5 + * Copyright (C) 2004 IBM Corporation
   207.6 + *
   207.7 + * Authors:
   207.8 + * Leendert van Doorn <leendert@watson.ibm.com>
   207.9 + * Dave Safford <safford@watson.ibm.com>
  207.10 + * Reiner Sailer <sailer@watson.ibm.com>
  207.11 + * Kylene Hall <kjhall@us.ibm.com>
  207.12 + *
  207.13 + * Maintained by: <tpmdd_devel@lists.sourceforge.net>
  207.14 + *
  207.15 + * Device driver for TCG/TCPA TPM (trusted platform module).
  207.16 + * Specifications at www.trustedcomputinggroup.org
  207.17 + *
  207.18 + * This program is free software; you can redistribute it and/or
  207.19 + * modify it under the terms of the GNU General Public License as
  207.20 + * published by the Free Software Foundation, version 2 of the
  207.21 + * License.
  207.22 + *
  207.23 + * Note, the TPM chip is not interrupt driven (only polling)
  207.24 + * and can have very long timeouts (minutes!). Hence the unusual
  207.25 + * calls to schedule_timeout.
  207.26 + *
  207.27 + */
  207.28 +
  207.29 +#include <linux/sched.h>
  207.30 +#include <linux/poll.h>
  207.31 +#include <linux/spinlock.h>
  207.32 +#include "tpm_nopci.h"
  207.33 +
  207.34 +enum {
  207.35 +	TPM_MINOR = 224,	/* officially assigned */
  207.36 +	TPM_BUFSIZE = 2048,
  207.37 +	TPM_NUM_DEVICES = 256,
  207.38 +	TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int))
  207.39 +};
  207.40 +
  207.41 +  /* PCI configuration addresses */
  207.42 +enum {
  207.43 +	PCI_GEN_PMCON_1 = 0xA0,
  207.44 +	PCI_GEN1_DEC = 0xE4,
  207.45 +	PCI_LPC_EN = 0xE6,
  207.46 +	PCI_GEN2_DEC = 0xEC
  207.47 +};
  207.48 +
  207.49 +enum {
  207.50 +	TPM_LOCK_REG = 0x0D,
  207.51 +	TPM_INTERUPT_REG = 0x0A,
  207.52 +	TPM_BASE_ADDR_LO = 0x08,
  207.53 +	TPM_BASE_ADDR_HI = 0x09,
  207.54 +	TPM_UNLOCK_VALUE = 0x55,
  207.55 +	TPM_LOCK_VALUE = 0xAA,
  207.56 +	TPM_DISABLE_INTERUPT_VALUE = 0x00
  207.57 +};
  207.58 +
  207.59 +static LIST_HEAD(tpm_chip_list);
  207.60 +static spinlock_t driver_lock = SPIN_LOCK_UNLOCKED;
  207.61 +static int dev_mask[32];
  207.62 +
  207.63 +static void user_reader_timeout(unsigned long ptr)
  207.64 +{
  207.65 +	struct tpm_chip *chip = (struct tpm_chip *) ptr;
  207.66 +
  207.67 +	down(&chip->buffer_mutex);
  207.68 +	atomic_set(&chip->data_pending, 0);
  207.69 +	memset(chip->data_buffer, 0, TPM_BUFSIZE);
  207.70 +	up(&chip->buffer_mutex);
  207.71 +}
  207.72 +
  207.73 +void tpm_time_expired(unsigned long ptr)
  207.74 +{
  207.75 +	int *exp = (int *) ptr;
  207.76 +	*exp = 1;
  207.77 +}
  207.78 +
  207.79 +EXPORT_SYMBOL_GPL(tpm_time_expired);
  207.80 +
  207.81 +
  207.82 +/*
  207.83 + * This function should be used by other kernel subsystems attempting to use the tpm through the tpm_transmit interface.
  207.84 + * A call to this function will return the chip structure corresponding to the TPM you are looking for that can then be sent with your command to tpm_transmit.
  207.85 + * Passing 0 as the argument corresponds to /dev/tpm0 and thus the first and probably primary TPM on the system.  Passing 1 corresponds to /dev/tpm1 and the next TPM discovered.  If a TPM with the given chip_num does not exist NULL will be returned.
  207.86 + */
  207.87 +struct tpm_chip* tpm_chip_lookup(int chip_num)
  207.88 +{
  207.89 +
  207.90 +	struct tpm_chip *pos;
  207.91 +	list_for_each_entry(pos, &tpm_chip_list, list)
  207.92 +		if (pos->dev_num == chip_num ||
  207.93 +		    chip_num == TPM_ANY_NUM)
  207.94 +			return pos;
  207.95 +
  207.96 +	return NULL;
  207.97 +
  207.98 +}
  207.99 +
 207.100 +/*
 207.101 + * Internal kernel interface to transmit TPM commands
 207.102 + */
 207.103 +ssize_t tpm_transmit(struct tpm_chip * chip, const char *buf,
 207.104 +		     size_t bufsiz)
 207.105 +{
 207.106 +	ssize_t rc;
 207.107 +	u32 count;
 207.108 +	unsigned long stop;
 207.109 +
 207.110 +	count = be32_to_cpu(*((__be32 *) (buf + 2)));
 207.111 +
 207.112 +	if (count == 0)
 207.113 +		return -ENODATA;
 207.114 +	if (count > bufsiz) {
 207.115 +		dev_err(chip->dev,
 207.116 +			"invalid count value %x %x \n", count, bufsiz);
 207.117 +		return -E2BIG;
 207.118 +	}
 207.119 +
 207.120 +	dev_dbg(chip->dev, "TPM Ordinal: %d\n",
 207.121 +		be32_to_cpu(*((__be32 *) (buf + 6))));
 207.122 +	dev_dbg(chip->dev, "Chip Status: %x\n",
 207.123 +		inb(chip->vendor->base + 1));
 207.124 +
 207.125 +	down(&chip->tpm_mutex);
 207.126 +
 207.127 +	if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
 207.128 +		dev_err(chip->dev,
 207.129 +			"tpm_transmit: tpm_send: error %d\n", rc);
 207.130 +		goto out;
 207.131 +	}
 207.132 +
 207.133 +	stop = jiffies + 2 * 60 * HZ;
 207.134 +	do {
 207.135 +		u8 status = chip->vendor->status(chip);
 207.136 +		if ((status & chip->vendor->req_complete_mask) ==
 207.137 +		    chip->vendor->req_complete_val) {
 207.138 +			goto out_recv;
 207.139 +		}
 207.140 +
 207.141 +		if ((status == chip->vendor->req_canceled)) {
 207.142 +			dev_err(chip->dev, "Operation Canceled\n");
 207.143 +			rc = -ECANCELED;
 207.144 +			goto out;
 207.145 +		}
 207.146 +
 207.147 +		msleep(TPM_TIMEOUT);	/* CHECK */
 207.148 +		rmb();
 207.149 +	}
 207.150 +	while (time_before(jiffies, stop));
 207.151 +
 207.152 +
 207.153 +	chip->vendor->cancel(chip);
 207.154 +	dev_err(chip->dev, "Operation Timed out\n");
 207.155 +	rc = -ETIME;
 207.156 +	goto out;
 207.157 +
 207.158 +out_recv:
 207.159 +	rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
 207.160 +	if (rc < 0)
 207.161 +		dev_err(chip->dev,
 207.162 +			"tpm_transmit: tpm_recv: error %d\n", rc);
 207.163 +	atomic_set(&chip->data_position, 0);
 207.164 +
 207.165 +out:
 207.166 +	up(&chip->tpm_mutex);
 207.167 +	return rc;
 207.168 +}
 207.169 +
 207.170 +EXPORT_SYMBOL_GPL(tpm_transmit);
 207.171 +
 207.172 +#define TPM_DIGEST_SIZE 20
 207.173 +#define CAP_PCR_RESULT_SIZE 18
 207.174 +static const u8 cap_pcr[] = {
 207.175 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
 207.176 +	0, 0, 0, 22,		/* length */
 207.177 +	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
 207.178 +	0, 0, 0, 5,
 207.179 +	0, 0, 0, 4,
 207.180 +	0, 0, 1, 1
 207.181 +};
 207.182 +
 207.183 +#define READ_PCR_RESULT_SIZE 30
 207.184 +static const u8 pcrread[] = {
 207.185 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
 207.186 +	0, 0, 0, 14,		/* length */
 207.187 +	0, 0, 0, 21,		/* TPM_ORD_PcrRead */
 207.188 +	0, 0, 0, 0		/* PCR index */
 207.189 +};
 207.190 +
 207.191 +ssize_t tpm_show_pcrs(struct device *dev, char *buf)
 207.192 +{
 207.193 +	u8 data[READ_PCR_RESULT_SIZE];
 207.194 +	ssize_t len;
 207.195 +	int i, j, num_pcrs;
 207.196 +	__be32 index;
 207.197 +	char *str = buf;
 207.198 +
 207.199 +	struct tpm_chip *chip = dev_get_drvdata(dev);
 207.200 +	if (chip == NULL)
 207.201 +		return -ENODEV;
 207.202 +
 207.203 +	memcpy(data, cap_pcr, sizeof(cap_pcr));
 207.204 +	if ((len = tpm_transmit(chip, data, sizeof(data)))
 207.205 +	    < CAP_PCR_RESULT_SIZE)
 207.206 +		return len;
 207.207 +
 207.208 +	num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
 207.209 +
 207.210 +	for (i = 0; i < num_pcrs; i++) {
 207.211 +		memcpy(data, pcrread, sizeof(pcrread));
 207.212 +		index = cpu_to_be32(i);
 207.213 +		memcpy(data + 10, &index, 4);
 207.214 +		if ((len = tpm_transmit(chip, data, sizeof(data)))
 207.215 +		    < READ_PCR_RESULT_SIZE)
 207.216 +			return len;
 207.217 +		str += sprintf(str, "PCR-%02d: ", i);
 207.218 +		for (j = 0; j < TPM_DIGEST_SIZE; j++)
 207.219 +			str += sprintf(str, "%02X ", *(data + 10 + j));
 207.220 +		str += sprintf(str, "\n");
 207.221 +	}
 207.222 +	return str - buf;
 207.223 +}
 207.224 +
 207.225 +EXPORT_SYMBOL_GPL(tpm_show_pcrs);
 207.226 +
 207.227 +/*
 207.228 + * Return 0 on success.  On error pass along error code.
 207.229 + * chip_id Upper 2 bytes equal ANY, HW_ONLY or SW_ONLY
 207.230 + * Lower 2 bytes equal tpm idx # or AN&
 207.231 + * res_buf must fit a TPM_PCR (20 bytes) or NULL if you don't care
 207.232 + */
 207.233 +int tpm_pcr_read( u32 chip_id, int pcr_idx, u8* res_buf, int res_buf_size )
 207.234 +{
 207.235 +	u8 data[READ_PCR_RESULT_SIZE];
 207.236 +	int rc;
 207.237 +	__be32 index;
 207.238 +	int chip_num = chip_id & TPM_CHIP_NUM_MASK;
 207.239 +	struct tpm_chip* chip;
 207.240 +
 207.241 +	if ( res_buf && res_buf_size < TPM_DIGEST_SIZE )
 207.242 +		return -ENOSPC;
 207.243 +	if ( (chip = tpm_chip_lookup( chip_num /*,
 207.244 +				       chip_id >> TPM_CHIP_TYPE_SHIFT*/ ) ) == NULL ) {
 207.245 +		printk("chip %d not found.\n",chip_num);
 207.246 +		return -ENODEV;
 207.247 +	}
 207.248 +	memcpy(data, pcrread, sizeof(pcrread));
 207.249 +	index = cpu_to_be32(pcr_idx);
 207.250 +	memcpy(data + 10, &index, 4);
 207.251 +	if ((rc = tpm_transmit(chip, data, sizeof(data))) > 0 )
 207.252 +		rc = be32_to_cpu(*((u32*)(data+6)));
 207.253 +
 207.254 +	if ( rc == 0 && res_buf )
 207.255 +		memcpy(res_buf, data+10, TPM_DIGEST_SIZE);
 207.256 +	return rc;
 207.257 +}
 207.258 +EXPORT_SYMBOL_GPL(tpm_pcr_read);
 207.259 +
 207.260 +#define EXTEND_PCR_SIZE 34
 207.261 +static const u8 pcrextend[] = {
 207.262 +	0, 193,		 		 		 /* TPM_TAG_RQU_COMMAND */
 207.263 +	0, 0, 0, 34,		 		 /* length */
 207.264 +	0, 0, 0, 20,		 		 /* TPM_ORD_Extend */
 207.265 +	0, 0, 0, 0		 		 /* PCR index */
 207.266 +};
 207.267 +
 207.268 +/*
 207.269 + * Return 0 on success.  On error pass along error code.
 207.270 + * chip_id Upper 2 bytes equal ANY, HW_ONLY or SW_ONLY
 207.271 + * Lower 2 bytes equal tpm idx # or ANY
 207.272 + */
 207.273 +int tpm_pcr_extend(u32 chip_id, int pcr_idx, const u8* hash)
 207.274 +{
 207.275 +	u8 data[EXTEND_PCR_SIZE];
 207.276 +	int rc;
 207.277 +	__be32 index;
 207.278 +	int chip_num = chip_id & TPM_CHIP_NUM_MASK;
 207.279 +	struct tpm_chip* chip;
 207.280 +
 207.281 +	if ( (chip = tpm_chip_lookup( chip_num /*,
 207.282 +				      chip_id >> TPM_CHIP_TYPE_SHIFT */)) == NULL )
 207.283 +		return -ENODEV;
 207.284 +
 207.285 +	memcpy(data, pcrextend, sizeof(pcrextend));
 207.286 +	index = cpu_to_be32(pcr_idx);
 207.287 +	memcpy(data + 10, &index, 4);
 207.288 +	memcpy( data + 14, hash, TPM_DIGEST_SIZE );
 207.289 +	if ((rc = tpm_transmit(chip, data, sizeof(data))) > 0 )
 207.290 +		rc = be32_to_cpu(*((u32*)(data+6)));
 207.291 +	return rc;
 207.292 +}
 207.293 +EXPORT_SYMBOL_GPL(tpm_pcr_extend);
 207.294 +
 207.295 +
 207.296 +
 207.297 +#define  READ_PUBEK_RESULT_SIZE 314
 207.298 +static const u8 readpubek[] = {
 207.299 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
 207.300 +	0, 0, 0, 30,		/* length */
 207.301 +	0, 0, 0, 124,		/* TPM_ORD_ReadPubek */
 207.302 +};
 207.303 +
 207.304 +ssize_t tpm_show_pubek(struct device *dev, char *buf)
 207.305 +{
 207.306 +	u8 *data;
 207.307 +	ssize_t len;
 207.308 +	int i, rc;
 207.309 +	char *str = buf;
 207.310 +
 207.311 +	struct tpm_chip *chip = dev_get_drvdata(dev);
 207.312 +	if (chip == NULL)
 207.313 +		return -ENODEV;
 207.314 +
 207.315 +	data = kmalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
 207.316 +	if (!data)
 207.317 +		return -ENOMEM;
 207.318 +
 207.319 +	memcpy(data, readpubek, sizeof(readpubek));
 207.320 +	memset(data + sizeof(readpubek), 0, 20);	/* zero nonce */
 207.321 +
 207.322 +	if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <
 207.323 +	    READ_PUBEK_RESULT_SIZE) {
 207.324 +		rc = len;
 207.325 +		goto out;
 207.326 +	}
 207.327 +
 207.328 +	/*
 207.329 +	   ignore header 10 bytes
 207.330 +	   algorithm 32 bits (1 == RSA )
 207.331 +	   encscheme 16 bits
 207.332 +	   sigscheme 16 bits
 207.333 +	   parameters (RSA 12->bytes: keybit, #primes, expbit)
 207.334 +	   keylenbytes 32 bits
 207.335 +	   256 byte modulus
 207.336 +	   ignore checksum 20 bytes
 207.337 +	 */
 207.338 +
 207.339 +	str +=
 207.340 +	    sprintf(str,
 207.341 +		    "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
 207.342 +		    "Sigscheme: %02X %02X\nParameters: %02X %02X %02X %02X"
 207.343 +		    " %02X %02X %02X %02X %02X %02X %02X %02X\n"
 207.344 +		    "Modulus length: %d\nModulus: \n",
 207.345 +		    data[10], data[11], data[12], data[13], data[14],
 207.346 +		    data[15], data[16], data[17], data[22], data[23],
 207.347 +		    data[24], data[25], data[26], data[27], data[28],
 207.348 +		    data[29], data[30], data[31], data[32], data[33],
 207.349 +		    be32_to_cpu(*((__be32 *) (data + 32))));
 207.350 +
 207.351 +	for (i = 0; i < 256; i++) {
 207.352 +		str += sprintf(str, "%02X ", data[i + 39]);
 207.353 +		if ((i + 1) % 16 == 0)
 207.354 +			str += sprintf(str, "\n");
 207.355 +	}
 207.356 +	rc = str - buf;
 207.357 +out:
 207.358 +	kfree(data);
 207.359 +	return rc;
 207.360 +}
 207.361 +
 207.362 +EXPORT_SYMBOL_GPL(tpm_show_pubek);
 207.363 +
 207.364 +#define CAP_VER_RESULT_SIZE 18
 207.365 +static const u8 cap_version[] = {
 207.366 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
 207.367 +	0, 0, 0, 18,		/* length */
 207.368 +	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
 207.369 +	0, 0, 0, 6,
 207.370 +	0, 0, 0, 0
 207.371 +};
 207.372 +
 207.373 +#define CAP_MANUFACTURER_RESULT_SIZE 18
 207.374 +static const u8 cap_manufacturer[] = {
 207.375 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
 207.376 +	0, 0, 0, 22,		/* length */
 207.377 +	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
 207.378 +	0, 0, 0, 5,
 207.379 +	0, 0, 0, 4,
 207.380 +	0, 0, 1, 3
 207.381 +};
 207.382 +
 207.383 +ssize_t tpm_show_caps(struct device *dev, char *buf)
 207.384 +{
 207.385 +	u8 data[sizeof(cap_manufacturer)];
 207.386 +	ssize_t len;
 207.387 +	char *str = buf;
 207.388 +
 207.389 +	struct tpm_chip *chip = dev_get_drvdata(dev);
 207.390 +	if (chip == NULL)
 207.391 +		return -ENODEV;
 207.392 +
 207.393 +	memcpy(data, cap_manufacturer, sizeof(cap_manufacturer));
 207.394 +
 207.395 +	if ((len = tpm_transmit(chip, data, sizeof(data))) <
 207.396 +	    CAP_MANUFACTURER_RESULT_SIZE)
 207.397 +		return len;
 207.398 +
 207.399 +	str += sprintf(str, "Manufacturer: 0x%x\n",
 207.400 +		       be32_to_cpu(*((__be32 *)(data + 14))));
 207.401 +
 207.402 +	memcpy(data, cap_version, sizeof(cap_version));
 207.403 +
 207.404 +	if ((len = tpm_transmit(chip, data, sizeof(data))) <
 207.405 +	    CAP_VER_RESULT_SIZE)
 207.406 +		return len;
 207.407 +
 207.408 +	str +=
 207.409 +	    sprintf(str, "TCG version: %d.%d\nFirmware version: %d.%d\n",
 207.410 +		    (int) data[14], (int) data[15], (int) data[16],
 207.411 +		    (int) data[17]);
 207.412 +
 207.413 +	return str - buf;
 207.414 +}
 207.415 +
 207.416 +EXPORT_SYMBOL_GPL(tpm_show_caps);
 207.417 +
 207.418 +ssize_t tpm_store_cancel(struct device * dev, const char *buf,
 207.419 +			 size_t count)
 207.420 +{
 207.421 +	struct tpm_chip *chip = dev_get_drvdata(dev);
 207.422 +	if (chip == NULL)
 207.423 +		return 0;
 207.424 +
 207.425 +	chip->vendor->cancel(chip);
 207.426 +	return count;
 207.427 +}
 207.428 +
 207.429 +EXPORT_SYMBOL_GPL(tpm_store_cancel);
 207.430 +
 207.431 +/*
 207.432 + * Device file system interface to the TPM
 207.433 + */
 207.434 +int tpm_open(struct inode *inode, struct file *file)
 207.435 +{
 207.436 +	int rc = 0, minor = iminor(inode);
 207.437 +	struct tpm_chip *chip = NULL, *pos;
 207.438 +
 207.439 +	spin_lock(&driver_lock);
 207.440 +
 207.441 +	list_for_each_entry(pos, &tpm_chip_list, list) {
 207.442 +		if (pos->vendor->miscdev.minor == minor) {
 207.443 +			chip = pos;
 207.444 +			break;
 207.445 +		}
 207.446 +	}
 207.447 +
 207.448 +	if (chip == NULL) {
 207.449 +		rc = -ENODEV;
 207.450 +		goto err_out;
 207.451 +	}
 207.452 +
 207.453 +	if (chip->num_opens) {
 207.454 +		dev_dbg(chip->dev, "Another process owns this TPM\n");
 207.455 +		rc = -EBUSY;
 207.456 +		goto err_out;
 207.457 +	}
 207.458 +
 207.459 +	chip->num_opens++;
 207.460 +	get_device(chip->dev);
 207.461 +
 207.462 +	spin_unlock(&driver_lock);
 207.463 +
 207.464 +	chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
 207.465 +	if (chip->data_buffer == NULL) {
 207.466 +		chip->num_opens--;
 207.467 +		put_device(chip->dev);
 207.468 +		return -ENOMEM;
 207.469 +	}
 207.470 +
 207.471 +	atomic_set(&chip->data_pending, 0);
 207.472 +
 207.473 +	file->private_data = chip;
 207.474 +	return 0;
 207.475 +
 207.476 +err_out:
 207.477 +	spin_unlock(&driver_lock);
 207.478 +	return rc;
 207.479 +}
 207.480 +
 207.481 +EXPORT_SYMBOL_GPL(tpm_open);
 207.482 +
 207.483 +int tpm_release(struct inode *inode, struct file *file)
 207.484 +{
 207.485 +	struct tpm_chip *chip = file->private_data;
 207.486 +
 207.487 +	spin_lock(&driver_lock);
 207.488 +	file->private_data = NULL;
 207.489 +	chip->num_opens--;
 207.490 +	del_singleshot_timer_sync(&chip->user_read_timer);
 207.491 +	atomic_set(&chip->data_pending, 0);
 207.492 +	put_device(chip->dev);
 207.493 +	kfree(chip->data_buffer);
 207.494 +	spin_unlock(&driver_lock);
 207.495 +	return 0;
 207.496 +}
 207.497 +
 207.498 +EXPORT_SYMBOL_GPL(tpm_release);
 207.499 +
 207.500 +ssize_t tpm_write(struct file * file, const char __user * buf,
 207.501 +		  size_t size, loff_t * off)
 207.502 +{
 207.503 +	struct tpm_chip *chip = file->private_data;
 207.504 +	int in_size = size, out_size;
 207.505 +
 207.506 +	/* cannot perform a write until the read has cleared
 207.507 +	   either via tpm_read or a user_read_timer timeout */
 207.508 +	while (atomic_read(&chip->data_pending) != 0)
 207.509 +		msleep(TPM_TIMEOUT);
 207.510 +
 207.511 +	down(&chip->buffer_mutex);
 207.512 +
 207.513 +	if (in_size > TPM_BUFSIZE)
 207.514 +		in_size = TPM_BUFSIZE;
 207.515 +
 207.516 +	if (copy_from_user
 207.517 +	    (chip->data_buffer, (void __user *) buf, in_size)) {
 207.518 +		up(&chip->buffer_mutex);
 207.519 +		return -EFAULT;
 207.520 +	}
 207.521 +
 207.522 +	/* atomic tpm command send and result receive */
 207.523 +	out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
 207.524 +
 207.525 +	atomic_set(&chip->data_pending, out_size);
 207.526 +	up(&chip->buffer_mutex);
 207.527 +
 207.528 +	/* Set a timeout by which the reader must come claim the result */
 207.529 +	mod_timer(&chip->user_read_timer, jiffies + (60 * HZ));
 207.530 +
 207.531 +	return in_size;
 207.532 +}
 207.533 +
 207.534 +EXPORT_SYMBOL_GPL(tpm_write);
 207.535 +
 207.536 +ssize_t tpm_read(struct file * file, char __user * buf,
 207.537 +		 size_t size, loff_t * off)
 207.538 +{
 207.539 +	struct tpm_chip *chip = file->private_data;
 207.540 +	int ret_size;
 207.541 +
 207.542 +	del_singleshot_timer_sync(&chip->user_read_timer);
 207.543 +	ret_size = atomic_read(&chip->data_pending);
 207.544 +
 207.545 +	if (ret_size > 0) {	/* relay data */
 207.546 +		int position = atomic_read(&chip->data_position);
 207.547 +
 207.548 +		if (size < ret_size)
 207.549 +			ret_size = size;
 207.550 +
 207.551 +		down(&chip->buffer_mutex);
 207.552 +
 207.553 +		if (copy_to_user((void __user *) buf,
 207.554 +				 &chip->data_buffer[position],
 207.555 +				 ret_size)) {
 207.556 +			ret_size = -EFAULT;
 207.557 +		} else {
 207.558 +		 	int pending = atomic_read(&chip->data_pending) - ret_size;
 207.559 +			atomic_set(&chip->data_pending,
 207.560 +			           pending);
 207.561 +			atomic_set(&chip->data_position,
 207.562 +			           position + ret_size);
 207.563 +		}
 207.564 +		up(&chip->buffer_mutex);
 207.565 +	}
 207.566 +
 207.567 +	return ret_size;
 207.568 +}
 207.569 +
 207.570 +EXPORT_SYMBOL_GPL(tpm_read);
 207.571 +
 207.572 +void tpm_remove_hardware(struct device *dev)
 207.573 +{
 207.574 +	struct tpm_chip *chip = dev_get_drvdata(dev);
 207.575 +	int i;
 207.576 +
 207.577 +	if (chip == NULL) {
 207.578 +		dev_err(dev, "No device data found\n");
 207.579 +		return;
 207.580 +	}
 207.581 +
 207.582 +	spin_lock(&driver_lock);
 207.583 +
 207.584 +	list_del(&chip->list);
 207.585 +
 207.586 +	spin_unlock(&driver_lock);
 207.587 +
 207.588 +	dev_set_drvdata(dev, NULL);
 207.589 +	misc_deregister(&chip->vendor->miscdev);
 207.590 +
 207.591 +	for (i = 0; i < TPM_NUM_ATTR; i++)
 207.592 +		device_remove_file(dev, &chip->vendor->attr[i]);
 207.593 +
 207.594 +	dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES] &=
 207.595 +	    !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
 207.596 +
 207.597 +	kfree(chip);
 207.598 +
 207.599 +	put_device(dev);
 207.600 +}
 207.601 +
 207.602 +EXPORT_SYMBOL_GPL(tpm_remove_hardware);
 207.603 +
 207.604 +static const u8 savestate[] = {
 207.605 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
 207.606 +	0, 0, 0, 10,		/* blob length (in bytes) */
 207.607 +	0, 0, 0, 152		/* TPM_ORD_SaveState */
 207.608 +};
 207.609 +
 207.610 +/*
 207.611 + * We are about to suspend. Save the TPM state
 207.612 + * so that it can be restored.
 207.613 + */
 207.614 +int tpm_pm_suspend(struct pci_dev *pci_dev, u32 pm_state)
 207.615 +{
 207.616 +	struct tpm_chip *chip = pci_get_drvdata(pci_dev);
 207.617 +	if (chip == NULL)
 207.618 +		return -ENODEV;
 207.619 +
 207.620 +	tpm_transmit(chip, savestate, sizeof(savestate));
 207.621 +	return 0;
 207.622 +}
 207.623 +
 207.624 +EXPORT_SYMBOL_GPL(tpm_pm_suspend);
 207.625 +
 207.626 +/*
 207.627 + * Resume from a power safe. The BIOS already restored
 207.628 + * the TPM state.
 207.629 + */
 207.630 +int tpm_pm_resume(struct pci_dev *pci_dev)
 207.631 +{
 207.632 +	struct tpm_chip *chip = pci_get_drvdata(pci_dev);
 207.633 +
 207.634 +	if (chip == NULL)
 207.635 +		return -ENODEV;
 207.636 +
 207.637 +	return 0;
 207.638 +}
 207.639 +
 207.640 +EXPORT_SYMBOL_GPL(tpm_pm_resume);
 207.641 +
 207.642 +/*
 207.643 + * Called from tpm_<specific>.c probe function only for devices
 207.644 + * the driver has determined it should claim.  Prior to calling
 207.645 + * this function the specific probe function has called pci_enable_device
 207.646 + * upon errant exit from this function specific probe function should call
 207.647 + * pci_disable_device
 207.648 + */
 207.649 +int tpm_register_hardware_nopci(struct device *dev,
 207.650 +			        struct tpm_vendor_specific *entry)
 207.651 +{
 207.652 +	char devname[7];
 207.653 +	struct tpm_chip *chip;
 207.654 +	int i, j;
 207.655 +
 207.656 +	/* Driver specific per-device data */
 207.657 +	chip = kmalloc(sizeof(*chip), GFP_KERNEL);
 207.658 +	if (chip == NULL)
 207.659 +		return -ENOMEM;
 207.660 +
 207.661 +	memset(chip, 0, sizeof(struct tpm_chip));
 207.662 +
 207.663 +	init_MUTEX(&chip->buffer_mutex);
 207.664 +	init_MUTEX(&chip->tpm_mutex);
 207.665 +	INIT_LIST_HEAD(&chip->list);
 207.666 +
 207.667 +	init_timer(&chip->user_read_timer);
 207.668 +	chip->user_read_timer.function = user_reader_timeout;
 207.669 +	chip->user_read_timer.data = (unsigned long) chip;
 207.670 +
 207.671 +	chip->vendor = entry;
 207.672 +
 207.673 +	chip->dev_num = -1;
 207.674 +
 207.675 +	for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++)
 207.676 +		for (j = 0; j < 8 * sizeof(int); j++)
 207.677 +			if ((dev_mask[i] & (1 << j)) == 0) {
 207.678 +				chip->dev_num =
 207.679 +				    i * TPM_NUM_MASK_ENTRIES + j;
 207.680 +				dev_mask[i] |= 1 << j;
 207.681 +				goto dev_num_search_complete;
 207.682 +			}
 207.683 +
 207.684 +dev_num_search_complete:
 207.685 +	if (chip->dev_num < 0) {
 207.686 +		dev_err(dev, "No available tpm device numbers\n");
 207.687 +		kfree(chip);
 207.688 +		return -ENODEV;
 207.689 +	} else if (chip->dev_num == 0)
 207.690 +		chip->vendor->miscdev.minor = TPM_MINOR;
 207.691 +	else
 207.692 +		chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
 207.693 +
 207.694 +	snprintf(devname, sizeof(devname), "%s%d", "tpm", chip->dev_num);
 207.695 +	chip->vendor->miscdev.name = devname;
 207.696 +
 207.697 +	chip->vendor->miscdev.dev = dev;
 207.698 +	chip->dev = get_device(dev);
 207.699 +
 207.700 +
 207.701 +	if (misc_register(&chip->vendor->miscdev)) {
 207.702 +		dev_err(chip->dev,
 207.703 +			"unable to misc_register %s, minor %d\n",
 207.704 +			chip->vendor->miscdev.name,
 207.705 +			chip->vendor->miscdev.minor);
 207.706 +		put_device(dev);
 207.707 +		kfree(chip);
 207.708 +		dev_mask[i] &= !(1 << j);
 207.709 +		return -ENODEV;
 207.710 +	}
 207.711 +
 207.712 +	spin_lock(&driver_lock);
 207.713 +
 207.714 +	dev_set_drvdata(dev, chip);
 207.715 +
 207.716 +	list_add(&chip->list, &tpm_chip_list);
 207.717 +
 207.718 +	spin_unlock(&driver_lock);
 207.719 +
 207.720 +	for (i = 0; i < TPM_NUM_ATTR; i++)
 207.721 +		device_create_file(dev, &chip->vendor->attr[i]);
 207.722 +
 207.723 +	return 0;
 207.724 +}
 207.725 +
 207.726 +EXPORT_SYMBOL_GPL(tpm_register_hardware_nopci);
 207.727 +
 207.728 +static int __init init_tpm(void)
 207.729 +{
 207.730 +	return 0;
 207.731 +}
 207.732 +
 207.733 +static void __exit cleanup_tpm(void)
 207.734 +{
 207.735 +
 207.736 +}
 207.737 +
 207.738 +module_init(init_tpm);
 207.739 +module_exit(cleanup_tpm);
 207.740 +
 207.741 +MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
 207.742 +MODULE_DESCRIPTION("TPM Driver");
 207.743 +MODULE_VERSION("2.0");
 207.744 +MODULE_LICENSE("GPL");
   208.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   208.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_nopci.h	Thu Sep 01 10:16:14 2005 +0000
   208.3 @@ -0,0 +1,127 @@
   208.4 +/*
   208.5 + * Copyright (C) 2004 IBM Corporation
   208.6 + *
   208.7 + * Authors:
   208.8 + * Leendert van Doorn <leendert@watson.ibm.com>
   208.9 + * Dave Safford <safford@watson.ibm.com>
  208.10 + * Reiner Sailer <sailer@watson.ibm.com>
  208.11 + * Kylene Hall <kjhall@us.ibm.com>
  208.12 + *
  208.13 + * Maintained by: <tpmdd_devel@lists.sourceforge.net>
  208.14 + *
  208.15 + * Device driver for TCG/TCPA TPM (trusted platform module).
  208.16 + * Specifications at www.trustedcomputinggroup.org
  208.17 + *
  208.18 + * This program is free software; you can redistribute it and/or
  208.19 + * modify it under the terms of the GNU General Public License as
  208.20 + * published by the Free Software Foundation, version 2 of the
  208.21 + * License.
  208.22 + *
  208.23 + */
  208.24 +#include <linux/module.h>
  208.25 +#include <linux/version.h>
  208.26 +#include <linux/pci.h>
  208.27 +#include <linux/delay.h>
  208.28 +#include <linux/miscdevice.h>
  208.29 +
  208.30 +enum {
  208.31 +	TPM_TIMEOUT = 5,	/* msecs */
  208.32 +	TPM_NUM_ATTR = 4
  208.33 +};
  208.34 +
  208.35 +/* TPM addresses */
  208.36 +enum {
  208.37 +	TPM_ADDR = 0x4E,
  208.38 +	TPM_DATA = 0x4F
  208.39 +};
  208.40 +
  208.41 +/*
  208.42 + * Chip num is this value or a valid tpm idx in lower two bytes of chip_id
  208.43 + */
  208.44 +enum tpm_chip_num {
  208.45 +	TPM_ANY_NUM = 0xFFFF,
  208.46 +};
  208.47 +
  208.48 +#define TPM_CHIP_NUM_MASK	0x0000ffff
  208.49 +
  208.50 +extern ssize_t tpm_show_pubek(struct device *, char *);
  208.51 +extern ssize_t tpm_show_pcrs(struct device *, char *);
  208.52 +extern ssize_t tpm_show_caps(struct device *, char *);
  208.53 +extern ssize_t tpm_store_cancel(struct device *, const char *, size_t);
  208.54 +
  208.55 +#define TPM_DEVICE_ATTRS { \
  208.56 +	__ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL), \
  208.57 +	__ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL), \
  208.58 +	__ATTR(caps, S_IRUGO, tpm_show_caps, NULL), \
  208.59 +	__ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel) }
  208.60 +
  208.61 +struct tpm_chip;
  208.62 +
  208.63 +struct tpm_vendor_specific {
  208.64 +	u8 req_complete_mask;
  208.65 +	u8 req_complete_val;
  208.66 +	u8 req_canceled;
  208.67 +	u16 base;		/* TPM base address */
  208.68 +
  208.69 +	int (*recv) (struct tpm_chip *, u8 *, size_t);
  208.70 +	int (*send) (struct tpm_chip *, u8 *, size_t);
  208.71 +	void (*cancel) (struct tpm_chip *);
  208.72 +	 u8(*status) (struct tpm_chip *);
  208.73 +	struct miscdevice miscdev;
  208.74 +	struct device_attribute attr[TPM_NUM_ATTR];
  208.75 +};
  208.76 +
  208.77 +struct tpm_chip {
  208.78 +	struct device *dev;	/* PCI device stuff */
  208.79 +
  208.80 +	int dev_num;		/* /dev/tpm# */
  208.81 +	int num_opens;		/* only one allowed */
  208.82 +	int time_expired;
  208.83 +
  208.84 +	/* Data passed to and from the tpm via the read/write calls */
  208.85 +	u8 *data_buffer;
  208.86 +	atomic_t data_pending;
  208.87 +	atomic_t data_position;
  208.88 +	struct semaphore buffer_mutex;
  208.89 +
  208.90 +	struct timer_list user_read_timer;	/* user needs to claim result */
  208.91 +	struct semaphore tpm_mutex;	/* tpm is processing */
  208.92 +
  208.93 +	struct tpm_vendor_specific *vendor;
  208.94 +
  208.95 +	struct list_head list;
  208.96 +};
  208.97 +
  208.98 +static inline int tpm_read_index(int index)
  208.99 +{
 208.100 +	outb(index, TPM_ADDR);
 208.101 +	return inb(TPM_DATA) & 0xFF;
 208.102 +}
 208.103 +
 208.104 +static inline void tpm_write_index(int index, int value)
 208.105 +{
 208.106 +	outb(index, TPM_ADDR);
 208.107 +	outb(value & 0xFF, TPM_DATA);
 208.108 +}
 208.109 +
 208.110 +extern void tpm_time_expired(unsigned long);
 208.111 +extern int tpm_lpc_bus_init(struct pci_dev *, u16);
 208.112 +
 208.113 +extern int tpm_register_hardware_nopci(struct device *,
 208.114 +				       struct tpm_vendor_specific *);
 208.115 +extern void tpm_remove_hardware(struct device *);
 208.116 +extern int tpm_open(struct inode *, struct file *);
 208.117 +extern int tpm_release(struct inode *, struct file *);
 208.118 +extern ssize_t tpm_write(struct file *, const char __user *, size_t,
 208.119 +			 loff_t *);
 208.120 +extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *);
 208.121 +extern int tpm_pcr_extend(u32 chip_id, int pcr_idx, const u8* hash);
 208.122 +extern int tpm_pcr_read( u32 chip_id, int pcr_idx, u8* res_buf, int res_buf_size );
 208.123 +
 208.124 +extern int tpm_pm_suspend(struct pci_dev *, u32);
 208.125 +extern int tpm_pm_resume(struct pci_dev *);
 208.126 +
 208.127 +/* internal kernel interface */
 208.128 +extern ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
 208.129 +			    size_t bufsiz);
 208.130 +extern struct tpm_chip *tpm_chip_lookup(int chip_num);
   209.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   209.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_nsc.c	Thu Sep 01 10:16:14 2005 +0000
   209.3 @@ -0,0 +1,377 @@
   209.4 +/*
   209.5 + * Copyright (C) 2004 IBM Corporation
   209.6 + *
   209.7 + * Authors:
   209.8 + * Leendert van Doorn <leendert@watson.ibm.com>
   209.9 + * Dave Safford <safford@watson.ibm.com>
  209.10 + * Reiner Sailer <sailer@watson.ibm.com>
  209.11 + * Kylene Hall <kjhall@us.ibm.com>
  209.12 + *
  209.13 + * Maintained by: <tpmdd_devel@lists.sourceforge.net>
  209.14 + *
  209.15 + * Device driver for TCG/TCPA TPM (trusted platform module).
  209.16 + * Specifications at www.trustedcomputinggroup.org
  209.17 + *
  209.18 + * This program is free software; you can redistribute it and/or
  209.19 + * modify it under the terms of the GNU General Public License as
  209.20 + * published by the Free Software Foundation, version 2 of the
  209.21 + * License.
  209.22 + *
  209.23 + */
  209.24 +
  209.25 +#include "tpm.h"
  209.26 +
  209.27 +/* National definitions */
  209.28 +#define	TPM_NSC_BASE			0x360
  209.29 +#define	TPM_NSC_IRQ			0x07
  209.30 +#define	TPM_NSC_BASE0_HI		0x60
  209.31 +#define	TPM_NSC_BASE0_LO		0x61
  209.32 +#define	TPM_NSC_BASE1_HI		0x62
  209.33 +#define	TPM_NSC_BASE1_LO		0x63
  209.34 +
  209.35 +#define	NSC_LDN_INDEX			0x07
  209.36 +#define	NSC_SID_INDEX			0x20
  209.37 +#define	NSC_LDC_INDEX			0x30
  209.38 +#define	NSC_DIO_INDEX			0x60
  209.39 +#define	NSC_CIO_INDEX			0x62
  209.40 +#define	NSC_IRQ_INDEX			0x70
  209.41 +#define	NSC_ITS_INDEX			0x71
  209.42 +
  209.43 +#define	NSC_STATUS			0x01
  209.44 +#define	NSC_COMMAND			0x01
  209.45 +#define	NSC_DATA			0x00
  209.46 +
  209.47 +/* status bits */
  209.48 +#define	NSC_STATUS_OBF			0x01	/* output buffer full */
  209.49 +#define	NSC_STATUS_IBF			0x02	/* input buffer full */
  209.50 +#define	NSC_STATUS_F0			0x04	/* F0 */
  209.51 +#define	NSC_STATUS_A2			0x08	/* A2 */
  209.52 +#define	NSC_STATUS_RDY			0x10	/* ready to receive command */
  209.53 +#define	NSC_STATUS_IBR			0x20	/* ready to receive data */
  209.54 +
  209.55 +/* command bits */
  209.56 +#define	NSC_COMMAND_NORMAL		0x01	/* normal mode */
  209.57 +#define	NSC_COMMAND_EOC			0x03
  209.58 +#define	NSC_COMMAND_CANCEL		0x22
  209.59 +
  209.60 +/*
  209.61 + * Wait for a certain status to appear
  209.62 + */
  209.63 +static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
  209.64 +{
  209.65 +	int expired = 0;
  209.66 +	struct timer_list status_timer =
  209.67 +	    TIMER_INITIALIZER(tpm_time_expired, jiffies + 10 * HZ,
  209.68 +			      (unsigned long) &expired);
  209.69 +
  209.70 +	/* status immediately available check */
  209.71 +	*data = inb(chip->vendor->base + NSC_STATUS);
  209.72 +	if ((*data & mask) == val)
  209.73 +		return 0;
  209.74 +
  209.75 +	/* wait for status */
  209.76 +	add_timer(&status_timer);
  209.77 +	do {
  209.78 +		set_current_state(TASK_UNINTERRUPTIBLE);
  209.79 +		schedule_timeout(TPM_TIMEOUT);
  209.80 +		*data = inb(chip->vendor->base + 1);
  209.81 +		if ((*data & mask) == val) {
  209.82 +			del_singleshot_timer_sync(&status_timer);
  209.83 +			return 0;
  209.84 +		}
  209.85 +	}
  209.86 +	while (!expired);
  209.87 +
  209.88 +	return -EBUSY;
  209.89 +}
  209.90 +
  209.91 +static int nsc_wait_for_ready(struct tpm_chip *chip)
  209.92 +{
  209.93 +	int status;
  209.94 +	int expired = 0;
  209.95 +	struct timer_list status_timer =
  209.96 +	    TIMER_INITIALIZER(tpm_time_expired, jiffies + 100,
  209.97 +			      (unsigned long) &expired);
  209.98 +
  209.99 +	/* status immediately available check */
 209.100 +	status = inb(chip->vendor->base + NSC_STATUS);
 209.101 +	if (status & NSC_STATUS_OBF)
 209.102 +		status = inb(chip->vendor->base + NSC_DATA);
 209.103 +	if (status & NSC_STATUS_RDY)
 209.104 +		return 0;
 209.105 +
 209.106 +	/* wait for status */
 209.107 +	add_timer(&status_timer);
 209.108 +	do {
 209.109 +		set_current_state(TASK_UNINTERRUPTIBLE);
 209.110 +		schedule_timeout(TPM_TIMEOUT);
 209.111 +		status = inb(chip->vendor->base + NSC_STATUS);
 209.112 +		if (status & NSC_STATUS_OBF)
 209.113 +			status = inb(chip->vendor->base + NSC_DATA);
 209.114 +		if (status & NSC_STATUS_RDY) {
 209.115 +			del_singleshot_timer_sync(&status_timer);
 209.116 +			return 0;
 209.117 +		}
 209.118 +	}
 209.119 +	while (!expired);
 209.120 +
 209.121 +	dev_info(&chip->pci_dev->dev, "wait for ready failed\n");
 209.122 +	return -EBUSY;
 209.123 +}
 209.124 +
 209.125 +
 209.126 +static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
 209.127 +{
 209.128 +	u8 *buffer = buf;
 209.129 +	u8 data, *p;
 209.130 +	u32 size;
 209.131 +	__be32 *native_size;
 209.132 +
 209.133 +	if (count < 6)
 209.134 +		return -EIO;
 209.135 +
 209.136 +	if (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0) {
 209.137 +		dev_err(&chip->pci_dev->dev, "F0 timeout\n");
 209.138 +		return -EIO;
 209.139 +	}
 209.140 +	if ((data =
 209.141 +	     inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
 209.142 +		dev_err(&chip->pci_dev->dev, "not in normal mode (0x%x)\n",
 209.143 +			data);
 209.144 +		return -EIO;
 209.145 +	}
 209.146 +
 209.147 +	/* read the whole packet */
 209.148 +	for (p = buffer; p < &buffer[count]; p++) {
 209.149 +		if (wait_for_stat
 209.150 +		    (chip, NSC_STATUS_OBF, NSC_STATUS_OBF, &data) < 0) {
 209.151 +			dev_err(&chip->pci_dev->dev,
 209.152 +				"OBF timeout (while reading data)\n");
 209.153 +			return -EIO;
 209.154 +		}
 209.155 +		if (data & NSC_STATUS_F0)
 209.156 +			break;
 209.157 +		*p = inb(chip->vendor->base + NSC_DATA);
 209.158 +	}
 209.159 +
 209.160 +	if ((data & NSC_STATUS_F0) == 0) {
 209.161 +		dev_err(&chip->pci_dev->dev, "F0 not set\n");
 209.162 +		return -EIO;
 209.163 +	}
 209.164 +	if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) {
 209.165 +		dev_err(&chip->pci_dev->dev,
 209.166 +			"expected end of command(0x%x)\n", data);
 209.167 +		return -EIO;
 209.168 +	}
 209.169 +
 209.170 +	native_size = (__force __be32 *) (buf + 2);
 209.171 +	size = be32_to_cpu(*native_size);
 209.172 +
 209.173 +	if (count < size)
 209.174 +		return -EIO;
 209.175 +
 209.176 +	return size;
 209.177 +}
 209.178 +
 209.179 +static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
 209.180 +{
 209.181 +	u8 data;
 209.182 +	int i;
 209.183 +
 209.184 +	/*
 209.185 +	 * If we hit the chip with back to back commands it locks up
 209.186 +	 * and never set IBF. Hitting it with this "hammer" seems to
 209.187 +	 * fix it. Not sure why this is needed, we followed the flow
 209.188 +	 * chart in the manual to the letter.
 209.189 +	 */
 209.190 +	outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
 209.191 +
 209.192 +	if (nsc_wait_for_ready(chip) != 0)
 209.193 +		return -EIO;
 209.194 +
 209.195 +	if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
 209.196 +		dev_err(&chip->pci_dev->dev, "IBF timeout\n");
 209.197 +		return -EIO;
 209.198 +	}
 209.199 +
 209.200 +	outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND);
 209.201 +	if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
 209.202 +		dev_err(&chip->pci_dev->dev, "IBR timeout\n");
 209.203 +		return -EIO;
 209.204 +	}
 209.205 +
 209.206 +	for (i = 0; i < count; i++) {
 209.207 +		if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
 209.208 +			dev_err(&chip->pci_dev->dev,
 209.209 +				"IBF timeout (while writing data)\n");
 209.210 +			return -EIO;
 209.211 +		}
 209.212 +		outb(buf[i], chip->vendor->base + NSC_DATA);
 209.213 +	}
 209.214 +
 209.215 +	if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
 209.216 +		dev_err(&chip->pci_dev->dev, "IBF timeout\n");
 209.217 +		return -EIO;
 209.218 +	}
 209.219 +	outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND);
 209.220 +
 209.221 +	return count;
 209.222 +}
 209.223 +
 209.224 +static void tpm_nsc_cancel(struct tpm_chip *chip)
 209.225 +{
 209.226 +	outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
 209.227 +}
 209.228 +
 209.229 +static struct file_operations nsc_ops = {
 209.230 +	.owner = THIS_MODULE,
 209.231 +	.llseek = no_llseek,
 209.232 +	.open = tpm_open,
 209.233 +	.read = tpm_read,
 209.234 +	.write = tpm_write,
 209.235 +	.release = tpm_release,
 209.236 +};
 209.237 +
 209.238 +static struct tpm_vendor_specific tpm_nsc = {
 209.239 +	.recv = tpm_nsc_recv,
 209.240 +	.send = tpm_nsc_send,
 209.241 +	.cancel = tpm_nsc_cancel,
 209.242 +	.req_complete_mask = NSC_STATUS_OBF,
 209.243 +	.req_complete_val = NSC_STATUS_OBF,
 209.244 +	.miscdev = { .fops = &nsc_ops, },
 209.245 +
 209.246 +};
 209.247 +
 209.248 +static int __devinit tpm_nsc_init(struct pci_dev *pci_dev,
 209.249 +				  const struct pci_device_id *pci_id)
 209.250 +{
 209.251 +	int rc = 0;
 209.252 +	int lo, hi;
 209.253 +
 209.254 +	hi = tpm_read_index(TPM_NSC_BASE0_HI);
 209.255 +	lo = tpm_read_index(TPM_NSC_BASE0_LO);
 209.256 +
 209.257 +	tpm_nsc.base = (hi<<8) | lo;
 209.258 +
 209.259 +	if (pci_enable_device(pci_dev))
 209.260 +		return -EIO;
 209.261 +
 209.262 +	/* verify that it is a National part (SID) */
 209.263 +	if (tpm_read_index(NSC_SID_INDEX) != 0xEF) {
 209.264 +		rc = -ENODEV;
 209.265 +		goto out_err;
 209.266 +	}
 209.267 +
 209.268 +	dev_dbg(&pci_dev->dev, "NSC TPM detected\n");
 209.269 +	dev_dbg(&pci_dev->dev,
 209.270 +		"NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n",
 209.271 +		tpm_read_index(0x07), tpm_read_index(0x20),
 209.272 +		tpm_read_index(0x27));
 209.273 +	dev_dbg(&pci_dev->dev,
 209.274 +		"NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n",
 209.275 +		tpm_read_index(0x21), tpm_read_index(0x25),
 209.276 +		tpm_read_index(0x26), tpm_read_index(0x28));
 209.277 +	dev_dbg(&pci_dev->dev, "NSC IO Base0 0x%x\n",
 209.278 +		(tpm_read_index(0x60) << 8) | tpm_read_index(0x61));
 209.279 +	dev_dbg(&pci_dev->dev, "NSC IO Base1 0x%x\n",
 209.280 +		(tpm_read_index(0x62) << 8) | tpm_read_index(0x63));
 209.281 +	dev_dbg(&pci_dev->dev, "NSC Interrupt number and wakeup 0x%x\n",
 209.282 +		tpm_read_index(0x70));
 209.283 +	dev_dbg(&pci_dev->dev, "NSC IRQ type select 0x%x\n",
 209.284 +		tpm_read_index(0x71));
 209.285 +	dev_dbg(&pci_dev->dev,
 209.286 +		"NSC DMA channel select0 0x%x, select1 0x%x\n",
 209.287 +		tpm_read_index(0x74), tpm_read_index(0x75));
 209.288 +	dev_dbg(&pci_dev->dev,
 209.289 +		"NSC Config "
 209.290 +		"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
 209.291 +		tpm_read_index(0xF0), tpm_read_index(0xF1),
 209.292 +		tpm_read_index(0xF2), tpm_read_index(0xF3),
 209.293 +		tpm_read_index(0xF4), tpm_read_index(0xF5),
 209.294 +		tpm_read_index(0xF6), tpm_read_index(0xF7),
 209.295 +		tpm_read_index(0xF8), tpm_read_index(0xF9));
 209.296 +
 209.297 +	dev_info(&pci_dev->dev,
 209.298 +		 "NSC PC21100 TPM revision %d\n",
 209.299 +		 tpm_read_index(0x27) & 0x1F);
 209.300 +
 209.301 +	if (tpm_read_index(NSC_LDC_INDEX) == 0)
 209.302 +		dev_info(&pci_dev->dev, ": NSC TPM not active\n");
 209.303 +
 209.304 +	/* select PM channel 1 */
 209.305 +	tpm_write_index(NSC_LDN_INDEX, 0x12);
 209.306 +	tpm_read_index(NSC_LDN_INDEX);
 209.307 +
 209.308 +	/* disable the DPM module */
 209.309 +	tpm_write_index(NSC_LDC_INDEX, 0);
 209.310 +	tpm_read_index(NSC_LDC_INDEX);
 209.311 +
 209.312 +	/* set the data register base addresses */
 209.313 +	tpm_write_index(NSC_DIO_INDEX, TPM_NSC_BASE >> 8);
 209.314 +	tpm_write_index(NSC_DIO_INDEX + 1, TPM_NSC_BASE);
 209.315 +	tpm_read_index(NSC_DIO_INDEX);
 209.316 +	tpm_read_index(NSC_DIO_INDEX + 1);
 209.317 +
 209.318 +	/* set the command register base addresses */
 209.319 +	tpm_write_index(NSC_CIO_INDEX, (TPM_NSC_BASE + 1) >> 8);
 209.320 +	tpm_write_index(NSC_CIO_INDEX + 1, (TPM_NSC_BASE + 1));
 209.321 +	tpm_read_index(NSC_DIO_INDEX);
 209.322 +	tpm_read_index(NSC_DIO_INDEX + 1);
 209.323 +
 209.324 +	/* set the interrupt number to be used for the host interface */
 209.325 +	tpm_write_index(NSC_IRQ_INDEX, TPM_NSC_IRQ);
 209.326 +	tpm_write_index(NSC_ITS_INDEX, 0x00);
 209.327 +	tpm_read_index(NSC_IRQ_INDEX);
 209.328 +
 209.329 +	/* enable the DPM module */
 209.330 +	tpm_write_index(NSC_LDC_INDEX, 0x01);
 209.331 +	tpm_read_index(NSC_LDC_INDEX);
 209.332 +
 209.333 +	if ((rc = tpm_register_hardware(pci_dev, &tpm_nsc)) < 0)
 209.334 +		goto out_err;
 209.335 +
 209.336 +	return 0;
 209.337 +
 209.338 +out_err:
 209.339 +	pci_disable_device(pci_dev);
 209.340 +	return rc;
 209.341 +}
 209.342 +
 209.343 +static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
 209.344 +	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
 209.345 +	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
 209.346 +	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
 209.347 +	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
 209.348 +	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
 209.349 +	{PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
 209.350 +	{0,}
 209.351 +};
 209.352 +
 209.353 +MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
 209.354 +
 209.355 +static struct pci_driver nsc_pci_driver = {
 209.356 +	.name = "tpm_nsc",
 209.357 +	.id_table = tpm_pci_tbl,
 209.358 +	.probe = tpm_nsc_init,
 209.359 +	.remove = __devexit_p(tpm_remove),
 209.360 +	.suspend = tpm_pm_suspend,
 209.361 +	.resume = tpm_pm_resume,
 209.362 +};
 209.363 +
 209.364 +static int __init init_nsc(void)
 209.365 +{
 209.366 +	return pci_register_driver(&nsc_pci_driver);
 209.367 +}
 209.368 +
 209.369 +static void __exit cleanup_nsc(void)
 209.370 +{
 209.371 +	pci_unregister_driver(&nsc_pci_driver);
 209.372 +}
 209.373 +
 209.374 +module_init(init_nsc);
 209.375 +module_exit(cleanup_nsc);
 209.376 +
 209.377 +MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
 209.378 +MODULE_DESCRIPTION("TPM Driver");
 209.379 +MODULE_VERSION("2.0");
 209.380 +MODULE_LICENSE("GPL");
   210.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   210.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c	Thu Sep 01 10:16:14 2005 +0000
   210.3 @@ -0,0 +1,513 @@
   210.4 +/*
   210.5 + * Copyright (C) 2004 IBM Corporation
   210.6 + *
   210.7 + * Authors:
   210.8 + * Leendert van Doorn <leendert@watson.ibm.com>
   210.9 + * Dave Safford <safford@watson.ibm.com>
  210.10 + * Reiner Sailer <sailer@watson.ibm.com>
  210.11 + * Kylene Hall <kjhall@us.ibm.com>
  210.12 + * Stefan Berger <stefanb@us.ibm.com>
  210.13 + *
  210.14 + * Maintained by: <tpmdd_devel@lists.sourceforge.net>
  210.15 + *
  210.16 + * Device driver for TCG/TCPA TPM (trusted platform module) for XEN.
  210.17 + * Specifications at www.trustedcomputinggroup.org
  210.18 + *
  210.19 + * This program is free software; you can redistribute it and/or
  210.20 + * modify it under the terms of the GNU General Public License as
  210.21 + * published by the Free Software Foundation, version 2 of the
  210.22 + * License.
  210.23 + *
  210.24 + */
  210.25 +
  210.26 +#include <asm/uaccess.h>
  210.27 +#include <linux/list.h>
  210.28 +#include <linux/tpmfe.h>
  210.29 +#include <linux/device.h>
  210.30 +#include <linux/interrupt.h>
  210.31 +#include "tpm_nopci.h"
  210.32 +
  210.33 +/* read status bits */
  210.34 +enum {
  210.35 +	STATUS_BUSY = 0x01,
  210.36 +	STATUS_DATA_AVAIL = 0x02,
  210.37 +	STATUS_READY = 0x04
  210.38 +};
  210.39 +
  210.40 +#define MIN(x,y)  ((x) < (y)) ? (x) : (y)
  210.41 +
  210.42 +struct transmission {
  210.43 +	struct list_head next;
  210.44 +	unsigned char *request;
  210.45 +	unsigned int request_len;
  210.46 +	unsigned char *rcv_buffer;
  210.47 +	unsigned int  buffersize;
  210.48 +	struct tpm_chip     *chip;
  210.49 +	unsigned int flags;
  210.50 +};
  210.51 +
  210.52 +enum {
  210.53 +	TRANSMISSION_FLAG_WAS_QUEUED = 0x1
  210.54 +};
  210.55 +
  210.56 +struct data_exchange {
  210.57 +	struct transmission *current_request;
  210.58 +	spinlock_t           req_list_lock;
  210.59 +	wait_queue_head_t    req_wait_queue;
  210.60 +
  210.61 +	struct list_head     queued_requests;
  210.62 +
  210.63 +	struct transmission *current_response;
  210.64 +	spinlock_t           resp_list_lock;
  210.65 +	wait_queue_head_t    resp_wait_queue;     // processes waiting for responses
  210.66 +
  210.67 +	struct transmission *req_cancelled;       // if a cancellation was encounterd
  210.68 +
  210.69 +	unsigned int         fe_status;
  210.70 +	unsigned int         flags;
  210.71 +};
  210.72 +
  210.73 +enum {
  210.74 +	DATAEX_FLAG_QUEUED_ONLY = 0x1
  210.75 +};
  210.76 +
  210.77 +static struct data_exchange dataex;
  210.78 +
  210.79 +static unsigned long disconnect_time;
  210.80 +
  210.81 +/* local function prototypes */
  210.82 +static void __exit cleanup_xen(void);
  210.83 +
  210.84 +
  210.85 +/* =============================================================
  210.86 + * Some utility functions
  210.87 + * =============================================================
  210.88 + */
  210.89 +static inline struct transmission *
  210.90 +transmission_alloc(void)
  210.91 +{
  210.92 +	struct transmission *t = kmalloc(sizeof(*t), GFP_KERNEL);
  210.93 +	if (t) {
  210.94 +		memset(t, 0x0, sizeof(*t));
  210.95 +	}
  210.96 +	return t;
  210.97 +}
  210.98 +
  210.99 +static inline unsigned char *
 210.100 +transmission_set_buffer(struct transmission *t,
 210.101 +                        unsigned char *buffer, unsigned int len)
 210.102 +{
 210.103 +	if (NULL != t->request) {
 210.104 +		kfree(t->request);
 210.105 +	}
 210.106 +	t->request = kmalloc(len, GFP_KERNEL);
 210.107 +	if (t->request) {
 210.108 +		memcpy(t->request,
 210.109 +		       buffer,
 210.110 +		       len);
 210.111 +		t->request_len = len;
 210.112 +	}
 210.113 +	return t->request;
 210.114 +}
 210.115 +
 210.116 +static inline void
 210.117 +transmission_free(struct transmission *t)
 210.118 +{
 210.119 +	if (t->request) {
 210.120 +		kfree(t->request);
 210.121 +	}
 210.122 +	if (t->rcv_buffer) {
 210.123 +		kfree(t->rcv_buffer);
 210.124 +	}
 210.125 +	kfree(t);
 210.126 +}
 210.127 +
 210.128 +/* =============================================================
 210.129 + * Interface with the TPM shared memory driver for XEN
 210.130 + * =============================================================
 210.131 + */
 210.132 +static int tpm_recv(const u8 *buffer, size_t count, const void *ptr)
 210.133 +{
 210.134 +	int ret_size = 0;
 210.135 +	struct transmission *t, *temp;
 210.136 +
 210.137 +	/*
 210.138 +	 * The list with requests must contain one request
 210.139 +	 * only and the element there must be the one that
 210.140 +	 * was passed to me from the front-end.
 210.141 +	 */
 210.142 +	if (dataex.current_request != ptr) {
 210.143 +		printk("WARNING: The request pointer is different than the pointer "
 210.144 +		       "the shared memory driver returned to me. %p != %p\n",
 210.145 +		       dataex.current_request, ptr);
 210.146 +	}
 210.147 +
 210.148 +	/*
 210.149 +	 * If the request has been cancelled, just quit here
 210.150 +	 */
 210.151 +	if (dataex.req_cancelled == (struct transmission *)ptr) {
 210.152 +		if (dataex.current_request == dataex.req_cancelled) {
 210.153 +			dataex.current_request = NULL;
 210.154 +		}
 210.155 +		transmission_free(dataex.req_cancelled);
 210.156 +		dataex.req_cancelled = NULL;
 210.157 +		return 0;
 210.158 +	}
 210.159 +
 210.160 +	if (NULL != (temp = dataex.current_request)) {
 210.161 +		transmission_free(temp);
 210.162 +		dataex.current_request = NULL;
 210.163 +	}
 210.164 +
 210.165 +	t = transmission_alloc();
 210.166 +	if (NULL != t) {
 210.167 +		unsigned long flags;
 210.168 +		t->rcv_buffer = kmalloc(count, GFP_KERNEL);
 210.169 +		if (NULL == t->rcv_buffer) {
 210.170 +			transmission_free(t);
 210.171 +			return -ENOMEM;
 210.172 +		}
 210.173 +		t->buffersize = count;
 210.174 +		memcpy(t->rcv_buffer, buffer, count);
 210.175 +		ret_size = count;
 210.176 +
 210.177 +		spin_lock_irqsave(&dataex.resp_list_lock ,flags);
 210.178 +		dataex.current_response = t;
 210.179 +		spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
 210.180 +		wake_up_interruptible(&dataex.resp_wait_queue);
 210.181 +	}
 210.182 +	return ret_size;
 210.183 +}
 210.184 +
 210.185 +
 210.186 +static void tpm_fe_status(unsigned int flags)
 210.187 +{
 210.188 +	dataex.fe_status = flags;
 210.189 +	if ((dataex.fe_status & TPMFE_STATUS_CONNECTED) == 0) {
 210.190 +		disconnect_time = jiffies;
 210.191 +	}
 210.192 +}
 210.193 +
 210.194 +/* =============================================================
 210.195 + * Interface with the generic TPM driver
 210.196 + * =============================================================
 210.197 + */
 210.198 +static int tpm_xen_recv(struct tpm_chip *chip, u8 * buf, size_t count)
 210.199 +{
 210.200 +	unsigned long flags;
 210.201 +	int rc = 0;
 210.202 +
 210.203 +	spin_lock_irqsave(&dataex.resp_list_lock, flags);
 210.204 +	/*
 210.205 +	 * Check if the previous operation only queued the command
 210.206 +	 * In this case there won't be a response, so I just
 210.207 +	 * return from here and reset that flag. In any other
 210.208 +	 * case I should receive a response from the back-end.
 210.209 +	 */
 210.210 +	if ((dataex.flags & DATAEX_FLAG_QUEUED_ONLY) != 0) {
 210.211 +		dataex.flags &= ~DATAEX_FLAG_QUEUED_ONLY;
 210.212 +		spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
 210.213 +		/*
 210.214 +		 * a little hack here. The first few measurements
 210.215 +		 * are queued since there's no way to talk to the
 210.216 +		 * TPM yet (due to slowness of the control channel)
 210.217 +		 * So we just make IMA happy by giving it 30 NULL
 210.218 +		 * bytes back where the most important part is
 210.219 +		 * that the result code is '0'.
 210.220 +		 */
 210.221 +
 210.222 +		count = MIN(count, 30);
 210.223 +		memset(buf, 0x0, count);
 210.224 +		return count;
 210.225 +	}
 210.226 +	/*
 210.227 +	 * Check whether something is in the responselist and if
 210.228 +	 * there's nothing in the list wait for something to appear.
 210.229 +	 */
 210.230 +
 210.231 +	if (NULL == dataex.current_response) {
 210.232 +		spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
 210.233 +		interruptible_sleep_on_timeout(&dataex.resp_wait_queue,
 210.234 +		                               1000);
 210.235 +		spin_lock_irqsave(&dataex.resp_list_lock ,flags);
 210.236 +	}
 210.237 +
 210.238 +	if (NULL != dataex.current_response) {
 210.239 +		struct transmission *t = dataex.current_response;
 210.240 +		dataex.current_response = NULL;
 210.241 +		rc = MIN(count, t->buffersize);
 210.242 +		memcpy(buf, t->rcv_buffer, rc);
 210.243 +		transmission_free(t);
 210.244 +	}
 210.245 +
 210.246 +	spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
 210.247 +	return rc;
 210.248 +}
 210.249 +
 210.250 +static int tpm_xen_send(struct tpm_chip *chip, u8 * buf, size_t count)
 210.251 +{
 210.252 +	/*
 210.253 +	 * We simply pass the packet onto the XEN shared
 210.254 +	 * memory driver.
 210.255 +	 */
 210.256 +	unsigned long flags;
 210.257 +	int rc;
 210.258 +	struct transmission *t = transmission_alloc();
 210.259 +
 210.260 +	spin_lock_irqsave(&dataex.req_list_lock, flags);
 210.261 +	/*
 210.262 +	 * If there's a current request, it must be the
 210.263 +	 * previous request that has timed out.
 210.264 +	 */
 210.265 +	if (dataex.current_request != NULL) {
 210.266 +		printk("WARNING: Sending although there is a request outstanding.\n"
 210.267 +		       "         Previous request must have timed out.\n");
 210.268 +		transmission_free(dataex.current_request);
 210.269 +		dataex.current_request = NULL;
 210.270 +	}
 210.271 +
 210.272 +	if (t != NULL) {
 210.273 +		unsigned int error = 0;
 210.274 +		t->rcv_buffer = NULL;
 210.275 +		t->buffersize = 0;
 210.276 +		t->chip = chip;
 210.277 +
 210.278 +		/*
 210.279 +		 * Queue the packet if the driver below is not
 210.280 +		 * ready, yet, or there is any packet already
 210.281 +		 * in the queue.
 210.282 +		 * If the driver below is ready, unqueue all
 210.283 +		 * packets first before sending our current
 210.284 +		 * packet.
 210.285 +		 * For each unqueued packet, except for the
 210.286 +		 * last (=current) packet, call the function
 210.287 +		 * tpm_xen_recv to wait for the response to come
 210.288 +		 * back.
 210.289 +		 */
 210.290 +		if ((dataex.fe_status & TPMFE_STATUS_CONNECTED) == 0) {
 210.291 +			if (time_after(jiffies, disconnect_time + HZ * 10)) {
 210.292 +				rc = -ENOENT;
 210.293 +			} else {
 210.294 +				/*
 210.295 +				 * copy the request into the buffer
 210.296 +				 */
 210.297 +				if (transmission_set_buffer(t, buf, count)
 210.298 +				    == NULL) {
 210.299 +					transmission_free(t);
 210.300 +					rc = -ENOMEM;
 210.301 +					goto exit;
 210.302 +				}
 210.303 +				dataex.flags |= DATAEX_FLAG_QUEUED_ONLY;
 210.304 +				list_add_tail(&t->next, &dataex.queued_requests);
 210.305 +				rc = 0;
 210.306 +			}
 210.307 +		} else {
 210.308 +			/*
 210.309 +			 * Check whether there are any packets in the queue
 210.310 +			 */
 210.311 +			while (!list_empty(&dataex.queued_requests)) {
 210.312 +				/*
 210.313 +				 * Need to dequeue them.
 210.314 +				 * Read the result into a dummy buffer.
 210.315 +				 */
 210.316 +				unsigned char buffer[1];
 210.317 +				struct transmission *qt = (struct transmission *) dataex.queued_requests.next;
 210.318 +				list_del(&qt->next);
 210.319 +				dataex.current_request = qt;
 210.320 +				spin_unlock_irqrestore(&dataex.req_list_lock, flags);
 210.321 +
 210.322 +				rc = tpm_fe_send(qt->request,
 210.323 +				                 qt->request_len,
 210.324 +				                 qt);
 210.325 +
 210.326 +				if (rc < 0) {
 210.327 +					spin_lock_irqsave(&dataex.req_list_lock, flags);
 210.328 +					if ((qt = dataex.current_request) != NULL) {
 210.329 +						/*
 210.330 +						 * requeue it at the beginning
 210.331 +						 * of the list
 210.332 +						 */
 210.333 +						list_add(&qt->next,
 210.334 +						         &dataex.queued_requests);
 210.335 +					}
 210.336 +					dataex.current_request = NULL;
 210.337 +					error = 1;
 210.338 +					break;
 210.339 +				}
 210.340 +				/*
 210.341 +				 * After this point qt is not valid anymore!
 210.342 +				 * It is freed when the front-end is delivering the data
 210.343 +				 * by calling tpm_recv
 210.344 +				 */
 210.345 +
 210.346 +				/*
 210.347 +				 * Try to receive the response now into the provided dummy
 210.348 +				 * buffer (I don't really care about this response since
 210.349 +				 * there is no receiver anymore for this response)
 210.350 +				 */
 210.351 +				rc = tpm_xen_recv(chip, buffer, sizeof(buffer));
 210.352 +
 210.353 +				spin_lock_irqsave(&dataex.req_list_lock, flags);
 210.354 +			}
 210.355 +
 210.356 +			if (error == 0) {
 210.357 +				/*
 210.358 +				 * Finally, send the current request.
 210.359 +				 */
 210.360 +				dataex.current_request = t;
 210.361 +				/*
 210.362 +				 * Call the shared memory driver
 210.363 +				 * Pass to it the buffer with the request, the
 210.364 +				 * amount of bytes in the request and
 210.365 +				 * a void * pointer (here: transmission structure)
 210.366 +				 */
 210.367 +				rc = tpm_fe_send(buf, count, t);
 210.368 +				/*
 210.369 +				 * The generic TPM driver will call
 210.370 +				 * the function to receive the response.
 210.371 +				 */
 210.372 +				if (rc < 0) {
 210.373 +					dataex.current_request = NULL;
 210.374 +					goto queue_it;
 210.375 +				}
 210.376 +			} else {
 210.377 +queue_it:
 210.378 +				if (transmission_set_buffer(t, buf, count) == NULL) {
 210.379 +					transmission_free(t);
 210.380 +					rc = -ENOMEM;
 210.381 +					goto exit;
 210.382 +				}
 210.383 +				/*
 210.384 +				 * An error occurred. Don't event try
 210.385 +				 * to send the current request. Just
 210.386 +				 * queue it.
 210.387 +				 */
 210.388 +				dataex.flags |= DATAEX_FLAG_QUEUED_ONLY;
 210.389 +				list_add_tail(&t->next, &dataex.queued_requests);
 210.390 +				rc = 0;
 210.391 +			}
 210.392 +		}
 210.393 +	} else {
 210.394 +		rc = -ENOMEM;
 210.395 +	}
 210.396 +
 210.397 +exit:
 210.398 +	spin_unlock_irqrestore(&dataex.req_list_lock, flags);
 210.399 +	return rc;
 210.400 +}
 210.401 +
 210.402 +static void tpm_xen_cancel(struct tpm_chip *chip)
 210.403 +{
 210.404 +	unsigned long flags;
 210.405 +	spin_lock_irqsave(&dataex.resp_list_lock,flags);
 210.406 +
 210.407 +	dataex.req_cancelled = dataex.current_request;
 210.408 +
 210.409 +	spin_unlock_irqrestore(&dataex.resp_list_lock,flags);
 210.410 +}
 210.411 +
 210.412 +static u8 tpm_xen_status(struct tpm_chip *chip)
 210.413 +{
 210.414 +	unsigned long flags;
 210.415 +	u8 rc = 0;
 210.416 +	spin_lock_irqsave(&dataex.resp_list_lock, flags);
 210.417 +	/*
 210.418 +	 * Data are available if:
 210.419 +	 *  - there's a current response
 210.420 +	 *  - the last packet was queued only (this is fake, but necessary to
 210.421 +	 *      get the generic TPM layer to call the receive function.)
 210.422 +	 */
 210.423 +	if (NULL != dataex.current_response ||
 210.424 +	    0 != (dataex.flags & DATAEX_FLAG_QUEUED_ONLY)) {
 210.425 +		rc = STATUS_DATA_AVAIL;
 210.426 +	}
 210.427 +	spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
 210.428 +	return rc;
 210.429 +}
 210.430 +
 210.431 +static struct file_operations tpm_xen_ops = {
 210.432 +	.owner = THIS_MODULE,
 210.433 +	.llseek = no_llseek,
 210.434 +	.open = tpm_open,
 210.435 +	.read = tpm_read,
 210.436 +	.write = tpm_write,
 210.437 +	.release = tpm_release,
 210.438 +};
 210.439 +
 210.440 +static struct tpm_vendor_specific tpm_xen = {
 210.441 +	.recv = tpm_xen_recv,
 210.442 +	.send = tpm_xen_send,
 210.443 +	.cancel = tpm_xen_cancel,
 210.444 +	.status = tpm_xen_status,
 210.445 +	.req_complete_mask = STATUS_BUSY | STATUS_DATA_AVAIL,
 210.446 +	.req_complete_val  = STATUS_DATA_AVAIL,
 210.447 +	.req_canceled = STATUS_READY,
 210.448 +	.base = 0,
 210.449 +	.attr = TPM_DEVICE_ATTRS,
 210.450 +	.miscdev.fops = &tpm_xen_ops,
 210.451 +};
 210.452 +
 210.453 +static struct device tpm_device = {
 210.454 +	.bus_id = "vtpm",
 210.455 +};
 210.456 +
 210.457 +static struct tpmfe_device tpmfe = {
 210.458 +	.receive = tpm_recv,
 210.459 +	.status  = tpm_fe_status,
 210.460 +};
 210.461 +
 210.462 +
 210.463 +static int __init init_xen(void)
 210.464 +{
 210.465 +	int rc;
 210.466 +
 210.467 +	/*
 210.468 +	 * Register device with the low lever front-end
 210.469 +	 * driver
 210.470 +	 */
 210.471 +	if ((rc = tpm_fe_register_receiver(&tpmfe)) < 0) {
 210.472 +		return rc;
 210.473 +	}
 210.474 +
 210.475 +	/*
 210.476 +	 * Register our device with the system.
 210.477 +	 */
 210.478 +	if ((rc = device_register(&tpm_device)) < 0) {
 210.479 +		tpm_fe_unregister_receiver();
 210.480 +		return rc;
 210.481 +	}
 210.482 +
 210.483 +	if ((rc = tpm_register_hardware_nopci(&tpm_device, &tpm_xen)) < 0) {
 210.484 +		device_unregister(&tpm_device);
 210.485 +		tpm_fe_unregister_receiver();
 210.486 +		return rc;
 210.487 +	}
 210.488 +
 210.489 +	dataex.current_request = NULL;
 210.490 +	spin_lock_init(&dataex.req_list_lock);
 210.491 +	init_waitqueue_head(&dataex.req_wait_queue);
 210.492 +	INIT_LIST_HEAD(&dataex.queued_requests);
 210.493 +
 210.494 +	dataex.current_response = NULL;
 210.495 +	spin_lock_init(&dataex.resp_list_lock);
 210.496 +	init_waitqueue_head(&dataex.resp_wait_queue);
 210.497 +
 210.498 +	disconnect_time = jiffies;
 210.499 +
 210.500 +	return 0;
 210.501 +}
 210.502 +
 210.503 +static void __exit cleanup_xen(void)
 210.504 +{
 210.505 +	tpm_remove_hardware(&tpm_device);
 210.506 +	device_unregister(&tpm_device);
 210.507 +	tpm_fe_unregister_receiver();
 210.508 +}
 210.509 +
 210.510 +fs_initcall(init_xen);
 210.511 +module_exit(cleanup_xen);
 210.512 +
 210.513 +MODULE_AUTHOR("Stefan Berger (stefanb@us.ibm.com)");
 210.514 +MODULE_DESCRIPTION("TPM Driver for XEN (shared memory)");
 210.515 +MODULE_VERSION("1.0");
 210.516 +MODULE_LICENSE("GPL");
   212.1 --- a/linux-2.6-xen-sparse/drivers/xen/Makefile	Thu Sep 01 10:08:53 2005 +0000
   212.2 +++ b/linux-2.6-xen-sparse/drivers/xen/Makefile	Thu Sep 01 10:16:14 2005 +0000
   212.3 @@ -8,7 +8,9 @@ obj-y	+= xenbus/
   212.4  
   212.5  obj-$(CONFIG_XEN_BLKDEV_BACKEND)	+= blkback/
   212.6  obj-$(CONFIG_XEN_NETDEV_BACKEND)	+= netback/
   212.7 +obj-$(CONFIG_XEN_TPMDEV_BACKEND)	+= tpmback/
   212.8  obj-$(CONFIG_XEN_BLKDEV_FRONTEND)	+= blkfront/
   212.9  obj-$(CONFIG_XEN_NETDEV_FRONTEND)	+= netfront/
  212.10  obj-$(CONFIG_XEN_BLKDEV_TAP)    	+= blktap/
  212.11 +obj-$(CONFIG_XEN_TPMDEV_FRONTEND)	+= tpmfront/
  212.12  
   249.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   249.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/Makefile	Thu Sep 01 10:16:14 2005 +0000
   249.3 @@ -0,0 +1,4 @@
   249.4 +
   249.5 +obj-$(CONFIG_XEN_TPMDEV_BACKEND)	+= tpmbk.o
   249.6 +
   249.7 +tpmbk-y += tpmback.o interface.o xenbus.o
   250.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   250.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h	Thu Sep 01 10:16:14 2005 +0000
   250.3 @@ -0,0 +1,89 @@
   250.4 +/******************************************************************************
   250.5 + * drivers/xen/tpmback/common.h
   250.6 + */
   250.7 +
   250.8 +#ifndef __NETIF__BACKEND__COMMON_H__
   250.9 +#define __NETIF__BACKEND__COMMON_H__
  250.10 +
  250.11 +#include <linux/config.h>
  250.12 +#include <linux/version.h>
  250.13 +#include <linux/module.h>
  250.14 +#include <linux/interrupt.h>
  250.15 +#include <linux/slab.h>
  250.16 +#include <asm-xen/ctrl_if.h>
  250.17 +#include <asm-xen/evtchn.h>
  250.18 +#include <asm-xen/xen-public/io/tpmif.h>
  250.19 +#include <asm/io.h>
  250.20 +#include <asm/pgalloc.h>
  250.21 +#include <asm-xen/xen-public/io/domain_controller.h>
  250.22 +
  250.23 +#if 0
  250.24 +#define ASSERT(_p) \
  250.25 +    if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
  250.26 +    __LINE__, __FILE__); *(int*)0=0; }
  250.27 +#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
  250.28 +                           __FILE__ , __LINE__ , ## _a )
  250.29 +#else
  250.30 +#define ASSERT(_p) ((void)0)
  250.31 +#define DPRINTK(_f, _a...) ((void)0)
  250.32 +#endif
  250.33 +
  250.34 +typedef struct tpmif_st {
  250.35 +        struct list_head tpmif_list;
  250.36 +	/* Unique identifier for this interface. */
  250.37 +	domid_t domid;
  250.38 +	unsigned int handle;
  250.39 +
  250.40 +	/* Physical parameters of the comms window. */
  250.41 +	unsigned long tx_shmem_frame;
  250.42 +	unsigned int evtchn;
  250.43 +	unsigned int remote_evtchn;
  250.44 +
  250.45 +	/* The shared rings and indexes. */
  250.46 +	tpmif_tx_interface_t *tx;
  250.47 +
  250.48 +	/* Miscellaneous private stuff. */
  250.49 +	enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
  250.50 +	int active;
  250.51 +
  250.52 +	struct tpmif_st *hash_next;
  250.53 +	struct list_head list;	/* scheduling list */
  250.54 +	atomic_t refcnt;
  250.55 +
  250.56 +	long int tpm_instance;
  250.57 +	unsigned long mmap_vstart;
  250.58 +
  250.59 +	struct work_struct work;
  250.60 +
  250.61 +	u16 shmem_handle;
  250.62 +	unsigned long shmem_vaddr;
  250.63 +	grant_ref_t shmem_ref;
  250.64 +
  250.65 +} tpmif_t;
  250.66 +
  250.67 +void tpmif_disconnect_complete(tpmif_t * tpmif);
  250.68 +tpmif_t *tpmif_find(domid_t domid, long int instance);
  250.69 +void tpmif_interface_init(void);
  250.70 +void tpmif_schedule_work(tpmif_t * tpmif);
  250.71 +void tpmif_deschedule_work(tpmif_t * tpmif);
  250.72 +void tpmif_xenbus_init(void);
  250.73 +int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn);
  250.74 +irqreturn_t tpmif_be_int(int irq, void *dev_id, struct pt_regs *regs);
  250.75 +int tpmif_vtpm_open(tpmif_t *tpmif, domid_t domain, u32 instance);
  250.76 +int tpmif_vtpm_close(u32 instance);
  250.77 +
  250.78 +int vtpm_release_packets(tpmif_t * tpmif, int send_msgs);
  250.79 +
  250.80 +#define tpmif_get(_b) (atomic_inc(&(_b)->refcnt))
  250.81 +#define tpmif_put(_b)                             \
  250.82 +    do {                                          \
  250.83 +        if ( atomic_dec_and_test(&(_b)->refcnt) ) \
  250.84 +            tpmif_disconnect_complete(_b);        \
  250.85 +    } while (0)
  250.86 +
  250.87 +
  250.88 +extern int num_frontends;
  250.89 +
  250.90 +#define MMAP_VADDR(t,_req) ((t)->mmap_vstart + ((_req) * PAGE_SIZE))
  250.91 +
  250.92 +#endif /* __TPMIF__BACKEND__COMMON_H__ */
   251.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   251.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c	Thu Sep 01 10:16:14 2005 +0000
   251.3 @@ -0,0 +1,200 @@
   251.4 +/******************************************************************************
   251.5 + * drivers/xen/tpmback/interface.c
   251.6 + *
   251.7 + * Vritual TPM interface management.
   251.8 + *
   251.9 + * Copyright (c) 2005, IBM Corporation
  251.10 + *
  251.11 + * Author: Stefan Berger, stefanb@us.ibm.com
  251.12 + *
  251.13 + * This code has been derived from drivers/xen/netback/interface.c
  251.14 + * Copyright (c) 2004, Keir Fraser
  251.15 + */
  251.16 +
  251.17 +#include "common.h"
  251.18 +#include <asm-xen/balloon.h>
  251.19 +
  251.20 +#define VMALLOC_VMADDR(x) ((unsigned long)(x))
  251.21 +
  251.22 +#define TPMIF_HASHSZ (2 << 5)
  251.23 +#define TPMIF_HASH(_d,_h) (((int)(_d)^(int)(_h))&(TPMIF_HASHSZ-1))
  251.24 +
  251.25 +static kmem_cache_t *tpmif_cachep;
  251.26 +int num_frontends = 0;
  251.27 +LIST_HEAD(tpmif_list);
  251.28 +
  251.29 +
  251.30 +tpmif_t *alloc_tpmif(domid_t domid, long int instance)
  251.31 +{
  251.32 +    struct page *page;
  251.33 +    tpmif_t *tpmif;
  251.34 +
  251.35 +    tpmif = kmem_cache_alloc(tpmif_cachep, GFP_KERNEL);
  251.36 +    if (!tpmif)
  251.37 +        return ERR_PTR(-ENOMEM);
  251.38 +
  251.39 +    memset(tpmif, 0, sizeof(*tpmif));
  251.40 +    tpmif->domid        = domid;
  251.41 +    tpmif->status       = DISCONNECTED;
  251.42 +    tpmif->tpm_instance = instance;
  251.43 +    atomic_set(&tpmif->refcnt, 1);
  251.44 +
  251.45 +    page = balloon_alloc_empty_page_range(TPMIF_TX_RING_SIZE);
  251.46 +    BUG_ON(page == NULL);
  251.47 +    tpmif->mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
  251.48 +
  251.49 +    list_add(&tpmif->tpmif_list, &tpmif_list);
  251.50 +    num_frontends++;
  251.51 +
  251.52 +    return tpmif;
  251.53 +}
  251.54 +
  251.55 +
  251.56 +void free_tpmif(tpmif_t *tpmif)
  251.57 +{
  251.58 +    num_frontends--;
  251.59 +    list_del(&tpmif->tpmif_list);
  251.60 +    kmem_cache_free(tpmif_cachep, tpmif);
  251.61 +}
  251.62 +
  251.63 +
  251.64 +tpmif_t *tpmif_find(domid_t domid, long int instance)
  251.65 +{
  251.66 +    tpmif_t *tpmif;
  251.67 +
  251.68 +    list_for_each_entry(tpmif, &tpmif_list, tpmif_list) {
  251.69 +        if (tpmif->tpm_instance == instance) {
  251.70 +            if (tpmif->domid == domid) {
  251.71 +                tpmif_get(tpmif);
  251.72 +                return tpmif;
  251.73 +	    } else {
  251.74 +	        return NULL;
  251.75 +	    }
  251.76 +        }
  251.77 +    }
  251.78 +
  251.79 +    return alloc_tpmif(domid, instance);
  251.80 +}
  251.81 +
  251.82 +
  251.83 +static int map_frontend_page(tpmif_t *tpmif, unsigned long localaddr,
  251.84 +			     unsigned long shared_page)
  251.85 +{
  251.86 +    struct gnttab_map_grant_ref op = {
  251.87 +        .host_addr = localaddr,
  251.88 +        .flags     = GNTMAP_host_map,
  251.89 +        .ref       = shared_page,
  251.90 +        .dom       = tpmif->domid,
  251.91 +    };
  251.92 +
  251.93 +    BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
  251.94 +
  251.95 +    if (op.handle < 0) {
  251.96 +	DPRINTK(" Grant table operation failure !\n");
  251.97 +	return op.handle;
  251.98 +    }
  251.99 +
 251.100 +    tpmif->shmem_ref    = shared_page;
 251.101 +    tpmif->shmem_handle = op.handle;
 251.102 +    tpmif->shmem_vaddr  = localaddr;
 251.103 +    return 0;
 251.104 +}
 251.105 +
 251.106 +
 251.107 +static void unmap_frontend_page(tpmif_t *tpmif)
 251.108 +{
 251.109 +    struct gnttab_unmap_grant_ref op;
 251.110 +
 251.111 +    op.host_addr = tpmif->shmem_vaddr;
 251.112 +    op.handle = tpmif->shmem_handle;
 251.113 +    op.dev_bus_addr = 0;
 251.114 +
 251.115 +    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
 251.116 +}
 251.117 +
 251.118 +
 251.119 +int tpmif_map(tpmif_t *tpmif,
 251.120 +              unsigned long shared_page, unsigned int evtchn)
 251.121 +{
 251.122 +    struct vm_struct *vma;
 251.123 +    evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
 251.124 +    int err;
 251.125 +
 251.126 +    BUG_ON(tpmif->remote_evtchn);
 251.127 +
 251.128 +    if ( (vma = get_vm_area(PAGE_SIZE, VM_IOREMAP)) == NULL )
 251.129 +	return -ENOMEM;
 251.130 +
 251.131 +    err = map_frontend_page(tpmif,
 251.132 +                            VMALLOC_VMADDR(vma->addr),
 251.133 +                            shared_page);
 251.134 +    if (err) {
 251.135 +        vfree(vma->addr);
 251.136 +	return err;
 251.137 +    }
 251.138 +
 251.139 +    op.u.bind_interdomain.dom1 = DOMID_SELF;
 251.140 +    op.u.bind_interdomain.dom2 = tpmif->domid;
 251.141 +    op.u.bind_interdomain.port1 = 0;
 251.142 +    op.u.bind_interdomain.port2 = evtchn;
 251.143 +    err = HYPERVISOR_event_channel_op(&op);
 251.144 +    if (err) {
 251.145 +	unmap_frontend_page(tpmif);
 251.146 +	vfree(vma->addr);
 251.147 +	return err;
 251.148 +    }
 251.149 +
 251.150 +    tpmif->evtchn = op.u.bind_interdomain.port1;
 251.151 +    tpmif->remote_evtchn = evtchn;
 251.152 +
 251.153 +    tpmif->tx = (tpmif_tx_interface_t *) vma->addr;
 251.154 +
 251.155 +    bind_evtchn_to_irqhandler(tpmif->evtchn,
 251.156 +                              tpmif_be_int,
 251.157 +                              0,
 251.158 +                              "tpmif-backend",
 251.159 +			      tpmif);
 251.160 +    tpmif->status        = CONNECTED;
 251.161 +    tpmif->shmem_ref     = shared_page;
 251.162 +    tpmif->active        = 1;
 251.163 +
 251.164 +    return 0;
 251.165 +}
 251.166 +
 251.167 +
 251.168 +static void __tpmif_disconnect_complete(void *arg)
 251.169 +{
 251.170 +    evtchn_op_t op = { .cmd = EVTCHNOP_close };
 251.171 +    tpmif_t *tpmif = (tpmif_t *) arg;
 251.172 +
 251.173 +    op.u.close.port = tpmif->evtchn;
 251.174 +    op.u.close.dom  = DOMID_SELF;
 251.175 +    HYPERVISOR_event_channel_op(&op);
 251.176 +    op.u.close.port = tpmif->remote_evtchn;
 251.177 +    op.u.close.dom  = tpmif->domid;
 251.178 +    HYPERVISOR_event_channel_op(&op);
 251.179 +
 251.180 +    if (tpmif->evtchn)
 251.181 +         unbind_evtchn_from_irqhandler(tpmif->evtchn, tpmif);
 251.182 +
 251.183 +    if (tpmif->tx) {
 251.184 +        unmap_frontend_page(tpmif);
 251.185 +        vfree(tpmif->tx);
 251.186 +    }
 251.187 +
 251.188 +    free_tpmif(tpmif);
 251.189 +}
 251.190 +
 251.191 +
 251.192 +void tpmif_disconnect_complete(tpmif_t * tpmif)
 251.193 +{
 251.194 +    INIT_WORK(&tpmif->work, __tpmif_disconnect_complete, (void *)tpmif);
 251.195 +    schedule_work(&tpmif->work);
 251.196 +}
 251.197 +
 251.198 +
 251.199 +void __init tpmif_interface_init(void)
 251.200 +{
 251.201 +    tpmif_cachep = kmem_cache_create("tpmif_cache", sizeof(tpmif_t),
 251.202 +                                     0, 0, NULL, NULL);
 251.203 +}
   252.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   252.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c	Thu Sep 01 10:16:14 2005 +0000
   252.3 @@ -0,0 +1,1078 @@
   252.4 +/******************************************************************************
   252.5 + * drivers/xen/tpmback/tpmback.c
   252.6 + *
   252.7 + * Copyright (c) 2005, IBM Corporation
   252.8 + *
   252.9 + * Author: Stefan Berger, stefanb@us.ibm.com
  252.10 + * Grant table support: Mahadevan Gomathisankaran
  252.11 + *
  252.12 + * This code has been derived from drivers/xen/netback/netback.c
  252.13 + * Copyright (c) 2002-2004, K A Fraser
  252.14 + *
  252.15 + */
  252.16 +
  252.17 +#include "common.h"
  252.18 +#include <asm-xen/evtchn.h>
  252.19 +
  252.20 +#include <linux/types.h>
  252.21 +#include <linux/list.h>
  252.22 +#include <linux/miscdevice.h>
  252.23 +#include <asm/uaccess.h>
  252.24 +#include <asm-xen/xenbus.h>
  252.25 +#include <asm-xen/xen-public/grant_table.h>
  252.26 +
  252.27 +
  252.28 +struct data_exchange {
  252.29 +	struct list_head pending_pak;
  252.30 +	struct list_head current_pak;
  252.31 +	unsigned int copied_so_far;
  252.32 +	u8 has_opener;
  252.33 +	rwlock_t pak_lock;  // protects all of the previous fields
  252.34 +	wait_queue_head_t wait_queue;
  252.35 +};
  252.36 +
  252.37 +struct packet {
  252.38 +	struct list_head next;
  252.39 +	unsigned int data_len;
  252.40 +	u8 *data_buffer;
  252.41 +	tpmif_t *tpmif;
  252.42 +	u32 tpm_instance;
  252.43 +	u8 req_tag;
  252.44 +	u32 last_read;
  252.45 +	u8 flags;
  252.46 +	ctrl_msg_t ctrl_msg;
  252.47 +	struct timer_list processing_timer;
  252.48 +};
  252.49 +
  252.50 +enum {
  252.51 +	PACKET_FLAG_DISCARD_RESPONSE = 1,
  252.52 +	PACKET_FLAG_SEND_CONTROLMESSAGE = 2,
  252.53 +};
  252.54 +
  252.55 +static struct data_exchange dataex;
  252.56 +
  252.57 +/* local function prototypes */
  252.58 +static int vtpm_queue_packet(struct packet *pak);
  252.59 +static int _packet_write(struct packet *pak,
  252.60 +                         const char *data, size_t size,
  252.61 +                         int userbuffer);
  252.62 +static void processing_timeout(unsigned long ptr);
  252.63 +static int  packet_read_shmem(struct packet *pak,
  252.64 +                              tpmif_t *tpmif,
  252.65 +                              u32 offset,
  252.66 +                              char *buffer,
  252.67 +                              int isuserbuffer,
  252.68 +                              u32 left);
  252.69 +
  252.70 +
  252.71 +#define MAX_PENDING_REQS TPMIF_TX_RING_SIZE
  252.72 +
  252.73 +static multicall_entry_t tx_mcl[MAX_PENDING_REQS];
  252.74 +
  252.75 +#define MIN(x,y)  (x) < (y) ? (x) : (y)
  252.76 +
  252.77 +/***************************************************************
  252.78 + Packet-related functions
  252.79 +***************************************************************/
  252.80 +
  252.81 +static struct packet *
  252.82 +packet_find_instance(struct list_head *head, u32 tpm_instance)
  252.83 +{
  252.84 +	struct packet *pak;
  252.85 +	struct list_head *p;
  252.86 +	/*
  252.87 +	 * traverse the list of packets and return the first
  252.88 +	 * one with the given instance number
  252.89 +	 */
  252.90 +	list_for_each(p, head) {
  252.91 +		pak = list_entry(p, struct packet, next);
  252.92 +		if (pak->tpm_instance == tpm_instance) {
  252.93 +			return pak;
  252.94 +		}
  252.95 +	}
  252.96 +	return NULL;
  252.97 +}
  252.98 +
  252.99 +static struct packet *
 252.100 +packet_find_packet(struct list_head *head, void *packet)
 252.101 +{
 252.102 +	struct packet *pak;
 252.103 +	struct list_head *p;
 252.104 +	/*
 252.105 +	 * traverse the list of packets and return the first
 252.106 +	 * one with the given instance number
 252.107 +	 */
 252.108 +	list_for_each(p, head) {
 252.109 +		pak = list_entry(p, struct packet, next);
 252.110 +		if (pak == packet) {
 252.111 +			return pak;
 252.112 +		}
 252.113 +	}
 252.114 +	return NULL;
 252.115 +}
 252.116 +
 252.117 +static struct packet *
 252.118 +packet_alloc(tpmif_t *tpmif, u32 size, u8 req_tag, u8 flags)
 252.119 +{
 252.120 +	struct packet *pak = NULL;
 252.121 +	pak = kmalloc(sizeof(struct packet),
 252.122 +                      GFP_KERNEL);
 252.123 +	if (NULL != pak) {
 252.124 +		memset(pak, 0x0, sizeof(*pak));
 252.125 +		if (tpmif) {
 252.126 +			pak->tpmif = tpmif;
 252.127 +			pak->tpm_instance = tpmif->tpm_instance;
 252.128 +		}
 252.129 +		pak->data_len  = size;
 252.130 +		pak->req_tag   = req_tag;
 252.131 +		pak->last_read = 0;
 252.132 +		pak->flags     = flags;
 252.133 +
 252.134 +		/*
 252.135 +		 * cannot do tpmif_get(tpmif); bad things happen
 252.136 +		 * on the last tpmif_put()
 252.137 +		 */
 252.138 +		init_timer(&pak->processing_timer);
 252.139 +		pak->processing_timer.function = processing_timeout;
 252.140 +		pak->processing_timer.data = (unsigned long)pak;
 252.141 +	}
 252.142 +	return pak;
 252.143 +}
 252.144 +
 252.145 +static void inline
 252.146 +packet_reset(struct packet *pak)
 252.147 +{
 252.148 +	pak->last_read = 0;
 252.149 +}
 252.150 +
 252.151 +static void inline
 252.152 +packet_free(struct packet *pak)
 252.153 +{
 252.154 +	del_singleshot_timer_sync(&pak->processing_timer);
 252.155 +	if (pak->data_buffer) {
 252.156 +		kfree(pak->data_buffer);
 252.157 +	}
 252.158 +	/*
 252.159 +	 * cannot do tpmif_put(pak->tpmif); bad things happen
 252.160 +	 * on the last tpmif_put()
 252.161 +	 */
 252.162 +	kfree(pak);
 252.163 +}
 252.164 +
 252.165 +static int
 252.166 +packet_set(struct packet *pak,
 252.167 +           const unsigned char *buffer, u32 size)
 252.168 +{
 252.169 +	int rc = 0;
 252.170 +	unsigned char *buf = kmalloc(size, GFP_KERNEL);
 252.171 +	if (NULL != buf) {
 252.172 +		pak->data_buffer = buf;
 252.173 +		memcpy(buf, buffer, size);
 252.174 +		pak->data_len = size;
 252.175 +	} else {
 252.176 +		rc = -ENOMEM;
 252.177 +	}
 252.178 +	return rc;
 252.179 +}
 252.180 +
 252.181 +
 252.182 +/*
 252.183 + * Write data to the shared memory and send it to the FE.
 252.184 + */
 252.185 +static int
 252.186 +packet_write(struct packet *pak,
 252.187 +             const char *data, size_t size,
 252.188 +             int userbuffer)
 252.189 +{
 252.190 +	int rc = 0;
 252.191 +
 252.192 +	DPRINTK("Supposed to send %d bytes to front-end!\n",
 252.193 +	        size);
 252.194 +
 252.195 +	if (0 != (pak->flags & PACKET_FLAG_SEND_CONTROLMESSAGE)) {
 252.196 +#ifdef CONFIG_XEN_TPMDEV_CLOSE_IF_VTPM_FAILS
 252.197 +		u32 res;
 252.198 +		memcpy(&res, &data[2+4], sizeof(res));
 252.199 +		if (res != 0) {
 252.200 +			/*
 252.201 +			 * Will close down this device and have the
 252.202 +			 * FE notified about closure.
 252.203 +			 */
 252.204 +		}
 252.205 +#endif
 252.206 +	}
 252.207 +
 252.208 +	if (0 != (pak->flags & PACKET_FLAG_DISCARD_RESPONSE)) {
 252.209 +		/* Don't send a respone to this packet. Just acknowledge it. */
 252.210 +		rc = size;
 252.211 +	} else {
 252.212 +		rc = _packet_write(pak, data, size, userbuffer);
 252.213 +	}
 252.214 +
 252.215 +	return rc;
 252.216 +}
 252.217 +
 252.218 +
 252.219 +static int
 252.220 +_packet_write(struct packet *pak,
 252.221 +              const char *data, size_t size,
 252.222 +              int userbuffer)
 252.223 +{
 252.224 +	/*
 252.225 +	 * Write into the shared memory pages directly
 252.226 +	 * and send it to the front end.
 252.227 +	 */
 252.228 +	tpmif_t *tpmif = pak->tpmif;
 252.229 +	u16 handle;
 252.230 +	int rc = 0;
 252.231 +	unsigned int i = 0;
 252.232 +	unsigned int offset = 0;
 252.233 +	multicall_entry_t *mcl;
 252.234 +
 252.235 +	if (tpmif == NULL)
 252.236 +		return -EFAULT;
 252.237 +
 252.238 +	if (tpmif->status != CONNECTED) {
 252.239 +		return size;
 252.240 +	}
 252.241 +
 252.242 +	mcl = tx_mcl;
 252.243 +	while (offset < size && i < TPMIF_TX_RING_SIZE) {
 252.244 +		unsigned int tocopy;
 252.245 +		struct gnttab_map_grant_ref map_op;
 252.246 +		struct gnttab_unmap_grant_ref unmap_op;
 252.247 +		tpmif_tx_request_t *tx;
 252.248 +
 252.249 +		tx = &tpmif->tx->ring[i].req;
 252.250 +
 252.251 +		if (0 == tx->addr) {
 252.252 +			DPRINTK("ERROR: Buffer for outgoing packet NULL?! i=%d\n", i);
 252.253 +			return 0;
 252.254 +		}
 252.255 +
 252.256 +		map_op.host_addr  = MMAP_VADDR(tpmif, i);
 252.257 +		map_op.flags      = GNTMAP_host_map;
 252.258 +		map_op.ref        = tx->ref;
 252.259 +		map_op.dom        = tpmif->domid;
 252.260 +
 252.261 +		if(unlikely(
 252.262 +		    HYPERVISOR_grant_table_op(
 252.263 +		        GNTTABOP_map_grant_ref,
 252.264 +		        &map_op,
 252.265 +		        1))) {
 252.266 +			BUG();
 252.267 +		}
 252.268 +
 252.269 +		handle = map_op.handle;
 252.270 +
 252.271 +		if (map_op.handle < 0) {
 252.272 +			DPRINTK(" Grant table operation failure !\n");
 252.273 +			return 0;
 252.274 +		}
 252.275 +		phys_to_machine_mapping[__pa(MMAP_VADDR(tpmif,i)) >>
 252.276 +					PAGE_SHIFT] =
 252.277 +			FOREIGN_FRAME(map_op.dev_bus_addr >> PAGE_SHIFT);
 252.278 +
 252.279 +		tocopy = size - offset;
 252.280 +		if (tocopy > PAGE_SIZE) {
 252.281 +			tocopy = PAGE_SIZE;
 252.282 +		}
 252.283 +		if (userbuffer) {
 252.284 +			if (copy_from_user((void *)(MMAP_VADDR(tpmif,i) |
 252.285 +			                           (tx->addr & ~PAGE_MASK)),
 252.286 +			                   (void __user *)&data[offset],
 252.287 +			                   tocopy)) {
 252.288 +				tpmif_put(tpmif);
 252.289 +				return -EFAULT;
 252.290 +			}
 252.291 +		} else {
 252.292 +			memcpy((void *)(MMAP_VADDR(tpmif,i) |
 252.293 +					(tx->addr & ~PAGE_MASK)),
 252.294 +			       &data[offset], tocopy);
 252.295 +		}
 252.296 +		tx->size = tocopy;
 252.297 +
 252.298 +		unmap_op.host_addr    = MMAP_VADDR(tpmif, i);
 252.299 +		unmap_op.handle       = handle;
 252.300 +		unmap_op.dev_bus_addr = 0;
 252.301 +
 252.302 +		if(unlikely(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref,
 252.303 +		                                      &unmap_op,
 252.304 +		                                      1))) {
 252.305 +			BUG();
 252.306 +		}
 252.307 +
 252.308 +		offset += tocopy;
 252.309 +		i++;
 252.310 +	}
 252.311 +
 252.312 +	rc = offset;
 252.313 +	DPRINTK("Notifying frontend via event channel %d\n",
 252.314 +	        tpmif->evtchn);
 252.315 +	notify_via_evtchn(tpmif->evtchn);
 252.316 +
 252.317 +	return rc;
 252.318 +}
 252.319 +
 252.320 +/*
 252.321 + * Read data from the shared memory and copy it directly into the
 252.322 + * provided buffer. Advance the read_last indicator which tells
 252.323 + * how many bytes have already been read.
 252.324 + */
 252.325 +static int
 252.326 +packet_read(struct packet *pak, size_t numbytes,
 252.327 +            char *buffer, size_t buffersize,
 252.328 +            int userbuffer)
 252.329 +{
 252.330 +	tpmif_t *tpmif = pak->tpmif;
 252.331 +	/*
 252.332 +	 * I am supposed to read 'numbytes' of data from the
 252.333 +	 * buffer.
 252.334 +	 * The first 4 bytes that are read are the instance number in
 252.335 +	 * network byte order, after that comes the data from the
 252.336 +	 * shared memory buffer.
 252.337 +	 */
 252.338 +	u32 to_copy;
 252.339 +	u32 offset = 0;
 252.340 +	u32 room_left = buffersize;
 252.341 +	/*
 252.342 +	 * Ensure that we see the request when we copy it.
 252.343 +	 */
 252.344 +	mb();
 252.345 +
 252.346 +	if (pak->last_read < 4) {
 252.347 +		/*
 252.348 +		 * copy the instance number into the buffer
 252.349 +		 */
 252.350 +		u32 instance_no = htonl(pak->tpm_instance);
 252.351 +		u32 last_read = pak->last_read;
 252.352 +		to_copy = MIN(4 - last_read, numbytes);
 252.353 +
 252.354 +		if (userbuffer) {
 252.355 +			if (copy_to_user(&buffer[0],
 252.356 +			                 &(((u8 *)&instance_no)[last_read]),
 252.357 +			                 to_copy)) {
 252.358 +				return -EFAULT;
 252.359 +			}
 252.360 +		} else {
 252.361 +			memcpy(&buffer[0],
 252.362 +			       &(((u8 *)&instance_no)[last_read]),
 252.363 +			       to_copy);
 252.364 +		}
 252.365 +
 252.366 +		pak->last_read += to_copy;
 252.367 +		offset += to_copy;
 252.368 +		room_left -= to_copy;
 252.369 +	}
 252.370 +
 252.371 +	/*
 252.372 +	 * If the packet has a data buffer appended, read from it...
 252.373 +	 */
 252.374 +
 252.375 +	if (room_left > 0) {
 252.376 +		if (pak->data_buffer) {
 252.377 +			u32 to_copy = MIN(pak->data_len - offset, room_left);
 252.378 +			u32 last_read = pak->last_read - 4;
 252.379 +			if (userbuffer) {
 252.380 +				if (copy_to_user(&buffer[offset],
 252.381 +				                 &pak->data_buffer[last_read],
 252.382 +				                 to_copy)) {
 252.383 +					return -EFAULT;
 252.384 +				}
 252.385 +			} else {
 252.386 +				memcpy(&buffer[offset],
 252.387 +				       &pak->data_buffer[last_read],
 252.388 +				       to_copy);
 252.389 +			}
 252.390 +			pak->last_read += to_copy;
 252.391 +			offset += to_copy;
 252.392 +		} else {
 252.393 +			offset = packet_read_shmem(pak,
 252.394 +			                           tpmif,
 252.395 +			                           offset,
 252.396 +			                           buffer,
 252.397 +			                           userbuffer,
 252.398 +			                           room_left);
 252.399 +		}
 252.400 +	}
 252.401 +	return offset;
 252.402 +}
 252.403 +
 252.404 +
 252.405 +static int
 252.406 +packet_read_shmem(struct packet *pak,
 252.407 +                  tpmif_t *tpmif,
 252.408 +                  u32 offset,
 252.409 +                  char *buffer,
 252.410 +                  int isuserbuffer,
 252.411 +                  u32 room_left) {
 252.412 +	u32 last_read = pak->last_read - 4;
 252.413 +	u32 i = (last_read / PAGE_SIZE);
 252.414 +	u32 pg_offset = last_read & (PAGE_SIZE - 1);
 252.415 +	u32 to_copy;
 252.416 +	u16 handle;
 252.417 +
 252.418 +	tpmif_tx_request_t *tx;
 252.419 +	tx = &tpmif->tx->ring[0].req;
 252.420 +	/*
 252.421 +	 * Start copying data at the page with index 'index'
 252.422 +	 * and within that page at offset 'offset'.
 252.423 +	 * Copy a maximum of 'room_left' bytes.
 252.424 +	 */
 252.425 +	to_copy = MIN(PAGE_SIZE - pg_offset, room_left);
 252.426 +	while (to_copy > 0) {
 252.427 +		void *src;
 252.428 +		struct gnttab_map_grant_ref map_op;
 252.429 +		struct gnttab_unmap_grant_ref unmap_op;
 252.430 +
 252.431 +		tx = &tpmif->tx->ring[i].req;
 252.432 +
 252.433 +		map_op.host_addr = MMAP_VADDR(tpmif, i);
 252.434 +		map_op.flags     = GNTMAP_host_map;
 252.435 +		map_op.ref       = tx->ref;
 252.436 +		map_op.dom       = tpmif->domid;
 252.437 +
 252.438 +		if(unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
 252.439 +		                                      &map_op,
 252.440 +		                                      1))) {
 252.441 +			BUG();
 252.442 +		}
 252.443 +
 252.444 +		if (map_op.handle < 0) {
 252.445 +			DPRINTK(" Grant table operation failure !\n");
 252.446 +			return -EFAULT;
 252.447 +		}
 252.448 +
 252.449 +		handle = map_op.handle;
 252.450 +
 252.451 +		if (to_copy > tx->size) {
 252.452 +			/*
 252.453 +			 * This is the case when the user wants to read more
 252.454 +			 * than what we have. So we just give him what we
 252.455 +			 * have.
 252.456 +			 */
 252.457 +			to_copy = MIN(tx->size, to_copy);
 252.458 +		}
 252.459 +
 252.460 +		DPRINTK("Copying from mapped memory at %08lx\n",
 252.461 +		        (unsigned long)(MMAP_VADDR(tpmif,i) |
 252.462 +			(tx->addr & ~PAGE_MASK)));
 252.463 +
 252.464 +		src = (void *)(MMAP_VADDR(tpmif,i) | ((tx->addr & ~PAGE_MASK) + pg_offset));
 252.465 +		if (isuserbuffer) {
 252.466 +			if (copy_to_user(&buffer[offset],
 252.467 +			                 src,
 252.468 +			                 to_copy)) {
 252.469 +				return -EFAULT;
 252.470 +			}
 252.471 +		} else {
 252.472 +			memcpy(&buffer[offset],
 252.473 +			       src,
 252.474 +			       to_copy);
 252.475 +		}
 252.476 +
 252.477 +
 252.478 +		DPRINTK("Data from TPM-FE of domain %d are %d %d %d %d\n",
 252.479 +		        tpmif->domid, buffer[offset], buffer[offset+1],buffer[offset+2],buffer[offset+3]);
 252.480 +
 252.481 +		unmap_op.host_addr    = MMAP_VADDR(tpmif, i);
 252.482 +		unmap_op.handle       = handle;
 252.483 +		unmap_op.dev_bus_addr = 0;
 252.484 +
 252.485 +		if(unlikely(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref,
 252.486 +		                                      &unmap_op,
 252.487 +		                                      1))) {
 252.488 +			BUG();
 252.489 +		}
 252.490 +
 252.491 +		offset += to_copy;
 252.492 +		pg_offset = 0;
 252.493 +		last_read += to_copy;
 252.494 +		room_left -= to_copy;
 252.495 +
 252.496 +		to_copy = MIN(PAGE_SIZE, room_left);
 252.497 +		i++;
 252.498 +	} /* while (to_copy > 0) */
 252.499 +	/*
 252.500 +	 * Adjust the last_read pointer
 252.501 +	 */
 252.502 +	pak->last_read = last_read + 4;
 252.503 +	return offset;
 252.504 +}
 252.505 +
 252.506 +
 252.507 +/* ============================================================
 252.508 + * The file layer for reading data from this device
 252.509 + * ============================================================
 252.510 + */
 252.511 +static int
 252.512 +vtpm_op_open(struct inode *inode, struct file *f)
 252.513 +{
 252.514 +	int rc = 0;
 252.515 +	unsigned long flags;
 252.516 +
 252.517 +	write_lock_irqsave(&dataex.pak_lock, flags);
 252.518 +	if (dataex.has_opener == 0) {
 252.519 +		dataex.has_opener = 1;
 252.520 +	} else {
 252.521 +		rc = -EPERM;
 252.522 +	}
 252.523 +	write_unlock_irqrestore(&dataex.pak_lock, flags);
 252.524 +	return rc;
 252.525 +}
 252.526 +
 252.527 +static ssize_t
 252.528 +vtpm_op_read(struct file *file,
 252.529 +	     char __user * data, size_t size, loff_t * offset)
 252.530 +{
 252.531 +	int ret_size = -ENODATA;
 252.532 +	struct packet *pak = NULL;
 252.533 +	unsigned long flags;
 252.534 +
 252.535 +	write_lock_irqsave(&dataex.pak_lock, flags);
 252.536 +
 252.537 +	if (list_empty(&dataex.pending_pak)) {
 252.538 +		write_unlock_irqrestore(&dataex.pak_lock, flags);
 252.539 +		wait_event_interruptible(dataex.wait_queue,
 252.540 +		                         !list_empty(&dataex.pending_pak));
 252.541 +		write_lock_irqsave(&dataex.pak_lock, flags);
 252.542 +	}
 252.543 +
 252.544 +	if (!list_empty(&dataex.pending_pak)) {
 252.545 +		unsigned int left;
 252.546 +		pak = list_entry(dataex.pending_pak.next, struct packet, next);
 252.547 +
 252.548 +		left = pak->data_len - dataex.copied_so_far;
 252.549 +
 252.550 +		DPRINTK("size given by app: %d, available: %d\n", size, left);
 252.551 +
 252.552 +		ret_size = MIN(size,left);
 252.553 +
 252.554 +		ret_size = packet_read(pak, ret_size, data, size, 1);
 252.555 +		if (ret_size < 0) {
 252.556 +			ret_size = -EFAULT;
 252.557 +		} else {
 252.558 +			DPRINTK("Copied %d bytes to user buffer\n", ret_size);
 252.559 +
 252.560 +			dataex.copied_so_far += ret_size;
 252.561 +			if (dataex.copied_so_far >= pak->data_len + 4) {
 252.562 +				DPRINTK("All data from this packet given to app.\n");
 252.563 +				/* All data given to app */
 252.564 +
 252.565 +				del_singleshot_timer_sync(&pak->processing_timer);
 252.566 +				list_del(&pak->next);
 252.567 +				list_add_tail(&pak->next, &dataex.current_pak);
 252.568 +				/*
 252.569 +				 * The more fontends that are handled at the same time,
 252.570 +				 * the more time we give the TPM to process the request.
 252.571 +				 */
 252.572 +				mod_timer(&pak->processing_timer,
 252.573 +				          jiffies + (num_frontends * 10 * HZ));
 252.574 +				dataex.copied_so_far = 0;
 252.575 +			}
 252.576 +		}
 252.577 +	}
 252.578 +	write_unlock_irqrestore(&dataex.pak_lock, flags);
 252.579 +
 252.580 +	DPRINTK("Returning result from read to app: %d\n", ret_size);
 252.581 +
 252.582 +	return ret_size;
 252.583 +}
 252.584 +
 252.585 +/*
 252.586 + * Write operation - only works after a previous read operation!
 252.587 + */
 252.588 +static ssize_t
 252.589 +vtpm_op_write(struct file *file, const char __user * data, size_t size,
 252.590 +	      loff_t * offset)
 252.591 +{
 252.592 +	struct packet *pak;
 252.593 +	int rc = 0;
 252.594 +	unsigned int off = 4;
 252.595 +	unsigned long flags;
 252.596 +	u32 instance_no = 0;
 252.597 +	u32 len_no = 0;
 252.598 +
 252.599 +	/*
 252.600 +	 * Minimum required packet size is:
 252.601 +	 * 4 bytes for instance number
 252.602 +	 * 2 bytes for tag
 252.603 +	 * 4 bytes for paramSize
 252.604 +	 * 4 bytes for the ordinal
 252.605 +	 * sum: 14 bytes
 252.606 +	 */
 252.607 +	if ( size < off + 10 ) {
 252.608 +		return -EFAULT;
 252.609 +	}
 252.610 +
 252.611 +	if (copy_from_user(&instance_no,
 252.612 +	                   (void __user *)&data[0],
 252.613 +	                   4)) {
 252.614 +		return -EFAULT;
 252.615 +	}
 252.616 +
 252.617 +	if (copy_from_user(&len_no,
 252.618 +	                   (void __user *)&data[off+2],
 252.619 +	                   4) ||
 252.620 +	    (off + ntohl(len_no) != size)) {
 252.621 +		return -EFAULT;
 252.622 +	}
 252.623 +
 252.624 +	write_lock_irqsave(&dataex.pak_lock, flags);
 252.625 +	pak = packet_find_instance(&dataex.current_pak, ntohl(instance_no));
 252.626 +
 252.627 +	if (pak == NULL) {
 252.628 +		write_unlock_irqrestore(&dataex.pak_lock, flags);
 252.629 +		printk(KERN_ALERT "No associated packet!\n");
 252.630 +		return -EFAULT;
 252.631 +	} else {
 252.632 +		del_singleshot_timer_sync(&pak->processing_timer);
 252.633 +		list_del(&pak->next);
 252.634 +	}
 252.635 +
 252.636 +	write_unlock_irqrestore(&dataex.pak_lock, flags);
 252.637 +
 252.638 +	/*
 252.639 +	 * The first 'offset' bytes must be the instance number.
 252.640 +	 * I will just pull that from the packet.
 252.641 +	 */
 252.642 +	size -= off;
 252.643 +	data = &data[off];
 252.644 +
 252.645 +	rc = packet_write(pak, data, size, 1);
 252.646 +
 252.647 +	if (rc > 0) {
 252.648 +		/* I neglected the first 4 bytes */
 252.649 +		rc += off;
 252.650 +	}
 252.651 +	packet_free(pak);
 252.652 +	return rc;
 252.653 +}
 252.654 +
 252.655 +static int
 252.656 +vtpm_op_release(struct inode *inode, struct file *file)
 252.657 +{
 252.658 +	unsigned long flags;
 252.659 +	vtpm_release_packets(NULL, 1);
 252.660 +	write_lock_irqsave(&dataex.pak_lock, flags);
 252.661 +	dataex.has_opener = 0;
 252.662 +	write_unlock_irqrestore(&dataex.pak_lock, flags);
 252.663 +	return 0;
 252.664 +}
 252.665 +
 252.666 +static unsigned int
 252.667 +vtpm_op_poll(struct file *file, struct poll_table_struct *pst)
 252.668 +{
 252.669 +	return 0;
 252.670 +}
 252.671 +
 252.672 +static struct file_operations vtpm_ops = {
 252.673 +	.owner = THIS_MODULE,
 252.674 +	.llseek = no_llseek,
 252.675 +	.open = vtpm_op_open,
 252.676 +	.read = vtpm_op_read,
 252.677 +	.write = vtpm_op_write,
 252.678 +	.release = vtpm_op_release,
 252.679 +	.poll = vtpm_op_poll,
 252.680 +};
 252.681 +
 252.682 +static struct miscdevice ibmvtpms_miscdevice = {
 252.683 +	.minor = 225,
 252.684 +	.name = "vtpm",
 252.685 +	.fops = &vtpm_ops,
 252.686 +};
 252.687 +
 252.688 +
 252.689 +/***************************************************************
 252.690 + Virtual TPM functions and data stuctures
 252.691 +***************************************************************/
 252.692 +
 252.693 +static u8 create_cmd[] = {
 252.694 +        1,193,		/* 0: TPM_TAG_RQU_COMMAMD */
 252.695 +        0,0,0,19,	/* 2: length */
 252.696 +        0,0,0,0x1,	/* 6: VTPM_ORD_OPEN */
 252.697 +        0,		/* 10: VTPM type */
 252.698 +        0,0,0,0,	/* 11: domain id */
 252.699 +        0,0,0,0		/* 15: instance id */
 252.700 +};
 252.701 +
 252.702 +static u8 destroy_cmd[] = {
 252.703 +        1,193,		/* 0: TPM_TAG_RQU_COMMAMD */
 252.704 +        0,0,0,14,	/* 2: length */
 252.705 +        0,0,0,0x2,	/* 6: VTPM_ORD_CLOSE */
 252.706 +        0,0,0,0		/* 10: instance id */
 252.707 +};
 252.708 +
 252.709 +int tpmif_vtpm_open(tpmif_t *tpmif, domid_t domid, u32 instance)
 252.710 +{
 252.711 +	int rc = 0;
 252.712 +	struct packet *pak = packet_alloc(tpmif, sizeof(create_cmd), create_cmd[0],
 252.713 +	    PACKET_FLAG_DISCARD_RESPONSE|
 252.714 +	    PACKET_FLAG_SEND_CONTROLMESSAGE);
 252.715 +	if (pak) {
 252.716 +		u8 buf[sizeof(create_cmd)];
 252.717 +		u32 domid_no = htonl((u32)domid);
 252.718 +		u32 instance_no = htonl(instance);
 252.719 +		memcpy(buf, create_cmd, sizeof(create_cmd));
 252.720 +
 252.721 +		memcpy(&buf[11], &domid_no, sizeof(u32));
 252.722 +		memcpy(&buf[15], &instance_no, sizeof(u32));
 252.723 +
 252.724 +		/* copy the buffer into the packet */
 252.725 +		rc = packet_set(pak, buf, sizeof(buf));
 252.726 +
 252.727 +		if (rc == 0) {
 252.728 +			pak->tpm_instance = 0;
 252.729 +			rc = vtpm_queue_packet(pak);
 252.730 +		}
 252.731 +		if (rc < 0) {
 252.732 +			/* could not be queued or built */
 252.733 +			packet_free(pak);
 252.734 +		}
 252.735 +	} else {
 252.736 +		rc = -ENOMEM;
 252.737 +	}
 252.738 +	return rc;
 252.739 +}
 252.740 +
 252.741 +int tpmif_vtpm_close(u32 instid)
 252.742 +{
 252.743 +	int rc = 0;
 252.744 +	struct packet *pak;
 252.745 +
 252.746 +	pak = packet_alloc(NULL,
 252.747 +	                   sizeof(create_cmd),
 252.748 +	                   create_cmd[0],
 252.749 +	                   PACKET_FLAG_DISCARD_RESPONSE|
 252.750 +	                   PACKET_FLAG_SEND_CONTROLMESSAGE);
 252.751 +	if (pak) {
 252.752 +		u8 buf[sizeof(destroy_cmd)];
 252.753 +		u32 instid_no = htonl(instid);
 252.754 +		memcpy(buf, destroy_cmd, sizeof(destroy_cmd));
 252.755 +		memcpy(&buf[10], &instid_no, sizeof(u32));
 252.756 +
 252.757 +		/* copy the buffer into the packet */
 252.758 +		rc = packet_set(pak, buf, sizeof(buf));
 252.759 +
 252.760 +		if (rc == 0) {
 252.761 +			pak->tpm_instance = 0;
 252.762 +			rc = vtpm_queue_packet(pak);
 252.763 +		}
 252.764 +		if (rc < 0) {
 252.765 +			/* could not be queued or built */
 252.766 +			packet_free(pak);
 252.767 +		}
 252.768 +	} else {
 252.769 +		rc = -ENOMEM;
 252.770 +	}
 252.771 +	return rc;
 252.772 +}
 252.773 +
 252.774 +
 252.775 +/***************************************************************
 252.776 + Utility functions
 252.777 +***************************************************************/
 252.778 +
 252.779 +static int
 252.780 +tpm_send_fail_message(struct packet *pak, u8 req_tag)
 252.781 +{
 252.782 +	int rc;
 252.783 +	static const unsigned char tpm_error_message_fail[] = {
 252.784 +		0x00, 0x00,
 252.785 +		0x00, 0x00, 0x00, 0x0a,
 252.786 +		0x00, 0x00, 0x00, 0x09 /* TPM_FAIL */
 252.787 +	};
 252.788 +	unsigned char buffer[sizeof(tpm_error_message_fail)];
 252.789 +
 252.790 +	memcpy(buffer, tpm_error_message_fail, sizeof(tpm_error_message_fail));
 252.791 +	/*
 252.792 +	 * Insert the right response tag depending on the given tag
 252.793 +	 * All response tags are '+3' to the request tag.
 252.794 +	 */
 252.795 +	buffer[1] = req_tag + 3;
 252.796 +
 252.797 +	/*
 252.798 +	 * Write the data to shared memory and notify the front-end
 252.799 +	 */
 252.800 +	rc = packet_write(pak, buffer, sizeof(buffer), 0);
 252.801 +
 252.802 +	return rc;
 252.803 +}
 252.804 +
 252.805 +
 252.806 +static void
 252.807 +_vtpm_release_packets(struct list_head *head, tpmif_t *tpmif,
 252.808 +                      int send_msgs)
 252.809 +{
 252.810 +	struct packet *pak;
 252.811 +	struct list_head *pos, *tmp;
 252.812 +
 252.813 +	list_for_each_safe(pos, tmp, head) {
 252.814 +		pak = list_entry(pos, struct packet, next);
 252.815 +		if (tpmif == NULL || pak->tpmif == tpmif) {
 252.816 +			int can_send = 0;
 252.817 +			del_singleshot_timer_sync(&pak->processing_timer);
 252.818 +			list_del(&pak->next);
 252.819 +
 252.820 +			if (pak->tpmif && pak->tpmif->status == CONNECTED) {
 252.821 +				can_send = 1;
 252.822 +			}
 252.823 +
 252.824 +			if (send_msgs && can_send) {
 252.825 +				tpm_send_fail_message(pak, pak->req_tag);
 252.826 +			}
 252.827 +			packet_free(pak);
 252.828 +		}
 252.829 +	}
 252.830 +}
 252.831 +
 252.832 +
 252.833 +int
 252.834 +vtpm_release_packets(tpmif_t *tpmif, int send_msgs)
 252.835 +{
 252.836 +	unsigned long flags;
 252.837 +
 252.838 +	write_lock_irqsave(&dataex.pak_lock, flags);
 252.839 +
 252.840 +	_vtpm_release_packets(&dataex.pending_pak, tpmif, send_msgs);
 252.841 +	_vtpm_release_packets(&dataex.current_pak, tpmif, send_msgs);
 252.842 +
 252.843 +	write_unlock_irqrestore(&dataex.pak_lock,
 252.844 +	                        flags);
 252.845 +	return 0;
 252.846 +}
 252.847 +
 252.848 +
 252.849 +static int vtpm_queue_packet(struct packet *pak)
 252.850 +{
 252.851 +	int rc = 0;
 252.852 +	if (dataex.has_opener) {
 252.853 +		unsigned long flags;
 252.854 +		write_lock_irqsave(&dataex.pak_lock, flags);
 252.855 +		list_add_tail(&pak->next, &dataex.pending_pak);
 252.856 +		/* give the TPM some time to pick up the request */
 252.857 +		mod_timer(&pak->processing_timer, jiffies + (10 * HZ));
 252.858 +		write_unlock_irqrestore(&dataex.pak_lock,
 252.859 +		                        flags);
 252.860 +
 252.861 +		wake_up_interruptible(&dataex.wait_queue);
 252.862 +	} else {
 252.863 +		rc = -EFAULT;
 252.864 +	}
 252.865 +	return rc;
 252.866 +}
 252.867 +
 252.868 +
 252.869 +static int vtpm_receive(tpmif_t *tpmif, u32 size)
 252.870 +{
 252.871 +	int rc = 0;
 252.872 +	unsigned char buffer[10];
 252.873 +	__be32 *native_size;
 252.874 +
 252.875 +	struct packet *pak = packet_alloc(tpmif, size, buffer[4], 0);
 252.876 +	if (NULL == pak) {
 252.877 +		return -ENOMEM;
 252.878 +	}
 252.879 +	/*
 252.880 +	 * Read 10 bytes from the received buffer to test its
 252.881 +	 * content for validity.
 252.882 +	 */
 252.883 +	if (sizeof(buffer) != packet_read(pak,
 252.884 +	                                  sizeof(buffer), buffer,
 252.885 +	                                  sizeof(buffer), 0)) {
 252.886 +		goto failexit;
 252.887 +	}
 252.888 +	/*
 252.889 +	 * Reset the packet read pointer so we can read all its
 252.890 +	 * contents again.
 252.891 +	 */
 252.892 +	packet_reset(pak);
 252.893 +
 252.894 +	native_size = (__force __be32 *)(&buffer[4+2]);
 252.895 +	/*
 252.896 +	 * Verify that the size of the packet is correct
 252.897 +	 * as indicated and that there's actually someone reading packets.
 252.898 +	 * The minimum size of the packet is '10' for tag, size indicator
 252.899 +	 * and ordinal.
 252.900 +	 */
 252.901 +	if (size < 10 ||
 252.902 +	    be32_to_cpu(*native_size) != size ||
 252.903 +	    0 == dataex.has_opener) {
 252.904 +	    	rc = -EINVAL;
 252.905 +	    	goto failexit;
 252.906 +	} else {
 252.907 +		if ((rc = vtpm_queue_packet(pak)) < 0) {
 252.908 +			goto failexit;
 252.909 +		}
 252.910 +	}
 252.911 +	return 0;
 252.912 +
 252.913 +failexit:
 252.914 +	if (pak) {
 252.915 +		tpm_send_fail_message(pak, buffer[4+1]);
 252.916 +		packet_free(pak);
 252.917 +	}
 252.918 +	return rc;
 252.919 +}
 252.920 +
 252.921 +
 252.922 +/*
 252.923 + * Timeout function that gets invoked when a packet has not been processed
 252.924 + * during the timeout period.
 252.925 + * The packet must be on a list when this function is invoked. This
 252.926 + * also means that once its taken off a list, the timer must be
 252.927 + * destroyed as well.
 252.928 + */
 252.929 +static void processing_timeout(unsigned long ptr)
 252.930 +{
 252.931 +	struct packet *pak = (struct packet *)ptr;
 252.932 +	unsigned long flags;
 252.933 +	write_lock_irqsave(&dataex.pak_lock, flags);
 252.934 +	/*
 252.935 +	 * The packet needs to be searched whether it
 252.936 +	 * is still on the list.
 252.937 +	 */
 252.938 +	if (pak == packet_find_packet(&dataex.pending_pak, pak) ||
 252.939 +	    pak == packet_find_packet(&dataex.current_pak, pak) ) {
 252.940 +		list_del(&pak->next);
 252.941 +		tpm_send_fail_message(pak, pak->req_tag);
 252.942 +		packet_free(pak);
 252.943 +	}
 252.944 +
 252.945 +	write_unlock_irqrestore(&dataex.pak_lock, flags);
 252.946 +}
 252.947 +
 252.948 +
 252.949 +
 252.950 +static void tpm_tx_action(unsigned long unused);
 252.951 +static DECLARE_TASKLET(tpm_tx_tasklet, tpm_tx_action, 0);
 252.952 +
 252.953 +#define MAX_PENDING_REQS TPMIF_TX_RING_SIZE
 252.954 +
 252.955 +static struct list_head tpm_schedule_list;
 252.956 +static spinlock_t tpm_schedule_list_lock;
 252.957 +
 252.958 +static inline void
 252.959 +maybe_schedule_tx_action(void)
 252.960 +{
 252.961 +	smp_mb();
 252.962 +	tasklet_schedule(&tpm_tx_tasklet);
 252.963 +}
 252.964 +
 252.965 +static inline int
 252.966 +__on_tpm_schedule_list(tpmif_t * tpmif)
 252.967 +{
 252.968 +	return tpmif->list.next != NULL;
 252.969 +}
 252.970 +
 252.971 +static void
 252.972 +remove_from_tpm_schedule_list(tpmif_t * tpmif)
 252.973 +{
 252.974 +	spin_lock_irq(&tpm_schedule_list_lock);
 252.975 +	if (likely(__on_tpm_schedule_list(tpmif))) {
 252.976 +		list_del(&tpmif->list);
 252.977 +		tpmif->list.next = NULL;
 252.978 +		tpmif_put(tpmif);
 252.979 +	}
 252.980 +	spin_unlock_irq(&tpm_schedule_list_lock);
 252.981 +}
 252.982 +
 252.983 +static void
 252.984 +add_to_tpm_schedule_list_tail(tpmif_t * tpmif)
 252.985 +{
 252.986 +	if (__on_tpm_schedule_list(tpmif))
 252.987 +		return;
 252.988 +
 252.989 +	spin_lock_irq(&tpm_schedule_list_lock);
 252.990 +	if (!__on_tpm_schedule_list(tpmif) && tpmif->active) {
 252.991 +		list_add_tail(&tpmif->list, &tpm_schedule_list);
 252.992 +		tpmif_get(tpmif);
 252.993 +	}
 252.994 +	spin_unlock_irq(&tpm_schedule_list_lock);
 252.995 +}
 252.996 +
 252.997 +void
 252.998 +tpmif_schedule_work(tpmif_t * tpmif)
 252.999 +{
252.1000 +	add_to_tpm_schedule_list_tail(tpmif);
252.1001 +	maybe_schedule_tx_action();
252.1002 +}
252.1003 +
252.1004 +void
252.1005 +tpmif_deschedule_work(tpmif_t * tpmif)
252.1006 +{
252.1007 +	remove_from_tpm_schedule_list(tpmif);
252.1008 +}
252.1009 +
252.1010 +
252.1011 +static void
252.1012 +tpm_tx_action(unsigned long unused)
252.1013 +{
252.1014 +	struct list_head *ent;
252.1015 +	tpmif_t *tpmif;
252.1016 +	tpmif_tx_request_t *tx;
252.1017 +
252.1018 +	DPRINTK("%s: Getting data from front-end(s)!\n", __FUNCTION__);
252.1019 +
252.1020 +	while (!list_empty(&tpm_schedule_list)) {
252.1021 +		/* Get a tpmif from the list with work to do. */
252.1022 +		ent = tpm_schedule_list.next;
252.1023 +		tpmif = list_entry(ent, tpmif_t, list);
252.1024 +		tpmif_get(tpmif);
252.1025 +		remove_from_tpm_schedule_list(tpmif);
252.1026 +		/*
252.1027 +		 * Ensure that we see the request when we read from it.
252.1028 +		 */
252.1029 +		mb();
252.1030 +
252.1031 +		tx = &tpmif->tx->ring[0].req;
252.1032 +
252.1033 +		/* pass it up */
252.1034 +		vtpm_receive(tpmif, tx->size);
252.1035 +
252.1036 +		tpmif_put(tpmif);
252.1037 +	}
252.1038 +}
252.1039 +
252.1040 +irqreturn_t
252.1041 +tpmif_be_int(int irq, void *dev_id, struct pt_regs *regs)
252.1042 +{
252.1043 +	tpmif_t *tpmif = dev_id;
252.1044 +	add_to_tpm_schedule_list_tail(tpmif);
252.1045 +	maybe_schedule_tx_action();
252.1046 +	return IRQ_HANDLED;
252.1047 +}
252.1048 +
252.1049 +static int __init
252.1050 +tpmback_init(void)
252.1051 +{
252.1052 +	int rc;
252.1053 +	if (!(xen_start_info.flags & SIF_TPM_BE_DOMAIN) &&
252.1054 +	    !(xen_start_info.flags & SIF_INITDOMAIN)) {
252.1055 +	    	printk(KERN_ALERT "Neither TPM-BE Domain nor INIT domain!\n");
252.1056 +		return 0;
252.1057 +	}
252.1058 +
252.1059 +	if ((rc = misc_register(&ibmvtpms_miscdevice)) != 0) {
252.1060 +		printk(KERN_ALERT "Could not register misc device for TPM BE.\n");
252.1061 +		return rc;
252.1062 +	}
252.1063 +
252.1064 +	INIT_LIST_HEAD(&dataex.pending_pak);
252.1065 +	INIT_LIST_HEAD(&dataex.current_pak);
252.1066 +	dataex.has_opener = 0;
252.1067 +	rwlock_init(&dataex.pak_lock);
252.1068 +	init_waitqueue_head(&dataex.wait_queue);
252.1069 +
252.1070 +	spin_lock_init(&tpm_schedule_list_lock);
252.1071 +	INIT_LIST_HEAD(&tpm_schedule_list);
252.1072 +
252.1073 +	tpmif_interface_init();
252.1074 +	tpmif_xenbus_init();
252.1075 +
252.1076 +	printk(KERN_ALERT "Successfully initialized TPM backend driver.\n");
252.1077 +
252.1078 +	return 0;
252.1079 +}
252.1080 +
252.1081 +__initcall(tpmback_init);
   253.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   253.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c	Thu Sep 01 10:16:14 2005 +0000
   253.3 @@ -0,0 +1,271 @@
   253.4 +/*  Xenbus code for tpmif backend
   253.5 +    Copyright (C) 2005 Rusty Russell <rusty@rustcorp.com.au>
   253.6 +
   253.7 +    This program is free software; you can redistribute it and/or modify
   253.8 +    it under the terms of the GNU General Public License as published by
   253.9 +    the Free Software Foundation; either version 2 of the License, or
  253.10 +    (at your option) any later version.
  253.11 +
  253.12 +    This program is distributed in the hope that it will be useful,
  253.13 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
  253.14 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  253.15 +    GNU General Public License for more details.
  253.16 +
  253.17 +    You should have received a copy of the GNU General Public License
  253.18 +    along with this program; if not, write to the Free Software
  253.19 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  253.20 +*/
  253.21 +#include <stdarg.h>
  253.22 +#include <linux/module.h>
  253.23 +#include <asm-xen/xenbus.h>
  253.24 +#include "common.h"
  253.25 +
  253.26 +struct backend_info
  253.27 +{
  253.28 +	struct xenbus_device *dev;
  253.29 +
  253.30 +	/* our communications channel */
  253.31 +	tpmif_t *tpmif;
  253.32 +
  253.33 +	long int frontend_id;
  253.34 +	long int instance; // instance of TPM
  253.35 +
  253.36 +	/* watch front end for changes */
  253.37 +	struct xenbus_watch backend_watch;
  253.38 +
  253.39 +	struct xenbus_watch watch;
  253.40 +	char * frontpath;
  253.41 +};
  253.42 +
  253.43 +static int tpmback_remove(struct xenbus_device *dev)
  253.44 +{
  253.45 +	struct backend_info *be = dev->data;
  253.46 +
  253.47 +	if (be->watch.node) {
  253.48 +		unregister_xenbus_watch(&be->watch);
  253.49 +	}
  253.50 +	unregister_xenbus_watch(&be->backend_watch);
  253.51 +
  253.52 +	tpmif_vtpm_close(be->instance);
  253.53 +
  253.54 +	if (be->tpmif) {
  253.55 +		tpmif_put(be->tpmif);
  253.56 +	}
  253.57 +
  253.58 +	if (be->frontpath)
  253.59 +		kfree(be->frontpath);
  253.60 +	kfree(be);
  253.61 +	return 0;
  253.62 +}
  253.63 +
  253.64 +
  253.65 +static void frontend_changed(struct xenbus_watch *watch, const char *node)
  253.66 +{
  253.67 +	unsigned long ringref;
  253.68 +	unsigned int evtchn;
  253.69 +	unsigned long ready = 1;
  253.70 +	int err;
  253.71 +	struct backend_info *be
  253.72 +		= container_of(watch, struct backend_info, watch);
  253.73 +
  253.74 +	/* If other end is gone, delete ourself. */
  253.75 +	if (node && !xenbus_exists(be->frontpath, "")) {
  253.76 +		xenbus_rm(be->dev->nodename, "");
  253.77 +		device_unregister(&be->dev->dev);
  253.78 +		return;
  253.79 +	}
  253.80 +
  253.81 +	if (be->tpmif == NULL || be->tpmif->status == CONNECTED)
  253.82 +		return;
  253.83 +
  253.84 +	err = xenbus_gather(be->frontpath,
  253.85 +	                    "ring-ref", "%lu", &ringref,
  253.86 +			    "event-channel", "%u", &evtchn, NULL);
  253.87 +	if (err) {
  253.88 +		xenbus_dev_error(be->dev, err,
  253.89 +				 "reading %s/grant-id and event-channel",
  253.90 +				 be->frontpath);
  253.91 +		return;
  253.92 +	}
  253.93 +
  253.94 +
  253.95 +	/*
  253.96 +	 * Tell the front-end that we are ready to go -
  253.97 +	 * unless something bad happens
  253.98 +	 */
  253.99 +	err = xenbus_transaction_start(be->dev->nodename);
 253.100 +	if (err) {
 253.101 +		xenbus_dev_error(be->dev, err, "starting transaction");
 253.102 +		return;
 253.103 +	}
 253.104 +
 253.105 +	err = xenbus_printf(be->dev->nodename,
 253.106 +	                    "ready", "%lu", ready);
 253.107 +	if (err) {
 253.108 +		xenbus_dev_error(be->dev, err, "writing 'ready'");
 253.109 +		goto abort;
 253.110 +	}
 253.111 +
 253.112 +	err = tpmif_map(be->tpmif, ringref, evtchn);
 253.113 +	if (err) {
 253.114 +		xenbus_dev_error(be->dev, err,
 253.115 +				 "mapping shared-frame %lu port %u",
 253.116 +				 ringref, evtchn);
 253.117 +		goto abort;
 253.118 +	}
 253.119 +
 253.120 +	err = tpmif_vtpm_open(be->tpmif,
 253.121 +	                      be->frontend_id,
 253.122 +	                      be->instance);
 253.123 +	if (err) {
 253.124 +		xenbus_dev_error(be->dev, err,
 253.125 +		                 "queueing vtpm open packet");
 253.126 +		/*
 253.127 +		 * Should close down this device and notify FE
 253.128 +		 * about closure.
 253.129 +		 */
 253.130 +		goto abort;
 253.131 +	}
 253.132 +
 253.133 +	xenbus_transaction_end(0);
 253.134 +	xenbus_dev_ok(be->dev);
 253.135 +	return;
 253.136 +abort:
 253.137 +	xenbus_transaction_end(1);
 253.138 +}
 253.139 +
 253.140 +
 253.141 +static void backend_changed(struct xenbus_watch *watch, const char *node)
 253.142 +{
 253.143 +	int err;
 253.144 +	long int instance;
 253.145 +	struct backend_info *be
 253.146 +		= container_of(watch, struct backend_info, backend_watch);
 253.147 +	struct xenbus_device *dev = be->dev;
 253.148 +
 253.149 +	err = xenbus_scanf(dev->nodename, "instance", "%li", &instance);
 253.150 +	if (XENBUS_EXIST_ERR(err))
 253.151 +		return;
 253.152 +	if (err < 0) {
 253.153 +		xenbus_dev_error(dev, err, "reading 'instance' variable");
 253.154 +		return;
 253.155 +	}
 253.156 +
 253.157 +	if (be->instance != -1 && be->instance != instance) {
 253.158 +		printk(KERN_WARNING
 253.159 +		       "cannot change the instance\n");
 253.160 +		return;
 253.161 +	}
 253.162 +	be->instance = instance;
 253.163 +
 253.164 +	if (be->tpmif == NULL) {
 253.165 +		be->tpmif = tpmif_find(be->frontend_id,
 253.166 +		                       instance);
 253.167 +		if (IS_ERR(be->tpmif)) {
 253.168 +			err = PTR_ERR(be->tpmif);
 253.169 +			be->tpmif = NULL;
 253.170 +			xenbus_dev_error(dev, err, "creating interface");
 253.171 +			return;
 253.172 +		}
 253.173 +
 253.174 +		/* Pass in NULL node to skip exist test. */
 253.175 +		frontend_changed(&be->watch, be->frontpath);
 253.176 +	}
 253.177 +}
 253.178 +
 253.179 +
 253.180 +static int tpmback_probe(struct xenbus_device *dev,
 253.181 +			 const struct xenbus_device_id *id)
 253.182 +{
 253.183 +	struct backend_info *be;
 253.184 +	char *frontend;
 253.185 +	int err;
 253.186 +
 253.187 +	be = kmalloc(sizeof(*be), GFP_KERNEL);
 253.188 +	if (!be) {
 253.189 +		xenbus_dev_error(dev, -ENOMEM, "allocating backend structure");
 253.190 +		err = -ENOMEM;
 253.191 +	}
 253.192 +
 253.193 +	memset(be, 0, sizeof(*be));
 253.194 +
 253.195 +	frontend = NULL;
 253.196 +	err = xenbus_gather(dev->nodename,
 253.197 +			    "frontend-id", "%li", &be->frontend_id,
 253.198 +			    "frontend", NULL, &frontend,
 253.199 +			    NULL);
 253.200 +	if (XENBUS_EXIST_ERR(err))
 253.201 +		goto free_be;
 253.202 +	if (err < 0) {
 253.203 +		xenbus_dev_error(dev, err,
 253.204 +				 "reading %s/frontend or frontend-id",
 253.205 +				 dev->nodename);
 253.206 +		goto free_be;
 253.207 +	}
 253.208 +	if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) {
 253.209 +		/* If we can't get a frontend path and a frontend-id,
 253.210 +		 * then our bus-id is no longer valid and we need to
 253.211 +		 * destroy the backend device.
 253.212 +		 */
 253.213 +		err = -ENOENT;
 253.214 +		goto free_be;
 253.215 +	}
 253.216 +
 253.217 +	be->dev = dev;
 253.218 +	be->backend_watch.node     = dev->nodename;
 253.219 +	be->backend_watch.callback = backend_changed;
 253.220 +	be->instance = -1;
 253.221 +	err = register_xenbus_watch(&be->backend_watch);
 253.222 +	if (err) {
 253.223 +		be->backend_watch.node = NULL;
 253.224 +		xenbus_dev_error(dev, err, "adding backend watch on %s",
 253.225 +				 dev->nodename);
 253.226 +		goto free_be;
 253.227 +	}
 253.228 +
 253.229 +	be->frontpath = frontend;
 253.230 +	be->watch.node = be->frontpath;
 253.231 +	be->watch.callback = frontend_changed;
 253.232 +	err = register_xenbus_watch(&be->watch);
 253.233 +	if (err) {
 253.234 +		be->watch.node = NULL;
 253.235 +		xenbus_dev_error(dev, err,
 253.236 +				 "adding frontend watch on %s",
 253.237 +				 be->frontpath);
 253.238 +		goto free_be;
 253.239 +	}
 253.240 +
 253.241 +	dev->data = be;
 253.242 +
 253.243 +	backend_changed(&be->backend_watch, dev->nodename);
 253.244 +	return err;
 253.245 +
 253.246 +free_be:
 253.247 +	if (be->backend_watch.node)
 253.248 +		unregister_xenbus_watch(&be->backend_watch);
 253.249 +	if (frontend)
 253.250 +		kfree(frontend);
 253.251 +	kfree(be);
 253.252 +	return err;
 253.253 +}
 253.254 +
 253.255 +
 253.256 +static struct xenbus_device_id tpmback_ids[] = {
 253.257 +	{ "vtpm" },
 253.258 +	{ "" }
 253.259 +};
 253.260 +
 253.261 +
 253.262 +static struct xenbus_driver tpmback = {
 253.263 +	.name = "vtpm",
 253.264 +	.owner = THIS_MODULE,
 253.265 +	.ids = tpmback_ids,
 253.266 +	.probe = tpmback_probe,
 253.267 +	.remove = tpmback_remove,
 253.268 +};
 253.269 +
 253.270 +
 253.271 +void tpmif_xenbus_init(void)
 253.272 +{
 253.273 +	xenbus_register_backend(&tpmback);
 253.274 +}
   254.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   254.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/Makefile	Thu Sep 01 10:16:14 2005 +0000
   254.3 @@ -0,0 +1,2 @@
   254.4 +
   254.5 +obj-$(CONFIG_XEN_TPMDEV_FRONTEND)	+= tpmfront.o
   255.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   255.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c	Thu Sep 01 10:16:14 2005 +0000
   255.3 @@ -0,0 +1,739 @@
   255.4 +/*
   255.5 + * Copyright (c) 2005, IBM Corporation
   255.6 + *
   255.7 + * Author: Stefan Berger, stefanb@us.ibm.com
   255.8 + * Grant table support: Mahadevan Gomathisankaran
   255.9 + *
  255.10 + * This code has been derived from drivers/xen/netfront/netfront.c
  255.11 + *
  255.12 + * Copyright (c) 2002-2004, K A Fraser
  255.13 + *
  255.14 + * This file may be distributed separately from the Linux kernel, or
  255.15 + * incorporated into other software packages, subject to the following license:
  255.16 + *
  255.17 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  255.18 + * of this source file (the "Software"), to deal in the Software without
  255.19 + * restriction, including without limitation the rights to use, copy, modify,
  255.20 + * merge, publish, distribute, sublicense, and/or sell copies of the Software,
  255.21 + * and to permit persons to whom the Software is furnished to do so, subject to
  255.22 + * the following conditions:
  255.23 + *
  255.24 + * The above copyright notice and this permission notice shall be included in
  255.25 + * all copies or substantial portions of the Software.
  255.26 + *
  255.27 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  255.28 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  255.29 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  255.30 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  255.31 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  255.32 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  255.33 + * IN THE SOFTWARE.
  255.34 + */
  255.35 +
  255.36 +#include <linux/config.h>
  255.37 +#include <linux/module.h>
  255.38 +#include <linux/version.h>
  255.39 +#include <linux/kernel.h>
  255.40 +#include <linux/slab.h>
  255.41 +#include <linux/errno.h>
  255.42 +#include <linux/interrupt.h>
  255.43 +#include <linux/init.h>
  255.44 +#include <linux/tpmfe.h>
  255.45 +
  255.46 +#include <asm/semaphore.h>
  255.47 +#include <asm/io.h>
  255.48 +#include <asm-xen/evtchn.h>
  255.49 +#include <asm-xen/ctrl_if.h>
  255.50 +#include <asm-xen/xen-public/io/tpmif.h>
  255.51 +#include <asm/uaccess.h>
  255.52 +#include <asm-xen/xenbus.h>
  255.53 +#include <asm-xen/xen-public/io/domain_controller.h>
  255.54 +#include <asm-xen/xen-public/grant_table.h>
  255.55 +
  255.56 +#include "tpmfront.h"
  255.57 +
  255.58 +#undef DEBUG
  255.59 +
  255.60 +#if 1
  255.61 +#define ASSERT(_p) \
  255.62 +    if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
  255.63 +        __LINE__, __FILE__); *(int*)0=0; }
  255.64 +#else
  255.65 +#define ASSERT(_p)
  255.66 +#endif
  255.67 +
  255.68 +/* locally visible variables */
  255.69 +static grant_ref_t gref_head;
  255.70 +static struct tpm_private my_private;
  255.71 +
  255.72 +/* local function prototypes */
  255.73 +static irqreturn_t tpmif_int(int irq,
  255.74 +                             void *tpm_priv,
  255.75 +                             struct pt_regs *ptregs);
  255.76 +static void tpmif_rx_action(unsigned long unused);
  255.77 +static void tpmif_connect(u16 evtchn, domid_t domid);
  255.78 +static DECLARE_TASKLET(tpmif_rx_tasklet, tpmif_rx_action, 0);
  255.79 +static int tpm_allocate_buffers(struct tpm_private *tp);
  255.80 +static void tpmif_set_connected_state(struct tpm_private *tp, int newstate);
  255.81 +static int tpm_xmit(struct tpm_private *tp,
  255.82 +                    const u8 * buf, size_t count, int userbuffer,
  255.83 +                    void *remember);
  255.84 +
  255.85 +#if DEBUG
  255.86 +#define DPRINTK(fmt, args...) \
  255.87 +    printk(KERN_ALERT "xen_tpm_fr (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args)
  255.88 +#else
  255.89 +#define DPRINTK(fmt, args...) ((void)0)
  255.90 +#endif
  255.91 +#define IPRINTK(fmt, args...) \
  255.92 +    printk(KERN_INFO "xen_tpm_fr: " fmt, ##args)
  255.93 +#define WPRINTK(fmt, args...) \
  255.94 +    printk(KERN_WARNING "xen_tpm_fr: " fmt, ##args)
  255.95 +
  255.96 +
  255.97 +static inline int
  255.98 +tx_buffer_copy(struct tx_buffer *txb, const u8 * src, int len,
  255.99 +               int isuserbuffer)
 255.100 +{
 255.101 +	int copied = len;
 255.102 +
 255.103 +	if (len > txb->size) {
 255.104 +		copied = txb->size;
 255.105 +	}
 255.106 +	if (isuserbuffer) {
 255.107 +		if (copy_from_user(txb->data,
 255.108 +		                   src,
 255.109 +		                   copied)) {
 255.110 +			return -EFAULT;
 255.111 +		}
 255.112 +	} else {
 255.113 +		memcpy(txb->data, src, copied);
 255.114 +	}
 255.115 +	txb->len = len;
 255.116 +	return copied;
 255.117 +}
 255.118 +
 255.119 +static inline struct tx_buffer *tx_buffer_alloc(void)
 255.120 +{
 255.121 +	struct tx_buffer *txb = kmalloc(sizeof (struct tx_buffer),
 255.122 +					GFP_KERNEL);
 255.123 +
 255.124 +	if (txb) {
 255.125 +		txb->len = 0;
 255.126 +		txb->size = PAGE_SIZE;
 255.127 +		txb->data = (unsigned char *)__get_free_page(GFP_KERNEL);
 255.128 +		if (txb->data == NULL) {
 255.129 +			kfree(txb);
 255.130 +			txb = NULL;
 255.131 +		}
 255.132 +	}
 255.133 +	return txb;
 255.134 +}
 255.135 +
 255.136 +
 255.137 +/**************************************************************
 255.138 +
 255.139 + The interface to let the tpm plugin register its callback
 255.140 + function and send data to another partition using this module
 255.141 +
 255.142 +**************************************************************/
 255.143 +
 255.144 +static DECLARE_MUTEX(upperlayer_lock);
 255.145 +static DECLARE_MUTEX(suspend_lock);
 255.146 +static struct tpmfe_device *upperlayer_tpmfe;
 255.147 +
 255.148 +/*
 255.149 + * Send data via this module by calling this function
 255.150 + */
 255.151 +int tpm_fe_send(const u8 * buf, size_t count, void *ptr)
 255.152 +{
 255.153 +	int sent = 0;
 255.154 +	struct tpm_private *tp = &my_private;
 255.155 +
 255.156 +	down(&suspend_lock);
 255.157 +	sent = tpm_xmit(tp, buf, count, 0, ptr);
 255.158 +	up(&suspend_lock);
 255.159 +
 255.160 +	return sent;
 255.161 +}
 255.162 +EXPORT_SYMBOL(tpm_fe_send);
 255.163 +
 255.164 +/*
 255.165 + * Register a callback for receiving data from this module
 255.166 + */
 255.167 +int tpm_fe_register_receiver(struct tpmfe_device *tpmfe_dev)
 255.168 +{
 255.169 +	int rc = 0;
 255.170 +
 255.171 +	down(&upperlayer_lock);
 255.172 +	if (NULL == upperlayer_tpmfe) {
 255.173 +		upperlayer_tpmfe = tpmfe_dev;
 255.174 +		tpmfe_dev->max_tx_size = TPMIF_TX_RING_SIZE * PAGE_SIZE;
 255.175 +	} else {
 255.176 +		rc = -EBUSY;
 255.177 +	}
 255.178 +	up(&upperlayer_lock);
 255.179 +	return rc;
 255.180 +}
 255.181 +EXPORT_SYMBOL(tpm_fe_register_receiver);
 255.182 +
 255.183 +/*
 255.184 + * Unregister the callback for receiving data from this module
 255.185 + */
 255.186 +void tpm_fe_unregister_receiver(void)
 255.187 +{
 255.188 +	down(&upperlayer_lock);
 255.189 +	upperlayer_tpmfe = NULL;
 255.190 +	up(&upperlayer_lock);
 255.191 +}
 255.192 +EXPORT_SYMBOL(tpm_fe_unregister_receiver);
 255.193 +
 255.194 +/*
 255.195 + * Call this function to send data to the upper layer's
 255.196 + * registered receiver function.
 255.197 + */
 255.198 +static int tpm_fe_send_upperlayer(const u8 * buf, size_t count,
 255.199 +                                  const void *ptr)
 255.200 +{
 255.201 +	int rc;
 255.202 +
 255.203 +	down(&upperlayer_lock);
 255.204 +
 255.205 +	if (upperlayer_tpmfe && upperlayer_tpmfe->receive) {
 255.206 +		rc = upperlayer_tpmfe->receive(buf, count, ptr);
 255.207 +	} else {
 255.208 +		rc = 0;
 255.209 +	}
 255.210 +
 255.211 +	up(&upperlayer_lock);
 255.212 +	return rc;
 255.213 +}
 255.214 +
 255.215 +/**************************************************************
 255.216 + XENBUS support code
 255.217 +**************************************************************/
 255.218 +
 255.219 +static void watch_for_status(struct xenbus_watch *watch, const char *node)
 255.220 +{
 255.221 +	struct tpmfront_info *info;
 255.222 +	int err;
 255.223 +	unsigned long ready;
 255.224 +	struct tpm_private *tp = &my_private;
 255.225 +
 255.226 +	info = container_of(watch, struct tpmfront_info, watch);
 255.227 +	node += strlen(watch->node);
 255.228 +
 255.229 +	if (tp->connected)
 255.230 +		return;
 255.231 +
 255.232 +	err = xenbus_gather(watch->node,
 255.233 +	                    "ready", "%lu", &ready,
 255.234 +	                    NULL);
 255.235 +	if (err) {
 255.236 +		xenbus_dev_error(info->dev, err, "reading 'ready' field");
 255.237 +		return;
 255.238 +	}
 255.239 +
 255.240 +	tpmif_set_connected_state(tp, 1);
 255.241 +
 255.242 +	xenbus_dev_ok(info->dev);
 255.243 +}
 255.244 +
 255.245 +
 255.246 +static int setup_tpmring(struct xenbus_device *dev,
 255.247 +                         struct tpmfront_info * info,
 255.248 +                         domid_t backend_id)
 255.249 +{
 255.250 +	tpmif_tx_interface_t *sring;
 255.251 +	struct tpm_private *tp = &my_private;
 255.252 +
 255.253 +	evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
 255.254 +	int err;
 255.255 +
 255.256 +	sring = (void *)__get_free_page(GFP_KERNEL);
 255.257 +	if (!sring) {
 255.258 +		xenbus_dev_error(dev, -ENOMEM, "allocating shared ring");
 255.259 +		return -ENOMEM;
 255.260 +	}
 255.261 +	tp->tx = sring;
 255.262 +
 255.263 +	tpm_allocate_buffers(tp);
 255.264 +
 255.265 +	info->ring_ref = gnttab_claim_grant_reference(&gref_head);
 255.266 +	ASSERT(info->ring_ref != -ENOSPC);
 255.267 +	gnttab_grant_foreign_access_ref(info->ring_ref,
 255.268 +					backend_id,
 255.269 +					(virt_to_machine(tp->tx) >> PAGE_SHIFT),
 255.270 +					0);
 255.271 +
 255.272 +	op.u.alloc_unbound.dom = backend_id;
 255.273 +	err = HYPERVISOR_event_channel_op(&op);
 255.274 +	if (err) {
 255.275 +		free_page((unsigned long)sring);
 255.276 +		tp->tx = 0;
 255.277 +		xenbus_dev_error(dev, err, "allocating event channel");
 255.278 +		return err;
 255.279 +	}
 255.280 +	tpmif_connect(op.u.alloc_unbound.port, backend_id);
 255.281 +	return 0;
 255.282 +}
 255.283 +
 255.284 +
 255.285 +static void destroy_tpmring(struct tpmfront_info *info, struct tpm_private *tp)
 255.286 +{
 255.287 +	tpmif_set_connected_state(tp,0);
 255.288 +
 255.289 +	if ( tp->tx != NULL ) {
 255.290 +		free_page((unsigned long)tp->tx);
 255.291 +		tp->tx = NULL;
 255.292 +	}
 255.293 +	unbind_evtchn_from_irqhandler(tp->evtchn, NULL);
 255.294 +	tp->evtchn = 0;
 255.295 +}
 255.296 +
 255.297 +
 255.298 +static int talk_to_backend(struct xenbus_device *dev,
 255.299 +                           struct tpmfront_info *info)
 255.300 +{
 255.301 +	char *backend;
 255.302 +	const char *message;
 255.303 +	int err;
 255.304 +	int backend_id;
 255.305 +
 255.306 +	backend = NULL;
 255.307 +	err = xenbus_gather(dev->nodename,
 255.308 +			    "backend-id", "%i", &backend_id,
 255.309 +			    "backend", NULL, &backend,
 255.310 +			    NULL);
 255.311 +	if (XENBUS_EXIST_ERR(err))
 255.312 +		goto out;
 255.313 +	if (backend && strlen(backend) == 0) {
 255.314 +		err = -ENOENT;
 255.315 +		goto out;
 255.316 +	}
 255.317 +	if (err < 0) {
 255.318 +		xenbus_dev_error(dev, err, "reading %s/backend or backend-id",
 255.319 +				 dev->nodename);
 255.320 +		goto out;
 255.321 +	}
 255.322 +
 255.323 +	info->backend_id      = backend_id;
 255.324 +	my_private.backend_id = backend_id;
 255.325 +
 255.326 +	err = setup_tpmring(dev, info, backend_id);
 255.327 +	if (err) {
 255.328 +		xenbus_dev_error(dev, err, "setting up ring");
 255.329 +		goto out;
 255.330 +	}
 255.331 +
 255.332 +	err = xenbus_transaction_start(dev->nodename);
 255.333 +	if (err) {
 255.334 +		xenbus_dev_error(dev, err, "starting transaction");
 255.335 +		goto destroy_tpmring;
 255.336 +	}
 255.337 +
 255.338 +	err = xenbus_printf(dev->nodename,
 255.339 +	                    "ring-ref","%u", info->ring_ref);
 255.340 +	if (err) {
 255.341 +		message = "writing ring-ref";
 255.342 +		goto abort_transaction;
 255.343 +	}
 255.344 +
 255.345 +	err = xenbus_printf(dev->nodename,
 255.346 +			    "event-channel", "%u", my_private.evtchn);
 255.347 +	if (err) {
 255.348 +		message = "writing event-channel";
 255.349 +		goto abort_transaction;
 255.350 +	}
 255.351 +
 255.352 +	info->backend = backend;
 255.353 +	backend = NULL;
 255.354 +
 255.355 +	info->watch.node = info->backend;
 255.356 +	info->watch.callback = watch_for_status;
 255.357 +	err = register_xenbus_watch(&info->watch);
 255.358 +	if (err) {
 255.359 +		message = "registering watch on backend";
 255.360 +		goto abort_transaction;
 255.361 +	}
 255.362 +
 255.363 +	err = xenbus_transaction_end(0);
 255.364 +	if (err) {
 255.365 +		xenbus_dev_error(dev, err, "completing transaction");
 255.366 +		goto destroy_tpmring;
 255.367 +	}
 255.368 +
 255.369 +out:
 255.370 +	if (backend)
 255.371 +		kfree(backend);
 255.372 +	return err;
 255.373 +
 255.374 +abort_transaction:
 255.375 +	xenbus_transaction_end(1);
 255.376 +	/* Have to do this *outside* transaction.  */
 255.377 +	xenbus_dev_error(dev, err, "%s", message);
 255.378 +destroy_tpmring:
 255.379 +	destroy_tpmring(info, &my_private);
 255.380 +	goto out;
 255.381 +}
 255.382 +
 255.383 +
 255.384 +static int tpmfront_probe(struct xenbus_device *dev,
 255.385 +                          const struct xenbus_device_id *id)
 255.386 +{
 255.387 +	int err;
 255.388 +	struct tpmfront_info *info;
 255.389 +	int handle;
 255.390 +
 255.391 +	err = xenbus_scanf(dev->nodename,
 255.392 +	                   "handle", "%i", &handle);
 255.393 +	if (XENBUS_EXIST_ERR(err))
 255.394 +		return err;
 255.395 +
 255.396 +	if (err < 0) {
 255.397 +		xenbus_dev_error(dev,err,"reading virtual-device");
 255.398 +		return err;
 255.399 +	}
 255.400 +
 255.401 +	info = kmalloc(sizeof(*info), GFP_KERNEL);
 255.402 +	if (!info) {
 255.403 +		xenbus_dev_error(dev,err,"allocating info structure");
 255.404 +		return err;
 255.405 +	}
 255.406 +	memset(info, 0x0, sizeof(*info));
 255.407 +
 255.408 +	info->dev = dev;
 255.409 +	info->handle = handle;
 255.410 +	dev->data = info;
 255.411 +
 255.412 +	err = talk_to_backend(dev, info);
 255.413 +	if (err) {
 255.414 +		kfree(info);
 255.415 +		dev->data = NULL;
 255.416 +		return err;
 255.417 +	}
 255.418 +
 255.419 +	watch_for_status(&info->watch, info->watch.node);
 255.420 +	return 0;
 255.421 +}
 255.422 +
 255.423 +static int tpmfront_remove(struct xenbus_device *dev)
 255.424 +{
 255.425 +	struct tpmfront_info *info = dev->data;
 255.426 +	if (info->backend)
 255.427 +		unregister_xenbus_watch(&info->watch);
 255.428 +
 255.429 +	destroy_tpmring(info, &my_private);
 255.430 +
 255.431 +	kfree(info->backend);
 255.432 +	kfree(info);
 255.433 +
 255.434 +	return 0;
 255.435 +}
 255.436 +
 255.437 +static int tpmfront_suspend(struct xenbus_device *dev)
 255.438 +{
 255.439 +	struct tpmfront_info *info = dev->data;
 255.440 +	struct tpm_private *tp = &my_private;
 255.441 +
 255.442 +	/* lock so no app can send */
 255.443 +	down(&suspend_lock);
 255.444 +
 255.445 +	while (atomic_read(&tp->tx_busy)) {
 255.446 +		printk("---- TPMIF: Outstanding request.\n");
 255.447 +#if 0
 255.448 +		/*
 255.449 +		 * Would like to wait until the outstanding request
 255.450 +		 * has come back, but this does not work properly, yet.
 255.451 +		 */
 255.452 +		interruptible_sleep_on_timeout(&tp->wait_q,
 255.453 +		                               100);
 255.454 +#else
 255.455 +		break;
 255.456 +#endif
 255.457 +	}
 255.458 +
 255.459 +	unregister_xenbus_watch(&info->watch);
 255.460 +
 255.461 +	kfree(info->backend);
 255.462 +	info->backend = NULL;
 255.463 +
 255.464 +	destroy_tpmring(info, tp);
 255.465 +
 255.466 +	return 0;
 255.467 +}
 255.468 +
 255.469 +static int tpmif_recover(void)
 255.470 +{
 255.471 +	return 0;
 255.472 +}
 255.473 +
 255.474 +static int tpmfront_resume(struct xenbus_device *dev)
 255.475 +{
 255.476 +	struct tpmfront_info *info = dev->data;
 255.477 +	int err;
 255.478 +
 255.479 +	err = talk_to_backend(dev, info);
 255.480 +	if (!err) {
 255.481 +		tpmif_recover();
 255.482 +	}
 255.483 +
 255.484 +	/* unlock so apps can resume */
 255.485 +	up(&suspend_lock);
 255.486 +
 255.487 +	return err;
 255.488 +}
 255.489 +
 255.490 +static void tpmif_connect(u16 evtchn, domid_t domid)
 255.491 +{
 255.492 +	int err = 0;
 255.493 +	struct tpm_private *tp = &my_private;
 255.494 +
 255.495 +	tp->evtchn = evtchn;
 255.496 +	tp->backend_id  = domid;
 255.497 +
 255.498 +	err = bind_evtchn_to_irqhandler(
 255.499 +		tp->evtchn,
 255.500 +		tpmif_int, SA_SAMPLE_RANDOM, "tpmif", tp);
 255.501 +	if ( err != 0 ) {
 255.502 +		WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
 255.503 +		return;
 255.504 +	}
 255.505 +}
 255.506 +
 255.507 +static struct xenbus_device_id tpmfront_ids[] = {
 255.508 +	{ "vtpm" },
 255.509 +	{ "" }
 255.510 +};
 255.511 +
 255.512 +static struct xenbus_driver tpmfront = {
 255.513 +	.name = "vtpm",
 255.514 +	.owner = THIS_MODULE,
 255.515 +	.ids = tpmfront_ids,
 255.516 +	.probe = tpmfront_probe,
 255.517 +	.remove =  tpmfront_remove,
 255.518 +	.resume = tpmfront_resume,
 255.519 +	.suspend = tpmfront_suspend,
 255.520 +};
 255.521 +
 255.522 +static void __init init_tpm_xenbus(void)
 255.523 +{
 255.524 +	xenbus_register_device(&tpmfront);
 255.525 +}
 255.526 +
 255.527 +
 255.528 +static int
 255.529 +tpm_allocate_buffers(struct tpm_private *tp)
 255.530 +{
 255.531 +	unsigned int i;
 255.532 +
 255.533 +	i = 0;
 255.534 +	while (i < TPMIF_TX_RING_SIZE) {
 255.535 +		tp->tx_buffers[i] = tx_buffer_alloc();
 255.536 +		i++;
 255.537 +	}
 255.538 +
 255.539 +	return 1;
 255.540 +}
 255.541 +
 255.542 +static void
 255.543 +tpmif_rx_action(unsigned long unused)
 255.544 +{
 255.545 +	struct tpm_private *tp = &my_private;
 255.546 +
 255.547 +	int i = 0;
 255.548 +	unsigned int received;
 255.549 +	unsigned int offset = 0;
 255.550 +	u8 *buffer;
 255.551 +	tpmif_tx_request_t *tx;
 255.552 +	tx = &tp->tx->ring[i].req;
 255.553 +
 255.554 +	received = tx->size;
 255.555 +
 255.556 +	buffer = kmalloc(received, GFP_KERNEL);
 255.557 +	if (NULL == buffer) {
 255.558 +		goto exit;
 255.559 +	}
 255.560 +
 255.561 +	i = 0;
 255.562 +	while (i < TPMIF_TX_RING_SIZE &&
 255.563 +	       offset < received) {
 255.564 +		struct tx_buffer *txb = tp->tx_buffers[i];
 255.565 +		tpmif_tx_request_t *tx;
 255.566 +		unsigned int tocopy;
 255.567 +
 255.568 +		tx = &tp->tx->ring[i].req;
 255.569 +		tocopy = tx->size;
 255.570 +		if (tocopy > PAGE_SIZE) {
 255.571 +			tocopy = PAGE_SIZE;
 255.572 +		}
 255.573 +
 255.574 +		memcpy(&buffer[offset], txb->data, tocopy);
 255.575 +
 255.576 +		gnttab_release_grant_reference(&gref_head, tx->ref);
 255.577 +
 255.578 +		offset += tocopy;
 255.579 +		i++;
 255.580 +	}
 255.581 +
 255.582 +	tpm_fe_send_upperlayer(buffer, received, tp->tx_remember);
 255.583 +	kfree(buffer);
 255.584 +
 255.585 +exit:
 255.586 +	atomic_set(&tp->tx_busy, 0);
 255.587 +	wake_up_interruptible(&tp->wait_q);
 255.588 +}
 255.589 +
 255.590 +
 255.591 +static irqreturn_t
 255.592 +tpmif_int(int irq, void *tpm_priv, struct pt_regs *ptregs)
 255.593 +{
 255.594 +	struct tpm_private *tp = tpm_priv;
 255.595 +	unsigned long flags;
 255.596 +
 255.597 +	spin_lock_irqsave(&tp->tx_lock, flags);
 255.598 +	tasklet_schedule(&tpmif_rx_tasklet);
 255.599 +	spin_unlock_irqrestore(&tp->tx_lock, flags);
 255.600 +
 255.601 +	return IRQ_HANDLED;
 255.602 +}
 255.603 +
 255.604 +
 255.605 +static int
 255.606 +tpm_xmit(struct tpm_private *tp,
 255.607 +         const u8 * buf, size_t count, int isuserbuffer,
 255.608 +         void *remember)
 255.609 +{
 255.610 +	tpmif_tx_request_t *tx;
 255.611 +	TPMIF_RING_IDX i;
 255.612 +	unsigned int offset = 0;
 255.613 +
 255.614 +	spin_lock_irq(&tp->tx_lock);
 255.615 +
 255.616 +	if (unlikely(atomic_read(&tp->tx_busy))) {
 255.617 +		printk("There's an outstanding request/response on the way!\n");
 255.618 +		spin_unlock_irq(&tp->tx_lock);
 255.619 +		return -EBUSY;
 255.620 +	}
 255.621 +
 255.622 +	if (tp->connected != 1) {
 255.623 +		spin_unlock_irq(&tp->tx_lock);
 255.624 +		return -EIO;
 255.625 +	}
 255.626 +
 255.627 +	i = 0;
 255.628 +	while (count > 0 && i < TPMIF_TX_RING_SIZE) {
 255.629 +		struct tx_buffer *txb = tp->tx_buffers[i];
 255.630 +		int copied;
 255.631 +
 255.632 +		if (NULL == txb) {
 255.633 +			DPRINTK("txb (i=%d) is NULL. buffers initilized?\n", i);
 255.634 +			DPRINTK("Not transmittin anything!\n");
 255.635 +			spin_unlock_irq(&tp->tx_lock);
 255.636 +			return -EFAULT;
 255.637 +		}
 255.638 +		copied = tx_buffer_copy(txb, &buf[offset], count,
 255.639 +		                        isuserbuffer);
 255.640 +		if (copied < 0) {
 255.641 +			/* An error occurred */
 255.642 +			return copied;
 255.643 +		}
 255.644 +		count -= copied;
 255.645 +		offset += copied;
 255.646 +
 255.647 +		tx = &tp->tx->ring[i].req;
 255.648 +
 255.649 +		tx->id = i;
 255.650 +		tx->addr = virt_to_machine(txb->data);
 255.651 +		tx->size = txb->len;
 255.652 +
 255.653 +		DPRINTK("First 4 characters sent by TPM-FE are 0x%02x 0x%02x 0x%02x 0x%02x\n",
 255.654 +		        txb->data[0],txb->data[1],txb->data[2],txb->data[3]);
 255.655 +
 255.656 +		/* get the granttable reference for this page */
 255.657 +		tx->ref = gnttab_claim_grant_reference( &gref_head );
 255.658 +
 255.659 +		if(-ENOSPC == tx->ref ) {
 255.660 +			DPRINTK(" Grant table claim reference failed in func:%s line:%d file:%s\n", __FUNCTION__, __LINE__, __FILE__);
 255.661 +			return -ENOSPC;
 255.662 +		}
 255.663 +		gnttab_grant_foreign_access_ref( tx->ref,
 255.664 +		                                 tp->backend_id,
 255.665 +		                                 (tx->addr >> PAGE_SHIFT),
 255.666 +		                                 0 /*RW*/);
 255.667 +		i++;
 255.668 +		wmb();
 255.669 +	}
 255.670 +
 255.671 +	atomic_set(&tp->tx_busy, 1);
 255.672 +	tp->tx_remember = remember;
 255.673 +	mb();
 255.674 +
 255.675 +	DPRINTK("Notifying backend via event channel %d\n",
 255.676 +	        tp->evtchn);
 255.677 +
 255.678 +	notify_via_evtchn(tp->evtchn);
 255.679 +
 255.680 +	spin_unlock_irq(&tp->tx_lock);
 255.681 +	return offset;
 255.682 +}
 255.683 +
 255.684 +
 255.685 +static void tpmif_notify_upperlayer(struct tpm_private *tp)
 255.686 +{
 255.687 +	/*
 255.688 +	 * Notify upper layer about the state of the connection
 255.689 +	 * to the BE.
 255.690 +	 */
 255.691 +	down(&upperlayer_lock);
 255.692 +
 255.693 +	if (upperlayer_tpmfe != NULL) {
 255.694 +		switch (tp->connected) {
 255.695 +			case 1:
 255.696 +				upperlayer_tpmfe->status(TPMFE_STATUS_CONNECTED);
 255.697 +			break;
 255.698 +
 255.699 +			default:
 255.700 +				upperlayer_tpmfe->status(0);
 255.701 +			break;
 255.702 +		}
 255.703 +	}
 255.704 +	up(&upperlayer_lock);
 255.705 +}
 255.706 +
 255.707 +
 255.708 +static void tpmif_set_connected_state(struct tpm_private *tp, int newstate)
 255.709 +{
 255.710 +	if (newstate != tp->connected) {
 255.711 +		tp->connected = newstate;
 255.712 +		tpmif_notify_upperlayer(tp);
 255.713 +	}
 255.714 +}
 255.715 +
 255.716 +
 255.717 +/* =================================================================
 255.718 + * Initialization function.
 255.719 + * =================================================================
 255.720 + */
 255.721 +
 255.722 +static int __init
 255.723 +tpmif_init(void)
 255.724 +{
 255.725 +	IPRINTK("Initialising the vTPM driver.\n");
 255.726 +	if ( gnttab_alloc_grant_references ( TPMIF_TX_RING_SIZE,
 255.727 +	                                     &gref_head ) < 0) {
 255.728 +		return -EFAULT;
 255.729 +	}
 255.730 +	/*
 255.731 +	 * Only don't send the driver status when we are in the
 255.732 +	 * INIT domain.
 255.733 +	 */
 255.734 +	spin_lock_init(&my_private.tx_lock);
 255.735 +	init_waitqueue_head(&my_private.wait_q);
 255.736 +
 255.737 +	init_tpm_xenbus();
 255.738 +
 255.739 +	return 0;
 255.740 +}
 255.741 +
 255.742 +__initcall(tpmif_init);
   256.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   256.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h	Thu Sep 01 10:16:14 2005 +0000
   256.3 @@ -0,0 +1,38 @@
   256.4 +#ifndef TPM_FRONT_H
   256.5 +#define TPM_FRONT_H
   256.6 +
   256.7 +
   256.8 +struct tpm_private {
   256.9 +	tpmif_tx_interface_t *tx;
  256.10 +	unsigned int evtchn;
  256.11 +	int connected;
  256.12 +
  256.13 +	spinlock_t tx_lock;
  256.14 +
  256.15 +	struct tx_buffer *tx_buffers[TPMIF_TX_RING_SIZE];
  256.16 +
  256.17 +	atomic_t tx_busy;
  256.18 +	void *tx_remember;
  256.19 +	domid_t backend_id;
  256.20 +	wait_queue_head_t wait_q;
  256.21 +};
  256.22 +
  256.23 +
  256.24 +struct tpmfront_info
  256.25 +{
  256.26 +	struct xenbus_watch watch;
  256.27 +	int handle;
  256.28 +	struct xenbus_device *dev;
  256.29 +	char *backend;
  256.30 +	int ring_ref;
  256.31 +	domid_t backend_id;
  256.32 +};
  256.33 +
  256.34 +
  256.35 +struct tx_buffer {
  256.36 +	unsigned int size;	// available space in data
  256.37 +	unsigned int len;	// used space in data
  256.38 +	unsigned char *data;    // pointer to a page
  256.39 +};
  256.40 +
  256.41 +#endif
   300.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h	Thu Sep 01 10:08:53 2005 +0000
   300.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h	Thu Sep 01 10:16:14 2005 +0000
   300.3 @@ -561,8 +561,14 @@ do {									\
   300.4  #define local_irq_disable()	__cli()
   300.5  #define local_irq_enable()	__sti()
   300.6  
   300.7 +/* Don't use smp_processor_id: this is called in debug versions of that fn. */
   300.8 +#ifdef CONFIG_SMP
   300.9  #define irqs_disabled()			\
  300.10 -    HYPERVISOR_shared_info->vcpu_data[smp_processor_id()].evtchn_upcall_mask
  300.11 +    HYPERVISOR_shared_info->vcpu_data[__smp_processor_id()].evtchn_upcall_mask
  300.12 +#else
  300.13 +#define irqs_disabled()			\
  300.14 +    HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask
  300.15 +#endif
  300.16  
  300.17  /*
  300.18   * disable hlt during certain critical i/o operations
   330.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h	Thu Sep 01 10:08:53 2005 +0000
   330.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h	Thu Sep 01 10:16:14 2005 +0000
   330.3 @@ -387,8 +387,14 @@ void cpu_idle_wait(void);
   330.4  #define local_irq_disable()	__cli()
   330.5  #define local_irq_enable()	__sti()
   330.6  
   330.7 +/* Don't use smp_processor_id: this is called in debug versions of that fn. */
   330.8 +#ifdef CONFIG_SMP
   330.9  #define irqs_disabled()			\
  330.10 -    HYPERVISOR_shared_info->vcpu_data[smp_processor_id()].evtchn_upcall_mask
  330.11 +    HYPERVISOR_shared_info->vcpu_data[__smp_processor_id()].evtchn_upcall_mask
  330.12 +#else
  330.13 +#define irqs_disabled()			\
  330.14 +    HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask
  330.15 +#endif
  330.16  
  330.17  /*
  330.18   * disable hlt during certain critical i/o operations
   352.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   352.2 +++ b/linux-2.6-xen-sparse/include/linux/tpmfe.h	Thu Sep 01 10:16:14 2005 +0000
   352.3 @@ -0,0 +1,33 @@
   352.4 +#ifndef TPM_FE_H
   352.5 +#define TPM_FE_H
   352.6 +
   352.7 +struct tpmfe_device {
   352.8 +	/*
   352.9 +	 * Let upper layer receive data from front-end
  352.10 +	 */
  352.11 +	int (*receive)(const u8 *buffer, size_t count, const void *ptr);
  352.12 +	/*
  352.13 +	 * Indicate the status of the front-end to the upper
  352.14 +	 * layer.
  352.15 +	 */
  352.16 +	void (*status)(unsigned int flags);
  352.17 +
  352.18 +	/*
  352.19 +	 * This field indicates the maximum size the driver can
  352.20 +	 * transfer in one chunk. It is filled out by the front-end
  352.21 +	 * driver and should be propagated to the generic tpm driver
  352.22 +	 * for allocation of buffers.
  352.23 +	 */
  352.24 +	unsigned int max_tx_size;
  352.25 +};
  352.26 +
  352.27 +enum {
  352.28 +	TPMFE_STATUS_DISCONNECTED = 0x0,
  352.29 +	TPMFE_STATUS_CONNECTED = 0x1
  352.30 +};
  352.31 +
  352.32 +int tpm_fe_send(const u8 * buf, size_t count, void *ptr);
  352.33 +int tpm_fe_register_receiver(struct tpmfe_device *);
  352.34 +void tpm_fe_unregister_receiver(void);
  352.35 +
  352.36 +#endif
   366.1 --- a/tools/Makefile	Thu Sep 01 10:08:53 2005 +0000
   366.2 +++ b/tools/Makefile	Thu Sep 01 10:16:14 2005 +0000
   366.3 @@ -12,8 +12,14 @@ SUBDIRS += xcutils
   366.4  SUBDIRS += firmware
   366.5  SUBDIRS += security
   366.6  SUBDIRS += console
   366.7 +ifeq ($(VTPM_TOOLS),y)
   366.8 +SUBDIRS += vtpm_manager
   366.9 +SUBDIRS += vtpm
  366.10 +endif
  366.11  SUBDIRS += xenstat
  366.12  
  366.13 +.PHONY: all install clean check check_clean ioemu eioemuinstall ioemuclean
  366.14 +
  366.15  # These don't cross-compile
  366.16  ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH))
  366.17  SUBDIRS += python
   373.1 --- a/tools/check/check_curl_devel	Thu Sep 01 10:08:53 2005 +0000
   373.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   373.3 @@ -1,11 +0,0 @@
   373.4 -#!/bin/bash
   373.5 -# CHECK-BUILD
   373.6 -
   373.7 -function error {
   373.8 -    echo 'Check for libcurl includes failed.'
   373.9 -    exit 1
  373.10 -}
  373.11 -
  373.12 -set -e
  373.13 -[ -e /usr/include/curl ] || error
  373.14 -[ -e /usr/include/curl/curl.h ] || error
  373.15 \ No newline at end of file
   374.1 --- a/tools/check/check_curl_lib	Thu Sep 01 10:08:53 2005 +0000
   374.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   374.3 @@ -1,10 +0,0 @@
   374.4 -#!/bin/bash
   374.5 -# CHECK-BUILD CHECK-INSTALL
   374.6 -
   374.7 -function error {
   374.8 -        echo 'Check for CURL library failed.'
   374.9 -        exit 1
  374.10 -}
  374.11 -
  374.12 -set -e
  374.13 -ldconfig -p | grep libcurl.so || error
  374.14 \ No newline at end of file
   429.1 --- a/tools/examples/xmexample1	Thu Sep 01 10:08:53 2005 +0000
   429.2 +++ b/tools/examples/xmexample1	Thu Sep 01 10:16:14 2005 +0000
   429.3 @@ -48,6 +48,20 @@ name = "ExampleDomain"
   429.4  disk = [ 'phy:hda1,hda1,w' ]
   429.5  
   429.6  #----------------------------------------------------------------------------
   429.7 +# Define to which TPM instance the user domain should communicate.
   429.8 +# The vtpm entry is of the form 'instance=INSTANCE,backend=DOM'
   429.9 +# where INSTANCE indicates the instance number of the TPM the VM
  429.10 +# should be talking to and DOM provides the domain where the backend
  429.11 +# is located.
  429.12 +# Note that no two virtual machines should try to connect to the same
  429.13 +# TPM instance. The handling of all TPM instances does require
  429.14 +# some management effort in so far that VM configration files (and thus
  429.15 +# a VM) should be associated with a TPM instance throughout the lifetime
  429.16 +# of the VM / VM configuration file. The instance number must be
  429.17 +# greater or equal to 1.
  429.18 +#vtpm = [ 'instance=1,backend=0' ]
  429.19 +
  429.20 +#----------------------------------------------------------------------------
  429.21  # Set the kernel command line for the new domain.
  429.22  # You only need to define the IP parameters and hostname if the domain's
  429.23  # IP config doesn't, e.g. in ifcfg-eth0 or via DHCP.
   430.1 --- a/tools/examples/xmexample2	Thu Sep 01 10:08:53 2005 +0000
   430.2 +++ b/tools/examples/xmexample2	Thu Sep 01 10:16:14 2005 +0000
   430.3 @@ -84,6 +84,20 @@ disk = [ 'phy:sda%d,sda1,w' % (7+vmid),
   430.4           'phy:sda6,sda6,r' ]
   430.5  
   430.6  #----------------------------------------------------------------------------
   430.7 +# Define to which TPM instance the user domain should communicate.
   430.8 +# The vtpm entry is of the form 'instance=INSTANCE,backend=DOM'
   430.9 +# where INSTANCE indicates the instance number of the TPM the VM
  430.10 +# should be talking to and DOM provides the domain where the backend
  430.11 +# is located.
  430.12 +# Note that no two virtual machines should try to connect to the same
  430.13 +# TPM instance. The handling of all TPM instances does require
  430.14 +# some management effort in so far that VM configration files (and thus
  430.15 +# a VM) should be associated with a TPM instance throughout the lifetime
  430.16 +# of the VM / VM configuration file. The instance number must be
  430.17 +# greater or equal to 1.
  430.18 +#vtpm = ['instance=%d,backend=0' % (vmid) ]
  430.19 +
  430.20 +#----------------------------------------------------------------------------
  430.21  # Set the kernel command line for the new domain.
  430.22  # You only need to define the IP parameters and hostname if the domain's
  430.23  # IP config doesn't, e.g. in ifcfg-eth0 or via DHCP.
   431.1 --- a/tools/examples/xmexample3	Thu Sep 01 10:08:53 2005 +0000
   431.2 +++ b/tools/examples/xmexample3	Thu Sep 01 10:16:14 2005 +0000
   431.3 @@ -80,6 +80,20 @@ vif = [ 'ip=192.168.%d.1/24' % (vmid)]
   431.4  disk = [ 'phy:hda%d,hda1,w' % (vmid)]
   431.5  
   431.6  #----------------------------------------------------------------------------
   431.7 +# Define to which TPM instance the user domain should communicate.
   431.8 +# The vtpm entry is of the form 'instance=INSTANCE,backend=DOM'
   431.9 +# where INSTANCE indicates the instance number of the TPM the VM
  431.10 +# should be talking to and DOM provides the domain where the backend
  431.11 +# is located.
  431.12 +# Note that no two virtual machines should try to connect to the same
  431.13 +# TPM instance. The handling of all TPM instances does require
  431.14 +# some management effort in so far that VM configration files (and thus
  431.15 +# a VM) should be associated with a TPM instance throughout the lifetime
  431.16 +# of the VM / VM configuration file. The instance number must be
  431.17 +# greater or equal to 1.
  431.18 +#vtpm = ['instance=%d,backend=0' % (vmid) ]
  431.19 +
  431.20 +#----------------------------------------------------------------------------
  431.21  # Set the kernel command line for the new domain.
  431.22  # You only need to define the IP parameters and hostname if the domain's
  431.23  # IP config doesn't, e.g. in ifcfg-eth0 or via DHCP.
   464.1 --- a/tools/libxc/xc_private.c	Thu Sep 01 10:08:53 2005 +0000
   464.2 +++ b/tools/libxc/xc_private.c	Thu Sep 01 10:16:14 2005 +0000
   464.3 @@ -422,3 +422,8 @@ int xc_dom0_op(int xc_handle, dom0_op_t 
   464.4  {
   464.5      return do_dom0_op(xc_handle, op);
   464.6  }
   464.7 +
   464.8 +int xc_version(int xc_handle, int cmd, void *arg)
   464.9 +{
  464.10 +    return do_xen_version(xc_handle, cmd, arg);
  464.11 +}
   465.1 --- a/tools/libxc/xc_private.h	Thu Sep 01 10:08:53 2005 +0000
   465.2 +++ b/tools/libxc/xc_private.h	Thu Sep 01 10:16:14 2005 +0000
   465.3 @@ -59,6 +59,17 @@ static inline int do_xen_hypercall(int x
   465.4                        (unsigned long)hypercall);
   465.5  }
   465.6  
   465.7 +static inline int do_xen_version(int xc_handle, int cmd, void *dest)
   465.8 +{
   465.9 +    privcmd_hypercall_t hypercall;
  465.10 +
  465.11 +    hypercall.op     = __HYPERVISOR_xen_version;
  465.12 +    hypercall.arg[0] = (unsigned long) cmd;
  465.13 +    hypercall.arg[1] = (unsigned long) dest;
  465.14 +    
  465.15 +    return do_xen_hypercall(xc_handle, &hypercall);
  465.16 +}
  465.17 +
  465.18  static inline int do_dom0_op(int xc_handle, dom0_op_t *op)
  465.19  {
  465.20      int ret = -1;
   468.1 --- a/tools/libxc/xenctrl.h	Thu Sep 01 10:08:53 2005 +0000
   468.2 +++ b/tools/libxc/xenctrl.h	Thu Sep 01 10:16:14 2005 +0000
   468.3 @@ -23,6 +23,7 @@ typedef int64_t            s64;
   468.4  #include <sys/ptrace.h>
   468.5  #include <xen/xen.h>
   468.6  #include <xen/dom0_ops.h>
   468.7 +#include <xen/version.h>
   468.8  #include <xen/event_channel.h>
   468.9  #include <xen/sched_ctl.h>
  468.10  #include <xen/acm.h>
  468.11 @@ -497,6 +498,8 @@ long xc_get_tot_pages(int xc_handle, u32
  468.12  /* Execute a privileged dom0 operation. */
  468.13  int xc_dom0_op(int xc_handle, dom0_op_t *op);
  468.14  
  468.15 +int xc_version(int xc_handle, int cmd, void *arg);
  468.16 +
  468.17  /* Initializes the store (for dom0)
  468.18     remote_port should be the remote end of a bound interdomain channel between
  468.19     the store and dom0.
   484.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Thu Sep 01 10:08:53 2005 +0000
   484.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Thu Sep 01 10:16:14 2005 +0000
   484.3 @@ -707,6 +707,39 @@ static PyObject *pyxc_physinfo(PyObject 
   484.4                           "cpu_khz",          info.cpu_khz);
   484.5  }
   484.6  
   484.7 +static PyObject *pyxc_xeninfo(PyObject *self,
   484.8 +                              PyObject *args,
   484.9 +                              PyObject *kwds)
  484.10 +{
  484.11 +    XcObject *xc = (XcObject *)self;
  484.12 +    xen_extraversion_t xen_extra;
  484.13 +    xen_compile_info_t xen_cc;
  484.14 +    xen_changeset_info_t xen_chgset;
  484.15 +    long xen_version;
  484.16 +
  484.17 +    xen_version = xc_version(xc->xc_handle, XENVER_version, NULL);
  484.18 +
  484.19 +    if ( xc_version(xc->xc_handle, XENVER_extraversion, &xen_extra) != 0 )
  484.20 +        return PyErr_SetFromErrno(xc_error);
  484.21 +
  484.22 +    if ( xc_version(xc->xc_handle, XENVER_compile_info, &xen_cc) != 0 )
  484.23 +        return PyErr_SetFromErrno(xc_error);
  484.24 +
  484.25 +    if ( xc_version(xc->xc_handle, XENVER_changeset, &xen_chgset) != 0 )
  484.26 +        return PyErr_SetFromErrno(xc_error);
  484.27 +
  484.28 +    return Py_BuildValue("{s:i,s:i,s:s,s:s,s:s,s:s,s:s,s:s}",
  484.29 +                         "xen_major", xen_version >> 16,
  484.30 +                         "xen_minor", (xen_version & 0xffff),
  484.31 +                         "xen_extra", xen_extra,
  484.32 +                         "xen_changeset", xen_chgset,
  484.33 +                         "cc_compiler", xen_cc.compiler,
  484.34 +                         "cc_compile_by", xen_cc.compile_by,
  484.35 +                         "cc_compile_domain", xen_cc.compile_domain,
  484.36 +                         "cc_compile_date", xen_cc.compile_date);
  484.37 +}
  484.38 +
  484.39 +
  484.40  static PyObject *pyxc_sedf_domain_set(PyObject *self,
  484.41                                           PyObject *args,
  484.42                                           PyObject *kwds)
  484.43 @@ -1089,6 +1122,13 @@ static PyMethodDef pyxc_methods[] = {
  484.44        "Returns [dict]: information about the hardware"
  484.45        "        [None]: on failure.\n" },
  484.46  
  484.47 +    { "xeninfo",
  484.48 +      (PyCFunction)pyxc_xeninfo,
  484.49 +      METH_VARARGS, "\n"
  484.50 +      "Get information about the Xen host\n"
  484.51 +      "Returns [dict]: information about Xen"
  484.52 +      "        [None]: on failure.\n" },
  484.53 +
  484.54      { "shadow_control", 
  484.55        (PyCFunction)pyxc_shadow_control, 
  484.56        METH_VARARGS | METH_KEYWORDS, "\n"
   518.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Thu Sep 01 10:08:53 2005 +0000
   518.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Thu Sep 01 10:16:14 2005 +0000
   518.3 @@ -269,6 +269,7 @@ class XendDomainInfo:
   518.4          self.blkif_backend = False
   518.5          self.netif_backend = False
   518.6          self.netif_idx = 0
   518.7 +        self.tpmif_backend = False
   518.8          
   518.9          #todo: state: running, suspended
  518.10          self.state = STATE_VM_OK
  518.11 @@ -458,6 +459,31 @@ class XendDomainInfo:
  518.12  
  518.13              return
  518.14          
  518.15 +        if type == 'vtpm':
  518.16 +            backdom = domain_exists(sxp.child_value(devconfig, 'backend', '0'))
  518.17 +
  518.18 +            devnum = int(sxp.child_value(devconfig, 'instance', '0'))
  518.19 +            log.error("The domain has a TPM with instance %d." % devnum)
  518.20 +
  518.21 +            # create backend db
  518.22 +            backdb = backdom.db.addChild("/backend/%s/%s/%d" %
  518.23 +                                         (type, self.uuid, devnum))
  518.24 +            # create frontend db
  518.25 +            db = self.db.addChild("/device/%s/%d" % (type, devnum))
  518.26 +
  518.27 +            backdb['frontend'] = db.getPath()
  518.28 +            backdb['frontend-id'] = "%i" % self.id
  518.29 +            backdb['instance'] = sxp.child_value(devconfig, 'instance', '0')
  518.30 +            backdb.saveDB(save=True)
  518.31 +
  518.32 +            db['handle'] = "%i" % devnum
  518.33 +            db['backend'] = backdb.getPath()
  518.34 +            db['backend-id'] = "%i" % int(sxp.child_value(devconfig,
  518.35 +                                                          'backend', '0'))
  518.36 +            db.saveDB(save=True)
  518.37 +
  518.38 +            return
  518.39 +
  518.40          ctrl = self.findDeviceController(type)
  518.41          return ctrl.createDevice(devconfig, recreate=self.recreate,
  518.42                                   change=change)
  518.43 @@ -779,6 +805,11 @@ class XendDomainInfo:
  518.44                  for dev in typedb.keys():
  518.45                      typedb[dev].delete()
  518.46                  typedb.saveDB(save=True)
  518.47 +            if type == 'vtpm':
  518.48 +                typedb = ddb.addChild(type)
  518.49 +                for dev in typedb.keys():
  518.50 +                    typedb[dev].delete()
  518.51 +                typedb.saveDB(save=True)
  518.52  
  518.53      def show(self):
  518.54          """Print virtual machine info.
  518.55 @@ -1018,6 +1049,8 @@ class XendDomainInfo:
  518.56                  self.netif_backend = True
  518.57              elif name == 'usbif':
  518.58                  self.usbif_backend = True
  518.59 +            elif name == 'tpmif':
  518.60 +                self.tpmif_backend = True
  518.61              else:
  518.62                  raise VmError('invalid backend type:' + str(name))
  518.63  
  518.64 @@ -1189,6 +1222,10 @@ from server import netif
  518.65  controller.addDevControllerClass("vif", netif.NetifController)
  518.66  add_device_handler("vif", "vif")
  518.67  
  518.68 +from server import tpmif
  518.69 +controller.addDevControllerClass("vtpm", tpmif.TPMifController)
  518.70 +add_device_handler("vtpm", "vtpm")
  518.71 +
  518.72  from server import pciif
  518.73  controller.addDevControllerClass("pci", pciif.PciController)
  518.74  add_device_handler("pci", "pci")
   521.1 --- a/tools/python/xen/xend/XendNode.py	Thu Sep 01 10:08:53 2005 +0000
   521.2 +++ b/tools/python/xen/xend/XendNode.py	Thu Sep 01 10:16:14 2005 +0000
   521.3 @@ -46,7 +46,7 @@ class XendNode:
   521.4          return self.xc.bvtsched_global_get()
   521.5      
   521.6      def info(self):
   521.7 -        return self.nodeinfo() + self.physinfo()
   521.8 +        return self.nodeinfo() + self.physinfo() + self.xeninfo()
   521.9  
  521.10      def nodeinfo(self):
  521.11          (sys, host, rel, ver, mch) = os.uname()
  521.12 @@ -65,7 +65,16 @@ class XendNode:
  521.13                  ['free_memory', pinfo['free_pages']/256]]
  521.14          return info
  521.15          
  521.16 -        
  521.17 +    def xeninfo(self):
  521.18 +        xinfo = self.xc.xeninfo()
  521.19 +	return [['xen_major', xinfo['xen_major']],
  521.20 +	        ['xen_minor', xinfo['xen_minor']],
  521.21 +	        ['xen_extra', xinfo['xen_extra']],
  521.22 +		['xen_changeset', xinfo['xen_changeset']],
  521.23 +		['cc_compiler', xinfo['cc_compiler']],
  521.24 +                ['cc_compile_by', xinfo['cc_compile_by']],
  521.25 +                ['cc_compile_domain', xinfo['cc_compile_domain']],
  521.26 +                ['cc_compile_date', xinfo['cc_compile_date']]]
  521.27  
  521.28  def instance():
  521.29      global inst
   526.1 --- a/tools/python/xen/xend/image.py	Thu Sep 01 10:08:53 2005 +0000
   526.2 +++ b/tools/python/xen/xend/image.py	Thu Sep 01 10:16:14 2005 +0000
   526.3 @@ -32,6 +32,9 @@ SIF_BLK_BE_DOMAIN = (1<<4)
   526.4  """Flag for a net device backend domain."""
   526.5  SIF_NET_BE_DOMAIN = (1<<5)
   526.6  
   526.7 +"""Flag for a TPM device backend domain."""
   526.8 +SIF_TPM_BE_DOMAIN = (1<<7)
   526.9 +
  526.10  class ImageHandler:
  526.11      """Abstract base class for image handlers.
  526.12  
  526.13 @@ -194,6 +197,7 @@ class ImageHandler:
  526.14          self.flags = 0
  526.15          if self.vm.netif_backend: self.flags |= SIF_NET_BE_DOMAIN
  526.16          if self.vm.blkif_backend: self.flags |= SIF_BLK_BE_DOMAIN
  526.17 +        if self.vm.tpmif_backend: self.flags |= SIF_TPM_BE_DOMAIN
  526.18  
  526.19          if self.vm.recreate or self.vm.restore:
  526.20              return
  526.21 @@ -366,6 +370,11 @@ class VmxImageHandler(ImageHandler):
  526.22                 mac = sxp.child_value(vifinfo, 'mac')
  526.23                 ret.append("-macaddr")
  526.24                 ret.append("%s" % mac)
  526.25 +            if name == 'vtpm':
  526.26 +               vtpminfo = sxp.child(device, 'vtpm')
  526.27 +               instance = sxp.child_value(vtpminfo, 'instance')
  526.28 +               ret.append("-instance")
  526.29 +               ret.append("%s" % instance)
  526.30  
  526.31  	# Handle graphics library related options
  526.32  	vnc = sxp.child_value(self.vm.config, 'vnc')
   546.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   546.2 +++ b/tools/python/xen/xend/server/tpmif.py	Thu Sep 01 10:16:14 2005 +0000
   546.3 @@ -0,0 +1,52 @@
   546.4 +# Copyright (C) 2005 IBM Corporation
   546.5 +#   Authort: Stefan Berger, stefanb@us.ibm.com
   546.6 +# Derived from netif.py:
   546.7 +# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
   546.8 +"""Support for virtual TPM interfaces.
   546.9 +"""
  546.10 +
  546.11 +import random
  546.12 +
  546.13 +from xen.xend import sxp
  546.14 +from xen.xend.XendError import XendError, VmError
  546.15 +from xen.xend.XendLogging import log
  546.16 +from xen.xend.XendRoot import get_component
  546.17 +from xen.xend.xenstore import DBVar
  546.18 +
  546.19 +from xen.xend.server import channel
  546.20 +from xen.xend.server.controller import CtrlMsgRcvr, Dev, DevController
  546.21 +from xen.xend.server.messages import *
  546.22 +
  546.23 +class TPMifController(DevController):
  546.24 +    """TPM interface controller. Handles all TPM devices for a domain.
  546.25 +    """
  546.26 +
  546.27 +    def __init__(self, vm, recreate=False):
  546.28 +        DevController.__init__(self, vm, recreate=recreate)
  546.29 +        self.rcvr = None
  546.30 +        self.channel = None
  546.31 +
  546.32 +    def initController(self, recreate=False, reboot=False):
  546.33 +        self.destroyed = False
  546.34 +        self.channel = self.getChannel()
  546.35 +
  546.36 +    def destroyController(self, reboot=False):
  546.37 +        """Destroy the controller and all devices.
  546.38 +        """
  546.39 +        self.destroyed = True
  546.40 +        self.destroyDevices(reboot=reboot)
  546.41 +        if self.rcvr:
  546.42 +            self.rcvr.deregisterChannel()
  546.43 +
  546.44 +    def sxpr(self):
  546.45 +        val = ['tpmif', ['dom', self.getDomain()]]
  546.46 +        return val
  546.47 +
  546.48 +    def newDevice(self, id, config, recreate=False):
  546.49 +        """Create a TPM device.
  546.50 +
  546.51 +        @param id: interface id
  546.52 +        @param config: device configuration
  546.53 +        @param recreate: recreate flag (true after xend restart)
  546.54 +        """
  546.55 +        return None
   553.1 --- a/tools/python/xen/xm/create.py	Thu Sep 01 10:08:53 2005 +0000
   553.2 +++ b/tools/python/xen/xm/create.py	Thu Sep 01 10:16:14 2005 +0000
   553.3 @@ -176,6 +176,12 @@ gopts.var('netif', val='no|yes',
   553.4            fn=set_bool, default=0,
   553.5            use="Make the domain a network interface backend.")
   553.6  
   553.7 +gopts.var('tpmif', val='frontend=DOM',
   553.8 +          fn=append_value, default=[],
   553.9 +          use="""Make the domain a TPM interface backend. If frontend is given,
  553.10 +          the frontend in that domain is connected to this backend (not
  553.11 +          completely implemented, yet)""")
  553.12 +
  553.13  gopts.var('disk', val='phy:DEV,VDEV,MODE[,DOM]',
  553.14            fn=append_value, default=[],
  553.15            use="""Add a disk device to a domain. The physical device is DEV,
  553.16 @@ -214,6 +220,12 @@ gopts.var('vif', val="mac=MAC,be_mac=MAC
  553.17            This option may be repeated to add more than one vif.
  553.18            Specifying vifs will increase the number of interfaces as needed.""")
  553.19  
  553.20 +gopts.var('vtpm', val="instance=INSTANCE,backend=DOM",
  553.21 +          fn=append_value, default=[],
  553.22 +          use="""Add a tpm interface. On the backend side us the the given
  553.23 +          instance as virtual TPM instance. Use the backend in the given
  553.24 +          domain.""")
  553.25 +
  553.26  gopts.var('nics', val="NUM",
  553.27            fn=set_int, default=1,
  553.28            use="""Set the number of network interfaces.
  553.29 @@ -374,6 +386,46 @@ def configure_usb(opts, config_devs, val
  553.30          config_usb = ['usb', ['path', path]]
  553.31          config_devs.append(['device', config_usb])
  553.32  
  553.33 +def configure_vtpm(opts, config_devs, vals):
  553.34 +    """Create the config for virtual TPM interfaces.
  553.35 +    """
  553.36 +    vtpm = vals.vtpm
  553.37 +    vtpm_n = 1
  553.38 +    for idx in range(0, vtpm_n):
  553.39 +        if idx < len(vtpm):
  553.40 +            d = vtpm[idx]
  553.41 +            instance = d.get('instance')
  553.42 +            if instance == "VTPMD":
  553.43 +                instance = "0"
  553.44 +            else:
  553.45 +                try:
  553.46 +                    if int(instance) == 0:
  553.47 +                        opts.err('VM config error: vTPM instance must not be 0.')
  553.48 +                except ValueError:
  553.49 +                    opts.err('Vm config error: could not parse instance number.')
  553.50 +            backend = d.get('backend')
  553.51 +            config_vtpm = ['vtpm']
  553.52 +            if instance:
  553.53 +                config_vtpm.append(['instance', instance])
  553.54 +            if backend:
  553.55 +                config_vtpm.append(['backend', backend])
  553.56 +            config_devs.append(['device', config_vtpm])
  553.57 +
  553.58 +def configure_tpmif(opts, config_devs, vals):
  553.59 +    """Create the config for virtual TPM interfaces.
  553.60 +    """
  553.61 +    tpmif = vals.tpmif
  553.62 +    tpmif_n = 1
  553.63 +    for idx in range(0, tpmif_n):
  553.64 +        if idx < len(tpmif):
  553.65 +            d = tpmif[idx]
  553.66 +            frontend = d.get('frontend')
  553.67 +            config_tpmif = ['tpmif']
  553.68 +            if frontend:
  553.69 +                config_tpmif.append(['frontend', frontend])
  553.70 +            config_devs.append(['device', config_tpmif])
  553.71 +
  553.72 +
  553.73  def randomMAC():
  553.74      """Generate a random MAC address.
  553.75  
  553.76 @@ -484,6 +536,8 @@ def make_config(opts, vals):
  553.77          config.append(['backend', ['blkif']])
  553.78      if vals.netif:
  553.79          config.append(['backend', ['netif']])
  553.80 +    if vals.tpmif:
  553.81 +        config.append(['backend', ['tpmif']])
  553.82      if vals.restart:
  553.83          config.append(['restart', vals.restart])
  553.84  
  553.85 @@ -496,6 +550,7 @@ def make_config(opts, vals):
  553.86      configure_pci(opts, config_devs, vals)
  553.87      configure_vifs(opts, config_devs, vals)
  553.88      configure_usb(opts, config_devs, vals)
  553.89 +    configure_vtpm(opts, config_devs, vals)
  553.90      configure_vmx(opts, config_devs, vals)
  553.91      config += config_devs
  553.92  
  553.93 @@ -544,6 +599,38 @@ def preprocess_vifs(opts, vals):
  553.94          vifs.append(d)
  553.95      vals.vif = vifs
  553.96  
  553.97 +def preprocess_vtpm(opts, vals):
  553.98 +    if not vals.vtpm: return
  553.99 +    vtpms = []
 553.100 +    for vtpm in vals.vtpm:
 553.101 +        d = {}
 553.102 +        a = vtpm.split(',')
 553.103 +        for b in a:
 553.104 +            (k, v) = b.strip().split('=', 1)
 553.105 +            k = k.strip()
 553.106 +            v = v.strip()
 553.107 +            if k not in ['backend', 'instance']:
 553.108 +                opts.err('Invalid vtpm specifier: ' + vtpm)
 553.109 +            d[k] = v
 553.110 +        vtpms.append(d)
 553.111 +    vals.vtpm = vtpms
 553.112 +
 553.113 +def preprocess_tpmif(opts, vals):
 553.114 +    if not vals.tpmif: return
 553.115 +    tpmifs = []
 553.116 +    for tpmif in vals.tpmif:
 553.117 +        d = {}
 553.118 +        a = tpmif.split(',')
 553.119 +        for b in a:
 553.120 +            (k, v) = b.strip().split('=', 1)
 553.121 +            k = k.strip()
 553.122 +            v = v.strip()
 553.123 +            if k not in ['frontend']:
 553.124 +                opts.err('Invalid tpmif specifier: ' + vtpm)
 553.125 +            d[k] = v
 553.126 +        tpmifs.append(d)
 553.127 +    vals.tpmif = tpmifs
 553.128 +
 553.129  def preprocess_ip(opts, vals):
 553.130      if vals.ip or vals.dhcp != 'off':
 553.131          dummy_nfs_server = '1.2.3.4'
 553.132 @@ -632,6 +719,8 @@ def preprocess(opts, vals):
 553.133      preprocess_ip(opts, vals)
 553.134      preprocess_nfs(opts, vals)
 553.135      preprocess_vnc(opts, vals)
 553.136 +    preprocess_vtpm(opts, vals)
 553.137 +    preprocess_tpmif(opts, vals)
 553.138           
 553.139  def make_domain(opts, config):
 553.140      """Create, build and start a domain.
   641.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   641.2 +++ b/tools/vtpm/Makefile	Thu Sep 01 10:16:14 2005 +0000
   641.3 @@ -0,0 +1,63 @@
   641.4 +XEN_ROOT = ../..
   641.5 +
   641.6 +# Base definitions and rules
   641.7 +include $(XEN_ROOT)/tools/vtpm/Rules.mk
   641.8 +
   641.9 +# Dir name for emulator (as dom0 tpm driver)
  641.10 +TPM_EMULATOR_DIR = tpm_emulator-0.2
  641.11 +# Dir name for vtpm instance
  641.12 +VTPM_DIR = vtpm
  641.13 +
  641.14 +# Emulator tarball name
  641.15 +TPM_EMULATOR_TARFILE = tpm_emulator-0.2b.tar.gz
  641.16 +
  641.17 +all: build
  641.18 +
  641.19 +build: $(TPM_EMULATOR_TARFILE) extract patch build_sub
  641.20 +
  641.21 +install: build
  641.22 +	$(MAKE) -C $(TPM_EMULATOR_DIR) $@
  641.23 +	$(MAKE) -C $(VTPM_DIR) $@
  641.24 +
  641.25 +clean:
  641.26 +	if [ -d $(TPM_EMULATOR_DIR) ]; \
  641.27 +		then $(MAKE) -C $(TPM_EMULATOR_DIR) clean; \
  641.28 +	fi
  641.29 +	if [ -d $(VTPM_DIR) ]; \
  641.30 +		then $(MAKE) -C $(VTPM_DIR) clean; \
  641.31 +	fi
  641.32 +	rm -rf $(TPM_EMULATOR_DIR)
  641.33 +	rm -rf $(VTPM_DIR)
  641.34 +
  641.35 +mrproper: clean
  641.36 +	rm -f $(TPM_EMULATOR_TARFILE)
  641.37 +
  641.38 +# Download Swiss emulator
  641.39 +$(TPM_EMULATOR_TARFILE):
  641.40 +	wget http://download.berlios.de/tpm-emulator/$(TPM_EMULATOR_TARFILE)
  641.41 +
  641.42 +# Create vtpm and TPM emulator dirs
  641.43 +extract: $(TPM_EMULATOR_DIR)/README $(VTPM_DIR)/README
  641.44 +
  641.45 +$(TPM_EMULATOR_DIR)/README:
  641.46 +	-rm -rf $(TPM_EMULATOR_DIR)
  641.47 +	tar -xzf $(TPM_EMULATOR_TARFILE)
  641.48 +
  641.49 +$(VTPM_DIR)/README:
  641.50 +	-rm -rf $(VTPM_DIR)
  641.51 +	cp -r --preserve $(TPM_EMULATOR_DIR) $(VTPM_DIR)
  641.52 +
  641.53 +# apply patches for 1) used as dom0 tpm driver 2) used as vtpm device instance
  641.54 +patch: $(TPM_EMULATOR_DIR)/Makefile $(VTPM_DIR)/Makefile
  641.55 +
  641.56 +$(TPM_EMULATOR_DIR)/Makefile: tpm_emulator.patch
  641.57 +	-cd $(TPM_EMULATOR_DIR); \
  641.58 +	patch -p1 <../tpm_emulator.patch
  641.59 +
  641.60 +$(VTPM_DIR)/Makefile: vtpm.patch
  641.61 +	-cd $(VTPM_DIR); \
  641.62 +	patch -p1 <../vtpm.patch
  641.63 +
  641.64 +build_sub:
  641.65 +	$(MAKE) -C $(TPM_EMULATOR_DIR)
  641.66 +	$(MAKE) -C $(VTPM_DIR)
   642.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   642.2 +++ b/tools/vtpm/README	Thu Sep 01 10:16:14 2005 +0000
   642.3 @@ -0,0 +1,44 @@
   642.4 +
   642.5 +Directory Structure
   642.6 +===================
   642.7 +tools/vtpm/tpm_emulator-0.2b.tar.gz    -> TPM Emulator downloaded at build time that will
   642.8 +                                          be patched and used for our vtpms
   642.9 +tools/vtpm/vtpm.patch                  -> patch applied to tpm_emulator to make vtpm
  642.10 +tools/vtpm/vtpm/                       -> (created on build) tpm_emulator moved to ring 3,
  642.11 +                                          listens on a pair of fifos for TPM commands,
  642.12 +                                          persistent state is sent via named fifo to vtpm
  642.13 +                                            manager, which encrypts it and protects it.
  642.14 +tools/vtpm/tpm_emulator.patch          -> To allow for debugging and testing on non-TPM
  642.15 +                                          platforms, this patches the emulator to allow
  642.16 +                                          it to be inserted into the dom0 kernel
  642.17 +tools/vtpm/tpm_emulator-0.2            -> (created on build) directory containing patched emulator
  642.18 +
  642.19 +Compile Flags
  642.20 +===================
  642.21 +VTPM_MULTI_VM                -> Defined (not finished): VTPMs run in their own VMs
  642.22 +                                Not Defined (default): VTPMs are processes
  642.23 +
  642.24 +Requirements
  642.25 +============
  642.26 +- xen-unstable 
  642.27 +- IBM frontend/backend vtpm driver patch
  642.28 +- vtpm_managerd
  642.29 +
  642.30 +vtpmd Flow (for vtpm_manager. vtpmd never run by default)
  642.31 +============================
  642.32 +- Launch the VTPM manager (vtpm_managerd) which which begins listening to the BE with one thread
  642.33 +  and listens to a named fifo that is shared by the vtpms to commuincate with the manager.
  642.34 +- VTPM Manager listens to TPM BE.
  642.35 +- When xend launches a tpm frontend equipped VM it contacts the manager over the vtpm backend. 
  642.36 +- When the manager receives the open message from the BE, it launches a vtpm
  642.37 +- Xend allows the VM to continue booting. 
  642.38 +- When a TPM request is issued to the front end, the front end transmits the TPM request to the backend.
  642.39 +- The manager receives the TPM requests and uses a named fifo to forward the request to the vtpm.
  642.40 +- The fifo listener begins listening for the reply from vtpm for the request.
  642.41 +- Vtpm processes request and replies to manager over shared named fifo.
  642.42 +- If needed, the vtpm may send a request to the vtpm_manager at any time to save it's secrets to disk.
  642.43 +- Manager receives response from vtpm and passes it back to backend for forwarding to guest.
  642.44 +
  642.45 +tpm_emulator flow
  642.46 +==================
  642.47 +Read documentation in tpm_emulator-0.2 directory
   643.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   643.2 +++ b/tools/vtpm/Rules.mk	Thu Sep 01 10:16:14 2005 +0000
   643.3 @@ -0,0 +1,37 @@
   643.4 +# Base definitions and rules (XEN_ROOT must be defined in including Makefile)
   643.5 +include $(XEN_ROOT)/tools/Rules.mk
   643.6 +
   643.7 +#
   643.8 +# Tool definitions
   643.9 +#
  643.10 +
  643.11 +# Installation program and options
  643.12 +INSTALL         = install
  643.13 +INSTALL_PROG    = $(INSTALL) -m0755
  643.14 +INSTALL_DIR     = $(INSTALL) -d -m0755
  643.15 +
  643.16 +# Xen tools installation directory
  643.17 +TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
  643.18 +
  643.19 +# General compiler flags
  643.20 +CFLAGS   = -Wall -Werror -g3 -I.
  643.21 +
  643.22 +# For generating dependencies
  643.23 +CFLAGS	+= -Wp,-MD,.$(@F).d
  643.24 +
  643.25 +DEP_FILES	= .*.d
  643.26 +
  643.27 +# Generic project files
  643.28 +HDRS	= $(wildcard *.h)
  643.29 +SRCS	= $(wildcard *.c)
  643.30 +OBJS	= $(patsubst %.c,%.o,$(SRCS))
  643.31 +
  643.32 +# Generic (non-header) dependencies
  643.33 +$(SRCS): Makefile $(XEN_ROOT)/tools/Rules.mk $(XEN_ROOT)/tools/vtpm/Rules.mk
  643.34 +
  643.35 +$(OBJS): $(SRCS)
  643.36 +
  643.37 +-include $(DEP_FILES)
  643.38 +
  643.39 +# Make sure these are just rules
  643.40 +.PHONY : all build install clean
   644.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   644.2 +++ b/tools/vtpm/tpm_emulator.patch	Thu Sep 01 10:16:14 2005 +0000
   644.3 @@ -0,0 +1,151 @@
   644.4 +diff -uprN orig/tpm_emulator-0.2/AUTHORS tpm_emulator-0.2/AUTHORS
   644.5 +--- orig/tpm_emulator-0.2/AUTHORS	2005-08-17 10:58:36.000000000 -0700
   644.6 ++++ tpm_emulator-0.2/AUTHORS	2005-08-17 10:55:52.000000000 -0700
   644.7 +@@ -1 +1,2 @@
   644.8 + Mario Strasser <mast@gmx.net>
   644.9 ++INTEL Corp <>
  644.10 +diff -uprN orig/tpm_emulator-0.2/ChangeLog tpm_emulator-0.2/ChangeLog
  644.11 +--- orig/tpm_emulator-0.2/ChangeLog	2005-08-17 10:58:36.000000000 -0700
  644.12 ++++ tpm_emulator-0.2/ChangeLog	2005-08-17 10:55:52.000000000 -0700
  644.13 +@@ -1,3 +1,7 @@
  644.14 ++2005-08-16: INTEL Corp
  644.15 ++	* Set default permissions to PCRs
  644.16 ++	* Changed device to /dev/tpm0
  644.17 ++
  644.18 + 2005-08-15  Mario Strasser <mast@gmx.net>
  644.19 + 	* all: some typos corrected
  644.20 + 	* tpm_integrity.c: bug in TPM_Extend fixed
  644.21 +diff -uprN orig/tpm_emulator-0.2/Makefile tpm_emulator-0.2/Makefile
  644.22 +--- orig/tpm_emulator-0.2/Makefile	2005-08-17 10:58:36.000000000 -0700
  644.23 ++++ tpm_emulator-0.2/Makefile	2005-08-17 10:55:52.000000000 -0700
  644.24 +@@ -1,15 +1,19 @@
  644.25 + # Software-Based Trusted Platform Module (TPM) Emulator for Linux
  644.26 + # Copyright (C) 2004 Mario Strasser <mast@gmx.net>
  644.27 ++# Copyright (C) 2005 INTEL Corp.
  644.28 + #
  644.29 + # $Id: Makefile 10 2005-04-26 20:59:50Z mast $
  644.30 + 
  644.31 ++XEN_ROOT       := ../../..
  644.32 ++EUID           := $(shell id -u)
  644.33 ++
  644.34 + # kernel settings
  644.35 + KERNEL_RELEASE := $(shell uname -r)
  644.36 +-KERNEL_BUILD   := /lib/modules/$(KERNEL_RELEASE)/build
  644.37 ++KERNEL_BUILD   := $(XEN_ROOT)/linux-2.6.12-xen0
  644.38 + MOD_SUBDIR     := misc
  644.39 + 
  644.40 + # module settings
  644.41 +-MODULE_NAME    := tpm_emulator
  644.42 ++BIN            := tpm_emulator
  644.43 + VERSION_MAJOR  := 0
  644.44 + VERSION_MINOR  := 2
  644.45 + VERSION_BUILD  := $(shell date +"%s")
  644.46 +@@ -27,11 +30,9 @@ DIRS           := . crypto tpm 
  644.47 + SRCS           := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c))
  644.48 + OBJS           := $(patsubst %.c, %.o, $(SRCS))
  644.49 + SRCS           += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h))
  644.50 +-DISTSRC        := ./README ./AUTHORS ./ChangeLog ./Makefile $(SRCS)
  644.51 +-DISTDIR        := tpm_emulator-$(VERSION_MAJOR).$(VERSION_MINOR)
  644.52 + 
  644.53 +-obj-m               := $(MODULE_NAME).o
  644.54 +-$(MODULE_NAME)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
  644.55 ++obj-m               := $(BIN).o
  644.56 ++$(BIN)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
  644.57 + 
  644.58 + EXTRA_CFLAGS   += -I$(src) -I$(src)/crypto -I$(src)/tpm 
  644.59 + 
  644.60 +@@ -42,23 +43,17 @@ all:	$(src)/crypto/gmp.h $(src)/crypto/l
  644.61 + 	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
  644.62 + 
  644.63 + install:
  644.64 +-	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules_install
  644.65 +-	test -d /var/tpm || mkdir /var/tpm
  644.66 +-	test -c /dev/tpm || mknod /dev/tpm c 10 224
  644.67 +-	chmod 666 /dev/tpm
  644.68 +-	depmod -a
  644.69 ++	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) INSTALL_MOD_PATH=$(DESTDIR) modules_install
  644.70 ++	test -d $(DESTDIR)/var/tpm || mkdir $(DESTDIR)/var/tpm
  644.71 ++	test -d $(DESTDIR)/dev || mkdir $(DESTDIR)/dev
  644.72 ++	test -c $(DESTDIR)/dev/tpm0 || [ $(EUID) -ne 0 ] || mknod $(DESTDIR)/dev/tpm0 c 10 224
  644.73 ++	[ $(EUID) -ne 0 ] || chmod 666 $(DESTDIR)/dev/tpm0
  644.74 + 
  644.75 + clean:
  644.76 + 	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
  644.77 + 	rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a
  644.78 + 
  644.79 +-dist:	$(DISTSRC)
  644.80 +-	rm -rf $(DISTDIR)
  644.81 +-	mkdir $(DISTDIR)
  644.82 +-	cp --parents $(DISTSRC) $(DISTDIR)/
  644.83 +-	rm -f $(DISTDIR)/crypto/gmp.h 
  644.84 +-	tar -chzf $(DISTDIR).tar.gz $(DISTDIR)
  644.85 +-	rm -rf $(DISTDIR)
  644.86 ++mrproper: clean
  644.87 + 
  644.88 + $(src)/crypto/libgmp.a:
  644.89 + 	test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB) $(src)/crypto/libgmp.a
  644.90 +diff -uprN orig/tpm_emulator-0.2/README tpm_emulator-0.2/README
  644.91 +--- orig/tpm_emulator-0.2/README	2005-08-17 10:58:36.000000000 -0700
  644.92 ++++ tpm_emulator-0.2/README	2005-08-17 10:55:52.000000000 -0700
  644.93 +@@ -13,7 +13,8 @@ $Id: README 8 2005-01-25 21:11:45Z jmoli
  644.94 + Copyright
  644.95 + --------------------------------------------------------------------------
  644.96 + Copyright (C) 2004 Mario Strasser <mast@gmx.net> and Swiss Federal 
  644.97 +-Institute of Technology (ETH) Zurich.
  644.98 ++                   Institute of Technology (ETH) Zurich.
  644.99 ++Copyright (C) 2005 
 644.100 +               
 644.101 + This program is free software; you can redistribute it and/or modify
 644.102 + it under the terms of the GNU General Public License as published by
 644.103 +diff -uprN orig/tpm_emulator-0.2/linux_module.h tpm_emulator-0.2/linux_module.h
 644.104 +--- orig/tpm_emulator-0.2/linux_module.h	2005-08-17 10:58:36.000000000 -0700
 644.105 ++++ tpm_emulator-0.2/linux_module.h	2005-08-17 10:55:52.000000000 -0700
 644.106 +@@ -1,5 +1,6 @@
 644.107 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 644.108 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 644.109 ++ * Copyright (C) 2005 INTEL Corp.
 644.110 +  *
 644.111 +  * This module is free software; you can redistribute it and/or modify
 644.112 +  * it under the terms of the GNU General Public License as published
 644.113 +@@ -33,7 +34,7 @@
 644.114 + #include "tpm_version.h"
 644.115 + 
 644.116 + #define TPM_DEVICE_MINOR	224
 644.117 +-#define TPM_DEVICE_NAME         "tpm"
 644.118 ++#define TPM_DEVICE_NAME         "tpm0"
 644.119 + #define TPM_MODULE_NAME 	"tpm_emulator"
 644.120 + 
 644.121 + /* debug and log output functions */
 644.122 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_data.c tpm_emulator-0.2/tpm/tpm_data.c
 644.123 +--- orig/tpm_emulator-0.2/tpm/tpm_data.c	2005-08-17 10:58:36.000000000 -0700
 644.124 ++++ tpm_emulator-0.2/tpm/tpm_data.c	2005-08-17 10:55:52.000000000 -0700
 644.125 +@@ -1,6 +1,7 @@
 644.126 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 644.127 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 644.128 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
 644.129 ++ * Copyright (C) 2005 INTEL Corp
 644.130 +  *
 644.131 +  * This module is free software; you can redistribute it and/or modify
 644.132 +  * it under the terms of the GNU General Public License as published
 644.133 +@@ -85,6 +86,11 @@ void tpm_init_data(void)
 644.134 +   tpmData.permanent.data.version.revMinor = VERSION_MINOR;
 644.135 +   /* setup PCR attributes */
 644.136 +   for (i = 0; i < TPM_NUM_PCR; i++) {
 644.137 ++    int j;
 644.138 ++    for (j=0; j < TPM_NUM_LOCALITY; j++) {
 644.139 ++      tpmData.permanent.data.pcrAttrib[i].pcrExtendLocal[j] = TRUE;
 644.140 ++    }
 644.141 ++
 644.142 +     tpmData.permanent.data.pcrAttrib[i].pcrReset = TRUE;
 644.143 +   }
 644.144 +   /* set tick type */
 644.145 +diff -uprN orig/tpm_emulator-0.2/tpm_version.h tpm_emulator-0.2/tpm_version.h
 644.146 +--- orig/tpm_emulator-0.2/tpm_version.h	2005-08-17 10:58:36.000000000 -0700
 644.147 ++++ tpm_emulator-0.2/tpm_version.h	2005-08-17 10:55:53.000000000 -0700
 644.148 +@@ -2,5 +2,5 @@
 644.149 + #define _TPM_VERSION_H_
 644.150 + #define VERSION_MAJOR 0
 644.151 + #define VERSION_MINOR 2
 644.152 +-#define VERSION_BUILD 1123950310
 644.153 ++#define VERSION_BUILD 1124301353
 644.154 + #endif /* _TPM_VERSION_H_ */
   645.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   645.2 +++ b/tools/vtpm/vtpm.patch	Thu Sep 01 10:16:14 2005 +0000
   645.3 @@ -0,0 +1,1645 @@
   645.4 +diff -uprN orig/tpm_emulator-0.2/AUTHORS vtpm/AUTHORS
   645.5 +--- orig/tpm_emulator-0.2/AUTHORS	2005-08-17 10:58:36.000000000 -0700
   645.6 ++++ vtpm/AUTHORS	2005-08-17 10:55:52.000000000 -0700
   645.7 +@@ -1 +1,2 @@
   645.8 + Mario Strasser <mast@gmx.net>
   645.9 ++INTEL Corp <>
  645.10 +diff -uprN orig/tpm_emulator-0.2/ChangeLog vtpm/ChangeLog
  645.11 +--- orig/tpm_emulator-0.2/ChangeLog	2005-08-17 10:58:36.000000000 -0700
  645.12 ++++ vtpm/ChangeLog	2005-08-17 10:55:52.000000000 -0700
  645.13 +@@ -1,3 +1,7 @@
  645.14 ++2005-08-16 Intel Corp
  645.15 ++	Moved module out of kernel to run as a ring 3 app
  645.16 ++	Modified save_to_file and load_from_file to call a xen backend driver to call a VTPM manager
  645.17 ++
  645.18 + 2005-08-15  Mario Strasser <mast@gmx.net>
  645.19 + 	* all: some typos corrected
  645.20 + 	* tpm_integrity.c: bug in TPM_Extend fixed
  645.21 +diff -uprN orig/tpm_emulator-0.2/Makefile vtpm/Makefile
  645.22 +--- orig/tpm_emulator-0.2/Makefile	2005-08-17 10:58:36.000000000 -0700
  645.23 ++++ vtpm/Makefile	2005-08-17 10:55:52.000000000 -0700
  645.24 +@@ -1,21 +1,29 @@
  645.25 + # Software-Based Trusted Platform Module (TPM) Emulator for Linux
  645.26 + # Copyright (C) 2004 Mario Strasser <mast@gmx.net>
  645.27 ++# Copyright (C) 2005 INTEL Corp.
  645.28 + #
  645.29 + # $Id: Makefile 10 2005-04-26 20:59:50Z mast $
  645.30 + 
  645.31 +-# kernel settings
  645.32 +-KERNEL_RELEASE := $(shell uname -r)
  645.33 +-KERNEL_BUILD   := /lib/modules/$(KERNEL_RELEASE)/build
  645.34 +-MOD_SUBDIR     := misc
  645.35 +-
  645.36 + # module settings
  645.37 +-MODULE_NAME    := tpm_emulator
  645.38 ++BIN            := vtpmd
  645.39 + VERSION_MAJOR  := 0
  645.40 + VERSION_MINOR  := 2
  645.41 + VERSION_BUILD  := $(shell date +"%s")
  645.42 + 
  645.43 +-# enable/disable DEBUG messages
  645.44 +-EXTRA_CFLAGS   += -DDEBUG -g  
  645.45 ++# Installation program and options
  645.46 ++INSTALL         = install
  645.47 ++INSTALL_PROG    = $(INSTALL) -m0755
  645.48 ++INSTALL_DIR     = $(INSTALL) -d -m0755
  645.49 ++
  645.50 ++# Xen tools installation directory
  645.51 ++TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
  645.52 ++
  645.53 ++CC      := gcc
  645.54 ++CFLAGS  += -g -Wall $(INCLUDE) -DDEBUG
  645.55 ++CFLAGS  += -I. -Itpm
  645.56 ++
  645.57 ++# Is the simulator running in it's own vm?
  645.58 ++#CFLAGS += -DVTPM_MULTI_VM
  645.59 + 
  645.60 + # GNU MP configuration
  645.61 + GMP_LIB        := /usr/lib/libgmp.a
  645.62 +@@ -27,38 +35,31 @@ DIRS           := . crypto tpm 
  645.63 + SRCS           := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c))
  645.64 + OBJS           := $(patsubst %.c, %.o, $(SRCS))
  645.65 + SRCS           += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h))
  645.66 +-DISTSRC        := ./README ./AUTHORS ./ChangeLog ./Makefile $(SRCS)
  645.67 +-DISTDIR        := tpm_emulator-$(VERSION_MAJOR).$(VERSION_MINOR)
  645.68 + 
  645.69 +-obj-m               := $(MODULE_NAME).o
  645.70 +-$(MODULE_NAME)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
  645.71 ++obj-m               := $(BIN)
  645.72 ++$(BIN)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
  645.73 + 
  645.74 + EXTRA_CFLAGS   += -I$(src) -I$(src)/crypto -I$(src)/tpm 
  645.75 + 
  645.76 + # do not print "Entering directory ..."
  645.77 + MAKEFLAGS      += --no-print-directory
  645.78 + 
  645.79 +-all:	$(src)/crypto/gmp.h $(src)/crypto/libgmp.a version
  645.80 +-	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
  645.81 ++all: $(BIN)
  645.82 ++
  645.83 ++$(BIN):	$(src)/crypto/gmp.h $(src)/crypto/libgmp.a version $(SRCS) $(OBJS)
  645.84 ++	$(CC) $(CFLAGS) $(OBJS) $(src)/crypto/libgmp.a -o $(BIN)
  645.85 ++
  645.86 ++%.o: %.c
  645.87 ++	$(CC) $(CFLAGS) -c $< -o $@
  645.88 + 
  645.89 + install:
  645.90 +-	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules_install
  645.91 +-	test -d /var/tpm || mkdir /var/tpm
  645.92 +-	test -c /dev/tpm || mknod /dev/tpm c 10 224
  645.93 +-	chmod 666 /dev/tpm
  645.94 +-	depmod -a
  645.95 ++	$(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR)
  645.96 + 
  645.97 + clean:
  645.98 +-	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
  645.99 +-	rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a
 645.100 ++	rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a $(OBJS)
 645.101 + 
 645.102 +-dist:	$(DISTSRC)
 645.103 +-	rm -rf $(DISTDIR)
 645.104 +-	mkdir $(DISTDIR)
 645.105 +-	cp --parents $(DISTSRC) $(DISTDIR)/
 645.106 +-	rm -f $(DISTDIR)/crypto/gmp.h 
 645.107 +-	tar -chzf $(DISTDIR).tar.gz $(DISTDIR)
 645.108 +-	rm -rf $(DISTDIR)
 645.109 ++mrproper: clean
 645.110 ++	rm -f $(BIN)
 645.111 + 
 645.112 + $(src)/crypto/libgmp.a:
 645.113 + 	test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB) $(src)/crypto/libgmp.a
 645.114 +diff -uprN orig/tpm_emulator-0.2/README vtpm/README
 645.115 +--- orig/tpm_emulator-0.2/README	2005-08-17 10:58:36.000000000 -0700
 645.116 ++++ vtpm/README	2005-08-17 10:55:52.000000000 -0700
 645.117 +@@ -13,7 +13,8 @@ $Id: README 8 2005-01-25 21:11:45Z jmoli
 645.118 + Copyright
 645.119 + --------------------------------------------------------------------------
 645.120 + Copyright (C) 2004 Mario Strasser <mast@gmx.net> and Swiss Federal 
 645.121 +-Institute of Technology (ETH) Zurich.
 645.122 ++                   Institute of Technology (ETH) Zurich.
 645.123 ++Copyright (C) 2005 INTEL Corp 
 645.124 +               
 645.125 + This program is free software; you can redistribute it and/or modify
 645.126 + it under the terms of the GNU General Public License as published by
 645.127 +diff -uprN orig/tpm_emulator-0.2/crypto/gmp_kernel_wrapper.c vtpm/crypto/gmp_kernel_wrapper.c
 645.128 +--- orig/tpm_emulator-0.2/crypto/gmp_kernel_wrapper.c	2005-08-17 10:58:36.000000000 -0700
 645.129 ++++ vtpm/crypto/gmp_kernel_wrapper.c	2005-08-17 10:55:52.000000000 -0700
 645.130 +@@ -1,5 +1,6 @@
 645.131 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 645.132 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 645.133 ++ * Copyright (C) 2005 INTEL Corp
 645.134 +  *
 645.135 +  * This module is free software; you can redistribute it and/or modify
 645.136 +  * it under the terms of the GNU General Public License as published
 645.137 +@@ -24,15 +25,10 @@ int __gmp_junk;
 645.138 + void __attribute__ ((regparm(0))) __gmp_assert_fail(const char *filename, 
 645.139 +   int linenum, const char *expr) 
 645.140 + {
 645.141 +-  panic(KERN_CRIT TPM_MODULE_NAME "%s:%d: GNU MP assertion failed: %s\n", 
 645.142 ++  error("%s:%d: GNU MP assertion failed: %s\n", 
 645.143 +     filename, linenum, expr);
 645.144 + }
 645.145 + 
 645.146 +-void __attribute__ ((regparm(0))) abort(void)
 645.147 +-{
 645.148 +-  panic(KERN_CRIT TPM_MODULE_NAME "GNU MP abort() was called\n");
 645.149 +-}
 645.150 +-
 645.151 + /* overwrite GNU MP random functions (used by mpz/millerrabin.c) */ 
 645.152 + 
 645.153 + void __attribute__ ((regparm(0))) gmp_randinit(gmp_randstate_t rstate, 
 645.154 +@@ -77,20 +73,19 @@ void __attribute__ ((regparm(0))) mpz_ur
 645.155 + 
 645.156 + void __attribute__ ((regparm(0))) *kernel_allocate(size_t size)
 645.157 + {
 645.158 +-  void *ret  = (void*)kmalloc(size, GFP_KERNEL);
 645.159 +-  if (!ret) panic(KERN_CRIT TPM_MODULE_NAME 
 645.160 +-    "GMP: cannot allocate memory (size=%u)\n", size);
 645.161 ++  void *ret  = (void*)malloc(size);
 645.162 ++  if (!ret) error("GMP: cannot allocate memory (size=%u)\n", size);
 645.163 +   return ret;
 645.164 + }
 645.165 + 
 645.166 + void __attribute__ ((regparm(0))) *kernel_reallocate(void *oldptr, 
 645.167 +   size_t old_size, size_t new_size)
 645.168 + {
 645.169 +-  void *ret = (void*)kmalloc(new_size, GFP_KERNEL);
 645.170 +-  if (!ret) panic(KERN_CRIT TPM_MODULE_NAME "GMP: Cannot reallocate memory "
 645.171 ++  void *ret = (void*)malloc(new_size);
 645.172 ++  if (!ret) error("GMP: Cannot reallocate memory "
 645.173 +     "(old_size=%u new_size=%u)\n", old_size, new_size);
 645.174 +   memcpy(ret, oldptr, old_size);
 645.175 +-  kfree(oldptr);
 645.176 ++  free(oldptr);
 645.177 +   return ret;
 645.178 + }
 645.179 + 
 645.180 +@@ -99,7 +94,7 @@ void __attribute__ ((regparm(0))) kernel
 645.181 +   /* overwrite used memory */
 645.182 +   if (blk_ptr != NULL) { 
 645.183 +     memset(blk_ptr, 0, blk_size);
 645.184 +-    kfree(blk_ptr);
 645.185 ++    free(blk_ptr);
 645.186 +   }
 645.187 + }
 645.188 + 
 645.189 +diff -uprN orig/tpm_emulator-0.2/crypto/rsa.c vtpm/crypto/rsa.c
 645.190 +--- orig/tpm_emulator-0.2/crypto/rsa.c	2005-08-17 10:58:36.000000000 -0700
 645.191 ++++ vtpm/crypto/rsa.c	2005-08-17 10:55:52.000000000 -0700
 645.192 +@@ -1,5 +1,6 @@
 645.193 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 645.194 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 645.195 ++ * Copyright (C) 2005 INTEL Corp
 645.196 +  *
 645.197 +  * This module is free software; you can redistribute it and/or modify
 645.198 +  * it under the terms of the GNU General Public License as published
 645.199 +@@ -363,7 +364,7 @@ static int encode_message(int type, uint
 645.200 +       msg[0] = 0x00;
 645.201 +       get_random_bytes(&msg[1], SHA1_DIGEST_LENGTH);
 645.202 +       sha1_init(&ctx);
 645.203 +-      sha1_update(&ctx, "TCPA", 4);
 645.204 ++      sha1_update(&ctx, (uint8_t *) "TCPA", 4);
 645.205 +       sha1_final(&ctx, &msg[1 + SHA1_DIGEST_LENGTH]);
 645.206 +       memset(&msg[1 + 2 * SHA1_DIGEST_LENGTH], 0x00, 
 645.207 +         msg_len - data_len - 2 * SHA1_DIGEST_LENGTH - 2);
 645.208 +@@ -411,7 +412,7 @@ static int decode_message(int type, uint
 645.209 +       mask_generation(&msg[1], SHA1_DIGEST_LENGTH,
 645.210 +         &msg[1 + SHA1_DIGEST_LENGTH], msg_len - SHA1_DIGEST_LENGTH - 1);
 645.211 +       sha1_init(&ctx);
 645.212 +-      sha1_update(&ctx, "TCPA", 4);
 645.213 ++      sha1_update(&ctx, (uint8_t *) "TCPA", 4);
 645.214 +       sha1_final(&ctx, &msg[1]);
 645.215 +       if (memcmp(&msg[1], &msg[1 + SHA1_DIGEST_LENGTH], 
 645.216 +           SHA1_DIGEST_LENGTH) != 0) return -1;
 645.217 +diff -uprN orig/tpm_emulator-0.2/linux_module.c vtpm/linux_module.c
 645.218 +--- orig/tpm_emulator-0.2/linux_module.c	2005-08-17 10:58:36.000000000 -0700
 645.219 ++++ vtpm/linux_module.c	1969-12-31 16:00:00.000000000 -0800
 645.220 +@@ -1,163 +0,0 @@
 645.221 +-/* Software-Based Trusted Platform Module (TPM) Emulator for Linux 
 645.222 +- * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 645.223 +- *
 645.224 +- * This module is free software; you can redistribute it and/or modify 
 645.225 +- * it under the terms of the GNU General Public License as published 
 645.226 +- * by the Free Software Foundation; either version 2 of the License, 
 645.227 +- * or (at your option) any later version.  
 645.228 +- *
 645.229 +- * This module is distributed in the hope that it will be useful, 
 645.230 +- * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 645.231 +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 645.232 +- * GNU General Public License for more details.
 645.233 +- *
 645.234 +- * $Id: linux_module.c 19 2005-05-18 08:29:37Z mast $
 645.235 +- */
 645.236 +-
 645.237 +-#include <linux/module.h>
 645.238 +-#include <linux/kernel.h>
 645.239 +-#include <linux/init.h>
 645.240 +-#include <linux/miscdevice.h>
 645.241 +-#include <linux/poll.h>
 645.242 +-#include "linux_module.h"
 645.243 +-#include "tpm/tpm_emulator.h"
 645.244 +-
 645.245 +-MODULE_LICENSE("GPL");
 645.246 +-MODULE_AUTHOR("Mario Strasser <mast@gmx.net>");
 645.247 +-MODULE_DESCRIPTION("Trusted Platform Module (TPM) Emulator");
 645.248 +-MODULE_SUPPORTED_DEVICE(TPM_DEVICE_NAME);
 645.249 +-
 645.250 +-/* module startup parameters */
 645.251 +-char *startup = "save";
 645.252 +-MODULE_PARM(startup, "s");
 645.253 +-MODULE_PARM_DESC(startup, " Sets the startup mode of the TPM. "
 645.254 +-  "Possible values are 'clear', 'save' (default) and 'deactivated.");
 645.255 +-char *storage_file = "/var/tpm/tpm_emulator-1.2.0.1";
 645.256 +-MODULE_PARM(storage_file, "s");
 645.257 +-MODULE_PARM_DESC(storage_file, " Sets the persistent-data storage " 
 645.258 +-  "file of the TPM.");
 645.259 +-
 645.260 +-/* TPM lock */
 645.261 +-static struct semaphore tpm_mutex;
 645.262 +-
 645.263 +-/* TPM command response */
 645.264 +-static struct {
 645.265 +-  uint8_t *data;
 645.266 +-  uint32_t size;
 645.267 +-} tpm_response;
 645.268 +-
 645.269 +-/* module state */
 645.270 +-#define STATE_IS_OPEN 0
 645.271 +-static uint32_t module_state;
 645.272 +-
 645.273 +-static int tpm_open(struct inode *inode, struct file *file)
 645.274 +-{
 645.275 +-  debug("%s()", __FUNCTION__);
 645.276 +-  if (test_and_set_bit(STATE_IS_OPEN, (void*)&module_state)) return -EBUSY;
 645.277 +-  return 0;
 645.278 +-}
 645.279 +-
 645.280 +-static int tpm_release(struct inode *inode, struct file *file)
 645.281 +-{
 645.282 +-  debug("%s()", __FUNCTION__);
 645.283 +-  clear_bit(STATE_IS_OPEN, (void*)&module_state);
 645.284 +-  return 0;
 645.285 +-}
 645.286 +-
 645.287 +-static ssize_t tpm_read(struct file *file, char *buf, size_t count, loff_t *ppos)
 645.288 +-{
 645.289 +-  debug("%s(%d)", __FUNCTION__, count);
 645.290 +-  down(&tpm_mutex);
 645.291 +-  if (tpm_response.data != NULL) {
 645.292 +-    count = min(count, (size_t)tpm_response.size - (size_t)*ppos);
 645.293 +-    count -= copy_to_user(buf, &tpm_response.data[*ppos], count);
 645.294 +-    *ppos += count;
 645.295 +-  } else {
 645.296 +-    count = 0;
 645.297 +-  }
 645.298 +-  up(&tpm_mutex);
 645.299 +-  return count;
 645.300 +-}
 645.301 +-
 645.302 +-static ssize_t tpm_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
 645.303 +-{
 645.304 +-  debug("%s(%d)", __FUNCTION__, count);
 645.305 +-  down(&tpm_mutex);
 645.306 +-  *ppos = 0;
 645.307 +-  if (tpm_response.data != NULL) kfree(tpm_response.data);
 645.308 +-  if (tpm_handle_command(buf, count, &tpm_response.data, 
 645.309 +-                         &tpm_response.size) != 0) { 
 645.310 +-    count = -EILSEQ;
 645.311 +-    tpm_response.data = NULL;
 645.312 +-  }
 645.313 +-  up(&tpm_mutex);
 645.314 +-  return count;
 645.315 +-}
 645.316 +-
 645.317 +-static int tpm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 645.318 +-{
 645.319 +-  debug("%s(%d, %ld)", __FUNCTION__, cmd, arg);
 645.320 +-  return -1;
 645.321 +-}
 645.322 +-
 645.323 +-struct file_operations fops = {
 645.324 +-  .owner   = THIS_MODULE,
 645.325 +-  .open    = tpm_open,
 645.326 +-  .release = tpm_release,
 645.327 +-  .read    = tpm_read,
 645.328 +-  .write   = tpm_write,
 645.329 +-  .ioctl   = tpm_ioctl,
 645.330 +-};
 645.331 +-
 645.332 +-static struct miscdevice tpm_dev = {
 645.333 +-  .minor      = TPM_DEVICE_MINOR, 
 645.334 +-  .name       = TPM_DEVICE_NAME, 
 645.335 +-  .fops       = &fops,
 645.336 +-};
 645.337 +-
 645.338 +-int __init init_tpm_module(void)
 645.339 +-{
 645.340 +-  int res = misc_register(&tpm_dev);
 645.341 +-  if (res != 0) {
 645.342 +-    error("misc_register() failed for minor %d\n", TPM_DEVICE_MINOR);
 645.343 +-    return res;
 645.344 +-  }
 645.345 +-  /* initialize variables */
 645.346 +-  sema_init(&tpm_mutex, 1);
 645.347 +-  module_state = 0;
 645.348 +-  tpm_response.data = NULL;    
 645.349 +-  /* initialize TPM emulator */
 645.350 +-  if (!strcmp(startup, "clear")) {
 645.351 +-    tpm_emulator_init(1);
 645.352 +-  } else if (!strcmp(startup, "save")) { 
 645.353 +-    tpm_emulator_init(2);
 645.354 +-  } else if (!strcmp(startup, "deactivated")) {
 645.355 +-    tpm_emulator_init(3);
 645.356 +-  } else {
 645.357 +-    error("invalid startup mode '%s'; must be 'clear', "
 645.358 +-      "'save' (default) or 'deactivated", startup);
 645.359 +-    misc_deregister(&tpm_dev);
 645.360 +-    return -EINVAL;
 645.361 +-  }
 645.362 +-  return 0;
 645.363 +-}
 645.364 +-
 645.365 +-void __exit cleanup_tpm_module(void)
 645.366 +-{
 645.367 +-  tpm_emulator_shutdown();
 645.368 +-  misc_deregister(&tpm_dev);
 645.369 +-}
 645.370 +-
 645.371 +-module_init(init_tpm_module);
 645.372 +-module_exit(cleanup_tpm_module);
 645.373 +-
 645.374 +-uint64_t tpm_get_ticks(void)
 645.375 +-{
 645.376 +-  static struct timespec old_time = {0, 0}; 
 645.377 +-  struct timespec new_time = current_kernel_time();
 645.378 +-  uint64_t ticks = (uint64_t)(old_time.tv_sec - new_time.tv_sec) * 1000000
 645.379 +-                   + (old_time.tv_nsec - new_time.tv_nsec) / 1000;
 645.380 +-  old_time = new_time;
 645.381 +-  return (ticks > 0) ? ticks : 1;
 645.382 +-}
 645.383 +-
 645.384 +diff -uprN orig/tpm_emulator-0.2/linux_module.h vtpm/linux_module.h
 645.385 +--- orig/tpm_emulator-0.2/linux_module.h	2005-08-17 10:58:36.000000000 -0700
 645.386 ++++ vtpm/linux_module.h	2005-08-17 10:55:52.000000000 -0700
 645.387 +@@ -1,5 +1,6 @@
 645.388 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 645.389 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 645.390 ++ * Copyright (C) 2005 INTEL Corp
 645.391 +  *
 645.392 +  * This module is free software; you can redistribute it and/or modify
 645.393 +  * it under the terms of the GNU General Public License as published
 645.394 +@@ -17,17 +18,22 @@
 645.395 + #ifndef _LINUX_MODULE_H_
 645.396 + #define _LINUX_MODULE_H_
 645.397 + 
 645.398 +-#include <linux/version.h>
 645.399 +-#include <linux/kernel.h>
 645.400 +-#include <linux/slab.h>
 645.401 ++#include <malloc.h>
 645.402 ++#include <stdint.h>
 645.403 ++#include <stdio.h>
 645.404 ++#include <string.h>
 645.405 + #include <linux/types.h>
 645.406 +-#include <linux/string.h>
 645.407 +-#include <linux/random.h>
 645.408 +-#include <linux/time.h>
 645.409 +-#include <asm/byteorder.h>
 645.410 + 
 645.411 +-/* module settings */
 645.412 ++#include <endian.h>
 645.413 ++#define __BYTEORDER_HAS_U64__
 645.414 ++#ifdef LITTLE_ENDIAN
 645.415 ++ #include <linux/byteorder/little_endian.h>
 645.416 ++#else
 645.417 ++ #include <linux/byteorder/big_endian.h>
 645.418 ++#endif
 645.419 + 
 645.420 ++/* module settings */
 645.421 ++#define min(A,B) ((A)<(B)?(A):(B))
 645.422 + #define STR(s) __STR__(s)
 645.423 + #define __STR__(s) #s
 645.424 + #include "tpm_version.h"
 645.425 +@@ -39,32 +45,35 @@
 645.426 + /* debug and log output functions */
 645.427 + 
 645.428 + #ifdef DEBUG
 645.429 +-#define debug(fmt, ...) printk(KERN_DEBUG "%s %s:%d: Debug: " fmt "\n", \
 645.430 +-                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
 645.431 ++#define debug(fmt, ...) printf("%s:%d: Debug: " fmt "\n", \
 645.432 ++                        __FILE__, __LINE__, ## __VA_ARGS__)
 645.433 + #else
 645.434 + #define debug(fmt, ...) 
 645.435 + #endif
 645.436 +-#define info(fmt, ...)  printk(KERN_INFO "%s %s:%d: Info: " fmt "\n", \
 645.437 +-                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
 645.438 +-#define error(fmt, ...) printk(KERN_ERR "%s %s:%d: Error: " fmt "\n", \
 645.439 +-                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
 645.440 +-#define alert(fmt, ...) printk(KERN_ALERT "%s %s:%d: Alert: " fmt "\n", \
 645.441 +-                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
 645.442 ++#define info(fmt, ...)  printf("%s:%d: Info: " fmt "\n", \
 645.443 ++                        __FILE__, __LINE__, ## __VA_ARGS__)
 645.444 ++#define error(fmt, ...) printf("%s:%d: Error: " fmt "\n", \
 645.445 ++                        __FILE__, __LINE__, ## __VA_ARGS__)
 645.446 ++#define alert(fmt, ...) printf("%s:%d: Alert: " fmt "\n", \
 645.447 ++                        __FILE__, __LINE__, ## __VA_ARGS__)
 645.448 + 
 645.449 + /* memory allocation */
 645.450 + 
 645.451 + static inline void *tpm_malloc(size_t size) 
 645.452 + {
 645.453 +-  return kmalloc(size, GFP_KERNEL);  
 645.454 ++  return malloc(size);  
 645.455 + }
 645.456 + 
 645.457 + static inline void tpm_free(const void *ptr)
 645.458 + {
 645.459 +-  if (ptr != NULL) kfree(ptr);
 645.460 ++  if (ptr != NULL) free( (void *) ptr);
 645.461 + }
 645.462 + 
 645.463 + /* random numbers */
 645.464 + 
 645.465 ++//FIXME;
 645.466 ++void get_random_bytes(void *buf, int nbytes);
 645.467 ++
 645.468 + static inline void tpm_get_random_bytes(void *buf, int nbytes)
 645.469 + {
 645.470 +   get_random_bytes(buf, nbytes);
 645.471 +@@ -84,9 +93,9 @@ uint64_t tpm_get_ticks(void);
 645.472 + #define CPU_TO_LE16(x) __cpu_to_le16(x)
 645.473 + 
 645.474 + #define BE64_TO_CPU(x) __be64_to_cpu(x)
 645.475 +-#define LE64_TO_CPU(x) __be64_to_cpu(x)
 645.476 ++#define LE64_TO_CPU(x) __le64_to_cpu(x)
 645.477 + #define BE32_TO_CPU(x) __be32_to_cpu(x)
 645.478 +-#define LE32_TO_CPU(x) __be32_to_cpu(x)
 645.479 ++#define LE32_TO_CPU(x) __le32_to_cpu(x)
 645.480 + #define BE16_TO_CPU(x) __be16_to_cpu(x)
 645.481 + #define LE16_TO_CPU(x) __le16_to_cpu(x)
 645.482 + 
 645.483 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_audit.c vtpm/tpm/tpm_audit.c
 645.484 +--- orig/tpm_emulator-0.2/tpm/tpm_audit.c	2005-08-17 10:58:36.000000000 -0700
 645.485 ++++ vtpm/tpm/tpm_audit.c	2005-08-17 10:55:52.000000000 -0700
 645.486 +@@ -1,6 +1,7 @@
 645.487 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 645.488 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 645.489 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
 645.490 ++ * Copyright (C) 2005 INTEL Corp
 645.491 +  *
 645.492 +  * This module is free software; you can redistribute it and/or modify
 645.493 +  * it under the terms of the GNU General Public License as published
 645.494 +@@ -45,14 +46,14 @@ void tpm_audit_request(TPM_COMMAND_CODE 
 645.495 +       tpmData.permanent.data.auditMonotonicCounter++;
 645.496 +     }
 645.497 +     /* update audit digest */
 645.498 +-    *((UINT16*)&buf[0])  = cpu_to_be16(TPM_TAG_AUDIT_EVENT_IN);
 645.499 +-    *((UINT32*)&buf[2]) = cpu_to_be32(ordinal);
 645.500 ++    *((UINT16*)&buf[0])  = CPU_TO_BE16(TPM_TAG_AUDIT_EVENT_IN);
 645.501 ++    *((UINT32*)&buf[2]) = CPU_TO_BE32(ordinal);
 645.502 +     sha1_init(&sha1_ctx);
 645.503 +     sha1_update(&sha1_ctx, req->param, req->paramSize);
 645.504 +     sha1_final(&sha1_ctx, &buf[6]);
 645.505 +-    *((UINT16*)&buf[26])  = cpu_to_be16(TPM_TAG_COUNTER_VALUE);
 645.506 ++    *((UINT16*)&buf[26])  = CPU_TO_BE16(TPM_TAG_COUNTER_VALUE);
 645.507 +     memset(&buf[30], 0, 4);
 645.508 +-    *((UINT32*)&buf[34]) = cpu_to_be32(tpmData.permanent.data.auditMonotonicCounter);
 645.509 ++    *((UINT32*)&buf[34]) = CPU_TO_BE32(tpmData.permanent.data.auditMonotonicCounter);
 645.510 +     sha1_init(&sha1_ctx);
 645.511 +     sha1_update(&sha1_ctx, tpmData.stany.data.auditDigest.digest, 
 645.512 +       sizeof(TPM_DIGEST));
 645.513 +@@ -70,15 +71,15 @@ void tpm_audit_response(TPM_COMMAND_CODE
 645.514 +       && (AUDIT_STATUS[ord / 8] & (1 << (ord & 0x07)))) {
 645.515 +     info("tpm_audit_response()");
 645.516 +     /* update audit digest */
 645.517 +-    *((UINT16*)&buf[0])  = cpu_to_be16(TPM_TAG_AUDIT_EVENT_OUT);
 645.518 +-    *((UINT32*)&buf[2]) = cpu_to_be32(ordinal);
 645.519 ++    *((UINT16*)&buf[0])  = CPU_TO_BE16(TPM_TAG_AUDIT_EVENT_OUT);
 645.520 ++    *((UINT32*)&buf[2]) = CPU_TO_BE32(ordinal);
 645.521 +     sha1_init(&sha1_ctx);
 645.522 +     sha1_update(&sha1_ctx, rsp->param, rsp->paramSize);
 645.523 +     sha1_final(&sha1_ctx, &buf[6]);
 645.524 +-    *((UINT16*)&buf[26])  = cpu_to_be16(TPM_TAG_COUNTER_VALUE);
 645.525 ++    *((UINT16*)&buf[26])  = CPU_TO_BE16(TPM_TAG_COUNTER_VALUE);
 645.526 +     memset(&buf[30], 0, 4);
 645.527 +-    *((UINT32*)&buf[34]) = cpu_to_be32(tpmData.permanent.data.auditMonotonicCounter);
 645.528 +-    *((UINT32*)&buf[34]) = cpu_to_be32(rsp->result);
 645.529 ++    *((UINT32*)&buf[34]) = CPU_TO_BE32(tpmData.permanent.data.auditMonotonicCounter);
 645.530 ++    *((UINT32*)&buf[34]) = CPU_TO_BE32(rsp->result);
 645.531 +     sha1_init(&sha1_ctx);
 645.532 +     sha1_update(&sha1_ctx, tpmData.stany.data.auditDigest.digest, 
 645.533 +       sizeof(TPM_DIGEST));
 645.534 +@@ -158,7 +159,7 @@ TPM_RESULT TPM_GetAuditDigestSigned(TPM_
 645.535 +   }
 645.536 +   memcpy(&buf[0], "\x05\x00ADIG", 6);
 645.537 +   memcpy(&buf[6], antiReplay->nonce, 20);
 645.538 +-  *(UINT32*)&buf[26] = cpu_to_be32(buf_size - 30);
 645.539 ++  *(UINT32*)&buf[26] = CPU_TO_BE32(buf_size - 30);
 645.540 +   memcpy(&buf[30], auditDigest->digest, 20);
 645.541 +   ptr = &buf[50];
 645.542 +   len = buf_size - 50;
 645.543 +@@ -198,4 +199,3 @@ TPM_RESULT TPM_SetOrdinalAuditStatus(TPM
 645.544 +   }
 645.545 +   return TPM_SUCCESS;
 645.546 + }
 645.547 +-
 645.548 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_authorization.c vtpm/tpm/tpm_authorization.c
 645.549 +--- orig/tpm_emulator-0.2/tpm/tpm_authorization.c	2005-08-17 10:58:36.000000000 -0700
 645.550 ++++ vtpm/tpm/tpm_authorization.c	2005-08-17 10:55:52.000000000 -0700
 645.551 +@@ -1,6 +1,7 @@
 645.552 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 645.553 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 645.554 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
 645.555 ++ * Copyright (C) 2005 INTEL Corp
 645.556 +  *
 645.557 +  * This module is free software; you can redistribute it and/or modify
 645.558 +  * it under the terms of the GNU General Public License as published
 645.559 +@@ -268,7 +269,7 @@ TPM_RESULT tpm_verify_auth(TPM_AUTH *aut
 645.560 + {
 645.561 +   hmac_ctx_t ctx;
 645.562 +   TPM_SESSION_DATA *session;
 645.563 +-  UINT32 auth_handle = cpu_to_be32(auth->authHandle);
 645.564 ++  UINT32 auth_handle = CPU_TO_BE32(auth->authHandle);
 645.565 +   
 645.566 +   info("tpm_verify_auth(%08x)", auth->authHandle);
 645.567 +   /* get dedicated authorization session */
 645.568 +@@ -316,5 +317,3 @@ void tpm_decrypt_auth_secret(TPM_ENCAUTH
 645.569 +   for (i = 0; i < sizeof(TPM_SECRET); i++)
 645.570 +     plainAuth[i] ^= encAuth[i];
 645.571 + }
 645.572 +-
 645.573 +-
 645.574 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_capability.c vtpm/tpm/tpm_capability.c
 645.575 +--- orig/tpm_emulator-0.2/tpm/tpm_capability.c	2005-08-17 10:58:36.000000000 -0700
 645.576 ++++ vtpm/tpm/tpm_capability.c	2005-08-17 10:55:52.000000000 -0700
 645.577 +@@ -1,6 +1,7 @@
 645.578 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 645.579 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 645.580 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
 645.581 ++ * Copyright (C) 2005 INTEL Corp
 645.582 +  *
 645.583 +  * This module is free software; you can redistribute it and/or modify
 645.584 +  * it under the terms of the GNU General Public License as published
 645.585 +@@ -398,7 +399,7 @@ TPM_RESULT TPM_GetCapability(TPM_CAPABIL
 645.586 + 
 645.587 +     case TPM_CAP_KEY_HANDLE:
 645.588 +       debug("[TPM_CAP_KEY_HANDLE]");
 645.589 +-      subCapSize = cpu_to_be32(TPM_RT_KEY);
 645.590 ++      subCapSize = CPU_TO_BE32(TPM_RT_KEY);
 645.591 +       return cap_handle(4, (BYTE*)&subCapSize, respSize, resp);
 645.592 + 
 645.593 +     case TPM_CAP_CHECK_LOADED:
 645.594 +@@ -472,4 +473,3 @@ TPM_RESULT TPM_GetCapability(TPM_CAPABIL
 645.595 +       return TPM_BAD_MODE;
 645.596 +   }
 645.597 + }
 645.598 +-
 645.599 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_cmd_handler.c vtpm/tpm/tpm_cmd_handler.c
 645.600 +--- orig/tpm_emulator-0.2/tpm/tpm_cmd_handler.c	2005-08-17 10:58:36.000000000 -0700
 645.601 ++++ vtpm/tpm/tpm_cmd_handler.c	2005-08-17 10:55:52.000000000 -0700
 645.602 +@@ -1,6 +1,7 @@
 645.603 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 645.604 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 645.605 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
 645.606 ++ * Copyright (C) 2005 INTEL Corp
 645.607 +  *
 645.608 +  * This module is free software; you can redistribute it and/or modify
 645.609 +  * it under the terms of the GNU General Public License as published
 645.610 +@@ -26,7 +27,7 @@ static void tpm_compute_in_param_digest(
 645.611 + {
 645.612 +   sha1_ctx_t sha1;
 645.613 +   UINT32 offset;
 645.614 +-  UINT32 ord = cpu_to_be32(req->ordinal);
 645.615 ++  UINT32 ord = CPU_TO_BE32(req->ordinal);
 645.616 + 
 645.617 +   /* skip all key-handles at the beginning */
 645.618 +   switch (req->ordinal) {
 645.619 +@@ -82,8 +83,8 @@ static void tpm_compute_in_param_digest(
 645.620 + static void tpm_compute_out_param_digest(TPM_COMMAND_CODE ordinal, TPM_RESPONSE *rsp)
 645.621 + {
 645.622 +   sha1_ctx_t sha1;
 645.623 +-  UINT32 res = cpu_to_be32(rsp->result);
 645.624 +-  UINT32 ord = cpu_to_be32(ordinal);
 645.625 ++  UINT32 res = CPU_TO_BE32(rsp->result);
 645.626 ++  UINT32 ord = CPU_TO_BE32(ordinal);
 645.627 + 
 645.628 +   /* compute SHA1 hash */
 645.629 +   sha1_init(&sha1);
 645.630 +@@ -3081,7 +3082,7 @@ static void tpm_setup_rsp_auth(TPM_COMMA
 645.631 +       hmac_update(&hmac, rsp->auth2->digest, sizeof(rsp->auth2->digest));
 645.632 + #if 0
 645.633 +       if (tpm_get_auth(rsp->auth2->authHandle)->type == TPM_ST_OIAP) {
 645.634 +-        UINT32 handle = cpu_to_be32(rsp->auth2->authHandle);
 645.635 ++        UINT32 handle = CPU_TO_BE32(rsp->auth2->authHandle);
 645.636 +         hmac_update(&hmac, (BYTE*)&handle, 4);
 645.637 +       }
 645.638 + #endif
 645.639 +@@ -3096,7 +3097,7 @@ static void tpm_setup_rsp_auth(TPM_COMMA
 645.640 +       hmac_update(&hmac, rsp->auth1->digest, sizeof(rsp->auth1->digest));
 645.641 + #if 0
 645.642 +       if (tpm_get_auth(rsp->auth1->authHandle)->type == TPM_ST_OIAP) {
 645.643 +-        UINT32 handle = cpu_to_be32(rsp->auth1->authHandle);
 645.644 ++        UINT32 handle = CPU_TO_BE32(rsp->auth1->authHandle);
 645.645 +         hmac_update(&hmac, (BYTE*)&handle, 4);
 645.646 +       }
 645.647 + #endif
 645.648 +@@ -3179,7 +3180,9 @@ extern const char *tpm_error_to_string(T
 645.649 + static void tpm_execute_command(TPM_REQUEST *req, TPM_RESPONSE *rsp)
 645.650 + {
 645.651 +   TPM_RESULT res;
 645.652 +-  
 645.653 ++
 645.654 ++  req->tag = (BYTE) req->tag;  // VIN HACK!!! 
 645.655 ++
 645.656 +   /* setup authorisation as well as response tag and size */
 645.657 +   memset(rsp, 0, sizeof(*rsp));
 645.658 +   switch (req->tag) {
 645.659 +@@ -3878,4 +3881,3 @@ int tpm_handle_command(const uint8_t *in
 645.660 +   tpm_free(rsp.param);
 645.661 +   return 0;
 645.662 + }
 645.663 +-
 645.664 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_crypto.c vtpm/tpm/tpm_crypto.c
 645.665 +--- orig/tpm_emulator-0.2/tpm/tpm_crypto.c	2005-08-17 10:58:36.000000000 -0700
 645.666 ++++ vtpm/tpm/tpm_crypto.c	2005-08-17 10:55:52.000000000 -0700
 645.667 +@@ -1,6 +1,7 @@
 645.668 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 645.669 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 645.670 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
 645.671 ++ * Copyright (C) 2005 INTEL Corp
 645.672 +  *
 645.673 +  * This module is free software; you can redistribute it and/or modify
 645.674 +  * it under the terms of the GNU General Public License as published
 645.675 +@@ -106,7 +107,7 @@ TPM_RESULT tpm_sign(TPM_KEY_DATA *key, T
 645.676 +     /* setup TPM_SIGN_INFO structure */
 645.677 +     memcpy(&buf[0], "\x05\x00SIGN", 6);
 645.678 +     memcpy(&buf[6], auth->nonceOdd.nonce, 20);
 645.679 +-    *(UINT32*)&buf[26] = cpu_to_be32(areaToSignSize);
 645.680 ++    *(UINT32*)&buf[26] = CPU_TO_BE32(areaToSignSize);
 645.681 +     memcpy(&buf[30], areaToSign, areaToSignSize);
 645.682 +     if (rsa_sign(&key->key, RSA_SSA_PKCS1_SHA1, 
 645.683 +         buf, areaToSignSize + 30, *sig)) {
 645.684 +@@ -379,4 +380,3 @@ TPM_RESULT TPM_CertifyKey2(TPM_KEY_HANDL
 645.685 +   }  
 645.686 +   return TPM_SUCCESS;
 645.687 + }
 645.688 +-
 645.689 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_data.c vtpm/tpm/tpm_data.c
 645.690 +--- orig/tpm_emulator-0.2/tpm/tpm_data.c	2005-08-17 10:58:36.000000000 -0700
 645.691 ++++ vtpm/tpm/tpm_data.c	2005-08-17 10:55:52.000000000 -0700
 645.692 +@@ -1,6 +1,7 @@
 645.693 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 645.694 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 645.695 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
 645.696 ++ * Copyright (C) 2005 INTEL Corp
 645.697 +  *
 645.698 +  * This module is free software; you can redistribute it and/or modify
 645.699 +  * it under the terms of the GNU General Public License as published
 645.700 +@@ -15,9 +16,15 @@
 645.701 +  * $Id: tpm_data.c 9 2005-04-26 18:15:31Z mast $
 645.702 +  */
 645.703 + 
 645.704 ++#include <sys/types.h>
 645.705 ++#include <sys/stat.h>
 645.706 ++#include <fcntl.h>
 645.707 ++#include <unistd.h>
 645.708 ++
 645.709 + #include "tpm_emulator.h"
 645.710 + #include "tpm_structures.h"
 645.711 + #include "tpm_marshalling.h"
 645.712 ++#include "vtpm_manager.h"
 645.713 + 
 645.714 + TPM_DATA tpmData;
 645.715 + 
 645.716 +@@ -28,6 +35,7 @@ BOOL tpm_get_physical_presence(void)
 645.717 + 
 645.718 + void tpm_init_data(void)
 645.719 + {
 645.720 ++#ifndef TPM_GENERATE_EK
 645.721 +   /* endorsement key */
 645.722 +   uint8_t ek_n[] =  "\xa8\xdb\xa9\x42\xa8\xf3\xb8\x06\x85\x90\x76\x93\xad\xf7"
 645.723 +     "\x74\xec\x3f\xd3\x3d\x9d\xe8\x2e\xff\x15\xed\x0e\xce\x5f\x93"
 645.724 +@@ -66,6 +74,8 @@ void tpm_init_data(void)
 645.725 +     "\xd1\xc0\x8b\x5b\xa2\x2e\xa7\x15\xca\x50\x75\x10\x48\x9c\x2b"
 645.726 +     "\x18\xb9\x67\x8f\x5d\x64\xc3\x28\x9f\x2f\x16\x2f\x08\xda\x47"
 645.727 +     "\xec\x86\x43\x0c\x80\x99\x07\x34\x0f";
 645.728 ++#endif
 645.729 ++
 645.730 +   int i;
 645.731 +   /* reset all data to NULL, FALSE or 0 */
 645.732 +   memset(&tpmData, 0, sizeof(tpmData));
 645.733 +@@ -85,6 +95,10 @@ void tpm_init_data(void)
 645.734 +   tpmData.permanent.data.version.revMinor = VERSION_MINOR;
 645.735 +   /* setup PCR attributes */
 645.736 +   for (i = 0; i < TPM_NUM_PCR; i++) {
 645.737 ++    int j;
 645.738 ++    for (j=0; j < TPM_NUM_LOCALITY; j++) {
 645.739 ++      tpmData.permanent.data.pcrAttrib[i].pcrExtendLocal[j] = TRUE;
 645.740 ++    }
 645.741 +     tpmData.permanent.data.pcrAttrib[i].pcrReset = TRUE;
 645.742 +   }
 645.743 +   /* set tick type */
 645.744 +@@ -115,49 +129,235 @@ void tpm_release_data(void)
 645.745 + 
 645.746 + #ifdef TPM_STORE_TO_FILE
 645.747 + 
 645.748 +-#include <linux/fs.h>
 645.749 +-#include <linux/unistd.h>
 645.750 +-#include <asm/uaccess.h>
 645.751 ++#include <sys/types.h>
 645.752 ++#include <sys/stat.h>
 645.753 ++#include <fcntl.h>
 645.754 ++
 645.755 ++ static int vtpm_tx_fh=-1, vtpm_rx_fh=-1;
 645.756 + 
 645.757 +-#define TPM_STORAGE_FILE "/var/tpm/tpm_emulator-1.2." STR(VERSION_MAJOR) "." STR(VERSION_MINOR) 
 645.758 ++#ifdef VTPM_MUTLI_VM
 645.759 ++ #define DEV_FE "/dev/tpm"
 645.760 ++#else
 645.761 ++ #define VTPM_RX_FIFO_D  "/var/vtpm/fifos/vtpm-to-%d.fifo"
 645.762 ++ #define VTPM_TX_FIFO  "/var/vtpm/fifos/vtpm-from-all.fifo"
 645.763 ++
 645.764 ++ extern int dmi_id;
 645.765 ++ static char *vtpm_rx_name=NULL; 
 645.766 ++#endif
 645.767 + 
 645.768 + static int write_to_file(uint8_t *data, size_t data_length)
 645.769 + {
 645.770 +-  int res;
 645.771 +-  struct file *fp;
 645.772 +-  mm_segment_t old_fs = get_fs();
 645.773 +-  fp = filp_open(TPM_STORAGE_FILE, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
 645.774 +-  if (IS_ERR(fp)) return -1;
 645.775 +-  set_fs(get_ds());
 645.776 +-  res = fp->f_op->write(fp, data, data_length, &fp->f_pos);
 645.777 +-  set_fs(old_fs);
 645.778 +-  filp_close(fp, NULL);
 645.779 +-  return (res == data_length) ? 0 : -1;
 645.780 ++  int res, out_data_size, in_header_size;
 645.781 ++  BYTE *ptr, *out_data, *in_header;
 645.782 ++  UINT32 result, len, in_rsp_size;
 645.783 ++  UINT16 tag = VTPM_TAG_REQ;
 645.784 ++	
 645.785 ++  printf("Saving NVM\n");
 645.786 ++  if (vtpm_tx_fh < 0) {
 645.787 ++#ifdef VTPM_MUTLI_VM
 645.788 ++    vtpm_tx_fh = open(DEV_FE, O_RDWR);
 645.789 ++#else
 645.790 ++	vtpm_tx_fh = open(VTPM_TX_FIFO, O_WRONLY);
 645.791 ++#endif
 645.792 ++  }
 645.793 ++
 645.794 ++  if (vtpm_tx_fh < 0) {
 645.795 ++		return -1;
 645.796 ++  }
 645.797 ++ 
 645.798 ++  // Send request to VTPM Manager to encrypt data
 645.799 ++#ifdef VTPM_MUTLI_VM
 645.800 ++  out_data_size = len = VTPM_COMMAND_HEADER_SIZE_CLT + data_length;
 645.801 ++#else
 645.802 ++  out_data_size = len = VTPM_COMMAND_HEADER_SIZE_SRV + data_length;
 645.803 ++#endif
 645.804 ++  
 645.805 ++  out_data = ptr = (BYTE *) malloc(len);
 645.806 ++
 645.807 ++  if (ptr == NULL
 645.808 ++#ifndef VTPM_MUTLI_VM
 645.809 ++      || tpm_marshal_UINT32(&ptr, &len, dmi_id)
 645.810 ++#endif
 645.811 ++	  || tpm_marshal_UINT16(&ptr, &len, tag)
 645.812 ++#ifdef VTPM_MUTLI_VM
 645.813 ++	  || tpm_marshal_UINT32(&ptr, &len, out_data_size)
 645.814 ++#else
 645.815 ++	  || tpm_marshal_UINT32(&ptr, &len, out_data_size - sizeof(uint32_t))
 645.816 ++#endif  
 645.817 ++	  || tpm_marshal_UINT32(&ptr, &len, VTPM_ORD_SAVENVM)
 645.818 ++	  || tpm_marshal_BYTE_ARRAY(&ptr, &len, data, data_length)) {
 645.819 ++	free(out_data);
 645.820 ++	return -1;
 645.821 ++  }
 645.822 ++  
 645.823 ++  printf("\tSending SaveNVM Command.\n");
 645.824 ++  res = write(vtpm_tx_fh, out_data, out_data_size);
 645.825 ++  free(out_data);
 645.826 ++  if (res != out_data_size) return -1;
 645.827 ++
 645.828 ++  if (vtpm_rx_fh < 0) {
 645.829 ++#ifdef VTPM_MUTLI_VM
 645.830 ++    vtpm_rx_fh = vtpm_tx_fh
 645.831 ++#else
 645.832 ++    if (vtpm_rx_name == NULL) {
 645.833 ++      vtpm_rx_name = malloc(10 + strlen(VTPM_RX_FIFO_D));
 645.834 ++      sprintf(vtpm_rx_name, VTPM_RX_FIFO_D, (uint32_t) dmi_id);
 645.835 ++    }
 645.836 ++	vtpm_rx_fh = open(vtpm_rx_name, O_RDONLY);
 645.837 ++#endif
 645.838 ++  }
 645.839 ++
 645.840 ++  if (vtpm_rx_fh < 0) {
 645.841 ++		return -1;
 645.842 ++  }
 645.843 ++  
 645.844 ++  // Read Header of response so we can get the size & status
 645.845 ++#ifdef VTPM_MUTLI_VM
 645.846 ++  in_header_size = len = VTPM_COMMAND_HEADER_SIZE_CLT;
 645.847 ++#else
 645.848 ++  in_header_size = len = VTPM_COMMAND_HEADER_SIZE_SRV;
 645.849 ++#endif
 645.850 ++  in_header = ptr = malloc(in_header_size);
 645.851 ++  
 645.852 ++  printf("\tReading SaveNVM header.\n");
 645.853 ++  res = read(vtpm_rx_fh, in_header, in_header_size);
 645.854 ++
 645.855 ++  if ( (res != in_header_size)
 645.856 ++#ifndef VTPM_MUTLI_VM
 645.857 ++       || tpm_unmarshal_UINT32(&ptr, &len, (UINT32*)&dmi_id)
 645.858 ++#endif
 645.859 ++	   || tpm_unmarshal_UINT16(&ptr, &len, &tag)
 645.860 ++	   || tpm_unmarshal_UINT32(&ptr, &len, &in_rsp_size)
 645.861 ++	   || tpm_unmarshal_UINT32(&ptr, &len, &result) ) {
 645.862 ++	  free(in_header);
 645.863 ++	  return -1;
 645.864 ++  }
 645.865 ++  free(in_header);
 645.866 ++  
 645.867 ++  if (result != VTPM_SUCCESS) {
 645.868 ++      return -1;  
 645.869 ++  }
 645.870 ++
 645.871 ++#ifdef VTPM_MUTLI_VM
 645.872 ++  close(vtpm_tx_fh); close(vtpm_rx_fh);
 645.873 ++#endif
 645.874 ++	  
 645.875 ++  printf("\tFinishing up SaveNVM\n");
 645.876 ++  return (0);
 645.877 + }
 645.878 + 
 645.879 + static int read_from_file(uint8_t **data, size_t *data_length)
 645.880 + {
 645.881 +-  int res;
 645.882 +-  struct file *fp;
 645.883 +-  mm_segment_t old_fs = get_fs();
 645.884 +-  fp = filp_open(TPM_STORAGE_FILE, O_RDONLY, 0);
 645.885 +-  if (IS_ERR(fp)) return -1;
 645.886 +-  *data_length = (size_t)fp->f_dentry->d_inode->i_size;
 645.887 +-  /* *data_length = i_size_read(fp->f_dentry->d_inode); */
 645.888 +-  *data = tpm_malloc(*data_length);
 645.889 +-  if (*data == NULL) {
 645.890 +-    filp_close(fp, NULL);
 645.891 ++  int res, out_data_size, in_header_size;
 645.892 ++  uint8_t *ptr, *out_data, *in_header;
 645.893 ++  UINT16 tag = VTPM_TAG_REQ;
 645.894 ++  UINT32 len, in_rsp_size, result;
 645.895 ++#ifdef VTPM_MUTLI_VM
 645.896 ++	int vtpm_rx_fh, vtpm_tx_fh;
 645.897 ++#endif
 645.898 ++	
 645.899 ++  printf("Loading NVM.\n");
 645.900 ++  if (vtpm_tx_fh < 0) {
 645.901 ++#ifdef VTPM_MUTLI_VM
 645.902 ++    vtpm_tx_fh = open(DEV_FE, O_RDWR);
 645.903 ++#else
 645.904 ++	vtpm_tx_fh = open(VTPM_TX_FIFO, O_WRONLY);
 645.905 ++#endif
 645.906 ++  }
 645.907 ++
 645.908 ++  if (vtpm_tx_fh < 0) {
 645.909 ++		return -1;
 645.910 ++  }
 645.911 ++ 
 645.912 ++  // Send request to VTPM Manager to encrypt data
 645.913 ++#ifdef VTPM_MUTLI_VM
 645.914 ++  out_data_size = len = VTPM_COMMAND_HEADER_SIZE_CLT;
 645.915 ++#else
 645.916 ++  out_data_size = len = VTPM_COMMAND_HEADER_SIZE_SRV;
 645.917 ++#endif
 645.918 ++  out_data = ptr = (BYTE *) malloc(len);
 645.919 ++
 645.920 ++  if (ptr == NULL
 645.921 ++#ifndef VTPM_MUTLI_VM
 645.922 ++      || tpm_marshal_UINT32(&ptr, &len, dmi_id)
 645.923 ++#endif  
 645.924 ++      || tpm_marshal_UINT16(&ptr, &len, tag)
 645.925 ++#ifdef VTPM_MUTLI_VM
 645.926 ++      || tpm_marshal_UINT32(&ptr, &len, out_data_size)
 645.927 ++#else
 645.928 ++      || tpm_marshal_UINT32(&ptr, &len, out_data_size - sizeof(uint32_t))
 645.929 ++#endif
 645.930 ++      || tpm_marshal_UINT32(&ptr, &len, VTPM_ORD_LOADNVM)) {
 645.931 ++    free(out_data);
 645.932 +     return -1;
 645.933 +   }
 645.934 +-  set_fs(get_ds());
 645.935 +-  res = fp->f_op->read(fp, *data, *data_length, &fp->f_pos);
 645.936 +-  set_fs(old_fs);
 645.937 +-  filp_close(fp, NULL);
 645.938 ++
 645.939 ++  printf("\tSending LoadNVM command\n");
 645.940 ++  res = write(vtpm_tx_fh, out_data, out_data_size);
 645.941 ++  free(out_data);
 645.942 ++  if (res != out_data_size) return -1;
 645.943 ++
 645.944 ++    if (vtpm_rx_fh < 0) {
 645.945 ++#ifdef VTPM_MUTLI_VM
 645.946 ++    vtpm_rx_fh = vtpm_tx_fh;
 645.947 ++#else
 645.948 ++    if (vtpm_rx_name == NULL) {
 645.949 ++      vtpm_rx_name = malloc(10 + strlen(VTPM_RX_FIFO_D));
 645.950 ++      sprintf(vtpm_rx_name, VTPM_RX_FIFO_D, (uint32_t) dmi_id);
 645.951 ++    }
 645.952 ++	vtpm_rx_fh = open(vtpm_rx_name, O_RDONLY);
 645.953 ++#endif
 645.954 ++  }
 645.955 ++
 645.956 ++  if (vtpm_rx_fh < 0) {
 645.957 ++		return -1;
 645.958 ++  }
 645.959 ++  
 645.960 ++  // Read Header of response so we can get the size & status
 645.961 ++#ifdef VTPM_MUTLI_VM
 645.962 ++  in_header_size = len = VTPM_COMMAND_HEADER_SIZE_CLT;
 645.963 ++#else
 645.964 ++  in_header_size = len = VTPM_COMMAND_HEADER_SIZE_SRV;
 645.965 ++#endif
 645.966 ++  in_header = ptr = malloc(in_header_size);
 645.967 ++  
 645.968 ++  printf("\tReading LoadNVM header\n");
 645.969 ++  res = read(vtpm_rx_fh, in_header, in_header_size);
 645.970 ++
 645.971 ++  if ( (res != in_header_size)
 645.972 ++#ifndef VTPM_MUTLI_VM
 645.973 ++       || tpm_unmarshal_UINT32(&ptr, &len, (UINT32*)&dmi_id)
 645.974 ++#endif
 645.975 ++       || tpm_unmarshal_UINT16(&ptr, &len, &tag)
 645.976 ++       || tpm_unmarshal_UINT32(&ptr, &len, &in_rsp_size)
 645.977 ++       || tpm_unmarshal_UINT32(&ptr, &len, &result) ) {
 645.978 ++      free(in_header);
 645.979 ++      return -1;
 645.980 ++  }
 645.981 ++  free(in_header);
 645.982 ++  
 645.983 ++  if (result != VTPM_SUCCESS) {
 645.984 ++      return -1;  
 645.985 ++  }
 645.986 ++
 645.987 ++  // Read Encrypted data from VTPM Manager
 645.988 ++  *data_length = in_rsp_size - VTPM_COMMAND_HEADER_SIZE_CLT;
 645.989 ++  *data = (uint8_t *) malloc(*data_length);
 645.990 ++
 645.991 ++  printf("\tReading clear data from LoadNVM.\n");
 645.992 ++  res = read(vtpm_rx_fh, *data, *data_length);
 645.993 ++#ifdef VTPM_MUTLI_VM
 645.994 ++  close(vtpm_rx_fh);close(vtpm_tx_fh);
 645.995 ++#endif 
 645.996 ++	
 645.997 ++  printf("\tReturing from loading NVM\n");
 645.998 +   if (res != *data_length) {
 645.999 +-    tpm_free(*data);
645.1000 +-    return -1;
645.1001 ++      free(*data);
645.1002 ++      return -1;
645.1003 ++  } else {
645.1004 ++      return 0;
645.1005 +   }
645.1006 +-  return 0;
645.1007 ++
645.1008 + }
645.1009 + 
645.1010 + #else
645.1011 +@@ -231,7 +431,6 @@ int tpm_restore_permanent_data(void)
645.1012 + 
645.1013 + int tpm_erase_permanent_data(void)
645.1014 + {
645.1015 +-  int res = write_to_file("", 0);
645.1016 ++  int res = write_to_file((uint8_t*)"", 0);
645.1017 +   return res;
645.1018 + }
645.1019 +-
645.1020 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_deprecated.c vtpm/tpm/tpm_deprecated.c
645.1021 +--- orig/tpm_emulator-0.2/tpm/tpm_deprecated.c	2005-08-17 10:58:36.000000000 -0700
645.1022 ++++ vtpm/tpm/tpm_deprecated.c	2005-08-17 10:55:52.000000000 -0700
645.1023 +@@ -1,6 +1,7 @@
645.1024 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
645.1025 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
645.1026 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
645.1027 ++ * Copyright (C) 2005 INTEL Corp
645.1028 +  *
645.1029 +  * This module is free software; you can redistribute it and/or modify
645.1030 +  * it under the terms of the GNU General Public License as published
645.1031 +@@ -50,7 +51,7 @@ TPM_RESULT TPM_SaveKeyContext(TPM_KEY_HA
645.1032 +   BYTE *ptr;
645.1033 +   UINT32 len;
645.1034 +   info("TPM_SaveKeyContext()");
645.1035 +-  res = TPM_SaveContext(keyHandle, TPM_RT_KEY, "SaveKeyContext..", 
645.1036 ++  res = TPM_SaveContext(keyHandle, TPM_RT_KEY, (BYTE*)"SaveKeyContext..", 
645.1037 +                         keyContextSize, &contextBlob);
645.1038 +   if (res != TPM_SUCCESS) return res;
645.1039 +   len = *keyContextSize;
645.1040 +@@ -82,7 +83,7 @@ TPM_RESULT TPM_SaveAuthContext(TPM_AUTHH
645.1041 +   BYTE *ptr;
645.1042 +   UINT32 len;
645.1043 +   info("TPM_SaveAuthContext()");
645.1044 +-  res = TPM_SaveContext(authHandle, TPM_RT_KEY, "SaveAuthContext.", 
645.1045 ++  res = TPM_SaveContext(authHandle, TPM_RT_KEY, (BYTE*)"SaveAuthContext.", 
645.1046 +                         authContextSize, &contextBlob);
645.1047 +   if (res != TPM_SUCCESS) return res;
645.1048 +   len = *authContextSize;
645.1049 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_emulator.h vtpm/tpm/tpm_emulator.h
645.1050 +--- orig/tpm_emulator-0.2/tpm/tpm_emulator.h	2005-08-17 10:58:36.000000000 -0700
645.1051 ++++ vtpm/tpm/tpm_emulator.h	2005-08-17 10:55:52.000000000 -0700
645.1052 +@@ -1,5 +1,6 @@
645.1053 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
645.1054 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
645.1055 ++ * Copyright (C) 2005 INTEL Corp
645.1056 +  *
645.1057 +  * This module is free software; you can redistribute it and/or modify
645.1058 +  * it under the terms of the GNU General Public License as published
645.1059 +@@ -22,7 +23,8 @@
645.1060 + /* TPM configuration */
645.1061 + #define TPM_STORE_TO_FILE       1
645.1062 + #undef  TPM_STRONG_PERSISTENCE
645.1063 +-#undef  TPM_GENERATE_EK
645.1064 ++//#undef  TPM_GENERATE_EK
645.1065 ++#define  TPM_GENERATE_EK
645.1066 + 
645.1067 + /**
645.1068 +  * tpm_emulator_init - initialises and starts the TPM emulator
645.1069 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_integrity.c vtpm/tpm/tpm_integrity.c
645.1070 +--- orig/tpm_emulator-0.2/tpm/tpm_integrity.c	2005-08-17 10:58:36.000000000 -0700
645.1071 ++++ vtpm/tpm/tpm_integrity.c	2005-08-17 10:55:52.000000000 -0700
645.1072 +@@ -1,6 +1,7 @@
645.1073 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
645.1074 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
645.1075 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
645.1076 ++ * Copyright (C) 2005 INTEL Corp
645.1077 +  *
645.1078 +  * This module is free software; you can redistribute it and/or modify
645.1079 +  * it under the terms of the GNU General Public License as published
645.1080 +@@ -194,4 +195,3 @@ TPM_RESULT tpm_verify_pcr(TPM_KEY_DATA *
645.1081 +   }
645.1082 +   return TPM_SUCCESS;
645.1083 + }
645.1084 +-
645.1085 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_structures.h vtpm/tpm/tpm_structures.h
645.1086 +--- orig/tpm_emulator-0.2/tpm/tpm_structures.h	2005-08-17 10:58:36.000000000 -0700
645.1087 ++++ vtpm/tpm/tpm_structures.h	2005-08-17 10:55:52.000000000 -0700
645.1088 +@@ -1,6 +1,7 @@
645.1089 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
645.1090 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
645.1091 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
645.1092 ++ * Copyright (C) 2005 INTEL Corp
645.1093 +  *
645.1094 +  * This module is free software; you can redistribute it and/or modify
645.1095 +  * it under the terms of the GNU General Public License as published
645.1096 +@@ -18,7 +19,7 @@
645.1097 + #ifndef _TPM_STRUCTURES_H_
645.1098 + #define _TPM_STRUCTURES_H_
645.1099 + 
645.1100 +-#include <linux/types.h>
645.1101 ++//#include <linux/types.h>
645.1102 + #include "crypto/rsa.h"
645.1103 + 
645.1104 + /*
645.1105 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_testing.c vtpm/tpm/tpm_testing.c
645.1106 +--- orig/tpm_emulator-0.2/tpm/tpm_testing.c	2005-08-17 10:58:36.000000000 -0700
645.1107 ++++ vtpm/tpm/tpm_testing.c	2005-08-17 10:55:52.000000000 -0700
645.1108 +@@ -1,6 +1,7 @@
645.1109 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
645.1110 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
645.1111 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
645.1112 ++ * Copyright (C) 2005 INTEL Corp
645.1113 +  *
645.1114 +  * This module is free software; you can redistribute it and/or modify
645.1115 +  * it under the terms of the GNU General Public License as published
645.1116 +@@ -95,24 +96,24 @@ static int tpm_test_sha1(void)
645.1117 +   struct {
645.1118 +     uint8_t *data; uint32_t repetitions; uint8_t *digest;
645.1119 +   } test_cases[] =  {{
645.1120 +-    "abc", 1,
645.1121 +-    "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D"
645.1122 ++	(uint8_t*)"abc", 1,
645.1123 ++    (uint8_t*)"\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D"
645.1124 +   }, {
645.1125 +-    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
645.1126 +-    "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1"
645.1127 ++    (uint8_t*)"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
645.1128 ++    (uint8_t*)"\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1"
645.1129 +   }, {
645.1130 +-    "a", 1000000,
645.1131 +-    "\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F"
645.1132 ++    (uint8_t*)"a", 1000000,
645.1133 ++    (uint8_t*)"\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F"
645.1134 +   }, {
645.1135 +-    "0123456701234567012345670123456701234567012345670123456701234567", 10,
645.1136 +-    "\xDE\xA3\x56\xA2\xCD\xDD\x90\xC7\xA7\xEC\xED\xC5\xEB\xB5\x63\x93\x4F\x46\x04\x52"
645.1137 ++    (uint8_t*)"0123456701234567012345670123456701234567012345670123456701234567", 10,
645.1138 ++    (uint8_t*)"\xDE\xA3\x56\xA2\xCD\xDD\x90\xC7\xA7\xEC\xED\xC5\xEB\xB5\x63\x93\x4F\x46\x04\x52"
645.1139 +   }};
645.1140 + 
645.1141 +   debug("tpm_test_sha1()");
645.1142 +   for (i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); i++) {
645.1143 +     sha1_init(&ctx);
645.1144 +     for (j = 0; j < test_cases[i].repetitions; j++)
645.1145 +-      sha1_update(&ctx, test_cases[i].data, strlen(test_cases[i].data));
645.1146 ++      sha1_update(&ctx, test_cases[i].data, strlen((char*)test_cases[i].data));
645.1147 +     sha1_final(&ctx, digest);
645.1148 +     if (memcmp(digest, test_cases[i].digest, SHA1_DIGEST_LENGTH) != 0) return -1;
645.1149 +   }
645.1150 +@@ -128,41 +129,41 @@ static int tpm_test_hmac(void)
645.1151 +   struct {
645.1152 +     uint8_t *key, key_len, *data, data_len, *digest;
645.1153 +   } test_cases[] = {{
645.1154 +-    "\x0b", 20, "Hi There", 8,
645.1155 +-    "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00"
645.1156 ++    (uint8_t*)"\x0b", 20, (uint8_t*)"Hi There", 8,
645.1157 ++    (uint8_t*)"\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00"
645.1158 +   }, {
645.1159 +-    "Jefe", 4, "what do ya want for nothing?", 28,
645.1160 +-    "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79"
645.1161 ++    (uint8_t*)"Jefe", 4, (uint8_t*)"what do ya want for nothing?", 28,
645.1162 ++    (uint8_t*)"\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79"
645.1163 +   }, {
645.1164 +-    "\xaa", 20, "\xdd", 50,
645.1165 +-    "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3"
645.1166 ++    (uint8_t*)"\xaa", 20, (uint8_t*)"\xdd", 50,
645.1167 ++    (uint8_t*)"\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3"
645.1168 +   }, {
645.1169 +-    "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
645.1170 +-    "\x15\x16\x17\x18\x19", 25, "\xcd", 50,
645.1171 +-    "\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda"
645.1172 ++    (uint8_t*)"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
645.1173 ++    "\x15\x16\x17\x18\x19", 25, (uint8_t*)"\xcd", 50,
645.1174 ++    (uint8_t*)"\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda"
645.1175 +   }, {
645.1176 +-    "\x0c", 20, "Test With Truncation", 20,
645.1177 +-    "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04"
645.1178 ++    (uint8_t*)"\x0c", 20, (uint8_t*)"Test With Truncation", 20,
645.1179 ++    (uint8_t*)"\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04"
645.1180 +   }, {
645.1181 +-    "\xaa", 80, "Test Using Larger Than Block-Size Key - Hash Key First", 54,
645.1182 +-    "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12"
645.1183 ++    (uint8_t*)"\xaa", 80, (uint8_t*)"Test Using Larger Than Block-Size Key - Hash Key First", 54,
645.1184 ++    (uint8_t*)"\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12"
645.1185 +   }, {
645.1186 +-    "\xaa", 80,
645.1187 +-    "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73,
645.1188 +-    "\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91"
645.1189 ++    (uint8_t*)"\xaa", 80,
645.1190 ++    (uint8_t*)"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73,
645.1191 ++    (uint8_t*)"\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91"
645.1192 +   }};
645.1193 + 
645.1194 +   debug("tpm_test_hmac()");
645.1195 +   for (i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); i++) {
645.1196 +-    if (strlen(test_cases[i].key) < test_cases[i].key_len) {
645.1197 ++    if (strlen((char*)test_cases[i].key) < test_cases[i].key_len) {
645.1198 +       uint8_t key[test_cases[i].key_len];
645.1199 +       memset(key, test_cases[i].key[0], test_cases[i].key_len);
645.1200 +       hmac_init(&ctx, key, test_cases[i].key_len);
645.1201 +     } else {
645.1202 +       hmac_init(&ctx, test_cases[i].key, test_cases[i].key_len);
645.1203 +     }
645.1204 +-    for (j = 0; j < test_cases[i].data_len; j += strlen(test_cases[i].data)) {
645.1205 +-      hmac_update(&ctx, test_cases[i].data, strlen(test_cases[i].data));
645.1206 ++    for (j = 0; j < test_cases[i].data_len; j += strlen((char*)test_cases[i].data)) {
645.1207 ++      hmac_update(&ctx, test_cases[i].data, strlen((char*)test_cases[i].data));
645.1208 +     }
645.1209 +     hmac_final(&ctx, digest);
645.1210 +     if (memcmp(digest, test_cases[i].digest, SHA1_DIGEST_LENGTH) != 0) return -1;
645.1211 +@@ -173,9 +174,9 @@ static int tpm_test_hmac(void)
645.1212 + static int tpm_test_rsa_EK(void)
645.1213 + {
645.1214 +   int res = 0;
645.1215 +-  char *data = "RSA PKCS #1 v1.5 Test-String";
645.1216 ++  uint8_t *data = (uint8_t*)"RSA PKCS #1 v1.5 Test-String";
645.1217 +   uint8_t buf[256];
645.1218 +-  size_t buf_len, data_len = strlen(data);
645.1219 ++  size_t buf_len, data_len = strlen((char*)data);
645.1220 +   rsa_private_key_t priv_key;
645.1221 +   rsa_public_key_t pub_key;
645.1222 + 
645.1223 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_ticks.c vtpm/tpm/tpm_ticks.c
645.1224 +--- orig/tpm_emulator-0.2/tpm/tpm_ticks.c	2005-08-17 10:58:36.000000000 -0700
645.1225 ++++ vtpm/tpm/tpm_ticks.c	2005-08-17 10:55:52.000000000 -0700
645.1226 +@@ -1,6 +1,7 @@
645.1227 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
645.1228 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
645.1229 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
645.1230 ++ * Copyright (C) 2005 INTEL Corp
645.1231 +  *
645.1232 +  * This module is free software; you can redistribute it and/or modify
645.1233 +  * it under the terms of the GNU General Public License as published
645.1234 +@@ -37,9 +38,7 @@ TPM_RESULT TPM_SetTickType(TPM_TICKTYPE 
645.1235 + TPM_RESULT TPM_GetTicks(TPM_CURRENT_TICKS *currentTime)
645.1236 + {
645.1237 +   info("TPM_GetTicks()");
645.1238 +-  memcpy(currentTime, &tpmData.stany.data.currentTicks, 
645.1239 +-    sizeof(TPM_CURRENT_TICKS));
645.1240 +-  return TPM_SUCCESS;
645.1241 ++  return TPM_DISABLED_CMD;
645.1242 + }
645.1243 + 
645.1244 + TPM_RESULT TPM_TickStampBlob(TPM_KEY_HANDLE keyHandle, TPM_NONCE *antiReplay,
645.1245 +@@ -47,61 +46,12 @@ TPM_RESULT TPM_TickStampBlob(TPM_KEY_HAN
645.1246 +                              TPM_CURRENT_TICKS *currentTicks, 
645.1247 +                              UINT32 *sigSize, BYTE **sig)
645.1248 + {
645.1249 +-  TPM_RESULT res;
645.1250 +-  TPM_KEY_DATA *key;
645.1251 +-  BYTE *info, *p;
645.1252 +-  UINT32 info_length, length;
645.1253 +   info("TPM_TickStampBlob()");
645.1254 +-  /* get key */
645.1255 +-  key = tpm_get_key(keyHandle);
645.1256 +-  if (key == NULL) return TPM_INVALID_KEYHANDLE;
645.1257 +-  /* verify authorization */ 
645.1258 +-  res = tpm_verify_auth(auth1, key->usageAuth, keyHandle);
645.1259 +-  if (res != TPM_SUCCESS) return res;
645.1260 +-  if (key->keyUsage != TPM_KEY_SIGNING && key->keyUsage != TPM_KEY_LEGACY
645.1261 +-      && key->keyUsage != TPM_KEY_IDENTITY) return TPM_INVALID_KEYUSAGE;
645.1262 +-  /* get current ticks */
645.1263 +-  TPM_GetTicks(currentTicks);
645.1264 +-  /* sign data using signature scheme PKCS1_SHA1 and TPM_SIGN_INFO container */
645.1265 +-  *sigSize = key->key.size >> 3;
645.1266 +-  *sig = tpm_malloc(*sigSize);
645.1267 +-  if (*sig == NULL) return TPM_FAIL; 
645.1268 +-  /* setup TPM_SIGN_INFO structure */
645.1269 +-  info_length = 30 + sizeof(TPM_DIGEST) + sizeof_TPM_CURRENT_TICKS(currentTicks);
645.1270 +-  info = tpm_malloc(info_length);
645.1271 +-  if (info == NULL) {
645.1272 +-    tpm_free(*sig);
645.1273 +-    return TPM_FAIL;
645.1274 +-  }
645.1275 +-  memcpy(&info[0], "\x05\x00TSTP", 6);
645.1276 +-  memcpy(&info[6], antiReplay->nonce, 20);
645.1277 +-  *(UINT32*)&info[26] = cpu_to_be32(20
645.1278 +-                        + sizeof_TPM_CURRENT_TICKS(currentTicks));
645.1279 +-  memcpy(&info[30], digestToStamp->digest, sizeof(TPM_DIGEST));
645.1280 +-  p = &info[30 + sizeof(TPM_DIGEST)]; 
645.1281 +-  length = sizeof_TPM_CURRENT_TICKS(currentTicks);
645.1282 +-  if (tpm_marshal_TPM_CURRENT_TICKS(&p, &length, currentTicks)
645.1283 +-      || rsa_sign(&key->key, RSA_SSA_PKCS1_SHA1, info, info_length, *sig)) {   
645.1284 +-    tpm_free(*sig);
645.1285 +-    tpm_free(info);
645.1286 +-    return TPM_FAIL;
645.1287 +-  } 
645.1288 +-  return TPM_SUCCESS;
645.1289 ++  return TPM_DISABLED_CMD;
645.1290 + }
645.1291 + 
645.1292 + void tpm_update_ticks(void)
645.1293 + {
645.1294 +-  if (tpmData.stany.data.currentTicks.tag == 0) {
645.1295 +-    tpmData.stany.data.currentTicks.tag = TPM_TAG_CURRENT_TICKS;
645.1296 +-    tpmData.stany.data.currentTicks.currentTicks += tpm_get_ticks();
645.1297 +-    tpmData.stany.data.currentTicks.tickType = tpmData.permanent.data.tickType;
645.1298 +-    tpm_get_random_bytes(tpmData.stany.data.currentTicks.tickNonce.nonce, 
645.1299 +-      sizeof(TPM_NONCE));
645.1300 +-    tpmData.stany.data.currentTicks.tickRate = 1;
645.1301 +-    tpmData.stany.data.currentTicks.tickSecurity = TICK_SEC_NO_CHECK;
645.1302 +-  } else {
645.1303 +-    tpmData.stany.data.currentTicks.currentTicks += tpm_get_ticks();   
645.1304 +-  }
645.1305 + }
645.1306 +   
645.1307 + 
645.1308 +diff -uprN orig/tpm_emulator-0.2/tpm/vtpm_manager.h vtpm/tpm/vtpm_manager.h
645.1309 +--- orig/tpm_emulator-0.2/tpm/vtpm_manager.h	1969-12-31 16:00:00.000000000 -0800
645.1310 ++++ vtpm/tpm/vtpm_manager.h	2005-08-17 10:55:52.000000000 -0700
645.1311 +@@ -0,0 +1,126 @@
645.1312 ++// ===================================================================
645.1313 ++// 
645.1314 ++// Copyright (c) 2005, Intel Corp.
645.1315 ++// All rights reserved.
645.1316 ++//
645.1317 ++// Redistribution and use in source and binary forms, with or without 
645.1318 ++// modification, are permitted provided that the following conditions 
645.1319 ++// are met:
645.1320 ++//
645.1321 ++//   * Redistributions of source code must retain the above copyright 
645.1322 ++//     notice, this list of conditions and the following disclaimer.
645.1323 ++//   * Redistributions in binary form must reproduce the above 
645.1324 ++//     copyright notice, this list of conditions and the following 
645.1325 ++//     disclaimer in the documentation and/or other materials provided 
645.1326 ++//     with the distribution.
645.1327 ++//   * Neither the name of Intel Corporation nor the names of its 
645.1328 ++//     contributors may be used to endorse or promote products derived
645.1329 ++//     from this software without specific prior written permission.
645.1330 ++//
645.1331 ++// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
645.1332 ++// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
645.1333 ++// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
645.1334 ++// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
645.1335 ++// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
645.1336 ++// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
645.1337 ++// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
645.1338 ++// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
645.1339 ++// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
645.1340 ++// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
645.1341 ++// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
645.1342 ++// OF THE POSSIBILITY OF SUCH DAMAGE.
645.1343 ++// ===================================================================
645.1344 ++// 
645.1345 ++// vtpm_manager.h
645.1346 ++// 
645.1347 ++//  Public Interface header for VTPM Manager
645.1348 ++//
645.1349 ++// ==================================================================
645.1350 ++
645.1351 ++#ifndef __VTPM_MANAGER_H__
645.1352 ++#define __VTPM_MANAGER_H__
645.1353 ++
645.1354 ++#define VTPM_TAG_REQ 0x01c1
645.1355 ++#define VTPM_TAG_RSP 0x01c4
645.1356 ++#define COMMAND_BUFFER_SIZE 4096
645.1357 ++
645.1358 ++// Header sizes. Note Header MAY include the DMI
645.1359 ++#define VTPM_COMMAND_HEADER_SIZE_SRV ( sizeof(UINT32) + sizeof(TPM_TAG) + sizeof(UINT32) + sizeof(TPM_COMMAND_CODE))
645.1360 ++#define VTPM_COMMAND_HEADER_SIZE_CLT (                  sizeof(TPM_TAG) + sizeof(UINT32) + sizeof(TPM_COMMAND_CODE))
645.1361 ++
645.1362 ++//************************ Command Codes ****************************
645.1363 ++#define VTPM_ORD_OPEN              1   // ULM Creates New DMI
645.1364 ++#define VTPM_ORD_CLOSE             2   // ULM Closes a DMI
645.1365 ++#define VTPM_ORD_DELETE            3   // ULM Permemently Deletes DMI
645.1366 ++#define VTPM_ORD_SAVENVM          4   // DMI requests Secrets Unseal
645.1367 ++#define VTPM_ORD_LOADNVM          5   // DMI requests Secrets Saved
645.1368 ++#define VTPM_ORD_TPMCOMMAND       6   // DMI issues HW TPM Command
645.1369 ++
645.1370 ++//************************ Return Codes ****************************
645.1371 ++#define VTPM_SUCCESS               0
645.1372 ++#define VTPM_FAIL                  1
645.1373 ++#define VTPM_UNSUPPORTED           2
645.1374 ++#define VTPM_FORBIDDEN             3
645.1375 ++#define VTPM_RESTORE_CONTEXT_FAILED    4
645.1376 ++#define VTPM_INVALID_REQUEST       5
645.1377 ++
645.1378 ++/******************* Command Parameter API *************************
645.1379 ++
645.1380 ++VTPM Command Format
645.1381 ++  dmi: 4 bytes                  // Source of message. 
645.1382 ++                                // WARNING: This is prepended by the channel. 
645.1383 ++                                // Thus it is received by VTPM Manager, 
645.1384 ++                                // but not sent by DMI
645.1385 ++  tpm tag: 2 bytes
645.1386 ++  command size: 4 bytes         // Size of command including header but not DMI
645.1387 ++  ord: 4 bytes                  // Command ordinal above
645.1388 ++  parameters: size - 10 bytes   // Command Parameter
645.1389 ++
645.1390 ++VTPM Response Format
645.1391 ++  tpm tag: 2 bytes
645.1392 ++  response_size: 4 bytes
645.1393 ++  status: 4 bytes         
645.1394 ++  parameters: size - 10 bytes
645.1395 ++
645.1396 ++
645.1397 ++VTPM_Open:
645.1398 ++  Input Parameters:
645.1399 ++    Domain_type: 1 byte
645.1400 ++    domain_id: 4 bytes
645.1401 ++    instance_id: 4 bytes
645.1402 ++  Output Parameters:
645.1403 ++    None
645.1404 ++    
645.1405 ++VTPM_Close
645.1406 ++  Input Parameters:
645.1407 ++    instance_id: 4 bytes
645.1408 ++  Output Parameters:
645.1409 ++    None
645.1410 ++
645.1411 ++VTPM_Delete
645.1412 ++  Input Parameters:
645.1413 ++    instance_id: 4 bytes
645.1414 ++  Output Parameters:
645.1415 ++    None
645.1416 ++
645.1417 ++VTPM_SaveNVM
645.1418 ++  Input Parameters:
645.1419 ++    data: n bytes (Header indicates size of data)
645.1420 ++  Output Parameters:
645.1421 ++    None
645.1422 ++
645.1423 ++VTPM_LoadNVM
645.1424 ++  Input Parameters:
645.1425 ++    None
645.1426 ++  Output Parameters:
645.1427 ++    data: n bytes (Header indicates size of data)
645.1428 ++
645.1429 ++VTPM_TPMCommand
645.1430 ++  Input Parameters:
645.1431 ++    TPM Command Byte Stream: n bytes 
645.1432 ++  Output Parameters:
645.1433 ++    TPM Reponse Byte Stream: n bytes 
645.1434 ++
645.1435 ++*********************************************************************/
645.1436 ++
645.1437 ++#endif //_VTPM_MANAGER_H_
645.1438 +diff -uprN orig/tpm_emulator-0.2/tpmd.c vtpm/tpmd.c
645.1439 +--- orig/tpm_emulator-0.2/tpmd.c	1969-12-31 16:00:00.000000000 -0800
645.1440 ++++ vtpm/tpmd.c	2005-08-17 10:55:52.000000000 -0700
645.1441 +@@ -0,0 +1,207 @@
645.1442 ++/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
645.1443 ++ * Copyright (C) 2005 INTEL Corp
645.1444 ++ *
645.1445 ++ * This module is free software; you can redistribute it and/or modify
645.1446 ++ * it under the terms of the GNU General Public License as published
645.1447 ++ * by the Free Software Foundation; either version 2 of the License,
645.1448 ++ * or (at your option) any later version.
645.1449 ++ *
645.1450 ++ * This module is distributed in the hope that it will be useful,
645.1451 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
645.1452 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
645.1453 ++ * GNU General Public License for more details.
645.1454 ++ *
645.1455 ++ */
645.1456 ++
645.1457 ++#include <stdio.h>
645.1458 ++#include <stdlib.h>
645.1459 ++#include <unistd.h>
645.1460 ++#include <string.h>
645.1461 ++#include <sys/types.h>
645.1462 ++#include <sys/stat.h>
645.1463 ++#include <fcntl.h>
645.1464 ++#include <sys/time.h>
645.1465 ++
645.1466 ++#include "tpm_emulator.h"
645.1467 ++#include "vtpm_manager.h"
645.1468 ++
645.1469 ++#ifdef VTPM_MULTI_VM
645.1470 ++ #define DEV_BE "/dev/vtpm"
645.1471 ++#else
645.1472 ++ #define GUEST_RX_FIFO_D "/var/vtpm/fifos/guest-to-%d.fifo"
645.1473 ++ #define GUEST_TX_FIFO "/var/vtpm/fifos/guest-from-all.fifo"
645.1474 ++
645.1475 ++ int dmi_id;
645.1476 ++#endif
645.1477 ++						
645.1478 ++#define BUFFER_SIZE 2048
645.1479 ++
645.1480 ++static uint8_t ctrl_msg[] = { 0, 0, 0, 0,   // destination
645.1481 ++                              1, 193,       // VTPM_TAG
645.1482 ++                              0, 0, 0, 10,  // Size
645.1483 ++                              0, 0, 0, 0};  // TPM_SUCCESS
645.1484 ++                            
645.1485 ++
645.1486 ++static int devurandom=0;
645.1487 ++
645.1488 ++	  
645.1489 ++void get_random_bytes(void *buf, int nbytes) {
645.1490 ++  
645.1491 ++  if (devurandom == 0) {
645.1492 ++    devurandom = open("/dev/urandom", O_RDONLY);
645.1493 ++  }
645.1494 ++
645.1495 ++  if (read(devurandom, buf, nbytes) != nbytes) {
645.1496 ++      printf("Can't get random number.\n");
645.1497 ++      exit(-1);
645.1498 ++  }
645.1499 ++}
645.1500 ++
645.1501 ++uint64_t tpm_get_ticks(void)
645.1502 ++{
645.1503 ++  //struct timeval tv;
645.1504 ++  //int gettimeofday(&tv, struct timezone *tz);
645.1505 ++  return 0;
645.1506 ++}
645.1507 ++
645.1508 ++int main(int argc, char **argv)
645.1509 ++{
645.1510 ++  uint8_t in[BUFFER_SIZE], *out, *addressed_out;
645.1511 ++  uint32_t out_size;
645.1512 ++  int in_size, written ;
645.1513 ++  int i, guest_id=-1;
645.1514 ++ 
645.1515 ++  int vtpm_tx_fh=-1, vtpm_rx_fh=-1;
645.1516 ++#ifdef VTPM_MULTI_VM
645.1517 ++  if (argc < 2) {
645.1518 ++    printf("Usage: tpmd clear|save|deactivated\n" );
645.1519 ++#else
645.1520 ++  if (argc < 3) {
645.1521 ++    printf("Usage: tpmd clear|save|deactivated vtpmid\n" );
645.1522 ++#endif
645.1523 ++	  return -1;
645.1524 ++  }
645.1525 ++
645.1526 ++#ifndef VTPM_MULTI_VM
645.1527 ++  dmi_id = atoi(argv[2]);
645.1528 ++#endif
645.1529 ++
645.1530 ++  /* initialize TPM emulator */
645.1531 ++  if (!strcmp(argv[1], "clear")) {
645.1532 ++    printf("Initializing tpm: %s\n", argv[1]);
645.1533 ++    tpm_emulator_init(1);
645.1534 ++  } else if (!strcmp(argv[1], "save")) { 
645.1535 ++    printf("Initializing tpm: %s\n", argv[1]);
645.1536 ++    tpm_emulator_init(2);
645.1537 ++  } else if (!strcmp(argv[1], "deactivated")) {
645.1538 ++    printf("Initializing tpm: %s\n", argv[1]);
645.1539 ++    tpm_emulator_init(3);
645.1540 ++  } else {
645.1541 ++    printf("invalid startup mode '%s'; must be 'clear', "
645.1542 ++      "'save' (default) or 'deactivated", argv[1]);
645.1543 ++    return -1;
645.1544 ++  }
645.1545 ++
645.1546 ++  char *guest_rx_file = malloc(10 + strlen(GUEST_RX_FIFO_D));
645.1547 ++  sprintf(guest_rx_file, GUEST_RX_FIFO_D, (uint32_t) dmi_id);
645.1548 ++  
645.1549 ++  while (1) {
645.1550 ++abort_command:
645.1551 ++    if (vtpm_rx_fh < 0) {
645.1552 ++#ifdef VTPM_MUTLI_VM
645.1553 ++	  vtpm_rx_fh = open(DEV_BE, O_RDWR);
645.1554 ++#else
645.1555 ++      vtpm_rx_fh = open(guest_rx_file, O_RDONLY);
645.1556 ++#endif
645.1557 ++    }
645.1558 ++    
645.1559 ++    if (vtpm_rx_fh < 0) {
645.1560 ++      printf("ERROR: failed to open devices to listen to guest.\n");
645.1561 ++      return -1;
645.1562 ++    }
645.1563 ++    
645.1564 ++    in_size = read(vtpm_rx_fh, in, BUFFER_SIZE);
645.1565 ++    if (in_size < 6) { // Magic size of minium TPM command
645.1566 ++      printf("Recv[%d] to small: 0x", in_size);
645.1567 ++      if (in_size <= 0) {
645.1568 ++          close(vtpm_rx_fh);
645.1569 ++          vtpm_rx_fh = -1;
645.1570 ++          goto abort_command;
645.1571 ++      }
645.1572 ++    } else { 
645.1573 ++      printf("Recv[%d]: 0x", in_size);
645.1574 ++      for (i=0; i< in_size; i++) 
645.1575 ++        printf("%x ", in[i]);
645.1576 ++      printf("\n");
645.1577 ++    }
645.1578 ++
645.1579 ++    if (guest_id == -1) {
645.1580 ++        guest_id = *((uint32_t *) in);
645.1581 ++        *((uint32_t *) ctrl_msg) = *((uint32_t *) in);
645.1582 ++    } else {
645.1583 ++        if (guest_id != *((uint32_t *) in) ) {
645.1584 ++            printf("WARNING: More than one guest attached\n");
645.1585 ++        }
645.1586 ++    }
645.1587 ++
645.1588 ++    if (vtpm_tx_fh < 0) {
645.1589 ++#ifdef VTPM_MUTLI_VM
645.1590 ++	  vtpm_tx_fh = open(DEV_BE, O_RDWR);
645.1591 ++	  vtpm_rx_fh = vtpm_tx_fh;
645.1592 ++#else
645.1593 ++      vtpm_tx_fh = open(GUEST_TX_FIFO, O_WRONLY);
645.1594 ++#endif
645.1595 ++    }
645.1596 ++
645.1597 ++    if (vtpm_tx_fh < 0) {
645.1598 ++      printf("ERROR: failed to open devices to respond to guest.\n");
645.1599 ++      return -1;
645.1600 ++    }
645.1601 ++    
645.1602 ++    // Handle command, but we need to skip the identifier
645.1603 ++    if (  BE16_TO_CPU( ((uint16_t *) in)[2] ) == VTPM_TAG_REQ ) { // Control message from xend
645.1604 ++      // This DM doesn't really care about ctrl messages. Just ACK the message
645.1605 ++      written = write(vtpm_tx_fh, ctrl_msg, sizeof(ctrl_msg));
645.1606 ++
645.1607 ++      if (written != sizeof(ctrl_msg)) {
645.1608 ++        printf("ERROR: Part of response not written %d/%d.\n", written, sizeof(ctrl_msg));
645.1609 ++      } else {
645.1610 ++        printf("Send Ctrl Message confermation\n");
645.1611 ++      }
645.1612 ++    } else { // Message from Guest
645.1613 ++      if (tpm_handle_command(in + sizeof(uint32_t), in_size - sizeof(uint32_t), &out, &out_size) != 0) { 
645.1614 ++        printf("ERROR: Handler Failed.\n");
645.1615 ++      }
645.1616 ++
645.1617 ++      addressed_out = (uint8_t *) tpm_malloc(sizeof(uint32_t) + out_size);
645.1618 ++      *(uint32_t *) addressed_out = *(uint32_t *) in;
645.1619 ++      memcpy(addressed_out + sizeof(uint32_t), out, out_size);
645.1620 ++
645.1621 ++      written = write(vtpm_tx_fh, addressed_out, out_size + sizeof(uint32_t));
645.1622 ++
645.1623 ++      if (written != out_size + sizeof(uint32_t)) {
645.1624 ++        printf("ERROR: Part of response not written %d/%d.\n", written, out_size);
645.1625 ++        for (i=0; i< out_size+ sizeof(uint32_t); i++)
645.1626 ++          printf("%x ", addressed_out[i]);
645.1627 ++        printf("\n");
645.1628 ++      } else {
645.1629 ++        printf("Sent[%d]: ", out_size + sizeof(uint32_t));
645.1630 ++        for (i=0; i< out_size+ sizeof(uint32_t); i++)
645.1631 ++          printf("%x ", addressed_out[i]);
645.1632 ++        printf("\n");
645.1633 ++      }
645.1634 ++      tpm_free(out);
645.1635 ++      tpm_free(addressed_out);
645.1636 ++    }
645.1637 ++
645.1638 ++  } // loop
645.1639 ++
645.1640 ++  tpm_emulator_shutdown();
645.1641 ++
645.1642 ++  close(vtpm_tx_fh);
645.1643 ++#ifndef VTPM_MUTLI_VM
645.1644 ++  close(vtpm_rx_fh);
645.1645 ++  free (guest_rx_file);
645.1646 ++#endif
645.1647 ++
645.1648 ++}
   646.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   646.2 +++ b/tools/vtpm_manager/COPYING	Thu Sep 01 10:16:14 2005 +0000
   646.3 @@ -0,0 +1,32 @@
   646.4 +// ===================================================================
   646.5 +// 
   646.6 +// Copyright (c) 2005, Intel Corp.
   646.7 +// All rights reserved.
   646.8 +//
   646.9 +// Redistribution and use in source and binary forms, with or without 
  646.10 +// modification, are permitted provided that the following conditions 
  646.11 +// are met:
  646.12 +//
  646.13 +//   * Redistributions of source code must retain the above copyright 
  646.14 +//     notice, this list of conditions and the following disclaimer.
  646.15 +//   * Redistributions in binary form must reproduce the above 
  646.16 +//     copyright notice, this list of conditions and the following 
  646.17 +//     disclaimer in the documentation and/or other materials provided 
  646.18 +//     with the distribution.
  646.19 +//   * Neither the name of Intel Corporation nor the names of its 
  646.20 +//     contributors may be used to endorse or promote products derived
  646.21 +//     from this software without specific prior written permission.
  646.22 +//
  646.23 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  646.24 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  646.25 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
  646.26 +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
  646.27 +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  646.28 +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  646.29 +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
  646.30 +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  646.31 +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
  646.32 +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
  646.33 +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  646.34 +// OF THE POSSIBILITY OF SUCH DAMAGE.
  646.35 +// ===================================================================
   647.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   647.2 +++ b/tools/vtpm_manager/Makefile	Thu Sep 01 10:16:14 2005 +0000
   647.3 @@ -0,0 +1,31 @@
   647.4 +XEN_ROOT = ../..
   647.5 +
   647.6 +# Base definitions and rules
   647.7 +include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
   647.8 +
   647.9 +SUBDIRS		= crypto tcs util manager
  647.10 +
  647.11 +all: build
  647.12 +
  647.13 +build:
  647.14 +	@set -e; for subdir in $(SUBDIRS); do \
  647.15 +		$(MAKE) -C $$subdir $@; \
  647.16 +	done
  647.17 +
  647.18 +install: build
  647.19 +	@set -e; for subdir in $(SUBDIRS); do \
  647.20 +		$(MAKE) -C $$subdir $@; \
  647.21 +	done
  647.22 +
  647.23 +clean:
  647.24 +	@set -e; for subdir in $(SUBDIRS); do \
  647.25 +		$(MAKE) -C $$subdir $@; \
  647.26 +	done
  647.27 +
  647.28 +
  647.29 +mrproper:
  647.30 +	@set -e; for subdir in $(SUBDIRS); do \
  647.31 +		$(MAKE) -C $$subdir $@; \
  647.32 +	done
  647.33 +
  647.34 +
   648.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   648.2 +++ b/tools/vtpm_manager/README	Thu Sep 01 10:16:14 2005 +0000
   648.3 @@ -0,0 +1,89 @@
   648.4 +// ===================================================================
   648.5 +//
   648.6 +// Copyright (c) 2005, Intel Corp.
   648.7 +// All rights reserved.
   648.8 +//
   648.9 +// Redistribution and use in source and binary forms, with or without
  648.10 +// modification, are permitted provided that the following conditions
  648.11 +// are met:
  648.12 +//
  648.13 +//   * Redistributions of source code must retain the above copyright
  648.14 +//     notice, this list of conditions and the following disclaimer.
  648.15 +//   * Redistributions in binary form must reproduce the above
  648.16 +//     copyright notice, this list of conditions and the following
  648.17 +//     disclaimer in the documentation and/or other materials provided
  648.18 +//     with the distribution.
  648.19 +//   * Neither the name of Intel Corporation nor the names of its
  648.20 +//     contributors may be used to endorse or promote products derived
  648.21 +//     from this software without specific prior written permission.
  648.22 +//
  648.23 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  648.24 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  648.25 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  648.26 +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  648.27 +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  648.28 +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  648.29 +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  648.30 +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  648.31 +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  648.32 +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  648.33 +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  648.34 +// OF THE POSSIBILITY OF SUCH DAMAGE.
  648.35 +// ===================================================================
  648.36 +
  648.37 +Directory Structure
  648.38 +===================
  648.39 +tools/vtpm_manager/crypto    -> crypto files
  648.40 +tools/vtpm_manager/TCS       -> TCS implementation
  648.41 +tools/vtpm_manager/util      -> Utility Library. Include disk-io and buffers.
  648.42 +tools/vtpm_manager/manager   -> VTPM Manager
  648.43 +
  648.44 +Compile Flags
  648.45 +===================
  648.46 +LOGGING_MODULES              -> How extensive logging happens
  648.47 +                                see util/log.h for more info
  648.48 +
  648.49 +VTPM_MULTI_VM                -> Defined: VTPMs run in their own VMs
  648.50 +                                Not Defined (default): VTPMs are processes
  648.51 +
  648.52 +# Debugging flags that may disappear without notice in the future
  648.53 +
  648.54 +DUMMY_BACKEND                -> vtpm_manager listens on /tmp/in.fifo and 
  648.55 +                                /tmp/out.fifo rather than backend
  648.56 +
  648.57 +MANUAL_DM_LAUNCH             -> User must manually launch & kill VTPMs
  648.58 +
  648.59 +USE_FIXED_SRK_AUTH           -> Do not randomly generate a random SRK & Owner auth
  648.60 +
  648.61 +Requirements
  648.62 +============
  648.63 +- xen-unstable 
  648.64 +- IBM frontend/backend vtpm driver patch
  648.65 +
  648.66 +Single-VM Flow
  648.67 +============================
  648.68 +- Launch the VTPM manager (vtpm_managerd) which which begins listening to the BE with one thread
  648.69 +  and listens to a named fifo that is shared by the vtpms to commuincate with the manager.
  648.70 +- VTPM Manager listens to TPM BE.
  648.71 +- When xend launches a tpm frontend equipped VM it contacts the manager over the vtpm backend. 
  648.72 +- When the manager receives the open message from the BE, it launches a vtpm
  648.73 +- Xend allows the VM to continue booting. 
  648.74 +- When a TPM request is issued to the front end, the front end transmits the TPM request to the backend.
  648.75 +- The manager receives the TPM requests and uses a named fifo to forward the request to the vtpm.
  648.76 +- The fifo listener begins listening for the reply from vtpm for the request.
  648.77 +- Vtpm processes request and replies to manager over shared named fifo.
  648.78 +- If needed, the vtpm may send a request to the vtpm_manager at any time to save it's secrets to disk.
  648.79 +- Manager receives response from vtpm and passes it back to backend for forwarding to guest.
  648.80 +
  648.81 +NOTES:
  648.82 +* SaveService SHOULD seal it's table before saving it to disk. However,
  648.83 +  the current Xen infrastructure does not provide a mechanism for this to be
  648.84 +  unsealed later. Specifically, the auth and wrapped key must be available ONLY
  648.85 +  to the service, or it's not even worth encrypting
  648.86 +
  648.87 +  In the future the vtpm manager will be protected by an early boot mechanism
  648.88 +  that will allow for better protection of it's data.
  648.89 +
  648.90 +TODO:
  648.91 +- Timeout on crashed vtpms
  648.92 +- create lock for shared fifo for talking to vtpms.
   649.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   649.2 +++ b/tools/vtpm_manager/Rules.mk	Thu Sep 01 10:16:14 2005 +0000
   649.3 @@ -0,0 +1,68 @@
   649.4 +# Base definitions and rules (XEN_ROOT must be defined in including Makefile)
   649.5 +include $(XEN_ROOT)/tools/Rules.mk
   649.6 +
   649.7 +#
   649.8 +# Tool definitions
   649.9 +#
  649.10 +
  649.11 +# Installation program and options
  649.12 +INSTALL         = install
  649.13 +INSTALL_PROG    = $(INSTALL) -m0755
  649.14 +INSTALL_DIR     = $(INSTALL) -d -m0755
  649.15 +
  649.16 +# Xen tools installation directory
  649.17 +TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
  649.18 +
  649.19 +# General compiler flags
  649.20 +CFLAGS	= -Wall -Werror -g3 -I.
  649.21 +
  649.22 +# For generating dependencies
  649.23 +CFLAGS	+= -Wp,-MD,.$(@F).d
  649.24 +
  649.25 +DEP_FILES	= .*.d
  649.26 +
  649.27 +# Generic project files
  649.28 +HDRS	= $(wildcard *.h)
  649.29 +SRCS	= $(wildcard *.c)
  649.30 +OBJS	= $(patsubst %.c,%.o,$(SRCS))
  649.31 +
  649.32 +# Generic (non-header) dependencies
  649.33 +$(SRCS): Makefile $(XEN_ROOT)/tools/Rules.mk $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
  649.34 +
  649.35 +$(OBJS): $(SRCS)
  649.36 +
  649.37 +-include $(DEP_FILES)
  649.38 +
  649.39 +# Make sure these are just rules
  649.40 +.PHONY : all build install clean
  649.41 +
  649.42 +#
  649.43 +# Project-specific definitions
  649.44 +#
  649.45 +
  649.46 +# Logging Level. See utils/tools.h for usage
  649.47 +CFLAGS += -DLOGGING_MODULES="(BITMASK(VTPM_LOG_TCS)|BITMASK(VTPM_LOG_VTSP)|BITMASK(VTPM_LOG_VTPM)|BITMASK(VTPM_LOG_VTPM_DEEP))"
  649.48 +
  649.49 +# Silent Mode
  649.50 +#CFLAGS += -DLOGGING_MODULES=0x0
  649.51 +#CFLAGS += -DLOGGING_MODULES=0xff
  649.52 +
  649.53 +# Use frontend/backend pairs between manager & DMs?
  649.54 +#CFLAGS += -DVTPM_MULTI_VM
  649.55 +
  649.56 +# vtpm_manager listens on /tmp/in.fifo and /tmp/out.fifo rather than backend
  649.57 +#CFLAGS += -DDUMMY_BACKEND
  649.58 +
  649.59 +# Do not have manager launch DMs.
  649.60 +#CFLAGS += -DMANUAL_DM_LAUNCH
  649.61 +
  649.62 +# Fixed SRK
  649.63 +CFLAGS += -DUSE_FIXED_SRK_AUTH
  649.64 +
  649.65 +# TPM Hardware Device or TPM Simulator
  649.66 +#CFLAGS += -DTPM_HWDEV
  649.67 +
  649.68 +# Include
  649.69 +CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/crypto
  649.70 +CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/util
  649.71 +CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/tcs
   650.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   650.2 +++ b/tools/vtpm_manager/crypto/Makefile	Thu Sep 01 10:16:14 2005 +0000
   650.3 @@ -0,0 +1,18 @@
   650.4 +XEN_ROOT = ../../..
   650.5 +include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
   650.6 +
   650.7 +BIN		= libtcpaCrypto.a
   650.8 +
   650.9 +all: build
  650.10 +
  650.11 +build: $(BIN)
  650.12 +
  650.13 +install: build
  650.14 +
  650.15 +clean:
  650.16 +	rm -f *.a *.so *.o *.rpm $(DEP_FILES)
  650.17 +
  650.18 +mrproper: clean
  650.19 +
  650.20 +$(BIN): $(OBJS)
  650.21 +	$(AR) rcs $(BIN) $(OBJS)
   651.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   651.2 +++ b/tools/vtpm_manager/crypto/crypto.c	Thu Sep 01 10:16:14 2005 +0000
   651.3 @@ -0,0 +1,88 @@
   651.4 +// ===================================================================
   651.5 +// 
   651.6 +// Copyright (c) 2005, Intel Corp.
   651.7 +// All rights reserved.
   651.8 +//
   651.9 +// Redistribution and use in source and binary forms, with or without 
  651.10 +// modification, are permitted provided that the following conditions 
  651.11 +// are met:
  651.12 +//
  651.13 +//   * Redistributions of source code must retain the above copyright 
  651.14 +//     notice, this list of conditions and the following disclaimer.
  651.15 +//   * Redistributions in binary form must reproduce the above 
  651.16 +//     copyright notice, this list of conditions and the following 
  651.17 +//     disclaimer in the documentation and/or other materials provided 
  651.18 +//     with the distribution.
  651.19 +//   * Neither the name of Intel Corporation nor the names of its 
  651.20 +//     contributors may be used to endorse or promote products derived
  651.21 +//     from this software without specific prior written permission.
  651.22 +//
  651.23 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  651.24 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  651.25 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
  651.26 +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
  651.27 +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  651.28 +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  651.29 +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
  651.30 +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  651.31 +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
  651.32 +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
  651.33 +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  651.34 +// OF THE POSSIBILITY OF SUCH DAMAGE.
  651.35 +// ===================================================================
  651.36 +// 
  651.37 +// crypto.c
  651.38 +// 
  651.39 +//  This file will handle all the TPM Crypto functionality
  651.40 +// 
  651.41 +// ==================================================================
  651.42 +
  651.43 +#include <string.h>
  651.44 +#include <openssl/crypto.h>
  651.45 +#include <openssl/err.h>
  651.46 +#include <openssl/evp.h>
  651.47 +#include <openssl/rand.h>
  651.48 +#include "crypto.h"
  651.49 +#include "log.h"
  651.50 +
  651.51 +/**
  651.52 + * Initialize cryptography library
  651.53 + * @rand: random seed
  651.54 + * @size: size of @rand
  651.55 + */
  651.56 +void Crypto_Init(const BYTE* rand, int size) {
  651.57 +	ERR_load_crypto_strings();
  651.58 +  CRYPTO_malloc_init();
  651.59 +  OpenSSL_add_all_algorithms();
  651.60 +  SYM_CIPHER = EVP_aes_128_cbc();
  651.61 +  RAND_poll();
  651.62 +  if (rand == NULL)
  651.63 +    return;
  651.64 +
  651.65 +  RAND_add(rand, size, size);
  651.66 +}
  651.67 +
  651.68 +/**
  651.69 + * Shutdown cryptography library
  651.70 + */
  651.71 +void Crypto_Exit() {
  651.72 +  ERR_free_strings();
  651.73 +  ERR_remove_state(0);
  651.74 +  EVP_cleanup();
  651.75 +}
  651.76 +
  651.77 +
  651.78 +/**
  651.79 + * Get random data
  651.80 + * @data: (OUT) Random data
  651.81 + * @size: Size of @data
  651.82 + */
  651.83 +void Crypto_GetRandom(void* data, int size) {
  651.84 +  int result;
  651.85 +  
  651.86 +  result = RAND_pseudo_bytes((BYTE*) data, size);
  651.87 +  
  651.88 +  if (result <= 0) 
  651.89 +    vtpmlogerror (VTPM_LOG_CRYPTO, "RAND_pseudo_bytes failed: %s\n",
  651.90 +	     ERR_error_string (ERR_get_error(), NULL));
  651.91 +}
   652.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   652.2 +++ b/tools/vtpm_manager/crypto/crypto.h	Thu Sep 01 10:16:14 2005 +0000
   652.3 @@ -0,0 +1,175 @@
   652.4 +// ===================================================================
   652.5 +// 
   652.6 +// Copyright (c) 2005, Intel Corp.
   652.7 +// All rights reserved.
   652.8 +//
   652.9 +// Redistribution and use in source and binary forms, with or without 
  652.10 +// modification, are permitted provided that the following conditions 
  652.11 +// are met:
  652.12 +//
  652.13 +//   * Redistributions of source code must retain the above copyright 
  652.14 +//     notice, this list of conditions and the following disclaimer.
  652.15 +//   * Redistributions in binary form must reproduce the above 
  652.16 +//     copyright notice, this list of conditions and the following 
  652.17 +//     disclaimer in the documentation and/or other materials provided 
  652.18 +//     with the distribution.
  652.19 +//   * Neither the name of Intel Corporation nor the names of its 
  652.20 +//     contributors may be used to endorse or promote products derived
  652.21 +//     from this software without specific prior written permission.
  652.22 +//
  652.23 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  652.24 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
  652.25 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
  652.26 +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
  652.27 +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  652.28 +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  652.29 +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
  652.30 +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  652.31 +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
  652.32 +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
  652.33 +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  652.34 +// OF THE POSSIBILITY OF SUCH DAMAGE.
  652.35 +// ===================================================================
  652.36 +// 
  652.37 +// crypto.h
  652.38 +// 
  652.39 +//  This file defines the TPM Crypto API
  652.40 +//
  652.41 +// ==================================================================
  652.42 +
  652.43 +#ifndef __CRYPTO_H__
  652.44 +#define __CRYPTO_H__
  652.45 +
  652.46 +#include <stddef.h>
  652.47 +#include <stdint.h>
  652.48 +#include <stdbool.h>
  652.49 +
  652.50 +#include "tcg.h"
  652.51 +#include "sym_crypto.h"
  652.52 +
  652.53 +#define CRYPTO_MAX_SIG_SIZE (2048 / 8)
  652.54 +#define CRYPTO_MAX_RSA_KEY_SIZE (4096 / 8) //in bytes
  652.55 +
  652.56 +#define OAEP_P "TCPA"
  652.57 +#define OAEP_P_SIZE 4
  652.58 +
  652.59 +// Algorithms supported by crypto. Stored in CRYPTO_INFO.algorithmID
  652.60 +#define CRYPTO_ALGORITH_RSA 0x01
  652.61 +
  652.62 +// Supported Encryption Schemes CRYPTO_INFO.encScheme
  652.63 +#define CRYPTO_ES_NONE 0x0001
  652.64 +#define CRYPTO_ES_RSAESPKCSv15 0x0002
  652.65 +#define CRYPTO_ES_RSAESOAEP_SHA1_MGF1 0x0003
  652.66 +
  652.67 +// Supported Signature schemes CRYPTO_INFO.sigScheme
  652.68 +#define CRYPTO_SS_NONE 0x0001
  652.69 +#define CRYPTO_SS_RSASSAPKCS1v15_SHA1 0x0002
  652.70 +#define CRYPTO_SS_RSASSAPKCS1v15_DER 0x0003
  652.71 +
  652.72 +typedef struct CRYPTO_INFO {
  652.73 +  void *keyInfo;
  652.74 +  UINT32 algorithmID;
  652.75 +  UINT32 encScheme;
  652.76 +  UINT32 sigScheme;
  652.77 +} CRYPTO_INFO;
  652.78 +
  652.79 +
  652.80 +void Crypto_Init(const BYTE* rand, int size);
  652.81 +
  652.82 +void Crypto_Exit();
  652.83 +
  652.84 +void Crypto_GetRandom(void* data, int size);
  652.85 +
  652.86 +void Crypto_HMAC(   const BYTE* text, 
  652.87 +                    int text_len, 
  652.88 +                    const BYTE* key, 
  652.89 +                    int key_len,
  652.90 +                    BYTE* digest);
  652.91 +
  652.92 +TPM_RESULT Crypto_HMAC_buf (const buffer_t * text,
  652.93 +                            const buffer_t * key,
  652.94 +                            BYTE * o_digest); /* presumably of 20 bytes */
  652.95 +    
  652.96 +void Crypto_SHA1Full(   const BYTE* text, 
  652.97 +                        UINT32 size,
  652.98 +                        BYTE* hash); //Complete 3part SHA1
  652.99 +
 652.100 +// o_hash needs to be large enough to hold the digest, ie 20 bytes
 652.101 +TPM_RESULT Crypto_SHA1Full_buf (const buffer_t * buf,
 652.102 +                                BYTE * o_hash);
 652.103 +    
 652.104 +void Crypto_SHA1Start(UINT32* maxNumBytes);
 652.105 +void Crypto_SHA1Update(int numBytes, const BYTE* hashData);
 652.106 +void Crypto_SHA1Complete(   int hashDataSize, 
 652.107 +                            const BYTE* hashData, 
 652.108 +                            BYTE* hashValue);
 652.109 +
 652.110 +void Crypto_RSACreateKey(   /*in*/ UINT32 keySize,
 652.111 +                            /*in*/ UINT32 pubExpSize, 
 652.112 +                            /*in*/ BYTE *pubExp,
 652.113 +                            /*out*/ UINT32 *privExpSize, 
 652.114 +                            /*out*/ BYTE *privExp,
 652.115 +                            /*out*/ UINT32 *modulusSize,
 652.116 +                            /*out*/ BYTE *modulus,
 652.117 +                            /*out*/ CRYPTO_INFO *keys);
 652.118 +                            
 652.119 +void Crypto_RSABuildCryptoInfo( /*[IN]*/ UINT32 pubExpSize, 
 652.120 +                                /*[IN]*/ BYTE *pubExp,
 652.121 +                                /*[IN]*/ UINT32 privExpSize, 
 652.122 +                                /*[IN]*/ BYTE *privExp,
 652.123 +                                /*[IN]*/ UINT32 modulusSize, 
 652.124 +                                /*[IN]*/ BYTE *modulus, 
 652.125 +                                /*[OUT]*/ CRYPTO_INFO* cryptoInfo);
 652.126 +                                
 652.127 +void Crypto_RSABuildCryptoInfoPublic(   /*[IN]*/ UINT32 pubExpSize, 
 652.128 +                                        /*[IN]*/ BYTE *pubExp,
 652.129 +                                        /*[IN]*/ UINT32 modulusSize, 
 652.130 +                                        /*[IN]*/ BYTE *modulus, 
 652.131 +                                        CRYPTO_INFO* cryptoInfo);
 652.132 +
 652.133 +//
 652.134 +// symmetric pack and unpack operations
 652.135 +//
 652.136 +TPM_RESULT Crypto_RSAPackCryptoInfo (const CRYPTO_INFO* cryptoInfo,
 652.137 +                                     BYTE ** io_buf, UINT32 * io_buflen);
 652.138 +
 652.139 +TPM_RESULT Crypto_RSAUnpackCryptoInfo (CRYPTO_INFO * ci,
 652.140 +                                       BYTE * in, UINT32 len,
 652.141 +                                       UINT32 * o_lenread);
 652.142 +
 652.143 +                             
 652.144 +// return 0 on success, -1 on error
 652.145 +int Crypto_RSAEnc(  CRYPTO_INFO *keys,
 652.146 +                    UINT32 inDataSize,
 652.147 +                    BYTE *inData,
 652.148 +                    /*out*/ UINT32 *outDataSize,
 652.149 +                    /*out*/ BYTE *outData);
 652.150 +
 652.151 +// return 0 on success, -1 on error
 652.152 +int Crypto_RSADec(  CRYPTO_INFO *keys,
 652.153 +                    UINT32 inDataSize,
 652.154 +                    BYTE *inData,
 652.155 +                    /*out*/ UINT32 *outDataSize,
 652.156 +                    /*out*/ BYTE *outData);
 652.157 +
 652.158 +// return 0 on success, -1 on error
 652.159 +int Crypto_RSASign( CRYPTO_INFO *keys,
 652.160 +                    UINT32 inDataSize,
 652.161 +                    BYTE *inData,
 652.162 +                    /*out*/ UINT32 *sigSize,
 652.163 +                    /*out*/ BYTE *sig);
 652.164 +
 652.165 +bool Crypto_RSAVerify(  CRYPTO_INFO *keys,
 652.166 +                        UINT32 inDataSize,
 652.167 +                        BYTE *inData,
 652.168 +                        UINT32 sigSize,
 652.169 +                        BYTE *sig);
 652.170 +
 652.171 +//private:
 652.172 +int RSA_verify_DER(int dtype, unsigned char *m, unsigned int m_len,
 652.173 +                   unsigned char *sigbuf, unsigned int siglen, CRYPTO_INFO *key);
 652.174 +
 652.175 +int RSA_sign_DER(int type, unsigned char *m, unsigned int m_len,
 652.176 +              unsigned char *sigret, unsigned int *siglen, CRYPTO_INFO *key);
 652.177 +
 652.178 +#endif // __CRYPTO_H__
   653.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   653.2 +++ b/tools/vtpm_manager/crypto/hash.c	Thu Sep 01 10:16:14 2005 +0000
   653.3