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)
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/docs/misc/vtpm.txt	Thu Sep 01 10:16:14 2005 +0000
     5.3 @@ -0,0 +1,122 @@
     5.4 +Copyright: IBM Corporation (C), Intel Corporation
     5.5 +17 August 2005
     5.6 +Authors: Stefan Berger <stefanb@us.ibm.com> (IBM), 
     5.7 +         Employees of Intel Corp
     5.8 +
     5.9 +This document gives a short introduction to the virtual TPM support
    5.10 +in XEN and goes as far as connecting a user domain to a virtual TPM
    5.11 +instance and doing a short test to verify success. It is assumed
    5.12 +that the user is fairly familiar with compiling and installing XEN
    5.13 +and Linux on a machine. 
    5.14 + 
    5.15 +Production Prerequisites: An x86-based machine machine with an ATMEL or
    5.16 +National Semiconductor (NSC) TPM on the motherboard.
    5.17 +Development Prerequisites: An emulator for TESTING ONLY is provided
    5.18 +
    5.19 +
    5.20 +Compiling XEN tree:
    5.21 +-------------------
    5.22 +
    5.23 +Compile the XEN tree as usual.
    5.24 +
    5.25 +make uninstall; make mrproper; make install 
    5.26 +
    5.27 +After compiling the tree, verify that in the linux-2.6.XX-xen0/.config 
    5.28 +file at least the following entries are set as below (they should be set
    5.29 +by default):
    5.30 +
    5.31 +CONFIG_XEN_TPMDEV_BACKEND=y
    5.32 +CONFIG_XEN_TPMDEV_GRANT=y
    5.33 +
    5.34 +CONFIG_TCG_TPM=m
    5.35 +CONFIG_TCG_NSC=m
    5.36 +CONFIG_TCG_ATMEL=m
    5.37 +
    5.38 +
    5.39 +Verify that in the linux-2.6.XX-xenU/.config file at least the 
    5.40 +Following entries are set as below (they should be set by default):
    5.41 +
    5.42 +CONFIG_XEN_TPMDEV_FRONTEND=y
    5.43 +CONFIG_XEN_TPMDEV_GRANT=y
    5.44 +
    5.45 +CONFIG_TCG_TPM=y
    5.46 +CONFIG_TCG_XEN=y
    5.47 +
    5.48 +
    5.49 +Reboot the machine with the created XEN-0 kernel.
    5.50 +
    5.51 +Note: If you do not want any TPM-related code compiled into your
    5.52 +kernel or built as module then comment all the above lines like
    5.53 +this example:
    5.54 +# CONFIG_TCG_TPM is not set
    5.55 +
    5.56 +
    5.57 +Modifying VM Configuration files:
    5.58 +---------------------------------
    5.59 +
    5.60 +VM configuration files need to be adapted to make a TPM instance
    5.61 +available to a user domain. The following VM configuration file is
    5.62 +an example of how a user domain can be configured to have a TPM
    5.63 +available. It works similar to making a network interface
    5.64 +available to a domain.
    5.65 +
    5.66 +kernel = "/boot/vmlinuz-2.6.12-xenU"
    5.67 +ramdisk = "/xen/initrd_domU/U1_ramdisk.img"
    5.68 +memory = 32
    5.69 +name = "TPMUserDomain0"
    5.70 +vtpm = ['instance=1,backend=0']
    5.71 +root = "/dev/ram0 cosole=tty ro"
    5.72 +vif = ['backend=0']
    5.73 +
    5.74 +In the above configuration file the line 'vtpm = ...' provides
    5.75 +information about the domain where the virtual TPM is running and
    5.76 +where the TPM backend has been compiled into - this has to be 
    5.77 +domain 0  at the moment - and which TPM instance the user domain
    5.78 +is supposed to talk to. Note that each running VM must use a 
    5.79 +different instance and that using instance 0 is NOT allowed.
    5.80 +
    5.81 +Note: If you do not want TPM functionality for your user domain simply
    5.82 +leave out the 'vtpm' line in the configuration file.
    5.83 +
    5.84 +
    5.85 +Running the TPM:
    5.86 +----------------
    5.87 +
    5.88 +To run the vTPM, dev device /dev/vtpm must be available.
    5.89 +Verify that 'ls -l /dev/vtpm' shows the following output:
    5.90 +
    5.91 +crw-------  1 root root 10, 225 Aug 11 06:58 /dev/vtpm
    5.92 +
    5.93 +If it is not available, run the following command as 'root'.
    5.94 +mknod /dev/vtpm c 10 225
    5.95 +
    5.96 +Make sure that the vTPM is running in domain 0. To do this run the
    5.97 +following
    5.98 +
    5.99 +/usr/bin/vtpm_managerd
   5.100 +
   5.101 +Start a user domain using the 'xm create' command. Once you are in the
   5.102 +shell of the user domain, you should be able to do the following:
   5.103 +
   5.104 +> cd /sys/devices/vtpm
   5.105 +> ls
   5.106 +cancel  caps   pcrs    pubek
   5.107 +> cat pcrs
   5.108 +PCR-00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   5.109 +PCR-01: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   5.110 +PCR-02: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   5.111 +PCR-03: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   5.112 +PCR-04: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   5.113 +PCR-05: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   5.114 +PCR-06: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   5.115 +PCR-07: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   5.116 +PCR-08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   5.117 +[...]
   5.118 +
   5.119 +At this point the user domain has been sucessfully connected to its
   5.120 +virtual TPM instance.
   5.121 +
   5.122 +For further information please read the documentation in 
   5.123 +tools/vtpm_manager/README and tools/vtpm/README
   5.124 +
   5.125 +Stefan Berger and Employees of the Intel Corp
     6.1 --- a/linux-2.6-xen-sparse/arch/xen/Kconfig	Thu Sep 01 10:08:53 2005 +0000
     6.2 +++ b/linux-2.6-xen-sparse/arch/xen/Kconfig	Thu Sep 01 10:16:14 2005 +0000
     6.3 @@ -70,6 +70,27 @@ config XEN_NETDEV_BACKEND
     6.4  	  network devices to other guests via a high-performance shared-memory
     6.5  	  interface.
     6.6  
     6.7 +config XEN_TPMDEV_FRONTEND
     6.8 +        bool "TPM-device frontend driver"
     6.9 +        default n
    6.10 +        help
    6.11 +          The TPM-device frontend driver.
    6.12 +
    6.13 +config XEN_TPMDEV_BACKEND
    6.14 +        bool "TPM-device backend driver"
    6.15 +        default n
    6.16 +        help
    6.17 +          The TPM-device backend driver
    6.18 +
    6.19 +config XEN_TPMDEV_CLOSE_IF_VTPM_FAILS
    6.20 +        bool "TPM backend closes upon vTPM failure"
    6.21 +        depends on XEN_TPMDEV_BACKEND
    6.22 +        default n
    6.23 +        help
    6.24 +          The TPM backend closes the channel if the vTPM in userspace indicates
    6.25 +          a failure. The corresponding domain's channel will be closed.
    6.26 +          Say Y if you want this feature.
    6.27 +
    6.28  config XEN_BLKDEV_FRONTEND
    6.29  	bool "Block-device frontend driver"
    6.30  	default y
     7.1 --- a/linux-2.6-xen-sparse/arch/xen/Kconfig.drivers	Thu Sep 01 10:08:53 2005 +0000
     7.2 +++ b/linux-2.6-xen-sparse/arch/xen/Kconfig.drivers	Thu Sep 01 10:16:14 2005 +0000
     7.3 @@ -49,6 +49,10 @@ source "drivers/infiniband/Kconfig"
     7.4  endif
     7.5  
     7.6  if !XEN_PHYSDEV_ACCESS
     7.7 +source "drivers/char/tpm/Kconfig.domU"
     7.8 +endif
     7.9 +
    7.10 +if !XEN_PHYSDEV_ACCESS
    7.11  
    7.12  menu "Character devices"
    7.13  
     8.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32	Thu Sep 01 10:08:53 2005 +0000
     8.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32	Thu Sep 01 10:16:14 2005 +0000
     8.3 @@ -15,6 +15,8 @@ CONFIG_XEN_PHYSDEV_ACCESS=y
     8.4  CONFIG_XEN_BLKDEV_BACKEND=y
     8.5  # CONFIG_XEN_BLKDEV_TAP_BE is not set
     8.6  CONFIG_XEN_NETDEV_BACKEND=y
     8.7 +# CONFIG_XEN_TPMDEV_FRONTEND is not set
     8.8 +# CONFIG_XEN_TPMDEV_BACKEND is not set
     8.9  CONFIG_XEN_BLKDEV_FRONTEND=y
    8.10  CONFIG_XEN_NETDEV_FRONTEND=y
    8.11  CONFIG_XEN_NETDEV_GRANT_TX=y
     9.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64	Thu Sep 01 10:08:53 2005 +0000
     9.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64	Thu Sep 01 10:16:14 2005 +0000
     9.3 @@ -15,6 +15,8 @@ CONFIG_XEN_PHYSDEV_ACCESS=y
     9.4  CONFIG_XEN_BLKDEV_BACKEND=y
     9.5  # CONFIG_XEN_BLKDEV_TAP_BE is not set
     9.6  CONFIG_XEN_NETDEV_BACKEND=y
     9.7 +# CONFIG_XEN_TPMDEV_FRONTEND is not set
     9.8 +# CONFIG_XEN_TPMDEV_BACKEND is not set
     9.9  CONFIG_XEN_BLKDEV_FRONTEND=y
    9.10  CONFIG_XEN_NETDEV_FRONTEND=y
    9.11  CONFIG_XEN_NETDEV_GRANT_TX=y
    10.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32	Thu Sep 01 10:08:53 2005 +0000
    10.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32	Thu Sep 01 10:16:14 2005 +0000
    10.3 @@ -12,6 +12,8 @@ CONFIG_NO_IDLE_HZ=y
    10.4  #
    10.5  # CONFIG_XEN_PRIVILEGED_GUEST is not set
    10.6  # CONFIG_XEN_PHYSDEV_ACCESS is not set
    10.7 +# CONFIG_XEN_TPMDEV_FRONTEND is not set
    10.8 +# CONFIG_XEN_TPMDEV_BACKEND is not set
    10.9  CONFIG_XEN_BLKDEV_FRONTEND=y
   10.10  CONFIG_XEN_NETDEV_FRONTEND=y
   10.11  CONFIG_XEN_NETDEV_GRANT_TX=y
   10.12 @@ -336,6 +338,7 @@ CONFIG_NETDEVICES=y
   10.13  CONFIG_UNIX98_PTYS=y
   10.14  CONFIG_LEGACY_PTYS=y
   10.15  CONFIG_LEGACY_PTY_COUNT=256
   10.16 +# CONFIG_TCG_TPM is not set
   10.17  
   10.18  #
   10.19  # Character devices
    11.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64	Thu Sep 01 10:08:53 2005 +0000
    11.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64	Thu Sep 01 10:16:14 2005 +0000
    11.3 @@ -12,6 +12,8 @@ CONFIG_NO_IDLE_HZ=y
    11.4  #
    11.5  # CONFIG_XEN_PRIVILEGED_GUEST is not set
    11.6  # CONFIG_XEN_PHYSDEV_ACCESS is not set
    11.7 +# CONFIG_XEN_TPMDEV_FRONTEND is not set
    11.8 +# CONFIG_XEN_TPMDEV_BACKEND is not set
    11.9  CONFIG_XEN_BLKDEV_FRONTEND=y
   11.10  CONFIG_XEN_NETDEV_FRONTEND=y
   11.11  CONFIG_XEN_NETDEV_GRANT_TX=y
   11.12 @@ -662,6 +664,7 @@ CONFIG_NETCONSOLE=m
   11.13  CONFIG_INPUT=m
   11.14  CONFIG_UNIX98_PTYS=y
   11.15  # CONFIG_LEGACY_PTYS is not set
   11.16 +# CONFIG_TCG_TPM is not set
   11.17  
   11.18  #
   11.19  # Character devices
    12.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32	Thu Sep 01 10:08:53 2005 +0000
    12.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32	Thu Sep 01 10:16:14 2005 +0000
    12.3 @@ -15,6 +15,8 @@ CONFIG_XEN_PHYSDEV_ACCESS=y
    12.4  CONFIG_XEN_BLKDEV_BACKEND=y
    12.5  # CONFIG_XEN_BLKDEV_TAP_BE is not set
    12.6  CONFIG_XEN_NETDEV_BACKEND=y
    12.7 +# CONFIG_XEN_TPMDEV_FRONTEND is not set
    12.8 +# CONFIG_XEN_TPMDEV_BACKEND is not set
    12.9  CONFIG_XEN_BLKDEV_FRONTEND=y
   12.10  CONFIG_XEN_NETDEV_FRONTEND=y
   12.11  CONFIG_XEN_NETDEV_GRANT_TX=y
   12.12 @@ -1855,9 +1857,7 @@ CONFIG_HANGCHECK_TIMER=m
   12.13  #
   12.14  # TPM devices
   12.15  #
   12.16 -CONFIG_TCG_TPM=m
   12.17 -CONFIG_TCG_NSC=m
   12.18 -CONFIG_TCG_ATMEL=m
   12.19 +# CONFIG_TCG_TPM is not set
   12.20  
   12.21  #
   12.22  # I2C support
    13.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64	Thu Sep 01 10:08:53 2005 +0000
    13.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64	Thu Sep 01 10:16:14 2005 +0000
    13.3 @@ -15,6 +15,8 @@ CONFIG_XEN_PHYSDEV_ACCESS=y
    13.4  CONFIG_XEN_BLKDEV_BACKEND=y
    13.5  # CONFIG_XEN_BLKDEV_TAP_BE is not set
    13.6  CONFIG_XEN_NETDEV_BACKEND=y
    13.7 +# CONFIG_XEN_TPMDEV_FRONTEND is not set
    13.8 +# CONFIG_XEN_TPMDEV_BACKEND is not set
    13.9  CONFIG_XEN_BLKDEV_FRONTEND=y
   13.10  CONFIG_XEN_NETDEV_FRONTEND=y
   13.11  CONFIG_XEN_NETDEV_GRANT_TX=y
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig.domU	Thu Sep 01 10:16:14 2005 +0000
    14.3 @@ -0,0 +1,30 @@
    14.4 +#
    14.5 +# TPM device configuration
    14.6 +#
    14.7 +
    14.8 +menu "TPM devices"
    14.9 +
   14.10 +config TCG_TPM
   14.11 +	tristate "TPM Support for XEN"
   14.12 +	depends on ARCH_XEN && !XEN_PHYSDEV_ACCESS
   14.13 +	---help---
   14.14 +	  If you want to make TPM security available in your system,
   14.15 +	  say Yes and it will be accessible from within a user domain.  For
   14.16 +	  more information see <http://www.trustedcomputinggroup.org>.
   14.17 +	  An implementation of the Trusted Software Stack (TSS), the
   14.18 +	  userspace enablement piece of the specification, can be
   14.19 +	  obtained at: <http://sourceforge.net/projects/trousers>.  To
   14.20 +	  compile this driver as a module, choose M here; the module
   14.21 +	  will be called tpm. If unsure, say N.
   14.22 +
   14.23 +config TCG_XEN
   14.24 +	tristate "XEN TPM Interface"
   14.25 +	depends on TCG_TPM && ARCH_XEN
   14.26 +	---help---
   14.27 +	  If you want to make TPM support available to a Xen
   14.28 +	  user domain, say Yes and it will
   14.29 +          be accessible from within Linux. To compile this driver
   14.30 +          as a module, choose M here; the module will be called
   14.31 +          tpm_xen.
   14.32 +
   14.33 +endmenu
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/Makefile	Thu Sep 01 10:16:14 2005 +0000
    15.3 @@ -0,0 +1,12 @@
    15.4 +#
    15.5 +# Makefile for the kernel tpm device drivers.
    15.6 +#
    15.7 +ifeq ($(CONFIG_XEN_PHYSDEV_ACCESS),y)
    15.8 +obj-$(CONFIG_TCG_TPM) += tpm.o
    15.9 +obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
   15.10 +obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
   15.11 +obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
   15.12 +else
   15.13 +obj-$(CONFIG_TCG_TPM) += tpm_nopci.o
   15.14 +obj-$(CONFIG_TCG_XEN) += tpm_xen.o
   15.15 +endif
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c	Thu Sep 01 10:16:14 2005 +0000
    16.3 @@ -0,0 +1,627 @@
    16.4 +/*
    16.5 + * Copyright (C) 2004 IBM Corporation
    16.6 + *
    16.7 + * Authors:
    16.8 + * Leendert van Doorn <leendert@watson.ibm.com>
    16.9 + * Dave Safford <safford@watson.ibm.com>
   16.10 + * Reiner Sailer <sailer@watson.ibm.com>
   16.11 + * Kylene Hall <kjhall@us.ibm.com>
   16.12 + *
   16.13 + * Maintained by: <tpmdd_devel@lists.sourceforge.net>
   16.14 + *
   16.15 + * Device driver for TCG/TCPA TPM (trusted platform module).
   16.16 + * Specifications at www.trustedcomputinggroup.org
   16.17 + *
   16.18 + * This program is free software; you can redistribute it and/or
   16.19 + * modify it under the terms of the GNU General Public License as
   16.20 + * published by the Free Software Foundation, version 2 of the
   16.21 + * License.
   16.22 + *
   16.23 + * Note, the TPM chip is not interrupt driven (only polling)
   16.24 + * and can have very long timeouts (minutes!). Hence the unusual
   16.25 + * calls to schedule_timeout.
   16.26 + *
   16.27 + */
   16.28 +
   16.29 +#include <linux/sched.h>
   16.30 +#include <linux/poll.h>
   16.31 +#include <linux/spinlock.h>
   16.32 +#include "tpm.h"
   16.33 +
   16.34 +#define	TPM_MINOR			224	/* officially assigned */
   16.35 +
   16.36 +#define	TPM_BUFSIZE			2048
   16.37 +
   16.38 +static LIST_HEAD(tpm_chip_list);
   16.39 +static DEFINE_SPINLOCK(driver_lock);
   16.40 +static int dev_mask[32];
   16.41 +
   16.42 +static void user_reader_timeout(unsigned long ptr)
   16.43 +{
   16.44 +	struct tpm_chip *chip = (struct tpm_chip *) ptr;
   16.45 +
   16.46 +	down(&chip->buffer_mutex);
   16.47 +	atomic_set(&chip->data_pending, 0);
   16.48 +	memset(chip->data_buffer, 0, TPM_BUFSIZE);
   16.49 +	up(&chip->buffer_mutex);
   16.50 +}
   16.51 +
   16.52 +void tpm_time_expired(unsigned long ptr)
   16.53 +{
   16.54 +	int *exp = (int *) ptr;
   16.55 +	*exp = 1;
   16.56 +}
   16.57 +
   16.58 +EXPORT_SYMBOL_GPL(tpm_time_expired);
   16.59 +
   16.60 +/*
   16.61 + * Internal kernel interface to transmit TPM commands
   16.62 + */
   16.63 +static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
   16.64 +			    size_t bufsiz)
   16.65 +{
   16.66 +	ssize_t len;
   16.67 +	u32 count;
   16.68 +	__be32 *native_size;
   16.69 +
   16.70 +	native_size = (__force __be32 *) (buf + 2);
   16.71 +	count = be32_to_cpu(*native_size);
   16.72 +
   16.73 +	if (count == 0)
   16.74 +		return -ENODATA;
   16.75 +	if (count > bufsiz) {
   16.76 +		dev_err(&chip->pci_dev->dev,
   16.77 +			"invalid count value %x %zx \n", count, bufsiz);
   16.78 +		return -E2BIG;
   16.79 +	}
   16.80 +
   16.81 +	down(&chip->tpm_mutex);
   16.82 +
   16.83 +	if ((len = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
   16.84 +		dev_err(&chip->pci_dev->dev,
   16.85 +			"tpm_transmit: tpm_send: error %zd\n", len);
   16.86 +		return len;
   16.87 +	}
   16.88 +
   16.89 +	down(&chip->timer_manipulation_mutex);
   16.90 +	chip->time_expired = 0;
   16.91 +	init_timer(&chip->device_timer);
   16.92 +	chip->device_timer.function = tpm_time_expired;
   16.93 +	chip->device_timer.expires = jiffies + 2 * 60 * HZ;
   16.94 +	chip->device_timer.data = (unsigned long) &chip->time_expired;
   16.95 +	add_timer(&chip->device_timer);
   16.96 +	up(&chip->timer_manipulation_mutex);
   16.97 +
   16.98 +	do {
   16.99 +		u8 status = inb(chip->vendor->base + 1);
  16.100 +		if ((status & chip->vendor->req_complete_mask) ==
  16.101 +		    chip->vendor->req_complete_val) {
  16.102 +			down(&chip->timer_manipulation_mutex);
  16.103 +			del_singleshot_timer_sync(&chip->device_timer);
  16.104 +			up(&chip->timer_manipulation_mutex);
  16.105 +			goto out_recv;
  16.106 +		}
  16.107 +		set_current_state(TASK_UNINTERRUPTIBLE);
  16.108 +		schedule_timeout(TPM_TIMEOUT);
  16.109 +		rmb();
  16.110 +	} while (!chip->time_expired);
  16.111 +
  16.112 +
  16.113 +	chip->vendor->cancel(chip);
  16.114 +	dev_err(&chip->pci_dev->dev, "Time expired\n");
  16.115 +	up(&chip->tpm_mutex);
  16.116 +	return -EIO;
  16.117 +
  16.118 +out_recv:
  16.119 +	len = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
  16.120 +	if (len < 0)
  16.121 +		dev_err(&chip->pci_dev->dev,
  16.122 +			"tpm_transmit: tpm_recv: error %zd\n", len);
  16.123 +	up(&chip->tpm_mutex);
  16.124 +	return len;
  16.125 +}
  16.126 +
  16.127 +#define TPM_DIGEST_SIZE 20
  16.128 +#define CAP_PCR_RESULT_SIZE 18
  16.129 +static u8 cap_pcr[] = {
  16.130 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
  16.131 +	0, 0, 0, 22,		/* length */
  16.132 +	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
  16.133 +	0, 0, 0, 5,
  16.134 +	0, 0, 0, 4,
  16.135 +	0, 0, 1, 1
  16.136 +};
  16.137 +
  16.138 +#define READ_PCR_RESULT_SIZE 30
  16.139 +static u8 pcrread[] = {
  16.140 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
  16.141 +	0, 0, 0, 14,		/* length */
  16.142 +	0, 0, 0, 21,		/* TPM_ORD_PcrRead */
  16.143 +	0, 0, 0, 0		/* PCR index */
  16.144 +};
  16.145 +
  16.146 +static ssize_t show_pcrs(struct device *dev, char *buf)
  16.147 +{
  16.148 +	u8 data[READ_PCR_RESULT_SIZE];
  16.149 +	ssize_t len;
  16.150 +	int i, j, index, num_pcrs;
  16.151 +	char *str = buf;
  16.152 +
  16.153 +	struct tpm_chip *chip =
  16.154 +	    pci_get_drvdata(container_of(dev, struct pci_dev, dev));
  16.155 +	if (chip == NULL)
  16.156 +		return -ENODEV;
  16.157 +
  16.158 +	memcpy(data, cap_pcr, sizeof(cap_pcr));
  16.159 +	if ((len = tpm_transmit(chip, data, sizeof(data)))
  16.160 +	    < CAP_PCR_RESULT_SIZE)
  16.161 +		return len;
  16.162 +
  16.163 +	num_pcrs = be32_to_cpu(*((__force __be32 *) (data + 14)));
  16.164 +
  16.165 +	for (i = 0; i < num_pcrs; i++) {
  16.166 +		memcpy(data, pcrread, sizeof(pcrread));
  16.167 +		index = cpu_to_be32(i);
  16.168 +		memcpy(data + 10, &index, 4);
  16.169 +		if ((len = tpm_transmit(chip, data, sizeof(data)))
  16.170 +		    < READ_PCR_RESULT_SIZE)
  16.171 +			return len;
  16.172 +		str += sprintf(str, "PCR-%02d: ", i);
  16.173 +		for (j = 0; j < TPM_DIGEST_SIZE; j++)
  16.174 +			str += sprintf(str, "%02X ", *(data + 10 + j));
  16.175 +		str += sprintf(str, "\n");
  16.176 +	}
  16.177 +	return str - buf;
  16.178 +}
  16.179 +
  16.180 +static DEVICE_ATTR(pcrs, S_IRUGO, show_pcrs, NULL);
  16.181 +
  16.182 +#define  READ_PUBEK_RESULT_SIZE 314
  16.183 +static u8 readpubek[] = {
  16.184 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
  16.185 +	0, 0, 0, 30,		/* length */
  16.186 +	0, 0, 0, 124,		/* TPM_ORD_ReadPubek */
  16.187 +};
  16.188 +
  16.189 +static ssize_t show_pubek(struct device *dev, char *buf)
  16.190 +{
  16.191 +	u8 data[READ_PUBEK_RESULT_SIZE];
  16.192 +	ssize_t len;
  16.193 +	__be32 *native_val;
  16.194 +	int i;
  16.195 +	char *str = buf;
  16.196 +
  16.197 +	struct tpm_chip *chip =
  16.198 +	    pci_get_drvdata(container_of(dev, struct pci_dev, dev));
  16.199 +	if (chip == NULL)
  16.200 +		return -ENODEV;
  16.201 +
  16.202 +	memcpy(data, readpubek, sizeof(readpubek));
  16.203 +	memset(data + sizeof(readpubek), 0, 20);	/* zero nonce */
  16.204 +
  16.205 +	if ((len = tpm_transmit(chip, data, sizeof(data))) <
  16.206 +	    READ_PUBEK_RESULT_SIZE)
  16.207 +		return len;
  16.208 +
  16.209 +	/*
  16.210 +	   ignore header 10 bytes
  16.211 +	   algorithm 32 bits (1 == RSA )
  16.212 +	   encscheme 16 bits
  16.213 +	   sigscheme 16 bits
  16.214 +	   parameters (RSA 12->bytes: keybit, #primes, expbit)
  16.215 +	   keylenbytes 32 bits
  16.216 +	   256 byte modulus
  16.217 +	   ignore checksum 20 bytes
  16.218 +	 */
  16.219 +
  16.220 +	native_val = (__force __be32 *) (data + 34);
  16.221 +
  16.222 +	str +=
  16.223 +	    sprintf(str,
  16.224 +		    "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
  16.225 +		    "Sigscheme: %02X %02X\nParameters: %02X %02X %02X %02X"
  16.226 +		    " %02X %02X %02X %02X %02X %02X %02X %02X\n"
  16.227 +		    "Modulus length: %d\nModulus: \n",
  16.228 +		    data[10], data[11], data[12], data[13], data[14],
  16.229 +		    data[15], data[16], data[17], data[22], data[23],
  16.230 +		    data[24], data[25], data[26], data[27], data[28],
  16.231 +		    data[29], data[30], data[31], data[32], data[33],
  16.232 +		    be32_to_cpu(*native_val)
  16.233 +	    );
  16.234 +
  16.235 +	for (i = 0; i < 256; i++) {
  16.236 +		str += sprintf(str, "%02X ", data[i + 39]);
  16.237 +		if ((i + 1) % 16 == 0)
  16.238 +			str += sprintf(str, "\n");
  16.239 +	}
  16.240 +	return str - buf;
  16.241 +}
  16.242 +
  16.243 +static DEVICE_ATTR(pubek, S_IRUGO, show_pubek, NULL);
  16.244 +
  16.245 +#define CAP_VER_RESULT_SIZE 18
  16.246 +static u8 cap_version[] = {
  16.247 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
  16.248 +	0, 0, 0, 18,		/* length */
  16.249 +	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
  16.250 +	0, 0, 0, 6,
  16.251 +	0, 0, 0, 0
  16.252 +};
  16.253 +
  16.254 +#define CAP_MANUFACTURER_RESULT_SIZE 18
  16.255 +static u8 cap_manufacturer[] = {
  16.256 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
  16.257 +	0, 0, 0, 22,		/* length */
  16.258 +	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
  16.259 +	0, 0, 0, 5,
  16.260 +	0, 0, 0, 4,
  16.261 +	0, 0, 1, 3
  16.262 +};
  16.263 +
  16.264 +static ssize_t show_caps(struct device *dev, char *buf)
  16.265 +{
  16.266 +	u8 data[READ_PUBEK_RESULT_SIZE];
  16.267 +	ssize_t len;
  16.268 +	char *str = buf;
  16.269 +
  16.270 +	struct tpm_chip *chip =
  16.271 +	    pci_get_drvdata(container_of(dev, struct pci_dev, dev));
  16.272 +	if (chip == NULL)
  16.273 +		return -ENODEV;
  16.274 +
  16.275 +	memcpy(data, cap_manufacturer, sizeof(cap_manufacturer));
  16.276 +
  16.277 +	if ((len = tpm_transmit(chip, data, sizeof(data))) <
  16.278 +	    CAP_MANUFACTURER_RESULT_SIZE)
  16.279 +		return len;
  16.280 +
  16.281 +	str += sprintf(str, "Manufacturer: 0x%x\n",
  16.282 +		       be32_to_cpu(*(data + 14)));
  16.283 +
  16.284 +	memcpy(data, cap_version, sizeof(cap_version));
  16.285 +
  16.286 +	if ((len = tpm_transmit(chip, data, sizeof(data))) <
  16.287 +	    CAP_VER_RESULT_SIZE)
  16.288 +		return len;
  16.289 +
  16.290 +	str +=
  16.291 +	    sprintf(str, "TCG version: %d.%d\nFirmware version: %d.%d\n",
  16.292 +		    (int) data[14], (int) data[15], (int) data[16],
  16.293 +		    (int) data[17]);
  16.294 +
  16.295 +	return str - buf;
  16.296 +}
  16.297 +
  16.298 +static DEVICE_ATTR(caps, S_IRUGO, show_caps, NULL);
  16.299 +
  16.300 +/*
  16.301 + * Device file system interface to the TPM
  16.302 + */
  16.303 +int tpm_open(struct inode *inode, struct file *file)
  16.304 +{
  16.305 +	int rc = 0, minor = iminor(inode);
  16.306 +	struct tpm_chip *chip = NULL, *pos;
  16.307 +
  16.308 +	spin_lock(&driver_lock);
  16.309 +
  16.310 +	list_for_each_entry(pos, &tpm_chip_list, list) {
  16.311 +		if (pos->vendor->miscdev.minor == minor) {
  16.312 +			chip = pos;
  16.313 +			break;
  16.314 +		}
  16.315 +	}
  16.316 +
  16.317 +	if (chip == NULL) {
  16.318 +		rc = -ENODEV;
  16.319 +		goto err_out;
  16.320 +	}
  16.321 +
  16.322 +	if (chip->num_opens) {
  16.323 +		dev_dbg(&chip->pci_dev->dev,
  16.324 +			"Another process owns this TPM\n");
  16.325 +		rc = -EBUSY;
  16.326 +		goto err_out;
  16.327 +	}
  16.328 +
  16.329 +	chip->num_opens++;
  16.330 +	pci_dev_get(chip->pci_dev);
  16.331 +
  16.332 +	spin_unlock(&driver_lock);
  16.333 +
  16.334 +	chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
  16.335 +	if (chip->data_buffer == NULL) {
  16.336 +		chip->num_opens--;
  16.337 +		pci_dev_put(chip->pci_dev);
  16.338 +		return -ENOMEM;
  16.339 +	}
  16.340 +
  16.341 +	atomic_set(&chip->data_pending, 0);
  16.342 +
  16.343 +	file->private_data = chip;
  16.344 +	return 0;
  16.345 +
  16.346 +err_out:
  16.347 +	spin_unlock(&driver_lock);
  16.348 +	return rc;
  16.349 +}
  16.350 +
  16.351 +EXPORT_SYMBOL_GPL(tpm_open);
  16.352 +
  16.353 +int tpm_release(struct inode *inode, struct file *file)
  16.354 +{
  16.355 +	struct tpm_chip *chip = file->private_data;
  16.356 +
  16.357 +	file->private_data = NULL;
  16.358 +
  16.359 +	spin_lock(&driver_lock);
  16.360 +	chip->num_opens--;
  16.361 +	spin_unlock(&driver_lock);
  16.362 +
  16.363 +	down(&chip->timer_manipulation_mutex);
  16.364 +	if (timer_pending(&chip->user_read_timer))
  16.365 +		del_singleshot_timer_sync(&chip->user_read_timer);
  16.366 +	else if (timer_pending(&chip->device_timer))
  16.367 +		del_singleshot_timer_sync(&chip->device_timer);
  16.368 +	up(&chip->timer_manipulation_mutex);
  16.369 +
  16.370 +	kfree(chip->data_buffer);
  16.371 +	atomic_set(&chip->data_pending, 0);
  16.372 +
  16.373 +	pci_dev_put(chip->pci_dev);
  16.374 +	return 0;
  16.375 +}
  16.376 +
  16.377 +EXPORT_SYMBOL_GPL(tpm_release);
  16.378 +
  16.379 +ssize_t tpm_write(struct file * file, const char __user * buf,
  16.380 +		  size_t size, loff_t * off)
  16.381 +{
  16.382 +	struct tpm_chip *chip = file->private_data;
  16.383 +	int in_size = size, out_size;
  16.384 +
  16.385 +	/* cannot perform a write until the read has cleared
  16.386 +	   either via tpm_read or a user_read_timer timeout */
  16.387 +	while (atomic_read(&chip->data_pending) != 0) {
  16.388 +		set_current_state(TASK_UNINTERRUPTIBLE);
  16.389 +		schedule_timeout(TPM_TIMEOUT);
  16.390 +	}
  16.391 +
  16.392 +	down(&chip->buffer_mutex);
  16.393 +
  16.394 +	if (in_size > TPM_BUFSIZE)
  16.395 +		in_size = TPM_BUFSIZE;
  16.396 +
  16.397 +	if (copy_from_user
  16.398 +	    (chip->data_buffer, (void __user *) buf, in_size)) {
  16.399 +		up(&chip->buffer_mutex);
  16.400 +		return -EFAULT;
  16.401 +	}
  16.402 +
  16.403 +	/* atomic tpm command send and result receive */
  16.404 +	out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
  16.405 +
  16.406 +	atomic_set(&chip->data_pending, out_size);
  16.407 +	atomic_set(&chip->data_position, 0);
  16.408 +	up(&chip->buffer_mutex);
  16.409 +
  16.410 +	/* Set a timeout by which the reader must come claim the result */
  16.411 +	down(&chip->timer_manipulation_mutex);
  16.412 +	init_timer(&chip->user_read_timer);
  16.413 +	chip->user_read_timer.function = user_reader_timeout;
  16.414 +	chip->user_read_timer.data = (unsigned long) chip;
  16.415 +	chip->user_read_timer.expires = jiffies + (60 * HZ);
  16.416 +	add_timer(&chip->user_read_timer);
  16.417 +	up(&chip->timer_manipulation_mutex);
  16.418 +
  16.419 +	return in_size;
  16.420 +}
  16.421 +
  16.422 +EXPORT_SYMBOL_GPL(tpm_write);
  16.423 +
  16.424 +ssize_t tpm_read(struct file * file, char __user * buf,
  16.425 +		 size_t size, loff_t * off)
  16.426 +{
  16.427 +	struct tpm_chip *chip = file->private_data;
  16.428 +	int ret_size = -ENODATA;
  16.429 +	int pos, pending = 0;
  16.430 +
  16.431 +	down(&chip->buffer_mutex);
  16.432 +	ret_size = atomic_read(&chip->data_pending);
  16.433 +	if ( ret_size > 0 ) {	/* Result available */
  16.434 +		if (size < ret_size)
  16.435 +			ret_size = size;
  16.436 +
  16.437 +		pos = atomic_read(&chip->data_position);
  16.438 +
  16.439 +		if (copy_to_user((void __user *) buf,
  16.440 +				 &chip->data_buffer[pos], ret_size)) {
  16.441 +			ret_size = -EFAULT;
  16.442 +		} else {
  16.443 +			pending = atomic_read(&chip->data_pending) - ret_size;
  16.444 +			if ( pending ) {
  16.445 +				atomic_set( &chip->data_pending, pending );
  16.446 +				atomic_set( &chip->data_position, pos+ret_size );
  16.447 +			}
  16.448 +		}
  16.449 +	}
  16.450 +	up(&chip->buffer_mutex);
  16.451 +
  16.452 +	if ( ret_size <= 0 || pending == 0 ) {
  16.453 +		atomic_set( &chip->data_pending, 0 );
  16.454 +		down(&chip->timer_manipulation_mutex);
  16.455 +		del_singleshot_timer_sync(&chip->user_read_timer);
  16.456 +		up(&chip->timer_manipulation_mutex);
  16.457 +	}
  16.458 +
  16.459 +	return ret_size;
  16.460 +}
  16.461 +
  16.462 +EXPORT_SYMBOL_GPL(tpm_read);
  16.463 +
  16.464 +void __devexit tpm_remove(struct pci_dev *pci_dev)
  16.465 +{
  16.466 +	struct tpm_chip *chip = pci_get_drvdata(pci_dev);
  16.467 +
  16.468 +	if (chip == NULL) {
  16.469 +		dev_err(&pci_dev->dev, "No device data found\n");
  16.470 +		return;
  16.471 +	}
  16.472 +
  16.473 +	spin_lock(&driver_lock);
  16.474 +
  16.475 +	list_del(&chip->list);
  16.476 +
  16.477 +	spin_unlock(&driver_lock);
  16.478 +
  16.479 +	pci_set_drvdata(pci_dev, NULL);
  16.480 +	misc_deregister(&chip->vendor->miscdev);
  16.481 +
  16.482 +	device_remove_file(&pci_dev->dev, &dev_attr_pubek);
  16.483 +	device_remove_file(&pci_dev->dev, &dev_attr_pcrs);
  16.484 +	device_remove_file(&pci_dev->dev, &dev_attr_caps);
  16.485 +
  16.486 +	pci_disable_device(pci_dev);
  16.487 +
  16.488 +	dev_mask[chip->dev_num / 32] &= !(1 << (chip->dev_num % 32));
  16.489 +
  16.490 +	kfree(chip);
  16.491 +
  16.492 +	pci_dev_put(pci_dev);
  16.493 +}
  16.494 +
  16.495 +EXPORT_SYMBOL_GPL(tpm_remove);
  16.496 +
  16.497 +static u8 savestate[] = {
  16.498 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
  16.499 +	0, 0, 0, 10,		/* blob length (in bytes) */
  16.500 +	0, 0, 0, 152		/* TPM_ORD_SaveState */
  16.501 +};
  16.502 +
  16.503 +/*
  16.504 + * We are about to suspend. Save the TPM state
  16.505 + * so that it can be restored.
  16.506 + */
  16.507 +int tpm_pm_suspend(struct pci_dev *pci_dev, pm_message_t pm_state)
  16.508 +{
  16.509 +	struct tpm_chip *chip = pci_get_drvdata(pci_dev);
  16.510 +	if (chip == NULL)
  16.511 +		return -ENODEV;
  16.512 +
  16.513 +	tpm_transmit(chip, savestate, sizeof(savestate));
  16.514 +	return 0;
  16.515 +}
  16.516 +
  16.517 +EXPORT_SYMBOL_GPL(tpm_pm_suspend);
  16.518 +
  16.519 +/*
  16.520 + * Resume from a power safe. The BIOS already restored
  16.521 + * the TPM state.
  16.522 + */
  16.523 +int tpm_pm_resume(struct pci_dev *pci_dev)
  16.524 +{
  16.525 +	struct tpm_chip *chip = pci_get_drvdata(pci_dev);
  16.526 +
  16.527 +	if (chip == NULL)
  16.528 +		return -ENODEV;
  16.529 +
  16.530 +	return 0;
  16.531 +}
  16.532 +
  16.533 +EXPORT_SYMBOL_GPL(tpm_pm_resume);
  16.534 +
  16.535 +/*
  16.536 + * Called from tpm_<specific>.c probe function only for devices
  16.537 + * the driver has determined it should claim.  Prior to calling
  16.538 + * this function the specific probe function has called pci_enable_device
  16.539 + * upon errant exit from this function specific probe function should call
  16.540 + * pci_disable_device
  16.541 + */
  16.542 +int tpm_register_hardware(struct pci_dev *pci_dev,
  16.543 +			  struct tpm_vendor_specific *entry)
  16.544 +{
  16.545 +	char devname[7];
  16.546 +	struct tpm_chip *chip;
  16.547 +	int i, j;
  16.548 +
  16.549 +	/* Driver specific per-device data */
  16.550 +	chip = kmalloc(sizeof(*chip), GFP_KERNEL);
  16.551 +	if (chip == NULL)
  16.552 +		return -ENOMEM;
  16.553 +
  16.554 +	memset(chip, 0, sizeof(struct tpm_chip));
  16.555 +
  16.556 +	init_MUTEX(&chip->buffer_mutex);
  16.557 +	init_MUTEX(&chip->tpm_mutex);
  16.558 +	init_MUTEX(&chip->timer_manipulation_mutex);
  16.559 +	INIT_LIST_HEAD(&chip->list);
  16.560 +
  16.561 +	chip->vendor = entry;
  16.562 +
  16.563 +	chip->dev_num = -1;
  16.564 +
  16.565 +	for (i = 0; i < 32; i++)
  16.566 +		for (j = 0; j < 8; j++)
  16.567 +			if ((dev_mask[i] & (1 << j)) == 0) {
  16.568 +				chip->dev_num = i * 32 + j;
  16.569 +				dev_mask[i] |= 1 << j;
  16.570 +				goto dev_num_search_complete;
  16.571 +			}
  16.572 +
  16.573 +dev_num_search_complete:
  16.574 +	if (chip->dev_num < 0) {
  16.575 +		dev_err(&pci_dev->dev,
  16.576 +			"No available tpm device numbers\n");
  16.577 +		kfree(chip);
  16.578 +		return -ENODEV;
  16.579 +	} else if (chip->dev_num == 0)
  16.580 +		chip->vendor->miscdev.minor = TPM_MINOR;
  16.581 +	else
  16.582 +		chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
  16.583 +
  16.584 +	snprintf(devname, sizeof(devname), "%s%d", "tpm", chip->dev_num);
  16.585 +	chip->vendor->miscdev.name = devname;
  16.586 +
  16.587 +	chip->vendor->miscdev.dev = &(pci_dev->dev);
  16.588 +	chip->pci_dev = pci_dev_get(pci_dev);
  16.589 +
  16.590 +	if (misc_register(&chip->vendor->miscdev)) {
  16.591 +		dev_err(&chip->pci_dev->dev,
  16.592 +			"unable to misc_register %s, minor %d\n",
  16.593 +			chip->vendor->miscdev.name,
  16.594 +			chip->vendor->miscdev.minor);
  16.595 +		pci_dev_put(pci_dev);
  16.596 +		kfree(chip);
  16.597 +		dev_mask[i] &= !(1 << j);
  16.598 +		return -ENODEV;
  16.599 +	}
  16.600 +
  16.601 +	pci_set_drvdata(pci_dev, chip);
  16.602 +
  16.603 +	list_add(&chip->list, &tpm_chip_list);
  16.604 +
  16.605 +	device_create_file(&pci_dev->dev, &dev_attr_pubek);
  16.606 +	device_create_file(&pci_dev->dev, &dev_attr_pcrs);
  16.607 +	device_create_file(&pci_dev->dev, &dev_attr_caps);
  16.608 +
  16.609 +	return 0;
  16.610 +}
  16.611 +
  16.612 +EXPORT_SYMBOL_GPL(tpm_register_hardware);
  16.613 +
  16.614 +static int __init init_tpm(void)
  16.615 +{
  16.616 +	return 0;
  16.617 +}
  16.618 +
  16.619 +static void __exit cleanup_tpm(void)
  16.620 +{
  16.621 +
  16.622 +}
  16.623 +
  16.624 +module_init(init_tpm);
  16.625 +module_exit(cleanup_tpm);
  16.626 +
  16.627 +MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
  16.628 +MODULE_DESCRIPTION("TPM Driver");
  16.629 +MODULE_VERSION("2.0");
  16.630 +MODULE_LICENSE("GPL");
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h	Thu Sep 01 10:16:14 2005 +0000
    17.3 @@ -0,0 +1,92 @@
    17.4 +/*
    17.5 + * Copyright (C) 2004 IBM Corporation
    17.6 + *
    17.7 + * Authors:
    17.8 + * Leendert van Doorn <leendert@watson.ibm.com>
    17.9 + * Dave Safford <safford@watson.ibm.com>
   17.10 + * Reiner Sailer <sailer@watson.ibm.com>
   17.11 + * Kylene Hall <kjhall@us.ibm.com>
   17.12 + *
   17.13 + * Maintained by: <tpmdd_devel@lists.sourceforge.net>
   17.14 + *
   17.15 + * Device driver for TCG/TCPA TPM (trusted platform module).
   17.16 + * Specifications at www.trustedcomputinggroup.org
   17.17 + *
   17.18 + * This program is free software; you can redistribute it and/or
   17.19 + * modify it under the terms of the GNU General Public License as
   17.20 + * published by the Free Software Foundation, version 2 of the
   17.21 + * License.
   17.22 + *
   17.23 + */
   17.24 +#include <linux/module.h>
   17.25 +#include <linux/version.h>
   17.26 +#include <linux/pci.h>
   17.27 +#include <linux/delay.h>
   17.28 +#include <linux/fs.h>
   17.29 +#include <linux/miscdevice.h>
   17.30 +
   17.31 +#define TPM_TIMEOUT msecs_to_jiffies(5)
   17.32 +
   17.33 +/* TPM addresses */
   17.34 +#define	TPM_ADDR			0x4E
   17.35 +#define	TPM_DATA			0x4F
   17.36 +
   17.37 +struct tpm_chip;
   17.38 +
   17.39 +struct tpm_vendor_specific {
   17.40 +	u8 req_complete_mask;
   17.41 +	u8 req_complete_val;
   17.42 +	u16 base;		/* TPM base address */
   17.43 +
   17.44 +	int (*recv) (struct tpm_chip *, u8 *, size_t);
   17.45 +	int (*send) (struct tpm_chip *, u8 *, size_t);
   17.46 +	void (*cancel) (struct tpm_chip *);
   17.47 +	struct miscdevice miscdev;
   17.48 +};
   17.49 +
   17.50 +struct tpm_chip {
   17.51 +	struct pci_dev *pci_dev;	/* PCI device stuff */
   17.52 +
   17.53 +	int dev_num;		/* /dev/tpm# */
   17.54 +	int num_opens;		/* only one allowed */
   17.55 +	int time_expired;
   17.56 +
   17.57 +	/* Data passed to and from the tpm via the read/write calls */
   17.58 +	u8 *data_buffer;
   17.59 +	atomic_t data_pending;
   17.60 +	atomic_t data_position;
   17.61 +	struct semaphore buffer_mutex;
   17.62 +
   17.63 +	struct timer_list user_read_timer;	/* user needs to claim result */
   17.64 +	struct semaphore tpm_mutex;	/* tpm is processing */
   17.65 +	struct timer_list device_timer;	/* tpm is processing */
   17.66 +	struct semaphore timer_manipulation_mutex;
   17.67 +
   17.68 +	struct tpm_vendor_specific *vendor;
   17.69 +
   17.70 +	struct list_head list;
   17.71 +};
   17.72 +
   17.73 +static inline int tpm_read_index(int index)
   17.74 +{
   17.75 +	outb(index, TPM_ADDR);
   17.76 +	return inb(TPM_DATA) & 0xFF;
   17.77 +}
   17.78 +
   17.79 +static inline void tpm_write_index(int index, int value)
   17.80 +{
   17.81 +	outb(index, TPM_ADDR);
   17.82 +	outb(value & 0xFF, TPM_DATA);
   17.83 +}
   17.84 +
   17.85 +extern void tpm_time_expired(unsigned long);
   17.86 +extern int tpm_register_hardware(struct pci_dev *,
   17.87 +				 struct tpm_vendor_specific *);
   17.88 +extern int tpm_open(struct inode *, struct file *);
   17.89 +extern int tpm_release(struct inode *, struct file *);
   17.90 +extern ssize_t tpm_write(struct file *, const char __user *, size_t,
   17.91 +			 loff_t *);
   17.92 +extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *);
   17.93 +extern void __devexit tpm_remove(struct pci_dev *);
   17.94 +extern int tpm_pm_suspend(struct pci_dev *, pm_message_t);
   17.95 +extern int tpm_pm_resume(struct pci_dev *);
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_atmel.c	Thu Sep 01 10:16:14 2005 +0000
    18.3 @@ -0,0 +1,220 @@
    18.4 +/*
    18.5 + * Copyright (C) 2004 IBM Corporation
    18.6 + *
    18.7 + * Authors:
    18.8 + * Leendert van Doorn <leendert@watson.ibm.com>
    18.9 + * Dave Safford <safford@watson.ibm.com>
   18.10 + * Reiner Sailer <sailer@watson.ibm.com>
   18.11 + * Kylene Hall <kjhall@us.ibm.com>
   18.12 + *
   18.13 + * Maintained by: <tpmdd_devel@lists.sourceforge.net>
   18.14 + *
   18.15 + * Device driver for TCG/TCPA TPM (trusted platform module).
   18.16 + * Specifications at www.trustedcomputinggroup.org
   18.17 + *
   18.18 + * This program is free software; you can redistribute it and/or
   18.19 + * modify it under the terms of the GNU General Public License as
   18.20 + * published by the Free Software Foundation, version 2 of the
   18.21 + * License.
   18.22 + *
   18.23 + */
   18.24 +
   18.25 +#include "tpm.h"
   18.26 +
   18.27 +/* Atmel definitions */
   18.28 +enum tpm_atmel_addr {
   18.29 +	TPM_ATMEL_BASE_ADDR_LO = 0x08,
   18.30 +	TPM_ATMEL_BASE_ADDR_HI = 0x09
   18.31 +};
   18.32 +
   18.33 +/* write status bits */
   18.34 +#define	ATML_STATUS_ABORT		0x01
   18.35 +#define	ATML_STATUS_LASTBYTE		0x04
   18.36 +
   18.37 +/* read status bits */
   18.38 +#define	ATML_STATUS_BUSY		0x01
   18.39 +#define	ATML_STATUS_DATA_AVAIL		0x02
   18.40 +#define	ATML_STATUS_REWRITE		0x04
   18.41 +
   18.42 +
   18.43 +static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
   18.44 +{
   18.45 +	u8 status, *hdr = buf;
   18.46 +	u32 size;
   18.47 +	int i;
   18.48 +	__be32 *native_size;
   18.49 +
   18.50 +	/* start reading header */
   18.51 +	if (count < 6)
   18.52 +		return -EIO;
   18.53 +
   18.54 +	for (i = 0; i < 6; i++) {
   18.55 +		status = inb(chip->vendor->base + 1);
   18.56 +		if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
   18.57 +			dev_err(&chip->pci_dev->dev,
   18.58 +				"error reading header\n");
   18.59 +			return -EIO;
   18.60 +		}
   18.61 +		*buf++ = inb(chip->vendor->base);
   18.62 +	}
   18.63 +
   18.64 +	/* size of the data received */
   18.65 +	native_size = (__force __be32 *) (hdr + 2);
   18.66 +	size = be32_to_cpu(*native_size);
   18.67 +
   18.68 +	if (count < size) {
   18.69 +		dev_err(&chip->pci_dev->dev,
   18.70 +			"Recv size(%d) less than available space\n", size);
   18.71 +		for (; i < size; i++) {	/* clear the waiting data anyway */
   18.72 +			status = inb(chip->vendor->base + 1);
   18.73 +			if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
   18.74 +				dev_err(&chip->pci_dev->dev,
   18.75 +					"error reading data\n");
   18.76 +				return -EIO;
   18.77 +			}
   18.78 +		}
   18.79 +		return -EIO;
   18.80 +	}
   18.81 +
   18.82 +	/* read all the data available */
   18.83 +	for (; i < size; i++) {
   18.84 +		status = inb(chip->vendor->base + 1);
   18.85 +		if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
   18.86 +			dev_err(&chip->pci_dev->dev,
   18.87 +				"error reading data\n");
   18.88 +			return -EIO;
   18.89 +		}
   18.90 +		*buf++ = inb(chip->vendor->base);
   18.91 +	}
   18.92 +
   18.93 +	/* make sure data available is gone */
   18.94 +	status = inb(chip->vendor->base + 1);
   18.95 +	if (status & ATML_STATUS_DATA_AVAIL) {
   18.96 +		dev_err(&chip->pci_dev->dev, "data available is stuck\n");
   18.97 +		return -EIO;
   18.98 +	}
   18.99 +
  18.100 +	return size;
  18.101 +}
  18.102 +
  18.103 +static int tpm_atml_send(struct tpm_chip *chip, u8 * buf, size_t count)
  18.104 +{
  18.105 +	int i;
  18.106 +
  18.107 +	dev_dbg(&chip->pci_dev->dev, "tpm_atml_send: ");
  18.108 +	for (i = 0; i < count; i++) {
  18.109 +		dev_dbg(&chip->pci_dev->dev, "0x%x(%d) ", buf[i], buf[i]);
  18.110 +		outb(buf[i], chip->vendor->base);
  18.111 +	}
  18.112 +
  18.113 +	return count;
  18.114 +}
  18.115 +
  18.116 +static void tpm_atml_cancel(struct tpm_chip *chip)
  18.117 +{
  18.118 +	outb(ATML_STATUS_ABORT, chip->vendor->base + 1);
  18.119 +}
  18.120 +
  18.121 +static struct file_operations atmel_ops = {
  18.122 +	.owner = THIS_MODULE,
  18.123 +	.llseek = no_llseek,
  18.124 +	.open = tpm_open,
  18.125 +	.read = tpm_read,
  18.126 +	.write = tpm_write,
  18.127 +	.release = tpm_release,
  18.128 +};
  18.129 +
  18.130 +static struct tpm_vendor_specific tpm_atmel = {
  18.131 +	.recv = tpm_atml_recv,
  18.132 +	.send = tpm_atml_send,
  18.133 +	.cancel = tpm_atml_cancel,
  18.134 +	.req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL,
  18.135 +	.req_complete_val = ATML_STATUS_DATA_AVAIL,
  18.136 +	.miscdev = { .fops = &atmel_ops, },
  18.137 +};
  18.138 +
  18.139 +static int __devinit tpm_atml_init(struct pci_dev *pci_dev,
  18.140 +				   const struct pci_device_id *pci_id)
  18.141 +{
  18.142 +	u8 version[4];
  18.143 +	int rc = 0;
  18.144 +	int lo, hi;
  18.145 +
  18.146 +	if (pci_enable_device(pci_dev))
  18.147 +		return -EIO;
  18.148 +
  18.149 +	lo = tpm_read_index( TPM_ATMEL_BASE_ADDR_LO );
  18.150 +	hi = tpm_read_index( TPM_ATMEL_BASE_ADDR_HI );
  18.151 +
  18.152 +	tpm_atmel.base = (hi<<8)|lo;
  18.153 +	dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base);
  18.154 +
  18.155 +	/* verify that it is an Atmel part */
  18.156 +	if (tpm_read_index(4) != 'A' || tpm_read_index(5) != 'T'
  18.157 +	    || tpm_read_index(6) != 'M' || tpm_read_index(7) != 'L') {
  18.158 +		rc = -ENODEV;
  18.159 +		goto out_err;
  18.160 +	}
  18.161 +
  18.162 +	/* query chip for its version number */
  18.163 +	if ((version[0] = tpm_read_index(0x00)) != 0xFF) {
  18.164 +		version[1] = tpm_read_index(0x01);
  18.165 +		version[2] = tpm_read_index(0x02);
  18.166 +		version[3] = tpm_read_index(0x03);
  18.167 +	} else {
  18.168 +		dev_info(&pci_dev->dev, "version query failed\n");
  18.169 +		rc = -ENODEV;
  18.170 +		goto out_err;
  18.171 +	}
  18.172 +
  18.173 +	if ((rc = tpm_register_hardware(pci_dev, &tpm_atmel)) < 0)
  18.174 +		goto out_err;
  18.175 +
  18.176 +	dev_info(&pci_dev->dev,
  18.177 +		 "Atmel TPM version %d.%d.%d.%d\n", version[0], version[1],
  18.178 +		 version[2], version[3]);
  18.179 +
  18.180 +	return 0;
  18.181 +out_err:
  18.182 +	pci_disable_device(pci_dev);
  18.183 +	return rc;
  18.184 +}
  18.185 +
  18.186 +static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
  18.187 +	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
  18.188 +	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
  18.189 +	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
  18.190 +	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
  18.191 +	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
  18.192 +	{PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
  18.193 +	{0,}
  18.194 +};
  18.195 +
  18.196 +MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
  18.197 +
  18.198 +static struct pci_driver atmel_pci_driver = {
  18.199 +	.name = "tpm_atmel",
  18.200 +	.id_table = tpm_pci_tbl,
  18.201 +	.probe = tpm_atml_init,
  18.202 +	.remove = __devexit_p(tpm_remove),
  18.203 +	.suspend = tpm_pm_suspend,
  18.204 +	.resume = tpm_pm_resume,
  18.205 +};
  18.206 +
  18.207 +static int __init init_atmel(void)
  18.208 +{
  18.209 +	return pci_register_driver(&atmel_pci_driver);
  18.210 +}
  18.211 +
  18.212 +static void __exit cleanup_atmel(void)
  18.213 +{
  18.214 +	pci_unregister_driver(&atmel_pci_driver);
  18.215 +}
  18.216 +
  18.217 +module_init(init_atmel);
  18.218 +module_exit(cleanup_atmel);
  18.219 +
  18.220 +MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
  18.221 +MODULE_DESCRIPTION("TPM Driver");
  18.222 +MODULE_VERSION("2.0");
  18.223 +MODULE_LICENSE("GPL");
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_nopci.c	Thu Sep 01 10:16:14 2005 +0000
    19.3 @@ -0,0 +1,741 @@
    19.4 +/*
    19.5 + * Copyright (C) 2004 IBM Corporation
    19.6 + *
    19.7 + * Authors:
    19.8 + * Leendert van Doorn <leendert@watson.ibm.com>
    19.9 + * Dave Safford <safford@watson.ibm.com>
   19.10 + * Reiner Sailer <sailer@watson.ibm.com>
   19.11 + * Kylene Hall <kjhall@us.ibm.com>
   19.12 + *
   19.13 + * Maintained by: <tpmdd_devel@lists.sourceforge.net>
   19.14 + *
   19.15 + * Device driver for TCG/TCPA TPM (trusted platform module).
   19.16 + * Specifications at www.trustedcomputinggroup.org
   19.17 + *
   19.18 + * This program is free software; you can redistribute it and/or
   19.19 + * modify it under the terms of the GNU General Public License as
   19.20 + * published by the Free Software Foundation, version 2 of the
   19.21 + * License.
   19.22 + *
   19.23 + * Note, the TPM chip is not interrupt driven (only polling)
   19.24 + * and can have very long timeouts (minutes!). Hence the unusual
   19.25 + * calls to schedule_timeout.
   19.26 + *
   19.27 + */
   19.28 +
   19.29 +#include <linux/sched.h>
   19.30 +#include <linux/poll.h>
   19.31 +#include <linux/spinlock.h>
   19.32 +#include "tpm_nopci.h"
   19.33 +
   19.34 +enum {
   19.35 +	TPM_MINOR = 224,	/* officially assigned */
   19.36 +	TPM_BUFSIZE = 2048,
   19.37 +	TPM_NUM_DEVICES = 256,
   19.38 +	TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int))
   19.39 +};
   19.40 +
   19.41 +  /* PCI configuration addresses */
   19.42 +enum {
   19.43 +	PCI_GEN_PMCON_1 = 0xA0,
   19.44 +	PCI_GEN1_DEC = 0xE4,
   19.45 +	PCI_LPC_EN = 0xE6,
   19.46 +	PCI_GEN2_DEC = 0xEC
   19.47 +};
   19.48 +
   19.49 +enum {
   19.50 +	TPM_LOCK_REG = 0x0D,
   19.51 +	TPM_INTERUPT_REG = 0x0A,
   19.52 +	TPM_BASE_ADDR_LO = 0x08,
   19.53 +	TPM_BASE_ADDR_HI = 0x09,
   19.54 +	TPM_UNLOCK_VALUE = 0x55,
   19.55 +	TPM_LOCK_VALUE = 0xAA,
   19.56 +	TPM_DISABLE_INTERUPT_VALUE = 0x00
   19.57 +};
   19.58 +
   19.59 +static LIST_HEAD(tpm_chip_list);
   19.60 +static spinlock_t driver_lock = SPIN_LOCK_UNLOCKED;
   19.61 +static int dev_mask[32];
   19.62 +
   19.63 +static void user_reader_timeout(unsigned long ptr)
   19.64 +{
   19.65 +	struct tpm_chip *chip = (struct tpm_chip *) ptr;
   19.66 +
   19.67 +	down(&chip->buffer_mutex);
   19.68 +	atomic_set(&chip->data_pending, 0);
   19.69 +	memset(chip->data_buffer, 0, TPM_BUFSIZE);
   19.70 +	up(&chip->buffer_mutex);
   19.71 +}
   19.72 +
   19.73 +void tpm_time_expired(unsigned long ptr)
   19.74 +{
   19.75 +	int *exp = (int *) ptr;
   19.76 +	*exp = 1;
   19.77 +}
   19.78 +
   19.79 +EXPORT_SYMBOL_GPL(tpm_time_expired);
   19.80 +
   19.81 +
   19.82 +/*
   19.83 + * This function should be used by other kernel subsystems attempting to use the tpm through the tpm_transmit interface.
   19.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.
   19.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.
   19.86 + */
   19.87 +struct tpm_chip* tpm_chip_lookup(int chip_num)
   19.88 +{
   19.89 +
   19.90 +	struct tpm_chip *pos;
   19.91 +	list_for_each_entry(pos, &tpm_chip_list, list)
   19.92 +		if (pos->dev_num == chip_num ||
   19.93 +		    chip_num == TPM_ANY_NUM)
   19.94 +			return pos;
   19.95 +
   19.96 +	return NULL;
   19.97 +
   19.98 +}
   19.99 +
  19.100 +/*
  19.101 + * Internal kernel interface to transmit TPM commands
  19.102 + */
  19.103 +ssize_t tpm_transmit(struct tpm_chip * chip, const char *buf,
  19.104 +		     size_t bufsiz)
  19.105 +{
  19.106 +	ssize_t rc;
  19.107 +	u32 count;
  19.108 +	unsigned long stop;
  19.109 +
  19.110 +	count = be32_to_cpu(*((__be32 *) (buf + 2)));
  19.111 +
  19.112 +	if (count == 0)
  19.113 +		return -ENODATA;
  19.114 +	if (count > bufsiz) {
  19.115 +		dev_err(chip->dev,
  19.116 +			"invalid count value %x %x \n", count, bufsiz);
  19.117 +		return -E2BIG;
  19.118 +	}
  19.119 +
  19.120 +	dev_dbg(chip->dev, "TPM Ordinal: %d\n",
  19.121 +		be32_to_cpu(*((__be32 *) (buf + 6))));
  19.122 +	dev_dbg(chip->dev, "Chip Status: %x\n",
  19.123 +		inb(chip->vendor->base + 1));
  19.124 +
  19.125 +	down(&chip->tpm_mutex);
  19.126 +
  19.127 +	if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
  19.128 +		dev_err(chip->dev,
  19.129 +			"tpm_transmit: tpm_send: error %d\n", rc);
  19.130 +		goto out;
  19.131 +	}
  19.132 +
  19.133 +	stop = jiffies + 2 * 60 * HZ;
  19.134 +	do {
  19.135 +		u8 status = chip->vendor->status(chip);
  19.136 +		if ((status & chip->vendor->req_complete_mask) ==
  19.137 +		    chip->vendor->req_complete_val) {
  19.138 +			goto out_recv;
  19.139 +		}
  19.140 +
  19.141 +		if ((status == chip->vendor->req_canceled)) {
  19.142 +			dev_err(chip->dev, "Operation Canceled\n");
  19.143 +			rc = -ECANCELED;
  19.144 +			goto out;
  19.145 +		}
  19.146 +
  19.147 +		msleep(TPM_TIMEOUT);	/* CHECK */
  19.148 +		rmb();
  19.149 +	}
  19.150 +	while (time_before(jiffies, stop));
  19.151 +
  19.152 +
  19.153 +	chip->vendor->cancel(chip);
  19.154 +	dev_err(chip->dev, "Operation Timed out\n");
  19.155 +	rc = -ETIME;
  19.156 +	goto out;
  19.157 +
  19.158 +out_recv:
  19.159 +	rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
  19.160 +	if (rc < 0)
  19.161 +		dev_err(chip->dev,
  19.162 +			"tpm_transmit: tpm_recv: error %d\n", rc);
  19.163 +	atomic_set(&chip->data_position, 0);
  19.164 +
  19.165 +out:
  19.166 +	up(&chip->tpm_mutex);
  19.167 +	return rc;
  19.168 +}
  19.169 +
  19.170 +EXPORT_SYMBOL_GPL(tpm_transmit);
  19.171 +
  19.172 +#define TPM_DIGEST_SIZE 20
  19.173 +#define CAP_PCR_RESULT_SIZE 18
  19.174 +static const u8 cap_pcr[] = {
  19.175 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
  19.176 +	0, 0, 0, 22,		/* length */
  19.177 +	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
  19.178 +	0, 0, 0, 5,
  19.179 +	0, 0, 0, 4,
  19.180 +	0, 0, 1, 1
  19.181 +};
  19.182 +
  19.183 +#define READ_PCR_RESULT_SIZE 30
  19.184 +static const u8 pcrread[] = {
  19.185 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
  19.186 +	0, 0, 0, 14,		/* length */
  19.187 +	0, 0, 0, 21,		/* TPM_ORD_PcrRead */
  19.188 +	0, 0, 0, 0		/* PCR index */
  19.189 +};
  19.190 +
  19.191 +ssize_t tpm_show_pcrs(struct device *dev, char *buf)
  19.192 +{
  19.193 +	u8 data[READ_PCR_RESULT_SIZE];
  19.194 +	ssize_t len;
  19.195 +	int i, j, num_pcrs;
  19.196 +	__be32 index;
  19.197 +	char *str = buf;
  19.198 +
  19.199 +	struct tpm_chip *chip = dev_get_drvdata(dev);
  19.200 +	if (chip == NULL)
  19.201 +		return -ENODEV;
  19.202 +
  19.203 +	memcpy(data, cap_pcr, sizeof(cap_pcr));
  19.204 +	if ((len = tpm_transmit(chip, data, sizeof(data)))
  19.205 +	    < CAP_PCR_RESULT_SIZE)
  19.206 +		return len;
  19.207 +
  19.208 +	num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
  19.209 +
  19.210 +	for (i = 0; i < num_pcrs; i++) {
  19.211 +		memcpy(data, pcrread, sizeof(pcrread));
  19.212 +		index = cpu_to_be32(i);
  19.213 +		memcpy(data + 10, &index, 4);
  19.214 +		if ((len = tpm_transmit(chip, data, sizeof(data)))
  19.215 +		    < READ_PCR_RESULT_SIZE)
  19.216 +			return len;
  19.217 +		str += sprintf(str, "PCR-%02d: ", i);
  19.218 +		for (j = 0; j < TPM_DIGEST_SIZE; j++)
  19.219 +			str += sprintf(str, "%02X ", *(data + 10 + j));
  19.220 +		str += sprintf(str, "\n");
  19.221 +	}
  19.222 +	return str - buf;
  19.223 +}
  19.224 +
  19.225 +EXPORT_SYMBOL_GPL(tpm_show_pcrs);
  19.226 +
  19.227 +/*
  19.228 + * Return 0 on success.  On error pass along error code.
  19.229 + * chip_id Upper 2 bytes equal ANY, HW_ONLY or SW_ONLY
  19.230 + * Lower 2 bytes equal tpm idx # or AN&
  19.231 + * res_buf must fit a TPM_PCR (20 bytes) or NULL if you don't care
  19.232 + */
  19.233 +int tpm_pcr_read( u32 chip_id, int pcr_idx, u8* res_buf, int res_buf_size )
  19.234 +{
  19.235 +	u8 data[READ_PCR_RESULT_SIZE];
  19.236 +	int rc;
  19.237 +	__be32 index;
  19.238 +	int chip_num = chip_id & TPM_CHIP_NUM_MASK;
  19.239 +	struct tpm_chip* chip;
  19.240 +
  19.241 +	if ( res_buf && res_buf_size < TPM_DIGEST_SIZE )
  19.242 +		return -ENOSPC;
  19.243 +	if ( (chip = tpm_chip_lookup( chip_num /*,
  19.244 +				       chip_id >> TPM_CHIP_TYPE_SHIFT*/ ) ) == NULL ) {
  19.245 +		printk("chip %d not found.\n",chip_num);
  19.246 +		return -ENODEV;
  19.247 +	}
  19.248 +	memcpy(data, pcrread, sizeof(pcrread));
  19.249 +	index = cpu_to_be32(pcr_idx);
  19.250 +	memcpy(data + 10, &index, 4);
  19.251 +	if ((rc = tpm_transmit(chip, data, sizeof(data))) > 0 )
  19.252 +		rc = be32_to_cpu(*((u32*)(data+6)));
  19.253 +
  19.254 +	if ( rc == 0 && res_buf )
  19.255 +		memcpy(res_buf, data+10, TPM_DIGEST_SIZE);
  19.256 +	return rc;
  19.257 +}
  19.258 +EXPORT_SYMBOL_GPL(tpm_pcr_read);
  19.259 +
  19.260 +#define EXTEND_PCR_SIZE 34
  19.261 +static const u8 pcrextend[] = {
  19.262 +	0, 193,		 		 		 /* TPM_TAG_RQU_COMMAND */
  19.263 +	0, 0, 0, 34,		 		 /* length */
  19.264 +	0, 0, 0, 20,		 		 /* TPM_ORD_Extend */
  19.265 +	0, 0, 0, 0		 		 /* PCR index */
  19.266 +};
  19.267 +
  19.268 +/*
  19.269 + * Return 0 on success.  On error pass along error code.
  19.270 + * chip_id Upper 2 bytes equal ANY, HW_ONLY or SW_ONLY
  19.271 + * Lower 2 bytes equal tpm idx # or ANY
  19.272 + */
  19.273 +int tpm_pcr_extend(u32 chip_id, int pcr_idx, const u8* hash)
  19.274 +{
  19.275 +	u8 data[EXTEND_PCR_SIZE];
  19.276 +	int rc;
  19.277 +	__be32 index;
  19.278 +	int chip_num = chip_id & TPM_CHIP_NUM_MASK;
  19.279 +	struct tpm_chip* chip;
  19.280 +
  19.281 +	if ( (chip = tpm_chip_lookup( chip_num /*,
  19.282 +				      chip_id >> TPM_CHIP_TYPE_SHIFT */)) == NULL )
  19.283 +		return -ENODEV;
  19.284 +
  19.285 +	memcpy(data, pcrextend, sizeof(pcrextend));
  19.286 +	index = cpu_to_be32(pcr_idx);
  19.287 +	memcpy(data + 10, &index, 4);
  19.288 +	memcpy( data + 14, hash, TPM_DIGEST_SIZE );
  19.289 +	if ((rc = tpm_transmit(chip, data, sizeof(data))) > 0 )
  19.290 +		rc = be32_to_cpu(*((u32*)(data+6)));
  19.291 +	return rc;
  19.292 +}
  19.293 +EXPORT_SYMBOL_GPL(tpm_pcr_extend);
  19.294 +
  19.295 +
  19.296 +
  19.297 +#define  READ_PUBEK_RESULT_SIZE 314
  19.298 +static const u8 readpubek[] = {
  19.299 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
  19.300 +	0, 0, 0, 30,		/* length */
  19.301 +	0, 0, 0, 124,		/* TPM_ORD_ReadPubek */
  19.302 +};
  19.303 +
  19.304 +ssize_t tpm_show_pubek(struct device *dev, char *buf)
  19.305 +{
  19.306 +	u8 *data;
  19.307 +	ssize_t len;
  19.308 +	int i, rc;
  19.309 +	char *str = buf;
  19.310 +
  19.311 +	struct tpm_chip *chip = dev_get_drvdata(dev);
  19.312 +	if (chip == NULL)
  19.313 +		return -ENODEV;
  19.314 +
  19.315 +	data = kmalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
  19.316 +	if (!data)
  19.317 +		return -ENOMEM;
  19.318 +
  19.319 +	memcpy(data, readpubek, sizeof(readpubek));
  19.320 +	memset(data + sizeof(readpubek), 0, 20);	/* zero nonce */
  19.321 +
  19.322 +	if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <
  19.323 +	    READ_PUBEK_RESULT_SIZE) {
  19.324 +		rc = len;
  19.325 +		goto out;
  19.326 +	}
  19.327 +
  19.328 +	/*
  19.329 +	   ignore header 10 bytes
  19.330 +	   algorithm 32 bits (1 == RSA )
  19.331 +	   encscheme 16 bits
  19.332 +	   sigscheme 16 bits
  19.333 +	   parameters (RSA 12->bytes: keybit, #primes, expbit)
  19.334 +	   keylenbytes 32 bits
  19.335 +	   256 byte modulus
  19.336 +	   ignore checksum 20 bytes
  19.337 +	 */
  19.338 +
  19.339 +	str +=
  19.340 +	    sprintf(str,
  19.341 +		    "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
  19.342 +		    "Sigscheme: %02X %02X\nParameters: %02X %02X %02X %02X"
  19.343 +		    " %02X %02X %02X %02X %02X %02X %02X %02X\n"
  19.344 +		    "Modulus length: %d\nModulus: \n",
  19.345 +		    data[10], data[11], data[12], data[13], data[14],
  19.346 +		    data[15], data[16], data[17], data[22], data[23],
  19.347 +		    data[24], data[25], data[26], data[27], data[28],
  19.348 +		    data[29], data[30], data[31], data[32], data[33],
  19.349 +		    be32_to_cpu(*((__be32 *) (data + 32))));
  19.350 +
  19.351 +	for (i = 0; i < 256; i++) {
  19.352 +		str += sprintf(str, "%02X ", data[i + 39]);
  19.353 +		if ((i + 1) % 16 == 0)
  19.354 +			str += sprintf(str, "\n");
  19.355 +	}
  19.356 +	rc = str - buf;
  19.357 +out:
  19.358 +	kfree(data);
  19.359 +	return rc;
  19.360 +}
  19.361 +
  19.362 +EXPORT_SYMBOL_GPL(tpm_show_pubek);
  19.363 +
  19.364 +#define CAP_VER_RESULT_SIZE 18
  19.365 +static const u8 cap_version[] = {
  19.366 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
  19.367 +	0, 0, 0, 18,		/* length */
  19.368 +	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
  19.369 +	0, 0, 0, 6,
  19.370 +	0, 0, 0, 0
  19.371 +};
  19.372 +
  19.373 +#define CAP_MANUFACTURER_RESULT_SIZE 18
  19.374 +static const u8 cap_manufacturer[] = {
  19.375 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
  19.376 +	0, 0, 0, 22,		/* length */
  19.377 +	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
  19.378 +	0, 0, 0, 5,
  19.379 +	0, 0, 0, 4,
  19.380 +	0, 0, 1, 3
  19.381 +};
  19.382 +
  19.383 +ssize_t tpm_show_caps(struct device *dev, char *buf)
  19.384 +{
  19.385 +	u8 data[sizeof(cap_manufacturer)];
  19.386 +	ssize_t len;
  19.387 +	char *str = buf;
  19.388 +
  19.389 +	struct tpm_chip *chip = dev_get_drvdata(dev);
  19.390 +	if (chip == NULL)
  19.391 +		return -ENODEV;
  19.392 +
  19.393 +	memcpy(data, cap_manufacturer, sizeof(cap_manufacturer));
  19.394 +
  19.395 +	if ((len = tpm_transmit(chip, data, sizeof(data))) <
  19.396 +	    CAP_MANUFACTURER_RESULT_SIZE)
  19.397 +		return len;
  19.398 +
  19.399 +	str += sprintf(str, "Manufacturer: 0x%x\n",
  19.400 +		       be32_to_cpu(*((__be32 *)(data + 14))));
  19.401 +
  19.402 +	memcpy(data, cap_version, sizeof(cap_version));
  19.403 +
  19.404 +	if ((len = tpm_transmit(chip, data, sizeof(data))) <
  19.405 +	    CAP_VER_RESULT_SIZE)
  19.406 +		return len;
  19.407 +
  19.408 +	str +=
  19.409 +	    sprintf(str, "TCG version: %d.%d\nFirmware version: %d.%d\n",
  19.410 +		    (int) data[14], (int) data[15], (int) data[16],
  19.411 +		    (int) data[17]);
  19.412 +
  19.413 +	return str - buf;
  19.414 +}
  19.415 +
  19.416 +EXPORT_SYMBOL_GPL(tpm_show_caps);
  19.417 +
  19.418 +ssize_t tpm_store_cancel(struct device * dev, const char *buf,
  19.419 +			 size_t count)
  19.420 +{
  19.421 +	struct tpm_chip *chip = dev_get_drvdata(dev);
  19.422 +	if (chip == NULL)
  19.423 +		return 0;
  19.424 +
  19.425 +	chip->vendor->cancel(chip);
  19.426 +	return count;
  19.427 +}
  19.428 +
  19.429 +EXPORT_SYMBOL_GPL(tpm_store_cancel);
  19.430 +
  19.431 +/*
  19.432 + * Device file system interface to the TPM
  19.433 + */
  19.434 +int tpm_open(struct inode *inode, struct file *file)
  19.435 +{
  19.436 +	int rc = 0, minor = iminor(inode);
  19.437 +	struct tpm_chip *chip = NULL, *pos;
  19.438 +
  19.439 +	spin_lock(&driver_lock);
  19.440 +
  19.441 +	list_for_each_entry(pos, &tpm_chip_list, list) {
  19.442 +		if (pos->vendor->miscdev.minor == minor) {
  19.443 +			chip = pos;
  19.444 +			break;
  19.445 +		}
  19.446 +	}
  19.447 +
  19.448 +	if (chip == NULL) {
  19.449 +		rc = -ENODEV;
  19.450 +		goto err_out;
  19.451 +	}
  19.452 +
  19.453 +	if (chip->num_opens) {
  19.454 +		dev_dbg(chip->dev, "Another process owns this TPM\n");
  19.455 +		rc = -EBUSY;
  19.456 +		goto err_out;
  19.457 +	}
  19.458 +
  19.459 +	chip->num_opens++;
  19.460 +	get_device(chip->dev);
  19.461 +
  19.462 +	spin_unlock(&driver_lock);
  19.463 +
  19.464 +	chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
  19.465 +	if (chip->data_buffer == NULL) {
  19.466 +		chip->num_opens--;
  19.467 +		put_device(chip->dev);
  19.468 +		return -ENOMEM;
  19.469 +	}
  19.470 +
  19.471 +	atomic_set(&chip->data_pending, 0);
  19.472 +
  19.473 +	file->private_data = chip;
  19.474 +	return 0;
  19.475 +
  19.476 +err_out:
  19.477 +	spin_unlock(&driver_lock);
  19.478 +	return rc;
  19.479 +}
  19.480 +
  19.481 +EXPORT_SYMBOL_GPL(tpm_open);
  19.482 +
  19.483 +int tpm_release(struct inode *inode, struct file *file)
  19.484 +{
  19.485 +	struct tpm_chip *chip = file->private_data;
  19.486 +
  19.487 +	spin_lock(&driver_lock);
  19.488 +	file->private_data = NULL;
  19.489 +	chip->num_opens--;
  19.490 +	del_singleshot_timer_sync(&chip->user_read_timer);
  19.491 +	atomic_set(&chip->data_pending, 0);
  19.492 +	put_device(chip->dev);
  19.493 +	kfree(chip->data_buffer);
  19.494 +	spin_unlock(&driver_lock);
  19.495 +	return 0;
  19.496 +}
  19.497 +
  19.498 +EXPORT_SYMBOL_GPL(tpm_release);
  19.499 +
  19.500 +ssize_t tpm_write(struct file * file, const char __user * buf,
  19.501 +		  size_t size, loff_t * off)
  19.502 +{
  19.503 +	struct tpm_chip *chip = file->private_data;
  19.504 +	int in_size = size, out_size;
  19.505 +
  19.506 +	/* cannot perform a write until the read has cleared
  19.507 +	   either via tpm_read or a user_read_timer timeout */
  19.508 +	while (atomic_read(&chip->data_pending) != 0)
  19.509 +		msleep(TPM_TIMEOUT);
  19.510 +
  19.511 +	down(&chip->buffer_mutex);
  19.512 +
  19.513 +	if (in_size > TPM_BUFSIZE)
  19.514 +		in_size = TPM_BUFSIZE;
  19.515 +
  19.516 +	if (copy_from_user
  19.517 +	    (chip->data_buffer, (void __user *) buf, in_size)) {
  19.518 +		up(&chip->buffer_mutex);
  19.519 +		return -EFAULT;
  19.520 +	}
  19.521 +
  19.522 +	/* atomic tpm command send and result receive */
  19.523 +	out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
  19.524 +
  19.525 +	atomic_set(&chip->data_pending, out_size);
  19.526 +	up(&chip->buffer_mutex);
  19.527 +
  19.528 +	/* Set a timeout by which the reader must come claim the result */
  19.529 +	mod_timer(&chip->user_read_timer, jiffies + (60 * HZ));
  19.530 +
  19.531 +	return in_size;
  19.532 +}
  19.533 +
  19.534 +EXPORT_SYMBOL_GPL(tpm_write);
  19.535 +
  19.536 +ssize_t tpm_read(struct file * file, char __user * buf,
  19.537 +		 size_t size, loff_t * off)
  19.538 +{
  19.539 +	struct tpm_chip *chip = file->private_data;
  19.540 +	int ret_size;
  19.541 +
  19.542 +	del_singleshot_timer_sync(&chip->user_read_timer);
  19.543 +	ret_size = atomic_read(&chip->data_pending);
  19.544 +
  19.545 +	if (ret_size > 0) {	/* relay data */
  19.546 +		int position = atomic_read(&chip->data_position);
  19.547 +
  19.548 +		if (size < ret_size)
  19.549 +			ret_size = size;
  19.550 +
  19.551 +		down(&chip->buffer_mutex);
  19.552 +
  19.553 +		if (copy_to_user((void __user *) buf,
  19.554 +				 &chip->data_buffer[position],
  19.555 +				 ret_size)) {
  19.556 +			ret_size = -EFAULT;
  19.557 +		} else {
  19.558 +		 	int pending = atomic_read(&chip->data_pending) - ret_size;
  19.559 +			atomic_set(&chip->data_pending,
  19.560 +			           pending);
  19.561 +			atomic_set(&chip->data_position,
  19.562 +			           position + ret_size);
  19.563 +		}
  19.564 +		up(&chip->buffer_mutex);
  19.565 +	}
  19.566 +
  19.567 +	return ret_size;
  19.568 +}
  19.569 +
  19.570 +EXPORT_SYMBOL_GPL(tpm_read);
  19.571 +
  19.572 +void tpm_remove_hardware(struct device *dev)
  19.573 +{
  19.574 +	struct tpm_chip *chip = dev_get_drvdata(dev);
  19.575 +	int i;
  19.576 +
  19.577 +	if (chip == NULL) {
  19.578 +		dev_err(dev, "No device data found\n");
  19.579 +		return;
  19.580 +	}
  19.581 +
  19.582 +	spin_lock(&driver_lock);
  19.583 +
  19.584 +	list_del(&chip->list);
  19.585 +
  19.586 +	spin_unlock(&driver_lock);
  19.587 +
  19.588 +	dev_set_drvdata(dev, NULL);
  19.589 +	misc_deregister(&chip->vendor->miscdev);
  19.590 +
  19.591 +	for (i = 0; i < TPM_NUM_ATTR; i++)
  19.592 +		device_remove_file(dev, &chip->vendor->attr[i]);
  19.593 +
  19.594 +	dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES] &=
  19.595 +	    !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
  19.596 +
  19.597 +	kfree(chip);
  19.598 +
  19.599 +	put_device(dev);
  19.600 +}
  19.601 +
  19.602 +EXPORT_SYMBOL_GPL(tpm_remove_hardware);
  19.603 +
  19.604 +static const u8 savestate[] = {
  19.605 +	0, 193,			/* TPM_TAG_RQU_COMMAND */
  19.606 +	0, 0, 0, 10,		/* blob length (in bytes) */
  19.607 +	0, 0, 0, 152		/* TPM_ORD_SaveState */
  19.608 +};
  19.609 +
  19.610 +/*
  19.611 + * We are about to suspend. Save the TPM state
  19.612 + * so that it can be restored.
  19.613 + */
  19.614 +int tpm_pm_suspend(struct pci_dev *pci_dev, u32 pm_state)
  19.615 +{
  19.616 +	struct tpm_chip *chip = pci_get_drvdata(pci_dev);
  19.617 +	if (chip == NULL)
  19.618 +		return -ENODEV;
  19.619 +
  19.620 +	tpm_transmit(chip, savestate, sizeof(savestate));
  19.621 +	return 0;
  19.622 +}
  19.623 +
  19.624 +EXPORT_SYMBOL_GPL(tpm_pm_suspend);
  19.625 +
  19.626 +/*
  19.627 + * Resume from a power safe. The BIOS already restored
  19.628 + * the TPM state.
  19.629 + */
  19.630 +int tpm_pm_resume(struct pci_dev *pci_dev)
  19.631 +{
  19.632 +	struct tpm_chip *chip = pci_get_drvdata(pci_dev);
  19.633 +
  19.634 +	if (chip == NULL)
  19.635 +		return -ENODEV;
  19.636 +
  19.637 +	return 0;
  19.638 +}
  19.639 +
  19.640 +EXPORT_SYMBOL_GPL(tpm_pm_resume);
  19.641 +
  19.642 +/*
  19.643 + * Called from tpm_<specific>.c probe function only for devices
  19.644 + * the driver has determined it should claim.  Prior to calling
  19.645 + * this function the specific probe function has called pci_enable_device
  19.646 + * upon errant exit from this function specific probe function should call
  19.647 + * pci_disable_device
  19.648 + */
  19.649 +int tpm_register_hardware_nopci(struct device *dev,
  19.650 +			        struct tpm_vendor_specific *entry)
  19.651 +{
  19.652 +	char devname[7];
  19.653 +	struct tpm_chip *chip;
  19.654 +	int i, j;
  19.655 +
  19.656 +	/* Driver specific per-device data */
  19.657 +	chip = kmalloc(sizeof(*chip), GFP_KERNEL);
  19.658 +	if (chip == NULL)
  19.659 +		return -ENOMEM;
  19.660 +
  19.661 +	memset(chip, 0, sizeof(struct tpm_chip));
  19.662 +
  19.663 +	init_MUTEX(&chip->buffer_mutex);
  19.664 +	init_MUTEX(&chip->tpm_mutex);
  19.665 +	INIT_LIST_HEAD(&chip->list);
  19.666 +
  19.667 +	init_timer(&chip->user_read_timer);
  19.668 +	chip->user_read_timer.function = user_reader_timeout;
  19.669 +	chip->user_read_timer.data = (unsigned long) chip;
  19.670 +
  19.671 +	chip->vendor = entry;
  19.672 +
  19.673 +	chip->dev_num = -1;
  19.674 +
  19.675 +	for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++)
  19.676 +		for (j = 0; j < 8 * sizeof(int); j++)
  19.677 +			if ((dev_mask[i] & (1 << j)) == 0) {
  19.678 +				chip->dev_num =
  19.679 +				    i * TPM_NUM_MASK_ENTRIES + j;
  19.680 +				dev_mask[i] |= 1 << j;
  19.681 +				goto dev_num_search_complete;
  19.682 +			}
  19.683 +
  19.684 +dev_num_search_complete:
  19.685 +	if (chip->dev_num < 0) {
  19.686 +		dev_err(dev, "No available tpm device numbers\n");
  19.687 +		kfree(chip);
  19.688 +		return -ENODEV;
  19.689 +	} else if (chip->dev_num == 0)
  19.690 +		chip->vendor->miscdev.minor = TPM_MINOR;
  19.691 +	else
  19.692 +		chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
  19.693 +
  19.694 +	snprintf(devname, sizeof(devname), "%s%d", "tpm", chip->dev_num);
  19.695 +	chip->vendor->miscdev.name = devname;
  19.696 +
  19.697 +	chip->vendor->miscdev.dev = dev;
  19.698 +	chip->dev = get_device(dev);
  19.699 +
  19.700 +
  19.701 +	if (misc_register(&chip->vendor->miscdev)) {
  19.702 +		dev_err(chip->dev,
  19.703 +			"unable to misc_register %s, minor %d\n",
  19.704 +			chip->vendor->miscdev.name,
  19.705 +			chip->vendor->miscdev.minor);
  19.706 +		put_device(dev);
  19.707 +		kfree(chip);
  19.708 +		dev_mask[i] &= !(1 << j);
  19.709 +		return -ENODEV;
  19.710 +	}
  19.711 +
  19.712 +	spin_lock(&driver_lock);
  19.713 +
  19.714 +	dev_set_drvdata(dev, chip);
  19.715 +
  19.716 +	list_add(&chip->list, &tpm_chip_list);
  19.717 +
  19.718 +	spin_unlock(&driver_lock);
  19.719 +
  19.720 +	for (i = 0; i < TPM_NUM_ATTR; i++)
  19.721 +		device_create_file(dev, &chip->vendor->attr[i]);
  19.722 +
  19.723 +	return 0;
  19.724 +}
  19.725 +
  19.726 +EXPORT_SYMBOL_GPL(tpm_register_hardware_nopci);
  19.727 +
  19.728 +static int __init init_tpm(void)
  19.729 +{
  19.730 +	return 0;
  19.731 +}
  19.732 +
  19.733 +static void __exit cleanup_tpm(void)
  19.734 +{
  19.735 +
  19.736 +}
  19.737 +
  19.738 +module_init(init_tpm);
  19.739 +module_exit(cleanup_tpm);
  19.740 +
  19.741 +MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
  19.742 +MODULE_DESCRIPTION("TPM Driver");
  19.743 +MODULE_VERSION("2.0");
  19.744 +MODULE_LICENSE("GPL");
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_nopci.h	Thu Sep 01 10:16:14 2005 +0000
    20.3 @@ -0,0 +1,127 @@
    20.4 +/*
    20.5 + * Copyright (C) 2004 IBM Corporation
    20.6 + *
    20.7 + * Authors:
    20.8 + * Leendert van Doorn <leendert@watson.ibm.com>
    20.9 + * Dave Safford <safford@watson.ibm.com>
   20.10 + * Reiner Sailer <sailer@watson.ibm.com>
   20.11 + * Kylene Hall <kjhall@us.ibm.com>
   20.12 + *
   20.13 + * Maintained by: <tpmdd_devel@lists.sourceforge.net>
   20.14 + *
   20.15 + * Device driver for TCG/TCPA TPM (trusted platform module).
   20.16 + * Specifications at www.trustedcomputinggroup.org
   20.17 + *
   20.18 + * This program is free software; you can redistribute it and/or
   20.19 + * modify it under the terms of the GNU General Public License as
   20.20 + * published by the Free Software Foundation, version 2 of the
   20.21 + * License.
   20.22 + *
   20.23 + */
   20.24 +#include <linux/module.h>
   20.25 +#include <linux/version.h>
   20.26 +#include <linux/pci.h>
   20.27 +#include <linux/delay.h>
   20.28 +#include <linux/miscdevice.h>
   20.29 +
   20.30 +enum {
   20.31 +	TPM_TIMEOUT = 5,	/* msecs */
   20.32 +	TPM_NUM_ATTR = 4
   20.33 +};
   20.34 +
   20.35 +/* TPM addresses */
   20.36 +enum {
   20.37 +	TPM_ADDR = 0x4E,
   20.38 +	TPM_DATA = 0x4F
   20.39 +};
   20.40 +
   20.41 +/*
   20.42 + * Chip num is this value or a valid tpm idx in lower two bytes of chip_id
   20.43 + */
   20.44 +enum tpm_chip_num {
   20.45 +	TPM_ANY_NUM = 0xFFFF,
   20.46 +};
   20.47 +
   20.48 +#define TPM_CHIP_NUM_MASK	0x0000ffff
   20.49 +
   20.50 +extern ssize_t tpm_show_pubek(struct device *, char *);
   20.51 +extern ssize_t tpm_show_pcrs(struct device *, char *);
   20.52 +extern ssize_t tpm_show_caps(struct device *, char *);
   20.53 +extern ssize_t tpm_store_cancel(struct device *, const char *, size_t);
   20.54 +
   20.55 +#define TPM_DEVICE_ATTRS { \
   20.56 +	__ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL), \
   20.57 +	__ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL), \
   20.58 +	__ATTR(caps, S_IRUGO, tpm_show_caps, NULL), \
   20.59 +	__ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel) }
   20.60 +
   20.61 +struct tpm_chip;
   20.62 +
   20.63 +struct tpm_vendor_specific {
   20.64 +	u8 req_complete_mask;
   20.65 +	u8 req_complete_val;
   20.66 +	u8 req_canceled;
   20.67 +	u16 base;		/* TPM base address */
   20.68 +
   20.69 +	int (*recv) (struct tpm_chip *, u8 *, size_t);
   20.70 +	int (*send) (struct tpm_chip *, u8 *, size_t);
   20.71 +	void (*cancel) (struct tpm_chip *);
   20.72 +	 u8(*status) (struct tpm_chip *);
   20.73 +	struct miscdevice miscdev;
   20.74 +	struct device_attribute attr[TPM_NUM_ATTR];
   20.75 +};
   20.76 +
   20.77 +struct tpm_chip {
   20.78 +	struct device *dev;	/* PCI device stuff */
   20.79 +
   20.80 +	int dev_num;		/* /dev/tpm# */
   20.81 +	int num_opens;		/* only one allowed */
   20.82 +	int time_expired;
   20.83 +
   20.84 +	/* Data passed to and from the tpm via the read/write calls */
   20.85 +	u8 *data_buffer;
   20.86 +	atomic_t data_pending;
   20.87 +	atomic_t data_position;
   20.88 +	struct semaphore buffer_mutex;
   20.89 +
   20.90 +	struct timer_list user_read_timer;	/* user needs to claim result */
   20.91 +	struct semaphore tpm_mutex;	/* tpm is processing */
   20.92 +
   20.93 +	struct tpm_vendor_specific *vendor;
   20.94 +
   20.95 +	struct list_head list;
   20.96 +};
   20.97 +
   20.98 +static inline int tpm_read_index(int index)
   20.99 +{
  20.100 +	outb(index, TPM_ADDR);
  20.101 +	return inb(TPM_DATA) & 0xFF;
  20.102 +}
  20.103 +
  20.104 +static inline void tpm_write_index(int index, int value)
  20.105 +{
  20.106 +	outb(index, TPM_ADDR);
  20.107 +	outb(value & 0xFF, TPM_DATA);
  20.108 +}
  20.109 +
  20.110 +extern void tpm_time_expired(unsigned long);
  20.111 +extern int tpm_lpc_bus_init(struct pci_dev *, u16);
  20.112 +
  20.113 +extern int tpm_register_hardware_nopci(struct device *,
  20.114 +				       struct tpm_vendor_specific *);
  20.115 +extern void tpm_remove_hardware(struct device *);
  20.116 +extern int tpm_open(struct inode *, struct file *);
  20.117 +extern int tpm_release(struct inode *, struct file *);
  20.118 +extern ssize_t tpm_write(struct file *, const char __user *, size_t,
  20.119 +			 loff_t *);
  20.120 +extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *);
  20.121 +extern int tpm_pcr_extend(u32 chip_id, int pcr_idx, const u8* hash);
  20.122 +extern int tpm_pcr_read( u32 chip_id, int pcr_idx, u8* res_buf, int res_buf_size );
  20.123 +
  20.124 +extern int tpm_pm_suspend(struct pci_dev *, u32);
  20.125 +extern int tpm_pm_resume(struct pci_dev *);
  20.126 +
  20.127 +/* internal kernel interface */
  20.128 +extern ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
  20.129 +			    size_t bufsiz);
  20.130 +extern struct tpm_chip *tpm_chip_lookup(int chip_num);
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_nsc.c	Thu Sep 01 10:16:14 2005 +0000
    21.3 @@ -0,0 +1,377 @@
    21.4 +/*
    21.5 + * Copyright (C) 2004 IBM Corporation
    21.6 + *
    21.7 + * Authors:
    21.8 + * Leendert van Doorn <leendert@watson.ibm.com>
    21.9 + * Dave Safford <safford@watson.ibm.com>
   21.10 + * Reiner Sailer <sailer@watson.ibm.com>
   21.11 + * Kylene Hall <kjhall@us.ibm.com>
   21.12 + *
   21.13 + * Maintained by: <tpmdd_devel@lists.sourceforge.net>
   21.14 + *
   21.15 + * Device driver for TCG/TCPA TPM (trusted platform module).
   21.16 + * Specifications at www.trustedcomputinggroup.org
   21.17 + *
   21.18 + * This program is free software; you can redistribute it and/or
   21.19 + * modify it under the terms of the GNU General Public License as
   21.20 + * published by the Free Software Foundation, version 2 of the
   21.21 + * License.
   21.22 + *
   21.23 + */
   21.24 +
   21.25 +#include "tpm.h"
   21.26 +
   21.27 +/* National definitions */
   21.28 +#define	TPM_NSC_BASE			0x360
   21.29 +#define	TPM_NSC_IRQ			0x07
   21.30 +#define	TPM_NSC_BASE0_HI		0x60
   21.31 +#define	TPM_NSC_BASE0_LO		0x61
   21.32 +#define	TPM_NSC_BASE1_HI		0x62
   21.33 +#define	TPM_NSC_BASE1_LO		0x63
   21.34 +
   21.35 +#define	NSC_LDN_INDEX			0x07
   21.36 +#define	NSC_SID_INDEX			0x20
   21.37 +#define	NSC_LDC_INDEX			0x30
   21.38 +#define	NSC_DIO_INDEX			0x60
   21.39 +#define	NSC_CIO_INDEX			0x62
   21.40 +#define	NSC_IRQ_INDEX			0x70
   21.41 +#define	NSC_ITS_INDEX			0x71
   21.42 +
   21.43 +#define	NSC_STATUS			0x01
   21.44 +#define	NSC_COMMAND			0x01
   21.45 +#define	NSC_DATA			0x00
   21.46 +
   21.47 +/* status bits */
   21.48 +#define	NSC_STATUS_OBF			0x01	/* output buffer full */
   21.49 +#define	NSC_STATUS_IBF			0x02	/* input buffer full */
   21.50 +#define	NSC_STATUS_F0			0x04	/* F0 */
   21.51 +#define	NSC_STATUS_A2			0x08	/* A2 */
   21.52 +#define	NSC_STATUS_RDY			0x10	/* ready to receive command */
   21.53 +#define	NSC_STATUS_IBR			0x20	/* ready to receive data */
   21.54 +
   21.55 +/* command bits */
   21.56 +#define	NSC_COMMAND_NORMAL		0x01	/* normal mode */
   21.57 +#define	NSC_COMMAND_EOC			0x03
   21.58 +#define	NSC_COMMAND_CANCEL		0x22
   21.59 +
   21.60 +/*
   21.61 + * Wait for a certain status to appear
   21.62 + */
   21.63 +static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
   21.64 +{
   21.65 +	int expired = 0;
   21.66 +	struct timer_list status_timer =
   21.67 +	    TIMER_INITIALIZER(tpm_time_expired, jiffies + 10 * HZ,
   21.68 +			      (unsigned long) &expired);
   21.69 +
   21.70 +	/* status immediately available check */
   21.71 +	*data = inb(chip->vendor->base + NSC_STATUS);
   21.72 +	if ((*data & mask) == val)
   21.73 +		return 0;
   21.74 +
   21.75 +	/* wait for status */
   21.76 +	add_timer(&status_timer);
   21.77 +	do {
   21.78 +		set_current_state(TASK_UNINTERRUPTIBLE);
   21.79 +		schedule_timeout(TPM_TIMEOUT);
   21.80 +		*data = inb(chip->vendor->base + 1);
   21.81 +		if ((*data & mask) == val) {
   21.82 +			del_singleshot_timer_sync(&status_timer);
   21.83 +			return 0;
   21.84 +		}
   21.85 +	}
   21.86 +	while (!expired);
   21.87 +
   21.88 +	return -EBUSY;
   21.89 +}
   21.90 +
   21.91 +static int nsc_wait_for_ready(struct tpm_chip *chip)
   21.92 +{
   21.93 +	int status;
   21.94 +	int expired = 0;
   21.95 +	struct timer_list status_timer =
   21.96 +	    TIMER_INITIALIZER(tpm_time_expired, jiffies + 100,
   21.97 +			      (unsigned long) &expired);
   21.98 +
   21.99 +	/* status immediately available check */
  21.100 +	status = inb(chip->vendor->base + NSC_STATUS);
  21.101 +	if (status & NSC_STATUS_OBF)
  21.102 +		status = inb(chip->vendor->base + NSC_DATA);
  21.103 +	if (status & NSC_STATUS_RDY)
  21.104 +		return 0;
  21.105 +
  21.106 +	/* wait for status */
  21.107 +	add_timer(&status_timer);
  21.108 +	do {
  21.109 +		set_current_state(TASK_UNINTERRUPTIBLE);
  21.110 +		schedule_timeout(TPM_TIMEOUT);
  21.111 +		status = inb(chip->vendor->base + NSC_STATUS);
  21.112 +		if (status & NSC_STATUS_OBF)
  21.113 +			status = inb(chip->vendor->base + NSC_DATA);
  21.114 +		if (status & NSC_STATUS_RDY) {
  21.115 +			del_singleshot_timer_sync(&status_timer);
  21.116 +			return 0;
  21.117 +		}
  21.118 +	}
  21.119 +	while (!expired);
  21.120 +
  21.121 +	dev_info(&chip->pci_dev->dev, "wait for ready failed\n");
  21.122 +	return -EBUSY;
  21.123 +}
  21.124 +
  21.125 +
  21.126 +static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
  21.127 +{
  21.128 +	u8 *buffer = buf;
  21.129 +	u8 data, *p;
  21.130 +	u32 size;
  21.131 +	__be32 *native_size;
  21.132 +
  21.133 +	if (count < 6)
  21.134 +		return -EIO;
  21.135 +
  21.136 +	if (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0) {
  21.137 +		dev_err(&chip->pci_dev->dev, "F0 timeout\n");
  21.138 +		return -EIO;
  21.139 +	}
  21.140 +	if ((data =
  21.141 +	     inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
  21.142 +		dev_err(&chip->pci_dev->dev, "not in normal mode (0x%x)\n",
  21.143 +			data);
  21.144 +		return -EIO;
  21.145 +	}
  21.146 +
  21.147 +	/* read the whole packet */
  21.148 +	for (p = buffer; p < &buffer[count]; p++) {
  21.149 +		if (wait_for_stat
  21.150 +		    (chip, NSC_STATUS_OBF, NSC_STATUS_OBF, &data) < 0) {
  21.151 +			dev_err(&chip->pci_dev->dev,
  21.152 +				"OBF timeout (while reading data)\n");
  21.153 +			return -EIO;
  21.154 +		}
  21.155 +		if (data & NSC_STATUS_F0)
  21.156 +			break;
  21.157 +		*p = inb(chip->vendor->base + NSC_DATA);
  21.158 +	}
  21.159 +
  21.160 +	if ((data & NSC_STATUS_F0) == 0) {
  21.161 +		dev_err(&chip->pci_dev->dev, "F0 not set\n");
  21.162 +		return -EIO;
  21.163 +	}
  21.164 +	if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) {
  21.165 +		dev_err(&chip->pci_dev->dev,
  21.166 +			"expected end of command(0x%x)\n", data);
  21.167 +		return -EIO;
  21.168 +	}
  21.169 +
  21.170 +	native_size = (__force __be32 *) (buf + 2);
  21.171 +	size = be32_to_cpu(*native_size);
  21.172 +
  21.173 +	if (count < size)
  21.174 +		return -EIO;
  21.175 +
  21.176 +	return size;
  21.177 +}
  21.178 +
  21.179 +static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
  21.180 +{
  21.181 +	u8 data;
  21.182 +	int i;
  21.183 +
  21.184 +	/*
  21.185 +	 * If we hit the chip with back to back commands it locks up
  21.186 +	 * and never set IBF. Hitting it with this "hammer" seems to
  21.187 +	 * fix it. Not sure why this is needed, we followed the flow
  21.188 +	 * chart in the manual to the letter.
  21.189 +	 */
  21.190 +	outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
  21.191 +
  21.192 +	if (nsc_wait_for_ready(chip) != 0)
  21.193 +		return -EIO;
  21.194 +
  21.195 +	if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
  21.196 +		dev_err(&chip->pci_dev->dev, "IBF timeout\n");
  21.197 +		return -EIO;
  21.198 +	}
  21.199 +
  21.200 +	outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND);
  21.201 +	if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
  21.202 +		dev_err(&chip->pci_dev->dev, "IBR timeout\n");
  21.203 +		return -EIO;
  21.204 +	}
  21.205 +
  21.206 +	for (i = 0; i < count; i++) {
  21.207 +		if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
  21.208 +			dev_err(&chip->pci_dev->dev,
  21.209 +				"IBF timeout (while writing data)\n");
  21.210 +			return -EIO;
  21.211 +		}
  21.212 +		outb(buf[i], chip->vendor->base + NSC_DATA);
  21.213 +	}
  21.214 +
  21.215 +	if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
  21.216 +		dev_err(&chip->pci_dev->dev, "IBF timeout\n");
  21.217 +		return -EIO;
  21.218 +	}
  21.219 +	outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND);
  21.220 +
  21.221 +	return count;
  21.222 +}
  21.223 +
  21.224 +static void tpm_nsc_cancel(struct tpm_chip *chip)
  21.225 +{
  21.226 +	outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
  21.227 +}
  21.228 +
  21.229 +static struct file_operations nsc_ops = {
  21.230 +	.owner = THIS_MODULE,
  21.231 +	.llseek = no_llseek,
  21.232 +	.open = tpm_open,
  21.233 +	.read = tpm_read,
  21.234 +	.write = tpm_write,
  21.235 +	.release = tpm_release,
  21.236 +};
  21.237 +
  21.238 +static struct tpm_vendor_specific tpm_nsc = {
  21.239 +	.recv = tpm_nsc_recv,
  21.240 +	.send = tpm_nsc_send,
  21.241 +	.cancel = tpm_nsc_cancel,
  21.242 +	.req_complete_mask = NSC_STATUS_OBF,
  21.243 +	.req_complete_val = NSC_STATUS_OBF,
  21.244 +	.miscdev = { .fops = &nsc_ops, },
  21.245 +
  21.246 +};
  21.247 +
  21.248 +static int __devinit tpm_nsc_init(struct pci_dev *pci_dev,
  21.249 +				  const struct pci_device_id *pci_id)
  21.250 +{
  21.251 +	int rc = 0;
  21.252 +	int lo, hi;
  21.253 +
  21.254 +	hi = tpm_read_index(TPM_NSC_BASE0_HI);
  21.255 +	lo = tpm_read_index(TPM_NSC_BASE0_LO);
  21.256 +
  21.257 +	tpm_nsc.base = (hi<<8) | lo;
  21.258 +
  21.259 +	if (pci_enable_device(pci_dev))
  21.260 +		return -EIO;
  21.261 +
  21.262 +	/* verify that it is a National part (SID) */
  21.263 +	if (tpm_read_index(NSC_SID_INDEX) != 0xEF) {
  21.264 +		rc = -ENODEV;
  21.265 +		goto out_err;
  21.266 +	}
  21.267 +
  21.268 +	dev_dbg(&pci_dev->dev, "NSC TPM detected\n");
  21.269 +	dev_dbg(&pci_dev->dev,
  21.270 +		"NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n",
  21.271 +		tpm_read_index(0x07), tpm_read_index(0x20),
  21.272 +		tpm_read_index(0x27));
  21.273 +	dev_dbg(&pci_dev->dev,
  21.274 +		"NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n",
  21.275 +		tpm_read_index(0x21), tpm_read_index(0x25),
  21.276 +		tpm_read_index(0x26), tpm_read_index(0x28));
  21.277 +	dev_dbg(&pci_dev->dev, "NSC IO Base0 0x%x\n",
  21.278 +		(tpm_read_index(0x60) << 8) | tpm_read_index(0x61));
  21.279 +	dev_dbg(&pci_dev->dev, "NSC IO Base1 0x%x\n",
  21.280 +		(tpm_read_index(0x62) << 8) | tpm_read_index(0x63));
  21.281 +	dev_dbg(&pci_dev->dev, "NSC Interrupt number and wakeup 0x%x\n",
  21.282 +		tpm_read_index(0x70));
  21.283 +	dev_dbg(&pci_dev->dev, "NSC IRQ type select 0x%x\n",
  21.284 +		tpm_read_index(0x71));
  21.285 +	dev_dbg(&pci_dev->dev,
  21.286 +		"NSC DMA channel select0 0x%x, select1 0x%x\n",
  21.287 +		tpm_read_index(0x74), tpm_read_index(0x75));
  21.288 +	dev_dbg(&pci_dev->dev,
  21.289 +		"NSC Config "
  21.290 +		"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
  21.291 +		tpm_read_index(0xF0), tpm_read_index(0xF1),
  21.292 +		tpm_read_index(0xF2), tpm_read_index(0xF3),
  21.293 +		tpm_read_index(0xF4), tpm_read_index(0xF5),
  21.294 +		tpm_read_index(0xF6), tpm_read_index(0xF7),
  21.295 +		tpm_read_index(0xF8), tpm_read_index(0xF9));
  21.296 +
  21.297 +	dev_info(&pci_dev->dev,
  21.298 +		 "NSC PC21100 TPM revision %d\n",
  21.299 +		 tpm_read_index(0x27) & 0x1F);
  21.300 +
  21.301 +	if (tpm_read_index(NSC_LDC_INDEX) == 0)
  21.302 +		dev_info(&pci_dev->dev, ": NSC TPM not active\n");
  21.303 +
  21.304 +	/* select PM channel 1 */
  21.305 +	tpm_write_index(NSC_LDN_INDEX, 0x12);
  21.306 +	tpm_read_index(NSC_LDN_INDEX);
  21.307 +
  21.308 +	/* disable the DPM module */
  21.309 +	tpm_write_index(NSC_LDC_INDEX, 0);
  21.310 +	tpm_read_index(NSC_LDC_INDEX);
  21.311 +
  21.312 +	/* set the data register base addresses */
  21.313 +	tpm_write_index(NSC_DIO_INDEX, TPM_NSC_BASE >> 8);
  21.314 +	tpm_write_index(NSC_DIO_INDEX + 1, TPM_NSC_BASE);
  21.315 +	tpm_read_index(NSC_DIO_INDEX);
  21.316 +	tpm_read_index(NSC_DIO_INDEX + 1);
  21.317 +
  21.318 +	/* set the command register base addresses */
  21.319 +	tpm_write_index(NSC_CIO_INDEX, (TPM_NSC_BASE + 1) >> 8);
  21.320 +	tpm_write_index(NSC_CIO_INDEX + 1, (TPM_NSC_BASE + 1));
  21.321 +	tpm_read_index(NSC_DIO_INDEX);
  21.322 +	tpm_read_index(NSC_DIO_INDEX + 1);
  21.323 +
  21.324 +	/* set the interrupt number to be used for the host interface */
  21.325 +	tpm_write_index(NSC_IRQ_INDEX, TPM_NSC_IRQ);
  21.326 +	tpm_write_index(NSC_ITS_INDEX, 0x00);
  21.327 +	tpm_read_index(NSC_IRQ_INDEX);
  21.328 +
  21.329 +	/* enable the DPM module */
  21.330 +	tpm_write_index(NSC_LDC_INDEX, 0x01);
  21.331 +	tpm_read_index(NSC_LDC_INDEX);
  21.332 +
  21.333 +	if ((rc = tpm_register_hardware(pci_dev, &tpm_nsc)) < 0)
  21.334 +		goto out_err;
  21.335 +
  21.336 +	return 0;
  21.337 +
  21.338 +out_err:
  21.339 +	pci_disable_device(pci_dev);
  21.340 +	return rc;
  21.341 +}
  21.342 +
  21.343 +static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
  21.344 +	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
  21.345 +	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
  21.346 +	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
  21.347 +	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
  21.348 +	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
  21.349 +	{PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
  21.350 +	{0,}
  21.351 +};
  21.352 +
  21.353 +MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
  21.354 +
  21.355 +static struct pci_driver nsc_pci_driver = {
  21.356 +	.name = "tpm_nsc",
  21.357 +	.id_table = tpm_pci_tbl,
  21.358 +	.probe = tpm_nsc_init,
  21.359 +	.remove = __devexit_p(tpm_remove),
  21.360 +	.suspend = tpm_pm_suspend,
  21.361 +	.resume = tpm_pm_resume,
  21.362 +};
  21.363 +
  21.364 +static int __init init_nsc(void)
  21.365 +{
  21.366 +	return pci_register_driver(&nsc_pci_driver);
  21.367 +}
  21.368 +
  21.369 +static void __exit cleanup_nsc(void)
  21.370 +{
  21.371 +	pci_unregister_driver(&nsc_pci_driver);
  21.372 +}
  21.373 +
  21.374 +module_init(init_nsc);
  21.375 +module_exit(cleanup_nsc);
  21.376 +
  21.377 +MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
  21.378 +MODULE_DESCRIPTION("TPM Driver");
  21.379 +MODULE_VERSION("2.0");
  21.380 +MODULE_LICENSE("GPL");
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c	Thu Sep 01 10:16:14 2005 +0000
    22.3 @@ -0,0 +1,513 @@
    22.4 +/*
    22.5 + * Copyright (C) 2004 IBM Corporation
    22.6 + *
    22.7 + * Authors:
    22.8 + * Leendert van Doorn <leendert@watson.ibm.com>
    22.9 + * Dave Safford <safford@watson.ibm.com>
   22.10 + * Reiner Sailer <sailer@watson.ibm.com>
   22.11 + * Kylene Hall <kjhall@us.ibm.com>
   22.12 + * Stefan Berger <stefanb@us.ibm.com>
   22.13 + *
   22.14 + * Maintained by: <tpmdd_devel@lists.sourceforge.net>
   22.15 + *
   22.16 + * Device driver for TCG/TCPA TPM (trusted platform module) for XEN.
   22.17 + * Specifications at www.trustedcomputinggroup.org
   22.18 + *
   22.19 + * This program is free software; you can redistribute it and/or
   22.20 + * modify it under the terms of the GNU General Public License as
   22.21 + * published by the Free Software Foundation, version 2 of the
   22.22 + * License.
   22.23 + *
   22.24 + */
   22.25 +
   22.26 +#include <asm/uaccess.h>
   22.27 +#include <linux/list.h>
   22.28 +#include <linux/tpmfe.h>
   22.29 +#include <linux/device.h>
   22.30 +#include <linux/interrupt.h>
   22.31 +#include "tpm_nopci.h"
   22.32 +
   22.33 +/* read status bits */
   22.34 +enum {
   22.35 +	STATUS_BUSY = 0x01,
   22.36 +	STATUS_DATA_AVAIL = 0x02,
   22.37 +	STATUS_READY = 0x04
   22.38 +};
   22.39 +
   22.40 +#define MIN(x,y)  ((x) < (y)) ? (x) : (y)
   22.41 +
   22.42 +struct transmission {
   22.43 +	struct list_head next;
   22.44 +	unsigned char *request;
   22.45 +	unsigned int request_len;
   22.46 +	unsigned char *rcv_buffer;
   22.47 +	unsigned int  buffersize;
   22.48 +	struct tpm_chip     *chip;
   22.49 +	unsigned int flags;
   22.50 +};
   22.51 +
   22.52 +enum {
   22.53 +	TRANSMISSION_FLAG_WAS_QUEUED = 0x1
   22.54 +};
   22.55 +
   22.56 +struct data_exchange {
   22.57 +	struct transmission *current_request;
   22.58 +	spinlock_t           req_list_lock;
   22.59 +	wait_queue_head_t    req_wait_queue;
   22.60 +
   22.61 +	struct list_head     queued_requests;
   22.62 +
   22.63 +	struct transmission *current_response;
   22.64 +	spinlock_t           resp_list_lock;
   22.65 +	wait_queue_head_t    resp_wait_queue;     // processes waiting for responses
   22.66 +
   22.67 +	struct transmission *req_cancelled;       // if a cancellation was encounterd
   22.68 +
   22.69 +	unsigned int         fe_status;
   22.70 +	unsigned int         flags;
   22.71 +};
   22.72 +
   22.73 +enum {
   22.74 +	DATAEX_FLAG_QUEUED_ONLY = 0x1
   22.75 +};
   22.76 +
   22.77 +static struct data_exchange dataex;
   22.78 +
   22.79 +static unsigned long disconnect_time;
   22.80 +
   22.81 +/* local function prototypes */
   22.82 +static void __exit cleanup_xen(void);
   22.83 +
   22.84 +
   22.85 +/* =============================================================
   22.86 + * Some utility functions
   22.87 + * =============================================================
   22.88 + */
   22.89 +static inline struct transmission *
   22.90 +transmission_alloc(void)
   22.91 +{
   22.92 +	struct transmission *t = kmalloc(sizeof(*t), GFP_KERNEL);
   22.93 +	if (t) {
   22.94 +		memset(t, 0x0, sizeof(*t));
   22.95 +	}
   22.96 +	return t;
   22.97 +}
   22.98 +
   22.99 +static inline unsigned char *
  22.100 +transmission_set_buffer(struct transmission *t,
  22.101 +                        unsigned char *buffer, unsigned int len)
  22.102 +{
  22.103 +	if (NULL != t->request) {
  22.104 +		kfree(t->request);
  22.105 +	}
  22.106 +	t->request = kmalloc(len, GFP_KERNEL);
  22.107 +	if (t->request) {
  22.108 +		memcpy(t->request,
  22.109 +		       buffer,
  22.110 +		       len);
  22.111 +		t->request_len = len;
  22.112 +	}
  22.113 +	return t->request;
  22.114 +}
  22.115 +
  22.116 +static inline void
  22.117 +transmission_free(struct transmission *t)
  22.118 +{
  22.119 +	if (t->request) {
  22.120 +		kfree(t->request);
  22.121 +	}
  22.122 +	if (t->rcv_buffer) {
  22.123 +		kfree(t->rcv_buffer);
  22.124 +	}
  22.125 +	kfree(t);
  22.126 +}
  22.127 +
  22.128 +/* =============================================================
  22.129 + * Interface with the TPM shared memory driver for XEN
  22.130 + * =============================================================
  22.131 + */
  22.132 +static int tpm_recv(const u8 *buffer, size_t count, const void *ptr)
  22.133 +{
  22.134 +	int ret_size = 0;
  22.135 +	struct transmission *t, *temp;
  22.136 +
  22.137 +	/*
  22.138 +	 * The list with requests must contain one request
  22.139 +	 * only and the element there must be the one that
  22.140 +	 * was passed to me from the front-end.
  22.141 +	 */
  22.142 +	if (dataex.current_request != ptr) {
  22.143 +		printk("WARNING: The request pointer is different than the pointer "
  22.144 +		       "the shared memory driver returned to me. %p != %p\n",
  22.145 +		       dataex.current_request, ptr);
  22.146 +	}
  22.147 +
  22.148 +	/*
  22.149 +	 * If the request has been cancelled, just quit here
  22.150 +	 */
  22.151 +	if (dataex.req_cancelled == (struct transmission *)ptr) {
  22.152 +		if (dataex.current_request == dataex.req_cancelled) {
  22.153 +			dataex.current_request = NULL;
  22.154 +		}
  22.155 +		transmission_free(dataex.req_cancelled);
  22.156 +		dataex.req_cancelled = NULL;
  22.157 +		return 0;
  22.158 +	}
  22.159 +
  22.160 +	if (NULL != (temp = dataex.current_request)) {
  22.161 +		transmission_free(temp);
  22.162 +		dataex.current_request = NULL;
  22.163 +	}
  22.164 +
  22.165 +	t = transmission_alloc();
  22.166 +	if (NULL != t) {
  22.167 +		unsigned long flags;
  22.168 +		t->rcv_buffer = kmalloc(count, GFP_KERNEL);
  22.169 +		if (NULL == t->rcv_buffer) {
  22.170 +			transmission_free(t);
  22.171 +			return -ENOMEM;
  22.172 +		}
  22.173 +		t->buffersize = count;
  22.174 +		memcpy(t->rcv_buffer, buffer, count);
  22.175 +		ret_size = count;
  22.176 +
  22.177 +		spin_lock_irqsave(&dataex.resp_list_lock ,flags);
  22.178 +		dataex.current_response = t;
  22.179 +		spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
  22.180 +		wake_up_interruptible(&dataex.resp_wait_queue);
  22.181 +	}
  22.182 +	return ret_size;
  22.183 +}
  22.184 +
  22.185 +
  22.186 +static void tpm_fe_status(unsigned int flags)
  22.187 +{
  22.188 +	dataex.fe_status = flags;
  22.189 +	if ((dataex.fe_status & TPMFE_STATUS_CONNECTED) == 0) {
  22.190 +		disconnect_time = jiffies;
  22.191 +	}
  22.192 +}
  22.193 +
  22.194 +/* =============================================================
  22.195 + * Interface with the generic TPM driver
  22.196 + * =============================================================
  22.197 + */
  22.198 +static int tpm_xen_recv(struct tpm_chip *chip, u8 * buf, size_t count)
  22.199 +{
  22.200 +	unsigned long flags;
  22.201 +	int rc = 0;
  22.202 +
  22.203 +	spin_lock_irqsave(&dataex.resp_list_lock, flags);
  22.204 +	/*
  22.205 +	 * Check if the previous operation only queued the command
  22.206 +	 * In this case there won't be a response, so I just
  22.207 +	 * return from here and reset that flag. In any other
  22.208 +	 * case I should receive a response from the back-end.
  22.209 +	 */
  22.210 +	if ((dataex.flags & DATAEX_FLAG_QUEUED_ONLY) != 0) {
  22.211 +		dataex.flags &= ~DATAEX_FLAG_QUEUED_ONLY;
  22.212 +		spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
  22.213 +		/*
  22.214 +		 * a little hack here. The first few measurements
  22.215 +		 * are queued since there's no way to talk to the
  22.216 +		 * TPM yet (due to slowness of the control channel)
  22.217 +		 * So we just make IMA happy by giving it 30 NULL
  22.218 +		 * bytes back where the most important part is
  22.219 +		 * that the result code is '0'.
  22.220 +		 */
  22.221 +
  22.222 +		count = MIN(count, 30);
  22.223 +		memset(buf, 0x0, count);
  22.224 +		return count;
  22.225 +	}
  22.226 +	/*
  22.227 +	 * Check whether something is in the responselist and if
  22.228 +	 * there's nothing in the list wait for something to appear.
  22.229 +	 */
  22.230 +
  22.231 +	if (NULL == dataex.current_response) {
  22.232 +		spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
  22.233 +		interruptible_sleep_on_timeout(&dataex.resp_wait_queue,
  22.234 +		                               1000);
  22.235 +		spin_lock_irqsave(&dataex.resp_list_lock ,flags);
  22.236 +	}
  22.237 +
  22.238 +	if (NULL != dataex.current_response) {
  22.239 +		struct transmission *t = dataex.current_response;
  22.240 +		dataex.current_response = NULL;
  22.241 +		rc = MIN(count, t->buffersize);
  22.242 +		memcpy(buf, t->rcv_buffer, rc);
  22.243 +		transmission_free(t);
  22.244 +	}
  22.245 +
  22.246 +	spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
  22.247 +	return rc;
  22.248 +}
  22.249 +
  22.250 +static int tpm_xen_send(struct tpm_chip *chip, u8 * buf, size_t count)
  22.251 +{
  22.252 +	/*
  22.253 +	 * We simply pass the packet onto the XEN shared
  22.254 +	 * memory driver.
  22.255 +	 */
  22.256 +	unsigned long flags;
  22.257 +	int rc;
  22.258 +	struct transmission *t = transmission_alloc();
  22.259 +
  22.260 +	spin_lock_irqsave(&dataex.req_list_lock, flags);
  22.261 +	/*
  22.262 +	 * If there's a current request, it must be the
  22.263 +	 * previous request that has timed out.
  22.264 +	 */
  22.265 +	if (dataex.current_request != NULL) {
  22.266 +		printk("WARNING: Sending although there is a request outstanding.\n"
  22.267 +		       "         Previous request must have timed out.\n");
  22.268 +		transmission_free(dataex.current_request);
  22.269 +		dataex.current_request = NULL;
  22.270 +	}
  22.271 +
  22.272 +	if (t != NULL) {
  22.273 +		unsigned int error = 0;
  22.274 +		t->rcv_buffer = NULL;
  22.275 +		t->buffersize = 0;
  22.276 +		t->chip = chip;
  22.277 +
  22.278 +		/*
  22.279 +		 * Queue the packet if the driver below is not
  22.280 +		 * ready, yet, or there is any packet already
  22.281 +		 * in the queue.
  22.282 +		 * If the driver below is ready, unqueue all
  22.283 +		 * packets first before sending our current
  22.284 +		 * packet.
  22.285 +		 * For each unqueued packet, except for the
  22.286 +		 * last (=current) packet, call the function
  22.287 +		 * tpm_xen_recv to wait for the response to come
  22.288 +		 * back.
  22.289 +		 */
  22.290 +		if ((dataex.fe_status & TPMFE_STATUS_CONNECTED) == 0) {
  22.291 +			if (time_after(jiffies, disconnect_time + HZ * 10)) {
  22.292 +				rc = -ENOENT;
  22.293 +			} else {
  22.294 +				/*
  22.295 +				 * copy the request into the buffer
  22.296 +				 */
  22.297 +				if (transmission_set_buffer(t, buf, count)
  22.298 +				    == NULL) {
  22.299 +					transmission_free(t);
  22.300 +					rc = -ENOMEM;
  22.301 +					goto exit;
  22.302 +				}
  22.303 +				dataex.flags |= DATAEX_FLAG_QUEUED_ONLY;
  22.304 +				list_add_tail(&t->next, &dataex.queued_requests);
  22.305 +				rc = 0;
  22.306 +			}
  22.307 +		} else {
  22.308 +			/*
  22.309 +			 * Check whether there are any packets in the queue
  22.310 +			 */
  22.311 +			while (!list_empty(&dataex.queued_requests)) {
  22.312 +				/*
  22.313 +				 * Need to dequeue them.
  22.314 +				 * Read the result into a dummy buffer.
  22.315 +				 */
  22.316 +				unsigned char buffer[1];
  22.317 +				struct transmission *qt = (struct transmission *) dataex.queued_requests.next;
  22.318 +				list_del(&qt->next);
  22.319 +				dataex.current_request = qt;
  22.320 +				spin_unlock_irqrestore(&dataex.req_list_lock, flags);
  22.321 +
  22.322 +				rc = tpm_fe_send(qt->request,
  22.323 +				                 qt->request_len,
  22.324 +				                 qt);
  22.325 +
  22.326 +				if (rc < 0) {
  22.327 +					spin_lock_irqsave(&dataex.req_list_lock, flags);
  22.328 +					if ((qt = dataex.current_request) != NULL) {
  22.329 +						/*
  22.330 +						 * requeue it at the beginning
  22.331 +						 * of the list
  22.332 +						 */
  22.333 +						list_add(&qt->next,
  22.334 +						         &dataex.queued_requests);
  22.335 +					}
  22.336 +					dataex.current_request = NULL;
  22.337 +					error = 1;
  22.338 +					break;
  22.339 +				}
  22.340 +				/*
  22.341 +				 * After this point qt is not valid anymore!
  22.342 +				 * It is freed when the front-end is delivering the data
  22.343 +				 * by calling tpm_recv
  22.344 +				 */
  22.345 +
  22.346 +				/*
  22.347 +				 * Try to receive the response now into the provided dummy
  22.348 +				 * buffer (I don't really care about this response since
  22.349 +				 * there is no receiver anymore for this response)
  22.350 +				 */
  22.351 +				rc = tpm_xen_recv(chip, buffer, sizeof(buffer));
  22.352 +
  22.353 +				spin_lock_irqsave(&dataex.req_list_lock, flags);
  22.354 +			}
  22.355 +
  22.356 +			if (error == 0) {
  22.357 +				/*
  22.358 +				 * Finally, send the current request.
  22.359 +				 */
  22.360 +				dataex.current_request = t;
  22.361 +				/*
  22.362 +				 * Call the shared memory driver
  22.363 +				 * Pass to it the buffer with the request, the
  22.364 +				 * amount of bytes in the request and
  22.365 +				 * a void * pointer (here: transmission structure)
  22.366 +				 */
  22.367 +				rc = tpm_fe_send(buf, count, t);
  22.368 +				/*
  22.369 +				 * The generic TPM driver will call
  22.370 +				 * the function to receive the response.
  22.371 +				 */
  22.372 +				if (rc < 0) {
  22.373 +					dataex.current_request = NULL;
  22.374 +					goto queue_it;
  22.375 +				}
  22.376 +			} else {
  22.377 +queue_it:
  22.378 +				if (transmission_set_buffer(t, buf, count) == NULL) {
  22.379 +					transmission_free(t);
  22.380 +					rc = -ENOMEM;
  22.381 +					goto exit;
  22.382 +				}
  22.383 +				/*
  22.384 +				 * An error occurred. Don't event try
  22.385 +				 * to send the current request. Just
  22.386 +				 * queue it.
  22.387 +				 */
  22.388 +				dataex.flags |= DATAEX_FLAG_QUEUED_ONLY;
  22.389 +				list_add_tail(&t->next, &dataex.queued_requests);
  22.390 +				rc = 0;
  22.391 +			}
  22.392 +		}
  22.393 +	} else {
  22.394 +		rc = -ENOMEM;
  22.395 +	}
  22.396 +
  22.397 +exit:
  22.398 +	spin_unlock_irqrestore(&dataex.req_list_lock, flags);
  22.399 +	return rc;
  22.400 +}
  22.401 +
  22.402 +static void tpm_xen_cancel(struct tpm_chip *chip)
  22.403 +{
  22.404 +	unsigned long flags;
  22.405 +	spin_lock_irqsave(&dataex.resp_list_lock,flags);
  22.406 +
  22.407 +	dataex.req_cancelled = dataex.current_request;
  22.408 +
  22.409 +	spin_unlock_irqrestore(&dataex.resp_list_lock,flags);
  22.410 +}
  22.411 +
  22.412 +static u8 tpm_xen_status(struct tpm_chip *chip)
  22.413 +{
  22.414 +	unsigned long flags;
  22.415 +	u8 rc = 0;
  22.416 +	spin_lock_irqsave(&dataex.resp_list_lock, flags);
  22.417 +	/*
  22.418 +	 * Data are available if:
  22.419 +	 *  - there's a current response
  22.420 +	 *  - the last packet was queued only (this is fake, but necessary to
  22.421 +	 *      get the generic TPM layer to call the receive function.)
  22.422 +	 */
  22.423 +	if (NULL != dataex.current_response ||
  22.424 +	    0 != (dataex.flags & DATAEX_FLAG_QUEUED_ONLY)) {
  22.425 +		rc = STATUS_DATA_AVAIL;
  22.426 +	}
  22.427 +	spin_unlock_irqrestore(&dataex.resp_list_lock, flags);
  22.428 +	return rc;
  22.429 +}
  22.430 +
  22.431 +static struct file_operations tpm_xen_ops = {
  22.432 +	.owner = THIS_MODULE,
  22.433 +	.llseek = no_llseek,
  22.434 +	.open = tpm_open,
  22.435 +	.read = tpm_read,
  22.436 +	.write = tpm_write,
  22.437 +	.release = tpm_release,
  22.438 +};
  22.439 +
  22.440 +static struct tpm_vendor_specific tpm_xen = {
  22.441 +	.recv = tpm_xen_recv,
  22.442 +	.send = tpm_xen_send,
  22.443 +	.cancel = tpm_xen_cancel,
  22.444 +	.status = tpm_xen_status,
  22.445 +	.req_complete_mask = STATUS_BUSY | STATUS_DATA_AVAIL,
  22.446 +	.req_complete_val  = STATUS_DATA_AVAIL,
  22.447 +	.req_canceled = STATUS_READY,
  22.448 +	.base = 0,
  22.449 +	.attr = TPM_DEVICE_ATTRS,
  22.450 +	.miscdev.fops = &tpm_xen_ops,
  22.451 +};
  22.452 +
  22.453 +static struct device tpm_device = {
  22.454 +	.bus_id = "vtpm",
  22.455 +};
  22.456 +
  22.457 +static struct tpmfe_device tpmfe = {
  22.458 +	.receive = tpm_recv,
  22.459 +	.status  = tpm_fe_status,
  22.460 +};
  22.461 +
  22.462 +
  22.463 +static int __init init_xen(void)
  22.464 +{
  22.465 +	int rc;
  22.466 +
  22.467 +	/*
  22.468 +	 * Register device with the low lever front-end
  22.469 +	 * driver
  22.470 +	 */
  22.471 +	if ((rc = tpm_fe_register_receiver(&tpmfe)) < 0) {
  22.472 +		return rc;
  22.473 +	}
  22.474 +
  22.475 +	/*
  22.476 +	 * Register our device with the system.
  22.477 +	 */
  22.478 +	if ((rc = device_register(&tpm_device)) < 0) {
  22.479 +		tpm_fe_unregister_receiver();
  22.480 +		return rc;
  22.481 +	}
  22.482 +
  22.483 +	if ((rc = tpm_register_hardware_nopci(&tpm_device, &tpm_xen)) < 0) {
  22.484 +		device_unregister(&tpm_device);
  22.485 +		tpm_fe_unregister_receiver();
  22.486 +		return rc;
  22.487 +	}
  22.488 +
  22.489 +	dataex.current_request = NULL;
  22.490 +	spin_lock_init(&dataex.req_list_lock);
  22.491 +	init_waitqueue_head(&dataex.req_wait_queue);
  22.492 +	INIT_LIST_HEAD(&dataex.queued_requests);
  22.493 +
  22.494 +	dataex.current_response = NULL;
  22.495 +	spin_lock_init(&dataex.resp_list_lock);
  22.496 +	init_waitqueue_head(&dataex.resp_wait_queue);
  22.497 +
  22.498 +	disconnect_time = jiffies;
  22.499 +
  22.500 +	return 0;
  22.501 +}
  22.502 +
  22.503 +static void __exit cleanup_xen(void)
  22.504 +{
  22.505 +	tpm_remove_hardware(&tpm_device);
  22.506 +	device_unregister(&tpm_device);
  22.507 +	tpm_fe_unregister_receiver();
  22.508 +}
  22.509 +
  22.510 +fs_initcall(init_xen);
  22.511 +module_exit(cleanup_xen);
  22.512 +
  22.513 +MODULE_AUTHOR("Stefan Berger (stefanb@us.ibm.com)");
  22.514 +MODULE_DESCRIPTION("TPM Driver for XEN (shared memory)");
  22.515 +MODULE_VERSION("1.0");
  22.516 +MODULE_LICENSE("GPL");
    23.1 --- a/linux-2.6-xen-sparse/drivers/xen/Makefile	Thu Sep 01 10:08:53 2005 +0000
    23.2 +++ b/linux-2.6-xen-sparse/drivers/xen/Makefile	Thu Sep 01 10:16:14 2005 +0000
    23.3 @@ -8,7 +8,9 @@ obj-y	+= xenbus/
    23.4  
    23.5  obj-$(CONFIG_XEN_BLKDEV_BACKEND)	+= blkback/
    23.6  obj-$(CONFIG_XEN_NETDEV_BACKEND)	+= netback/
    23.7 +obj-$(CONFIG_XEN_TPMDEV_BACKEND)	+= tpmback/
    23.8  obj-$(CONFIG_XEN_BLKDEV_FRONTEND)	+= blkfront/
    23.9  obj-$(CONFIG_XEN_NETDEV_FRONTEND)	+= netfront/
   23.10  obj-$(CONFIG_XEN_BLKDEV_TAP)    	+= blktap/
   23.11 +obj-$(CONFIG_XEN_TPMDEV_FRONTEND)	+= tpmfront/
   23.12  
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/Makefile	Thu Sep 01 10:16:14 2005 +0000
    24.3 @@ -0,0 +1,4 @@
    24.4 +
    24.5 +obj-$(CONFIG_XEN_TPMDEV_BACKEND)	+= tpmbk.o
    24.6 +
    24.7 +tpmbk-y += tpmback.o interface.o xenbus.o
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h	Thu Sep 01 10:16:14 2005 +0000
    25.3 @@ -0,0 +1,89 @@
    25.4 +/******************************************************************************
    25.5 + * drivers/xen/tpmback/common.h
    25.6 + */
    25.7 +
    25.8 +#ifndef __NETIF__BACKEND__COMMON_H__
    25.9 +#define __NETIF__BACKEND__COMMON_H__
   25.10 +
   25.11 +#include <linux/config.h>
   25.12 +#include <linux/version.h>
   25.13 +#include <linux/module.h>
   25.14 +#include <linux/interrupt.h>
   25.15 +#include <linux/slab.h>
   25.16 +#include <asm-xen/ctrl_if.h>
   25.17 +#include <asm-xen/evtchn.h>
   25.18 +#include <asm-xen/xen-public/io/tpmif.h>
   25.19 +#include <asm/io.h>
   25.20 +#include <asm/pgalloc.h>
   25.21 +#include <asm-xen/xen-public/io/domain_controller.h>
   25.22 +
   25.23 +#if 0
   25.24 +#define ASSERT(_p) \
   25.25 +    if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
   25.26 +    __LINE__, __FILE__); *(int*)0=0; }
   25.27 +#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
   25.28 +                           __FILE__ , __LINE__ , ## _a )
   25.29 +#else
   25.30 +#define ASSERT(_p) ((void)0)
   25.31 +#define DPRINTK(_f, _a...) ((void)0)
   25.32 +#endif
   25.33 +
   25.34 +typedef struct tpmif_st {
   25.35 +        struct list_head tpmif_list;
   25.36 +	/* Unique identifier for this interface. */
   25.37 +	domid_t domid;
   25.38 +	unsigned int handle;
   25.39 +
   25.40 +	/* Physical parameters of the comms window. */
   25.41 +	unsigned long tx_shmem_frame;
   25.42 +	unsigned int evtchn;
   25.43 +	unsigned int remote_evtchn;
   25.44 +
   25.45 +	/* The shared rings and indexes. */
   25.46 +	tpmif_tx_interface_t *tx;
   25.47 +
   25.48 +	/* Miscellaneous private stuff. */
   25.49 +	enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
   25.50 +	int active;
   25.51 +
   25.52 +	struct tpmif_st *hash_next;
   25.53 +	struct list_head list;	/* scheduling list */
   25.54 +	atomic_t refcnt;
   25.55 +
   25.56 +	long int tpm_instance;
   25.57 +	unsigned long mmap_vstart;
   25.58 +
   25.59 +	struct work_struct work;
   25.60 +
   25.61 +	u16 shmem_handle;
   25.62 +	unsigned long shmem_vaddr;
   25.63 +	grant_ref_t shmem_ref;
   25.64 +
   25.65 +} tpmif_t;
   25.66 +
   25.67 +void tpmif_disconnect_complete(tpmif_t * tpmif);
   25.68 +tpmif_t *tpmif_find(domid_t domid, long int instance);
   25.69 +void tpmif_interface_init(void);
   25.70 +void tpmif_schedule_work(tpmif_t * tpmif);
   25.71 +void tpmif_deschedule_work(tpmif_t * tpmif);
   25.72 +void tpmif_xenbus_init(void);
   25.73 +int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn);
   25.74 +irqreturn_t tpmif_be_int(int irq, void *dev_id, struct pt_regs *regs);
   25.75 +int tpmif_vtpm_open(tpmif_t *tpmif, domid_t domain, u32 instance);
   25.76 +int tpmif_vtpm_close(u32 instance);
   25.77 +
   25.78 +int vtpm_release_packets(tpmif_t * tpmif, int send_msgs);
   25.79 +
   25.80 +#define tpmif_get(_b) (atomic_inc(&(_b)->refcnt))
   25.81 +#define tpmif_put(_b)                             \
   25.82 +    do {                                          \
   25.83 +        if ( atomic_dec_and_test(&(_b)->refcnt) ) \
   25.84 +            tpmif_disconnect_complete(_b);        \
   25.85 +    } while (0)
   25.86 +
   25.87 +
   25.88 +extern int num_frontends;
   25.89 +
   25.90 +#define MMAP_VADDR(t,_req) ((t)->mmap_vstart + ((_req) * PAGE_SIZE))
   25.91 +
   25.92 +#endif /* __TPMIF__BACKEND__COMMON_H__ */
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c	Thu Sep 01 10:16:14 2005 +0000
    26.3 @@ -0,0 +1,200 @@
    26.4 +/******************************************************************************
    26.5 + * drivers/xen/tpmback/interface.c
    26.6 + *
    26.7 + * Vritual TPM interface management.
    26.8 + *
    26.9 + * Copyright (c) 2005, IBM Corporation
   26.10 + *
   26.11 + * Author: Stefan Berger, stefanb@us.ibm.com
   26.12 + *
   26.13 + * This code has been derived from drivers/xen/netback/interface.c
   26.14 + * Copyright (c) 2004, Keir Fraser
   26.15 + */
   26.16 +
   26.17 +#include "common.h"
   26.18 +#include <asm-xen/balloon.h>
   26.19 +
   26.20 +#define VMALLOC_VMADDR(x) ((unsigned long)(x))
   26.21 +
   26.22 +#define TPMIF_HASHSZ (2 << 5)
   26.23 +#define TPMIF_HASH(_d,_h) (((int)(_d)^(int)(_h))&(TPMIF_HASHSZ-1))
   26.24 +
   26.25 +static kmem_cache_t *tpmif_cachep;
   26.26 +int num_frontends = 0;
   26.27 +LIST_HEAD(tpmif_list);
   26.28 +
   26.29 +
   26.30 +tpmif_t *alloc_tpmif(domid_t domid, long int instance)
   26.31 +{
   26.32 +    struct page *page;
   26.33 +    tpmif_t *tpmif;
   26.34 +
   26.35 +    tpmif = kmem_cache_alloc(tpmif_cachep, GFP_KERNEL);
   26.36 +    if (!tpmif)
   26.37 +        return ERR_PTR(-ENOMEM);
   26.38 +
   26.39 +    memset(tpmif, 0, sizeof(*tpmif));
   26.40 +    tpmif->domid        = domid;
   26.41 +    tpmif->status       = DISCONNECTED;
   26.42 +    tpmif->tpm_instance = instance;
   26.43 +    atomic_set(&tpmif->refcnt, 1);
   26.44 +
   26.45 +    page = balloon_alloc_empty_page_range(TPMIF_TX_RING_SIZE);
   26.46 +    BUG_ON(page == NULL);
   26.47 +    tpmif->mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
   26.48 +
   26.49 +    list_add(&tpmif->tpmif_list, &tpmif_list);
   26.50 +    num_frontends++;
   26.51 +
   26.52 +    return tpmif;
   26.53 +}
   26.54 +
   26.55 +
   26.56 +void free_tpmif(tpmif_t *tpmif)
   26.57 +{
   26.58 +    num_frontends--;
   26.59 +    list_del(&tpmif->tpmif_list);
   26.60 +    kmem_cache_free(tpmif_cachep, tpmif);
   26.61 +}
   26.62 +
   26.63 +
   26.64 +tpmif_t *tpmif_find(domid_t domid, long int instance)
   26.65 +{
   26.66 +    tpmif_t *tpmif;
   26.67 +
   26.68 +    list_for_each_entry(tpmif, &tpmif_list, tpmif_list) {
   26.69 +        if (tpmif->tpm_instance == instance) {
   26.70 +            if (tpmif->domid == domid) {
   26.71 +                tpmif_get(tpmif);
   26.72 +                return tpmif;
   26.73 +	    } else {
   26.74 +	        return NULL;
   26.75 +	    }
   26.76 +        }
   26.77 +    }
   26.78 +
   26.79 +    return alloc_tpmif(domid, instance);
   26.80 +}
   26.81 +
   26.82 +
   26.83 +static int map_frontend_page(tpmif_t *tpmif, unsigned long localaddr,
   26.84 +			     unsigned long shared_page)
   26.85 +{
   26.86 +    struct gnttab_map_grant_ref op = {
   26.87 +        .host_addr = localaddr,
   26.88 +        .flags     = GNTMAP_host_map,
   26.89 +        .ref       = shared_page,
   26.90 +        .dom       = tpmif->domid,
   26.91 +    };
   26.92 +
   26.93 +    BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
   26.94 +
   26.95 +    if (op.handle < 0) {
   26.96 +	DPRINTK(" Grant table operation failure !\n");
   26.97 +	return op.handle;
   26.98 +    }
   26.99 +
  26.100 +    tpmif->shmem_ref    = shared_page;
  26.101 +    tpmif->shmem_handle = op.handle;
  26.102 +    tpmif->shmem_vaddr  = localaddr;
  26.103 +    return 0;
  26.104 +}
  26.105 +
  26.106 +
  26.107 +static void unmap_frontend_page(tpmif_t *tpmif)
  26.108 +{
  26.109 +    struct gnttab_unmap_grant_ref op;
  26.110 +
  26.111 +    op.host_addr = tpmif->shmem_vaddr;
  26.112 +    op.handle = tpmif->shmem_handle;
  26.113 +    op.dev_bus_addr = 0;
  26.114 +
  26.115 +    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
  26.116 +}
  26.117 +
  26.118 +
  26.119 +int tpmif_map(tpmif_t *tpmif,
  26.120 +              unsigned long shared_page, unsigned int evtchn)
  26.121 +{
  26.122 +    struct vm_struct *vma;
  26.123 +    evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
  26.124 +    int err;
  26.125 +
  26.126 +    BUG_ON(tpmif->remote_evtchn);
  26.127 +
  26.128 +    if ( (vma = get_vm_area(PAGE_SIZE, VM_IOREMAP)) == NULL )
  26.129 +	return -ENOMEM;
  26.130 +
  26.131 +    err = map_frontend_page(tpmif,
  26.132 +                            VMALLOC_VMADDR(vma->addr),
  26.133 +                            shared_page);
  26.134 +    if (err) {
  26.135 +        vfree(vma->addr);
  26.136 +	return err;
  26.137 +    }
  26.138 +
  26.139 +    op.u.bind_interdomain.dom1 = DOMID_SELF;
  26.140 +    op.u.bind_interdomain.dom2 = tpmif->domid;
  26.141 +    op.u.bind_interdomain.port1 = 0;
  26.142 +    op.u.bind_interdomain.port2 = evtchn;
  26.143 +    err = HYPERVISOR_event_channel_op(&op);
  26.144 +    if (err) {
  26.145 +	unmap_frontend_page(tpmif);
  26.146 +	vfree(vma->addr);
  26.147 +	return err;
  26.148 +    }
  26.149 +
  26.150 +    tpmif->evtchn = op.u.bind_interdomain.port1;
  26.151 +    tpmif->remote_evtchn = evtchn;
  26.152 +
  26.153 +    tpmif->tx = (tpmif_tx_interface_t *) vma->addr;
  26.154 +
  26.155 +    bind_evtchn_to_irqhandler(tpmif->evtchn,
  26.156 +                              tpmif_be_int,
  26.157 +                              0,
  26.158 +                              "tpmif-backend",
  26.159 +			      tpmif);
  26.160 +    tpmif->status        = CONNECTED;
  26.161 +    tpmif->shmem_ref     = shared_page;
  26.162 +    tpmif->active        = 1;
  26.163 +
  26.164 +    return 0;
  26.165 +}
  26.166 +
  26.167 +
  26.168 +static void __tpmif_disconnect_complete(void *arg)
  26.169 +{
  26.170 +    evtchn_op_t op = { .cmd = EVTCHNOP_close };
  26.171 +    tpmif_t *tpmif = (tpmif_t *) arg;
  26.172 +
  26.173 +    op.u.close.port = tpmif->evtchn;
  26.174 +    op.u.close.dom  = DOMID_SELF;
  26.175 +    HYPERVISOR_event_channel_op(&op);
  26.176 +    op.u.close.port = tpmif->remote_evtchn;
  26.177 +    op.u.close.dom  = tpmif->domid;
  26.178 +    HYPERVISOR_event_channel_op(&op);
  26.179 +
  26.180 +    if (tpmif->evtchn)
  26.181 +         unbind_evtchn_from_irqhandler(tpmif->evtchn, tpmif);
  26.182 +
  26.183 +    if (tpmif->tx) {
  26.184 +        unmap_frontend_page(tpmif);
  26.185 +        vfree(tpmif->tx);
  26.186 +    }
  26.187 +
  26.188 +    free_tpmif(tpmif);
  26.189 +}
  26.190 +
  26.191 +
  26.192 +void tpmif_disconnect_complete(tpmif_t * tpmif)
  26.193 +{
  26.194 +    INIT_WORK(&tpmif->work, __tpmif_disconnect_complete, (void *)tpmif);
  26.195 +    schedule_work(&tpmif->work);
  26.196 +}
  26.197 +
  26.198 +
  26.199 +void __init tpmif_interface_init(void)
  26.200 +{
  26.201 +    tpmif_cachep = kmem_cache_create("tpmif_cache", sizeof(tpmif_t),
  26.202 +                                     0, 0, NULL, NULL);
  26.203 +}
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c	Thu Sep 01 10:16:14 2005 +0000
    27.3 @@ -0,0 +1,1078 @@
    27.4 +/******************************************************************************
    27.5 + * drivers/xen/tpmback/tpmback.c
    27.6 + *
    27.7 + * Copyright (c) 2005, IBM Corporation
    27.8 + *
    27.9 + * Author: Stefan Berger, stefanb@us.ibm.com
   27.10 + * Grant table support: Mahadevan Gomathisankaran
   27.11 + *
   27.12 + * This code has been derived from drivers/xen/netback/netback.c
   27.13 + * Copyright (c) 2002-2004, K A Fraser
   27.14 + *
   27.15 + */
   27.16 +
   27.17 +#include "common.h"
   27.18 +#include <asm-xen/evtchn.h>
   27.19 +
   27.20 +#include <linux/types.h>
   27.21 +#include <linux/list.h>
   27.22 +#include <linux/miscdevice.h>
   27.23 +#include <asm/uaccess.h>
   27.24 +#include <asm-xen/xenbus.h>
   27.25 +#include <asm-xen/xen-public/grant_table.h>
   27.26 +
   27.27 +
   27.28 +struct data_exchange {
   27.29 +	struct list_head pending_pak;
   27.30 +	struct list_head current_pak;
   27.31 +	unsigned int copied_so_far;
   27.32 +	u8 has_opener;
   27.33 +	rwlock_t pak_lock;  // protects all of the previous fields
   27.34 +	wait_queue_head_t wait_queue;
   27.35 +};
   27.36 +
   27.37 +struct packet {
   27.38 +	struct list_head next;
   27.39 +	unsigned int data_len;
   27.40 +	u8 *data_buffer;
   27.41 +	tpmif_t *tpmif;
   27.42 +	u32 tpm_instance;
   27.43 +	u8 req_tag;
   27.44 +	u32 last_read;
   27.45 +	u8 flags;
   27.46 +	ctrl_msg_t ctrl_msg;
   27.47 +	struct timer_list processing_timer;
   27.48 +};
   27.49 +
   27.50 +enum {
   27.51 +	PACKET_FLAG_DISCARD_RESPONSE = 1,
   27.52 +	PACKET_FLAG_SEND_CONTROLMESSAGE = 2,
   27.53 +};
   27.54 +
   27.55 +static struct data_exchange dataex;
   27.56 +
   27.57 +/* local function prototypes */
   27.58 +static int vtpm_queue_packet(struct packet *pak);
   27.59 +static int _packet_write(struct packet *pak,
   27.60 +                         const char *data, size_t size,
   27.61 +                         int userbuffer);
   27.62 +static void processing_timeout(unsigned long ptr);
   27.63 +static int  packet_read_shmem(struct packet *pak,
   27.64 +                              tpmif_t *tpmif,
   27.65 +                              u32 offset,
   27.66 +                              char *buffer,
   27.67 +                              int isuserbuffer,
   27.68 +                              u32 left);
   27.69 +
   27.70 +
   27.71 +#define MAX_PENDING_REQS TPMIF_TX_RING_SIZE
   27.72 +
   27.73 +static multicall_entry_t tx_mcl[MAX_PENDING_REQS];
   27.74 +
   27.75 +#define MIN(x,y)  (x) < (y) ? (x) : (y)
   27.76 +
   27.77 +/***************************************************************
   27.78 + Packet-related functions
   27.79 +***************************************************************/
   27.80 +
   27.81 +static struct packet *
   27.82 +packet_find_instance(struct list_head *head, u32 tpm_instance)
   27.83 +{
   27.84 +	struct packet *pak;
   27.85 +	struct list_head *p;
   27.86 +	/*
   27.87 +	 * traverse the list of packets and return the first
   27.88 +	 * one with the given instance number
   27.89 +	 */
   27.90 +	list_for_each(p, head) {
   27.91 +		pak = list_entry(p, struct packet, next);
   27.92 +		if (pak->tpm_instance == tpm_instance) {
   27.93 +			return pak;
   27.94 +		}
   27.95 +	}
   27.96 +	return NULL;
   27.97 +}
   27.98 +
   27.99 +static struct packet *
  27.100 +packet_find_packet(struct list_head *head, void *packet)
  27.101 +{
  27.102 +	struct packet *pak;
  27.103 +	struct list_head *p;
  27.104 +	/*
  27.105 +	 * traverse the list of packets and return the first
  27.106 +	 * one with the given instance number
  27.107 +	 */
  27.108 +	list_for_each(p, head) {
  27.109 +		pak = list_entry(p, struct packet, next);
  27.110 +		if (pak == packet) {
  27.111 +			return pak;
  27.112 +		}
  27.113 +	}
  27.114 +	return NULL;
  27.115 +}
  27.116 +
  27.117 +static struct packet *
  27.118 +packet_alloc(tpmif_t *tpmif, u32 size, u8 req_tag, u8 flags)
  27.119 +{
  27.120 +	struct packet *pak = NULL;
  27.121 +	pak = kmalloc(sizeof(struct packet),
  27.122 +                      GFP_KERNEL);
  27.123 +	if (NULL != pak) {
  27.124 +		memset(pak, 0x0, sizeof(*pak));
  27.125 +		if (tpmif) {
  27.126 +			pak->tpmif = tpmif;
  27.127 +			pak->tpm_instance = tpmif->tpm_instance;
  27.128 +		}
  27.129 +		pak->data_len  = size;
  27.130 +		pak->req_tag   = req_tag;
  27.131 +		pak->last_read = 0;
  27.132 +		pak->flags     = flags;
  27.133 +
  27.134 +		/*
  27.135 +		 * cannot do tpmif_get(tpmif); bad things happen
  27.136 +		 * on the last tpmif_put()
  27.137 +		 */
  27.138 +		init_timer(&pak->processing_timer);
  27.139 +		pak->processing_timer.function = processing_timeout;
  27.140 +		pak->processing_timer.data = (unsigned long)pak;
  27.141 +	}
  27.142 +	return pak;
  27.143 +}
  27.144 +
  27.145 +static void inline
  27.146 +packet_reset(struct packet *pak)
  27.147 +{
  27.148 +	pak->last_read = 0;
  27.149 +}
  27.150 +
  27.151 +static void inline
  27.152 +packet_free(struct packet *pak)
  27.153 +{
  27.154 +	del_singleshot_timer_sync(&pak->processing_timer);
  27.155 +	if (pak->data_buffer) {
  27.156 +		kfree(pak->data_buffer);
  27.157 +	}
  27.158 +	/*
  27.159 +	 * cannot do tpmif_put(pak->tpmif); bad things happen
  27.160 +	 * on the last tpmif_put()
  27.161 +	 */
  27.162 +	kfree(pak);
  27.163 +}
  27.164 +
  27.165 +static int
  27.166 +packet_set(struct packet *pak,
  27.167 +           const unsigned char *buffer, u32 size)
  27.168 +{
  27.169 +	int rc = 0;
  27.170 +	unsigned char *buf = kmalloc(size, GFP_KERNEL);
  27.171 +	if (NULL != buf) {
  27.172 +		pak->data_buffer = buf;
  27.173 +		memcpy(buf, buffer, size);
  27.174 +		pak->data_len = size;
  27.175 +	} else {
  27.176 +		rc = -ENOMEM;
  27.177 +	}
  27.178 +	return rc;
  27.179 +}
  27.180 +
  27.181 +
  27.182 +/*
  27.183 + * Write data to the shared memory and send it to the FE.
  27.184 + */
  27.185 +static int
  27.186 +packet_write(struct packet *pak,
  27.187 +             const char *data, size_t size,
  27.188 +             int userbuffer)
  27.189 +{
  27.190 +	int rc = 0;
  27.191 +
  27.192 +	DPRINTK("Supposed to send %d bytes to front-end!\n",
  27.193 +	        size);
  27.194 +
  27.195 +	if (0 != (pak->flags & PACKET_FLAG_SEND_CONTROLMESSAGE)) {
  27.196 +#ifdef CONFIG_XEN_TPMDEV_CLOSE_IF_VTPM_FAILS
  27.197 +		u32 res;
  27.198 +		memcpy(&res, &data[2+4], sizeof(res));
  27.199 +		if (res != 0) {
  27.200 +			/*
  27.201 +			 * Will close down this device and have the
  27.202 +			 * FE notified about closure.
  27.203 +			 */
  27.204 +		}
  27.205 +#endif
  27.206 +	}
  27.207 +
  27.208 +	if (0 != (pak->flags & PACKET_FLAG_DISCARD_RESPONSE)) {
  27.209 +		/* Don't send a respone to this packet. Just acknowledge it. */
  27.210 +		rc = size;
  27.211 +	} else {
  27.212 +		rc = _packet_write(pak, data, size, userbuffer);
  27.213 +	}
  27.214 +
  27.215 +	return rc;
  27.216 +}
  27.217 +
  27.218 +
  27.219 +static int
  27.220 +_packet_write(struct packet *pak,
  27.221 +              const char *data, size_t size,
  27.222 +              int userbuffer)
  27.223 +{
  27.224 +	/*
  27.225 +	 * Write into the shared memory pages directly
  27.226 +	 * and send it to the front end.
  27.227 +	 */
  27.228 +	tpmif_t *tpmif = pak->tpmif;
  27.229 +	u16 handle;
  27.230 +	int rc = 0;
  27.231 +	unsigned int i = 0;
  27.232 +	unsigned int offset = 0;
  27.233 +	multicall_entry_t *mcl;
  27.234 +
  27.235 +	if (tpmif == NULL)
  27.236 +		return -EFAULT;
  27.237 +
  27.238 +	if (tpmif->status != CONNECTED) {
  27.239 +		return size;
  27.240 +	}
  27.241 +
  27.242 +	mcl = tx_mcl;
  27.243 +	while (offset < size && i < TPMIF_TX_RING_SIZE) {
  27.244 +		unsigned int tocopy;
  27.245 +		struct gnttab_map_grant_ref map_op;
  27.246 +		struct gnttab_unmap_grant_ref unmap_op;
  27.247 +		tpmif_tx_request_t *tx;
  27.248 +
  27.249 +		tx = &tpmif->tx->ring[i].req;
  27.250 +
  27.251 +		if (0 == tx->addr) {
  27.252 +			DPRINTK("ERROR: Buffer for outgoing packet NULL?! i=%d\n", i);
  27.253 +			return 0;
  27.254 +		}
  27.255 +
  27.256 +		map_op.host_addr  = MMAP_VADDR(tpmif, i);
  27.257 +		map_op.flags      = GNTMAP_host_map;
  27.258 +		map_op.ref        = tx->ref;
  27.259 +		map_op.dom        = tpmif->domid;
  27.260 +
  27.261 +		if(unlikely(
  27.262 +		    HYPERVISOR_grant_table_op(
  27.263 +		        GNTTABOP_map_grant_ref,
  27.264 +		        &map_op,
  27.265 +		        1))) {
  27.266 +			BUG();
  27.267 +		}
  27.268 +
  27.269 +		handle = map_op.handle;
  27.270 +
  27.271 +		if (map_op.handle < 0) {
  27.272 +			DPRINTK(" Grant table operation failure !\n");
  27.273 +			return 0;
  27.274 +		}
  27.275 +		phys_to_machine_mapping[__pa(MMAP_VADDR(tpmif,i)) >>
  27.276 +					PAGE_SHIFT] =
  27.277 +			FOREIGN_FRAME(map_op.dev_bus_addr >> PAGE_SHIFT);
  27.278 +
  27.279 +		tocopy = size - offset;
  27.280 +		if (tocopy > PAGE_SIZE) {
  27.281 +			tocopy = PAGE_SIZE;
  27.282 +		}
  27.283 +		if (userbuffer) {
  27.284 +			if (copy_from_user((void *)(MMAP_VADDR(tpmif,i) |
  27.285 +			                           (tx->addr & ~PAGE_MASK)),
  27.286 +			                   (void __user *)&data[offset],
  27.287 +			                   tocopy)) {
  27.288 +				tpmif_put(tpmif);
  27.289 +				return -EFAULT;
  27.290 +			}
  27.291 +		} else {
  27.292 +			memcpy((void *)(MMAP_VADDR(tpmif,i) |
  27.293 +					(tx->addr & ~PAGE_MASK)),
  27.294 +			       &data[offset], tocopy);
  27.295 +		}
  27.296 +		tx->size = tocopy;
  27.297 +
  27.298 +		unmap_op.host_addr    = MMAP_VADDR(tpmif, i);
  27.299 +		unmap_op.handle       = handle;
  27.300 +		unmap_op.dev_bus_addr = 0;
  27.301 +
  27.302 +		if(unlikely(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref,
  27.303 +		                                      &unmap_op,
  27.304 +		                                      1))) {
  27.305 +			BUG();
  27.306 +		}
  27.307 +
  27.308 +		offset += tocopy;
  27.309 +		i++;
  27.310 +	}
  27.311 +
  27.312 +	rc = offset;
  27.313 +	DPRINTK("Notifying frontend via event channel %d\n",
  27.314 +	        tpmif->evtchn);
  27.315 +	notify_via_evtchn(tpmif->evtchn);
  27.316 +
  27.317 +	return rc;
  27.318 +}
  27.319 +
  27.320 +/*
  27.321 + * Read data from the shared memory and copy it directly into the
  27.322 + * provided buffer. Advance the read_last indicator which tells
  27.323 + * how many bytes have already been read.
  27.324 + */
  27.325 +static int
  27.326 +packet_read(struct packet *pak, size_t numbytes,
  27.327 +            char *buffer, size_t buffersize,
  27.328 +            int userbuffer)
  27.329 +{
  27.330 +	tpmif_t *tpmif = pak->tpmif;
  27.331 +	/*
  27.332 +	 * I am supposed to read 'numbytes' of data from the
  27.333 +	 * buffer.
  27.334 +	 * The first 4 bytes that are read are the instance number in
  27.335 +	 * network byte order, after that comes the data from the
  27.336 +	 * shared memory buffer.
  27.337 +	 */
  27.338 +	u32 to_copy;
  27.339 +	u32 offset = 0;
  27.340 +	u32 room_left = buffersize;
  27.341 +	/*
  27.342 +	 * Ensure that we see the request when we copy it.
  27.343 +	 */
  27.344 +	mb();
  27.345 +
  27.346 +	if (pak->last_read < 4) {
  27.347 +		/*
  27.348 +		 * copy the instance number into the buffer
  27.349 +		 */
  27.350 +		u32 instance_no = htonl(pak->tpm_instance);
  27.351 +		u32 last_read = pak->last_read;
  27.352 +		to_copy = MIN(4 - last_read, numbytes);
  27.353 +
  27.354 +		if (userbuffer) {
  27.355 +			if (copy_to_user(&buffer[0],
  27.356 +			                 &(((u8 *)&instance_no)[last_read]),
  27.357 +			                 to_copy)) {
  27.358 +				return -EFAULT;
  27.359 +			}
  27.360 +		} else {
  27.361 +			memcpy(&buffer[0],
  27.362 +			       &(((u8 *)&instance_no)[last_read]),
  27.363 +			       to_copy);
  27.364 +		}
  27.365 +
  27.366 +		pak->last_read += to_copy;
  27.367 +		offset += to_copy;
  27.368 +		room_left -= to_copy;
  27.369 +	}
  27.370 +
  27.371 +	/*
  27.372 +	 * If the packet has a data buffer appended, read from it...
  27.373 +	 */
  27.374 +
  27.375 +	if (room_left > 0) {
  27.376 +		if (pak->data_buffer) {
  27.377 +			u32 to_copy = MIN(pak->data_len - offset, room_left);
  27.378 +			u32 last_read = pak->last_read - 4;
  27.379 +			if (userbuffer) {
  27.380 +				if (copy_to_user(&buffer[offset],
  27.381 +				                 &pak->data_buffer[last_read],
  27.382 +				                 to_copy)) {
  27.383 +					return -EFAULT;
  27.384 +				}
  27.385 +			} else {
  27.386 +				memcpy(&buffer[offset],
  27.387 +				       &pak->data_buffer[last_read],
  27.388 +				       to_copy);
  27.389 +			}
  27.390 +			pak->last_read += to_copy;
  27.391 +			offset += to_copy;
  27.392 +		} else {
  27.393 +			offset = packet_read_shmem(pak,
  27.394 +			                           tpmif,
  27.395 +			                           offset,
  27.396 +			                           buffer,
  27.397 +			                           userbuffer,
  27.398 +			                           room_left);
  27.399 +		}
  27.400 +	}
  27.401 +	return offset;
  27.402 +}
  27.403 +
  27.404 +
  27.405 +static int
  27.406 +packet_read_shmem(struct packet *pak,
  27.407 +                  tpmif_t *tpmif,
  27.408 +                  u32 offset,
  27.409 +                  char *buffer,
  27.410 +                  int isuserbuffer,
  27.411 +                  u32 room_left) {
  27.412 +	u32 last_read = pak->last_read - 4;
  27.413 +	u32 i = (last_read / PAGE_SIZE);
  27.414 +	u32 pg_offset = last_read & (PAGE_SIZE - 1);
  27.415 +	u32 to_copy;
  27.416 +	u16 handle;
  27.417 +
  27.418 +	tpmif_tx_request_t *tx;
  27.419 +	tx = &tpmif->tx->ring[0].req;
  27.420 +	/*
  27.421 +	 * Start copying data at the page with index 'index'
  27.422 +	 * and within that page at offset 'offset'.
  27.423 +	 * Copy a maximum of 'room_left' bytes.
  27.424 +	 */
  27.425 +	to_copy = MIN(PAGE_SIZE - pg_offset, room_left);
  27.426 +	while (to_copy > 0) {
  27.427 +		void *src;
  27.428 +		struct gnttab_map_grant_ref map_op;
  27.429 +		struct gnttab_unmap_grant_ref unmap_op;
  27.430 +
  27.431 +		tx = &tpmif->tx->ring[i].req;
  27.432 +
  27.433 +		map_op.host_addr = MMAP_VADDR(tpmif, i);
  27.434 +		map_op.flags     = GNTMAP_host_map;
  27.435 +		map_op.ref       = tx->ref;
  27.436 +		map_op.dom       = tpmif->domid;
  27.437 +
  27.438 +		if(unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
  27.439 +		                                      &map_op,
  27.440 +		                                      1))) {
  27.441 +			BUG();
  27.442 +		}
  27.443 +
  27.444 +		if (map_op.handle < 0) {
  27.445 +			DPRINTK(" Grant table operation failure !\n");
  27.446 +			return -EFAULT;
  27.447 +		}
  27.448 +
  27.449 +		handle = map_op.handle;
  27.450 +
  27.451 +		if (to_copy > tx->size) {
  27.452 +			/*
  27.453 +			 * This is the case when the user wants to read more
  27.454 +			 * than what we have. So we just give him what we
  27.455 +			 * have.
  27.456 +			 */
  27.457 +			to_copy = MIN(tx->size, to_copy);
  27.458 +		}
  27.459 +
  27.460 +		DPRINTK("Copying from mapped memory at %08lx\n",
  27.461 +		        (unsigned long)(MMAP_VADDR(tpmif,i) |
  27.462 +			(tx->addr & ~PAGE_MASK)));
  27.463 +
  27.464 +		src = (void *)(MMAP_VADDR(tpmif,i) | ((tx->addr & ~PAGE_MASK) + pg_offset));
  27.465 +		if (isuserbuffer) {
  27.466 +			if (copy_to_user(&buffer[offset],
  27.467 +			                 src,
  27.468 +			                 to_copy)) {
  27.469 +				return -EFAULT;
  27.470 +			}
  27.471 +		} else {
  27.472 +			memcpy(&buffer[offset],
  27.473 +			       src,
  27.474 +			       to_copy);
  27.475 +		}
  27.476 +
  27.477 +
  27.478 +		DPRINTK("Data from TPM-FE of domain %d are %d %d %d %d\n",
  27.479 +		        tpmif->domid, buffer[offset], buffer[offset+1],buffer[offset+2],buffer[offset+3]);
  27.480 +
  27.481 +		unmap_op.host_addr    = MMAP_VADDR(tpmif, i);
  27.482 +		unmap_op.handle       = handle;
  27.483 +		unmap_op.dev_bus_addr = 0;
  27.484 +
  27.485 +		if(unlikely(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref,
  27.486 +		                                      &unmap_op,
  27.487 +		                                      1))) {
  27.488 +			BUG();
  27.489 +		}
  27.490 +
  27.491 +		offset += to_copy;
  27.492 +		pg_offset = 0;
  27.493 +		last_read += to_copy;
  27.494 +		room_left -= to_copy;
  27.495 +
  27.496 +		to_copy = MIN(PAGE_SIZE, room_left);
  27.497 +		i++;
  27.498 +	} /* while (to_copy > 0) */
  27.499 +	/*
  27.500 +	 * Adjust the last_read pointer
  27.501 +	 */
  27.502 +	pak->last_read = last_read + 4;
  27.503 +	return offset;
  27.504 +}
  27.505 +
  27.506 +
  27.507 +/* ============================================================
  27.508 + * The file layer for reading data from this device
  27.509 + * ============================================================
  27.510 + */
  27.511 +static int
  27.512 +vtpm_op_open(struct inode *inode, struct file *f)
  27.513 +{
  27.514 +	int rc = 0;
  27.515 +	unsigned long flags;
  27.516 +
  27.517 +	write_lock_irqsave(&dataex.pak_lock, flags);
  27.518 +	if (dataex.has_opener == 0) {
  27.519 +		dataex.has_opener = 1;
  27.520 +	} else {
  27.521 +		rc = -EPERM;
  27.522 +	}
  27.523 +	write_unlock_irqrestore(&dataex.pak_lock, flags);
  27.524 +	return rc;
  27.525 +}
  27.526 +
  27.527 +static ssize_t
  27.528 +vtpm_op_read(struct file *file,
  27.529 +	     char __user * data, size_t size, loff_t * offset)
  27.530 +{
  27.531 +	int ret_size = -ENODATA;
  27.532 +	struct packet *pak = NULL;
  27.533 +	unsigned long flags;
  27.534 +
  27.535 +	write_lock_irqsave(&dataex.pak_lock, flags);
  27.536 +
  27.537 +	if (list_empty(&dataex.pending_pak)) {
  27.538 +		write_unlock_irqrestore(&dataex.pak_lock, flags);
  27.539 +		wait_event_interruptible(dataex.wait_queue,
  27.540 +		                         !list_empty(&dataex.pending_pak));
  27.541 +		write_lock_irqsave(&dataex.pak_lock, flags);
  27.542 +	}
  27.543 +
  27.544 +	if (!list_empty(&dataex.pending_pak)) {
  27.545 +		unsigned int left;
  27.546 +		pak = list_entry(dataex.pending_pak.next, struct packet, next);
  27.547 +
  27.548 +		left = pak->data_len - dataex.copied_so_far;
  27.549 +
  27.550 +		DPRINTK("size given by app: %d, available: %d\n", size, left);
  27.551 +
  27.552 +		ret_size = MIN(size,left);
  27.553 +
  27.554 +		ret_size = packet_read(pak, ret_size, data, size, 1);
  27.555 +		if (ret_size < 0) {
  27.556 +			ret_size = -EFAULT;
  27.557 +		} else {
  27.558 +			DPRINTK("Copied %d bytes to user buffer\n", ret_size);
  27.559 +
  27.560 +			dataex.copied_so_far += ret_size;
  27.561 +			if (dataex.copied_so_far >= pak->data_len + 4) {
  27.562 +				DPRINTK("All data from this packet given to app.\n");
  27.563 +				/* All data given to app */
  27.564 +
  27.565 +				del_singleshot_timer_sync(&pak->processing_timer);
  27.566 +				list_del(&pak->next);
  27.567 +				list_add_tail(&pak->next, &dataex.current_pak);
  27.568 +				/*
  27.569 +				 * The more fontends that are handled at the same time,
  27.570 +				 * the more time we give the TPM to process the request.
  27.571 +				 */
  27.572 +				mod_timer(&pak->processing_timer,
  27.573 +				          jiffies + (num_frontends * 10 * HZ));
  27.574 +				dataex.copied_so_far = 0;
  27.575 +			}
  27.576 +		}
  27.577 +	}
  27.578 +	write_unlock_irqrestore(&dataex.pak_lock, flags);
  27.579 +
  27.580 +	DPRINTK("Returning result from read to app: %d\n", ret_size);
  27.581 +
  27.582 +	return ret_size;
  27.583 +}
  27.584 +
  27.585 +/*
  27.586 + * Write operation - only works after a previous read operation!
  27.587 + */
  27.588 +static ssize_t
  27.589 +vtpm_op_write(struct file *file, const char __user * data, size_t size,
  27.590 +	      loff_t * offset)
  27.591 +{
  27.592 +	struct packet *pak;
  27.593 +	int rc = 0;
  27.594 +	unsigned int off = 4;
  27.595 +	unsigned long flags;
  27.596 +	u32 instance_no = 0;
  27.597 +	u32 len_no = 0;
  27.598 +
  27.599 +	/*
  27.600 +	 * Minimum required packet size is:
  27.601 +	 * 4 bytes for instance number
  27.602 +	 * 2 bytes for tag
  27.603 +	 * 4 bytes for paramSize
  27.604 +	 * 4 bytes for the ordinal
  27.605 +	 * sum: 14 bytes
  27.606 +	 */
  27.607 +	if ( size < off + 10 ) {
  27.608 +		return -EFAULT;
  27.609 +	}
  27.610 +
  27.611 +	if (copy_from_user(&instance_no,
  27.612 +	                   (void __user *)&data[0],
  27.613 +	                   4)) {
  27.614 +		return -EFAULT;
  27.615 +	}
  27.616 +
  27.617 +	if (copy_from_user(&len_no,
  27.618 +	                   (void __user *)&data[off+2],
  27.619 +	                   4) ||
  27.620 +	    (off + ntohl(len_no) != size)) {
  27.621 +		return -EFAULT;
  27.622 +	}
  27.623 +
  27.624 +	write_lock_irqsave(&dataex.pak_lock, flags);
  27.625 +	pak = packet_find_instance(&dataex.current_pak, ntohl(instance_no));
  27.626 +
  27.627 +	if (pak == NULL) {
  27.628 +		write_unlock_irqrestore(&dataex.pak_lock, flags);
  27.629 +		printk(KERN_ALERT "No associated packet!\n");
  27.630 +		return -EFAULT;
  27.631 +	} else {
  27.632 +		del_singleshot_timer_sync(&pak->processing_timer);
  27.633 +		list_del(&pak->next);
  27.634 +	}
  27.635 +
  27.636 +	write_unlock_irqrestore(&dataex.pak_lock, flags);
  27.637 +
  27.638 +	/*
  27.639 +	 * The first 'offset' bytes must be the instance number.
  27.640 +	 * I will just pull that from the packet.
  27.641 +	 */
  27.642 +	size -= off;
  27.643 +	data = &data[off];
  27.644 +
  27.645 +	rc = packet_write(pak, data, size, 1);
  27.646 +
  27.647 +	if (rc > 0) {
  27.648 +		/* I neglected the first 4 bytes */
  27.649 +		rc += off;
  27.650 +	}
  27.651 +	packet_free(pak);
  27.652 +	return rc;
  27.653 +}
  27.654 +
  27.655 +static int
  27.656 +vtpm_op_release(struct inode *inode, struct file *file)
  27.657 +{
  27.658 +	unsigned long flags;
  27.659 +	vtpm_release_packets(NULL, 1);
  27.660 +	write_lock_irqsave(&dataex.pak_lock, flags);
  27.661 +	dataex.has_opener = 0;
  27.662 +	write_unlock_irqrestore(&dataex.pak_lock, flags);
  27.663 +	return 0;
  27.664 +}
  27.665 +
  27.666 +static unsigned int
  27.667 +vtpm_op_poll(struct file *file, struct poll_table_struct *pst)
  27.668 +{
  27.669 +	return 0;
  27.670 +}
  27.671 +
  27.672 +static struct file_operations vtpm_ops = {
  27.673 +	.owner = THIS_MODULE,
  27.674 +	.llseek = no_llseek,
  27.675 +	.open = vtpm_op_open,
  27.676 +	.read = vtpm_op_read,
  27.677 +	.write = vtpm_op_write,
  27.678 +	.release = vtpm_op_release,
  27.679 +	.poll = vtpm_op_poll,
  27.680 +};
  27.681 +
  27.682 +static struct miscdevice ibmvtpms_miscdevice = {
  27.683 +	.minor = 225,
  27.684 +	.name = "vtpm",
  27.685 +	.fops = &vtpm_ops,
  27.686 +};
  27.687 +
  27.688 +
  27.689 +/***************************************************************
  27.690 + Virtual TPM functions and data stuctures
  27.691 +***************************************************************/
  27.692 +
  27.693 +static u8 create_cmd[] = {
  27.694 +        1,193,		/* 0: TPM_TAG_RQU_COMMAMD */
  27.695 +        0,0,0,19,	/* 2: length */
  27.696 +        0,0,0,0x1,	/* 6: VTPM_ORD_OPEN */
  27.697 +        0,		/* 10: VTPM type */
  27.698 +        0,0,0,0,	/* 11: domain id */
  27.699 +        0,0,0,0		/* 15: instance id */
  27.700 +};
  27.701 +
  27.702 +static u8 destroy_cmd[] = {
  27.703 +        1,193,		/* 0: TPM_TAG_RQU_COMMAMD */
  27.704 +        0,0,0,14,	/* 2: length */
  27.705 +        0,0,0,0x2,	/* 6: VTPM_ORD_CLOSE */
  27.706 +        0,0,0,0		/* 10: instance id */
  27.707 +};
  27.708 +
  27.709 +int tpmif_vtpm_open(tpmif_t *tpmif, domid_t domid, u32 instance)
  27.710 +{
  27.711 +	int rc = 0;
  27.712 +	struct packet *pak = packet_alloc(tpmif, sizeof(create_cmd), create_cmd[0],
  27.713 +	    PACKET_FLAG_DISCARD_RESPONSE|
  27.714 +	    PACKET_FLAG_SEND_CONTROLMESSAGE);
  27.715 +	if (pak) {
  27.716 +		u8 buf[sizeof(create_cmd)];
  27.717 +		u32 domid_no = htonl((u32)domid);
  27.718 +		u32 instance_no = htonl(instance);
  27.719 +		memcpy(buf, create_cmd, sizeof(create_cmd));
  27.720 +
  27.721 +		memcpy(&buf[11], &domid_no, sizeof(u32));
  27.722 +		memcpy(&buf[15], &instance_no, sizeof(u32));
  27.723 +
  27.724 +		/* copy the buffer into the packet */
  27.725 +		rc = packet_set(pak, buf, sizeof(buf));
  27.726 +
  27.727 +		if (rc == 0) {
  27.728 +			pak->tpm_instance = 0;
  27.729 +			rc = vtpm_queue_packet(pak);
  27.730 +		}
  27.731 +		if (rc < 0) {
  27.732 +			/* could not be queued or built */
  27.733 +			packet_free(pak);
  27.734 +		}
  27.735 +	} else {
  27.736 +		rc = -ENOMEM;
  27.737 +	}
  27.738 +	return rc;
  27.739 +}
  27.740 +
  27.741 +int tpmif_vtpm_close(u32 instid)
  27.742 +{
  27.743 +	int rc = 0;
  27.744 +	struct packet *pak;
  27.745 +
  27.746 +	pak = packet_alloc(NULL,
  27.747 +	                   sizeof(create_cmd),
  27.748 +	                   create_cmd[0],
  27.749 +	                   PACKET_FLAG_DISCARD_RESPONSE|
  27.750 +	                   PACKET_FLAG_SEND_CONTROLMESSAGE);
  27.751 +	if (pak) {
  27.752 +		u8 buf[sizeof(destroy_cmd)];
  27.753 +		u32 instid_no = htonl(instid);
  27.754 +		memcpy(buf, destroy_cmd, sizeof(destroy_cmd));
  27.755 +		memcpy(&buf[10], &instid_no, sizeof(u32));
  27.756 +
  27.757 +		/* copy the buffer into the packet */
  27.758 +		rc = packet_set(pak, buf, sizeof(buf));
  27.759 +
  27.760 +		if (rc == 0) {
  27.761 +			pak->tpm_instance = 0;
  27.762 +			rc = vtpm_queue_packet(pak);
  27.763 +		}
  27.764 +		if (rc < 0) {
  27.765 +			/* could not be queued or built */
  27.766 +			packet_free(pak);
  27.767 +		}
  27.768 +	} else {
  27.769 +		rc = -ENOMEM;
  27.770 +	}
  27.771 +	return rc;
  27.772 +}
  27.773 +
  27.774 +
  27.775 +/***************************************************************
  27.776 + Utility functions
  27.777 +***************************************************************/
  27.778 +
  27.779 +static int
  27.780 +tpm_send_fail_message(struct packet *pak, u8 req_tag)
  27.781 +{
  27.782 +	int rc;
  27.783 +	static const unsigned char tpm_error_message_fail[] = {
  27.784 +		0x00, 0x00,
  27.785 +		0x00, 0x00, 0x00, 0x0a,
  27.786 +		0x00, 0x00, 0x00, 0x09 /* TPM_FAIL */
  27.787 +	};
  27.788 +	unsigned char buffer[sizeof(tpm_error_message_fail)];
  27.789 +
  27.790 +	memcpy(buffer, tpm_error_message_fail, sizeof(tpm_error_message_fail));
  27.791 +	/*
  27.792 +	 * Insert the right response tag depending on the given tag
  27.793 +	 * All response tags are '+3' to the request tag.
  27.794 +	 */
  27.795 +	buffer[1] = req_tag + 3;
  27.796 +
  27.797 +	/*
  27.798 +	 * Write the data to shared memory and notify the front-end
  27.799 +	 */
  27.800 +	rc = packet_write(pak, buffer, sizeof(buffer), 0);
  27.801 +
  27.802 +	return rc;
  27.803 +}
  27.804 +
  27.805 +
  27.806 +static void
  27.807 +_vtpm_release_packets(struct list_head *head, tpmif_t *tpmif,
  27.808 +                      int send_msgs)
  27.809 +{
  27.810 +	struct packet *pak;
  27.811 +	struct list_head *pos, *tmp;
  27.812 +
  27.813 +	list_for_each_safe(pos, tmp, head) {
  27.814 +		pak = list_entry(pos, struct packet, next);
  27.815 +		if (tpmif == NULL || pak->tpmif == tpmif) {
  27.816 +			int can_send = 0;
  27.817 +			del_singleshot_timer_sync(&pak->processing_timer);
  27.818 +			list_del(&pak->next);
  27.819 +
  27.820 +			if (pak->tpmif && pak->tpmif->status == CONNECTED) {
  27.821 +				can_send = 1;
  27.822 +			}
  27.823 +
  27.824 +			if (send_msgs && can_send) {
  27.825 +				tpm_send_fail_message(pak, pak->req_tag);
  27.826 +			}
  27.827 +			packet_free(pak);
  27.828 +		}
  27.829 +	}
  27.830 +}
  27.831 +
  27.832 +
  27.833 +int
  27.834 +vtpm_release_packets(tpmif_t *tpmif, int send_msgs)
  27.835 +{
  27.836 +	unsigned long flags;
  27.837 +
  27.838 +	write_lock_irqsave(&dataex.pak_lock, flags);
  27.839 +
  27.840 +	_vtpm_release_packets(&dataex.pending_pak, tpmif, send_msgs);
  27.841 +	_vtpm_release_packets(&dataex.current_pak, tpmif, send_msgs);
  27.842 +
  27.843 +	write_unlock_irqrestore(&dataex.pak_lock,
  27.844 +	                        flags);
  27.845 +	return 0;
  27.846 +}
  27.847 +
  27.848 +
  27.849 +static int vtpm_queue_packet(struct packet *pak)
  27.850 +{
  27.851 +	int rc = 0;
  27.852 +	if (dataex.has_opener) {
  27.853 +		unsigned long flags;
  27.854 +		write_lock_irqsave(&dataex.pak_lock, flags);
  27.855 +		list_add_tail(&pak->next, &dataex.pending_pak);
  27.856 +		/* give the TPM some time to pick up the request */
  27.857 +		mod_timer(&pak->processing_timer, jiffies + (10 * HZ));
  27.858 +		write_unlock_irqrestore(&dataex.pak_lock,
  27.859 +		                        flags);
  27.860 +
  27.861 +		wake_up_interruptible(&dataex.wait_queue);
  27.862 +	} else {
  27.863 +		rc = -EFAULT;
  27.864 +	}
  27.865 +	return rc;
  27.866 +}
  27.867 +
  27.868 +
  27.869 +static int vtpm_receive(tpmif_t *tpmif, u32 size)
  27.870 +{
  27.871 +	int rc = 0;
  27.872 +	unsigned char buffer[10];
  27.873 +	__be32 *native_size;
  27.874 +
  27.875 +	struct packet *pak = packet_alloc(tpmif, size, buffer[4], 0);
  27.876 +	if (NULL == pak) {
  27.877 +		return -ENOMEM;
  27.878 +	}
  27.879 +	/*
  27.880 +	 * Read 10 bytes from the received buffer to test its
  27.881 +	 * content for validity.
  27.882 +	 */
  27.883 +	if (sizeof(buffer) != packet_read(pak,
  27.884 +	                                  sizeof(buffer), buffer,
  27.885 +	                                  sizeof(buffer), 0)) {
  27.886 +		goto failexit;
  27.887 +	}
  27.888 +	/*
  27.889 +	 * Reset the packet read pointer so we can read all its
  27.890 +	 * contents again.
  27.891 +	 */
  27.892 +	packet_reset(pak);
  27.893 +
  27.894 +	native_size = (__force __be32 *)(&buffer[4+2]);
  27.895 +	/*
  27.896 +	 * Verify that the size of the packet is correct
  27.897 +	 * as indicated and that there's actually someone reading packets.
  27.898 +	 * The minimum size of the packet is '10' for tag, size indicator
  27.899 +	 * and ordinal.
  27.900 +	 */
  27.901 +	if (size < 10 ||
  27.902 +	    be32_to_cpu(*native_size) != size ||
  27.903 +	    0 == dataex.has_opener) {
  27.904 +	    	rc = -EINVAL;
  27.905 +	    	goto failexit;
  27.906 +	} else {
  27.907 +		if ((rc = vtpm_queue_packet(pak)) < 0) {
  27.908 +			goto failexit;
  27.909 +		}
  27.910 +	}
  27.911 +	return 0;
  27.912 +
  27.913 +failexit:
  27.914 +	if (pak) {
  27.915 +		tpm_send_fail_message(pak, buffer[4+1]);
  27.916 +		packet_free(pak);
  27.917 +	}
  27.918 +	return rc;
  27.919 +}
  27.920 +
  27.921 +
  27.922 +/*
  27.923 + * Timeout function that gets invoked when a packet has not been processed
  27.924 + * during the timeout period.
  27.925 + * The packet must be on a list when this function is invoked. This
  27.926 + * also means that once its taken off a list, the timer must be
  27.927 + * destroyed as well.
  27.928 + */
  27.929 +static void processing_timeout(unsigned long ptr)
  27.930 +{
  27.931 +	struct packet *pak = (struct packet *)ptr;
  27.932 +	unsigned long flags;
  27.933 +	write_lock_irqsave(&dataex.pak_lock, flags);
  27.934 +	/*
  27.935 +	 * The packet needs to be searched whether it
  27.936 +	 * is still on the list.
  27.937 +	 */
  27.938 +	if (pak == packet_find_packet(&dataex.pending_pak, pak) ||
  27.939 +	    pak == packet_find_packet(&dataex.current_pak, pak) ) {
  27.940 +		list_del(&pak->next);
  27.941 +		tpm_send_fail_message(pak, pak->req_tag);
  27.942 +		packet_free(pak);
  27.943 +	}
  27.944 +
  27.945 +	write_unlock_irqrestore(&dataex.pak_lock, flags);
  27.946 +}
  27.947 +
  27.948 +
  27.949 +
  27.950 +static void tpm_tx_action(unsigned long unused);
  27.951 +static DECLARE_TASKLET(tpm_tx_tasklet, tpm_tx_action, 0);
  27.952 +
  27.953 +#define MAX_PENDING_REQS TPMIF_TX_RING_SIZE
  27.954 +
  27.955 +static struct list_head tpm_schedule_list;
  27.956 +static spinlock_t tpm_schedule_list_lock;
  27.957 +
  27.958 +static inline void
  27.959 +maybe_schedule_tx_action(void)
  27.960 +{
  27.961 +	smp_mb();
  27.962 +	tasklet_schedule(&tpm_tx_tasklet);
  27.963 +}
  27.964 +
  27.965 +static inline int
  27.966 +__on_tpm_schedule_list(tpmif_t * tpmif)
  27.967 +{
  27.968 +	return tpmif->list.next != NULL;
  27.969 +}
  27.970 +
  27.971 +static void
  27.972 +remove_from_tpm_schedule_list(tpmif_t * tpmif)
  27.973 +{
  27.974 +	spin_lock_irq(&tpm_schedule_list_lock);
  27.975 +	if (likely(__on_tpm_schedule_list(tpmif))) {
  27.976 +		list_del(&tpmif->list);
  27.977 +		tpmif->list.next = NULL;
  27.978 +		tpmif_put(tpmif);
  27.979 +	}
  27.980 +	spin_unlock_irq(&tpm_schedule_list_lock);
  27.981 +}
  27.982 +
  27.983 +static void
  27.984 +add_to_tpm_schedule_list_tail(tpmif_t * tpmif)
  27.985 +{
  27.986 +	if (__on_tpm_schedule_list(tpmif))
  27.987 +		return;
  27.988 +
  27.989 +	spin_lock_irq(&tpm_schedule_list_lock);
  27.990 +	if (!__on_tpm_schedule_list(tpmif) && tpmif->active) {
  27.991 +		list_add_tail(&tpmif->list, &tpm_schedule_list);
  27.992 +		tpmif_get(tpmif);
  27.993 +	}
  27.994 +	spin_unlock_irq(&tpm_schedule_list_lock);
  27.995 +}
  27.996 +
  27.997 +void
  27.998 +tpmif_schedule_work(tpmif_t * tpmif)
  27.999 +{
 27.1000 +	add_to_tpm_schedule_list_tail(tpmif);
 27.1001 +	maybe_schedule_tx_action();
 27.1002 +}
 27.1003 +
 27.1004 +void
 27.1005 +tpmif_deschedule_work(tpmif_t * tpmif)
 27.1006 +{
 27.1007 +	remove_from_tpm_schedule_list(tpmif);
 27.1008 +}
 27.1009 +
 27.1010 +
 27.1011 +static void
 27.1012 +tpm_tx_action(unsigned long unused)
 27.1013 +{
 27.1014 +	struct list_head *ent;
 27.1015 +	tpmif_t *tpmif;
 27.1016 +	tpmif_tx_request_t *tx;
 27.1017 +
 27.1018 +	DPRINTK("%s: Getting data from front-end(s)!\n", __FUNCTION__);
 27.1019 +
 27.1020 +	while (!list_empty(&tpm_schedule_list)) {
 27.1021 +		/* Get a tpmif from the list with work to do. */
 27.1022 +		ent = tpm_schedule_list.next;
 27.1023 +		tpmif = list_entry(ent, tpmif_t, list);
 27.1024 +		tpmif_get(tpmif);
 27.1025 +		remove_from_tpm_schedule_list(tpmif);
 27.1026 +		/*
 27.1027 +		 * Ensure that we see the request when we read from it.
 27.1028 +		 */
 27.1029 +		mb();
 27.1030 +
 27.1031 +		tx = &tpmif->tx->ring[0].req;
 27.1032 +
 27.1033 +		/* pass it up */
 27.1034 +		vtpm_receive(tpmif, tx->size);
 27.1035 +
 27.1036 +		tpmif_put(tpmif);
 27.1037 +	}
 27.1038 +}
 27.1039 +
 27.1040 +irqreturn_t
 27.1041 +tpmif_be_int(int irq, void *dev_id, struct pt_regs *regs)
 27.1042 +{
 27.1043 +	tpmif_t *tpmif = dev_id;
 27.1044 +	add_to_tpm_schedule_list_tail(tpmif);
 27.1045 +	maybe_schedule_tx_action();
 27.1046 +	return IRQ_HANDLED;
 27.1047 +}
 27.1048 +
 27.1049 +static int __init
 27.1050 +tpmback_init(void)
 27.1051 +{
 27.1052 +	int rc;
 27.1053 +	if (!(xen_start_info.flags & SIF_TPM_BE_DOMAIN) &&
 27.1054 +	    !(xen_start_info.flags & SIF_INITDOMAIN)) {
 27.1055 +	    	printk(KERN_ALERT "Neither TPM-BE Domain nor INIT domain!\n");
 27.1056 +		return 0;
 27.1057 +	}
 27.1058 +
 27.1059 +	if ((rc = misc_register(&ibmvtpms_miscdevice)) != 0) {
 27.1060 +		printk(KERN_ALERT "Could not register misc device for TPM BE.\n");
 27.1061 +		return rc;
 27.1062 +	}
 27.1063 +
 27.1064 +	INIT_LIST_HEAD(&dataex.pending_pak);
 27.1065 +	INIT_LIST_HEAD(&dataex.current_pak);
 27.1066 +	dataex.has_opener = 0;
 27.1067 +	rwlock_init(&dataex.pak_lock);
 27.1068 +	init_waitqueue_head(&dataex.wait_queue);
 27.1069 +
 27.1070 +	spin_lock_init(&tpm_schedule_list_lock);
 27.1071 +	INIT_LIST_HEAD(&tpm_schedule_list);
 27.1072 +
 27.1073 +	tpmif_interface_init();
 27.1074 +	tpmif_xenbus_init();
 27.1075 +
 27.1076 +	printk(KERN_ALERT "Successfully initialized TPM backend driver.\n");
 27.1077 +
 27.1078 +	return 0;
 27.1079 +}
 27.1080 +
 27.1081 +__initcall(tpmback_init);
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c	Thu Sep 01 10:16:14 2005 +0000
    28.3 @@ -0,0 +1,271 @@
    28.4 +/*  Xenbus code for tpmif backend
    28.5 +    Copyright (C) 2005 Rusty Russell <rusty@rustcorp.com.au>
    28.6 +
    28.7 +    This program is free software; you can redistribute it and/or modify
    28.8 +    it under the terms of the GNU General Public License as published by
    28.9 +    the Free Software Foundation; either version 2 of the License, or
   28.10 +    (at your option) any later version.
   28.11 +
   28.12 +    This program is distributed in the hope that it will be useful,
   28.13 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   28.14 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   28.15 +    GNU General Public License for more details.
   28.16 +
   28.17 +    You should have received a copy of the GNU General Public License
   28.18 +    along with this program; if not, write to the Free Software
   28.19 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   28.20 +*/
   28.21 +#include <stdarg.h>
   28.22 +#include <linux/module.h>
   28.23 +#include <asm-xen/xenbus.h>
   28.24 +#include "common.h"
   28.25 +
   28.26 +struct backend_info
   28.27 +{
   28.28 +	struct xenbus_device *dev;
   28.29 +
   28.30 +	/* our communications channel */
   28.31 +	tpmif_t *tpmif;
   28.32 +
   28.33 +	long int frontend_id;
   28.34 +	long int instance; // instance of TPM
   28.35 +
   28.36 +	/* watch front end for changes */
   28.37 +	struct xenbus_watch backend_watch;
   28.38 +
   28.39 +	struct xenbus_watch watch;
   28.40 +	char * frontpath;
   28.41 +};
   28.42 +
   28.43 +static int tpmback_remove(struct xenbus_device *dev)
   28.44 +{
   28.45 +	struct backend_info *be = dev->data;
   28.46 +
   28.47 +	if (be->watch.node) {
   28.48 +		unregister_xenbus_watch(&be->watch);
   28.49 +	}
   28.50 +	unregister_xenbus_watch(&be->backend_watch);
   28.51 +
   28.52 +	tpmif_vtpm_close(be->instance);
   28.53 +
   28.54 +	if (be->tpmif) {
   28.55 +		tpmif_put(be->tpmif);
   28.56 +	}
   28.57 +
   28.58 +	if (be->frontpath)
   28.59 +		kfree(be->frontpath);
   28.60 +	kfree(be);
   28.61 +	return 0;
   28.62 +}
   28.63 +
   28.64 +
   28.65 +static void frontend_changed(struct xenbus_watch *watch, const char *node)
   28.66 +{
   28.67 +	unsigned long ringref;
   28.68 +	unsigned int evtchn;
   28.69 +	unsigned long ready = 1;
   28.70 +	int err;
   28.71 +	struct backend_info *be
   28.72 +		= container_of(watch, struct backend_info, watch);
   28.73 +
   28.74 +	/* If other end is gone, delete ourself. */
   28.75 +	if (node && !xenbus_exists(be->frontpath, "")) {
   28.76 +		xenbus_rm(be->dev->nodename, "");
   28.77 +		device_unregister(&be->dev->dev);
   28.78 +		return;
   28.79 +	}
   28.80 +
   28.81 +	if (be->tpmif == NULL || be->tpmif->status == CONNECTED)
   28.82 +		return;
   28.83 +
   28.84 +	err = xenbus_gather(be->frontpath,
   28.85 +	                    "ring-ref", "%lu", &ringref,
   28.86 +			    "event-channel", "%u", &evtchn, NULL);
   28.87 +	if (err) {
   28.88 +		xenbus_dev_error(be->dev, err,
   28.89 +				 "reading %s/grant-id and event-channel",
   28.90 +				 be->frontpath);
   28.91 +		return;
   28.92 +	}
   28.93 +
   28.94 +
   28.95 +	/*
   28.96 +	 * Tell the front-end that we are ready to go -
   28.97 +	 * unless something bad happens
   28.98 +	 */
   28.99 +	err = xenbus_transaction_start(be->dev->nodename);
  28.100 +	if (err) {
  28.101 +		xenbus_dev_error(be->dev, err, "starting transaction");
  28.102 +		return;
  28.103 +	}
  28.104 +
  28.105 +	err = xenbus_printf(be->dev->nodename,
  28.106 +	                    "ready", "%lu", ready);
  28.107 +	if (err) {
  28.108 +		xenbus_dev_error(be->dev, err, "writing 'ready'");
  28.109 +		goto abort;
  28.110 +	}
  28.111 +
  28.112 +	err = tpmif_map(be->tpmif, ringref, evtchn);
  28.113 +	if (err) {
  28.114 +		xenbus_dev_error(be->dev, err,
  28.115 +				 "mapping shared-frame %lu port %u",
  28.116 +				 ringref, evtchn);
  28.117 +		goto abort;
  28.118 +	}
  28.119 +
  28.120 +	err = tpmif_vtpm_open(be->tpmif,
  28.121 +	                      be->frontend_id,
  28.122 +	                      be->instance);
  28.123 +	if (err) {
  28.124 +		xenbus_dev_error(be->dev, err,
  28.125 +		                 "queueing vtpm open packet");
  28.126 +		/*
  28.127 +		 * Should close down this device and notify FE
  28.128 +		 * about closure.
  28.129 +		 */
  28.130 +		goto abort;
  28.131 +	}
  28.132 +
  28.133 +	xenbus_transaction_end(0);
  28.134 +	xenbus_dev_ok(be->dev);
  28.135 +	return;
  28.136 +abort:
  28.137 +	xenbus_transaction_end(1);
  28.138 +}
  28.139 +
  28.140 +
  28.141 +static void backend_changed(struct xenbus_watch *watch, const char *node)
  28.142 +{
  28.143 +	int err;
  28.144 +	long int instance;
  28.145 +	struct backend_info *be
  28.146 +		= container_of(watch, struct backend_info, backend_watch);
  28.147 +	struct xenbus_device *dev = be->dev;
  28.148 +
  28.149 +	err = xenbus_scanf(dev->nodename, "instance", "%li", &instance);
  28.150 +	if (XENBUS_EXIST_ERR(err))
  28.151 +		return;
  28.152 +	if (err < 0) {
  28.153 +		xenbus_dev_error(dev, err, "reading 'instance' variable");
  28.154 +		return;
  28.155 +	}
  28.156 +
  28.157 +	if (be->instance != -1 && be->instance != instance) {
  28.158 +		printk(KERN_WARNING
  28.159 +		       "cannot change the instance\n");
  28.160 +		return;
  28.161 +	}
  28.162 +	be->instance = instance;
  28.163 +
  28.164 +	if (be->tpmif == NULL) {
  28.165 +		be->tpmif = tpmif_find(be->frontend_id,
  28.166 +		                       instance);
  28.167 +		if (IS_ERR(be->tpmif)) {
  28.168 +			err = PTR_ERR(be->tpmif);
  28.169 +			be->tpmif = NULL;
  28.170 +			xenbus_dev_error(dev, err, "creating interface");
  28.171 +			return;
  28.172 +		}
  28.173 +
  28.174 +		/* Pass in NULL node to skip exist test. */
  28.175 +		frontend_changed(&be->watch, be->frontpath);
  28.176 +	}
  28.177 +}
  28.178 +
  28.179 +
  28.180 +static int tpmback_probe(struct xenbus_device *dev,
  28.181 +			 const struct xenbus_device_id *id)
  28.182 +{
  28.183 +	struct backend_info *be;
  28.184 +	char *frontend;
  28.185 +	int err;
  28.186 +
  28.187 +	be = kmalloc(sizeof(*be), GFP_KERNEL);
  28.188 +	if (!be) {
  28.189 +		xenbus_dev_error(dev, -ENOMEM, "allocating backend structure");
  28.190 +		err = -ENOMEM;
  28.191 +	}
  28.192 +
  28.193 +	memset(be, 0, sizeof(*be));
  28.194 +
  28.195 +	frontend = NULL;
  28.196 +	err = xenbus_gather(dev->nodename,
  28.197 +			    "frontend-id", "%li", &be->frontend_id,
  28.198 +			    "frontend", NULL, &frontend,
  28.199 +			    NULL);
  28.200 +	if (XENBUS_EXIST_ERR(err))
  28.201 +		goto free_be;
  28.202 +	if (err < 0) {
  28.203 +		xenbus_dev_error(dev, err,
  28.204 +				 "reading %s/frontend or frontend-id",
  28.205 +				 dev->nodename);
  28.206 +		goto free_be;
  28.207 +	}
  28.208 +	if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) {
  28.209 +		/* If we can't get a frontend path and a frontend-id,
  28.210 +		 * then our bus-id is no longer valid and we need to
  28.211 +		 * destroy the backend device.
  28.212 +		 */
  28.213 +		err = -ENOENT;
  28.214 +		goto free_be;
  28.215 +	}
  28.216 +
  28.217 +	be->dev = dev;
  28.218 +	be->backend_watch.node     = dev->nodename;
  28.219 +	be->backend_watch.callback = backend_changed;
  28.220 +	be->instance = -1;
  28.221 +	err = register_xenbus_watch(&be->backend_watch);
  28.222 +	if (err) {
  28.223 +		be->backend_watch.node = NULL;
  28.224 +		xenbus_dev_error(dev, err, "adding backend watch on %s",
  28.225 +				 dev->nodename);
  28.226 +		goto free_be;
  28.227 +	}
  28.228 +
  28.229 +	be->frontpath = frontend;
  28.230 +	be->watch.node = be->frontpath;
  28.231 +	be->watch.callback = frontend_changed;
  28.232 +	err = register_xenbus_watch(&be->watch);
  28.233 +	if (err) {
  28.234 +		be->watch.node = NULL;
  28.235 +		xenbus_dev_error(dev, err,
  28.236 +				 "adding frontend watch on %s",
  28.237 +				 be->frontpath);
  28.238 +		goto free_be;
  28.239 +	}
  28.240 +
  28.241 +	dev->data = be;
  28.242 +
  28.243 +	backend_changed(&be->backend_watch, dev->nodename);
  28.244 +	return err;
  28.245 +
  28.246 +free_be:
  28.247 +	if (be->backend_watch.node)
  28.248 +		unregister_xenbus_watch(&be->backend_watch);
  28.249 +	if (frontend)
  28.250 +		kfree(frontend);
  28.251 +	kfree(be);
  28.252 +	return err;
  28.253 +}
  28.254 +
  28.255 +
  28.256 +static struct xenbus_device_id tpmback_ids[] = {
  28.257 +	{ "vtpm" },
  28.258 +	{ "" }
  28.259 +};
  28.260 +
  28.261 +
  28.262 +static struct xenbus_driver tpmback = {
  28.263 +	.name = "vtpm",
  28.264 +	.owner = THIS_MODULE,
  28.265 +	.ids = tpmback_ids,
  28.266 +	.probe = tpmback_probe,
  28.267 +	.remove = tpmback_remove,
  28.268 +};
  28.269 +
  28.270 +
  28.271 +void tpmif_xenbus_init(void)
  28.272 +{
  28.273 +	xenbus_register_backend(&tpmback);
  28.274 +}
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/Makefile	Thu Sep 01 10:16:14 2005 +0000
    29.3 @@ -0,0 +1,2 @@
    29.4 +
    29.5 +obj-$(CONFIG_XEN_TPMDEV_FRONTEND)	+= tpmfront.o
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c	Thu Sep 01 10:16:14 2005 +0000
    30.3 @@ -0,0 +1,739 @@
    30.4 +/*
    30.5 + * Copyright (c) 2005, IBM Corporation
    30.6 + *
    30.7 + * Author: Stefan Berger, stefanb@us.ibm.com
    30.8 + * Grant table support: Mahadevan Gomathisankaran
    30.9 + *
   30.10 + * This code has been derived from drivers/xen/netfront/netfront.c
   30.11 + *
   30.12 + * Copyright (c) 2002-2004, K A Fraser
   30.13 + *
   30.14 + * This file may be distributed separately from the Linux kernel, or
   30.15 + * incorporated into other software packages, subject to the following license:
   30.16 + *
   30.17 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   30.18 + * of this source file (the "Software"), to deal in the Software without
   30.19 + * restriction, including without limitation the rights to use, copy, modify,
   30.20 + * merge, publish, distribute, sublicense, and/or sell copies of the Software,
   30.21 + * and to permit persons to whom the Software is furnished to do so, subject to
   30.22 + * the following conditions:
   30.23 + *
   30.24 + * The above copyright notice and this permission notice shall be included in
   30.25 + * all copies or substantial portions of the Software.
   30.26 + *
   30.27 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   30.28 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   30.29 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   30.30 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   30.31 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   30.32 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   30.33 + * IN THE SOFTWARE.
   30.34 + */
   30.35 +
   30.36 +#include <linux/config.h>
   30.37 +#include <linux/module.h>
   30.38 +#include <linux/version.h>
   30.39 +#include <linux/kernel.h>
   30.40 +#include <linux/slab.h>
   30.41 +#include <linux/errno.h>
   30.42 +#include <linux/interrupt.h>
   30.43 +#include <linux/init.h>
   30.44 +#include <linux/tpmfe.h>
   30.45 +
   30.46 +#include <asm/semaphore.h>
   30.47 +#include <asm/io.h>
   30.48 +#include <asm-xen/evtchn.h>
   30.49 +#include <asm-xen/ctrl_if.h>
   30.50 +#include <asm-xen/xen-public/io/tpmif.h>
   30.51 +#include <asm/uaccess.h>
   30.52 +#include <asm-xen/xenbus.h>
   30.53 +#include <asm-xen/xen-public/io/domain_controller.h>
   30.54 +#include <asm-xen/xen-public/grant_table.h>
   30.55 +
   30.56 +#include "tpmfront.h"
   30.57 +
   30.58 +#undef DEBUG
   30.59 +
   30.60 +#if 1
   30.61 +#define ASSERT(_p) \
   30.62 +    if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
   30.63 +        __LINE__, __FILE__); *(int*)0=0; }
   30.64 +#else
   30.65 +#define ASSERT(_p)
   30.66 +#endif
   30.67 +
   30.68 +/* locally visible variables */
   30.69 +static grant_ref_t gref_head;
   30.70 +static struct tpm_private my_private;
   30.71 +
   30.72 +/* local function prototypes */
   30.73 +static irqreturn_t tpmif_int(int irq,
   30.74 +                             void *tpm_priv,
   30.75 +                             struct pt_regs *ptregs);
   30.76 +static void tpmif_rx_action(unsigned long unused);
   30.77 +static void tpmif_connect(u16 evtchn, domid_t domid);
   30.78 +static DECLARE_TASKLET(tpmif_rx_tasklet, tpmif_rx_action, 0);
   30.79 +static int tpm_allocate_buffers(struct tpm_private *tp);
   30.80 +static void tpmif_set_connected_state(struct tpm_private *tp, int newstate);
   30.81 +static int tpm_xmit(struct tpm_private *tp,
   30.82 +                    const u8 * buf, size_t count, int userbuffer,
   30.83 +                    void *remember);
   30.84 +
   30.85 +#if DEBUG
   30.86 +#define DPRINTK(fmt, args...) \
   30.87 +    printk(KERN_ALERT "xen_tpm_fr (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args)
   30.88 +#else
   30.89 +#define DPRINTK(fmt, args...) ((void)0)
   30.90 +#endif
   30.91 +#define IPRINTK(fmt, args...) \
   30.92 +    printk(KERN_INFO "xen_tpm_fr: " fmt, ##args)
   30.93 +#define WPRINTK(fmt, args...) \
   30.94 +    printk(KERN_WARNING "xen_tpm_fr: " fmt, ##args)
   30.95 +
   30.96 +
   30.97 +static inline int
   30.98 +tx_buffer_copy(struct tx_buffer *txb, const u8 * src, int len,
   30.99 +               int isuserbuffer)
  30.100 +{
  30.101 +	int copied = len;
  30.102 +
  30.103 +	if (len > txb->size) {
  30.104 +		copied = txb->size;
  30.105 +	}
  30.106 +	if (isuserbuffer) {
  30.107 +		if (copy_from_user(txb->data,
  30.108 +		                   src,
  30.109 +		                   copied)) {
  30.110 +			return -EFAULT;
  30.111 +		}
  30.112 +	} else {
  30.113 +		memcpy(txb->data, src, copied);
  30.114 +	}
  30.115 +	txb->len = len;
  30.116 +	return copied;
  30.117 +}
  30.118 +
  30.119 +static inline struct tx_buffer *tx_buffer_alloc(void)
  30.120 +{
  30.121 +	struct tx_buffer *txb = kmalloc(sizeof (struct tx_buffer),
  30.122 +					GFP_KERNEL);
  30.123 +
  30.124 +	if (txb) {
  30.125 +		txb->len = 0;
  30.126 +		txb->size = PAGE_SIZE;
  30.127 +		txb->data = (unsigned char *)__get_free_page(GFP_KERNEL);
  30.128 +		if (txb->data == NULL) {
  30.129 +			kfree(txb);
  30.130 +			txb = NULL;
  30.131 +		}
  30.132 +	}
  30.133 +	return txb;
  30.134 +}
  30.135 +
  30.136 +
  30.137 +/**************************************************************
  30.138 +
  30.139 + The interface to let the tpm plugin register its callback
  30.140 + function and send data to another partition using this module
  30.141 +
  30.142 +**************************************************************/
  30.143 +
  30.144 +static DECLARE_MUTEX(upperlayer_lock);
  30.145 +static DECLARE_MUTEX(suspend_lock);
  30.146 +static struct tpmfe_device *upperlayer_tpmfe;
  30.147 +
  30.148 +/*
  30.149 + * Send data via this module by calling this function
  30.150 + */
  30.151 +int tpm_fe_send(const u8 * buf, size_t count, void *ptr)
  30.152 +{
  30.153 +	int sent = 0;
  30.154 +	struct tpm_private *tp = &my_private;
  30.155 +
  30.156 +	down(&suspend_lock);
  30.157 +	sent = tpm_xmit(tp, buf, count, 0, ptr);
  30.158 +	up(&suspend_lock);
  30.159 +
  30.160 +	return sent;
  30.161 +}
  30.162 +EXPORT_SYMBOL(tpm_fe_send);
  30.163 +
  30.164 +/*
  30.165 + * Register a callback for receiving data from this module
  30.166 + */
  30.167 +int tpm_fe_register_receiver(struct tpmfe_device *tpmfe_dev)
  30.168 +{
  30.169 +	int rc = 0;
  30.170 +
  30.171 +	down(&upperlayer_lock);
  30.172 +	if (NULL == upperlayer_tpmfe) {
  30.173 +		upperlayer_tpmfe = tpmfe_dev;
  30.174 +		tpmfe_dev->max_tx_size = TPMIF_TX_RING_SIZE * PAGE_SIZE;
  30.175 +	} else {
  30.176 +		rc = -EBUSY;
  30.177 +	}
  30.178 +	up(&upperlayer_lock);
  30.179 +	return rc;
  30.180 +}
  30.181 +EXPORT_SYMBOL(tpm_fe_register_receiver);
  30.182 +
  30.183 +/*
  30.184 + * Unregister the callback for receiving data from this module
  30.185 + */
  30.186 +void tpm_fe_unregister_receiver(void)
  30.187 +{
  30.188 +	down(&upperlayer_lock);
  30.189 +	upperlayer_tpmfe = NULL;
  30.190 +	up(&upperlayer_lock);
  30.191 +}
  30.192 +EXPORT_SYMBOL(tpm_fe_unregister_receiver);
  30.193 +
  30.194 +/*
  30.195 + * Call this function to send data to the upper layer's
  30.196 + * registered receiver function.
  30.197 + */
  30.198 +static int tpm_fe_send_upperlayer(const u8 * buf, size_t count,
  30.199 +                                  const void *ptr)
  30.200 +{
  30.201 +	int rc;
  30.202 +
  30.203 +	down(&upperlayer_lock);
  30.204 +
  30.205 +	if (upperlayer_tpmfe && upperlayer_tpmfe->receive) {
  30.206 +		rc = upperlayer_tpmfe->receive(buf, count, ptr);
  30.207 +	} else {
  30.208 +		rc = 0;
  30.209 +	}
  30.210 +
  30.211 +	up(&upperlayer_lock);
  30.212 +	return rc;
  30.213 +}
  30.214 +
  30.215 +/**************************************************************
  30.216 + XENBUS support code
  30.217 +**************************************************************/
  30.218 +
  30.219 +static void watch_for_status(struct xenbus_watch *watch, const char *node)
  30.220 +{
  30.221 +	struct tpmfront_info *info;
  30.222 +	int err;
  30.223 +	unsigned long ready;
  30.224 +	struct tpm_private *tp = &my_private;
  30.225 +
  30.226 +	info = container_of(watch, struct tpmfront_info, watch);
  30.227 +	node += strlen(watch->node);
  30.228 +
  30.229 +	if (tp->connected)
  30.230 +		return;
  30.231 +
  30.232 +	err = xenbus_gather(watch->node,
  30.233 +	                    "ready", "%lu", &ready,
  30.234 +	                    NULL);
  30.235 +	if (err) {
  30.236 +		xenbus_dev_error(info->dev, err, "reading 'ready' field");
  30.237 +		return;
  30.238 +	}
  30.239 +
  30.240 +	tpmif_set_connected_state(tp, 1);
  30.241 +
  30.242 +	xenbus_dev_ok(info->dev);
  30.243 +}
  30.244 +
  30.245 +
  30.246 +static int setup_tpmring(struct xenbus_device *dev,
  30.247 +                         struct tpmfront_info * info,
  30.248 +                         domid_t backend_id)
  30.249 +{
  30.250 +	tpmif_tx_interface_t *sring;
  30.251 +	struct tpm_private *tp = &my_private;
  30.252 +
  30.253 +	evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
  30.254 +	int err;
  30.255 +
  30.256 +	sring = (void *)__get_free_page(GFP_KERNEL);
  30.257 +	if (!sring) {
  30.258 +		xenbus_dev_error(dev, -ENOMEM, "allocating shared ring");
  30.259 +		return -ENOMEM;
  30.260 +	}
  30.261 +	tp->tx = sring;
  30.262 +
  30.263 +	tpm_allocate_buffers(tp);
  30.264 +
  30.265 +	info->ring_ref = gnttab_claim_grant_reference(&gref_head);
  30.266 +	ASSERT(info->ring_ref != -ENOSPC);
  30.267 +	gnttab_grant_foreign_access_ref(info->ring_ref,
  30.268 +					backend_id,
  30.269 +					(virt_to_machine(tp->tx) >> PAGE_SHIFT),
  30.270 +					0);
  30.271 +
  30.272 +	op.u.alloc_unbound.dom = backend_id;
  30.273 +	err = HYPERVISOR_event_channel_op(&op);
  30.274 +	if (err) {
  30.275 +		free_page((unsigned long)sring);
  30.276 +		tp->tx = 0;
  30.277 +		xenbus_dev_error(dev, err, "allocating event channel");
  30.278 +		return err;
  30.279 +	}
  30.280 +	tpmif_connect(op.u.alloc_unbound.port, backend_id);
  30.281 +	return 0;
  30.282 +}
  30.283 +
  30.284 +
  30.285 +static void destroy_tpmring(struct tpmfront_info *info, struct tpm_private *tp)
  30.286 +{
  30.287 +	tpmif_set_connected_state(tp,0);
  30.288 +
  30.289 +	if ( tp->tx != NULL ) {
  30.290 +		free_page((unsigned long)tp->tx);
  30.291 +		tp->tx = NULL;
  30.292 +	}
  30.293 +	unbind_evtchn_from_irqhandler(tp->evtchn, NULL);
  30.294 +	tp->evtchn = 0;
  30.295 +}
  30.296 +
  30.297 +
  30.298 +static int talk_to_backend(struct xenbus_device *dev,
  30.299 +                           struct tpmfront_info *info)
  30.300 +{
  30.301 +	char *backend;
  30.302 +	const char *message;
  30.303 +	int err;
  30.304 +	int backend_id;
  30.305 +
  30.306 +	backend = NULL;
  30.307 +	err = xenbus_gather(dev->nodename,
  30.308 +			    "backend-id", "%i", &backend_id,
  30.309 +			    "backend", NULL, &backend,
  30.310 +			    NULL);
  30.311 +	if (XENBUS_EXIST_ERR(err))
  30.312 +		goto out;
  30.313 +	if (backend && strlen(backend) == 0) {
  30.314 +		err = -ENOENT;
  30.315 +		goto out;
  30.316 +	}
  30.317 +	if (err < 0) {
  30.318 +		xenbus_dev_error(dev, err, "reading %s/backend or backend-id",
  30.319 +				 dev->nodename);
  30.320 +		goto out;
  30.321 +	}
  30.322 +
  30.323 +	info->backend_id      = backend_id;
  30.324 +	my_private.backend_id = backend_id;
  30.325 +
  30.326 +	err = setup_tpmring(dev, info, backend_id);
  30.327 +	if (err) {
  30.328 +		xenbus_dev_error(dev, err, "setting up ring");
  30.329 +		goto out;
  30.330 +	}
  30.331 +
  30.332 +	err = xenbus_transaction_start(dev->nodename);
  30.333 +	if (err) {
  30.334 +		xenbus_dev_error(dev, err, "starting transaction");
  30.335 +		goto destroy_tpmring;
  30.336 +	}
  30.337 +
  30.338 +	err = xenbus_printf(dev->nodename,
  30.339 +	                    "ring-ref","%u", info->ring_ref);
  30.340 +	if (err) {
  30.341 +		message = "writing ring-ref";
  30.342 +		goto abort_transaction;
  30.343 +	}
  30.344 +
  30.345 +	err = xenbus_printf(dev->nodename,
  30.346 +			    "event-channel", "%u", my_private.evtchn);
  30.347 +	if (err) {
  30.348 +		message = "writing event-channel";
  30.349 +		goto abort_transaction;
  30.350 +	}
  30.351 +
  30.352 +	info->backend = backend;
  30.353 +	backend = NULL;
  30.354 +
  30.355 +	info->watch.node = info->backend;
  30.356 +	info->watch.callback = watch_for_status;
  30.357 +	err = register_xenbus_watch(&info->watch);
  30.358 +	if (err) {
  30.359 +		message = "registering watch on backend";
  30.360 +		goto abort_transaction;
  30.361 +	}
  30.362 +
  30.363 +	err = xenbus_transaction_end(0);
  30.364 +	if (err) {
  30.365 +		xenbus_dev_error(dev, err, "completing transaction");
  30.366 +		goto destroy_tpmring;
  30.367 +	}
  30.368 +
  30.369 +out:
  30.370 +	if (backend)
  30.371 +		kfree(backend);
  30.372 +	return err;
  30.373 +
  30.374 +abort_transaction:
  30.375 +	xenbus_transaction_end(1);
  30.376 +	/* Have to do this *outside* transaction.  */
  30.377 +	xenbus_dev_error(dev, err, "%s", message);
  30.378 +destroy_tpmring:
  30.379 +	destroy_tpmring(info, &my_private);
  30.380 +	goto out;
  30.381 +}
  30.382 +
  30.383 +
  30.384 +static int tpmfront_probe(struct xenbus_device *dev,
  30.385 +                          const struct xenbus_device_id *id)
  30.386 +{
  30.387 +	int err;
  30.388 +	struct tpmfront_info *info;
  30.389 +	int handle;
  30.390 +
  30.391 +	err = xenbus_scanf(dev->nodename,
  30.392 +	                   "handle", "%i", &handle);
  30.393 +	if (XENBUS_EXIST_ERR(err))
  30.394 +		return err;
  30.395 +
  30.396 +	if (err < 0) {
  30.397 +		xenbus_dev_error(dev,err,"reading virtual-device");
  30.398 +		return err;
  30.399 +	}
  30.400 +
  30.401 +	info = kmalloc(sizeof(*info), GFP_KERNEL);
  30.402 +	if (!info) {
  30.403 +		xenbus_dev_error(dev,err,"allocating info structure");
  30.404 +		return err;
  30.405 +	}
  30.406 +	memset(info, 0x0, sizeof(*info));
  30.407 +
  30.408 +	info->dev = dev;
  30.409 +	info->handle = handle;
  30.410 +	dev->data = info;
  30.411 +
  30.412 +	err = talk_to_backend(dev, info);
  30.413 +	if (err) {
  30.414 +		kfree(info);
  30.415 +		dev->data = NULL;
  30.416 +		return err;
  30.417 +	}
  30.418 +
  30.419 +	watch_for_status(&info->watch, info->watch.node);
  30.420 +	return 0;
  30.421 +}
  30.422 +
  30.423 +static int tpmfront_remove(struct xenbus_device *dev)
  30.424 +{
  30.425 +	struct tpmfront_info *info = dev->data;
  30.426 +	if (info->backend)
  30.427 +		unregister_xenbus_watch(&info->watch);
  30.428 +
  30.429 +	destroy_tpmring(info, &my_private);
  30.430 +
  30.431 +	kfree(info->backend);
  30.432 +	kfree(info);
  30.433 +
  30.434 +	return 0;
  30.435 +}
  30.436 +
  30.437 +static int tpmfront_suspend(struct xenbus_device *dev)
  30.438 +{
  30.439 +	struct tpmfront_info *info = dev->data;
  30.440 +	struct tpm_private *tp = &my_private;
  30.441 +
  30.442 +	/* lock so no app can send */
  30.443 +	down(&suspend_lock);
  30.444 +
  30.445 +	while (atomic_read(&tp->tx_busy)) {
  30.446 +		printk("---- TPMIF: Outstanding request.\n");
  30.447 +#if 0
  30.448 +		/*
  30.449 +		 * Would like to wait until the outstanding request
  30.450 +		 * has come back, but this does not work properly, yet.
  30.451 +		 */
  30.452 +		interruptible_sleep_on_timeout(&tp->wait_q,
  30.453 +		                               100);
  30.454 +#else
  30.455 +		break;
  30.456 +#endif
  30.457 +	}
  30.458 +
  30.459 +	unregister_xenbus_watch(&info->watch);
  30.460 +
  30.461 +	kfree(info->backend);
  30.462 +	info->backend = NULL;
  30.463 +
  30.464 +	destroy_tpmring(info, tp);
  30.465 +
  30.466 +	return 0;
  30.467 +}
  30.468 +
  30.469 +static int tpmif_recover(void)
  30.470 +{
  30.471 +	return 0;
  30.472 +}
  30.473 +
  30.474 +static int tpmfront_resume(struct xenbus_device *dev)
  30.475 +{
  30.476 +	struct tpmfront_info *info = dev->data;
  30.477 +	int err;
  30.478 +
  30.479 +	err = talk_to_backend(dev, info);
  30.480 +	if (!err) {
  30.481 +		tpmif_recover();
  30.482 +	}
  30.483 +
  30.484 +	/* unlock so apps can resume */
  30.485 +	up(&suspend_lock);
  30.486 +
  30.487 +	return err;
  30.488 +}
  30.489 +
  30.490 +static void tpmif_connect(u16 evtchn, domid_t domid)
  30.491 +{
  30.492 +	int err = 0;
  30.493 +	struct tpm_private *tp = &my_private;
  30.494 +
  30.495 +	tp->evtchn = evtchn;
  30.496 +	tp->backend_id  = domid;
  30.497 +
  30.498 +	err = bind_evtchn_to_irqhandler(
  30.499 +		tp->evtchn,
  30.500 +		tpmif_int, SA_SAMPLE_RANDOM, "tpmif", tp);
  30.501 +	if ( err != 0 ) {
  30.502 +		WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
  30.503 +		return;
  30.504 +	}
  30.505 +}
  30.506 +
  30.507 +static struct xenbus_device_id tpmfront_ids[] = {
  30.508 +	{ "vtpm" },
  30.509 +	{ "" }
  30.510 +};
  30.511 +
  30.512 +static struct xenbus_driver tpmfront = {
  30.513 +	.name = "vtpm",
  30.514 +	.owner = THIS_MODULE,
  30.515 +	.ids = tpmfront_ids,
  30.516 +	.probe = tpmfront_probe,
  30.517 +	.remove =  tpmfront_remove,
  30.518 +	.resume = tpmfront_resume,
  30.519 +	.suspend = tpmfront_suspend,
  30.520 +};
  30.521 +
  30.522 +static void __init init_tpm_xenbus(void)
  30.523 +{
  30.524 +	xenbus_register_device(&tpmfront);
  30.525 +}
  30.526 +
  30.527 +
  30.528 +static int
  30.529 +tpm_allocate_buffers(struct tpm_private *tp)
  30.530 +{
  30.531 +	unsigned int i;
  30.532 +
  30.533 +	i = 0;
  30.534 +	while (i < TPMIF_TX_RING_SIZE) {
  30.535 +		tp->tx_buffers[i] = tx_buffer_alloc();
  30.536 +		i++;
  30.537 +	}
  30.538 +
  30.539 +	return 1;
  30.540 +}
  30.541 +
  30.542 +static void
  30.543 +tpmif_rx_action(unsigned long unused)
  30.544 +{
  30.545 +	struct tpm_private *tp = &my_private;
  30.546 +
  30.547 +	int i = 0;
  30.548 +	unsigned int received;
  30.549 +	unsigned int offset = 0;
  30.550 +	u8 *buffer;
  30.551 +	tpmif_tx_request_t *tx;
  30.552 +	tx = &tp->tx->ring[i].req;
  30.553 +
  30.554 +	received = tx->size;
  30.555 +
  30.556 +	buffer = kmalloc(received, GFP_KERNEL);
  30.557 +	if (NULL == buffer) {
  30.558 +		goto exit;
  30.559 +	}
  30.560 +
  30.561 +	i = 0;
  30.562 +	while (i < TPMIF_TX_RING_SIZE &&
  30.563 +	       offset < received) {
  30.564 +		struct tx_buffer *txb = tp->tx_buffers[i];
  30.565 +		tpmif_tx_request_t *tx;
  30.566 +		unsigned int tocopy;
  30.567 +
  30.568 +		tx = &tp->tx->ring[i].req;
  30.569 +		tocopy = tx->size;
  30.570 +		if (tocopy > PAGE_SIZE) {
  30.571 +			tocopy = PAGE_SIZE;
  30.572 +		}
  30.573 +
  30.574 +		memcpy(&buffer[offset], txb->data, tocopy);
  30.575 +
  30.576 +		gnttab_release_grant_reference(&gref_head, tx->ref);
  30.577 +
  30.578 +		offset += tocopy;
  30.579 +		i++;
  30.580 +	}
  30.581 +
  30.582 +	tpm_fe_send_upperlayer(buffer, received, tp->tx_remember);
  30.583 +	kfree(buffer);
  30.584 +
  30.585 +exit:
  30.586 +	atomic_set(&tp->tx_busy, 0);
  30.587 +	wake_up_interruptible(&tp->wait_q);
  30.588 +}
  30.589 +
  30.590 +
  30.591 +static irqreturn_t
  30.592 +tpmif_int(int irq, void *tpm_priv, struct pt_regs *ptregs)
  30.593 +{
  30.594 +	struct tpm_private *tp = tpm_priv;
  30.595 +	unsigned long flags;
  30.596 +
  30.597 +	spin_lock_irqsave(&tp->tx_lock, flags);
  30.598 +	tasklet_schedule(&tpmif_rx_tasklet);
  30.599 +	spin_unlock_irqrestore(&tp->tx_lock, flags);
  30.600 +
  30.601 +	return IRQ_HANDLED;
  30.602 +}
  30.603 +
  30.604 +
  30.605 +static int
  30.606 +tpm_xmit(struct tpm_private *tp,
  30.607 +         const u8 * buf, size_t count, int isuserbuffer,
  30.608 +         void *remember)
  30.609 +{
  30.610 +	tpmif_tx_request_t *tx;
  30.611 +	TPMIF_RING_IDX i;
  30.612 +	unsigned int offset = 0;
  30.613 +
  30.614 +	spin_lock_irq(&tp->tx_lock);
  30.615 +
  30.616 +	if (unlikely(atomic_read(&tp->tx_busy))) {
  30.617 +		printk("There's an outstanding request/response on the way!\n");
  30.618 +		spin_unlock_irq(&tp->tx_lock);
  30.619 +		return -EBUSY;
  30.620 +	}
  30.621 +
  30.622 +	if (tp->connected != 1) {
  30.623 +		spin_unlock_irq(&tp->tx_lock);
  30.624 +		return -EIO;
  30.625 +	}
  30.626 +
  30.627 +	i = 0;
  30.628 +	while (count > 0 && i < TPMIF_TX_RING_SIZE) {
  30.629 +		struct tx_buffer *txb = tp->tx_buffers[i];
  30.630 +		int copied;
  30.631 +
  30.632 +		if (NULL == txb) {
  30.633 +			DPRINTK("txb (i=%d) is NULL. buffers initilized?\n", i);
  30.634 +			DPRINTK("Not transmittin anything!\n");
  30.635 +			spin_unlock_irq(&tp->tx_lock);
  30.636 +			return -EFAULT;
  30.637 +		}
  30.638 +		copied = tx_buffer_copy(txb, &buf[offset], count,
  30.639 +		                        isuserbuffer);
  30.640 +		if (copied < 0) {
  30.641 +			/* An error occurred */
  30.642 +			return copied;
  30.643 +		}
  30.644 +		count -= copied;
  30.645 +		offset += copied;
  30.646 +
  30.647 +		tx = &tp->tx->ring[i].req;
  30.648 +
  30.649 +		tx->id = i;
  30.650 +		tx->addr = virt_to_machine(txb->data);
  30.651 +		tx->size = txb->len;
  30.652 +
  30.653 +		DPRINTK("First 4 characters sent by TPM-FE are 0x%02x 0x%02x 0x%02x 0x%02x\n",
  30.654 +		        txb->data[0],txb->data[1],txb->data[2],txb->data[3]);
  30.655 +
  30.656 +		/* get the granttable reference for this page */
  30.657 +		tx->ref = gnttab_claim_grant_reference( &gref_head );
  30.658 +
  30.659 +		if(-ENOSPC == tx->ref ) {
  30.660 +			DPRINTK(" Grant table claim reference failed in func:%s line:%d file:%s\n", __FUNCTION__, __LINE__, __FILE__);
  30.661 +			return -ENOSPC;
  30.662 +		}
  30.663 +		gnttab_grant_foreign_access_ref( tx->ref,
  30.664 +		                                 tp->backend_id,
  30.665 +		                                 (tx->addr >> PAGE_SHIFT),
  30.666 +		                                 0 /*RW*/);
  30.667 +		i++;
  30.668 +		wmb();
  30.669 +	}
  30.670 +
  30.671 +	atomic_set(&tp->tx_busy, 1);
  30.672 +	tp->tx_remember = remember;
  30.673 +	mb();
  30.674 +
  30.675 +	DPRINTK("Notifying backend via event channel %d\n",
  30.676 +	        tp->evtchn);
  30.677 +
  30.678 +	notify_via_evtchn(tp->evtchn);
  30.679 +
  30.680 +	spin_unlock_irq(&tp->tx_lock);
  30.681 +	return offset;
  30.682 +}
  30.683 +
  30.684 +
  30.685 +static void tpmif_notify_upperlayer(struct tpm_private *tp)
  30.686 +{
  30.687 +	/*
  30.688 +	 * Notify upper layer about the state of the connection
  30.689 +	 * to the BE.
  30.690 +	 */
  30.691 +	down(&upperlayer_lock);
  30.692 +
  30.693 +	if (upperlayer_tpmfe != NULL) {
  30.694 +		switch (tp->connected) {
  30.695 +			case 1:
  30.696 +				upperlayer_tpmfe->status(TPMFE_STATUS_CONNECTED);
  30.697 +			break;
  30.698 +
  30.699 +			default:
  30.700 +				upperlayer_tpmfe->status(0);
  30.701 +			break;
  30.702 +		}
  30.703 +	}
  30.704 +	up(&upperlayer_lock);
  30.705 +}
  30.706 +
  30.707 +
  30.708 +static void tpmif_set_connected_state(struct tpm_private *tp, int newstate)
  30.709 +{
  30.710 +	if (newstate != tp->connected) {
  30.711 +		tp->connected = newstate;
  30.712 +		tpmif_notify_upperlayer(tp);
  30.713 +	}
  30.714 +}
  30.715 +
  30.716 +
  30.717 +/* =================================================================
  30.718 + * Initialization function.
  30.719 + * =================================================================
  30.720 + */
  30.721 +
  30.722 +static int __init
  30.723 +tpmif_init(void)
  30.724 +{
  30.725 +	IPRINTK("Initialising the vTPM driver.\n");
  30.726 +	if ( gnttab_alloc_grant_references ( TPMIF_TX_RING_SIZE,
  30.727 +	                                     &gref_head ) < 0) {
  30.728 +		return -EFAULT;
  30.729 +	}
  30.730 +	/*
  30.731 +	 * Only don't send the driver status when we are in the
  30.732 +	 * INIT domain.
  30.733 +	 */
  30.734 +	spin_lock_init(&my_private.tx_lock);
  30.735 +	init_waitqueue_head(&my_private.wait_q);
  30.736 +
  30.737 +	init_tpm_xenbus();
  30.738 +
  30.739 +	return 0;
  30.740 +}
  30.741 +
  30.742 +__initcall(tpmif_init);
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h	Thu Sep 01 10:16:14 2005 +0000
    31.3 @@ -0,0 +1,38 @@
    31.4 +#ifndef TPM_FRONT_H
    31.5 +#define TPM_FRONT_H
    31.6 +
    31.7 +
    31.8 +struct tpm_private {
    31.9 +	tpmif_tx_interface_t *tx;
   31.10 +	unsigned int evtchn;
   31.11 +	int connected;
   31.12 +
   31.13 +	spinlock_t tx_lock;
   31.14 +
   31.15 +	struct tx_buffer *tx_buffers[TPMIF_TX_RING_SIZE];
   31.16 +
   31.17 +	atomic_t tx_busy;
   31.18 +	void *tx_remember;
   31.19 +	domid_t backend_id;
   31.20 +	wait_queue_head_t wait_q;
   31.21 +};
   31.22 +
   31.23 +
   31.24 +struct tpmfront_info
   31.25 +{
   31.26 +	struct xenbus_watch watch;
   31.27 +	int handle;
   31.28 +	struct xenbus_device *dev;
   31.29 +	char *backend;
   31.30 +	int ring_ref;
   31.31 +	domid_t backend_id;
   31.32 +};
   31.33 +
   31.34 +
   31.35 +struct tx_buffer {
   31.36 +	unsigned int size;	// available space in data
   31.37 +	unsigned int len;	// used space in data
   31.38 +	unsigned char *data;    // pointer to a page
   31.39 +};
   31.40 +
   31.41 +#endif
    32.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h	Thu Sep 01 10:08:53 2005 +0000
    32.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h	Thu Sep 01 10:16:14 2005 +0000
    32.3 @@ -561,8 +561,14 @@ do {									\
    32.4  #define local_irq_disable()	__cli()
    32.5  #define local_irq_enable()	__sti()
    32.6  
    32.7 +/* Don't use smp_processor_id: this is called in debug versions of that fn. */
    32.8 +#ifdef CONFIG_SMP
    32.9  #define irqs_disabled()			\
   32.10 -    HYPERVISOR_shared_info->vcpu_data[smp_processor_id()].evtchn_upcall_mask
   32.11 +    HYPERVISOR_shared_info->vcpu_data[__smp_processor_id()].evtchn_upcall_mask
   32.12 +#else
   32.13 +#define irqs_disabled()			\
   32.14 +    HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask
   32.15 +#endif
   32.16  
   32.17  /*
   32.18   * disable hlt during certain critical i/o operations
    33.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h	Thu Sep 01 10:08:53 2005 +0000
    33.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h	Thu Sep 01 10:16:14 2005 +0000
    33.3 @@ -387,8 +387,14 @@ void cpu_idle_wait(void);
    33.4  #define local_irq_disable()	__cli()
    33.5  #define local_irq_enable()	__sti()
    33.6  
    33.7 +/* Don't use smp_processor_id: this is called in debug versions of that fn. */
    33.8 +#ifdef CONFIG_SMP
    33.9  #define irqs_disabled()			\
   33.10 -    HYPERVISOR_shared_info->vcpu_data[smp_processor_id()].evtchn_upcall_mask
   33.11 +    HYPERVISOR_shared_info->vcpu_data[__smp_processor_id()].evtchn_upcall_mask
   33.12 +#else
   33.13 +#define irqs_disabled()			\
   33.14 +    HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask
   33.15 +#endif
   33.16  
   33.17  /*
   33.18   * disable hlt during certain critical i/o operations
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/linux-2.6-xen-sparse/include/linux/tpmfe.h	Thu Sep 01 10:16:14 2005 +0000
    34.3 @@ -0,0 +1,33 @@
    34.4 +#ifndef TPM_FE_H
    34.5 +#define TPM_FE_H
    34.6 +
    34.7 +struct tpmfe_device {
    34.8 +	/*
    34.9 +	 * Let upper layer receive data from front-end
   34.10 +	 */
   34.11 +	int (*receive)(const u8 *buffer, size_t count, const void *ptr);
   34.12 +	/*
   34.13 +	 * Indicate the status of the front-end to the upper
   34.14 +	 * layer.
   34.15 +	 */
   34.16 +	void (*status)(unsigned int flags);
   34.17 +
   34.18 +	/*
   34.19 +	 * This field indicates the maximum size the driver can
   34.20 +	 * transfer in one chunk. It is filled out by the front-end
   34.21 +	 * driver and should be propagated to the generic tpm driver
   34.22 +	 * for allocation of buffers.
   34.23 +	 */
   34.24 +	unsigned int max_tx_size;
   34.25 +};
   34.26 +
   34.27 +enum {
   34.28 +	TPMFE_STATUS_DISCONNECTED = 0x0,
   34.29 +	TPMFE_STATUS_CONNECTED = 0x1
   34.30 +};
   34.31 +
   34.32 +int tpm_fe_send(const u8 * buf, size_t count, void *ptr);
   34.33 +int tpm_fe_register_receiver(struct tpmfe_device *);
   34.34 +void tpm_fe_unregister_receiver(void);
   34.35 +
   34.36 +#endif
    35.1 --- a/tools/Makefile	Thu Sep 01 10:08:53 2005 +0000
    35.2 +++ b/tools/Makefile	Thu Sep 01 10:16:14 2005 +0000
    35.3 @@ -12,8 +12,14 @@ SUBDIRS += xcutils
    35.4  SUBDIRS += firmware
    35.5  SUBDIRS += security
    35.6  SUBDIRS += console
    35.7 +ifeq ($(VTPM_TOOLS),y)
    35.8 +SUBDIRS += vtpm_manager
    35.9 +SUBDIRS += vtpm
   35.10 +endif
   35.11  SUBDIRS += xenstat
   35.12  
   35.13 +.PHONY: all install clean check check_clean ioemu eioemuinstall ioemuclean
   35.14 +
   35.15  # These don't cross-compile
   35.16  ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH))
   35.17  SUBDIRS += python
    36.1 --- a/tools/check/check_curl_devel	Thu Sep 01 10:08:53 2005 +0000
    36.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.3 @@ -1,11 +0,0 @@
    36.4 -#!/bin/bash
    36.5 -# CHECK-BUILD
    36.6 -
    36.7 -function error {
    36.8 -    echo 'Check for libcurl includes failed.'
    36.9 -    exit 1
   36.10 -}
   36.11 -
   36.12 -set -e
   36.13 -[ -e /usr/include/curl ] || error
   36.14 -[ -e /usr/include/curl/curl.h ] || error
   36.15 \ No newline at end of file
    37.1 --- a/tools/check/check_curl_lib	Thu Sep 01 10:08:53 2005 +0000
    37.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.3 @@ -1,10 +0,0 @@
    37.4 -#!/bin/bash
    37.5 -# CHECK-BUILD CHECK-INSTALL
    37.6 -
    37.7 -function error {
    37.8 -        echo 'Check for CURL library failed.'
    37.9 -        exit 1
   37.10 -}
   37.11 -
   37.12 -set -e
   37.13 -ldconfig -p | grep libcurl.so || error
   37.14 \ No newline at end of file
    38.1 --- a/tools/examples/xmexample1	Thu Sep 01 10:08:53 2005 +0000
    38.2 +++ b/tools/examples/xmexample1	Thu Sep 01 10:16:14 2005 +0000
    38.3 @@ -48,6 +48,20 @@ name = "ExampleDomain"
    38.4  disk = [ 'phy:hda1,hda1,w' ]
    38.5  
    38.6  #----------------------------------------------------------------------------
    38.7 +# Define to which TPM instance the user domain should communicate.
    38.8 +# The vtpm entry is of the form 'instance=INSTANCE,backend=DOM'
    38.9 +# where INSTANCE indicates the instance number of the TPM the VM
   38.10 +# should be talking to and DOM provides the domain where the backend
   38.11 +# is located.
   38.12 +# Note that no two virtual machines should try to connect to the same
   38.13 +# TPM instance. The handling of all TPM instances does require
   38.14 +# some management effort in so far that VM configration files (and thus
   38.15 +# a VM) should be associated with a TPM instance throughout the lifetime
   38.16 +# of the VM / VM configuration file. The instance number must be
   38.17 +# greater or equal to 1.
   38.18 +#vtpm = [ 'instance=1,backend=0' ]
   38.19 +
   38.20 +#----------------------------------------------------------------------------
   38.21  # Set the kernel command line for the new domain.
   38.22  # You only need to define the IP parameters and hostname if the domain's
   38.23  # IP config doesn't, e.g. in ifcfg-eth0 or via DHCP.
    39.1 --- a/tools/examples/xmexample2	Thu Sep 01 10:08:53 2005 +0000
    39.2 +++ b/tools/examples/xmexample2	Thu Sep 01 10:16:14 2005 +0000
    39.3 @@ -84,6 +84,20 @@ disk = [ 'phy:sda%d,sda1,w' % (7+vmid),
    39.4           'phy:sda6,sda6,r' ]
    39.5  
    39.6  #----------------------------------------------------------------------------
    39.7 +# Define to which TPM instance the user domain should communicate.
    39.8 +# The vtpm entry is of the form 'instance=INSTANCE,backend=DOM'
    39.9 +# where INSTANCE indicates the instance number of the TPM the VM
   39.10 +# should be talking to and DOM provides the domain where the backend
   39.11 +# is located.
   39.12 +# Note that no two virtual machines should try to connect to the same
   39.13 +# TPM instance. The handling of all TPM instances does require
   39.14 +# some management effort in so far that VM configration files (and thus
   39.15 +# a VM) should be associated with a TPM instance throughout the lifetime
   39.16 +# of the VM / VM configuration file. The instance number must be
   39.17 +# greater or equal to 1.
   39.18 +#vtpm = ['instance=%d,backend=0' % (vmid) ]
   39.19 +
   39.20 +#----------------------------------------------------------------------------
   39.21  # Set the kernel command line for the new domain.
   39.22  # You only need to define the IP parameters and hostname if the domain's
   39.23  # IP config doesn't, e.g. in ifcfg-eth0 or via DHCP.
    40.1 --- a/tools/examples/xmexample3	Thu Sep 01 10:08:53 2005 +0000
    40.2 +++ b/tools/examples/xmexample3	Thu Sep 01 10:16:14 2005 +0000
    40.3 @@ -80,6 +80,20 @@ vif = [ 'ip=192.168.%d.1/24' % (vmid)]
    40.4  disk = [ 'phy:hda%d,hda1,w' % (vmid)]
    40.5  
    40.6  #----------------------------------------------------------------------------
    40.7 +# Define to which TPM instance the user domain should communicate.
    40.8 +# The vtpm entry is of the form 'instance=INSTANCE,backend=DOM'
    40.9 +# where INSTANCE indicates the instance number of the TPM the VM
   40.10 +# should be talking to and DOM provides the domain where the backend
   40.11 +# is located.
   40.12 +# Note that no two virtual machines should try to connect to the same
   40.13 +# TPM instance. The handling of all TPM instances does require
   40.14 +# some management effort in so far that VM configration files (and thus
   40.15 +# a VM) should be associated with a TPM instance throughout the lifetime
   40.16 +# of the VM / VM configuration file. The instance number must be
   40.17 +# greater or equal to 1.
   40.18 +#vtpm = ['instance=%d,backend=0' % (vmid) ]
   40.19 +
   40.20 +#----------------------------------------------------------------------------
   40.21  # Set the kernel command line for the new domain.
   40.22  # You only need to define the IP parameters and hostname if the domain's
   40.23  # IP config doesn't, e.g. in ifcfg-eth0 or via DHCP.
    41.1 --- a/tools/libxc/xc_private.c	Thu Sep 01 10:08:53 2005 +0000
    41.2 +++ b/tools/libxc/xc_private.c	Thu Sep 01 10:16:14 2005 +0000
    41.3 @@ -422,3 +422,8 @@ int xc_dom0_op(int xc_handle, dom0_op_t 
    41.4  {
    41.5      return do_dom0_op(xc_handle, op);
    41.6  }
    41.7 +
    41.8 +int xc_version(int xc_handle, int cmd, void *arg)
    41.9 +{
   41.10 +    return do_xen_version(xc_handle, cmd, arg);
   41.11 +}
    42.1 --- a/tools/libxc/xc_private.h	Thu Sep 01 10:08:53 2005 +0000
    42.2 +++ b/tools/libxc/xc_private.h	Thu Sep 01 10:16:14 2005 +0000
    42.3 @@ -59,6 +59,17 @@ static inline int do_xen_hypercall(int x
    42.4                        (unsigned long)hypercall);
    42.5  }
    42.6  
    42.7 +static inline int do_xen_version(int xc_handle, int cmd, void *dest)
    42.8 +{
    42.9 +    privcmd_hypercall_t hypercall;
   42.10 +
   42.11 +    hypercall.op     = __HYPERVISOR_xen_version;
   42.12 +    hypercall.arg[0] = (unsigned long) cmd;
   42.13 +    hypercall.arg[1] = (unsigned long) dest;
   42.14 +    
   42.15 +    return do_xen_hypercall(xc_handle, &hypercall);
   42.16 +}
   42.17 +
   42.18  static inline int do_dom0_op(int xc_handle, dom0_op_t *op)
   42.19  {
   42.20      int ret = -1;
    43.1 --- a/tools/libxc/xenctrl.h	Thu Sep 01 10:08:53 2005 +0000
    43.2 +++ b/tools/libxc/xenctrl.h	Thu Sep 01 10:16:14 2005 +0000
    43.3 @@ -23,6 +23,7 @@ typedef int64_t            s64;
    43.4  #include <sys/ptrace.h>
    43.5  #include <xen/xen.h>
    43.6  #include <xen/dom0_ops.h>
    43.7 +#include <xen/version.h>
    43.8  #include <xen/event_channel.h>
    43.9  #include <xen/sched_ctl.h>
   43.10  #include <xen/acm.h>
   43.11 @@ -497,6 +498,8 @@ long xc_get_tot_pages(int xc_handle, u32
   43.12  /* Execute a privileged dom0 operation. */
   43.13  int xc_dom0_op(int xc_handle, dom0_op_t *op);
   43.14  
   43.15 +int xc_version(int xc_handle, int cmd, void *arg);
   43.16 +
   43.17  /* Initializes the store (for dom0)
   43.18     remote_port should be the remote end of a bound interdomain channel between
   43.19     the store and dom0.
    44.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Thu Sep 01 10:08:53 2005 +0000
    44.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Thu Sep 01 10:16:14 2005 +0000
    44.3 @@ -707,6 +707,39 @@ static PyObject *pyxc_physinfo(PyObject 
    44.4                           "cpu_khz",          info.cpu_khz);
    44.5  }
    44.6  
    44.7 +static PyObject *pyxc_xeninfo(PyObject *self,
    44.8 +                              PyObject *args,
    44.9 +                              PyObject *kwds)
   44.10 +{
   44.11 +    XcObject *xc = (XcObject *)self;
   44.12 +    xen_extraversion_t xen_extra;
   44.13 +    xen_compile_info_t xen_cc;
   44.14 +    xen_changeset_info_t xen_chgset;
   44.15 +    long xen_version;
   44.16 +
   44.17 +    xen_version = xc_version(xc->xc_handle, XENVER_version, NULL);
   44.18 +
   44.19 +    if ( xc_version(xc->xc_handle, XENVER_extraversion, &xen_extra) != 0 )
   44.20 +        return PyErr_SetFromErrno(xc_error);
   44.21 +
   44.22 +    if ( xc_version(xc->xc_handle, XENVER_compile_info, &xen_cc) != 0 )
   44.23 +        return PyErr_SetFromErrno(xc_error);
   44.24 +
   44.25 +    if ( xc_version(xc->xc_handle, XENVER_changeset, &xen_chgset) != 0 )
   44.26 +        return PyErr_SetFromErrno(xc_error);
   44.27 +
   44.28 +    return Py_BuildValue("{s:i,s:i,s:s,s:s,s:s,s:s,s:s,s:s}",
   44.29 +                         "xen_major", xen_version >> 16,
   44.30 +                         "xen_minor", (xen_version & 0xffff),
   44.31 +                         "xen_extra", xen_extra,
   44.32 +                         "xen_changeset", xen_chgset,
   44.33 +                         "cc_compiler", xen_cc.compiler,
   44.34 +                         "cc_compile_by", xen_cc.compile_by,
   44.35 +                         "cc_compile_domain", xen_cc.compile_domain,
   44.36 +                         "cc_compile_date", xen_cc.compile_date);
   44.37 +}
   44.38 +
   44.39 +
   44.40  static PyObject *pyxc_sedf_domain_set(PyObject *self,
   44.41                                           PyObject *args,
   44.42                                           PyObject *kwds)
   44.43 @@ -1089,6 +1122,13 @@ static PyMethodDef pyxc_methods[] = {
   44.44        "Returns [dict]: information about the hardware"
   44.45        "        [None]: on failure.\n" },
   44.46  
   44.47 +    { "xeninfo",
   44.48 +      (PyCFunction)pyxc_xeninfo,
   44.49 +      METH_VARARGS, "\n"
   44.50 +      "Get information about the Xen host\n"
   44.51 +      "Returns [dict]: information about Xen"
   44.52 +      "        [None]: on failure.\n" },
   44.53 +
   44.54      { "shadow_control", 
   44.55        (PyCFunction)pyxc_shadow_control, 
   44.56        METH_VARARGS | METH_KEYWORDS, "\n"
    45.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Thu Sep 01 10:08:53 2005 +0000
    45.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Thu Sep 01 10:16:14 2005 +0000
    45.3 @@ -269,6 +269,7 @@ class XendDomainInfo:
    45.4          self.blkif_backend = False
    45.5          self.netif_backend = False
    45.6          self.netif_idx = 0
    45.7 +        self.tpmif_backend = False
    45.8          
    45.9          #todo: state: running, suspended
   45.10          self.state = STATE_VM_OK
   45.11 @@ -458,6 +459,31 @@ class XendDomainInfo:
   45.12  
   45.13              return
   45.14          
   45.15 +        if type == 'vtpm':
   45.16 +            backdom = domain_exists(sxp.child_value(devconfig, 'backend', '0'))
   45.17 +
   45.18 +            devnum = int(sxp.child_value(devconfig, 'instance', '0'))
   45.19 +            log.error("The domain has a TPM with instance %d." % devnum)
   45.20 +
   45.21 +            # create backend db
   45.22 +            backdb = backdom.db.addChild("/backend/%s/%s/%d" %
   45.23 +                                         (type, self.uuid, devnum))
   45.24 +            # create frontend db
   45.25 +            db = self.db.addChild("/device/%s/%d" % (type, devnum))
   45.26 +
   45.27 +            backdb['frontend'] = db.getPath()
   45.28 +            backdb['frontend-id'] = "%i" % self.id
   45.29 +            backdb['instance'] = sxp.child_value(devconfig, 'instance', '0')
   45.30 +            backdb.saveDB(save=True)
   45.31 +
   45.32 +            db['handle'] = "%i" % devnum
   45.33 +            db['backend'] = backdb.getPath()
   45.34 +            db['backend-id'] = "%i" % int(sxp.child_value(devconfig,
   45.35 +                                                          'backend', '0'))
   45.36 +            db.saveDB(save=True)
   45.37 +
   45.38 +            return
   45.39 +
   45.40          ctrl = self.findDeviceController(type)
   45.41          return ctrl.createDevice(devconfig, recreate=self.recreate,
   45.42                                   change=change)
   45.43 @@ -779,6 +805,11 @@ class XendDomainInfo:
   45.44                  for dev in typedb.keys():
   45.45                      typedb[dev].delete()
   45.46                  typedb.saveDB(save=True)
   45.47 +            if type == 'vtpm':
   45.48 +                typedb = ddb.addChild(type)
   45.49 +                for dev in typedb.keys():
   45.50 +                    typedb[dev].delete()
   45.51 +                typedb.saveDB(save=True)
   45.52  
   45.53      def show(self):
   45.54          """Print virtual machine info.
   45.55 @@ -1018,6 +1049,8 @@ class XendDomainInfo:
   45.56                  self.netif_backend = True
   45.57              elif name == 'usbif':
   45.58                  self.usbif_backend = True
   45.59 +            elif name == 'tpmif':
   45.60 +                self.tpmif_backend = True
   45.61              else:
   45.62                  raise VmError('invalid backend type:' + str(name))
   45.63  
   45.64 @@ -1189,6 +1222,10 @@ from server import netif
   45.65  controller.addDevControllerClass("vif", netif.NetifController)
   45.66  add_device_handler("vif", "vif")
   45.67  
   45.68 +from server import tpmif
   45.69 +controller.addDevControllerClass("vtpm", tpmif.TPMifController)
   45.70 +add_device_handler("vtpm", "vtpm")
   45.71 +
   45.72  from server import pciif
   45.73  controller.addDevControllerClass("pci", pciif.PciController)
   45.74  add_device_handler("pci", "pci")
    46.1 --- a/tools/python/xen/xend/XendNode.py	Thu Sep 01 10:08:53 2005 +0000
    46.2 +++ b/tools/python/xen/xend/XendNode.py	Thu Sep 01 10:16:14 2005 +0000
    46.3 @@ -46,7 +46,7 @@ class XendNode:
    46.4          return self.xc.bvtsched_global_get()
    46.5      
    46.6      def info(self):
    46.7 -        return self.nodeinfo() + self.physinfo()
    46.8 +        return self.nodeinfo() + self.physinfo() + self.xeninfo()
    46.9  
   46.10      def nodeinfo(self):
   46.11          (sys, host, rel, ver, mch) = os.uname()
   46.12 @@ -65,7 +65,16 @@ class XendNode:
   46.13                  ['free_memory', pinfo['free_pages']/256]]
   46.14          return info
   46.15          
   46.16 -        
   46.17 +    def xeninfo(self):
   46.18 +        xinfo = self.xc.xeninfo()
   46.19 +	return [['xen_major', xinfo['xen_major']],
   46.20 +	        ['xen_minor', xinfo['xen_minor']],
   46.21 +	        ['xen_extra', xinfo['xen_extra']],
   46.22 +		['xen_changeset', xinfo['xen_changeset']],
   46.23 +		['cc_compiler', xinfo['cc_compiler']],
   46.24 +                ['cc_compile_by', xinfo['cc_compile_by']],
   46.25 +                ['cc_compile_domain', xinfo['cc_compile_domain']],
   46.26 +                ['cc_compile_date', xinfo['cc_compile_date']]]
   46.27  
   46.28  def instance():
   46.29      global inst
    47.1 --- a/tools/python/xen/xend/image.py	Thu Sep 01 10:08:53 2005 +0000
    47.2 +++ b/tools/python/xen/xend/image.py	Thu Sep 01 10:16:14 2005 +0000
    47.3 @@ -32,6 +32,9 @@ SIF_BLK_BE_DOMAIN = (1<<4)
    47.4  """Flag for a net device backend domain."""
    47.5  SIF_NET_BE_DOMAIN = (1<<5)
    47.6  
    47.7 +"""Flag for a TPM device backend domain."""
    47.8 +SIF_TPM_BE_DOMAIN = (1<<7)
    47.9 +
   47.10  class ImageHandler:
   47.11      """Abstract base class for image handlers.
   47.12  
   47.13 @@ -194,6 +197,7 @@ class ImageHandler:
   47.14          self.flags = 0
   47.15          if self.vm.netif_backend: self.flags |= SIF_NET_BE_DOMAIN
   47.16          if self.vm.blkif_backend: self.flags |= SIF_BLK_BE_DOMAIN
   47.17 +        if self.vm.tpmif_backend: self.flags |= SIF_TPM_BE_DOMAIN
   47.18  
   47.19          if self.vm.recreate or self.vm.restore:
   47.20              return
   47.21 @@ -366,6 +370,11 @@ class VmxImageHandler(ImageHandler):
   47.22                 mac = sxp.child_value(vifinfo, 'mac')
   47.23                 ret.append("-macaddr")
   47.24                 ret.append("%s" % mac)
   47.25 +            if name == 'vtpm':
   47.26 +               vtpminfo = sxp.child(device, 'vtpm')
   47.27 +               instance = sxp.child_value(vtpminfo, 'instance')
   47.28 +               ret.append("-instance")
   47.29 +               ret.append("%s" % instance)
   47.30  
   47.31  	# Handle graphics library related options
   47.32  	vnc = sxp.child_value(self.vm.config, 'vnc')
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/tools/python/xen/xend/server/tpmif.py	Thu Sep 01 10:16:14 2005 +0000
    48.3 @@ -0,0 +1,52 @@
    48.4 +# Copyright (C) 2005 IBM Corporation
    48.5 +#   Authort: Stefan Berger, stefanb@us.ibm.com
    48.6 +# Derived from netif.py:
    48.7 +# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    48.8 +"""Support for virtual TPM interfaces.
    48.9 +"""
   48.10 +
   48.11 +import random
   48.12 +
   48.13 +from xen.xend import sxp
   48.14 +from xen.xend.XendError import XendError, VmError
   48.15 +from xen.xend.XendLogging import log
   48.16 +from xen.xend.XendRoot import get_component
   48.17 +from xen.xend.xenstore import DBVar
   48.18 +
   48.19 +from xen.xend.server import channel
   48.20 +from xen.xend.server.controller import CtrlMsgRcvr, Dev, DevController
   48.21 +from xen.xend.server.messages import *
   48.22 +
   48.23 +class TPMifController(DevController):
   48.24 +    """TPM interface controller. Handles all TPM devices for a domain.
   48.25 +    """
   48.26 +
   48.27 +    def __init__(self, vm, recreate=False):
   48.28 +        DevController.__init__(self, vm, recreate=recreate)
   48.29 +        self.rcvr = None
   48.30 +        self.channel = None
   48.31 +
   48.32 +    def initController(self, recreate=False, reboot=False):
   48.33 +        self.destroyed = False
   48.34 +        self.channel = self.getChannel()
   48.35 +
   48.36 +    def destroyController(self, reboot=False):
   48.37 +        """Destroy the controller and all devices.
   48.38 +        """
   48.39 +        self.destroyed = True
   48.40 +        self.destroyDevices(reboot=reboot)
   48.41 +        if self.rcvr:
   48.42 +            self.rcvr.deregisterChannel()
   48.43 +
   48.44 +    def sxpr(self):
   48.45 +        val = ['tpmif', ['dom', self.getDomain()]]
   48.46 +        return val
   48.47 +
   48.48 +    def newDevice(self, id, config, recreate=False):
   48.49 +        """Create a TPM device.
   48.50 +
   48.51 +        @param id: interface id
   48.52 +        @param config: device configuration
   48.53 +        @param recreate: recreate flag (true after xend restart)
   48.54 +        """
   48.55 +        return None
    49.1 --- a/tools/python/xen/xm/create.py	Thu Sep 01 10:08:53 2005 +0000
    49.2 +++ b/tools/python/xen/xm/create.py	Thu Sep 01 10:16:14 2005 +0000
    49.3 @@ -176,6 +176,12 @@ gopts.var('netif', val='no|yes',
    49.4            fn=set_bool, default=0,
    49.5            use="Make the domain a network interface backend.")
    49.6  
    49.7 +gopts.var('tpmif', val='frontend=DOM',
    49.8 +          fn=append_value, default=[],
    49.9 +          use="""Make the domain a TPM interface backend. If frontend is given,
   49.10 +          the frontend in that domain is connected to this backend (not
   49.11 +          completely implemented, yet)""")
   49.12 +
   49.13  gopts.var('disk', val='phy:DEV,VDEV,MODE[,DOM]',
   49.14            fn=append_value, default=[],
   49.15            use="""Add a disk device to a domain. The physical device is DEV,
   49.16 @@ -214,6 +220,12 @@ gopts.var('vif', val="mac=MAC,be_mac=MAC
   49.17            This option may be repeated to add more than one vif.
   49.18            Specifying vifs will increase the number of interfaces as needed.""")
   49.19  
   49.20 +gopts.var('vtpm', val="instance=INSTANCE,backend=DOM",
   49.21 +          fn=append_value, default=[],
   49.22 +          use="""Add a tpm interface. On the backend side us the the given
   49.23 +          instance as virtual TPM instance. Use the backend in the given
   49.24 +          domain.""")
   49.25 +
   49.26  gopts.var('nics', val="NUM",
   49.27            fn=set_int, default=1,
   49.28            use="""Set the number of network interfaces.
   49.29 @@ -374,6 +386,46 @@ def configure_usb(opts, config_devs, val
   49.30          config_usb = ['usb', ['path', path]]
   49.31          config_devs.append(['device', config_usb])
   49.32  
   49.33 +def configure_vtpm(opts, config_devs, vals):
   49.34 +    """Create the config for virtual TPM interfaces.
   49.35 +    """
   49.36 +    vtpm = vals.vtpm
   49.37 +    vtpm_n = 1
   49.38 +    for idx in range(0, vtpm_n):
   49.39 +        if idx < len(vtpm):
   49.40 +            d = vtpm[idx]
   49.41 +            instance = d.get('instance')
   49.42 +            if instance == "VTPMD":
   49.43 +                instance = "0"
   49.44 +            else:
   49.45 +                try:
   49.46 +                    if int(instance) == 0:
   49.47 +                        opts.err('VM config error: vTPM instance must not be 0.')
   49.48 +                except ValueError:
   49.49 +                    opts.err('Vm config error: could not parse instance number.')
   49.50 +            backend = d.get('backend')
   49.51 +            config_vtpm = ['vtpm']
   49.52 +            if instance:
   49.53 +                config_vtpm.append(['instance', instance])
   49.54 +            if backend:
   49.55 +                config_vtpm.append(['backend', backend])
   49.56 +            config_devs.append(['device', config_vtpm])
   49.57 +
   49.58 +def configure_tpmif(opts, config_devs, vals):
   49.59 +    """Create the config for virtual TPM interfaces.
   49.60 +    """
   49.61 +    tpmif = vals.tpmif
   49.62 +    tpmif_n = 1
   49.63 +    for idx in range(0, tpmif_n):
   49.64 +        if idx < len(tpmif):
   49.65 +            d = tpmif[idx]
   49.66 +            frontend = d.get('frontend')
   49.67 +            config_tpmif = ['tpmif']
   49.68 +            if frontend:
   49.69 +                config_tpmif.append(['frontend', frontend])
   49.70 +            config_devs.append(['device', config_tpmif])
   49.71 +
   49.72 +
   49.73  def randomMAC():
   49.74      """Generate a random MAC address.
   49.75  
   49.76 @@ -484,6 +536,8 @@ def make_config(opts, vals):
   49.77          config.append(['backend', ['blkif']])
   49.78      if vals.netif:
   49.79          config.append(['backend', ['netif']])
   49.80 +    if vals.tpmif:
   49.81 +        config.append(['backend', ['tpmif']])
   49.82      if vals.restart:
   49.83          config.append(['restart', vals.restart])
   49.84  
   49.85 @@ -496,6 +550,7 @@ def make_config(opts, vals):
   49.86      configure_pci(opts, config_devs, vals)
   49.87      configure_vifs(opts, config_devs, vals)
   49.88      configure_usb(opts, config_devs, vals)
   49.89 +    configure_vtpm(opts, config_devs, vals)
   49.90      configure_vmx(opts, config_devs, vals)
   49.91      config += config_devs
   49.92  
   49.93 @@ -544,6 +599,38 @@ def preprocess_vifs(opts, vals):
   49.94          vifs.append(d)
   49.95      vals.vif = vifs
   49.96  
   49.97 +def preprocess_vtpm(opts, vals):
   49.98 +    if not vals.vtpm: return
   49.99 +    vtpms = []
  49.100 +    for vtpm in vals.vtpm:
  49.101 +        d = {}
  49.102 +        a = vtpm.split(',')
  49.103 +        for b in a:
  49.104 +            (k, v) = b.strip().split('=', 1)
  49.105 +            k = k.strip()
  49.106 +            v = v.strip()
  49.107 +            if k not in ['backend', 'instance']:
  49.108 +                opts.err('Invalid vtpm specifier: ' + vtpm)
  49.109 +            d[k] = v
  49.110 +        vtpms.append(d)
  49.111 +    vals.vtpm = vtpms
  49.112 +
  49.113 +def preprocess_tpmif(opts, vals):
  49.114 +    if not vals.tpmif: return
  49.115 +    tpmifs = []
  49.116 +    for tpmif in vals.tpmif:
  49.117 +        d = {}
  49.118 +        a = tpmif.split(',')
  49.119 +        for b in a:
  49.120 +            (k, v) = b.strip().split('=', 1)
  49.121 +            k = k.strip()
  49.122 +            v = v.strip()
  49.123 +            if k not in ['frontend']:
  49.124 +                opts.err('Invalid tpmif specifier: ' + vtpm)
  49.125 +            d[k] = v
  49.126 +        tpmifs.append(d)
  49.127 +    vals.tpmif = tpmifs
  49.128 +
  49.129  def preprocess_ip(opts, vals):
  49.130      if vals.ip or vals.dhcp != 'off':
  49.131          dummy_nfs_server = '1.2.3.4'
  49.132 @@ -632,6 +719,8 @@ def preprocess(opts, vals):
  49.133      preprocess_ip(opts, vals)
  49.134      preprocess_nfs(opts, vals)
  49.135      preprocess_vnc(opts, vals)
  49.136 +    preprocess_vtpm(opts, vals)
  49.137 +    preprocess_tpmif(opts, vals)
  49.138           
  49.139  def make_domain(opts, config):
  49.140      """Create, build and start a domain.
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/tools/vtpm/Makefile	Thu Sep 01 10:16:14 2005 +0000
    50.3 @@ -0,0 +1,63 @@
    50.4 +XEN_ROOT = ../..
    50.5 +
    50.6 +# Base definitions and rules
    50.7 +include $(XEN_ROOT)/tools/vtpm/Rules.mk
    50.8 +
    50.9 +# Dir name for emulator (as dom0 tpm driver)
   50.10 +TPM_EMULATOR_DIR = tpm_emulator-0.2
   50.11 +# Dir name for vtpm instance
   50.12 +VTPM_DIR = vtpm
   50.13 +
   50.14 +# Emulator tarball name
   50.15 +TPM_EMULATOR_TARFILE = tpm_emulator-0.2b.tar.gz
   50.16 +
   50.17 +all: build
   50.18 +
   50.19 +build: $(TPM_EMULATOR_TARFILE) extract patch build_sub
   50.20 +
   50.21 +install: build
   50.22 +	$(MAKE) -C $(TPM_EMULATOR_DIR) $@
   50.23 +	$(MAKE) -C $(VTPM_DIR) $@
   50.24 +
   50.25 +clean:
   50.26 +	if [ -d $(TPM_EMULATOR_DIR) ]; \
   50.27 +		then $(MAKE) -C $(TPM_EMULATOR_DIR) clean; \
   50.28 +	fi
   50.29 +	if [ -d $(VTPM_DIR) ]; \
   50.30 +		then $(MAKE) -C $(VTPM_DIR) clean; \
   50.31 +	fi
   50.32 +	rm -rf $(TPM_EMULATOR_DIR)
   50.33 +	rm -rf $(VTPM_DIR)
   50.34 +
   50.35 +mrproper: clean
   50.36 +	rm -f $(TPM_EMULATOR_TARFILE)
   50.37 +
   50.38 +# Download Swiss emulator
   50.39 +$(TPM_EMULATOR_TARFILE):
   50.40 +	wget http://download.berlios.de/tpm-emulator/$(TPM_EMULATOR_TARFILE)
   50.41 +
   50.42 +# Create vtpm and TPM emulator dirs
   50.43 +extract: $(TPM_EMULATOR_DIR)/README $(VTPM_DIR)/README
   50.44 +
   50.45 +$(TPM_EMULATOR_DIR)/README:
   50.46 +	-rm -rf $(TPM_EMULATOR_DIR)
   50.47 +	tar -xzf $(TPM_EMULATOR_TARFILE)
   50.48 +
   50.49 +$(VTPM_DIR)/README:
   50.50 +	-rm -rf $(VTPM_DIR)
   50.51 +	cp -r --preserve $(TPM_EMULATOR_DIR) $(VTPM_DIR)
   50.52 +
   50.53 +# apply patches for 1) used as dom0 tpm driver 2) used as vtpm device instance
   50.54 +patch: $(TPM_EMULATOR_DIR)/Makefile $(VTPM_DIR)/Makefile
   50.55 +
   50.56 +$(TPM_EMULATOR_DIR)/Makefile: tpm_emulator.patch
   50.57 +	-cd $(TPM_EMULATOR_DIR); \
   50.58 +	patch -p1 <../tpm_emulator.patch
   50.59 +
   50.60 +$(VTPM_DIR)/Makefile: vtpm.patch
   50.61 +	-cd $(VTPM_DIR); \
   50.62 +	patch -p1 <../vtpm.patch
   50.63 +
   50.64 +build_sub:
   50.65 +	$(MAKE) -C $(TPM_EMULATOR_DIR)
   50.66 +	$(MAKE) -C $(VTPM_DIR)
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/tools/vtpm/README	Thu Sep 01 10:16:14 2005 +0000
    51.3 @@ -0,0 +1,44 @@
    51.4 +
    51.5 +Directory Structure
    51.6 +===================
    51.7 +tools/vtpm/tpm_emulator-0.2b.tar.gz    -> TPM Emulator downloaded at build time that will
    51.8 +                                          be patched and used for our vtpms
    51.9 +tools/vtpm/vtpm.patch                  -> patch applied to tpm_emulator to make vtpm
   51.10 +tools/vtpm/vtpm/                       -> (created on build) tpm_emulator moved to ring 3,
   51.11 +                                          listens on a pair of fifos for TPM commands,
   51.12 +                                          persistent state is sent via named fifo to vtpm
   51.13 +                                            manager, which encrypts it and protects it.
   51.14 +tools/vtpm/tpm_emulator.patch          -> To allow for debugging and testing on non-TPM
   51.15 +                                          platforms, this patches the emulator to allow
   51.16 +                                          it to be inserted into the dom0 kernel
   51.17 +tools/vtpm/tpm_emulator-0.2            -> (created on build) directory containing patched emulator
   51.18 +
   51.19 +Compile Flags
   51.20 +===================
   51.21 +VTPM_MULTI_VM                -> Defined (not finished): VTPMs run in their own VMs
   51.22 +                                Not Defined (default): VTPMs are processes
   51.23 +
   51.24 +Requirements
   51.25 +============
   51.26 +- xen-unstable 
   51.27 +- IBM frontend/backend vtpm driver patch
   51.28 +- vtpm_managerd
   51.29 +
   51.30 +vtpmd Flow (for vtpm_manager. vtpmd never run by default)
   51.31 +============================
   51.32 +- Launch the VTPM manager (vtpm_managerd) which which begins listening to the BE with one thread
   51.33 +  and listens to a named fifo that is shared by the vtpms to commuincate with the manager.
   51.34 +- VTPM Manager listens to TPM BE.
   51.35 +- When xend launches a tpm frontend equipped VM it contacts the manager over the vtpm backend. 
   51.36 +- When the manager receives the open message from the BE, it launches a vtpm
   51.37 +- Xend allows the VM to continue booting. 
   51.38 +- When a TPM request is issued to the front end, the front end transmits the TPM request to the backend.
   51.39 +- The manager receives the TPM requests and uses a named fifo to forward the request to the vtpm.
   51.40 +- The fifo listener begins listening for the reply from vtpm for the request.
   51.41 +- Vtpm processes request and replies to manager over shared named fifo.
   51.42 +- If needed, the vtpm may send a request to the vtpm_manager at any time to save it's secrets to disk.
   51.43 +- Manager receives response from vtpm and passes it back to backend for forwarding to guest.
   51.44 +
   51.45 +tpm_emulator flow
   51.46 +==================
   51.47 +Read documentation in tpm_emulator-0.2 directory
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/tools/vtpm/Rules.mk	Thu Sep 01 10:16:14 2005 +0000
    52.3 @@ -0,0 +1,37 @@
    52.4 +# Base definitions and rules (XEN_ROOT must be defined in including Makefile)
    52.5 +include $(XEN_ROOT)/tools/Rules.mk
    52.6 +
    52.7 +#
    52.8 +# Tool definitions
    52.9 +#
   52.10 +
   52.11 +# Installation program and options
   52.12 +INSTALL         = install
   52.13 +INSTALL_PROG    = $(INSTALL) -m0755
   52.14 +INSTALL_DIR     = $(INSTALL) -d -m0755
   52.15 +
   52.16 +# Xen tools installation directory
   52.17 +TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
   52.18 +
   52.19 +# General compiler flags
   52.20 +CFLAGS   = -Wall -Werror -g3 -I.
   52.21 +
   52.22 +# For generating dependencies
   52.23 +CFLAGS	+= -Wp,-MD,.$(@F).d
   52.24 +
   52.25 +DEP_FILES	= .*.d
   52.26 +
   52.27 +# Generic project files
   52.28 +HDRS	= $(wildcard *.h)
   52.29 +SRCS	= $(wildcard *.c)
   52.30 +OBJS	= $(patsubst %.c,%.o,$(SRCS))
   52.31 +
   52.32 +# Generic (non-header) dependencies
   52.33 +$(SRCS): Makefile $(XEN_ROOT)/tools/Rules.mk $(XEN_ROOT)/tools/vtpm/Rules.mk
   52.34 +
   52.35 +$(OBJS): $(SRCS)
   52.36 +
   52.37 +-include $(DEP_FILES)
   52.38 +
   52.39 +# Make sure these are just rules
   52.40 +.PHONY : all build install clean
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/tools/vtpm/tpm_emulator.patch	Thu Sep 01 10:16:14 2005 +0000
    53.3 @@ -0,0 +1,151 @@
    53.4 +diff -uprN orig/tpm_emulator-0.2/AUTHORS tpm_emulator-0.2/AUTHORS
    53.5 +--- orig/tpm_emulator-0.2/AUTHORS	2005-08-17 10:58:36.000000000 -0700
    53.6 ++++ tpm_emulator-0.2/AUTHORS	2005-08-17 10:55:52.000000000 -0700
    53.7 +@@ -1 +1,2 @@
    53.8 + Mario Strasser <mast@gmx.net>
    53.9 ++INTEL Corp <>
   53.10 +diff -uprN orig/tpm_emulator-0.2/ChangeLog tpm_emulator-0.2/ChangeLog
   53.11 +--- orig/tpm_emulator-0.2/ChangeLog	2005-08-17 10:58:36.000000000 -0700
   53.12 ++++ tpm_emulator-0.2/ChangeLog	2005-08-17 10:55:52.000000000 -0700
   53.13 +@@ -1,3 +1,7 @@
   53.14 ++2005-08-16: INTEL Corp
   53.15 ++	* Set default permissions to PCRs
   53.16 ++	* Changed device to /dev/tpm0
   53.17 ++
   53.18 + 2005-08-15  Mario Strasser <mast@gmx.net>
   53.19 + 	* all: some typos corrected
   53.20 + 	* tpm_integrity.c: bug in TPM_Extend fixed
   53.21 +diff -uprN orig/tpm_emulator-0.2/Makefile tpm_emulator-0.2/Makefile
   53.22 +--- orig/tpm_emulator-0.2/Makefile	2005-08-17 10:58:36.000000000 -0700
   53.23 ++++ tpm_emulator-0.2/Makefile	2005-08-17 10:55:52.000000000 -0700
   53.24 +@@ -1,15 +1,19 @@
   53.25 + # Software-Based Trusted Platform Module (TPM) Emulator for Linux
   53.26 + # Copyright (C) 2004 Mario Strasser <mast@gmx.net>
   53.27 ++# Copyright (C) 2005 INTEL Corp.
   53.28 + #
   53.29 + # $Id: Makefile 10 2005-04-26 20:59:50Z mast $
   53.30 + 
   53.31 ++XEN_ROOT       := ../../..
   53.32 ++EUID           := $(shell id -u)
   53.33 ++
   53.34 + # kernel settings
   53.35 + KERNEL_RELEASE := $(shell uname -r)
   53.36 +-KERNEL_BUILD   := /lib/modules/$(KERNEL_RELEASE)/build
   53.37 ++KERNEL_BUILD   := $(XEN_ROOT)/linux-2.6.12-xen0
   53.38 + MOD_SUBDIR     := misc
   53.39 + 
   53.40 + # module settings
   53.41 +-MODULE_NAME    := tpm_emulator
   53.42 ++BIN            := tpm_emulator
   53.43 + VERSION_MAJOR  := 0
   53.44 + VERSION_MINOR  := 2
   53.45 + VERSION_BUILD  := $(shell date +"%s")
   53.46 +@@ -27,11 +30,9 @@ DIRS           := . crypto tpm 
   53.47 + SRCS           := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c))
   53.48 + OBJS           := $(patsubst %.c, %.o, $(SRCS))
   53.49 + SRCS           += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h))
   53.50 +-DISTSRC        := ./README ./AUTHORS ./ChangeLog ./Makefile $(SRCS)
   53.51 +-DISTDIR        := tpm_emulator-$(VERSION_MAJOR).$(VERSION_MINOR)
   53.52 + 
   53.53 +-obj-m               := $(MODULE_NAME).o
   53.54 +-$(MODULE_NAME)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
   53.55 ++obj-m               := $(BIN).o
   53.56 ++$(BIN)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
   53.57 + 
   53.58 + EXTRA_CFLAGS   += -I$(src) -I$(src)/crypto -I$(src)/tpm 
   53.59 + 
   53.60 +@@ -42,23 +43,17 @@ all:	$(src)/crypto/gmp.h $(src)/crypto/l
   53.61 + 	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
   53.62 + 
   53.63 + install:
   53.64 +-	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules_install
   53.65 +-	test -d /var/tpm || mkdir /var/tpm
   53.66 +-	test -c /dev/tpm || mknod /dev/tpm c 10 224
   53.67 +-	chmod 666 /dev/tpm
   53.68 +-	depmod -a
   53.69 ++	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) INSTALL_MOD_PATH=$(DESTDIR) modules_install
   53.70 ++	test -d $(DESTDIR)/var/tpm || mkdir $(DESTDIR)/var/tpm
   53.71 ++	test -d $(DESTDIR)/dev || mkdir $(DESTDIR)/dev
   53.72 ++	test -c $(DESTDIR)/dev/tpm0 || [ $(EUID) -ne 0 ] || mknod $(DESTDIR)/dev/tpm0 c 10 224
   53.73 ++	[ $(EUID) -ne 0 ] || chmod 666 $(DESTDIR)/dev/tpm0
   53.74 + 
   53.75 + clean:
   53.76 + 	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
   53.77 + 	rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a
   53.78 + 
   53.79 +-dist:	$(DISTSRC)
   53.80 +-	rm -rf $(DISTDIR)
   53.81 +-	mkdir $(DISTDIR)
   53.82 +-	cp --parents $(DISTSRC) $(DISTDIR)/
   53.83 +-	rm -f $(DISTDIR)/crypto/gmp.h 
   53.84 +-	tar -chzf $(DISTDIR).tar.gz $(DISTDIR)
   53.85 +-	rm -rf $(DISTDIR)
   53.86 ++mrproper: clean
   53.87 + 
   53.88 + $(src)/crypto/libgmp.a:
   53.89 + 	test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB) $(src)/crypto/libgmp.a
   53.90 +diff -uprN orig/tpm_emulator-0.2/README tpm_emulator-0.2/README
   53.91 +--- orig/tpm_emulator-0.2/README	2005-08-17 10:58:36.000000000 -0700
   53.92 ++++ tpm_emulator-0.2/README	2005-08-17 10:55:52.000000000 -0700
   53.93 +@@ -13,7 +13,8 @@ $Id: README 8 2005-01-25 21:11:45Z jmoli
   53.94 + Copyright
   53.95 + --------------------------------------------------------------------------
   53.96 + Copyright (C) 2004 Mario Strasser <mast@gmx.net> and Swiss Federal 
   53.97 +-Institute of Technology (ETH) Zurich.
   53.98 ++                   Institute of Technology (ETH) Zurich.
   53.99 ++Copyright (C) 2005 
  53.100 +               
  53.101 + This program is free software; you can redistribute it and/or modify
  53.102 + it under the terms of the GNU General Public License as published by
  53.103 +diff -uprN orig/tpm_emulator-0.2/linux_module.h tpm_emulator-0.2/linux_module.h
  53.104 +--- orig/tpm_emulator-0.2/linux_module.h	2005-08-17 10:58:36.000000000 -0700
  53.105 ++++ tpm_emulator-0.2/linux_module.h	2005-08-17 10:55:52.000000000 -0700
  53.106 +@@ -1,5 +1,6 @@
  53.107 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  53.108 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  53.109 ++ * Copyright (C) 2005 INTEL Corp.
  53.110 +  *
  53.111 +  * This module is free software; you can redistribute it and/or modify
  53.112 +  * it under the terms of the GNU General Public License as published
  53.113 +@@ -33,7 +34,7 @@
  53.114 + #include "tpm_version.h"
  53.115 + 
  53.116 + #define TPM_DEVICE_MINOR	224
  53.117 +-#define TPM_DEVICE_NAME         "tpm"
  53.118 ++#define TPM_DEVICE_NAME         "tpm0"
  53.119 + #define TPM_MODULE_NAME 	"tpm_emulator"
  53.120 + 
  53.121 + /* debug and log output functions */
  53.122 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_data.c tpm_emulator-0.2/tpm/tpm_data.c
  53.123 +--- orig/tpm_emulator-0.2/tpm/tpm_data.c	2005-08-17 10:58:36.000000000 -0700
  53.124 ++++ tpm_emulator-0.2/tpm/tpm_data.c	2005-08-17 10:55:52.000000000 -0700
  53.125 +@@ -1,6 +1,7 @@
  53.126 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  53.127 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  53.128 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
  53.129 ++ * Copyright (C) 2005 INTEL Corp
  53.130 +  *
  53.131 +  * This module is free software; you can redistribute it and/or modify
  53.132 +  * it under the terms of the GNU General Public License as published
  53.133 +@@ -85,6 +86,11 @@ void tpm_init_data(void)
  53.134 +   tpmData.permanent.data.version.revMinor = VERSION_MINOR;
  53.135 +   /* setup PCR attributes */
  53.136 +   for (i = 0; i < TPM_NUM_PCR; i++) {
  53.137 ++    int j;
  53.138 ++    for (j=0; j < TPM_NUM_LOCALITY; j++) {
  53.139 ++      tpmData.permanent.data.pcrAttrib[i].pcrExtendLocal[j] = TRUE;
  53.140 ++    }
  53.141 ++
  53.142 +     tpmData.permanent.data.pcrAttrib[i].pcrReset = TRUE;
  53.143 +   }
  53.144 +   /* set tick type */
  53.145 +diff -uprN orig/tpm_emulator-0.2/tpm_version.h tpm_emulator-0.2/tpm_version.h
  53.146 +--- orig/tpm_emulator-0.2/tpm_version.h	2005-08-17 10:58:36.000000000 -0700
  53.147 ++++ tpm_emulator-0.2/tpm_version.h	2005-08-17 10:55:53.000000000 -0700
  53.148 +@@ -2,5 +2,5 @@
  53.149 + #define _TPM_VERSION_H_
  53.150 + #define VERSION_MAJOR 0
  53.151 + #define VERSION_MINOR 2
  53.152 +-#define VERSION_BUILD 1123950310
  53.153 ++#define VERSION_BUILD 1124301353
  53.154 + #endif /* _TPM_VERSION_H_ */
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/tools/vtpm/vtpm.patch	Thu Sep 01 10:16:14 2005 +0000
    54.3 @@ -0,0 +1,1645 @@
    54.4 +diff -uprN orig/tpm_emulator-0.2/AUTHORS vtpm/AUTHORS
    54.5 +--- orig/tpm_emulator-0.2/AUTHORS	2005-08-17 10:58:36.000000000 -0700
    54.6 ++++ vtpm/AUTHORS	2005-08-17 10:55:52.000000000 -0700
    54.7 +@@ -1 +1,2 @@
    54.8 + Mario Strasser <mast@gmx.net>
    54.9 ++INTEL Corp <>
   54.10 +diff -uprN orig/tpm_emulator-0.2/ChangeLog vtpm/ChangeLog
   54.11 +--- orig/tpm_emulator-0.2/ChangeLog	2005-08-17 10:58:36.000000000 -0700
   54.12 ++++ vtpm/ChangeLog	2005-08-17 10:55:52.000000000 -0700
   54.13 +@@ -1,3 +1,7 @@
   54.14 ++2005-08-16 Intel Corp
   54.15 ++	Moved module out of kernel to run as a ring 3 app
   54.16 ++	Modified save_to_file and load_from_file to call a xen backend driver to call a VTPM manager
   54.17 ++
   54.18 + 2005-08-15  Mario Strasser <mast@gmx.net>
   54.19 + 	* all: some typos corrected
   54.20 + 	* tpm_integrity.c: bug in TPM_Extend fixed
   54.21 +diff -uprN orig/tpm_emulator-0.2/Makefile vtpm/Makefile
   54.22 +--- orig/tpm_emulator-0.2/Makefile	2005-08-17 10:58:36.000000000 -0700
   54.23 ++++ vtpm/Makefile	2005-08-17 10:55:52.000000000 -0700
   54.24 +@@ -1,21 +1,29 @@
   54.25 + # Software-Based Trusted Platform Module (TPM) Emulator for Linux
   54.26 + # Copyright (C) 2004 Mario Strasser <mast@gmx.net>
   54.27 ++# Copyright (C) 2005 INTEL Corp.
   54.28 + #
   54.29 + # $Id: Makefile 10 2005-04-26 20:59:50Z mast $
   54.30 + 
   54.31 +-# kernel settings
   54.32 +-KERNEL_RELEASE := $(shell uname -r)
   54.33 +-KERNEL_BUILD   := /lib/modules/$(KERNEL_RELEASE)/build
   54.34 +-MOD_SUBDIR     := misc
   54.35 +-
   54.36 + # module settings
   54.37 +-MODULE_NAME    := tpm_emulator
   54.38 ++BIN            := vtpmd
   54.39 + VERSION_MAJOR  := 0
   54.40 + VERSION_MINOR  := 2
   54.41 + VERSION_BUILD  := $(shell date +"%s")
   54.42 + 
   54.43 +-# enable/disable DEBUG messages
   54.44 +-EXTRA_CFLAGS   += -DDEBUG -g  
   54.45 ++# Installation program and options
   54.46 ++INSTALL         = install
   54.47 ++INSTALL_PROG    = $(INSTALL) -m0755
   54.48 ++INSTALL_DIR     = $(INSTALL) -d -m0755
   54.49 ++
   54.50 ++# Xen tools installation directory
   54.51 ++TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
   54.52 ++
   54.53 ++CC      := gcc
   54.54 ++CFLAGS  += -g -Wall $(INCLUDE) -DDEBUG
   54.55 ++CFLAGS  += -I. -Itpm
   54.56 ++
   54.57 ++# Is the simulator running in it's own vm?
   54.58 ++#CFLAGS += -DVTPM_MULTI_VM
   54.59 + 
   54.60 + # GNU MP configuration
   54.61 + GMP_LIB        := /usr/lib/libgmp.a
   54.62 +@@ -27,38 +35,31 @@ DIRS           := . crypto tpm 
   54.63 + SRCS           := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c))
   54.64 + OBJS           := $(patsubst %.c, %.o, $(SRCS))
   54.65 + SRCS           += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h))
   54.66 +-DISTSRC        := ./README ./AUTHORS ./ChangeLog ./Makefile $(SRCS)
   54.67 +-DISTDIR        := tpm_emulator-$(VERSION_MAJOR).$(VERSION_MINOR)
   54.68 + 
   54.69 +-obj-m               := $(MODULE_NAME).o
   54.70 +-$(MODULE_NAME)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
   54.71 ++obj-m               := $(BIN)
   54.72 ++$(BIN)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
   54.73 + 
   54.74 + EXTRA_CFLAGS   += -I$(src) -I$(src)/crypto -I$(src)/tpm 
   54.75 + 
   54.76 + # do not print "Entering directory ..."
   54.77 + MAKEFLAGS      += --no-print-directory
   54.78 + 
   54.79 +-all:	$(src)/crypto/gmp.h $(src)/crypto/libgmp.a version
   54.80 +-	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
   54.81 ++all: $(BIN)
   54.82 ++
   54.83 ++$(BIN):	$(src)/crypto/gmp.h $(src)/crypto/libgmp.a version $(SRCS) $(OBJS)
   54.84 ++	$(CC) $(CFLAGS) $(OBJS) $(src)/crypto/libgmp.a -o $(BIN)
   54.85 ++
   54.86 ++%.o: %.c
   54.87 ++	$(CC) $(CFLAGS) -c $< -o $@
   54.88 + 
   54.89 + install:
   54.90 +-	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules_install
   54.91 +-	test -d /var/tpm || mkdir /var/tpm
   54.92 +-	test -c /dev/tpm || mknod /dev/tpm c 10 224
   54.93 +-	chmod 666 /dev/tpm
   54.94 +-	depmod -a
   54.95 ++	$(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR)
   54.96 + 
   54.97 + clean:
   54.98 +-	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
   54.99 +-	rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a
  54.100 ++	rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a $(OBJS)
  54.101 + 
  54.102 +-dist:	$(DISTSRC)
  54.103 +-	rm -rf $(DISTDIR)
  54.104 +-	mkdir $(DISTDIR)
  54.105 +-	cp --parents $(DISTSRC) $(DISTDIR)/
  54.106 +-	rm -f $(DISTDIR)/crypto/gmp.h 
  54.107 +-	tar -chzf $(DISTDIR).tar.gz $(DISTDIR)
  54.108 +-	rm -rf $(DISTDIR)
  54.109 ++mrproper: clean
  54.110 ++	rm -f $(BIN)
  54.111 + 
  54.112 + $(src)/crypto/libgmp.a:
  54.113 + 	test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB) $(src)/crypto/libgmp.a
  54.114 +diff -uprN orig/tpm_emulator-0.2/README vtpm/README
  54.115 +--- orig/tpm_emulator-0.2/README	2005-08-17 10:58:36.000000000 -0700
  54.116 ++++ vtpm/README	2005-08-17 10:55:52.000000000 -0700
  54.117 +@@ -13,7 +13,8 @@ $Id: README 8 2005-01-25 21:11:45Z jmoli
  54.118 + Copyright
  54.119 + --------------------------------------------------------------------------
  54.120 + Copyright (C) 2004 Mario Strasser <mast@gmx.net> and Swiss Federal 
  54.121 +-Institute of Technology (ETH) Zurich.
  54.122 ++                   Institute of Technology (ETH) Zurich.
  54.123 ++Copyright (C) 2005 INTEL Corp 
  54.124 +               
  54.125 + This program is free software; you can redistribute it and/or modify
  54.126 + it under the terms of the GNU General Public License as published by
  54.127 +diff -uprN orig/tpm_emulator-0.2/crypto/gmp_kernel_wrapper.c vtpm/crypto/gmp_kernel_wrapper.c
  54.128 +--- orig/tpm_emulator-0.2/crypto/gmp_kernel_wrapper.c	2005-08-17 10:58:36.000000000 -0700
  54.129 ++++ vtpm/crypto/gmp_kernel_wrapper.c	2005-08-17 10:55:52.000000000 -0700
  54.130 +@@ -1,5 +1,6 @@
  54.131 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  54.132 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  54.133 ++ * Copyright (C) 2005 INTEL Corp
  54.134 +  *
  54.135 +  * This module is free software; you can redistribute it and/or modify
  54.136 +  * it under the terms of the GNU General Public License as published
  54.137 +@@ -24,15 +25,10 @@ int __gmp_junk;
  54.138 + void __attribute__ ((regparm(0))) __gmp_assert_fail(const char *filename, 
  54.139 +   int linenum, const char *expr) 
  54.140 + {
  54.141 +-  panic(KERN_CRIT TPM_MODULE_NAME "%s:%d: GNU MP assertion failed: %s\n", 
  54.142 ++  error("%s:%d: GNU MP assertion failed: %s\n", 
  54.143 +     filename, linenum, expr);
  54.144 + }
  54.145 + 
  54.146 +-void __attribute__ ((regparm(0))) abort(void)
  54.147 +-{
  54.148 +-  panic(KERN_CRIT TPM_MODULE_NAME "GNU MP abort() was called\n");
  54.149 +-}
  54.150 +-
  54.151 + /* overwrite GNU MP random functions (used by mpz/millerrabin.c) */ 
  54.152 + 
  54.153 + void __attribute__ ((regparm(0))) gmp_randinit(gmp_randstate_t rstate, 
  54.154 +@@ -77,20 +73,19 @@ void __attribute__ ((regparm(0))) mpz_ur
  54.155 + 
  54.156 + void __attribute__ ((regparm(0))) *kernel_allocate(size_t size)
  54.157 + {
  54.158 +-  void *ret  = (void*)kmalloc(size, GFP_KERNEL);
  54.159 +-  if (!ret) panic(KERN_CRIT TPM_MODULE_NAME 
  54.160 +-    "GMP: cannot allocate memory (size=%u)\n", size);
  54.161 ++  void *ret  = (void*)malloc(size);
  54.162 ++  if (!ret) error("GMP: cannot allocate memory (size=%u)\n", size);
  54.163 +   return ret;
  54.164 + }
  54.165 + 
  54.166 + void __attribute__ ((regparm(0))) *kernel_reallocate(void *oldptr, 
  54.167 +   size_t old_size, size_t new_size)
  54.168 + {
  54.169 +-  void *ret = (void*)kmalloc(new_size, GFP_KERNEL);
  54.170 +-  if (!ret) panic(KERN_CRIT TPM_MODULE_NAME "GMP: Cannot reallocate memory "
  54.171 ++  void *ret = (void*)malloc(new_size);
  54.172 ++  if (!ret) error("GMP: Cannot reallocate memory "
  54.173 +     "(old_size=%u new_size=%u)\n", old_size, new_size);
  54.174 +   memcpy(ret, oldptr, old_size);
  54.175 +-  kfree(oldptr);
  54.176 ++  free(oldptr);
  54.177 +   return ret;
  54.178 + }
  54.179 + 
  54.180 +@@ -99,7 +94,7 @@ void __attribute__ ((regparm(0))) kernel
  54.181 +   /* overwrite used memory */
  54.182 +   if (blk_ptr != NULL) { 
  54.183 +     memset(blk_ptr, 0, blk_size);
  54.184 +-    kfree(blk_ptr);
  54.185 ++    free(blk_ptr);
  54.186 +   }
  54.187 + }
  54.188 + 
  54.189 +diff -uprN orig/tpm_emulator-0.2/crypto/rsa.c vtpm/crypto/rsa.c
  54.190 +--- orig/tpm_emulator-0.2/crypto/rsa.c	2005-08-17 10:58:36.000000000 -0700
  54.191 ++++ vtpm/crypto/rsa.c	2005-08-17 10:55:52.000000000 -0700
  54.192 +@@ -1,5 +1,6 @@
  54.193 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  54.194 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  54.195 ++ * Copyright (C) 2005 INTEL Corp
  54.196 +  *
  54.197 +  * This module is free software; you can redistribute it and/or modify
  54.198 +  * it under the terms of the GNU General Public License as published
  54.199 +@@ -363,7 +364,7 @@ static int encode_message(int type, uint
  54.200 +       msg[0] = 0x00;
  54.201 +       get_random_bytes(&msg[1], SHA1_DIGEST_LENGTH);
  54.202 +       sha1_init(&ctx);
  54.203 +-      sha1_update(&ctx, "TCPA", 4);
  54.204 ++      sha1_update(&ctx, (uint8_t *) "TCPA", 4);
  54.205 +       sha1_final(&ctx, &msg[1 + SHA1_DIGEST_LENGTH]);
  54.206 +       memset(&msg[1 + 2 * SHA1_DIGEST_LENGTH], 0x00, 
  54.207 +         msg_len - data_len - 2 * SHA1_DIGEST_LENGTH - 2);
  54.208 +@@ -411,7 +412,7 @@ static int decode_message(int type, uint
  54.209 +       mask_generation(&msg[1], SHA1_DIGEST_LENGTH,
  54.210 +         &msg[1 + SHA1_DIGEST_LENGTH], msg_len - SHA1_DIGEST_LENGTH - 1);
  54.211 +       sha1_init(&ctx);
  54.212 +-      sha1_update(&ctx, "TCPA", 4);
  54.213 ++      sha1_update(&ctx, (uint8_t *) "TCPA", 4);
  54.214 +       sha1_final(&ctx, &msg[1]);
  54.215 +       if (memcmp(&msg[1], &msg[1 + SHA1_DIGEST_LENGTH], 
  54.216 +           SHA1_DIGEST_LENGTH) != 0) return -1;
  54.217 +diff -uprN orig/tpm_emulator-0.2/linux_module.c vtpm/linux_module.c
  54.218 +--- orig/tpm_emulator-0.2/linux_module.c	2005-08-17 10:58:36.000000000 -0700
  54.219 ++++ vtpm/linux_module.c	1969-12-31 16:00:00.000000000 -0800
  54.220 +@@ -1,163 +0,0 @@
  54.221 +-/* Software-Based Trusted Platform Module (TPM) Emulator for Linux 
  54.222 +- * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  54.223 +- *
  54.224 +- * This module is free software; you can redistribute it and/or modify 
  54.225 +- * it under the terms of the GNU General Public License as published 
  54.226 +- * by the Free Software Foundation; either version 2 of the License, 
  54.227 +- * or (at your option) any later version.  
  54.228 +- *
  54.229 +- * This module is distributed in the hope that it will be useful, 
  54.230 +- * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  54.231 +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  54.232 +- * GNU General Public License for more details.
  54.233 +- *
  54.234 +- * $Id: linux_module.c 19 2005-05-18 08:29:37Z mast $
  54.235 +- */
  54.236 +-
  54.237 +-#include <linux/module.h>
  54.238 +-#include <linux/kernel.h>
  54.239 +-#include <linux/init.h>
  54.240 +-#include <linux/miscdevice.h>
  54.241 +-#include <linux/poll.h>
  54.242 +-#include "linux_module.h"
  54.243 +-#include "tpm/tpm_emulator.h"
  54.244 +-
  54.245 +-MODULE_LICENSE("GPL");
  54.246 +-MODULE_AUTHOR("Mario Strasser <mast@gmx.net>");
  54.247 +-MODULE_DESCRIPTION("Trusted Platform Module (TPM) Emulator");
  54.248 +-MODULE_SUPPORTED_DEVICE(TPM_DEVICE_NAME);
  54.249 +-
  54.250 +-/* module startup parameters */
  54.251 +-char *startup = "save";
  54.252 +-MODULE_PARM(startup, "s");
  54.253 +-MODULE_PARM_DESC(startup, " Sets the startup mode of the TPM. "
  54.254 +-  "Possible values are 'clear', 'save' (default) and 'deactivated.");
  54.255 +-char *storage_file = "/var/tpm/tpm_emulator-1.2.0.1";
  54.256 +-MODULE_PARM(storage_file, "s");
  54.257 +-MODULE_PARM_DESC(storage_file, " Sets the persistent-data storage " 
  54.258 +-  "file of the TPM.");
  54.259 +-
  54.260 +-/* TPM lock */
  54.261 +-static struct semaphore tpm_mutex;
  54.262 +-
  54.263 +-/* TPM command response */
  54.264 +-static struct {
  54.265 +-  uint8_t *data;
  54.266 +-  uint32_t size;
  54.267 +-} tpm_response;
  54.268 +-
  54.269 +-/* module state */
  54.270 +-#define STATE_IS_OPEN 0
  54.271 +-static uint32_t module_state;
  54.272 +-
  54.273 +-static int tpm_open(struct inode *inode, struct file *file)
  54.274 +-{
  54.275 +-  debug("%s()", __FUNCTION__);
  54.276 +-  if (test_and_set_bit(STATE_IS_OPEN, (void*)&module_state)) return -EBUSY;
  54.277 +-  return 0;
  54.278 +-}
  54.279 +-
  54.280 +-static int tpm_release(struct inode *inode, struct file *file)
  54.281 +-{
  54.282 +-  debug("%s()", __FUNCTION__);
  54.283 +-  clear_bit(STATE_IS_OPEN, (void*)&module_state);
  54.284 +-  return 0;
  54.285 +-}
  54.286 +-
  54.287 +-static ssize_t tpm_read(struct file *file, char *buf, size_t count, loff_t *ppos)
  54.288 +-{
  54.289 +-  debug("%s(%d)", __FUNCTION__, count);
  54.290 +-  down(&tpm_mutex);
  54.291 +-  if (tpm_response.data != NULL) {
  54.292 +-    count = min(count, (size_t)tpm_response.size - (size_t)*ppos);
  54.293 +-    count -= copy_to_user(buf, &tpm_response.data[*ppos], count);
  54.294 +-    *ppos += count;
  54.295 +-  } else {
  54.296 +-    count = 0;
  54.297 +-  }
  54.298 +-  up(&tpm_mutex);
  54.299 +-  return count;
  54.300 +-}
  54.301 +-
  54.302 +-static ssize_t tpm_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
  54.303 +-{
  54.304 +-  debug("%s(%d)", __FUNCTION__, count);
  54.305 +-  down(&tpm_mutex);
  54.306 +-  *ppos = 0;
  54.307 +-  if (tpm_response.data != NULL) kfree(tpm_response.data);
  54.308 +-  if (tpm_handle_command(buf, count, &tpm_response.data, 
  54.309 +-                         &tpm_response.size) != 0) { 
  54.310 +-    count = -EILSEQ;
  54.311 +-    tpm_response.data = NULL;
  54.312 +-  }
  54.313 +-  up(&tpm_mutex);
  54.314 +-  return count;
  54.315 +-}
  54.316 +-
  54.317 +-static int tpm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  54.318 +-{
  54.319 +-  debug("%s(%d, %ld)", __FUNCTION__, cmd, arg);
  54.320 +-  return -1;
  54.321 +-}
  54.322 +-
  54.323 +-struct file_operations fops = {
  54.324 +-  .owner   = THIS_MODULE,
  54.325 +-  .open    = tpm_open,
  54.326 +-  .release = tpm_release,
  54.327 +-  .read    = tpm_read,
  54.328 +-  .write   = tpm_write,
  54.329 +-  .ioctl   = tpm_ioctl,
  54.330 +-};
  54.331 +-
  54.332 +-static struct miscdevice tpm_dev = {
  54.333 +-  .minor      = TPM_DEVICE_MINOR, 
  54.334 +-  .name       = TPM_DEVICE_NAME, 
  54.335 +-  .fops       = &fops,
  54.336 +-};
  54.337 +-
  54.338 +-int __init init_tpm_module(void)
  54.339 +-{
  54.340 +-  int res = misc_register(&tpm_dev);
  54.341 +-  if (res != 0) {
  54.342 +-    error("misc_register() failed for minor %d\n", TPM_DEVICE_MINOR);
  54.343 +-    return res;
  54.344 +-  }
  54.345 +-  /* initialize variables */
  54.346 +-  sema_init(&tpm_mutex, 1);
  54.347 +-  module_state = 0;
  54.348 +-  tpm_response.data = NULL;    
  54.349 +-  /* initialize TPM emulator */
  54.350 +-  if (!strcmp(startup, "clear")) {
  54.351 +-    tpm_emulator_init(1);
  54.352 +-  } else if (!strcmp(startup, "save")) { 
  54.353 +-    tpm_emulator_init(2);
  54.354 +-  } else if (!strcmp(startup, "deactivated")) {
  54.355 +-    tpm_emulator_init(3);
  54.356 +-  } else {
  54.357 +-    error("invalid startup mode '%s'; must be 'clear', "
  54.358 +-      "'save' (default) or 'deactivated", startup);
  54.359 +-    misc_deregister(&tpm_dev);
  54.360 +-    return -EINVAL;
  54.361 +-  }
  54.362 +-  return 0;
  54.363 +-}
  54.364 +-
  54.365 +-void __exit cleanup_tpm_module(void)
  54.366 +-{
  54.367 +-  tpm_emulator_shutdown();
  54.368 +-  misc_deregister(&tpm_dev);
  54.369 +-}
  54.370 +-
  54.371 +-module_init(init_tpm_module);
  54.372 +-module_exit(cleanup_tpm_module);
  54.373 +-
  54.374 +-uint64_t tpm_get_ticks(void)
  54.375 +-{
  54.376 +-  static struct timespec old_time = {0, 0}; 
  54.377 +-  struct timespec new_time = current_kernel_time();
  54.378 +-  uint64_t ticks = (uint64_t)(old_time.tv_sec - new_time.tv_sec) * 1000000
  54.379 +-                   + (old_time.tv_nsec - new_time.tv_nsec) / 1000;
  54.380 +-  old_time = new_time;
  54.381 +-  return (ticks > 0) ? ticks : 1;
  54.382 +-}
  54.383 +-
  54.384 +diff -uprN orig/tpm_emulator-0.2/linux_module.h vtpm/linux_module.h
  54.385 +--- orig/tpm_emulator-0.2/linux_module.h	2005-08-17 10:58:36.000000000 -0700
  54.386 ++++ vtpm/linux_module.h	2005-08-17 10:55:52.000000000 -0700
  54.387 +@@ -1,5 +1,6 @@
  54.388 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  54.389 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  54.390 ++ * Copyright (C) 2005 INTEL Corp
  54.391 +  *
  54.392 +  * This module is free software; you can redistribute it and/or modify
  54.393 +  * it under the terms of the GNU General Public License as published
  54.394 +@@ -17,17 +18,22 @@
  54.395 + #ifndef _LINUX_MODULE_H_
  54.396 + #define _LINUX_MODULE_H_
  54.397 + 
  54.398 +-#include <linux/version.h>
  54.399 +-#include <linux/kernel.h>
  54.400 +-#include <linux/slab.h>
  54.401 ++#include <malloc.h>
  54.402 ++#include <stdint.h>
  54.403 ++#include <stdio.h>
  54.404 ++#include <string.h>
  54.405 + #include <linux/types.h>
  54.406 +-#include <linux/string.h>
  54.407 +-#include <linux/random.h>
  54.408 +-#include <linux/time.h>
  54.409 +-#include <asm/byteorder.h>
  54.410 + 
  54.411 +-/* module settings */
  54.412 ++#include <endian.h>
  54.413 ++#define __BYTEORDER_HAS_U64__
  54.414 ++#ifdef LITTLE_ENDIAN
  54.415 ++ #include <linux/byteorder/little_endian.h>
  54.416 ++#else
  54.417 ++ #include <linux/byteorder/big_endian.h>
  54.418 ++#endif
  54.419 + 
  54.420 ++/* module settings */
  54.421 ++#define min(A,B) ((A)<(B)?(A):(B))
  54.422 + #define STR(s) __STR__(s)
  54.423 + #define __STR__(s) #s
  54.424 + #include "tpm_version.h"
  54.425 +@@ -39,32 +45,35 @@
  54.426 + /* debug and log output functions */
  54.427 + 
  54.428 + #ifdef DEBUG
  54.429 +-#define debug(fmt, ...) printk(KERN_DEBUG "%s %s:%d: Debug: " fmt "\n", \
  54.430 +-                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
  54.431 ++#define debug(fmt, ...) printf("%s:%d: Debug: " fmt "\n", \
  54.432 ++                        __FILE__, __LINE__, ## __VA_ARGS__)
  54.433 + #else
  54.434 + #define debug(fmt, ...) 
  54.435 + #endif
  54.436 +-#define info(fmt, ...)  printk(KERN_INFO "%s %s:%d: Info: " fmt "\n", \
  54.437 +-                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
  54.438 +-#define error(fmt, ...) printk(KERN_ERR "%s %s:%d: Error: " fmt "\n", \
  54.439 +-                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
  54.440 +-#define alert(fmt, ...) printk(KERN_ALERT "%s %s:%d: Alert: " fmt "\n", \
  54.441 +-                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
  54.442 ++#define info(fmt, ...)  printf("%s:%d: Info: " fmt "\n", \
  54.443 ++                        __FILE__, __LINE__, ## __VA_ARGS__)
  54.444 ++#define error(fmt, ...) printf("%s:%d: Error: " fmt "\n", \
  54.445 ++                        __FILE__, __LINE__, ## __VA_ARGS__)
  54.446 ++#define alert(fmt, ...) printf("%s:%d: Alert: " fmt "\n", \
  54.447 ++                        __FILE__, __LINE__, ## __VA_ARGS__)
  54.448 + 
  54.449 + /* memory allocation */
  54.450 + 
  54.451 + static inline void *tpm_malloc(size_t size) 
  54.452 + {
  54.453 +-  return kmalloc(size, GFP_KERNEL);  
  54.454 ++  return malloc(size);  
  54.455 + }
  54.456 + 
  54.457 + static inline void tpm_free(const void *ptr)
  54.458 + {
  54.459 +-  if (ptr != NULL) kfree(ptr);
  54.460 ++  if (ptr != NULL) free( (void *) ptr);
  54.461 + }
  54.462 + 
  54.463 + /* random numbers */
  54.464 + 
  54.465 ++//FIXME;
  54.466 ++void get_random_bytes(void *buf, int nbytes);
  54.467 ++
  54.468 + static inline void tpm_get_random_bytes(void *buf, int nbytes)
  54.469 + {
  54.470 +   get_random_bytes(buf, nbytes);
  54.471 +@@ -84,9 +93,9 @@ uint64_t tpm_get_ticks(void);
  54.472 + #define CPU_TO_LE16(x) __cpu_to_le16(x)
  54.473 + 
  54.474 + #define BE64_TO_CPU(x) __be64_to_cpu(x)
  54.475 +-#define LE64_TO_CPU(x) __be64_to_cpu(x)
  54.476 ++#define LE64_TO_CPU(x) __le64_to_cpu(x)
  54.477 + #define BE32_TO_CPU(x) __be32_to_cpu(x)
  54.478 +-#define LE32_TO_CPU(x) __be32_to_cpu(x)
  54.479 ++#define LE32_TO_CPU(x) __le32_to_cpu(x)
  54.480 + #define BE16_TO_CPU(x) __be16_to_cpu(x)
  54.481 + #define LE16_TO_CPU(x) __le16_to_cpu(x)
  54.482 + 
  54.483 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_audit.c vtpm/tpm/tpm_audit.c
  54.484 +--- orig/tpm_emulator-0.2/tpm/tpm_audit.c	2005-08-17 10:58:36.000000000 -0700
  54.485 ++++ vtpm/tpm/tpm_audit.c	2005-08-17 10:55:52.000000000 -0700
  54.486 +@@ -1,6 +1,7 @@
  54.487 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  54.488 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  54.489 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
  54.490 ++ * Copyright (C) 2005 INTEL Corp
  54.491 +  *
  54.492 +  * This module is free software; you can redistribute it and/or modify
  54.493 +  * it under the terms of the GNU General Public License as published
  54.494 +@@ -45,14 +46,14 @@ void tpm_audit_request(TPM_COMMAND_CODE 
  54.495 +       tpmData.permanent.data.auditMonotonicCounter++;
  54.496 +     }
  54.497 +     /* update audit digest */
  54.498 +-    *((UINT16*)&buf[0])  = cpu_to_be16(TPM_TAG_AUDIT_EVENT_IN);
  54.499 +-    *((UINT32*)&buf[2]) = cpu_to_be32(ordinal);
  54.500 ++    *((UINT16*)&buf[0])  = CPU_TO_BE16(TPM_TAG_AUDIT_EVENT_IN);
  54.501 ++    *((UINT32*)&buf[2]) = CPU_TO_BE32(ordinal);
  54.502 +     sha1_init(&sha1_ctx);
  54.503 +     sha1_update(&sha1_ctx, req->param, req->paramSize);
  54.504 +     sha1_final(&sha1_ctx, &buf[6]);
  54.505 +-    *((UINT16*)&buf[26])  = cpu_to_be16(TPM_TAG_COUNTER_VALUE);
  54.506 ++    *((UINT16*)&buf[26])  = CPU_TO_BE16(TPM_TAG_COUNTER_VALUE);
  54.507 +     memset(&buf[30], 0, 4);
  54.508 +-    *((UINT32*)&buf[34]) = cpu_to_be32(tpmData.permanent.data.auditMonotonicCounter);
  54.509 ++    *((UINT32*)&buf[34]) = CPU_TO_BE32(tpmData.permanent.data.auditMonotonicCounter);
  54.510 +     sha1_init(&sha1_ctx);
  54.511 +     sha1_update(&sha1_ctx, tpmData.stany.data.auditDigest.digest, 
  54.512 +       sizeof(TPM_DIGEST));
  54.513 +@@ -70,15 +71,15 @@ void tpm_audit_response(TPM_COMMAND_CODE
  54.514 +       && (AUDIT_STATUS[ord / 8] & (1 << (ord & 0x07)))) {
  54.515 +     info("tpm_audit_response()");
  54.516 +     /* update audit digest */
  54.517 +-    *((UINT16*)&buf[0])  = cpu_to_be16(TPM_TAG_AUDIT_EVENT_OUT);
  54.518 +-    *((UINT32*)&buf[2]) = cpu_to_be32(ordinal);
  54.519 ++    *((UINT16*)&buf[0])  = CPU_TO_BE16(TPM_TAG_AUDIT_EVENT_OUT);
  54.520 ++    *((UINT32*)&buf[2]) = CPU_TO_BE32(ordinal);
  54.521 +     sha1_init(&sha1_ctx);
  54.522 +     sha1_update(&sha1_ctx, rsp->param, rsp->paramSize);
  54.523 +     sha1_final(&sha1_ctx, &buf[6]);
  54.524 +-    *((UINT16*)&buf[26])  = cpu_to_be16(TPM_TAG_COUNTER_VALUE);
  54.525 ++    *((UINT16*)&buf[26])  = CPU_TO_BE16(TPM_TAG_COUNTER_VALUE);
  54.526 +     memset(&buf[30], 0, 4);
  54.527 +-    *((UINT32*)&buf[34]) = cpu_to_be32(tpmData.permanent.data.auditMonotonicCounter);
  54.528 +-    *((UINT32*)&buf[34]) = cpu_to_be32(rsp->result);
  54.529 ++    *((UINT32*)&buf[34]) = CPU_TO_BE32(tpmData.permanent.data.auditMonotonicCounter);
  54.530 ++    *((UINT32*)&buf[34]) = CPU_TO_BE32(rsp->result);
  54.531 +     sha1_init(&sha1_ctx);
  54.532 +     sha1_update(&sha1_ctx, tpmData.stany.data.auditDigest.digest, 
  54.533 +       sizeof(TPM_DIGEST));
  54.534 +@@ -158,7 +159,7 @@ TPM_RESULT TPM_GetAuditDigestSigned(TPM_
  54.535 +   }
  54.536 +   memcpy(&buf[0], "\x05\x00ADIG", 6);
  54.537 +   memcpy(&buf[6], antiReplay->nonce, 20);
  54.538 +-  *(UINT32*)&buf[26] = cpu_to_be32(buf_size - 30);
  54.539 ++  *(UINT32*)&buf[26] = CPU_TO_BE32(buf_size - 30);
  54.540 +   memcpy(&buf[30], auditDigest->digest, 20);
  54.541 +   ptr = &buf[50];
  54.542 +   len = buf_size - 50;
  54.543 +@@ -198,4 +199,3 @@ TPM_RESULT TPM_SetOrdinalAuditStatus(TPM
  54.544 +   }
  54.545 +   return TPM_SUCCESS;
  54.546 + }
  54.547 +-
  54.548 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_authorization.c vtpm/tpm/tpm_authorization.c
  54.549 +--- orig/tpm_emulator-0.2/tpm/tpm_authorization.c	2005-08-17 10:58:36.000000000 -0700
  54.550 ++++ vtpm/tpm/tpm_authorization.c	2005-08-17 10:55:52.000000000 -0700
  54.551 +@@ -1,6 +1,7 @@
  54.552 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  54.553 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  54.554 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
  54.555 ++ * Copyright (C) 2005 INTEL Corp
  54.556 +  *
  54.557 +  * This module is free software; you can redistribute it and/or modify
  54.558 +  * it under the terms of the GNU General Public License as published
  54.559 +@@ -268,7 +269,7 @@ TPM_RESULT tpm_verify_auth(TPM_AUTH *aut
  54.560 + {
  54.561 +   hmac_ctx_t ctx;
  54.562 +   TPM_SESSION_DATA *session;
  54.563 +-  UINT32 auth_handle = cpu_to_be32(auth->authHandle);
  54.564 ++  UINT32 auth_handle = CPU_TO_BE32(auth->authHandle);
  54.565 +   
  54.566 +   info("tpm_verify_auth(%08x)", auth->authHandle);
  54.567 +   /* get dedicated authorization session */
  54.568 +@@ -316,5 +317,3 @@ void tpm_decrypt_auth_secret(TPM_ENCAUTH
  54.569 +   for (i = 0; i < sizeof(TPM_SECRET); i++)
  54.570 +     plainAuth[i] ^= encAuth[i];
  54.571 + }
  54.572 +-
  54.573 +-
  54.574 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_capability.c vtpm/tpm/tpm_capability.c
  54.575 +--- orig/tpm_emulator-0.2/tpm/tpm_capability.c	2005-08-17 10:58:36.000000000 -0700
  54.576 ++++ vtpm/tpm/tpm_capability.c	2005-08-17 10:55:52.000000000 -0700
  54.577 +@@ -1,6 +1,7 @@
  54.578 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  54.579 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  54.580 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
  54.581 ++ * Copyright (C) 2005 INTEL Corp
  54.582 +  *
  54.583 +  * This module is free software; you can redistribute it and/or modify
  54.584 +  * it under the terms of the GNU General Public License as published
  54.585 +@@ -398,7 +399,7 @@ TPM_RESULT TPM_GetCapability(TPM_CAPABIL
  54.586 + 
  54.587 +     case TPM_CAP_KEY_HANDLE:
  54.588 +       debug("[TPM_CAP_KEY_HANDLE]");
  54.589 +-      subCapSize = cpu_to_be32(TPM_RT_KEY);
  54.590 ++      subCapSize = CPU_TO_BE32(TPM_RT_KEY);
  54.591 +       return cap_handle(4, (BYTE*)&subCapSize, respSize, resp);
  54.592 + 
  54.593 +     case TPM_CAP_CHECK_LOADED:
  54.594 +@@ -472,4 +473,3 @@ TPM_RESULT TPM_GetCapability(TPM_CAPABIL
  54.595 +       return TPM_BAD_MODE;
  54.596 +   }
  54.597 + }
  54.598 +-
  54.599 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_cmd_handler.c vtpm/tpm/tpm_cmd_handler.c
  54.600 +--- orig/tpm_emulator-0.2/tpm/tpm_cmd_handler.c	2005-08-17 10:58:36.000000000 -0700
  54.601 ++++ vtpm/tpm/tpm_cmd_handler.c	2005-08-17 10:55:52.000000000 -0700
  54.602 +@@ -1,6 +1,7 @@
  54.603 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  54.604 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  54.605 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
  54.606 ++ * Copyright (C) 2005 INTEL Corp
  54.607 +  *
  54.608 +  * This module is free software; you can redistribute it and/or modify
  54.609 +  * it under the terms of the GNU General Public License as published
  54.610 +@@ -26,7 +27,7 @@ static void tpm_compute_in_param_digest(
  54.611 + {
  54.612 +   sha1_ctx_t sha1;
  54.613 +   UINT32 offset;
  54.614 +-  UINT32 ord = cpu_to_be32(req->ordinal);
  54.615 ++  UINT32 ord = CPU_TO_BE32(req->ordinal);
  54.616 + 
  54.617 +   /* skip all key-handles at the beginning */
  54.618 +   switch (req->ordinal) {
  54.619 +@@ -82,8 +83,8 @@ static void tpm_compute_in_param_digest(
  54.620 + static void tpm_compute_out_param_digest(TPM_COMMAND_CODE ordinal, TPM_RESPONSE *rsp)
  54.621 + {
  54.622 +   sha1_ctx_t sha1;
  54.623 +-  UINT32 res = cpu_to_be32(rsp->result);
  54.624 +-  UINT32 ord = cpu_to_be32(ordinal);
  54.625 ++  UINT32 res = CPU_TO_BE32(rsp->result);
  54.626 ++  UINT32 ord = CPU_TO_BE32(ordinal);
  54.627 + 
  54.628 +   /* compute SHA1 hash */
  54.629 +   sha1_init(&sha1);
  54.630 +@@ -3081,7 +3082,7 @@ static void tpm_setup_rsp_auth(TPM_COMMA
  54.631 +       hmac_update(&hmac, rsp->auth2->digest, sizeof(rsp->auth2->digest));
  54.632 + #if 0
  54.633 +       if (tpm_get_auth(rsp->auth2->authHandle)->type == TPM_ST_OIAP) {
  54.634 +-        UINT32 handle = cpu_to_be32(rsp->auth2->authHandle);
  54.635 ++        UINT32 handle = CPU_TO_BE32(rsp->auth2->authHandle);
  54.636 +         hmac_update(&hmac, (BYTE*)&handle, 4);
  54.637 +       }
  54.638 + #endif
  54.639 +@@ -3096,7 +3097,7 @@ static void tpm_setup_rsp_auth(TPM_COMMA
  54.640 +       hmac_update(&hmac, rsp->auth1->digest, sizeof(rsp->auth1->digest));
  54.641 + #if 0
  54.642 +       if (tpm_get_auth(rsp->auth1->authHandle)->type == TPM_ST_OIAP) {
  54.643 +-        UINT32 handle = cpu_to_be32(rsp->auth1->authHandle);
  54.644 ++        UINT32 handle = CPU_TO_BE32(rsp->auth1->authHandle);
  54.645 +         hmac_update(&hmac, (BYTE*)&handle, 4);
  54.646 +       }
  54.647 + #endif
  54.648 +@@ -3179,7 +3180,9 @@ extern const char *tpm_error_to_string(T
  54.649 + static void tpm_execute_command(TPM_REQUEST *req, TPM_RESPONSE *rsp)
  54.650 + {
  54.651 +   TPM_RESULT res;
  54.652 +-  
  54.653 ++
  54.654 ++  req->tag = (BYTE) req->tag;  // VIN HACK!!! 
  54.655 ++
  54.656 +   /* setup authorisation as well as response tag and size */
  54.657 +   memset(rsp, 0, sizeof(*rsp));
  54.658 +   switch (req->tag) {
  54.659 +@@ -3878,4 +3881,3 @@ int tpm_handle_command(const uint8_t *in
  54.660 +   tpm_free(rsp.param);
  54.661 +   return 0;
  54.662 + }
  54.663 +-
  54.664 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_crypto.c vtpm/tpm/tpm_crypto.c
  54.665 +--- orig/tpm_emulator-0.2/tpm/tpm_crypto.c	2005-08-17 10:58:36.000000000 -0700
  54.666 ++++ vtpm/tpm/tpm_crypto.c	2005-08-17 10:55:52.000000000 -0700
  54.667 +@@ -1,6 +1,7 @@
  54.668 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  54.669 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  54.670 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
  54.671 ++ * Copyright (C) 2005 INTEL Corp
  54.672 +  *
  54.673 +  * This module is free software; you can redistribute it and/or modify
  54.674 +  * it under the terms of the GNU General Public License as published
  54.675 +@@ -106,7 +107,7 @@ TPM_RESULT tpm_sign(TPM_KEY_DATA *key, T
  54.676 +     /* setup TPM_SIGN_INFO structure */
  54.677 +     memcpy(&buf[0], "\x05\x00SIGN", 6);
  54.678 +     memcpy(&buf[6], auth->nonceOdd.nonce, 20);
  54.679 +-    *(UINT32*)&buf[26] = cpu_to_be32(areaToSignSize);
  54.680 ++    *(UINT32*)&buf[26] = CPU_TO_BE32(areaToSignSize);
  54.681 +     memcpy(&buf[30], areaToSign, areaToSignSize);
  54.682 +     if (rsa_sign(&key->key, RSA_SSA_PKCS1_SHA1, 
  54.683 +         buf, areaToSignSize + 30, *sig)) {
  54.684 +@@ -379,4 +380,3 @@ TPM_RESULT TPM_CertifyKey2(TPM_KEY_HANDL
  54.685 +   }  
  54.686 +   return TPM_SUCCESS;
  54.687 + }
  54.688 +-
  54.689 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_data.c vtpm/tpm/tpm_data.c
  54.690 +--- orig/tpm_emulator-0.2/tpm/tpm_data.c	2005-08-17 10:58:36.000000000 -0700
  54.691 ++++ vtpm/tpm/tpm_data.c	2005-08-17 10:55:52.000000000 -0700
  54.692 +@@ -1,6 +1,7 @@
  54.693 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  54.694 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  54.695 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
  54.696 ++ * Copyright (C) 2005 INTEL Corp
  54.697 +  *
  54.698 +  * This module is free software; you can redistribute it and/or modify
  54.699 +  * it under the terms of the GNU General Public License as published
  54.700 +@@ -15,9 +16,15 @@
  54.701 +  * $Id: tpm_data.c 9 2005-04-26 18:15:31Z mast $
  54.702 +  */
  54.703 + 
  54.704 ++#include <sys/types.h>
  54.705 ++#include <sys/stat.h>
  54.706 ++#include <fcntl.h>
  54.707 ++#include <unistd.h>
  54.708 ++
  54.709 + #include "tpm_emulator.h"
  54.710 + #include "tpm_structures.h"
  54.711 + #include "tpm_marshalling.h"
  54.712 ++#include "vtpm_manager.h"
  54.713 + 
  54.714 + TPM_DATA tpmData;
  54.715 + 
  54.716 +@@ -28,6 +35,7 @@ BOOL tpm_get_physical_presence(void)
  54.717 + 
  54.718 + void tpm_init_data(void)
  54.719 + {
  54.720 ++#ifndef TPM_GENERATE_EK
  54.721 +   /* endorsement key */
  54.722 +   uint8_t ek_n[] =  "\xa8\xdb\xa9\x42\xa8\xf3\xb8\x06\x85\x90\x76\x93\xad\xf7"
  54.723 +     "\x74\xec\x3f\xd3\x3d\x9d\xe8\x2e\xff\x15\xed\x0e\xce\x5f\x93"
  54.724 +@@ -66,6 +74,8 @@ void tpm_init_data(void)
  54.725 +     "\xd1\xc0\x8b\x5b\xa2\x2e\xa7\x15\xca\x50\x75\x10\x48\x9c\x2b"
  54.726 +     "\x18\xb9\x67\x8f\x5d\x64\xc3\x28\x9f\x2f\x16\x2f\x08\xda\x47"
  54.727 +     "\xec\x86\x43\x0c\x80\x99\x07\x34\x0f";
  54.728 ++#endif
  54.729 ++
  54.730 +   int i;
  54.731 +   /* reset all data to NULL, FALSE or 0 */
  54.732 +   memset(&tpmData, 0, sizeof(tpmData));
  54.733 +@@ -85,6 +95,10 @@ void tpm_init_data(void)
  54.734 +   tpmData.permanent.data.version.revMinor = VERSION_MINOR;
  54.735 +   /* setup PCR attributes */
  54.736 +   for (i = 0; i < TPM_NUM_PCR; i++) {
  54.737 ++    int j;
  54.738 ++    for (j=0; j < TPM_NUM_LOCALITY; j++) {
  54.739 ++      tpmData.permanent.data.pcrAttrib[i].pcrExtendLocal[j] = TRUE;
  54.740 ++    }
  54.741 +     tpmData.permanent.data.pcrAttrib[i].pcrReset = TRUE;
  54.742 +   }
  54.743 +   /* set tick type */
  54.744 +@@ -115,49 +129,235 @@ void tpm_release_data(void)
  54.745 + 
  54.746 + #ifdef TPM_STORE_TO_FILE
  54.747 + 
  54.748 +-#include <linux/fs.h>
  54.749 +-#include <linux/unistd.h>
  54.750 +-#include <asm/uaccess.h>
  54.751 ++#include <sys/types.h>
  54.752 ++#include <sys/stat.h>
  54.753 ++#include <fcntl.h>
  54.754 ++
  54.755 ++ static int vtpm_tx_fh=-1, vtpm_rx_fh=-1;
  54.756 + 
  54.757 +-#define TPM_STORAGE_FILE "/var/tpm/tpm_emulator-1.2." STR(VERSION_MAJOR) "." STR(VERSION_MINOR) 
  54.758 ++#ifdef VTPM_MUTLI_VM
  54.759 ++ #define DEV_FE "/dev/tpm"
  54.760 ++#else
  54.761 ++ #define VTPM_RX_FIFO_D  "/var/vtpm/fifos/vtpm-to-%d.fifo"
  54.762 ++ #define VTPM_TX_FIFO  "/var/vtpm/fifos/vtpm-from-all.fifo"
  54.763 ++
  54.764 ++ extern int dmi_id;
  54.765 ++ static char *vtpm_rx_name=NULL; 
  54.766 ++#endif
  54.767 + 
  54.768 + static int write_to_file(uint8_t *data, size_t data_length)
  54.769 + {
  54.770 +-  int res;
  54.771 +-  struct file *fp;
  54.772 +-  mm_segment_t old_fs = get_fs();
  54.773 +-  fp = filp_open(TPM_STORAGE_FILE, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
  54.774 +-  if (IS_ERR(fp)) return -1;
  54.775 +-  set_fs(get_ds());
  54.776 +-  res = fp->f_op->write(fp, data, data_length, &fp->f_pos);
  54.777 +-  set_fs(old_fs);
  54.778 +-  filp_close(fp, NULL);
  54.779 +-  return (res == data_length) ? 0 : -1;
  54.780 ++  int res, out_data_size, in_header_size;
  54.781 ++  BYTE *ptr, *out_data, *in_header;
  54.782 ++  UINT32 result, len, in_rsp_size;
  54.783 ++  UINT16 tag = VTPM_TAG_REQ;
  54.784 ++	
  54.785 ++  printf("Saving NVM\n");
  54.786 ++  if (vtpm_tx_fh < 0) {
  54.787 ++#ifdef VTPM_MUTLI_VM
  54.788 ++    vtpm_tx_fh = open(DEV_FE, O_RDWR);
  54.789 ++#else
  54.790 ++	vtpm_tx_fh = open(VTPM_TX_FIFO, O_WRONLY);
  54.791 ++#endif
  54.792 ++  }
  54.793 ++
  54.794 ++  if (vtpm_tx_fh < 0) {
  54.795 ++		return -1;
  54.796 ++  }
  54.797 ++ 
  54.798 ++  // Send request to VTPM Manager to encrypt data
  54.799 ++#ifdef VTPM_MUTLI_VM
  54.800 ++  out_data_size = len = VTPM_COMMAND_HEADER_SIZE_CLT + data_length;
  54.801 ++#else
  54.802 ++  out_data_size = len = VTPM_COMMAND_HEADER_SIZE_SRV + data_length;
  54.803 ++#endif
  54.804 ++  
  54.805 ++  out_data = ptr = (BYTE *) malloc(len);
  54.806 ++
  54.807 ++  if (ptr == NULL
  54.808 ++#ifndef VTPM_MUTLI_VM
  54.809 ++      || tpm_marshal_UINT32(&ptr, &len, dmi_id)
  54.810 ++#endif
  54.811 ++	  || tpm_marshal_UINT16(&ptr, &len, tag)
  54.812 ++#ifdef VTPM_MUTLI_VM
  54.813 ++	  || tpm_marshal_UINT32(&ptr, &len, out_data_size)
  54.814 ++#else
  54.815 ++	  || tpm_marshal_UINT32(&ptr, &len, out_data_size - sizeof(uint32_t))
  54.816 ++#endif  
  54.817 ++	  || tpm_marshal_UINT32(&ptr, &len, VTPM_ORD_SAVENVM)
  54.818 ++	  || tpm_marshal_BYTE_ARRAY(&ptr, &len, data, data_length)) {
  54.819 ++	free(out_data);
  54.820 ++	return -1;
  54.821 ++  }
  54.822 ++  
  54.823 ++  printf("\tSending SaveNVM Command.\n");
  54.824 ++  res = write(vtpm_tx_fh, out_data, out_data_size);
  54.825 ++  free(out_data);
  54.826 ++  if (res != out_data_size) return -1;
  54.827 ++
  54.828 ++  if (vtpm_rx_fh < 0) {
  54.829 ++#ifdef VTPM_MUTLI_VM
  54.830 ++    vtpm_rx_fh = vtpm_tx_fh
  54.831 ++#else
  54.832 ++    if (vtpm_rx_name == NULL) {
  54.833 ++      vtpm_rx_name = malloc(10 + strlen(VTPM_RX_FIFO_D));
  54.834 ++      sprintf(vtpm_rx_name, VTPM_RX_FIFO_D, (uint32_t) dmi_id);
  54.835 ++    }
  54.836 ++	vtpm_rx_fh = open(vtpm_rx_name, O_RDONLY);
  54.837 ++#endif
  54.838 ++  }
  54.839 ++
  54.840 ++  if (vtpm_rx_fh < 0) {
  54.841 ++		return -1;
  54.842 ++  }
  54.843 ++  
  54.844 ++  // Read Header of response so we can get the size & status
  54.845 ++#ifdef VTPM_MUTLI_VM
  54.846 ++  in_header_size = len = VTPM_COMMAND_HEADER_SIZE_CLT;
  54.847 ++#else
  54.848 ++  in_header_size = len = VTPM_COMMAND_HEADER_SIZE_SRV;
  54.849 ++#endif
  54.850 ++  in_header = ptr = malloc(in_header_size);
  54.851 ++  
  54.852 ++  printf("\tReading SaveNVM header.\n");
  54.853 ++  res = read(vtpm_rx_fh, in_header, in_header_size);
  54.854 ++
  54.855 ++  if ( (res != in_header_size)
  54.856 ++#ifndef VTPM_MUTLI_VM
  54.857 ++       || tpm_unmarshal_UINT32(&ptr, &len, (UINT32*)&dmi_id)
  54.858 ++#endif
  54.859 ++	   || tpm_unmarshal_UINT16(&ptr, &len, &tag)
  54.860 ++	   || tpm_unmarshal_UINT32(&ptr, &len, &in_rsp_size)
  54.861 ++	   || tpm_unmarshal_UINT32(&ptr, &len, &result) ) {
  54.862 ++	  free(in_header);
  54.863 ++	  return -1;
  54.864 ++  }
  54.865 ++  free(in_header);
  54.866 ++  
  54.867 ++  if (result != VTPM_SUCCESS) {
  54.868 ++      return -1;  
  54.869 ++  }
  54.870 ++
  54.871 ++#ifdef VTPM_MUTLI_VM
  54.872 ++  close(vtpm_tx_fh); close(vtpm_rx_fh);
  54.873 ++#endif
  54.874 ++	  
  54.875 ++  printf("\tFinishing up SaveNVM\n");
  54.876 ++  return (0);
  54.877 + }
  54.878 + 
  54.879 + static int read_from_file(uint8_t **data, size_t *data_length)
  54.880 + {
  54.881 +-  int res;
  54.882 +-  struct file *fp;
  54.883 +-  mm_segment_t old_fs = get_fs();
  54.884 +-  fp = filp_open(TPM_STORAGE_FILE, O_RDONLY, 0);
  54.885 +-  if (IS_ERR(fp)) return -1;
  54.886 +-  *data_length = (size_t)fp->f_dentry->d_inode->i_size;
  54.887 +-  /* *data_length = i_size_read(fp->f_dentry->d_inode); */
  54.888 +-  *data = tpm_malloc(*data_length);
  54.889 +-  if (*data == NULL) {
  54.890 +-    filp_close(fp, NULL);
  54.891 ++  int res, out_data_size, in_header_size;
  54.892 ++  uint8_t *ptr, *out_data, *in_header;
  54.893 ++  UINT16 tag = VTPM_TAG_REQ;
  54.894 ++  UINT32 len, in_rsp_size, result;
  54.895 ++#ifdef VTPM_MUTLI_VM
  54.896 ++	int vtpm_rx_fh, vtpm_tx_fh;
  54.897 ++#endif
  54.898 ++	
  54.899 ++  printf("Loading NVM.\n");
  54.900 ++  if (vtpm_tx_fh < 0) {
  54.901 ++#ifdef VTPM_MUTLI_VM
  54.902 ++    vtpm_tx_fh = open(DEV_FE, O_RDWR);
  54.903 ++#else
  54.904 ++	vtpm_tx_fh = open(VTPM_TX_FIFO, O_WRONLY);
  54.905 ++#endif
  54.906 ++  }
  54.907 ++
  54.908 ++  if (vtpm_tx_fh < 0) {
  54.909 ++		return -1;
  54.910 ++  }
  54.911 ++ 
  54.912 ++  // Send request to VTPM Manager to encrypt data
  54.913 ++#ifdef VTPM_MUTLI_VM
  54.914 ++  out_data_size = len = VTPM_COMMAND_HEADER_SIZE_CLT;
  54.915 ++#else
  54.916 ++  out_data_size = len = VTPM_COMMAND_HEADER_SIZE_SRV;
  54.917 ++#endif
  54.918 ++  out_data = ptr = (BYTE *) malloc(len);
  54.919 ++
  54.920 ++  if (ptr == NULL
  54.921 ++#ifndef VTPM_MUTLI_VM
  54.922 ++      || tpm_marshal_UINT32(&ptr, &len, dmi_id)
  54.923 ++#endif  
  54.924 ++      || tpm_marshal_UINT16(&ptr, &len, tag)
  54.925 ++#ifdef VTPM_MUTLI_VM
  54.926 ++      || tpm_marshal_UINT32(&ptr, &len, out_data_size)
  54.927 ++#else
  54.928 ++      || tpm_marshal_UINT32(&ptr, &len, out_data_size - sizeof(uint32_t))
  54.929 ++#endif
  54.930 ++      || tpm_marshal_UINT32(&ptr, &len, VTPM_ORD_LOADNVM)) {
  54.931 ++    free(out_data);
  54.932 +     return -1;
  54.933 +   }
  54.934 +-  set_fs(get_ds());
  54.935 +-  res = fp->f_op->read(fp, *data, *data_length, &fp->f_pos);
  54.936 +-  set_fs(old_fs);
  54.937 +-  filp_close(fp, NULL);
  54.938 ++
  54.939 ++  printf("\tSending LoadNVM command\n");
  54.940 ++  res = write(vtpm_tx_fh, out_data, out_data_size);
  54.941 ++  free(out_data);
  54.942 ++  if (res != out_data_size) return -1;
  54.943 ++
  54.944 ++    if (vtpm_rx_fh < 0) {
  54.945 ++#ifdef VTPM_MUTLI_VM
  54.946 ++    vtpm_rx_fh = vtpm_tx_fh;
  54.947 ++#else
  54.948 ++    if (vtpm_rx_name == NULL) {
  54.949 ++      vtpm_rx_name = malloc(10 + strlen(VTPM_RX_FIFO_D));
  54.950 ++      sprintf(vtpm_rx_name, VTPM_RX_FIFO_D, (uint32_t) dmi_id);
  54.951 ++    }
  54.952 ++	vtpm_rx_fh = open(vtpm_rx_name, O_RDONLY);
  54.953 ++#endif
  54.954 ++  }
  54.955 ++
  54.956 ++  if (vtpm_rx_fh < 0) {
  54.957 ++		return -1;
  54.958 ++  }
  54.959 ++  
  54.960 ++  // Read Header of response so we can get the size & status
  54.961 ++#ifdef VTPM_MUTLI_VM
  54.962 ++  in_header_size = len = VTPM_COMMAND_HEADER_SIZE_CLT;
  54.963 ++#else
  54.964 ++  in_header_size = len = VTPM_COMMAND_HEADER_SIZE_SRV;
  54.965 ++#endif
  54.966 ++  in_header = ptr = malloc(in_header_size);
  54.967 ++  
  54.968 ++  printf("\tReading LoadNVM header\n");
  54.969 ++  res = read(vtpm_rx_fh, in_header, in_header_size);
  54.970 ++
  54.971 ++  if ( (res != in_header_size)
  54.972 ++#ifndef VTPM_MUTLI_VM
  54.973 ++       || tpm_unmarshal_UINT32(&ptr, &len, (UINT32*)&dmi_id)
  54.974 ++#endif
  54.975 ++       || tpm_unmarshal_UINT16(&ptr, &len, &tag)
  54.976 ++       || tpm_unmarshal_UINT32(&ptr, &len, &in_rsp_size)
  54.977 ++       || tpm_unmarshal_UINT32(&ptr, &len, &result) ) {
  54.978 ++      free(in_header);
  54.979 ++      return -1;
  54.980 ++  }
  54.981 ++  free(in_header);
  54.982 ++  
  54.983 ++  if (result != VTPM_SUCCESS) {
  54.984 ++      return -1;  
  54.985 ++  }
  54.986 ++
  54.987 ++  // Read Encrypted data from VTPM Manager
  54.988 ++  *data_length = in_rsp_size - VTPM_COMMAND_HEADER_SIZE_CLT;
  54.989 ++  *data = (uint8_t *) malloc(*data_length);
  54.990 ++
  54.991 ++  printf("\tReading clear data from LoadNVM.\n");
  54.992 ++  res = read(vtpm_rx_fh, *data, *data_length);
  54.993 ++#ifdef VTPM_MUTLI_VM
  54.994 ++  close(vtpm_rx_fh);close(vtpm_tx_fh);
  54.995 ++#endif 
  54.996 ++	
  54.997 ++  printf("\tReturing from loading NVM\n");
  54.998 +   if (res != *data_length) {
  54.999 +-    tpm_free(*data);
 54.1000 +-    return -1;
 54.1001 ++      free(*data);
 54.1002 ++      return -1;
 54.1003 ++  } else {
 54.1004 ++      return 0;
 54.1005 +   }
 54.1006 +-  return 0;
 54.1007 ++
 54.1008 + }
 54.1009 + 
 54.1010 + #else
 54.1011 +@@ -231,7 +431,6 @@ int tpm_restore_permanent_data(void)
 54.1012 + 
 54.1013 + int tpm_erase_permanent_data(void)
 54.1014 + {
 54.1015 +-  int res = write_to_file("", 0);
 54.1016 ++  int res = write_to_file((uint8_t*)"", 0);
 54.1017 +   return res;
 54.1018 + }
 54.1019 +-
 54.1020 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_deprecated.c vtpm/tpm/tpm_deprecated.c
 54.1021 +--- orig/tpm_emulator-0.2/tpm/tpm_deprecated.c	2005-08-17 10:58:36.000000000 -0700
 54.1022 ++++ vtpm/tpm/tpm_deprecated.c	2005-08-17 10:55:52.000000000 -0700
 54.1023 +@@ -1,6 +1,7 @@
 54.1024 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 54.1025 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 54.1026 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
 54.1027 ++ * Copyright (C) 2005 INTEL Corp
 54.1028 +  *
 54.1029 +  * This module is free software; you can redistribute it and/or modify
 54.1030 +  * it under the terms of the GNU General Public License as published
 54.1031 +@@ -50,7 +51,7 @@ TPM_RESULT TPM_SaveKeyContext(TPM_KEY_HA
 54.1032 +   BYTE *ptr;
 54.1033 +   UINT32 len;
 54.1034 +   info("TPM_SaveKeyContext()");
 54.1035 +-  res = TPM_SaveContext(keyHandle, TPM_RT_KEY, "SaveKeyContext..", 
 54.1036 ++  res = TPM_SaveContext(keyHandle, TPM_RT_KEY, (BYTE*)"SaveKeyContext..", 
 54.1037 +                         keyContextSize, &contextBlob);
 54.1038 +   if (res != TPM_SUCCESS) return res;
 54.1039 +   len = *keyContextSize;
 54.1040 +@@ -82,7 +83,7 @@ TPM_RESULT TPM_SaveAuthContext(TPM_AUTHH
 54.1041 +   BYTE *ptr;
 54.1042 +   UINT32 len;
 54.1043 +   info("TPM_SaveAuthContext()");
 54.1044 +-  res = TPM_SaveContext(authHandle, TPM_RT_KEY, "SaveAuthContext.", 
 54.1045 ++  res = TPM_SaveContext(authHandle, TPM_RT_KEY, (BYTE*)"SaveAuthContext.", 
 54.1046 +                         authContextSize, &contextBlob);
 54.1047 +   if (res != TPM_SUCCESS) return res;
 54.1048 +   len = *authContextSize;
 54.1049 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_emulator.h vtpm/tpm/tpm_emulator.h
 54.1050 +--- orig/tpm_emulator-0.2/tpm/tpm_emulator.h	2005-08-17 10:58:36.000000000 -0700
 54.1051 ++++ vtpm/tpm/tpm_emulator.h	2005-08-17 10:55:52.000000000 -0700
 54.1052 +@@ -1,5 +1,6 @@
 54.1053 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 54.1054 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 54.1055 ++ * Copyright (C) 2005 INTEL Corp
 54.1056 +  *
 54.1057 +  * This module is free software; you can redistribute it and/or modify
 54.1058 +  * it under the terms of the GNU General Public License as published
 54.1059 +@@ -22,7 +23,8 @@
 54.1060 + /* TPM configuration */
 54.1061 + #define TPM_STORE_TO_FILE       1
 54.1062 + #undef  TPM_STRONG_PERSISTENCE
 54.1063 +-#undef  TPM_GENERATE_EK
 54.1064 ++//#undef  TPM_GENERATE_EK
 54.1065 ++#define  TPM_GENERATE_EK
 54.1066 + 
 54.1067 + /**
 54.1068 +  * tpm_emulator_init - initialises and starts the TPM emulator
 54.1069 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_integrity.c vtpm/tpm/tpm_integrity.c
 54.1070 +--- orig/tpm_emulator-0.2/tpm/tpm_integrity.c	2005-08-17 10:58:36.000000000 -0700
 54.1071 ++++ vtpm/tpm/tpm_integrity.c	2005-08-17 10:55:52.000000000 -0700
 54.1072 +@@ -1,6 +1,7 @@
 54.1073 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 54.1074 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 54.1075 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
 54.1076 ++ * Copyright (C) 2005 INTEL Corp
 54.1077 +  *
 54.1078 +  * This module is free software; you can redistribute it and/or modify
 54.1079 +  * it under the terms of the GNU General Public License as published
 54.1080 +@@ -194,4 +195,3 @@ TPM_RESULT tpm_verify_pcr(TPM_KEY_DATA *
 54.1081 +   }
 54.1082 +   return TPM_SUCCESS;
 54.1083 + }
 54.1084 +-
 54.1085 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_structures.h vtpm/tpm/tpm_structures.h
 54.1086 +--- orig/tpm_emulator-0.2/tpm/tpm_structures.h	2005-08-17 10:58:36.000000000 -0700
 54.1087 ++++ vtpm/tpm/tpm_structures.h	2005-08-17 10:55:52.000000000 -0700
 54.1088 +@@ -1,6 +1,7 @@
 54.1089 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 54.1090 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 54.1091 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
 54.1092 ++ * Copyright (C) 2005 INTEL Corp
 54.1093 +  *
 54.1094 +  * This module is free software; you can redistribute it and/or modify
 54.1095 +  * it under the terms of the GNU General Public License as published
 54.1096 +@@ -18,7 +19,7 @@
 54.1097 + #ifndef _TPM_STRUCTURES_H_
 54.1098 + #define _TPM_STRUCTURES_H_
 54.1099 + 
 54.1100 +-#include <linux/types.h>
 54.1101 ++//#include <linux/types.h>
 54.1102 + #include "crypto/rsa.h"
 54.1103 + 
 54.1104 + /*
 54.1105 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_testing.c vtpm/tpm/tpm_testing.c
 54.1106 +--- orig/tpm_emulator-0.2/tpm/tpm_testing.c	2005-08-17 10:58:36.000000000 -0700
 54.1107 ++++ vtpm/tpm/tpm_testing.c	2005-08-17 10:55:52.000000000 -0700
 54.1108 +@@ -1,6 +1,7 @@
 54.1109 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 54.1110 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 54.1111 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
 54.1112 ++ * Copyright (C) 2005 INTEL Corp
 54.1113 +  *
 54.1114 +  * This module is free software; you can redistribute it and/or modify
 54.1115 +  * it under the terms of the GNU General Public License as published
 54.1116 +@@ -95,24 +96,24 @@ static int tpm_test_sha1(void)
 54.1117 +   struct {
 54.1118 +     uint8_t *data; uint32_t repetitions; uint8_t *digest;
 54.1119 +   } test_cases[] =  {{
 54.1120 +-    "abc", 1,
 54.1121 +-    "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D"
 54.1122 ++	(uint8_t*)"abc", 1,
 54.1123 ++    (uint8_t*)"\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D"
 54.1124 +   }, {
 54.1125 +-    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
 54.1126 +-    "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1"
 54.1127 ++    (uint8_t*)"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
 54.1128 ++    (uint8_t*)"\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1"
 54.1129 +   }, {
 54.1130 +-    "a", 1000000,
 54.1131 +-    "\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F"
 54.1132 ++    (uint8_t*)"a", 1000000,
 54.1133 ++    (uint8_t*)"\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F"
 54.1134 +   }, {
 54.1135 +-    "0123456701234567012345670123456701234567012345670123456701234567", 10,
 54.1136 +-    "\xDE\xA3\x56\xA2\xCD\xDD\x90\xC7\xA7\xEC\xED\xC5\xEB\xB5\x63\x93\x4F\x46\x04\x52"
 54.1137 ++    (uint8_t*)"0123456701234567012345670123456701234567012345670123456701234567", 10,
 54.1138 ++    (uint8_t*)"\xDE\xA3\x56\xA2\xCD\xDD\x90\xC7\xA7\xEC\xED\xC5\xEB\xB5\x63\x93\x4F\x46\x04\x52"
 54.1139 +   }};
 54.1140 + 
 54.1141 +   debug("tpm_test_sha1()");
 54.1142 +   for (i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); i++) {
 54.1143 +     sha1_init(&ctx);
 54.1144 +     for (j = 0; j < test_cases[i].repetitions; j++)
 54.1145 +-      sha1_update(&ctx, test_cases[i].data, strlen(test_cases[i].data));
 54.1146 ++      sha1_update(&ctx, test_cases[i].data, strlen((char*)test_cases[i].data));
 54.1147 +     sha1_final(&ctx, digest);
 54.1148 +     if (memcmp(digest, test_cases[i].digest, SHA1_DIGEST_LENGTH) != 0) return -1;
 54.1149 +   }
 54.1150 +@@ -128,41 +129,41 @@ static int tpm_test_hmac(void)
 54.1151 +   struct {
 54.1152 +     uint8_t *key, key_len, *data, data_len, *digest;
 54.1153 +   } test_cases[] = {{
 54.1154 +-    "\x0b", 20, "Hi There", 8,
 54.1155 +-    "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00"
 54.1156 ++    (uint8_t*)"\x0b", 20, (uint8_t*)"Hi There", 8,
 54.1157 ++    (uint8_t*)"\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00"
 54.1158 +   }, {
 54.1159 +-    "Jefe", 4, "what do ya want for nothing?", 28,
 54.1160 +-    "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79"
 54.1161 ++    (uint8_t*)"Jefe", 4, (uint8_t*)"what do ya want for nothing?", 28,
 54.1162 ++    (uint8_t*)"\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79"
 54.1163 +   }, {
 54.1164 +-    "\xaa", 20, "\xdd", 50,
 54.1165 +-    "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3"
 54.1166 ++    (uint8_t*)"\xaa", 20, (uint8_t*)"\xdd", 50,
 54.1167 ++    (uint8_t*)"\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3"
 54.1168 +   }, {
 54.1169 +-    "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
 54.1170 +-    "\x15\x16\x17\x18\x19", 25, "\xcd", 50,
 54.1171 +-    "\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda"
 54.1172 ++    (uint8_t*)"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
 54.1173 ++    "\x15\x16\x17\x18\x19", 25, (uint8_t*)"\xcd", 50,
 54.1174 ++    (uint8_t*)"\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda"
 54.1175 +   }, {
 54.1176 +-    "\x0c", 20, "Test With Truncation", 20,
 54.1177 +-    "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04"
 54.1178 ++    (uint8_t*)"\x0c", 20, (uint8_t*)"Test With Truncation", 20,
 54.1179 ++    (uint8_t*)"\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04"
 54.1180 +   }, {
 54.1181 +-    "\xaa", 80, "Test Using Larger Than Block-Size Key - Hash Key First", 54,
 54.1182 +-    "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12"
 54.1183 ++    (uint8_t*)"\xaa", 80, (uint8_t*)"Test Using Larger Than Block-Size Key - Hash Key First", 54,
 54.1184 ++    (uint8_t*)"\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12"
 54.1185 +   }, {
 54.1186 +-    "\xaa", 80,
 54.1187 +-    "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73,
 54.1188 +-    "\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91"
 54.1189 ++    (uint8_t*)"\xaa", 80,
 54.1190 ++    (uint8_t*)"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73,
 54.1191 ++    (uint8_t*)"\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91"
 54.1192 +   }};
 54.1193 + 
 54.1194 +   debug("tpm_test_hmac()");
 54.1195 +   for (i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); i++) {
 54.1196 +-    if (strlen(test_cases[i].key) < test_cases[i].key_len) {
 54.1197 ++    if (strlen((char*)test_cases[i].key) < test_cases[i].key_len) {
 54.1198 +       uint8_t key[test_cases[i].key_len];
 54.1199 +       memset(key, test_cases[i].key[0], test_cases[i].key_len);
 54.1200 +       hmac_init(&ctx, key, test_cases[i].key_len);
 54.1201 +     } else {
 54.1202 +       hmac_init(&ctx, test_cases[i].key, test_cases[i].key_len);
 54.1203 +     }
 54.1204 +-    for (j = 0; j < test_cases[i].data_len; j += strlen(test_cases[i].data)) {
 54.1205 +-      hmac_update(&ctx, test_cases[i].data, strlen(test_cases[i].data));
 54.1206 ++    for (j = 0; j < test_cases[i].data_len; j += strlen((char*)test_cases[i].data)) {
 54.1207 ++      hmac_update(&ctx, test_cases[i].data, strlen((char*)test_cases[i].data));
 54.1208 +     }
 54.1209 +     hmac_final(&ctx, digest);
 54.1210 +     if (memcmp(digest, test_cases[i].digest, SHA1_DIGEST_LENGTH) != 0) return -1;
 54.1211 +@@ -173,9 +174,9 @@ static int tpm_test_hmac(void)
 54.1212 + static int tpm_test_rsa_EK(void)
 54.1213 + {
 54.1214 +   int res = 0;
 54.1215 +-  char *data = "RSA PKCS #1 v1.5 Test-String";
 54.1216 ++  uint8_t *data = (uint8_t*)"RSA PKCS #1 v1.5 Test-String";
 54.1217 +   uint8_t buf[256];
 54.1218 +-  size_t buf_len, data_len = strlen(data);
 54.1219 ++  size_t buf_len, data_len = strlen((char*)data);
 54.1220 +   rsa_private_key_t priv_key;
 54.1221 +   rsa_public_key_t pub_key;
 54.1222 + 
 54.1223 +diff -uprN orig/tpm_emulator-0.2/tpm/tpm_ticks.c vtpm/tpm/tpm_ticks.c
 54.1224 +--- orig/tpm_emulator-0.2/tpm/tpm_ticks.c	2005-08-17 10:58:36.000000000 -0700
 54.1225 ++++ vtpm/tpm/tpm_ticks.c	2005-08-17 10:55:52.000000000 -0700
 54.1226 +@@ -1,6 +1,7 @@
 54.1227 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 54.1228 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 54.1229 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
 54.1230 ++ * Copyright (C) 2005 INTEL Corp
 54.1231 +  *
 54.1232 +  * This module is free software; you can redistribute it and/or modify
 54.1233 +  * it under the terms of the GNU General Public License as published
 54.1234 +@@ -37,9 +38,7 @@ TPM_RESULT TPM_SetTickType(TPM_TICKTYPE 
 54.1235 + TPM_RESULT TPM_GetTicks(TPM_CURRENT_TICKS *currentTime)
 54.1236 + {
 54.1237 +   info("TPM_GetTicks()");
 54.1238 +-  memcpy(currentTime, &tpmData.stany.data.currentTicks, 
 54.1239 +-    sizeof(TPM_CURRENT_TICKS));
 54.1240 +-  return TPM_SUCCESS;
 54.1241 ++  return TPM_DISABLED_CMD;
 54.1242 + }
 54.1243 + 
 54.1244 + TPM_RESULT TPM_TickStampBlob(TPM_KEY_HANDLE keyHandle, TPM_NONCE *antiReplay,
 54.1245 +@@ -47,61 +46,12 @@ TPM_RESULT TPM_TickStampBlob(TPM_KEY_HAN
 54.1246 +                              TPM_CURRENT_TICKS *currentTicks, 
 54.1247 +                              UINT32 *sigSize, BYTE **sig)
 54.1248 + {
 54.1249 +-  TPM_RESULT res;
 54.1250 +-  TPM_KEY_DATA *key;
 54.1251 +-  BYTE *info, *p;
 54.1252 +-  UINT32 info_length, length;
 54.1253 +   info("TPM_TickStampBlob()");
 54.1254 +-  /* get key */
 54.1255 +-  key = tpm_get_key(keyHandle);
 54.1256 +-  if (key == NULL) return TPM_INVALID_KEYHANDLE;
 54.1257 +-  /* verify authorization */ 
 54.1258 +-  res = tpm_verify_auth(auth1, key->usageAuth, keyHandle);
 54.1259 +-  if (res != TPM_SUCCESS) return res;
 54.1260 +-  if (key->keyUsage != TPM_KEY_SIGNING && key->keyUsage != TPM_KEY_LEGACY
 54.1261 +-      && key->keyUsage != TPM_KEY_IDENTITY) return TPM_INVALID_KEYUSAGE;
 54.1262 +-  /* get current ticks */
 54.1263 +-  TPM_GetTicks(currentTicks);
 54.1264 +-  /* sign data using signature scheme PKCS1_SHA1 and TPM_SIGN_INFO container */
 54.1265 +-  *sigSize = key->key.size >> 3;
 54.1266 +-  *sig = tpm_malloc(*sigSize);
 54.1267 +-  if (*sig == NULL) return TPM_FAIL; 
 54.1268 +-  /* setup TPM_SIGN_INFO structure */
 54.1269 +-  info_length = 30 + sizeof(TPM_DIGEST) + sizeof_TPM_CURRENT_TICKS(currentTicks);
 54.1270 +-  info = tpm_malloc(info_length);
 54.1271 +-  if (info == NULL) {
 54.1272 +-    tpm_free(*sig);
 54.1273 +-    return TPM_FAIL;
 54.1274 +-  }
 54.1275 +-  memcpy(&info[0], "\x05\x00TSTP", 6);
 54.1276 +-  memcpy(&info[6], antiReplay->nonce, 20);
 54.1277 +-  *(UINT32*)&info[26] = cpu_to_be32(20
 54.1278 +-                        + sizeof_TPM_CURRENT_TICKS(currentTicks));
 54.1279 +-  memcpy(&info[30], digestToStamp->digest, sizeof(TPM_DIGEST));
 54.1280 +-  p = &info[30 + sizeof(TPM_DIGEST)]; 
 54.1281 +-  length = sizeof_TPM_CURRENT_TICKS(currentTicks);
 54.1282 +-  if (tpm_marshal_TPM_CURRENT_TICKS(&p, &length, currentTicks)
 54.1283 +-      || rsa_sign(&key->key, RSA_SSA_PKCS1_SHA1, info, info_length, *sig)) {   
 54.1284 +-    tpm_free(*sig);
 54.1285 +-    tpm_free(info);
 54.1286 +-    return TPM_FAIL;
 54.1287 +-  } 
 54.1288 +-  return TPM_SUCCESS;
 54.1289 ++  return TPM_DISABLED_CMD;
 54.1290 + }
 54.1291 + 
 54.1292 + void tpm_update_ticks(void)
 54.1293 + {
 54.1294 +-  if (tpmData.stany.data.currentTicks.tag == 0) {
 54.1295 +-    tpmData.stany.data.currentTicks.tag = TPM_TAG_CURRENT_TICKS;
 54.1296 +-    tpmData.stany.data.currentTicks.currentTicks += tpm_get_ticks();
 54.1297 +-    tpmData.stany.data.currentTicks.tickType = tpmData.permanent.data.tickType;
 54.1298 +-    tpm_get_random_bytes(tpmData.stany.data.currentTicks.tickNonce.nonce, 
 54.1299 +-      sizeof(TPM_NONCE));
 54.1300 +-    tpmData.stany.data.currentTicks.tickRate = 1;
 54.1301 +-    tpmData.stany.data.currentTicks.tickSecurity = TICK_SEC_NO_CHECK;
 54.1302 +-  } else {
 54.1303 +-    tpmData.stany.data.currentTicks.currentTicks += tpm_get_ticks();   
 54.1304 +-  }
 54.1305 + }
 54.1306 +   
 54.1307 + 
 54.1308 +diff -uprN orig/tpm_emulator-0.2/tpm/vtpm_manager.h vtpm/tpm/vtpm_manager.h
 54.1309 +--- orig/tpm_emulator-0.2/tpm/vtpm_manager.h	1969-12-31 16:00:00.000000000 -0800
 54.1310 ++++ vtpm/tpm/vtpm_manager.h	2005-08-17 10:55:52.000000000 -0700
 54.1311 +@@ -0,0 +1,126 @@
 54.1312 ++// ===================================================================
 54.1313 ++// 
 54.1314 ++// Copyright (c) 2005, Intel Corp.
 54.1315 ++// All rights reserved.
 54.1316 ++//
 54.1317 ++// Redistribution and use in source and binary forms, with or without 
 54.1318 ++// modification, are permitted provided that the following conditions 
 54.1319 ++// are met:
 54.1320 ++//
 54.1321 ++//   * Redistributions of source code must retain the above copyright 
 54.1322 ++//     notice, this list of conditions and the following disclaimer.
 54.1323 ++//   * Redistributions in binary form must reproduce the above 
 54.1324 ++//     copyright notice, this list of conditions and the following 
 54.1325 ++//     disclaimer in the documentation and/or other materials provided 
 54.1326 ++//     with the distribution.
 54.1327 ++//   * Neither the name of Intel Corporation nor the names of its 
 54.1328 ++//     contributors may be used to endorse or promote products derived
 54.1329 ++//     from this software without specific prior written permission.
 54.1330 ++//
 54.1331 ++// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 54.1332 ++// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 54.1333 ++// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 54.1334 ++// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 54.1335 ++// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 54.1336 ++// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 54.1337 ++// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 54.1338 ++// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 54.1339 ++// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 54.1340 ++// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 54.1341 ++// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 54.1342 ++// OF THE POSSIBILITY OF SUCH DAMAGE.
 54.1343 ++// ===================================================================
 54.1344 ++// 
 54.1345 ++// vtpm_manager.h
 54.1346 ++// 
 54.1347 ++//  Public Interface header for VTPM Manager
 54.1348 ++//
 54.1349 ++// ==================================================================
 54.1350 ++
 54.1351 ++#ifndef __VTPM_MANAGER_H__
 54.1352 ++#define __VTPM_MANAGER_H__
 54.1353 ++
 54.1354 ++#define VTPM_TAG_REQ 0x01c1
 54.1355 ++#define VTPM_TAG_RSP 0x01c4
 54.1356 ++#define COMMAND_BUFFER_SIZE 4096
 54.1357 ++
 54.1358 ++// Header sizes. Note Header MAY include the DMI
 54.1359 ++#define VTPM_COMMAND_HEADER_SIZE_SRV ( sizeof(UINT32) + sizeof(TPM_TAG) + sizeof(UINT32) + sizeof(TPM_COMMAND_CODE))
 54.1360 ++#define VTPM_COMMAND_HEADER_SIZE_CLT (                  sizeof(TPM_TAG) + sizeof(UINT32) + sizeof(TPM_COMMAND_CODE))
 54.1361 ++
 54.1362 ++//************************ Command Codes ****************************
 54.1363 ++#define VTPM_ORD_OPEN              1   // ULM Creates New DMI
 54.1364 ++#define VTPM_ORD_CLOSE             2   // ULM Closes a DMI
 54.1365 ++#define VTPM_ORD_DELETE            3   // ULM Permemently Deletes DMI
 54.1366 ++#define VTPM_ORD_SAVENVM          4   // DMI requests Secrets Unseal
 54.1367 ++#define VTPM_ORD_LOADNVM          5   // DMI requests Secrets Saved
 54.1368 ++#define VTPM_ORD_TPMCOMMAND       6   // DMI issues HW TPM Command
 54.1369 ++
 54.1370 ++//************************ Return Codes ****************************
 54.1371 ++#define VTPM_SUCCESS               0
 54.1372 ++#define VTPM_FAIL                  1
 54.1373 ++#define VTPM_UNSUPPORTED           2
 54.1374 ++#define VTPM_FORBIDDEN             3
 54.1375 ++#define VTPM_RESTORE_CONTEXT_FAILED    4
 54.1376 ++#define VTPM_INVALID_REQUEST       5
 54.1377 ++
 54.1378 ++/******************* Command Parameter API *************************
 54.1379 ++
 54.1380 ++VTPM Command Format
 54.1381 ++  dmi: 4 bytes                  // Source of message. 
 54.1382 ++                                // WARNING: This is prepended by the channel. 
 54.1383 ++                                // Thus it is received by VTPM Manager, 
 54.1384 ++                                // but not sent by DMI
 54.1385 ++  tpm tag: 2 bytes
 54.1386 ++  command size: 4 bytes         // Size of command including header but not DMI
 54.1387 ++  ord: 4 bytes                  // Command ordinal above
 54.1388 ++  parameters: size - 10 bytes   // Command Parameter
 54.1389 ++
 54.1390 ++VTPM Response Format
 54.1391 ++  tpm tag: 2 bytes
 54.1392 ++  response_size: 4 bytes
 54.1393 ++  status: 4 bytes         
 54.1394 ++  parameters: size - 10 bytes
 54.1395 ++
 54.1396 ++
 54.1397 ++VTPM_Open:
 54.1398 ++  Input Parameters:
 54.1399 ++    Domain_type: 1 byte
 54.1400 ++    domain_id: 4 bytes
 54.1401 ++    instance_id: 4 bytes
 54.1402 ++  Output Parameters:
 54.1403 ++    None
 54.1404 ++    
 54.1405 ++VTPM_Close
 54.1406 ++  Input Parameters:
 54.1407 ++    instance_id: 4 bytes
 54.1408 ++  Output Parameters:
 54.1409 ++    None
 54.1410 ++
 54.1411 ++VTPM_Delete
 54.1412 ++  Input Parameters:
 54.1413 ++    instance_id: 4 bytes
 54.1414 ++  Output Parameters:
 54.1415 ++    None
 54.1416 ++
 54.1417 ++VTPM_SaveNVM
 54.1418 ++  Input Parameters:
 54.1419 ++    data: n bytes (Header indicates size of data)
 54.1420 ++  Output Parameters:
 54.1421 ++    None
 54.1422 ++
 54.1423 ++VTPM_LoadNVM
 54.1424 ++  Input Parameters:
 54.1425 ++    None
 54.1426 ++  Output Parameters:
 54.1427 ++    data: n bytes (Header indicates size of data)
 54.1428 ++
 54.1429 ++VTPM_TPMCommand
 54.1430 ++  Input Parameters:
 54.1431 ++    TPM Command Byte Stream: n bytes 
 54.1432 ++  Output Parameters:
 54.1433 ++    TPM Reponse Byte Stream: n bytes 
 54.1434 ++
 54.1435 ++*********************************************************************/
 54.1436 ++
 54.1437 ++#endif //_VTPM_MANAGER_H_
 54.1438 +diff -uprN orig/tpm_emulator-0.2/tpmd.c vtpm/tpmd.c
 54.1439 +--- orig/tpm_emulator-0.2/tpmd.c	1969-12-31 16:00:00.000000000 -0800
 54.1440 ++++ vtpm/tpmd.c	2005-08-17 10:55:52.000000000 -0700
 54.1441 +@@ -0,0 +1,207 @@
 54.1442 ++/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 54.1443 ++ * Copyright (C) 2005 INTEL Corp
 54.1444 ++ *
 54.1445 ++ * This module is free software; you can redistribute it and/or modify
 54.1446 ++ * it under the terms of the GNU General Public License as published
 54.1447 ++ * by the Free Software Foundation; either version 2 of the License,
 54.1448 ++ * or (at your option) any later version.
 54.1449 ++ *
 54.1450 ++ * This module is distributed in the hope that it will be useful,
 54.1451 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 54.1452 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 54.1453 ++ * GNU General Public License for more details.
 54.1454 ++ *
 54.1455 ++ */
 54.1456 ++
 54.1457 ++#include <stdio.h>
 54.1458 ++#include <stdlib.h>
 54.1459 ++#include <unistd.h>
 54.1460 ++#include <string.h>
 54.1461 ++#include <sys/types.h>
 54.1462 ++#include <sys/stat.h>
 54.1463 ++#include <fcntl.h>
 54.1464 ++#include <sys/time.h>
 54.1465 ++
 54.1466 ++#include "tpm_emulator.h"
 54.1467 ++#include "vtpm_manager.h"
 54.1468 ++
 54.1469 ++#ifdef VTPM_MULTI_VM
 54.1470 ++ #define DEV_BE "/dev/vtpm"
 54.1471 ++#else
 54.1472 ++ #define GUEST_RX_FIFO_D "/var/vtpm/fifos/guest-to-%d.fifo"
 54.1473 ++ #define GUEST_TX_FIFO "/var/vtpm/fifos/guest-from-all.fifo"
 54.1474 ++
 54.1475 ++ int dmi_id;
 54.1476 ++#endif
 54.1477 ++						
 54.1478 ++#define BUFFER_SIZE 2048
 54.1479 ++
 54.1480 ++static uint8_t ctrl_msg[] = { 0, 0, 0, 0,   // destination
 54.1481 ++                              1, 193,       // VTPM_TAG
 54.1482 ++                              0, 0, 0, 10,  // Size
 54.1483 ++                              0, 0, 0, 0};  // TPM_SUCCESS
 54.1484 ++                            
 54.1485 ++
 54.1486 ++static int devurandom=0;
 54.1487 ++
 54.1488 ++	  
 54.1489 ++void get_random_bytes(void *buf, int nbytes) {
 54.1490 ++  
 54.1491 ++  if (devurandom == 0) {
 54.1492 ++    devurandom = open("/dev/urandom", O_RDONLY);
 54.1493 ++  }
 54.1494 ++
 54.1495 ++  if (read(devurandom, buf, nbytes) != nbytes) {
 54.1496 ++      printf("Can't get random number.\n");
 54.1497 ++      exit(-1);
 54.1498 ++  }
 54.1499 ++}
 54.1500 ++
 54.1501 ++uint64_t tpm_get_ticks(void)
 54.1502 ++{
 54.1503 ++  //struct timeval tv;
 54.1504 ++  //int gettimeofday(&tv, struct timezone *tz);
 54.1505 ++  return 0;
 54.1506 ++}
 54.1507 ++
 54.1508 ++int main(int argc, char **argv)
 54.1509 ++{
 54.1510 ++  uint8_t in[BUFFER_SIZE], *out, *addressed_out;
 54.1511 ++  uint32_t out_size;
 54.1512 ++  int in_size, written ;
 54.1513 ++  int i, guest_id=-1;
 54.1514 ++ 
 54.1515 ++  int vtpm_tx_fh=-1, vtpm_rx_fh=-1;
 54.1516 ++#ifdef VTPM_MULTI_VM
 54.1517 ++  if (argc < 2) {
 54.1518 ++    printf("Usage: tpmd clear|save|deactivated\n" );
 54.1519 ++#else
 54.1520 ++  if (argc < 3) {
 54.1521 ++    printf("Usage: tpmd clear|save|deactivated vtpmid\n" );
 54.1522 ++#endif
 54.1523 ++	  return -1;
 54.1524 ++  }
 54.1525 ++
 54.1526 ++#ifndef VTPM_MULTI_VM
 54.1527 ++  dmi_id = atoi(argv[2]);
 54.1528 ++#endif
 54.1529 ++
 54.1530 ++  /* initialize TPM emulator */
 54.1531 ++  if (!strcmp(argv[1], "clear")) {
 54.1532 ++    printf("Initializing tpm: %s\n", argv[1]);
 54.1533 ++    tpm_emulator_init(1);
 54.1534 ++  } else if (!strcmp(argv[1], "save")) { 
 54.1535 ++    printf("Initializing tpm: %s\n", argv[1]);
 54.1536 ++    tpm_emulator_init(2);
 54.1537 ++  } else if (!strcmp(argv[1], "deactivated")) {
 54.1538 ++    printf("Initializing tpm: %s\n", argv[1]);
 54.1539 ++    tpm_emulator_init(3);
 54.1540 ++  } else {
 54.1541 ++    printf("invalid startup mode '%s'; must be 'clear', "
 54.1542 ++      "'save' (default) or 'deactivated", argv[1]);
 54.1543 ++    return -1;
 54.1544 ++  }
 54.1545 ++
 54.1546 ++  char *guest_rx_file = malloc(10 + strlen(GUEST_RX_FIFO_D));
 54.1547 ++  sprintf(guest_rx_file, GUEST_RX_FIFO_D, (uint32_t) dmi_id);
 54.1548 ++  
 54.1549 ++  while (1) {
 54.1550 ++abort_command:
 54.1551 ++    if (vtpm_rx_fh < 0) {
 54.1552 ++#ifdef VTPM_MUTLI_VM
 54.1553 ++	  vtpm_rx_fh = open(DEV_BE, O_RDWR);
 54.1554 ++#else
 54.1555 ++      vtpm_rx_fh = open(guest_rx_file, O_RDONLY);
 54.1556 ++#endif
 54.1557 ++    }
 54.1558 ++    
 54.1559 ++    if (vtpm_rx_fh < 0) {
 54.1560 ++      printf("ERROR: failed to open devices to listen to guest.\n");
 54.1561 ++      return -1;
 54.1562 ++    }
 54.1563 ++    
 54.1564 ++    in_size = read(vtpm_rx_fh, in, BUFFER_SIZE);
 54.1565 ++    if (in_size < 6) { // Magic size of minium TPM command
 54.1566 ++      printf("Recv[%d] to small: 0x", in_size);
 54.1567 ++      if (in_size <= 0) {
 54.1568 ++          close(vtpm_rx_fh);
 54.1569 ++          vtpm_rx_fh = -1;
 54.1570 ++          goto abort_command;
 54.1571 ++      }
 54.1572 ++    } else { 
 54.1573 ++      printf("Recv[%d]: 0x", in_size);
 54.1574 ++      for (i=0; i< in_size; i++) 
 54.1575 ++        printf("%x ", in[i]);
 54.1576 ++      printf("\n");
 54.1577 ++    }
 54.1578 ++
 54.1579 ++    if (guest_id == -1) {
 54.1580 ++        guest_id = *((uint32_t *) in);
 54.1581 ++        *((uint32_t *) ctrl_msg) = *((uint32_t *) in);
 54.1582 ++    } else {
 54.1583 ++        if (guest_id != *((uint32_t *) in) ) {
 54.1584 ++            printf("WARNING: More than one guest attached\n");
 54.1585 ++        }
 54.1586 ++    }
 54.1587 ++
 54.1588 ++    if (vtpm_tx_fh < 0) {
 54.1589 ++#ifdef VTPM_MUTLI_VM
 54.1590 ++	  vtpm_tx_fh = open(DEV_BE, O_RDWR);
 54.1591 ++	  vtpm_rx_fh = vtpm_tx_fh;
 54.1592 ++#else
 54.1593 ++      vtpm_tx_fh = open(GUEST_TX_FIFO, O_WRONLY);
 54.1594 ++#endif
 54.1595 ++    }
 54.1596 ++
 54.1597 ++    if (vtpm_tx_fh < 0) {
 54.1598 ++      printf("ERROR: failed to open devices to respond to guest.\n");
 54.1599 ++      return -1;
 54.1600 ++    }
 54.1601 ++    
 54.1602 ++    // Handle command, but we need to skip the identifier
 54.1603 ++    if (  BE16_TO_CPU( ((uint16_t *) in)[2] ) == VTPM_TAG_REQ ) { // Control message from xend
 54.1604 ++      // This DM doesn't really care about ctrl messages. Just ACK the message
 54.1605 ++      written = write(vtpm_tx_fh, ctrl_msg, sizeof(ctrl_msg));
 54.1606 ++
 54.1607 ++      if (written != sizeof(ctrl_msg)) {
 54.1608 ++        printf("ERROR: Part of response not written %d/%d.\n", written, sizeof(ctrl_msg));
 54.1609 ++      } else {
 54.1610 ++        printf("Send Ctrl Message confermation\n");
 54.1611 ++      }
 54.1612 ++    } else { // Message from Guest
 54.1613 ++      if (tpm_handle_command(in + sizeof(uint32_t), in_size - sizeof(uint32_t), &out, &out_size) != 0) { 
 54.1614 ++        printf("ERROR: Handler Failed.\n");
 54.1615 ++      }
 54.1616 ++
 54.1617 ++      addressed_out = (uint8_t *) tpm_malloc(sizeof(uint32_t) + out_size);
 54.1618 ++      *(uint32_t *) addressed_out = *(uint32_t *) in;
 54.1619 ++      memcpy(addressed_out + sizeof(uint32_t), out, out_size);
 54.1620 ++
 54.1621 ++      written = write(vtpm_tx_fh, addressed_out, out_size + sizeof(uint32_t));
 54.1622 ++
 54.1623 ++      if (written != out_size + sizeof(uint32_t)) {
 54.1624 ++        printf("ERROR: Part of response not written %d/%d.\n", written, out_size);
 54.1625 ++        for (i=0; i< out_size+ sizeof(uint32_t); i++)
 54.1626 ++          printf("%x ", addressed_out[i]);
 54.1627 ++        printf("\n");
 54.1628 ++      } else {
 54.1629 ++        printf("Sent[%d]: ", out_size + sizeof(uint32_t));
 54.1630 ++        for (i=0; i< out_size+ sizeof(uint32_t); i++)
 54.1631 ++          printf("%x ", addressed_out[i]);
 54.1632 ++        printf("\n");
 54.1633 ++      }
 54.1634 ++      tpm_free(out);
 54.1635 ++      tpm_free(addressed_out);
 54.1636 ++    }
 54.1637 ++
 54.1638 ++  } // loop
 54.1639 ++
 54.1640 ++  tpm_emulator_shutdown();
 54.1641 ++
 54.1642 ++  close(vtpm_tx_fh);
 54.1643 ++#ifndef VTPM_MUTLI_VM
 54.1644 ++  close(vtpm_rx_fh);
 54.1645 ++  free (guest_rx_file);
 54.1646 ++#endif
 54.1647 ++
 54.1648 ++}
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/tools/vtpm_manager/COPYING	Thu Sep 01 10:16:14 2005 +0000
    55.3 @@ -0,0 +1,32 @@
    55.4 +// ===================================================================
    55.5 +// 
    55.6 +// Copyright (c) 2005, Intel Corp.
    55.7 +// All rights reserved.
    55.8 +//
    55.9 +// Redistribution and use in source and binary forms, with or without 
   55.10 +// modification, are permitted provided that the following conditions 
   55.11 +// are met:
   55.12 +//
   55.13 +//   * Redistributions of source code must retain the above copyright 
   55.14 +//     notice, this list of conditions and the following disclaimer.
   55.15 +//   * Redistributions in binary form must reproduce the above 
   55.16 +//     copyright notice, this list of conditions and the following 
   55.17 +//     disclaimer in the documentation and/or other materials provided 
   55.18 +//     with the distribution.
   55.19 +//   * Neither the name of Intel Corporation nor the names of its 
   55.20 +//     contributors may be used to endorse or promote products derived
   55.21 +//     from this software without specific prior written permission.
   55.22 +//
   55.23 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   55.24 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   55.25 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
   55.26 +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
   55.27 +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   55.28 +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   55.29 +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
   55.30 +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   55.31 +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
   55.32 +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
   55.33 +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   55.34 +// OF THE POSSIBILITY OF SUCH DAMAGE.
   55.35 +// ===================================================================
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/tools/vtpm_manager/Makefile	Thu Sep 01 10:16:14 2005 +0000
    56.3 @@ -0,0 +1,31 @@
    56.4 +XEN_ROOT = ../..
    56.5 +
    56.6 +# Base definitions and rules
    56.7 +include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
    56.8 +
    56.9 +SUBDIRS		= crypto tcs util manager
   56.10 +
   56.11 +all: build
   56.12 +
   56.13 +build:
   56.14 +	@set -e; for subdir in $(SUBDIRS); do \
   56.15 +		$(MAKE) -C $$subdir $@; \
   56.16 +	done
   56.17 +
   56.18 +install: build
   56.19 +	@set -e; for subdir in $(SUBDIRS); do \
   56.20 +		$(MAKE) -C $$subdir $@; \
   56.21 +	done
   56.22 +
   56.23 +clean:
   56.24 +	@set -e; for subdir in $(SUBDIRS); do \
   56.25 +		$(MAKE) -C $$subdir $@; \
   56.26 +	done
   56.27 +
   56.28 +
   56.29 +mrproper:
   56.30 +	@set -e; for subdir in $(SUBDIRS); do \
   56.31 +		$(MAKE) -C $$subdir $@; \
   56.32 +	done
   56.33 +
   56.34 +
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/tools/vtpm_manager/README	Thu Sep 01 10:16:14 2005 +0000
    57.3 @@ -0,0 +1,89 @@
    57.4 +// ===================================================================
    57.5 +//
    57.6 +// Copyright (c) 2005, Intel Corp.
    57.7 +// All rights reserved.
    57.8 +//
    57.9 +// Redistribution and use in source and binary forms, with or without
   57.10 +// modification, are permitted provided that the following conditions
   57.11 +// are met:
   57.12 +//
   57.13 +//   * Redistributions of source code must retain the above copyright
   57.14 +//     notice, this list of conditions and the following disclaimer.
   57.15 +//   * Redistributions in binary form must reproduce the above
   57.16 +//     copyright notice, this list of conditions and the following
   57.17 +//     disclaimer in the documentation and/or other materials provided
   57.18 +//     with the distribution.
   57.19 +//   * Neither the name of Intel Corporation nor the names of its
   57.20 +//     contributors may be used to endorse or promote products derived
   57.21 +//     from this software without specific prior written permission.
   57.22 +//
   57.23 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   57.24 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   57.25 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   57.26 +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   57.27 +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   57.28 +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   57.29 +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   57.30 +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   57.31 +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   57.32 +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   57.33 +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   57.34 +// OF THE POSSIBILITY OF SUCH DAMAGE.
   57.35 +// ===================================================================
   57.36 +
   57.37 +Directory Structure
   57.38 +===================
   57.39 +tools/vtpm_manager/crypto    -> crypto files
   57.40 +tools/vtpm_manager/TCS       -> TCS implementation
   57.41 +tools/vtpm_manager/util      -> Utility Library. Include disk-io and buffers.
   57.42 +tools/vtpm_manager/manager   -> VTPM Manager
   57.43 +
   57.44 +Compile Flags
   57.45 +===================
   57.46 +LOGGING_MODULES              -> How extensive logging happens
   57.47 +                                see util/log.h for more info
   57.48 +
   57.49 +VTPM_MULTI_VM                -> Defined: VTPMs run in their own VMs
   57.50 +                                Not Defined (default): VTPMs are processes
   57.51 +
   57.52 +# Debugging flags that may disappear without notice in the future
   57.53 +
   57.54 +DUMMY_BACKEND                -> vtpm_manager listens on /tmp/in.fifo and 
   57.55 +                                /tmp/out.fifo rather than backend
   57.56 +
   57.57 +MANUAL_DM_LAUNCH             -> User must manually launch & kill VTPMs
   57.58 +
   57.59 +USE_FIXED_SRK_AUTH           -> Do not randomly generate a random SRK & Owner auth
   57.60 +
   57.61 +Requirements
   57.62 +============
   57.63 +- xen-unstable 
   57.64 +- IBM frontend/backend vtpm driver patch
   57.65 +
   57.66 +Single-VM Flow
   57.67 +============================
   57.68 +- Launch the VTPM manager (vtpm_managerd) which which begins listening to the BE with one thread
   57.69 +  and listens to a named fifo that is shared by the vtpms to commuincate with the manager.
   57.70 +- VTPM Manager listens to TPM BE.
   57.71 +- When xend launches a tpm frontend equipped VM it contacts the manager over the vtpm backend. 
   57.72 +- When the manager receives the open message from the BE, it launches a vtpm
   57.73 +- Xend allows the VM to continue booting. 
   57.74 +- When a TPM request is issued to the front end, the front end transmits the TPM request to the backend.
   57.75 +- The manager receives the TPM requests and uses a named fifo to forward the request to the vtpm.
   57.76 +- The fifo listener begins listening for the reply from vtpm for the request.
   57.77 +- Vtpm processes request and replies to manager over shared named fifo.
   57.78 +- If needed, the vtpm may send a request to the vtpm_manager at any time to save it's secrets to disk.
   57.79 +- Manager receives response from vtpm and passes it back to backend for forwarding to guest.
   57.80 +
   57.81 +NOTES:
   57.82 +* SaveService SHOULD seal it's table before saving it to disk. However,
   57.83 +  the current Xen infrastructure does not provide a mechanism for this to be
   57.84 +  unsealed later. Specifically, the auth and wrapped key must be available ONLY
   57.85 +  to the service, or it's not even worth encrypting
   57.86 +
   57.87 +  In the future the vtpm manager will be protected by an early boot mechanism
   57.88 +  that will allow for better protection of it's data.
   57.89 +
   57.90 +TODO:
   57.91 +- Timeout on crashed vtpms
   57.92 +- create lock for shared fifo for talking to vtpms.
    58.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    58.2 +++ b/tools/vtpm_manager/Rules.mk	Thu Sep 01 10:16:14 2005 +0000
    58.3 @@ -0,0 +1,68 @@
    58.4 +# Base definitions and rules (XEN_ROOT must be defined in including Makefile)
    58.5 +include $(XEN_ROOT)/tools/Rules.mk
    58.6 +
    58.7 +#
    58.8 +# Tool definitions
    58.9 +#
   58.10 +
   58.11 +# Installation program and options
   58.12 +INSTALL         = install
   58.13 +INSTALL_PROG    = $(INSTALL) -m0755
   58.14 +INSTALL_DIR     = $(INSTALL) -d -m0755
   58.15 +
   58.16 +# Xen tools installation directory
   58.17 +TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
   58.18 +
   58.19 +# General compiler flags
   58.20 +CFLAGS	= -Wall -Werror -g3 -I.
   58.21 +
   58.22 +# For generating dependencies
   58.23 +CFLAGS	+= -Wp,-MD,.$(@F).d
   58.24 +
   58.25 +DEP_FILES	= .*.d
   58.26 +
   58.27 +# Generic project files
   58.28 +HDRS	= $(wildcard *.h)
   58.29 +SRCS	= $(wildcard *.c)
   58.30 +OBJS	= $(patsubst %.c,%.o,$(SRCS))
   58.31 +
   58.32 +# Generic (non-header) dependencies
   58.33 +$(SRCS): Makefile $(XEN_ROOT)/tools/Rules.mk $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
   58.34 +
   58.35 +$(OBJS): $(SRCS)
   58.36 +
   58.37 +-include $(DEP_FILES)
   58.38 +
   58.39 +# Make sure these are just rules
   58.40 +.PHONY : all build install clean
   58.41 +
   58.42 +#
   58.43 +# Project-specific definitions
   58.44 +#
   58.45 +
   58.46 +# Logging Level. See utils/tools.h for usage
   58.47 +CFLAGS += -DLOGGING_MODULES="(BITMASK(VTPM_LOG_TCS)|BITMASK(VTPM_LOG_VTSP)|BITMASK(VTPM_LOG_VTPM)|BITMASK(VTPM_LOG_VTPM_DEEP))"
   58.48 +
   58.49 +# Silent Mode
   58.50 +#CFLAGS += -DLOGGING_MODULES=0x0
   58.51 +#CFLAGS += -DLOGGING_MODULES=0xff
   58.52 +
   58.53 +# Use frontend/backend pairs between manager & DMs?
   58.54 +#CFLAGS += -DVTPM_MULTI_VM
   58.55 +
   58.56 +# vtpm_manager listens on /tmp/in.fifo and /tmp/out.fifo rather than backend
   58.57 +#CFLAGS += -DDUMMY_BACKEND
   58.58 +
   58.59 +# Do not have manager launch DMs.
   58.60 +#CFLAGS += -DMANUAL_DM_LAUNCH
   58.61 +
   58.62 +# Fixed SRK
   58.63 +CFLAGS += -DUSE_FIXED_SRK_AUTH
   58.64 +
   58.65 +# TPM Hardware Device or TPM Simulator
   58.66 +#CFLAGS += -DTPM_HWDEV
   58.67 +
   58.68 +# Include
   58.69 +CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/crypto
   58.70 +CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/util
   58.71 +CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/tcs
    59.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.2 +++ b/tools/vtpm_manager/crypto/Makefile	Thu Sep 01 10:16:14 2005 +0000
    59.3 @@ -0,0 +1,18 @@
    59.4 +XEN_ROOT = ../../..
    59.5 +include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
    59.6 +
    59.7 +BIN		= libtcpaCrypto.a
    59.8 +
    59.9 +all: build
   59.10 +
   59.11 +build: $(BIN)
   59.12 +
   59.13 +install: build
   59.14 +
   59.15 +clean:
   59.16 +	rm -f *.a *.so *.o *.rpm $(DEP_FILES)
   59.17 +
   59.18 +mrproper: clean
   59.19 +
   59.20 +$(BIN): $(OBJS)
   59.21 +	$(AR) rcs $(BIN) $(OBJS)
    60.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.2 +++ b/tools/vtpm_manager/crypto/crypto.c	Thu Sep 01 10:16:14 2005 +0000
    60.3 @@ -0,0 +1,88 @@
    60.4 +// ===================================================================
    60.5 +// 
    60.6 +// Copyright (c) 2005, Intel Corp.
    60.7 +// All rights reserved.
    60.8 +//
    60.9 +// Redistribution and use in source and binary forms, with or without 
   60.10 +// modification, are permitted provided that the following conditions 
   60.11 +// are met:
   60.12 +//
   60.13 +//   * Redistributions of source code must retain the above copyright 
   60.14 +//     notice, this list of conditions and the following disclaimer.
   60.15 +//   * Redistributions in binary form must reproduce the above 
   60.16 +//     copyright notice, this list of conditions and the following 
   60.17 +//     disclaimer in the documentation and/or other materials provided 
   60.18 +//     with the distribution.
   60.19 +//   * Neither the name of Intel Corporation nor the names of its 
   60.20 +//     contributors may be used to endorse or promote products derived
   60.21 +//     from this software without specific prior written permission.
   60.22 +//
   60.23 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   60.24 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   60.25 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
   60.26 +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
   60.27 +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   60.28 +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   60.29 +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
   60.30 +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   60.31 +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
   60.32 +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
   60.33 +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   60.34 +// OF THE POSSIBILITY OF SUCH DAMAGE.
   60.35 +// ===================================================================
   60.36 +// 
   60.37 +// crypto.c
   60.38 +// 
   60.39 +//  This file will handle all the TPM Crypto functionality
   60.40 +// 
   60.41 +// ==================================================================
   60.42 +
   60.43 +#include <string.h>
   60.44 +#include <openssl/crypto.h>
   60.45 +#include <openssl/err.h>
   60.46 +#include <openssl/evp.h>
   60.47 +#include <openssl/rand.h>
   60.48 +#include "crypto.h"
   60.49 +#include "log.h"
   60.50 +
   60.51 +/**
   60.52 + * Initialize cryptography library
   60.53 + * @rand: random seed
   60.54 + * @size: size of @rand
   60.55 + */
   60.56 +void Crypto_Init(const BYTE* rand, int size) {
   60.57 +	ERR_load_crypto_strings();
   60.58 +  CRYPTO_malloc_init();
   60.59 +  OpenSSL_add_all_algorithms();
   60.60 +  SYM_CIPHER = EVP_aes_128_cbc();
   60.61 +  RAND_poll();
   60.62 +  if (rand == NULL)
   60.63 +    return;
   60.64 +
   60.65 +  RAND_add(rand, size, size);
   60.66 +}
   60.67 +
   60.68 +/**
   60.69 + * Shutdown cryptography library
   60.70 + */
   60.71 +void Crypto_Exit() {
   60.72 +  ERR_free_strings();
   60.73 +  ERR_remove_state(0);
   60.74 +  EVP_cleanup();
   60.75 +}
   60.76 +
   60.77 +
   60.78 +/**
   60.79 + * Get random data
   60.80 + * @data: (OUT) Random data
   60.81 + * @size: Size of @data
   60.82 + */
   60.83 +void Crypto_GetRandom(void* data, int size) {
   60.84 +  int result;
   60.85 +  
   60.86 +  result = RAND_pseudo_bytes((BYTE*) data, size);
   60.87 +  
   60.88 +  if (result <= 0) 
   60.89 +    vtpmlogerror (VTPM_LOG_CRYPTO, "RAND_pseudo_bytes failed: %s\n",
   60.90 +	     ERR_error_string (ERR_get_error(), NULL));
   60.91 +}
    61.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.2 +++ b/tools/vtpm_manager/crypto/crypto.h	Thu Sep 01 10:16:14 2005 +0000
    61.3 @@ -0,0 +1,175 @@
    61.4 +// ===================================================================
    61.5 +// 
    61.6 +// Copyright (c) 2005, Intel Corp.
    61.7 +// All rights reserved.
    61.8 +//
    61.9 +// Redistribution and use in source and binary forms, with or without 
   61.10 +// modification, are permitted provided that the following conditions 
   61.11 +// are met:
   61.12 +//
   61.13 +//   * Redistributions of source code must retain the above copyright 
   61.14 +//     notice, this list of conditions and the following disclaimer.
   61.15 +//   * Redistributions in binary form must reproduce the above 
   61.16 +//     copyright notice, this list of conditions and the following 
   61.17 +//     disclaimer in the documentation and/or other materials provided 
   61.18 +//     with the distribution.
   61.19 +//   * Neither the name of Intel Corporation nor the names of its 
   61.20 +//     contributors may be used to endorse or promote products derived
   61.21 +//     from this software without specific prior written permission.
   61.22 +//
   61.23 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   61.24 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   61.25 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
   61.26 +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
   61.27 +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   61.28 +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   61.29 +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
   61.30 +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   61.31 +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
   61.32 +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
   61.33 +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   61.34 +// OF THE POSSIBILITY OF SUCH DAMAGE.
   61.35 +// ===================================================================
   61.36 +// 
   61.37 +// crypto.h
   61.38 +// 
   61.39 +//  This file defines the TPM Crypto API
   61.40 +//
   61.41 +// ==================================================================
   61.42 +
   61.43 +#ifndef __CRYPTO_H__
   61.44 +#define __CRYPTO_H__
   61.45 +
   61.46 +#include <stddef.h>
   61.47 +#include <stdint.h>
   61.48 +#include <stdbool.h>
   61.49 +
   61.50 +#include "tcg.h"
   61.51 +#include "sym_crypto.h"
   61.52 +
   61.53 +#define CRYPTO_MAX_SIG_SIZE (2048 / 8)
   61.54 +#define CRYPTO_MAX_RSA_KEY_SIZE (4096 / 8) //in bytes
   61.55 +
   61.56 +#define OAEP_P "TCPA"
   61.57 +#define OAEP_P_SIZE 4
   61.58 +
   61.59 +// Algorithms supported by crypto. Stored in CRYPTO_INFO.algorithmID
   61.60 +#define CRYPTO_ALGORITH_RSA 0x01
   61.61 +
   61.62 +// Supported Encryption Schemes CRYPTO_INFO.encScheme
   61.63 +#define CRYPTO_ES_NONE 0x0001
   61.64 +#define CRYPTO_ES_RSAESPKCSv15 0x0002
   61.65 +#define CRYPTO_ES_RSAESOAEP_SHA1_MGF1 0x0003
   61.66 +
   61.67 +// Supported Signature schemes CRYPTO_INFO.sigScheme
   61.68 +#define CRYPTO_SS_NONE 0x0001
   61.69 +#define CRYPTO_SS_RSASSAPKCS1v15_SHA1 0x0002
   61.70 +#define CRYPTO_SS_RSASSAPKCS1v15_DER 0x0003
   61.71 +
   61.72 +typedef struct CRYPTO_INFO {
   61.73 +  void *keyInfo;
   61.74 +  UINT32 algorithmID;
   61.75 +  UINT32 encScheme;
   61.76 +  UINT32 sigScheme;
   61.77 +} CRYPTO_INFO;
   61.78 +
   61.79 +
   61.80 +void Crypto_Init(const BYTE* rand, int size);
   61.81 +
   61.82 +void Crypto_Exit();
   61.83 +
   61.84 +void Crypto_GetRandom(void* data, int size);
   61.85 +
   61.86 +void Crypto_HMAC(   const BYTE* text, 
   61.87 +                    int text_len, 
   61.88 +                    const BYTE* key, 
   61.89 +                    int key_len,
   61.90 +                    BYTE* digest);
   61.91 +
   61.92 +TPM_RESULT Crypto_HMAC_buf (const buffer_t * text,
   61.93 +                            const buffer_t * key,
   61.94 +                            BYTE * o_digest); /* presumably of 20 bytes */
   61.95 +    
   61.96 +void Crypto_SHA1Full(   const BYTE* text, 
   61.97 +                        UINT32 size,
   61.98 +                        BYTE* hash); //Complete 3part SHA1
   61.99 +
  61.100 +// o_hash needs to be large enough to hold the digest, ie 20 bytes
  61.101 +TPM_RESULT Crypto_SHA1Full_buf (const buffer_t * buf,
  61.102 +                                BYTE * o_hash);
  61.103 +    
  61.104 +void Crypto_SHA1Start(UINT32* maxNumBytes);
  61.105 +void Crypto_SHA1Update(int numBytes, const BYTE* hashData);
  61.106 +void Crypto_SHA1Complete(   int hashDataSize, 
  61.107 +                            const BYTE* hashData, 
  61.108 +                            BYTE* hashValue);
  61.109 +
  61.110 +void Crypto_RSACreateKey(   /*in*/ UINT32 keySize,
  61.111 +                            /*in*/ UINT32 pubExpSize, 
  61.112 +                            /*in*/ BYTE *pubExp,
  61.113 +                            /*out*/ UINT32 *privExpSize, 
  61.114 +                            /*out*/ BYTE *privExp,
  61.115 +                            /*out*/ UINT32 *modulusSize,
  61.116 +                            /*out*/ BYTE *modulus,
  61.117 +                            /*out*/ CRYPTO_INFO *keys);
  61.118 +                            
  61.119 +void Crypto_RSABuildCryptoInfo( /*[IN]*/ UINT32 pubExpSize, 
  61.120 +                                /*[IN]*/ BYTE *pubExp,
  61.121 +                                /*[IN]*/ UINT32 privExpSize, 
  61.122 +                                /*[IN]*/ BYTE *privExp,
  61.123 +                                /*[IN]*/ UINT32 modulusSize, 
  61.124 +                                /*[IN]*/ BYTE *modulus, 
  61.125 +                                /*[OUT]*/ CRYPTO_INFO* cryptoInfo);
  61.126 +                                
  61.127 +void Crypto_RSABuildCryptoInfoPublic(   /*[IN]*/ UINT32 pubExpSize, 
  61.128 +                                        /*[IN]*/ BYTE *pubExp,
  61.129 +                                        /*[IN]*/ UINT32 modulusSize, 
  61.130 +                                        /*[IN]*/ BYTE *modulus, 
  61.131 +                                        CRYPTO_INFO* cryptoInfo);
  61.132 +
  61.133 +//
  61.134 +// symmetric pack and unpack operations
  61.135 +//
  61.136 +TPM_RESULT Crypto_RSAPackCryptoInfo (const CRYPTO_INFO* cryptoInfo,
  61.137 +                                     BYTE ** io_buf, UINT32 * io_buflen);
  61.138 +
  61.139 +TPM_RESULT Crypto_RSAUnpackCryptoInfo (CRYPTO_INFO * ci,
  61.140 +                                       BYTE * in, UINT32 len,
  61.141 +                                       UINT32 * o_lenread);
  61.142 +
  61.143 +                             
  61.144 +// return 0 on success, -1 on error
  61.145 +int Crypto_RSAEnc(  CRYPTO_INFO *keys,
  61.146 +                    UINT32 inDataSize,
  61.147 +                    BYTE *inData,
  61.148 +                    /*out*/ UINT32 *outDataSize,
  61.149 +                    /*out*/ BYTE *outData);
  61.150 +
  61.151 +// return 0 on success, -1 on error
  61.152 +int Crypto_RSADec(  CRYPTO_INFO *keys,
  61.153 +                    UINT32 inDataSize,
  61.154 +                    BYTE *inData,
  61.155 +                    /*out*/ UINT32 *outDataSize,
  61.156 +                    /*out*/ BYTE *outData);
  61.157 +
  61.158 +// return 0 on success, -1 on error
  61.159 +int Crypto_RSASign( CRYPTO_INFO *keys,
  61.160 +                    UINT32 inDataSize,
  61.161 +                    BYTE *inData,
  61.162 +                    /*out*/ UINT32 *sigSize,
  61.163 +                    /*out*/ BYTE *sig);
  61.164 +
  61.165 +bool Crypto_RSAVerify(  CRYPTO_INFO *keys,
  61.166 +                        UINT32 inDataSize,
  61.167 +                        BYTE *inData,
  61.168 +                        UINT32 sigSize,
  61.169 +                        BYTE *sig);
  61.170 +
  61.171 +//private:
  61.172 +int RSA_verify_DER(int dtype, unsigned char *m, unsigned int m_len,
  61.173 +                   unsigned char *sigbuf, unsigned int siglen, CRYPTO_INFO *key);
  61.174 +
  61.175 +int RSA_sign_DER(int type, unsigned char *m, unsigned int m_len,
  61.176 +              unsigned char *sigret, unsigned int *siglen, CRYPTO_INFO *key);
  61.177 +
  61.178 +#endif // __CRYPTO_H__
    62.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.2 +++ b/tools/vtpm_manager/crypto/hash.c	Thu Sep 01 10:16:14 2005 +0000
    62.3 @@ -0,0 +1,153 @@
    62.4 +// ===================================================================
    62.5 +// 
    62.6 +// Copyright (c) 2005, Intel Corp.
    62.7 +// All rights reserved.
    62.8 +//
    62.9 +// Redistribution and use in source and binary forms, with or without 
   62.10 +// modification, are permitted provided that the following conditions 
   62.11 +// are met:
   62.12 +//
   62.13 +//   * Redistributions of source code must retain the above copyright 
   62.14 +//     notice, this list of conditions and the following disclaimer.
   62.15 +//   * Redistributions in binary form must reproduce the above 
   62.16 +//     copyright notice, this list of conditions and the following 
   62.17 +//     disclaimer in the documentation and/or other materials provided 
   62.18 +//     with the distribution.
   62.19 +//   * Neither the name of Intel Corporation nor the names of its 
   62.20 +//     contributors may be used to endorse or promote products derived
   62.21 +//     from this software without specific prior written permission.
   62.22 +//
   62.23 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   62.24 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   62.25 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
   62.26 +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
   62.27 +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   62.28 +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   62.29 +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
   62.30 +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   62.31 +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
   62.32 +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
   62.33 +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   62.34 +// OF THE POSSIBILITY OF SUCH DAMAGE.
   62.35 +// ===================================================================
   62.36 +// 
   62.37 +// hash.c
   62.38 +// 
   62.39 +//  This file will handle all the TPM Hash functionality
   62.40 +//
   62.41 +// ==================================================================
   62.42 +
   62.43 +#include <string.h>
   62.44 +#include <openssl/crypto.h>
   62.45 +#include <openssl/err.h>
   62.46 +#include <openssl/evp.h>
   62.47 +#include <openssl/rand.h>
   62.48 +#include <openssl/hmac.h>
   62.49 +#include <openssl/sha.h>
   62.50 +#include <openssl/bn.h>
   62.51 +#include <openssl/rsa.h>
   62.52 +
   62.53 +#include "tcg.h"         // for TPM_SUCCESS
   62.54 +#include "crypto.h"
   62.55 +
   62.56 +static SHA_CTX g_shaContext;
   62.57 +
   62.58 +void Crypto_HMAC(   const BYTE* text, 
   62.59 +                    int text_len, 
   62.60 +                    const BYTE* key, 
   62.61 +                    int key_len, 
   62.62 +                    BYTE* digest) {
   62.63 +  if (text == NULL || key == NULL || text_len == 0 || key_len == 0) 
   62.64 +    return;
   62.65 +  
   62.66 +  HMAC(EVP_sha1(), key, key_len, text, text_len, digest, NULL);
   62.67 +}
   62.68 +
   62.69 +TPM_RESULT Crypto_HMAC_buf (const buffer_t * text,
   62.70 +			    const buffer_t * key,
   62.71 +			    BYTE * o_digest) { /* presumably of 20 bytes */
   62.72 +  
   62.73 +  Crypto_HMAC (text->bytes, text->size, 
   62.74 +	       key->bytes, key->size,
   62.75 +	       o_digest);
   62.76 +  
   62.77 +  return TPM_SUCCESS;
   62.78 +}
   62.79 +
   62.80 +
   62.81 +/*
   62.82 + * SHA1
   62.83 + * (OUT) Create a SHA1 hash of text. Calls all three SHA1 steps internally
   62.84 + */
   62.85 +void Crypto_SHA1Full( const BYTE* text, 
   62.86 +      uint32_t size, 
   62.87 +      BYTE* hash) {
   62.88 +
   62.89 +  if (text == NULL || size == 0) 
   62.90 +    return;
   62.91 +  
   62.92 +  // Run SHA1Start + SHAUpdate (if necessary) + SHAComplete
   62.93 +  uint32_t maxBytes; // Not used for anything
   62.94 +  Crypto_SHA1Start(&maxBytes);
   62.95 +  
   62.96 +  while (size > 64){
   62.97 +    Crypto_SHA1Update(64, text); 
   62.98 +    size -= 64;
   62.99 +    text += 64;
  62.100 +  }
  62.101 +  
  62.102 +  Crypto_SHA1Complete(size, text, hash);
  62.103 +}
  62.104 +
  62.105 +// same thing using buffer_t
  62.106 +TPM_RESULT Crypto_SHA1Full_buf (const buffer_t * buf,
  62.107 +                                 BYTE * o_digest) {
  62.108 +
  62.109 +  if (buf->bytes == NULL || buf->size == 0) 
  62.110 +    return TPM_BAD_PARAMETER;
  62.111 +  
  62.112 +  Crypto_SHA1Full (buf->bytes, buf->size, o_digest);
  62.113 +  
  62.114 +  return TPM_SUCCESS;
  62.115 +}
  62.116 +
  62.117 +
  62.118 +/*
  62.119 + * Initialize SHA1
  62.120 + * (OUT) Maximum number of bytes that can be sent to SHA1Update. 
  62.121 + *   Must be a multiple of 64 bytes.
  62.122 + */
  62.123 +void Crypto_SHA1Start(uint32_t* maxNumBytes) {
  62.124 +  int max = SHA_CBLOCK;
  62.125 +  // Initialize the crypto library
  62.126 +  SHA1_Init(&g_shaContext);
  62.127 +  *maxNumBytes = max;
  62.128 +}
  62.129 +
  62.130 +/*
  62.131 + * Process SHA1
  62.132 + * @numBytes: (IN) The number of bytes in hashData. 
  62.133 + *       Must be a multiple of 64 bytes.
  62.134 + * @hashData: (IN) Bytes to be hashed.
  62.135 + */
  62.136 +void Crypto_SHA1Update(int numBytes, const BYTE* hashData) {
  62.137 +
  62.138 +  if (hashData == NULL || numBytes == 0 || numBytes%64 != 0) 
  62.139 +    return;
  62.140 +  
  62.141 +  SHA1_Update(&g_shaContext, hashData, numBytes); 
  62.142 +}
  62.143 +
  62.144 +/*
  62.145 + * Complete the SHA1 process
  62.146 + * @hashDataSize: (IN) Number of bytes in hashData.
  62.147 + *       Must be a multiple of 64 bytes.
  62.148 + * @hashData: (IN) Final bytes to be hashed.
  62.149 + * @hashValue: (OUT) The output of the SHA-1 hash.
  62.150 + */
  62.151 +void Crypto_SHA1Complete(int hashDataSize, 
  62.152 +			 const BYTE* hashData, 
  62.153 +			 BYTE* hashValue) {
  62.154 +  SHA1_Update(&g_shaContext, hashData, hashDataSize);
  62.155 +  SHA1_Final(hashValue, &g_shaContext);
  62.156 +}
    63.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.2 +++ b/tools/vtpm_manager/crypto/rsa.c	Thu Sep 01 10:16:14 2005 +0000
    63.3 @@ -0,0 +1,434 @@
    63.4 +// ===================================================================
    63.5 +// 
    63.6 +// Copyright (c) 2005, Intel Corp.
    63.7 +// All right