ia64/xen-unstable

changeset 10662:2b815d9acdea

merge with xen-unstable.hg
author awilliam@xenbuild.aw
date Wed Jul 05 20:11:37 2006 -0600 (2006-07-05)
parents 26dae1c72cd9 8e55c5c11475
children 49cea8b66d4a
files tools/libxc/xc_linux_build.c xen/arch/ia64/xen/dom0_ops.c xen/include/public/arch-ia64.h
line diff
     1.1 --- a/Makefile	Wed Jul 05 10:23:54 2006 -0600
     1.2 +++ b/Makefile	Wed Jul 05 20:11:37 2006 -0600
     1.3 @@ -130,6 +130,7 @@ distclean:
     1.4  	rm -rf dist patches/tmp
     1.5  	for i in $(ALLKERNELS) ; do $(MAKE) $$i-delete ; done
     1.6  	for i in $(ALLSPARSETREES) ; do $(MAKE) $$i-mrproper ; done
     1.7 +	rm -rf patches/*/.makedep
     1.8  
     1.9  # Linux name for GNU distclean
    1.10  .PHONY: mrproper
     2.1 --- a/buildconfigs/Rules.mk	Wed Jul 05 10:23:54 2006 -0600
     2.2 +++ b/buildconfigs/Rules.mk	Wed Jul 05 20:11:37 2006 -0600
     2.3 @@ -59,10 +59,6 @@ ifneq ($(PATCHDIRS),)
     2.4  $(patsubst patches/%,patches/%/.makedep,$(PATCHDIRS)): patches/%/.makedep: 
     2.5  	@echo 'ref-$*/.valid-ref: $$(wildcard patches/$*/*.patch)' >$@
     2.6  
     2.7 -.PHONY: clean
     2.8 -clean::
     2.9 -	rm -f patches/*/.makedep
    2.10 -
    2.11  ref-%/.valid-ref: pristine-%/.valid-pristine
    2.12  	set -e
    2.13  	rm -rf $(@D)
    2.14 @@ -111,7 +107,8 @@ linux-2.6-xen.patch: ref-linux-$(LINUX_V
    2.15  	rm -rf tmp-$@
    2.16  
    2.17  %-mrproper:
    2.18 -	rm -rf pristine-$(*)* ref-$(*)* $*.tar.bz2
    2.19 +	$(MAKE) -f buildconfigs/mk.$*-xen mrpropper
    2.20 +	rm -rf pristine-$(*)* ref-$(*)*
    2.21  	rm -rf $*-xen.patch
    2.22  
    2.23  .PHONY: config-update-pae
     3.1 --- a/buildconfigs/linux-defconfig_xen_x86_32	Wed Jul 05 10:23:54 2006 -0600
     3.2 +++ b/buildconfigs/linux-defconfig_xen_x86_32	Wed Jul 05 20:11:37 2006 -0600
     3.3 @@ -1902,6 +1902,7 @@ CONFIG_HANGCHECK_TIMER=m
     3.4  # TPM devices
     3.5  #
     3.6  CONFIG_TCG_TPM=m
     3.7 +CONFIG_TCG_TIS=m
     3.8  CONFIG_TCG_NSC=m
     3.9  CONFIG_TCG_ATMEL=m
    3.10  CONFIG_TCG_INFINEON=m
     4.1 --- a/buildconfigs/linux-defconfig_xen_x86_64	Wed Jul 05 10:23:54 2006 -0600
     4.2 +++ b/buildconfigs/linux-defconfig_xen_x86_64	Wed Jul 05 20:11:37 2006 -0600
     4.3 @@ -1765,6 +1765,7 @@ CONFIG_HANGCHECK_TIMER=m
     4.4  # TPM devices
     4.5  #
     4.6  CONFIG_TCG_TPM=m
     4.7 +CONFIG_TCG_TIS=m
     4.8  CONFIG_TCG_NSC=m
     4.9  CONFIG_TCG_ATMEL=m
    4.10  CONFIG_TCG_INFINEON=m
     5.1 --- a/buildconfigs/mk.linux-2.6-xen	Wed Jul 05 10:23:54 2006 -0600
     5.2 +++ b/buildconfigs/mk.linux-2.6-xen	Wed Jul 05 20:11:37 2006 -0600
     5.3 @@ -47,8 +47,14 @@ config: $(LINUX_DIR)/include/linux/autoc
     5.4  
     5.5  .PHONY: clean
     5.6  clean::
     5.7 -	$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) clean
     5.8 +	[ ! -d $(LINUX_DIR) ] || \
     5.9 +		$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) clean
    5.10 +
    5.11  
    5.12  .PHONY: delete
    5.13  delete: 
    5.14  	rm -rf tmp-linux-$(LINUX_VER) $(LINUX_DIR) 
    5.15 +
    5.16 +.PHONY: mrpropper
    5.17 +mrpropper:
    5.18 +	rm -f linux-$(LINUX_VER).tar.bz2
     6.1 --- a/docs/man/xm.pod.1	Wed Jul 05 10:23:54 2006 -0600
     6.2 +++ b/docs/man/xm.pod.1	Wed Jul 05 20:11:37 2006 -0600
     6.3 @@ -875,14 +875,43 @@ defined in the I<policy>. Unless specifi
     6.4  the currently enforced access control policy. The default for I<type>
     6.5  is 'dom'. The labels are arranged in alphabetical order.
     6.6  
     6.7 -=item B<addlabel> I<configfile> I<label> [I<policy>]
     6.8 +=item B<addlabel> I<label> dom I<configfile> [I<policy>]
     6.9 +
    6.10 +=item B<addlabel> I<label> res I<resource> [I<policy>]
    6.11  
    6.12  Adds the security label with name I<label> to a domain
    6.13 -I<configfile>. Unless specified, the default I<policy> is the
    6.14 +I<configfile> (dom) or to the global resource label file for the
    6.15 +given I<resource> (res). Unless specified, the default I<policy> is the
    6.16  currently enforced access control policy. This subcommand also
    6.17  verifies that the I<policy> definition supports the specified I<label>
    6.18  name.
    6.19  
    6.20 +=item B<rmlabel> dom I<configfile>
    6.21 +
    6.22 +=item B<rmlabel> res I<resource>
    6.23 +
    6.24 +Works the same as the I<addlabel> command (above), except that this
    6.25 +command will remove the label from the domain I<configfile> (dom) or
    6.26 +the global resource label file (res).
    6.27 +
    6.28 +=item B<getlabel> dom I<configfile>
    6.29 +
    6.30 +=item B<getlabel> res I<resource>
    6.31 +
    6.32 +Shows the label for the given I<configfile> or I<resource>
    6.33 +
    6.34 +=item B<resources>
    6.35 +
    6.36 +Lists all resources in the global resource label file.  Each resource
    6.37 +is listed with its associated label and policy name.
    6.38 +
    6.39 +=item B<dry-run> I<configfile>
    6.40 +
    6.41 +Determines if the specified I<configfile> describes a domain with a valid
    6.42 +security configuration for type enforcement. The test shows the policy
    6.43 +decision made for each resource label against the domain label as well as
    6.44 +the overall decision.
    6.45 +
    6.46  B<CONFIGURING SECURITY>
    6.47  
    6.48  =over 4
    6.49 @@ -960,17 +989,18 @@ B<ATTACHING A SECURITY LABEL TO A DOMAIN
    6.50  
    6.51  =over 4
    6.52  
    6.53 -This subcommand attaches a security label to a domain configuration
    6.54 -file, here a HomeBanking label. The example policy ensures that this
    6.55 -domain does not share information with other non-hombanking user
    6.56 -domains (i.e., domains labeled as dom_Fun or dom_Boinc) and that it
    6.57 -will not run simultaneously with domains labeled as dom_Fun.
    6.58 +The I<addlabel> subcommand can attach a security label to a domain
    6.59 +configuration file, here a HomeBanking label. The example policy
    6.60 +ensures that this domain does not share information with other
    6.61 +non-hombanking user domains (i.e., domains labeled as dom_Fun or
    6.62 +dom_Boinc) and that it will not run simultaneously with domains
    6.63 +labeled as dom_Fun.
    6.64  
    6.65  We assume that the specified myconfig.xm configuration file actually
    6.66  instantiates a domain that runs workloads related to home-banking,
    6.67  probably just a browser environment for online-banking.
    6.68  
    6.69 -    xm addlabel myconfig.xm dom_HomeBanking
    6.70 +    xm addlabel dom_HomeBanking dom myconfig.xm
    6.71  
    6.72  The very simple configuration file might now look as printed
    6.73  below. The I<addlabel> subcommand added the B<access_control> entry at
    6.74 @@ -997,6 +1027,38 @@ permitted".
    6.75  
    6.76  =back
    6.77  
    6.78 +B<ATTACHING A SECURITY LABEL TO A RESOURCE>
    6.79 +
    6.80 +=over 4
    6.81 +
    6.82 +The I<addlabel> subcommand can also be used to attach a security
    6.83 +label to a resource. Following the home banking example from above,
    6.84 +we can label a disk resource (e.g., a physical partition or a file)
    6.85 +to make it accessible to the home banking domain. The example policy
    6.86 +provides a resource label, res_LogicalDiskPartition1(hda1), that is
    6.87 +compatible with the HomeBanking domain label.
    6.88 +
    6.89 +    xm addlabel "res_LogicalDiskPartition1(hda1)" res phy:hda6
    6.90 +
    6.91 +After labeling this disk resource, it can be attached to the domain
    6.92 +by adding a line to the domain configuration file. The line below
    6.93 +attaches this disk to the domain at boot time.
    6.94 +
    6.95 +    disk = [ 'phy:hda6,sda2,w' ]
    6.96 +
    6.97 +Alternatively, the resource can be attached after booting the domain
    6.98 +by using the I<block-attach> subcommand.
    6.99 +
   6.100 +    xm block-attach homebanking phy:hda6 sda2 w
   6.101 +
   6.102 +Note that labeled resources cannot be used when security is turned
   6.103 +off.  Any attempt to use labeled resources with security turned off
   6.104 +will result in a failure with a corresponding error message.  The
   6.105 +solution is to enable security or, if security is no longer desired,
   6.106 +to remove the resource label using the I<rmlabel> subcommand.
   6.107 +
   6.108 +=back
   6.109 +
   6.110  B<STARTING AND LISTING LABELED DOMAINS>
   6.111  
   6.112  =over 4
   6.113 @@ -1011,6 +1073,21 @@ B<STARTING AND LISTING LABELED DOMAINS>
   6.114  
   6.115  =back
   6.116  
   6.117 +B<LISTING LABELED RESOURCES>
   6.118 +
   6.119 +=over 4
   6.120 +
   6.121 +    xm resources
   6.122 +
   6.123 +      phy:hda6
   6.124 +          policy: example.chwall_ste.client_v1
   6.125 +          label:  res_LogicalDiskPartition1(hda1)
   6.126 +      file:/xen/disk_image/disk.img
   6.127 +          policy: example.chwall_ste.client_v1
   6.128 +          label:  res_LogicalDiskPartition2(hda2)
   6.129 +
   6.130 +=back
   6.131 +
   6.132  B<POLICY REPRESENTATIONS>
   6.133  
   6.134  =over 4
     7.1 --- a/docs/misc/vtpm.txt	Wed Jul 05 10:23:54 2006 -0600
     7.2 +++ b/docs/misc/vtpm.txt	Wed Jul 05 20:11:37 2006 -0600
     7.3 @@ -1,5 +1,5 @@
     7.4  Copyright: IBM Corporation (C), Intel Corporation
     7.5 -17 August 2005
     7.6 +29 June 2006
     7.7  Authors: Stefan Berger <stefanb@us.ibm.com> (IBM), 
     7.8           Employees of Intel Corp
     7.9  
    7.10 @@ -9,24 +9,34 @@ instance and doing a short test to verif
    7.11  that the user is fairly familiar with compiling and installing XEN
    7.12  and Linux on a machine. 
    7.13   
    7.14 -Production Prerequisites: An x86-based machine machine with an ATMEL or
    7.15 -National Semiconductor (NSC) TPM on the motherboard.
    7.16 +Production Prerequisites: An x86-based machine machine with a
    7.17 +Linux-supported TPM on the motherboard (NSC, Atmel, Infineon, TPM V1.2).
    7.18  Development Prerequisites: An emulator for TESTING ONLY is provided
    7.19  
    7.20  
    7.21 -Compiling XEN tree:
    7.22 --------------------
    7.23 +Compiling the XEN tree:
    7.24 +-----------------------
    7.25  
    7.26  Compile the XEN tree as usual after the following lines set in the
    7.27  linux-2.6.??-xen/.config file:
    7.28  
    7.29 -CONFIG_XEN_TPMDEV_BACKEND=y
    7.30 +CONFIG_XEN_TPMDEV_BACKEND=m
    7.31 +
    7.32 +CONFIG_TCG_TPM=m
    7.33 +CONFIG_TCG_TIS=m      (supported after 2.6.17-rc4)
    7.34 +CONFIG_TCG_NSC=m
    7.35 +CONFIG_TCG_ATMEL=m
    7.36 +CONFIG_TCG_INFINEON=m
    7.37 +CONFIG_TCG_XEN=m
    7.38 +<possible other TPM drivers supported by Linux>
    7.39 +
    7.40 +If the frontend driver needs to be compiled into the user domain
    7.41 +kernel, then the following two lines should be changed.
    7.42  
    7.43  CONFIG_TCG_TPM=y
    7.44 -CONFIG_TCG_NSC=m
    7.45 -CONFIG_TCG_ATMEL=m
    7.46  CONFIG_TCG_XEN=y
    7.47  
    7.48 +
    7.49  You must also enable the virtual TPM to be built:
    7.50  
    7.51  In Config.mk in the Xen root directory set the line
    7.52 @@ -63,7 +73,7 @@ an example of how a user domain can be c
    7.53  available. It works similar to making a network interface
    7.54  available to a domain.
    7.55  
    7.56 -kernel = "/boot/vmlinuz-2.6.12-xenU"
    7.57 +kernel = "/boot/vmlinuz-2.6.x"
    7.58  ramdisk = "/xen/initrd_domU/U1_ramdisk.img"
    7.59  memory = 32
    7.60  name = "TPMUserDomain0"
    7.61 @@ -92,7 +102,7 @@ leave out the 'vtpm' line in the configu
    7.62  Running the TPM:
    7.63  ----------------
    7.64  
    7.65 -To run the vTPM, dev device /dev/vtpm must be available.
    7.66 +To run the vTPM, the device /dev/vtpm must be available.
    7.67  Verify that 'ls -l /dev/vtpm' shows the following output:
    7.68  
    7.69  crw-------  1 root root 10, 225 Aug 11 06:58 /dev/vtpm
    7.70 @@ -101,16 +111,26 @@ If it is not available, run the followin
    7.71  mknod /dev/vtpm c 10 225
    7.72  
    7.73  Make sure that the vTPM is running in domain 0. To do this run the
    7.74 -following
    7.75 +following:
    7.76 +
    7.77 +modprobe tpmbk
    7.78  
    7.79  /usr/bin/vtpm_managerd
    7.80  
    7.81  Start a user domain using the 'xm create' command. Once you are in the
    7.82 -shell of the user domain, you should be able to do the following:
    7.83 +shell of the user domain, you should be able to do the following as
    7.84 +user 'root':
    7.85  
    7.86 -> cd /sys/devices/vtpm
    7.87 +Insert the TPM frontend into the kernel if it has been compiled as a
    7.88 +kernel module.
    7.89 +
    7.90 +> modprobe tpm_xenu
    7.91 +
    7.92 +Check the status of the TPM
    7.93 +
    7.94 +> cd /sys/devices/xen/vtpm-0
    7.95  > ls
    7.96 -cancel  caps   pcrs    pubek
    7.97 +[...]  cancel  caps   pcrs    pubek   [...]
    7.98  > cat pcrs
    7.99  PCR-00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   7.100  PCR-01: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
     8.1 --- a/docs/src/user.tex	Wed Jul 05 10:23:54 2006 -0600
     8.2 +++ b/docs/src/user.tex	Wed Jul 05 20:11:37 2006 -0600
     8.3 @@ -2203,6 +2203,33 @@ ne2000 &        Enable ne2000, default =
     8.4  
     8.5  serial &        Enable redirection of VMX serial output to pty device\\
     8.6  
     8.7 +\end{tabular}
     8.8 +
     8.9 +\begin{tabular}{lp{10cm}}
    8.10 +
    8.11 +usb &           Enable USB support without defining a specific USB device.
    8.12 +This option defaults to 0 (disabled) unless the option usbdevice is
    8.13 +specified in which case this option then defaults to 1 (enabled).\\
    8.14 +
    8.15 +usbdevice &     Enable USB support and also enable support for the given
    8.16 +device.  Devices that can be specified are {\small {\tt mouse}} (a PS/2 style
    8.17 +mouse), {\small {\tt tablet}} (an absolute pointing device) and
    8.18 +{\small {\tt host:id1:id2}} (a physical USB device on the host machine whose
    8.19 +ids are {\small {\tt id1}} and {\small {\tt id2}}).  The advantage
    8.20 +of {\small {\tt tablet}} is that Windows guests will automatically recognize
    8.21 +and support this device so specifying the config line
    8.22 +
    8.23 +{\small
    8.24 +\begin{verbatim}
    8.25 +    usbdevice='tablet'
    8.26 +\end{verbatim}
    8.27 +}
    8.28 +
    8.29 +will create a mouse that works transparently with Windows guests under VNC.
    8.30 +Linux doesn't recognize the USB tablet yet so Linux guests under VNC will
    8.31 +still need the Summagraphics emulation.
    8.32 +Details about mouse emulation are provided in section \textbf{A.4.3}.\\
    8.33 +
    8.34  localtime &     Set the real time clock to local time [default=0, that is, set to UTC].\\
    8.35  
    8.36  enable-audio &  Enable audio support. This is under development.\\
    8.37 @@ -2317,29 +2344,458 @@ Simply follow the usual method of creati
    8.38  
    8.39  In the default configuration, VNC is on and SDL is off. Therefore VNC windows will open when VMX guests are created. If you want to use SDL to create VMX guests, set {\small {\tt sdl=1}} in your VMX configuration file. You can also turn off VNC by setting {\small {\tt vnc=0}}.
    8.40   
    8.41 -\subsection{Use mouse in VNC window}
    8.42 -The default PS/2 mouse will not work properly in VMX by a VNC window. Summagraphics mouse emulation does work in this environment. A Summagraphics mouse can be enabled by reconfiguring 2 services:
    8.43 -
    8.44 -{\small {\tt 1. General Purpose Mouse (GPM). The GPM daemon is configured in different ways in different Linux distributions. On a Redhat distribution, this is accomplished by changing the file `/etc/sysconfig/mouse' to have the following:\\
    8.45 -MOUSETYPE="summa"\\
    8.46 -XMOUSETYPE="SUMMA"\\
    8.47 -DEVICE=/dev/ttyS0\\
    8.48 -\\
    8.49 -2. X11. For all Linux distributions, change the Mouse0 stanza in `/etc/X11/xorg.conf' to:\\
    8.50 -Section "InputDevice"\\
    8.51 -Identifier "Mouse0"\\
    8.52 -Driver "summa"\\
    8.53 -Option "Device" "/dev/ttyS0"\\
    8.54 -Option "InputFashion" "Tablet"\\
    8.55 -Option "Mode" "Absolute"\\
    8.56 -Option "Name" "EasyPen"\\
    8.57 -Option "Compatible" "True"\\
    8.58 -Option "Protocol" "Auto"\\
    8.59 -Option "SendCoreEvents" "on"\\
    8.60 -Option "Vendor" "GENIUS"\\
    8.61 -EndSection}}
    8.62 -
    8.63 -If the Summagraphics mouse isn't the default mouse, you can manually kill 'gpm' and restart it with the command "gpm -m /dev/ttyS0 -t summa". Note that Summagraphics mouse makes no sense in an SDL window and is therefore not available in this environment.
    8.64 +\subsection{Mouse issues, especially under VNC}
    8.65 +Mouse handling when using VNC is a little problematic.
    8.66 +The problem is that the VNC viewer provides a virtual pointer which is
    8.67 +located at an absolute location in the VNC window and only absolute
    8.68 +coordinates are provided.
    8.69 +The VMX device model converts these absolute mouse coordinates
    8.70 +into the relative motion deltas that are expected by the PS/2
    8.71 +mouse driver running in the guest.
    8.72 +Unfortunately,
    8.73 +it is impossible to keep these generated mouse deltas
    8.74 +accurate enough for the guest cursor to exactly match
    8.75 +the VNC pointer.
    8.76 +This can lead to situations where the guest's cursor
    8.77 +is in the center of the screen and there's no way to
    8.78 +move that cursor to the left
    8.79 +(it can happen that the VNC pointer is at the left
    8.80 +edge of the screen and,
    8.81 +therefore,
    8.82 +there are no longer any left mouse deltas that
    8.83 +can be provided by the device model emulation code.)
    8.84 +
    8.85 +To deal with these mouse issues there are 4 different
    8.86 +mouse emulations available from the VMX device model:
    8.87 +
    8.88 +\begin{description}
    8.89 +\item[PS/2 mouse over the PS/2 port.]
    8.90 +This is the default mouse
    8.91 +that works perfectly well under SDL.
    8.92 +Under VNC the guest cursor will get
    8.93 +out of sync with the VNC pointer.
    8.94 +When this happens you can re-synchronize
    8.95 +the guest cursor to the VNC pointer by
    8.96 +holding down the
    8.97 +\textbf{left-ctl}
    8.98 +and
    8.99 +\textbf{left-alt}
   8.100 +keys together.
   8.101 +While these keys are down VNC pointer motions
   8.102 +will not be reported to the guest so
   8.103 +that the VNC pointer can be moved
   8.104 +to a place where it is possible
   8.105 +to move the guest cursor again.
   8.106 +
   8.107 +\item[Summagraphics mouse over the serial port.]
   8.108 +The device model also provides emulation
   8.109 +for a Summagraphics tablet,
   8.110 +an absolute pointer device.
   8.111 +This emulation is provided over the second
   8.112 +serial port,
   8.113 +\textbf{/dev/ttyS1}
   8.114 +for Linux guests and
   8.115 +\textbf{COM2}
   8.116 +for Windows guests.
   8.117 +Unfortunately,
   8.118 +neither Linux nor Windows provides
   8.119 +default support for the Summagraphics
   8.120 +tablet so the guest will have to be
   8.121 +manually configured for this mouse.
   8.122 +
   8.123 +\textbf{Linux configuration.}
   8.124 +
   8.125 +First,
   8.126 +configure the GPM service to use the Summagraphics tablet.
   8.127 +This can vary between distributions but,
   8.128 +typically,
   8.129 +all that needs to be done is modify the file
   8.130 +\path{/etc/sysconfig/mouse} to contain the lines:
   8.131 +
   8.132 +{\small
   8.133 +\begin{verbatim}
   8.134 +    MOUSETYPE="summa"
   8.135 +    XMOUSETYPE="SUMMA"
   8.136 +    DEVICE=/dev/ttyS1
   8.137 +\end{verbatim}
   8.138 +}
   8.139 +
   8.140 +and then restart the GPM daemon.
   8.141 +
   8.142 +Next,
   8.143 +modify the X11 config
   8.144 +\path{/etc/X11/xorg.conf}
   8.145 +to support the Summgraphics tablet by replacing
   8.146 +the input device stanza with the following:
   8.147 +
   8.148 +{\small
   8.149 +\begin{verbatim}
   8.150 +    Section "InputDevice"
   8.151 +        Identifier "Mouse0"
   8.152 +        Driver "summa"
   8.153 +        Option "Device" "/dev/ttyS1"
   8.154 +        Option "InputFashion" "Tablet"
   8.155 +        Option "Mode" "Absolute"
   8.156 +        Option "Name" "EasyPen"
   8.157 +        Option "Compatible" "True"
   8.158 +        Option "Protocol" "Auto"
   8.159 +        Option "SendCoreEvents" "on"
   8.160 +        Option "Vendor" "GENIUS"
   8.161 +    EndSection
   8.162 +\end{verbatim}
   8.163 +}
   8.164 +
   8.165 +Restart X and the X cursor should now properly
   8.166 +track the VNC pointer.
   8.167 +
   8.168 +
   8.169 +\textbf{Windows configuration.}
   8.170 +
   8.171 +Get the file
   8.172 +\path{http://www.cad-plan.de/files/download/tw2k.exe}
   8.173 +and execute that file on the guest,
   8.174 +answering the questions as follows:
   8.175 +
   8.176 +\begin{enumerate}
   8.177 +\item When the program asks for \textbf{model},
   8.178 +scroll down and selese \textbf{SummaSketch (MM Compatible)}.
   8.179 +
   8.180 +\item When the program asks for \textbf{COM Port} specify \textbf{com2}.
   8.181 +
   8.182 +\item When the programs asks for a \textbf{Cursor Type} specify
   8.183 +\textbf{4 button cursor/puck}.
   8.184 +
   8.185 +\item The guest system will then reboot and,
   8.186 +when it comes back up,
   8.187 +the guest cursor will now properly track
   8.188 +the VNC pointer.
   8.189 +\end{enumerate}
   8.190 +
   8.191 +\item[PS/2 mouse over USB port.]
   8.192 +This is just the same PS/2 emulation except it is
   8.193 +provided over a USB port.
   8.194 +This emulation is enabled by the configuration flag:
   8.195 +{\small
   8.196 +\begin{verbatim}
   8.197 +    usbdevice='mouse'
   8.198 +\end{verbatim}
   8.199 +}
   8.200 +
   8.201 +\item[USB tablet over USB port.]
   8.202 +The USB tablet is an absolute pointing device
   8.203 +that has the advantage that it is automatically
   8.204 +supported under Windows guests,
   8.205 +although Linux guests still require some
   8.206 +manual configuration.
   8.207 +This mouse emulation is enabled by the
   8.208 +configuration flag:
   8.209 +{\small
   8.210 +\begin{verbatim}
   8.211 +    usbdevice='tablet'
   8.212 +\end{verbatim}
   8.213 +}
   8.214 +
   8.215 +\textbf{Linux configuration.}
   8.216 +
   8.217 +Unfortunately,
   8.218 +there is no GPM support for the
   8.219 +USB tablet at this point in time.
   8.220 +If you intend to use a GPM pointing
   8.221 +device under VNC you should
   8.222 +configure the guest for Summagraphics
   8.223 +emulation.
   8.224 +
   8.225 +Support for X11 is available by following
   8.226 +the instructions at\\
   8.227 +\verb+http://stz-softwaretechnik.com/~ke/touchscreen/evtouch.html+\\
   8.228 +with one minor change.
   8.229 +The
   8.230 +\path{xorg.conf}
   8.231 +given in those instructions
   8.232 +uses the wrong values for the X \& Y minimums and maximums,
   8.233 +use the following config stanza instead:
   8.234 +
   8.235 +{\small
   8.236 +\begin{verbatim}
   8.237 +    Section "InputDevice"
   8.238 +        Identifier      "Tablet"
   8.239 +        Driver          "evtouch"
   8.240 +        Option          "Device" "/dev/input/event2"
   8.241 +        Option          "DeviceName" "touchscreen"
   8.242 +        Option          "MinX" "0"
   8.243 +        Option          "MinY" "0"
   8.244 +        Option          "MaxX" "32256"
   8.245 +        Option          "MaxY" "32256"
   8.246 +        Option          "ReportingMode" "Raw"
   8.247 +        Option          "Emulate3Buttons"
   8.248 +        Option          "Emulate3Timeout" "50"
   8.249 +        Option          "SendCoreEvents" "On"
   8.250 +    EndSection
   8.251 +\end{verbatim}
   8.252 +}
   8.253 +
   8.254 +\textbf{Windows configuration.}
   8.255 +
   8.256 +Just enabling the USB tablet in the
   8.257 +guest's configuration file is sufficient,
   8.258 +Windows will automatically recognize and
   8.259 +configure device drivers for this
   8.260 +pointing device.
   8.261 +
   8.262 +\end{description}
   8.263 +
   8.264 +\subsection{USB Support}
   8.265 +There is support for an emulated USB mouse,
   8.266 +an emulated USB tablet
   8.267 +and physical low speed USB devices
   8.268 +(support for high speed USB 2.0 devices is
   8.269 +still under development).
   8.270 +
   8.271 +\begin{description}
   8.272 +\item[USB PS/2 style mouse.]
   8.273 +Details on the USB mouse emulation are
   8.274 +given in sections
   8.275 +\textbf{A.2}
   8.276 +and
   8.277 +\textbf{A.4.3}.
   8.278 +Enabling USB PS/2 style mouse emulation
   8.279 +is just a matter of adding the line
   8.280 +
   8.281 +{\small
   8.282 +\begin{verbatim}
   8.283 +    usbdevice='mouse'
   8.284 +\end{verbatim}
   8.285 +}
   8.286 +
   8.287 +to the configuration file.
   8.288 +\item[USB tablet.]
   8.289 +Details on the USB tablet emulation are
   8.290 +given in sections
   8.291 +\textbf{A.2}
   8.292 +and
   8.293 +\textbf{A.4.3}.
   8.294 +Enabling USB tablet emulation
   8.295 +is just a matter of adding the line
   8.296 +
   8.297 +{\small
   8.298 +\begin{verbatim}
   8.299 +    usbdevice='tablet'
   8.300 +\end{verbatim}
   8.301 +}
   8.302 +
   8.303 +to the configuration file.
   8.304 +\item[USB physical devices.]
   8.305 +Access to a physical (low speed) USB device
   8.306 +is enabled by adding a line of the form
   8.307 +
   8.308 +{\small
   8.309 +\begin{verbatim}
   8.310 +    usbdevice='host:vid:pid'
   8.311 +\end{verbatim}
   8.312 +}
   8.313 +
   8.314 +into the the configuration file.\footnote{
   8.315 +There is an alternate
   8.316 +way of specifying a USB device that
   8.317 +uses the syntax
   8.318 +\textbf{host:bus.addr}
   8.319 +but this syntax suffers from
   8.320 +a major problem that makes
   8.321 +it effectively useless.
   8.322 +The problem is that the
   8.323 +\textbf{addr}
   8.324 +portion of this address
   8.325 +changes every time the USB device
   8.326 +is plugged into the system.
   8.327 +For this reason this addressing
   8.328 +scheme is not recommended and
   8.329 +will not be documented further.
   8.330 +}
   8.331 +\textbf{vid}
   8.332 +and
   8.333 +\textbf{pid}
   8.334 +are a
   8.335 +product id and
   8.336 +vendor id
   8.337 +that uniquely identify
   8.338 +the USB device.
   8.339 +These ids can be identified
   8.340 +in two ways:
   8.341 +
   8.342 +\begin{enumerate}
   8.343 +\item Through the control window.
   8.344 +As described in section
   8.345 +\textbf{A.4.6}
   8.346 +the control window
   8.347 +is activated by pressing
   8.348 +\textbf{ctl-alt-2}
   8.349 +in the guest VGA window.
   8.350 +As long as USB support is
   8.351 +enabled in the guest by including
   8.352 +the config file line
   8.353 +{\small
   8.354 +\begin{verbatim}
   8.355 +    usb=1
   8.356 +\end{verbatim}
   8.357 +}
   8.358 +then executing the command
   8.359 +{\small
   8.360 +\begin{verbatim}
   8.361 +    info usbhost
   8.362 +\end{verbatim}
   8.363 +}
   8.364 +in the control window
   8.365 +will display a list of all
   8.366 +usb devices and their ids.
   8.367 +For example,
   8.368 +this output:
   8.369 +{\small
   8.370 +\begin{verbatim}
   8.371 +    Device 1.3, speed 1.5 Mb/s
   8.372 +      Class 00: USB device 04b3:310b
   8.373 +\end{verbatim}
   8.374 +}
   8.375 +was created from a USB mouse with
   8.376 +vendor id
   8.377 +\textbf{04b3}
   8.378 +and product id
   8.379 +\textbf{310b}.
   8.380 +This device could be made available
   8.381 +to the VMX guest by including the
   8.382 +config file entry
   8.383 +{\small
   8.384 +\begin{verbatim}
   8.385 +    usbdevice='host:04be:310b'
   8.386 +\end{verbatim}
   8.387 +}
   8.388 +
   8.389 +It is also possible to
   8.390 +enable access to a USB
   8.391 +device dynamically through
   8.392 +the control window.
   8.393 +The control window command
   8.394 +{\small
   8.395 +\begin{verbatim}
   8.396 +    usb_add host:vid:pid
   8.397 +\end{verbatim}
   8.398 +}
   8.399 +will also allow access to a
   8.400 +USB device with vendor id
   8.401 +\textbf{vid}
   8.402 +and product id
   8.403 +\textbf{pid}.
   8.404 +\item Through the
   8.405 +\path{/proc} file system.
   8.406 +The contents of the pseudo file
   8.407 +\path{/proc/bus/usb/devices}
   8.408 +can also be used to identify
   8.409 +vendor and product ids.
   8.410 +Looking at this file,
   8.411 +the line starting with
   8.412 +\textbf{P:}
   8.413 +has a field
   8.414 +\textbf{Vendor}
   8.415 +giving the vendor id and
   8.416 +another field
   8.417 +\textbf{ProdID}
   8.418 +giving the product id.
   8.419 +The contents of
   8.420 +\path{/proc/bus/usb/devices}
   8.421 +for the example mouse is as
   8.422 +follows:
   8.423 +{\small
   8.424 +\begin{verbatim}
   8.425 +T:  Bus=01 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#=  3 Spd=1.5 MxCh= 0
   8.426 +D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
   8.427 +P:  Vendor=04b3 ProdID=310b Rev= 1.60
   8.428 +C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=100mA
   8.429 +I:  If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=01 Prot=02 Driver=(none)
   8.430 +E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=10ms
   8.431 +\end{verbatim}
   8.432 +}
   8.433 +Note that the
   8.434 +\textbf{P:}
   8.435 +line correctly identifies the
   8.436 +vendor id and product id
   8.437 +for this mouse as
   8.438 +\textbf{04b3:310b}.
   8.439 +\end{enumerate}
   8.440 +There is one other issue to
   8.441 +be aware of when accessing a
   8.442 +physical USB device from the guest.
   8.443 +The Dom0 kernel must not have
   8.444 +a device driver loaded for
   8.445 +the device that the guest wishes
   8.446 +to access.
   8.447 +This means that the Dom0
   8.448 +kernel must not have that
   8.449 +device driver compiled into
   8.450 +the kernel or,
   8.451 +if using modules,
   8.452 +that driver module must
   8.453 +not be loaded.
   8.454 +Note that this is the device
   8.455 +specific USB driver that must
   8.456 +not be loaded,
   8.457 +either the
   8.458 +\textbf{UHCI}
   8.459 +or
   8.460 +\textbf{OHCI}
   8.461 +USB controller driver must
   8.462 +still be loaded.
   8.463 +
   8.464 +Going back to the USB mouse
   8.465 +as an example,
   8.466 +if \textbf{lsmod}
   8.467 +gives the output:
   8.468 +
   8.469 +{\small
   8.470 +\begin{verbatim}
   8.471 +Module                  Size  Used by
   8.472 +usbmouse                4128  0 
   8.473 +usbhid                 28996  0
   8.474 +uhci_hcd               35409  0
   8.475 +\end{verbatim}
   8.476 +}
   8.477 +
   8.478 +then the USB mouse is being
   8.479 +used by the Dom0 kernel and is
   8.480 +not available to the guest.
   8.481 +Executing the command
   8.482 +\textbf{rmmod usbhid}\footnote{
   8.483 +Turns out the
   8.484 +\textbf{usbhid}
   8.485 +driver is the significant
   8.486 +one for the USB mouse,
   8.487 +the presence or absence of
   8.488 +the module
   8.489 +\textbf{usbmouse}
   8.490 +has no effect on whether or
   8.491 +not the guest can see a USB mouse.}
   8.492 +will remove the USB mouse
   8.493 +driver from the Dom0 kernel
   8.494 +and the mouse will now be
   8.495 +accessible by the VMX guest.
   8.496 +
   8.497 +Be aware the the Linux USB
   8.498 +hotplug system will reload
   8.499 +the drivers if a USB device
   8.500 +is removed and plugged back
   8.501 +in.
   8.502 +This means that just unloading
   8.503 +the driver module might not
   8.504 +be sufficient if the USB device
   8.505 +is removed and added back.
   8.506 +A more reliable technique is
   8.507 +to first
   8.508 +\textbf{rmmod}
   8.509 +the driver and then rename the
   8.510 +driver file in the
   8.511 +\path{/lib/modules}
   8.512 +directory,
   8.513 +just to make sure it doesn't get
   8.514 +reloaded.
   8.515 +\end{description}
   8.516  
   8.517  \subsection{Destroy VMX guests}
   8.518  VMX guests can be destroyed in the same way as can paravirtualized guests. We recommend that you type the command 
     9.1 --- a/extras/mini-os/console/xencons_ring.c	Wed Jul 05 10:23:54 2006 -0600
     9.2 +++ b/extras/mini-os/console/xencons_ring.c	Wed Jul 05 20:11:37 2006 -0600
     9.3 @@ -53,7 +53,7 @@ int xencons_ring_send(const char *data, 
     9.4  
     9.5  
     9.6  
     9.7 -static void handle_input(int port, struct pt_regs *regs)
     9.8 +static void handle_input(int port, struct pt_regs *regs, void *ign)
     9.9  {
    9.10  	struct xencons_interface *intf = xencons_interface();
    9.11  	XENCONS_RING_IDX cons, prod;
    9.12 @@ -83,7 +83,8 @@ int xencons_ring_init(void)
    9.13  	if (!start_info.console_evtchn)
    9.14  		return 0;
    9.15  
    9.16 -	err = bind_evtchn(start_info.console_evtchn, handle_input);
    9.17 +	err = bind_evtchn(start_info.console_evtchn, handle_input,
    9.18 +			  NULL);
    9.19  	if (err <= 0) {
    9.20  		printk("XEN console request chn bind failed %i\n", err);
    9.21  		return err;
    10.1 --- a/extras/mini-os/events.c	Wed Jul 05 10:23:54 2006 -0600
    10.2 +++ b/extras/mini-os/events.c	Wed Jul 05 20:11:37 2006 -0600
    10.3 @@ -22,9 +22,18 @@
    10.4  #include <events.h>
    10.5  #include <lib.h>
    10.6  
    10.7 +#define NR_EVS 1024
    10.8 +
    10.9 +/* this represents a event handler. Chaining or sharing is not allowed */
   10.10 +typedef struct _ev_action_t {
   10.11 +	void (*handler)(int, struct pt_regs *, void *);
   10.12 +	void *data;
   10.13 +    u32 count;
   10.14 +} ev_action_t;
   10.15 +
   10.16  
   10.17  static ev_action_t ev_actions[NR_EVS];
   10.18 -void default_handler(int port, struct pt_regs *regs);
   10.19 +void default_handler(int port, struct pt_regs *regs, void *data);
   10.20  
   10.21  
   10.22  /*
   10.23 @@ -35,42 +44,33 @@ int do_event(u32 port, struct pt_regs *r
   10.24      ev_action_t  *action;
   10.25      if (port >= NR_EVS) {
   10.26          printk("Port number too large: %d\n", port);
   10.27 -        goto out;
   10.28 +		goto out;
   10.29      }
   10.30  
   10.31      action = &ev_actions[port];
   10.32      action->count++;
   10.33  
   10.34 -    if (!action->handler)
   10.35 -    {
   10.36 -        printk("Spurious event on port %d\n", port);
   10.37 -        goto out;
   10.38 -    }
   10.39 -    
   10.40 -    if (action->status & EVS_DISABLED)
   10.41 -    {
   10.42 -        printk("Event on port %d disabled\n", port);
   10.43 -        goto out;
   10.44 -    }
   10.45 -    
   10.46      /* call the handler */
   10.47 -    action->handler(port, regs);
   10.48 -    
   10.49 +	action->handler(port, regs, action->data);
   10.50 +
   10.51   out:
   10.52  	clear_evtchn(port);
   10.53 +
   10.54      return 1;
   10.55  
   10.56  }
   10.57  
   10.58 -int bind_evtchn( u32 port, void (*handler)(int, struct pt_regs *) )
   10.59 +int bind_evtchn( u32 port, void (*handler)(int, struct pt_regs *, void *),
   10.60 +				 void *data )
   10.61  {
   10.62   	if(ev_actions[port].handler != default_handler)
   10.63          printk("WARN: Handler for port %d already registered, replacing\n",
   10.64  				port);
   10.65  
   10.66 +	ev_actions[port].data = data;
   10.67 +	wmb();
   10.68  	ev_actions[port].handler = handler;
   10.69 -	ev_actions[port].status &= ~EVS_DISABLED;	  
   10.70 - 
   10.71 +
   10.72  	/* Finally unmask the port */
   10.73  	unmask_evtchn(port);
   10.74  
   10.75 @@ -82,13 +82,14 @@ void unbind_evtchn( u32 port )
   10.76  	if (ev_actions[port].handler == default_handler)
   10.77  		printk("WARN: No handler for port %d when unbinding\n", port);
   10.78  	ev_actions[port].handler = default_handler;
   10.79 -	ev_actions[port].status |= EVS_DISABLED;
   10.80 +	wmb();
   10.81 +	ev_actions[port].data = NULL;
   10.82  }
   10.83  
   10.84 -int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *) )
   10.85 +int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *, void *data),
   10.86 +			   void *data)
   10.87  {
   10.88  	evtchn_op_t op;
   10.89 -	int ret = 0;
   10.90  
   10.91  	/* Try to bind the virq to a port */
   10.92  	op.cmd = EVTCHNOP_bind_virq;
   10.93 @@ -97,13 +98,11 @@ int bind_virq( u32 virq, void (*handler)
   10.94  
   10.95  	if ( HYPERVISOR_event_channel_op(&op) != 0 )
   10.96  	{
   10.97 -		ret = 1;
   10.98  		printk("Failed to bind virtual IRQ %d\n", virq);
   10.99 -		goto out;
  10.100 +		return 1;
  10.101      }
  10.102 -    bind_evtchn(op.u.bind_virq.port, handler);	
  10.103 -out:
  10.104 -	return ret;
  10.105 +    bind_evtchn(op.u.bind_virq.port, handler, data);
  10.106 +	return 0;
  10.107  }
  10.108  
  10.109  void unbind_virq( u32 port )
  10.110 @@ -137,13 +136,38 @@ void init_events(void)
  10.111  #endif
  10.112      /* inintialise event handler */
  10.113      for ( i = 0; i < NR_EVS; i++ )
  10.114 -    {
  10.115 -        ev_actions[i].status  = EVS_DISABLED;
  10.116 +	{
  10.117          ev_actions[i].handler = default_handler;
  10.118          mask_evtchn(i);
  10.119      }
  10.120  }
  10.121  
  10.122 -void default_handler(int port, struct pt_regs *regs) {
  10.123 +void default_handler(int port, struct pt_regs *regs, void *ignore)
  10.124 +{
  10.125      printk("[Port %d] - event received\n", port);
  10.126  }
  10.127 +
  10.128 +/* Unfortunate confusion of terminology: the port is unbound as far
  10.129 +   as Xen is concerned, but we automatically bind a handler to it
  10.130 +   from inside mini-os. */
  10.131 +int evtchn_alloc_unbound(void (*handler)(int, struct pt_regs *regs,
  10.132 +										 void *data),
  10.133 +						 void *data)
  10.134 +{
  10.135 +	u32 port;
  10.136 +	evtchn_op_t op;
  10.137 +	int err;
  10.138 +
  10.139 +	op.cmd = EVTCHNOP_alloc_unbound;
  10.140 +	op.u.alloc_unbound.dom = DOMID_SELF;
  10.141 +	op.u.alloc_unbound.remote_dom = 0;
  10.142 +
  10.143 +	err = HYPERVISOR_event_channel_op(&op);
  10.144 +	if (err) {
  10.145 +		printk("Failed to alloc unbound evtchn: %d.\n", err);
  10.146 +		return -1;
  10.147 +	}
  10.148 +	port = op.u.alloc_unbound.port;
  10.149 +	bind_evtchn(port, handler, data);
  10.150 +	return port;
  10.151 +}
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/extras/mini-os/gnttab.c	Wed Jul 05 20:11:37 2006 -0600
    11.3 @@ -0,0 +1,158 @@
    11.4 +/* 
    11.5 + ****************************************************************************
    11.6 + * (C) 2006 - Cambridge University
    11.7 + ****************************************************************************
    11.8 + *
    11.9 + *        File: gnttab.c
   11.10 + *      Author: Steven Smith (sos22@cam.ac.uk) 
   11.11 + *     Changes: Grzegorz Milos (gm281@cam.ac.uk)
   11.12 + *              
   11.13 + *        Date: July 2006
   11.14 + * 
   11.15 + * Environment: Xen Minimal OS
   11.16 + * Description: Simple grant tables implementation. About as stupid as it's
   11.17 + *  possible to be and still work.
   11.18 + *
   11.19 + ****************************************************************************
   11.20 + */
   11.21 +#include <os.h>
   11.22 +#include <mm.h>
   11.23 +#include <gnttab.h>
   11.24 +
   11.25 +#define NR_RESERVED_ENTRIES 8
   11.26 +
   11.27 +#define NR_GRANT_FRAMES 4
   11.28 +#define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
   11.29 +#define GNTTAB_LIST_END (NR_GRANT_ENTRIES + 1)
   11.30 +
   11.31 +static grant_entry_t *gnttab_table;
   11.32 +static grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
   11.33 +static grant_ref_t gnttab_free_head;
   11.34 +
   11.35 +static grant_ref_t
   11.36 +get_free_entries(int count)
   11.37 +{
   11.38 +    grant_ref_t ref;
   11.39 +    grant_ref_t head;
   11.40 +
   11.41 +    ref = head = gnttab_free_head;
   11.42 +    while (count-- > 1)
   11.43 +	head = gnttab_list[head];
   11.44 +    gnttab_free_head = gnttab_list[head];
   11.45 +    gnttab_list[head] = GNTTAB_LIST_END;
   11.46 +    return ref;
   11.47 +}
   11.48 +
   11.49 +static void
   11.50 +put_free_entry(grant_ref_t gref)
   11.51 +{
   11.52 +    gnttab_list[gref] = gnttab_free_head;
   11.53 +    gnttab_free_head = gref;
   11.54 +}
   11.55 +
   11.56 +grant_ref_t
   11.57 +gnttab_grant_access(domid_t domid, unsigned long frame, int readonly)
   11.58 +{
   11.59 +    grant_ref_t ref;
   11.60 +
   11.61 +    ref = get_free_entries(1);
   11.62 +    gnttab_table[ref].frame = frame;
   11.63 +    gnttab_table[ref].domid = domid;
   11.64 +    wmb();
   11.65 +    readonly *= GTF_readonly;
   11.66 +    gnttab_table[ref].flags = GTF_permit_access | readonly;
   11.67 +
   11.68 +    return ref;
   11.69 +}
   11.70 +
   11.71 +grant_ref_t
   11.72 +gnttab_grant_transfer(domid_t domid, unsigned long pfn)
   11.73 +{
   11.74 +    grant_ref_t ref;
   11.75 +
   11.76 +    ref = get_free_entries(1);
   11.77 +    gnttab_table[ref].frame = pfn;
   11.78 +    gnttab_table[ref].domid = domid;
   11.79 +    wmb();
   11.80 +    gnttab_table[ref].flags = GTF_accept_transfer;
   11.81 +
   11.82 +    return ref;
   11.83 +}
   11.84 +
   11.85 +int
   11.86 +gnttab_end_access(grant_ref_t ref)
   11.87 +{
   11.88 +    u16 flags, nflags;
   11.89 +
   11.90 +    nflags = gnttab_table[ref].flags;
   11.91 +    do {
   11.92 +        if ((flags = nflags) & (GTF_reading|GTF_writing)) {
   11.93 +            printk("WARNING: g.e. still in use!\n");
   11.94 +            return 0;
   11.95 +        }
   11.96 +    } while ((nflags = synch_cmpxchg(&gnttab_table[ref].flags, flags, 0)) !=
   11.97 +            flags);
   11.98 +
   11.99 +    put_free_entry(ref);
  11.100 +    return 1;
  11.101 +}
  11.102 +
  11.103 +unsigned long
  11.104 +gnttab_end_transfer(grant_ref_t ref)
  11.105 +{
  11.106 +    unsigned long frame;
  11.107 +    u16 flags;
  11.108 +
  11.109 +    while (!((flags = gnttab_table[ref].flags) & GTF_transfer_committed)) {
  11.110 +        if (synch_cmpxchg(&gnttab_table[ref].flags, flags, 0) == flags) {
  11.111 +            printk("Release unused transfer grant.\n");
  11.112 +            put_free_entry(ref);
  11.113 +            return 0;
  11.114 +        }
  11.115 +    }
  11.116 +
  11.117 +    /* If a transfer is in progress then wait until it is completed. */
  11.118 +    while (!(flags & GTF_transfer_completed)) {
  11.119 +        flags = gnttab_table[ref].flags;
  11.120 +    }
  11.121 +
  11.122 +    /* Read the frame number /after/ reading completion status. */
  11.123 +    rmb();
  11.124 +    frame = gnttab_table[ref].frame;
  11.125 +
  11.126 +    put_free_entry(ref);
  11.127 +
  11.128 +    return frame;
  11.129 +}
  11.130 +
  11.131 +grant_ref_t
  11.132 +gnttab_alloc_and_grant(void **map)
  11.133 +{
  11.134 +    unsigned long mfn;
  11.135 +    grant_ref_t gref;
  11.136 +
  11.137 +    *map = (void *)alloc_page();
  11.138 +    mfn = virt_to_mfn(*map);
  11.139 +    gref = gnttab_grant_access(0, mfn, 0);
  11.140 +    return gref;
  11.141 +}
  11.142 +
  11.143 +void
  11.144 +init_gnttab(void)
  11.145 +{
  11.146 +    struct gnttab_setup_table setup;
  11.147 +    unsigned long frames[NR_GRANT_FRAMES];
  11.148 +    int i;
  11.149 +
  11.150 +    for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++)
  11.151 +	gnttab_list[i] = i + 1;
  11.152 +    gnttab_free_head = NR_RESERVED_ENTRIES;
  11.153 +
  11.154 +    setup.dom = DOMID_SELF;
  11.155 +    setup.nr_frames = NR_GRANT_FRAMES;
  11.156 +    set_xen_guest_handle(setup.frame_list, frames);
  11.157 +
  11.158 +    HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
  11.159 +    gnttab_table = map_frames(frames, NR_GRANT_FRAMES);
  11.160 +    printk("gnttab_table mapped at %p.\n", gnttab_table);
  11.161 +}
    12.1 --- a/extras/mini-os/include/events.h	Wed Jul 05 10:23:54 2006 -0600
    12.2 +++ b/extras/mini-os/include/events.h	Wed Jul 05 20:11:37 2006 -0600
    12.3 @@ -22,28 +22,18 @@
    12.4  #include<traps.h>
    12.5  #include <xen/event_channel.h>
    12.6  
    12.7 -#define NR_EVS 1024
    12.8 -
    12.9 -/* ev handler status */
   12.10 -#define EVS_INPROGRESS	1	/* Event handler active - do not enter! */
   12.11 -#define EVS_DISABLED	2	/* Event disabled - do not enter! */
   12.12 -#define EVS_PENDING	    4	/* Event pending - replay on enable */
   12.13 -#define EVS_REPLAY	    8	/* Event has been replayed but not acked yet */
   12.14 -
   12.15 -/* this represents a event handler. Chaining or sharing is not allowed */
   12.16 -typedef struct _ev_action_t {
   12.17 -	void (*handler)(int, struct pt_regs *);
   12.18 -    unsigned int status;		/* IRQ status */
   12.19 -    u32 count;
   12.20 -} ev_action_t;
   12.21 -
   12.22  /* prototypes */
   12.23  int do_event(u32 port, struct pt_regs *regs);
   12.24 -int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *) );
   12.25 -int bind_evtchn( u32 virq, void (*handler)(int, struct pt_regs *) );
   12.26 +int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *, void *data),
   12.27 +			   void *data);
   12.28 +int bind_evtchn( u32 virq, void (*handler)(int, struct pt_regs *, void *data),
   12.29 +				 void *data );
   12.30  void unbind_evtchn( u32 port );
   12.31  void init_events(void);
   12.32  void unbind_virq( u32 port );
   12.33 +int evtchn_alloc_unbound(void (*handler)(int, struct pt_regs *regs,
   12.34 +										 void *data),
   12.35 +						 void *data);
   12.36  
   12.37  static inline int notify_remote_via_evtchn(int port)
   12.38  {
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/extras/mini-os/include/gnttab.h	Wed Jul 05 20:11:37 2006 -0600
    13.3 @@ -0,0 +1,14 @@
    13.4 +#ifndef __GNTTAB_H__
    13.5 +#define __GNTTAB_H__
    13.6 +
    13.7 +#include <xen/grant_table.h>
    13.8 +
    13.9 +void init_gnttab(void);
   13.10 +grant_ref_t gnttab_alloc_and_grant(void **map);
   13.11 +grant_ref_t gnttab_grant_access(domid_t domid, unsigned long frame,
   13.12 +				int readonly);
   13.13 +grant_ref_t gnttab_grant_transfer(domid_t domid, unsigned long pfn);
   13.14 +unsigned long gnttab_end_transfer(grant_ref_t gref);
   13.15 +int gnttab_end_access(grant_ref_t ref);
   13.16 +
   13.17 +#endif /* !__GNTTAB_H__ */
    14.1 --- a/extras/mini-os/include/lib.h	Wed Jul 05 10:23:54 2006 -0600
    14.2 +++ b/extras/mini-os/include/lib.h	Wed Jul 05 20:11:37 2006 -0600
    14.3 @@ -89,6 +89,7 @@ size_t strlen(const char *s);
    14.4  char  *strchr(const char *s, int c);
    14.5  char  *strstr(const char *s1, const char *s2);
    14.6  char * strcat(char * dest, const char * src);
    14.7 +char  *strdup(const char *s);
    14.8  
    14.9  
   14.10  #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
   14.11 @@ -98,6 +99,18 @@ struct kvec {
   14.12      size_t iov_len;
   14.13  };
   14.14  
   14.15 +#define ASSERT(x)                                              \
   14.16 +do {                                                           \
   14.17 +	if (!(x)) {                                                \
   14.18 +		printk("ASSERTION FAILED: %s at %s:%d.\n",             \
   14.19 +			   # x ,                                           \
   14.20 +			   __FILE__,                                       \
   14.21 +			   __LINE__);                                      \
   14.22 +        BUG();                                                 \
   14.23 +	}                                                          \
   14.24 +} while(0)
   14.25  
   14.26 +/* Consistency check as much as possible. */
   14.27 +void sanity_check(void);
   14.28  
   14.29  #endif /* _LIB_H_ */
    15.1 --- a/extras/mini-os/include/mm.h	Wed Jul 05 10:23:54 2006 -0600
    15.2 +++ b/extras/mini-os/include/mm.h	Wed Jul 05 20:11:37 2006 -0600
    15.3 @@ -196,9 +196,11 @@ static __inline__ paddr_t machine_to_phy
    15.4  #define to_virt(x)                 ((void *)((unsigned long)(x)+VIRT_START))
    15.5  
    15.6  #define virt_to_pfn(_virt)         (PFN_DOWN(to_phys(_virt)))
    15.7 +#define virt_to_mfn(_virt)         (pfn_to_mfn(virt_to_pfn(_virt)))
    15.8  #define mach_to_virt(_mach)        (to_virt(machine_to_phys(_mach)))
    15.9 +#define virt_to_mach(_virt)        (phys_to_machine(to_phys(_virt)))
   15.10  #define mfn_to_virt(_mfn)          (to_virt(mfn_to_pfn(_mfn) << PAGE_SHIFT))
   15.11 -#define pfn_to_virt(_pfn)          (to_virt(_pfn << PAGE_SHIFT))
   15.12 +#define pfn_to_virt(_pfn)          (to_virt((_pfn) << PAGE_SHIFT))
   15.13  
   15.14  /* Pagetable walking. */
   15.15  #define pte_to_mfn(_pte)           (((_pte) & (PADDR_MASK&PAGE_MASK)) >> L1_PAGETABLE_SHIFT)
   15.16 @@ -206,7 +208,7 @@ static __inline__ paddr_t machine_to_phy
   15.17  
   15.18  void init_mm(void);
   15.19  unsigned long alloc_pages(int order);
   15.20 -#define alloc_page()    alloc_pages(0);
   15.21 +#define alloc_page()    alloc_pages(0)
   15.22  void free_pages(void *pointer, int order);
   15.23  
   15.24  static __inline__ int get_order(unsigned long size)
   15.25 @@ -219,4 +221,6 @@ static __inline__ int get_order(unsigned
   15.26  }
   15.27  
   15.28  
   15.29 +void *map_frames(unsigned long *f, unsigned long n);
   15.30 +
   15.31  #endif /* _MM_H_ */
    16.1 --- a/extras/mini-os/include/os.h	Wed Jul 05 10:23:54 2006 -0600
    16.2 +++ b/extras/mini-os/include/os.h	Wed Jul 05 20:11:37 2006 -0600
    16.3 @@ -445,7 +445,62 @@ static __inline__ unsigned long __ffs(un
    16.4  
    16.5  
    16.6  /********************* common i386 and x86_64  ****************************/
    16.7 +struct __synch_xchg_dummy { unsigned long a[100]; };
    16.8 +#define __synch_xg(x) ((struct __synch_xchg_dummy *)(x))
    16.9  
   16.10 +#define synch_cmpxchg(ptr, old, new) \
   16.11 +((__typeof__(*(ptr)))__synch_cmpxchg((ptr),\
   16.12 +                                     (unsigned long)(old), \
   16.13 +                                     (unsigned long)(new), \
   16.14 +                                     sizeof(*(ptr))))
   16.15 +
   16.16 +static inline unsigned long __synch_cmpxchg(volatile void *ptr,
   16.17 +        unsigned long old,
   16.18 +        unsigned long new, int size)
   16.19 +{
   16.20 +    unsigned long prev;
   16.21 +    switch (size) {
   16.22 +        case 1:
   16.23 +            __asm__ __volatile__("lock; cmpxchgb %b1,%2"
   16.24 +                    : "=a"(prev)
   16.25 +                    : "q"(new), "m"(*__synch_xg(ptr)),
   16.26 +                    "0"(old)
   16.27 +                    : "memory");
   16.28 +            return prev;
   16.29 +        case 2:
   16.30 +            __asm__ __volatile__("lock; cmpxchgw %w1,%2"
   16.31 +                    : "=a"(prev)
   16.32 +                    : "r"(new), "m"(*__synch_xg(ptr)),
   16.33 +                    "0"(old)
   16.34 +                    : "memory");
   16.35 +            return prev;
   16.36 +#ifdef __x86_64__
   16.37 +        case 4:
   16.38 +            __asm__ __volatile__("lock; cmpxchgl %k1,%2"
   16.39 +                    : "=a"(prev)
   16.40 +                    : "r"(new), "m"(*__synch_xg(ptr)),
   16.41 +                    "0"(old)
   16.42 +                    : "memory");
   16.43 +            return prev;
   16.44 +        case 8:
   16.45 +            __asm__ __volatile__("lock; cmpxchgq %1,%2"
   16.46 +                    : "=a"(prev)
   16.47 +                    : "r"(new), "m"(*__synch_xg(ptr)),
   16.48 +                    "0"(old)
   16.49 +                    : "memory");
   16.50 +            return prev;
   16.51 +#else
   16.52 +        case 4:
   16.53 +            __asm__ __volatile__("lock; cmpxchgl %1,%2"
   16.54 +                    : "=a"(prev)
   16.55 +                    : "r"(new), "m"(*__synch_xg(ptr)),
   16.56 +                    "0"(old)
   16.57 +                    : "memory");
   16.58 +            return prev;
   16.59 +#endif
   16.60 +    }
   16.61 +    return old;
   16.62 +}
   16.63  
   16.64  
   16.65  static __inline__ void synch_set_bit(int nr, volatile void * addr)
    17.1 --- a/extras/mini-os/include/xenbus.h	Wed Jul 05 10:23:54 2006 -0600
    17.2 +++ b/extras/mini-os/include/xenbus.h	Wed Jul 05 20:11:37 2006 -0600
    17.3 @@ -1,34 +1,51 @@
    17.4  #ifndef XENBUS_H__
    17.5  #define XENBUS_H__
    17.6  
    17.7 +typedef unsigned long xenbus_transaction_t;
    17.8 +#define XBT_NIL ((xenbus_transaction_t)0)
    17.9 +
   17.10  /* Initialize the XenBus system. */
   17.11  void init_xenbus(void);
   17.12  
   17.13  /* Read the value associated with a path.  Returns a malloc'd error
   17.14     string on failure and sets *value to NULL.  On success, *value is
   17.15     set to a malloc'd copy of the value. */
   17.16 -char *xenbus_read(const char *path, char **value);
   17.17 +char *xenbus_read(xenbus_transaction_t xbt, const char *path, char **value);
   17.18  
   17.19  /* Associates a value with a path.  Returns a malloc'd error string on
   17.20     failure. */
   17.21 -char *xenbus_write(const char *path, const char *value);
   17.22 +char *xenbus_write(xenbus_transaction_t xbt, const char *path, const char *value);
   17.23  
   17.24  /* Removes the value associated with a path.  Returns a malloc'd error
   17.25     string on failure. */
   17.26 -char *xenbus_rm(const char *path);
   17.27 +char *xenbus_rm(xenbus_transaction_t xbt, const char *path);
   17.28  
   17.29  /* List the contents of a directory.  Returns a malloc'd error string
   17.30     on failure and sets *contents to NULL.  On success, *contents is
   17.31     set to a malloc'd array of pointers to malloc'd strings.  The array
   17.32     is NULL terminated.  May block. */
   17.33 -char *xenbus_ls(const char *prefix, char ***contents);
   17.34 +char *xenbus_ls(xenbus_transaction_t xbt, const char *prefix, char ***contents);
   17.35  
   17.36  /* Reads permissions associated with a path.  Returns a malloc'd error
   17.37     string on failure and sets *value to NULL.  On success, *value is
   17.38     set to a malloc'd copy of the value. */
   17.39 -char *xenbus_get_perms(const char *path, char **value);
   17.40 +char *xenbus_get_perms(xenbus_transaction_t xbt, const char *path, char **value);
   17.41  
   17.42  /* Sets the permissions associated with a path.  Returns a malloc'd
   17.43     error string on failure. */
   17.44 -char *xenbus_set_perms(const char *path, domid_t dom, char perm);
   17.45 +char *xenbus_set_perms(xenbus_transaction_t xbt, const char *path, domid_t dom, char perm);
   17.46 +
   17.47 +/* Start a xenbus transaction.  Returns the transaction in xbt on
   17.48 +   success or a malloc'd error string otherwise. */
   17.49 +char *xenbus_transaction_start(xenbus_transaction_t *xbt);
   17.50 +
   17.51 +/* End a xenbus transaction.  Returns a malloc'd error string if it
   17.52 +   fails.  abort says whether the transaction should be aborted.
   17.53 +   Returns 1 in *retry iff the transaction should be retried. */
   17.54 +char *xenbus_transaction_end(xenbus_transaction_t, int abort,
   17.55 +			     int *retry);
   17.56 +
   17.57 +/* Read path and parse it as an integer.  Returns -1 on error. */
   17.58 +int xenbus_read_integer(char *path);
   17.59 +
   17.60  #endif /* XENBUS_H__ */
    18.1 --- a/extras/mini-os/kernel.c	Wed Jul 05 10:23:54 2006 -0600
    18.2 +++ b/extras/mini-os/kernel.c	Wed Jul 05 20:11:37 2006 -0600
    18.3 @@ -35,6 +35,7 @@
    18.4  #include <lib.h>
    18.5  #include <sched.h>
    18.6  #include <xenbus.h>
    18.7 +#include <gnttab.h>
    18.8  #include <xen/features.h>
    18.9  #include <xen/version.h>
   18.10  
   18.11 @@ -104,7 +105,8 @@ void test_xenbus(void);
   18.12  
   18.13  void xenbus_tester(void *p)
   18.14  {
   18.15 -    test_xenbus();
   18.16 +    printk("Xenbus tests disabled, because of a Xend bug.\n");
   18.17 +    /* test_xenbus(); */
   18.18  }
   18.19  
   18.20  /* This should be overridden by the application we are linked against. */
   18.21 @@ -176,7 +178,10 @@ void start_kernel(start_info_t *si)
   18.22  
   18.23      /* Init the console driver. */
   18.24      init_console();
   18.25 - 
   18.26 +
   18.27 +    /* Init grant tables */
   18.28 +    init_gnttab();
   18.29 +    
   18.30      /* Init scheduler. */
   18.31      init_sched();
   18.32   
    19.1 --- a/extras/mini-os/lib/string.c	Wed Jul 05 10:23:54 2006 -0600
    19.2 +++ b/extras/mini-os/lib/string.c	Wed Jul 05 20:11:37 2006 -0600
    19.3 @@ -23,6 +23,7 @@
    19.4  #include <os.h>
    19.5  #include <types.h>
    19.6  #include <lib.h>
    19.7 +#include <xmalloc.h>
    19.8  
    19.9  int memcmp(const void * cs,const void * ct,size_t count)
   19.10  {
   19.11 @@ -156,4 +157,13 @@ char * strstr(const char * s1,const char
   19.12          return NULL;
   19.13  }
   19.14  
   19.15 +char *strdup(const char *x)
   19.16 +{
   19.17 +    int l = strlen(x);
   19.18 +    char *res = malloc(l + 1);
   19.19 +	if (!res) return NULL;
   19.20 +    memcpy(res, x, l + 1);
   19.21 +    return res;
   19.22 +}
   19.23 +
   19.24  #endif
    20.1 --- a/extras/mini-os/mm.c	Wed Jul 05 10:23:54 2006 -0600
    20.2 +++ b/extras/mini-os/mm.c	Wed Jul 05 20:11:37 2006 -0600
    20.3 @@ -343,7 +343,7 @@ void free_pages(void *pointer, int order
    20.4                  break;
    20.5              
    20.6              /* Merge with successor */
    20.7 -            freed_ct = (chunk_tail_t *)((char *)to_merge_ch + mask);
    20.8 +            freed_ct = (chunk_tail_t *)((char *)to_merge_ch + mask) - 1;
    20.9          }
   20.10          
   20.11          /* We are commited to merging, unlink the chunk */
   20.12 @@ -612,6 +612,107 @@ void mem_test(unsigned long *start_add, 
   20.13  
   20.14  }
   20.15  
   20.16 +static pgentry_t *demand_map_pgt;
   20.17 +static void *demand_map_area_start;
   20.18 +
   20.19 +static void init_demand_mapping_area(unsigned long max_pfn)
   20.20 +{
   20.21 +    unsigned long mfn;
   20.22 +    pgentry_t *tab;
   20.23 +    unsigned long start_addr;
   20.24 +    unsigned long pt_pfn;
   20.25 +    unsigned offset;
   20.26 +
   20.27 +    /* Round up to four megs.  + 1024 rather than + 1023 since we want
   20.28 +       to be sure we don't end up in the same place we started. */
   20.29 +    max_pfn = (max_pfn + L1_PAGETABLE_ENTRIES) & ~(L1_PAGETABLE_ENTRIES - 1);
   20.30 +    if (max_pfn == 0 ||
   20.31 +            (unsigned long)pfn_to_virt(max_pfn + L1_PAGETABLE_ENTRIES) >=
   20.32 +            HYPERVISOR_VIRT_START) {
   20.33 +        printk("Too much memory; no room for demand map hole.\n");
   20.34 +        do_exit();
   20.35 +    }
   20.36 +
   20.37 +    demand_map_area_start = pfn_to_virt(max_pfn);
   20.38 +    printk("Demand map pfns start at %lx (%p).\n", max_pfn,
   20.39 +            demand_map_area_start);
   20.40 +    start_addr = (unsigned long)demand_map_area_start;
   20.41 +
   20.42 +    tab = (pgentry_t *)start_info.pt_base;
   20.43 +    mfn = virt_to_mfn(start_info.pt_base);
   20.44 +    pt_pfn = virt_to_pfn(alloc_page());
   20.45 +
   20.46 +#if defined(__x86_64__)
   20.47 +    offset = l4_table_offset(start_addr);
   20.48 +    if (!(tab[offset] & _PAGE_PRESENT)) {
   20.49 +        new_pt_frame(&pt_pfn, mfn, offset, L3_FRAME);
   20.50 +        pt_pfn = virt_to_pfn(alloc_page());
   20.51 +    }
   20.52 +    ASSERT(tab[offset] & _PAGE_PRESENT);
   20.53 +    mfn = pte_to_mfn(tab[offset]);
   20.54 +    tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
   20.55 +#endif
   20.56 +#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
   20.57 +    offset = l3_table_offset(start_addr);
   20.58 +    if (!(tab[offset] & _PAGE_PRESENT)) {
   20.59 +        new_pt_frame(&pt_pfn, mfn, offset, L2_FRAME);
   20.60 +        pt_pfn = virt_to_pfn(alloc_page());
   20.61 +    }
   20.62 +    ASSERT(tab[offset] & _PAGE_PRESENT);
   20.63 +    mfn = pte_to_mfn(tab[offset]);
   20.64 +    tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
   20.65 +#endif
   20.66 +    offset = l2_table_offset(start_addr);
   20.67 +    if (tab[offset] & _PAGE_PRESENT) {
   20.68 +        printk("Demand map area already has a page table covering it?\n");
   20.69 +        BUG();
   20.70 +    }
   20.71 +    demand_map_pgt = pfn_to_virt(pt_pfn);
   20.72 +    new_pt_frame(&pt_pfn, mfn, offset, L1_FRAME);
   20.73 +    ASSERT(tab[offset] & _PAGE_PRESENT);
   20.74 +}
   20.75 +
   20.76 +void *map_frames(unsigned long *f, unsigned long n)
   20.77 +{
   20.78 +    unsigned long x;
   20.79 +    unsigned long y = 0;
   20.80 +    mmu_update_t mmu_updates[16];
   20.81 +    int rc;
   20.82 +
   20.83 +    if (n > 16) {
   20.84 +        printk("Tried to map too many (%ld) frames at once.\n", n);
   20.85 +        return NULL;
   20.86 +    }
   20.87 +
   20.88 +    /* Find a run of n contiguous frames */
   20.89 +    for (x = 0; x <= 1024 - n; x += y + 1) {
   20.90 +        for (y = 0; y < n; y++)
   20.91 +            if (demand_map_pgt[y] & _PAGE_PRESENT)
   20.92 +                break;
   20.93 +        if (y == n)
   20.94 +            break;
   20.95 +    }
   20.96 +    if (y != n) {
   20.97 +        printk("Failed to map %ld frames!\n", n);
   20.98 +        return NULL;
   20.99 +    }
  20.100 +
  20.101 +    /* Found it at x.  Map it in. */
  20.102 +    for (y = 0; y < n; y++) {
  20.103 +        mmu_updates[y].ptr = virt_to_mach(&demand_map_pgt[x + y]);
  20.104 +        mmu_updates[y].val = (f[y] << PAGE_SHIFT) | L1_PROT;
  20.105 +    }
  20.106 +
  20.107 +    rc = HYPERVISOR_mmu_update(mmu_updates, n, NULL, DOMID_SELF);
  20.108 +    if (rc < 0) {
  20.109 +        printk("Map %ld failed: %d.\n", n, rc);
  20.110 +        return NULL;
  20.111 +    } else {
  20.112 +        return (void *)(unsigned long)((unsigned long)demand_map_area_start +
  20.113 +                x * PAGE_SIZE);
  20.114 +    }
  20.115 +}
  20.116 +
  20.117  void init_mm(void)
  20.118  {
  20.119  
  20.120 @@ -643,4 +744,24 @@ void init_mm(void)
  20.121             (u_long)to_virt(PFN_PHYS(max_pfn)), PFN_PHYS(max_pfn));
  20.122      init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn));
  20.123      printk("MM: done\n");
  20.124 +
  20.125 +    init_demand_mapping_area(max_pfn);
  20.126 +    printk("Initialised demand area.\n");
  20.127  }
  20.128 +
  20.129 +void sanity_check(void)
  20.130 +{
  20.131 +    int x;
  20.132 +    chunk_head_t *head;
  20.133 +
  20.134 +    for (x = 0; x < FREELIST_SIZE; x++) {
  20.135 +        for (head = free_head[x]; !FREELIST_EMPTY(head); head = head->next) {
  20.136 +            ASSERT(!allocated_in_map(virt_to_pfn(head)));
  20.137 +            if (head->next)
  20.138 +                ASSERT(head->next->pprev == &head->next);
  20.139 +        }
  20.140 +        if (free_head[x]) {
  20.141 +            ASSERT(free_head[x]->pprev == &free_head[x]);
  20.142 +        }
  20.143 +    }
  20.144 +}
    21.1 --- a/extras/mini-os/time.c	Wed Jul 05 10:23:54 2006 -0600
    21.2 +++ b/extras/mini-os/time.c	Wed Jul 05 20:11:37 2006 -0600
    21.3 @@ -215,7 +215,7 @@ void block_domain(u32 millisecs)
    21.4  /*
    21.5   * Just a dummy 
    21.6   */
    21.7 -static void timer_handler(int ev, struct pt_regs *regs)
    21.8 +static void timer_handler(int ev, struct pt_regs *regs, void *ign)
    21.9  {
   21.10      static int i;
   21.11  
   21.12 @@ -233,5 +233,5 @@ static void timer_handler(int ev, struct
   21.13  void init_time(void)
   21.14  {
   21.15      printk("Initialising timer interface\n");
   21.16 -    bind_virq(VIRQ_TIMER, &timer_handler);
   21.17 +    bind_virq(VIRQ_TIMER, &timer_handler, NULL);
   21.18  }
    22.1 --- a/extras/mini-os/xenbus/xenbus.c	Wed Jul 05 10:23:54 2006 -0600
    22.2 +++ b/extras/mini-os/xenbus/xenbus.c	Wed Jul 05 20:11:37 2006 -0600
    22.3 @@ -112,7 +112,7 @@ static void xenbus_thread_func(void *ign
    22.4      }
    22.5  }
    22.6  
    22.7 -static void xenbus_evtchn_handler(int port, struct pt_regs *regs)
    22.8 +static void xenbus_evtchn_handler(int port, struct pt_regs *regs, void *ign)
    22.9  {
   22.10      wake_up(&xb_waitq);
   22.11  }
   22.12 @@ -174,7 +174,8 @@ void init_xenbus(void)
   22.13      create_thread("xenstore", xenbus_thread_func, NULL);
   22.14      DEBUG("buf at %p.\n", xenstore_buf);
   22.15      err = bind_evtchn(start_info.store_evtchn,
   22.16 -            xenbus_evtchn_handler);
   22.17 +		      xenbus_evtchn_handler,
   22.18 +              NULL);
   22.19      DEBUG("xenbus on irq %d\n", err);
   22.20  }
   22.21  
   22.22 @@ -187,8 +188,8 @@ struct write_req {
   22.23     by xenbus as if sent atomically.  The header is added
   22.24     automatically, using type %type, req_id %req_id, and trans_id
   22.25     %trans_id. */
   22.26 -static void xb_write(int type, int req_id, int trans_id,
   22.27 -        const struct write_req *req, int nr_reqs)
   22.28 +static void xb_write(int type, int req_id, xenbus_transaction_t trans_id,
   22.29 +		     const struct write_req *req, int nr_reqs)
   22.30  {
   22.31      XENSTORE_RING_IDX prod;
   22.32      int r;
   22.33 @@ -266,9 +267,9 @@ static void xb_write(int type, int req_i
   22.34     freed by the caller. */
   22.35  static struct xsd_sockmsg *
   22.36  xenbus_msg_reply(int type,
   22.37 -        int trans,
   22.38 -        struct write_req *io,
   22.39 -        int nr_reqs)
   22.40 +		 xenbus_transaction_t trans,
   22.41 +		 struct write_req *io,
   22.42 +		 int nr_reqs)
   22.43  {
   22.44      int id;
   22.45      DEFINE_WAIT(w);
   22.46 @@ -322,14 +323,14 @@ static void xenbus_debug_msg(const char 
   22.47  /* List the contents of a directory.  Returns a malloc()ed array of
   22.48     pointers to malloc()ed strings.  The array is NULL terminated.  May
   22.49     block. */
   22.50 -char *xenbus_ls(const char *pre, char ***contents)
   22.51 +char *xenbus_ls(xenbus_transaction_t xbt, const char *pre, char ***contents)
   22.52  {
   22.53      struct xsd_sockmsg *reply, *repmsg;
   22.54      struct write_req req[] = { { pre, strlen(pre)+1 } };
   22.55      int nr_elems, x, i;
   22.56      char **res;
   22.57  
   22.58 -    repmsg = xenbus_msg_reply(XS_DIRECTORY, 0, req, ARRAY_SIZE(req));
   22.59 +    repmsg = xenbus_msg_reply(XS_DIRECTORY, xbt, req, ARRAY_SIZE(req));
   22.60      char *msg = errmsg(repmsg);
   22.61      if (msg) {
   22.62  	*contents = NULL;
   22.63 @@ -351,12 +352,12 @@ char *xenbus_ls(const char *pre, char **
   22.64      return NULL;
   22.65  }
   22.66  
   22.67 -char *xenbus_read(const char *path, char **value)
   22.68 +char *xenbus_read(xenbus_transaction_t xbt, const char *path, char **value)
   22.69  {
   22.70      struct write_req req[] = { {path, strlen(path) + 1} };
   22.71      struct xsd_sockmsg *rep;
   22.72      char *res;
   22.73 -    rep = xenbus_msg_reply(XS_READ, 0, req, ARRAY_SIZE(req));
   22.74 +    rep = xenbus_msg_reply(XS_READ, xbt, req, ARRAY_SIZE(req));
   22.75      char *msg = errmsg(rep);
   22.76      if (msg) {
   22.77  	*value = NULL;
   22.78 @@ -370,14 +371,14 @@ char *xenbus_read(const char *path, char
   22.79      return NULL;
   22.80  }
   22.81  
   22.82 -char *xenbus_write(const char *path, const char *value)
   22.83 +char *xenbus_write(xenbus_transaction_t xbt, const char *path, const char *value)
   22.84  {
   22.85      struct write_req req[] = { 
   22.86  	{path, strlen(path) + 1},
   22.87  	{value, strlen(value) + 1},
   22.88      };
   22.89      struct xsd_sockmsg *rep;
   22.90 -    rep = xenbus_msg_reply(XS_WRITE, 0, req, ARRAY_SIZE(req));
   22.91 +    rep = xenbus_msg_reply(XS_WRITE, xbt, req, ARRAY_SIZE(req));
   22.92      char *msg = errmsg(rep);
   22.93      if (msg)
   22.94  	return msg;
   22.95 @@ -385,11 +386,11 @@ char *xenbus_write(const char *path, con
   22.96      return NULL;
   22.97  }
   22.98  
   22.99 -char *xenbus_rm(const char *path)
  22.100 +char *xenbus_rm(xenbus_transaction_t xbt, const char *path)
  22.101  {
  22.102      struct write_req req[] = { {path, strlen(path) + 1} };
  22.103      struct xsd_sockmsg *rep;
  22.104 -    rep = xenbus_msg_reply(XS_RM, 0, req, ARRAY_SIZE(req));
  22.105 +    rep = xenbus_msg_reply(XS_RM, xbt, req, ARRAY_SIZE(req));
  22.106      char *msg = errmsg(rep);
  22.107      if (msg)
  22.108  	return msg;
  22.109 @@ -397,12 +398,12 @@ char *xenbus_rm(const char *path)
  22.110      return NULL;
  22.111  }
  22.112  
  22.113 -char *xenbus_get_perms(const char *path, char **value)
  22.114 +char *xenbus_get_perms(xenbus_transaction_t xbt, const char *path, char **value)
  22.115  {
  22.116      struct write_req req[] = { {path, strlen(path) + 1} };
  22.117      struct xsd_sockmsg *rep;
  22.118      char *res;
  22.119 -    rep = xenbus_msg_reply(XS_GET_PERMS, 0, req, ARRAY_SIZE(req));
  22.120 +    rep = xenbus_msg_reply(XS_GET_PERMS, xbt, req, ARRAY_SIZE(req));
  22.121      char *msg = errmsg(rep);
  22.122      if (msg) {
  22.123  	*value = NULL;
  22.124 @@ -417,7 +418,7 @@ char *xenbus_get_perms(const char *path,
  22.125  }
  22.126  
  22.127  #define PERM_MAX_SIZE 32
  22.128 -char *xenbus_set_perms(const char *path, domid_t dom, char perm)
  22.129 +char *xenbus_set_perms(xenbus_transaction_t xbt, const char *path, domid_t dom, char perm)
  22.130  {
  22.131      char value[PERM_MAX_SIZE];
  22.132      snprintf(value, PERM_MAX_SIZE, "%c%hu", perm, dom);
  22.133 @@ -426,7 +427,7 @@ char *xenbus_set_perms(const char *path,
  22.134  	{value, strlen(value) + 1},
  22.135      };
  22.136      struct xsd_sockmsg *rep;
  22.137 -    rep = xenbus_msg_reply(XS_SET_PERMS, 0, req, ARRAY_SIZE(req));
  22.138 +    rep = xenbus_msg_reply(XS_SET_PERMS, xbt, req, ARRAY_SIZE(req));
  22.139      char *msg = errmsg(rep);
  22.140      if (msg)
  22.141  	return msg;
  22.142 @@ -434,13 +435,72 @@ char *xenbus_set_perms(const char *path,
  22.143      return NULL;
  22.144  }
  22.145  
  22.146 +char *xenbus_transaction_start(xenbus_transaction_t *xbt)
  22.147 +{
  22.148 +    /* xenstored becomes angry if you send a length 0 message, so just
  22.149 +       shove a nul terminator on the end */
  22.150 +    struct write_req req = { "", 1};
  22.151 +    struct xsd_sockmsg *rep;
  22.152 +    char *err;
  22.153 +
  22.154 +    rep = xenbus_msg_reply(XS_TRANSACTION_START, 0, &req, 1);
  22.155 +    err = errmsg(rep);
  22.156 +    if (err)
  22.157 +	return err;
  22.158 +    sscanf((char *)(rep + 1), "%u", xbt);
  22.159 +    free(rep);
  22.160 +    return NULL;
  22.161 +}
  22.162 +
  22.163 +char *
  22.164 +xenbus_transaction_end(xenbus_transaction_t t, int abort, int *retry)
  22.165 +{
  22.166 +    struct xsd_sockmsg *rep;
  22.167 +    struct write_req req;
  22.168 +    char *err;
  22.169 +
  22.170 +    *retry = 0;
  22.171 +
  22.172 +    req.data = abort ? "F" : "T";
  22.173 +    req.len = 2;
  22.174 +    rep = xenbus_msg_reply(XS_TRANSACTION_END, t, &req, 1);
  22.175 +    err = errmsg(rep);
  22.176 +    if (err) {
  22.177 +	if (!strcmp(err, "EAGAIN")) {
  22.178 +	    *retry = 1;
  22.179 +	    free(err);
  22.180 +	    return NULL;
  22.181 +	} else {
  22.182 +	    return err;
  22.183 +	}
  22.184 +    }
  22.185 +    free(rep);
  22.186 +    return NULL;
  22.187 +}
  22.188 +
  22.189 +int xenbus_read_integer(char *path)
  22.190 +{
  22.191 +    char *res, *buf;
  22.192 +    int t;
  22.193 +
  22.194 +    res = xenbus_read(XBT_NIL, path, &buf);
  22.195 +    if (res) {
  22.196 +	printk("Failed to read %s.\n", path);
  22.197 +	free(res);
  22.198 +	return -1;
  22.199 +    }
  22.200 +    sscanf(buf, "%d", &t);
  22.201 +    free(buf);
  22.202 +    return t;
  22.203 +}
  22.204 +
  22.205  static void do_ls_test(const char *pre)
  22.206  {
  22.207      char **dirs;
  22.208      int x;
  22.209  
  22.210      DEBUG("ls %s...\n", pre);
  22.211 -    char *msg = xenbus_ls(pre, &dirs);
  22.212 +    char *msg = xenbus_ls(XBT_NIL, pre, &dirs);
  22.213      if (msg) {
  22.214  	DEBUG("Error in xenbus ls: %s\n", msg);
  22.215  	free(msg);
  22.216 @@ -458,7 +518,7 @@ static void do_read_test(const char *pat
  22.217  {
  22.218      char *res;
  22.219      DEBUG("Read %s...\n", path);
  22.220 -    char *msg = xenbus_read(path, &res);
  22.221 +    char *msg = xenbus_read(XBT_NIL, path, &res);
  22.222      if (msg) {
  22.223  	DEBUG("Error in xenbus read: %s\n", msg);
  22.224  	free(msg);
  22.225 @@ -471,7 +531,7 @@ static void do_read_test(const char *pat
  22.226  static void do_write_test(const char *path, const char *val)
  22.227  {
  22.228      DEBUG("Write %s to %s...\n", val, path);
  22.229 -    char *msg = xenbus_write(path, val);
  22.230 +    char *msg = xenbus_write(XBT_NIL, path, val);
  22.231      if (msg) {
  22.232  	DEBUG("Result %s\n", msg);
  22.233  	free(msg);
  22.234 @@ -483,7 +543,7 @@ static void do_write_test(const char *pa
  22.235  static void do_rm_test(const char *path)
  22.236  {
  22.237      DEBUG("rm %s...\n", path);
  22.238 -    char *msg = xenbus_rm(path);
  22.239 +    char *msg = xenbus_rm(XBT_NIL, path);
  22.240      if (msg) {
  22.241  	DEBUG("Result %s\n", msg);
  22.242  	free(msg);
    23.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/smp-xen.c	Wed Jul 05 10:23:54 2006 -0600
    23.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/smp-xen.c	Wed Jul 05 20:11:37 2006 -0600
    23.3 @@ -442,6 +442,7 @@ void flush_tlb_mm(struct mm_struct * mm)
    23.4  { xen_tlb_flush_mask(&mm->cpu_vm_mask); }
    23.5  void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
    23.6  { xen_invlpg_mask(&vma->vm_mm->cpu_vm_mask, va); }
    23.7 +EXPORT_SYMBOL(flush_tlb_page);
    23.8  void flush_tlb_all(void)
    23.9  { xen_tlb_flush_all(); }
   23.10  
    24.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c	Wed Jul 05 10:23:54 2006 -0600
    24.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c	Wed Jul 05 20:11:37 2006 -0600
    24.3 @@ -989,12 +989,11 @@ static void stop_hz_timer(void)
    24.4  
    24.5  	smp_mb();
    24.6  
    24.7 -	/* Leave ourselves in 'tick mode' if rcu or softirq pending. */
    24.8 -	if (rcu_needs_cpu(cpu) || local_softirq_pending()) {
    24.9 +	/* Leave ourselves in 'tick mode' if rcu or softirq or timer pending. */
   24.10 +	if (rcu_needs_cpu(cpu) || local_softirq_pending() ||
   24.11 +	    (j = next_timer_interrupt(), time_before_eq(j, jiffies))) {
   24.12  		cpu_clear(cpu, nohz_cpu_mask);
   24.13  		j = jiffies + 1;
   24.14 -	} else {
   24.15 -		j = next_timer_interrupt();
   24.16  	}
   24.17  
   24.18  	BUG_ON(HYPERVISOR_set_timer_op(jiffies_to_st(j)) != 0);
    25.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c	Wed Jul 05 10:23:54 2006 -0600
    25.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c	Wed Jul 05 20:11:37 2006 -0600
    25.3 @@ -60,7 +60,7 @@ void *kmap_atomic_pte(struct page *page,
    25.4  
    25.5  void kunmap_atomic(void *kvaddr, enum km_type type)
    25.6  {
    25.7 -#ifdef CONFIG_DEBUG_HIGHMEM
    25.8 +#if defined(CONFIG_DEBUG_HIGHMEM) || defined(CONFIG_XEN)
    25.9  	unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
   25.10  	enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
   25.11  
   25.12 @@ -69,7 +69,9 @@ void kunmap_atomic(void *kvaddr, enum km
   25.13  		preempt_check_resched();
   25.14  		return;
   25.15  	}
   25.16 +#endif
   25.17  
   25.18 +#if defined(CONFIG_DEBUG_HIGHMEM)
   25.19  	if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx))
   25.20  		BUG();
   25.21  
   25.22 @@ -79,6 +81,14 @@ void kunmap_atomic(void *kvaddr, enum km
   25.23  	 */
   25.24  	pte_clear(&init_mm, vaddr, kmap_pte-idx);
   25.25  	__flush_tlb_one(vaddr);
   25.26 +#elif defined(CONFIG_XEN)
   25.27 +	/*
   25.28 +	 * We must ensure there are no dangling pagetable references when
   25.29 +	 * returning memory to Xen (decrease_reservation).
   25.30 +	 * XXX TODO: We could make this faster by only zapping when
   25.31 +	 * kmap_flush_unused is called but that is trickier and more invasive.
   25.32 +	 */
   25.33 +	pte_clear(&init_mm, vaddr, kmap_pte-idx);
   25.34  #endif
   25.35  
   25.36  	dec_preempt_count();
    26.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c	Wed Jul 05 10:23:54 2006 -0600
    26.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c	Wed Jul 05 20:11:37 2006 -0600
    26.3 @@ -271,10 +271,6 @@ static unsigned long discontig_frames[1<
    26.4  int xen_create_contiguous_region(
    26.5  	unsigned long vstart, unsigned int order, unsigned int address_bits)
    26.6  {
    26.7 -	pgd_t         *pgd; 
    26.8 -	pud_t         *pud; 
    26.9 -	pmd_t         *pmd;
   26.10 -	pte_t         *pte;
   26.11  	unsigned long *in_frames = discontig_frames, out_frame;
   26.12  	unsigned long  frame, i, flags;
   26.13  	long           rc;
   26.14 @@ -301,7 +297,7 @@ int xen_create_contiguous_region(
   26.15  	if (xen_feature(XENFEAT_auto_translated_physmap))
   26.16  		return 0;
   26.17  
   26.18 -	if (order > MAX_CONTIG_ORDER)
   26.19 +	if (unlikely(order > MAX_CONTIG_ORDER))
   26.20  		return -ENOMEM;
   26.21  
   26.22  	set_xen_guest_handle(exchange.in.extent_start, in_frames);
   26.23 @@ -313,11 +309,7 @@ int xen_create_contiguous_region(
   26.24  
   26.25  	/* 1. Zap current PTEs, remembering MFNs. */
   26.26  	for (i = 0; i < (1UL<<order); i++) {
   26.27 -		pgd = pgd_offset_k(vstart + (i*PAGE_SIZE));
   26.28 -		pud = pud_offset(pgd, (vstart + (i*PAGE_SIZE)));
   26.29 -		pmd = pmd_offset(pud, (vstart + (i*PAGE_SIZE)));
   26.30 -		pte = pte_offset_kernel(pmd, (vstart + (i*PAGE_SIZE)));
   26.31 -		in_frames[i] = pte_mfn(*pte);
   26.32 +		in_frames[i] = pfn_to_mfn((__pa(vstart) >> PAGE_SHIFT) + i);
   26.33  		if (HYPERVISOR_update_va_mapping(vstart + (i*PAGE_SIZE),
   26.34  						 __pte_ma(0), 0))
   26.35  			BUG();
   26.36 @@ -372,10 +364,6 @@ int xen_create_contiguous_region(
   26.37  
   26.38  void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order)
   26.39  {
   26.40 -	pgd_t         *pgd; 
   26.41 -	pud_t         *pud; 
   26.42 -	pmd_t         *pmd;
   26.43 -	pte_t         *pte;
   26.44  	unsigned long *out_frames = discontig_frames, in_frame;
   26.45  	unsigned long  frame, i, flags;
   26.46  	long           rc;
   26.47 @@ -397,7 +385,7 @@ void xen_destroy_contiguous_region(unsig
   26.48  	    !test_bit(__pa(vstart) >> PAGE_SHIFT, contiguous_bitmap))
   26.49  		return;
   26.50  
   26.51 -	if (order > MAX_CONTIG_ORDER)
   26.52 +	if (unlikely(order > MAX_CONTIG_ORDER))
   26.53  		return;
   26.54  
   26.55  	set_xen_guest_handle(exchange.in.extent_start, &in_frame);
   26.56 @@ -410,16 +398,13 @@ void xen_destroy_contiguous_region(unsig
   26.57  	contiguous_bitmap_clear(__pa(vstart) >> PAGE_SHIFT, 1UL << order);
   26.58  
   26.59  	/* 1. Find start MFN of contiguous extent. */
   26.60 -	pgd = pgd_offset_k(vstart);
   26.61 -	pud = pud_offset(pgd, vstart);
   26.62 -	pmd = pmd_offset(pud, vstart);
   26.63 -	pte = pte_offset_kernel(pmd, vstart);
   26.64 -	in_frame = pte_mfn(*pte);
   26.65 +	in_frame = pfn_to_mfn(__pa(vstart) >> PAGE_SHIFT);
   26.66  
   26.67  	/* 2. Zap current PTEs. */
   26.68  	for (i = 0; i < (1UL<<order); i++) {
   26.69  		if (HYPERVISOR_update_va_mapping(vstart + (i*PAGE_SIZE),
   26.70 -						 __pte_ma(0), 0));
   26.71 +						 __pte_ma(0), 0))
   26.72 +			BUG();
   26.73  		set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i,
   26.74  			INVALID_P2M_ENTRY);
   26.75  		out_frames[i] = (__pa(vstart) >> PAGE_SHIFT) + i;
   26.76 @@ -430,7 +415,7 @@ void xen_destroy_contiguous_region(unsig
   26.77  	success = (exchange.nr_exchanged == 1);
   26.78  	BUG_ON(!success && ((exchange.nr_exchanged != 0) || (rc == 0)));
   26.79  	BUG_ON(success && (rc != 0));
   26.80 -	if (rc == -ENOSYS) {
   26.81 +	if (unlikely(rc == -ENOSYS)) {
   26.82  		/* Compatibility when XENMEM_exchange is unsupported. */
   26.83  		if (HYPERVISOR_memory_op(XENMEM_decrease_reservation,
   26.84  					 &exchange.in) != 1)
    27.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig	Wed Jul 05 10:23:54 2006 -0600
    27.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig	Wed Jul 05 20:11:37 2006 -0600
    27.3 @@ -20,9 +20,18 @@ config TCG_TPM
    27.4  	  Note: For more TPM drivers enable CONFIG_PNP, CONFIG_ACPI
    27.5  	  and CONFIG_PNPACPI.
    27.6  
    27.7 +config TCG_TIS
    27.8 +	tristate "TPM Interface Specification 1.2 Interface"
    27.9 +	depends on TCG_TPM
   27.10 +	---help---
   27.11 +	  If you have a TPM security chip that is compliant with the
   27.12 +	  TCG TIS 1.2 TPM specification say Yes and it will be accessible
   27.13 +	  from within Linux.  To compile this driver as a module, choose
   27.14 +	  M here; the module will be called tpm_tis.
   27.15 +
   27.16  config TCG_NSC
   27.17  	tristate "National Semiconductor TPM Interface"
   27.18 -	depends on TCG_TPM && !XEN_UNPRIVILEGED_GUEST
   27.19 +	depends on TCG_TPM && PNPACPI
   27.20  	---help---
   27.21  	  If you have a TPM security chip from National Semicondutor 
   27.22  	  say Yes and it will be accessible from within Linux.  To 
   27.23 @@ -31,7 +40,7 @@ config TCG_NSC
   27.24  
   27.25  config TCG_ATMEL
   27.26  	tristate "Atmel TPM Interface"
   27.27 -	depends on TCG_TPM && !XEN_UNPRIVILEGED_GUEST
   27.28 +	depends on TCG_TPM
   27.29  	---help---
   27.30  	  If you have a TPM security chip from Atmel say Yes and it 
   27.31  	  will be accessible from within Linux.  To compile this driver 
    28.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/Makefile	Wed Jul 05 10:23:54 2006 -0600
    28.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/Makefile	Wed Jul 05 20:11:37 2006 -0600
    28.3 @@ -5,6 +5,7 @@ obj-$(CONFIG_TCG_TPM) += tpm.o
    28.4  ifdef CONFIG_ACPI
    28.5  	obj-$(CONFIG_TCG_TPM) += tpm_bios.o
    28.6  endif
    28.7 +obj-$(CONFIG_TCG_TIS) += tpm_tis.o
    28.8  obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
    28.9  obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
   28.10  obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
    29.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c	Wed Jul 05 10:23:54 2006 -0600
    29.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c	Wed Jul 05 20:11:37 2006 -0600
    29.3 @@ -30,15 +30,295 @@
    29.4  
    29.5  enum tpm_const {
    29.6  	TPM_MINOR = 224,	/* officially assigned */
    29.7 -	TPM_MIN_BUFSIZE = 2048,
    29.8 -	TPM_MAX_BUFSIZE = 64 * 1024,
    29.9 +#ifndef CONFIG_XEN
   29.10 +	TPM_BUFSIZE = 2048,
   29.11 +#endif
   29.12  	TPM_NUM_DEVICES = 256,
   29.13 -	TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int))
   29.14  };
   29.15  
   29.16 +enum tpm_duration {
   29.17 +	TPM_SHORT = 0,
   29.18 +	TPM_MEDIUM = 1,
   29.19 +	TPM_LONG = 2,
   29.20 +	TPM_UNDEFINED,
   29.21 +};
   29.22 +
   29.23 +#define TPM_MAX_ORDINAL 243
   29.24 +#define TPM_MAX_PROTECTED_ORDINAL 12
   29.25 +#define TPM_PROTECTED_ORDINAL_MASK 0xFF
   29.26 +
   29.27  static LIST_HEAD(tpm_chip_list);
   29.28  static DEFINE_SPINLOCK(driver_lock);
   29.29 -static int dev_mask[TPM_NUM_MASK_ENTRIES];
   29.30 +static DECLARE_BITMAP(dev_mask, TPM_NUM_DEVICES);
   29.31 +
   29.32 +/*
   29.33 + * Array with one entry per ordinal defining the maximum amount
   29.34 + * of time the chip could take to return the result.  The ordinal
   29.35 + * designation of short, medium or long is defined in a table in
   29.36 + * TCG Specification TPM Main Part 2 TPM Structures Section 17. The
   29.37 + * values of the SHORT, MEDIUM, and LONG durations are retrieved
   29.38 + * from the chip during initialization with a call to tpm_get_timeouts.
   29.39 + */
   29.40 +static const u8 tpm_protected_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL] = {
   29.41 +	TPM_UNDEFINED,		/* 0 */
   29.42 +	TPM_UNDEFINED,
   29.43 +	TPM_UNDEFINED,
   29.44 +	TPM_UNDEFINED,
   29.45 +	TPM_UNDEFINED,
   29.46 +	TPM_UNDEFINED,		/* 5 */
   29.47 +	TPM_UNDEFINED,
   29.48 +	TPM_UNDEFINED,
   29.49 +	TPM_UNDEFINED,
   29.50 +	TPM_UNDEFINED,
   29.51 +	TPM_SHORT,		/* 10 */
   29.52 +	TPM_SHORT,
   29.53 +};
   29.54 +
   29.55 +static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
   29.56 +	TPM_UNDEFINED,		/* 0 */
   29.57 +	TPM_UNDEFINED,
   29.58 +	TPM_UNDEFINED,
   29.59 +	TPM_UNDEFINED,
   29.60 +	TPM_UNDEFINED,
   29.61 +	TPM_UNDEFINED,		/* 5 */
   29.62 +	TPM_UNDEFINED,
   29.63 +	TPM_UNDEFINED,
   29.64 +	TPM_UNDEFINED,
   29.65 +	TPM_UNDEFINED,
   29.66 +	TPM_SHORT,		/* 10 */
   29.67 +	TPM_SHORT,
   29.68 +	TPM_MEDIUM,
   29.69 +	TPM_LONG,
   29.70 +	TPM_LONG,
   29.71 +	TPM_MEDIUM,		/* 15 */
   29.72 +	TPM_SHORT,
   29.73 +	TPM_SHORT,
   29.74 +	TPM_MEDIUM,
   29.75 +	TPM_LONG,
   29.76 +	TPM_SHORT,		/* 20 */
   29.77 +	TPM_SHORT,
   29.78 +	TPM_MEDIUM,
   29.79 +	TPM_MEDIUM,
   29.80 +	TPM_MEDIUM,
   29.81 +	TPM_SHORT,		/* 25 */
   29.82 +	TPM_SHORT,
   29.83 +	TPM_MEDIUM,
   29.84 +	TPM_SHORT,
   29.85 +	TPM_SHORT,
   29.86 +	TPM_MEDIUM,		/* 30 */
   29.87 +	TPM_LONG,
   29.88 +	TPM_MEDIUM,
   29.89 +	TPM_SHORT,
   29.90 +	TPM_SHORT,
   29.91 +	TPM_SHORT,		/* 35 */
   29.92 +	TPM_MEDIUM,
   29.93 +	TPM_MEDIUM,
   29.94 +	TPM_UNDEFINED,
   29.95 +	TPM_UNDEFINED,
   29.96 +	TPM_MEDIUM,		/* 40 */
   29.97 +	TPM_LONG,
   29.98 +	TPM_MEDIUM,
   29.99 +	TPM_SHORT,
  29.100 +	TPM_SHORT,
  29.101 +	TPM_SHORT,		/* 45 */
  29.102 +	TPM_SHORT,
  29.103 +	TPM_SHORT,
  29.104 +	TPM_SHORT,
  29.105 +	TPM_LONG,
  29.106 +	TPM_MEDIUM,		/* 50 */
  29.107 +	TPM_MEDIUM,
  29.108 +	TPM_UNDEFINED,
  29.109 +	TPM_UNDEFINED,
  29.110 +	TPM_UNDEFINED,
  29.111 +	TPM_UNDEFINED,		/* 55 */
  29.112 +	TPM_UNDEFINED,
  29.113 +	TPM_UNDEFINED,
  29.114 +	TPM_UNDEFINED,
  29.115 +	TPM_UNDEFINED,
  29.116 +	TPM_MEDIUM,		/* 60 */
  29.117 +	TPM_MEDIUM,
  29.118 +	TPM_MEDIUM,
  29.119 +	TPM_SHORT,
  29.120 +	TPM_SHORT,
  29.121 +	TPM_MEDIUM,		/* 65 */
  29.122 +	TPM_UNDEFINED,
  29.123 +	TPM_UNDEFINED,
  29.124 +	TPM_UNDEFINED,
  29.125 +	TPM_UNDEFINED,
  29.126 +	TPM_SHORT,		/* 70 */
  29.127 +	TPM_SHORT,
  29.128 +	TPM_UNDEFINED,
  29.129 +	TPM_UNDEFINED,
  29.130 +	TPM_UNDEFINED,
  29.131 +	TPM_UNDEFINED,		/* 75 */
  29.132 +	TPM_UNDEFINED,
  29.133 +	TPM_UNDEFINED,
  29.134 +	TPM_UNDEFINED,
  29.135 +	TPM_UNDEFINED,
  29.136 +	TPM_LONG,		/* 80 */
  29.137 +	TPM_UNDEFINED,
  29.138 +	TPM_MEDIUM,
  29.139 +	TPM_LONG,
  29.140 +	TPM_SHORT,
  29.141 +	TPM_UNDEFINED,		/* 85 */
  29.142 +	TPM_UNDEFINED,
  29.143 +	TPM_UNDEFINED,
  29.144 +	TPM_UNDEFINED,
  29.145 +	TPM_UNDEFINED,
  29.146 +	TPM_SHORT,		/* 90 */
  29.147 +	TPM_SHORT,
  29.148 +	TPM_SHORT,
  29.149 +	TPM_SHORT,
  29.150 +	TPM_SHORT,
  29.151 +	TPM_UNDEFINED,		/* 95 */
  29.152 +	TPM_UNDEFINED,
  29.153 +	TPM_UNDEFINED,
  29.154 +	TPM_UNDEFINED,
  29.155 +	TPM_UNDEFINED,
  29.156 +	TPM_MEDIUM,		/* 100 */
  29.157 +	TPM_SHORT,
  29.158 +	TPM_SHORT,
  29.159 +	TPM_UNDEFINED,
  29.160 +	TPM_UNDEFINED,
  29.161 +	TPM_UNDEFINED,		/* 105 */
  29.162 +	TPM_UNDEFINED,
  29.163 +	TPM_UNDEFINED,
  29.164 +	TPM_UNDEFINED,
  29.165 +	TPM_UNDEFINED,
  29.166 +	TPM_SHORT,		/* 110 */
  29.167 +	TPM_SHORT,
  29.168 +	TPM_SHORT,
  29.169 +	TPM_SHORT,
  29.170 +	TPM_SHORT,
  29.171 +	TPM_SHORT,		/* 115 */
  29.172 +	TPM_SHORT,
  29.173 +	TPM_SHORT,
  29.174 +	TPM_UNDEFINED,
  29.175 +	TPM_UNDEFINED,
  29.176 +	TPM_LONG,		/* 120 */
  29.177 +	TPM_LONG,
  29.178 +	TPM_MEDIUM,
  29.179 +	TPM_UNDEFINED,
  29.180 +	TPM_SHORT,
  29.181 +	TPM_SHORT,		/* 125 */
  29.182 +	TPM_SHORT,
  29.183 +	TPM_LONG,
  29.184 +	TPM_SHORT,
  29.185 +	TPM_SHORT,
  29.186 +	TPM_SHORT,		/* 130 */
  29.187 +	TPM_MEDIUM,
  29.188 +	TPM_UNDEFINED,
  29.189 +	TPM_SHORT,
  29.190 +	TPM_MEDIUM,
  29.191 +	TPM_UNDEFINED,		/* 135 */
  29.192 +	TPM_UNDEFINED,
  29.193 +	TPM_UNDEFINED,
  29.194 +	TPM_UNDEFINED,
  29.195 +	TPM_UNDEFINED,
  29.196 +	TPM_SHORT,		/* 140 */
  29.197 +	TPM_SHORT,
  29.198 +	TPM_UNDEFINED,
  29.199 +	TPM_UNDEFINED,
  29.200 +	TPM_UNDEFINED,
  29.201 +	TPM_UNDEFINED,		/* 145 */
  29.202 +	TPM_UNDEFINED,
  29.203 +	TPM_UNDEFINED,
  29.204 +	TPM_UNDEFINED,
  29.205 +	TPM_UNDEFINED,
  29.206 +	TPM_SHORT,		/* 150 */
  29.207 +	TPM_MEDIUM,
  29.208 +	TPM_MEDIUM,
  29.209 +	TPM_SHORT,
  29.210 +	TPM_SHORT,
  29.211 +	TPM_UNDEFINED,		/* 155 */
  29.212 +	TPM_UNDEFINED,
  29.213 +	TPM_UNDEFINED,
  29.214 +	TPM_UNDEFINED,
  29.215 +	TPM_UNDEFINED,
  29.216 +	TPM_SHORT,		/* 160 */
  29.217 +	TPM_SHORT,
  29.218 +	TPM_SHORT,
  29.219 +	TPM_SHORT,
  29.220 +	TPM_UNDEFINED,
  29.221 +	TPM_UNDEFINED,		/* 165 */
  29.222 +	TPM_UNDEFINED,
  29.223 +	TPM_UNDEFINED,
  29.224 +	TPM_UNDEFINED,
  29.225 +	TPM_UNDEFINED,
  29.226 +	TPM_LONG,		/* 170 */
  29.227 +	TPM_UNDEFINED,
  29.228 +	TPM_UNDEFINED,
  29.229 +	TPM_UNDEFINED,
  29.230 +	TPM_UNDEFINED,
  29.231 +	TPM_UNDEFINED,		/* 175 */
  29.232 +	TPM_UNDEFINED,
  29.233 +	TPM_UNDEFINED,
  29.234 +	TPM_UNDEFINED,
  29.235 +	TPM_UNDEFINED,
  29.236 +	TPM_MEDIUM,		/* 180 */
  29.237 +	TPM_SHORT,
  29.238 +	TPM_MEDIUM,
  29.239 +	TPM_MEDIUM,
  29.240 +	TPM_MEDIUM,
  29.241 +	TPM_MEDIUM,		/* 185 */
  29.242 +	TPM_SHORT,
  29.243 +	TPM_UNDEFINED,
  29.244 +	TPM_UNDEFINED,
  29.245 +	TPM_UNDEFINED,
  29.246 +	TPM_UNDEFINED,		/* 190 */
  29.247 +	TPM_UNDEFINED,
  29.248 +	TPM_UNDEFINED,
  29.249 +	TPM_UNDEFINED,
  29.250 +	TPM_UNDEFINED,
  29.251 +	TPM_UNDEFINED,		/* 195 */
  29.252 +	TPM_UNDEFINED,
  29.253 +	TPM_UNDEFINED,
  29.254 +	TPM_UNDEFINED,
  29.255 +	TPM_UNDEFINED,
  29.256 +	TPM_SHORT,		/* 200 */
  29.257 +	TPM_UNDEFINED,
  29.258 +	TPM_UNDEFINED,
  29.259 +	TPM_UNDEFINED,
  29.260 +	TPM_SHORT,
  29.261 +	TPM_SHORT,		/* 205 */
  29.262 +	TPM_SHORT,
  29.263 +	TPM_SHORT,
  29.264 +	TPM_SHORT,
  29.265 +	TPM_SHORT,
  29.266 +	TPM_MEDIUM,		/* 210 */
  29.267 +	TPM_UNDEFINED,
  29.268 +	TPM_MEDIUM,
  29.269 +	TPM_MEDIUM,
  29.270 +	TPM_MEDIUM,
  29.271 +	TPM_UNDEFINED,		/* 215 */
  29.272 +	TPM_MEDIUM,
  29.273 +	TPM_UNDEFINED,
  29.274 +	TPM_UNDEFINED,
  29.275 +	TPM_SHORT,
  29.276 +	TPM_SHORT,		/* 220 */
  29.277 +	TPM_SHORT,
  29.278 +	TPM_SHORT,
  29.279 +	TPM_SHORT,
  29.280 +	TPM_SHORT,
  29.281 +	TPM_UNDEFINED,		/* 225 */
  29.282 +	TPM_UNDEFINED,
  29.283 +	TPM_UNDEFINED,
  29.284 +	TPM_UNDEFINED,
  29.285 +	TPM_UNDEFINED,
  29.286 +	TPM_SHORT,		/* 230 */
  29.287 +	TPM_LONG,
  29.288 +	TPM_MEDIUM,
  29.289 +	TPM_UNDEFINED,
  29.290 +	TPM_UNDEFINED,
  29.291 +	TPM_UNDEFINED,		/* 235 */
  29.292 +	TPM_UNDEFINED,
  29.293 +	TPM_UNDEFINED,
  29.294 +	TPM_UNDEFINED,
  29.295 +	TPM_UNDEFINED,
  29.296 +	TPM_SHORT,		/* 240 */
  29.297 +	TPM_UNDEFINED,
  29.298 +	TPM_MEDIUM,
  29.299 +};
  29.300  
  29.301  static void user_reader_timeout(unsigned long ptr)
  29.302  {
  29.303 @@ -47,28 +327,58 @@ static void user_reader_timeout(unsigned
  29.304  	schedule_work(&chip->work);
  29.305  }
  29.306  
  29.307 -static void timeout_work(void * ptr)
  29.308 +static void timeout_work(void *ptr)
  29.309  {
  29.310  	struct tpm_chip *chip = ptr;
  29.311  
  29.312  	down(&chip->buffer_mutex);
  29.313  	atomic_set(&chip->data_pending, 0);
  29.314 +#ifndef CONFIG_XEN
  29.315 +	memset(chip->data_buffer, 0, TPM_BUFSIZE);
  29.316 +#else
  29.317  	memset(chip->data_buffer, 0, get_chip_buffersize(chip));
  29.318 +#endif
  29.319  	up(&chip->buffer_mutex);
  29.320  }
  29.321  
  29.322  /*
  29.323 + * Returns max number of jiffies to wait
  29.324 + */
  29.325 +unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
  29.326 +					   u32 ordinal)
  29.327 +{
  29.328 +	int duration_idx = TPM_UNDEFINED;
  29.329 +	int duration = 0;
  29.330 +
  29.331 +	if (ordinal < TPM_MAX_ORDINAL)
  29.332 +		duration_idx = tpm_ordinal_duration[ordinal];
  29.333 +	else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
  29.334 +		 TPM_MAX_PROTECTED_ORDINAL)
  29.335 +		duration_idx =
  29.336 +		    tpm_protected_ordinal_duration[ordinal &
  29.337 +						   TPM_PROTECTED_ORDINAL_MASK];
  29.338 +
  29.339 +	if (duration_idx != TPM_UNDEFINED)
  29.340 +		duration = chip->vendor.duration[duration_idx];
  29.341 +	if (duration <= 0)
  29.342 +		return 2 * 60 * HZ;
  29.343 +	else
  29.344 +		return duration;
  29.345 +}
  29.346 +EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
  29.347 +
  29.348 +/*
  29.349   * Internal kernel interface to transmit TPM commands
  29.350   */
  29.351 -static ssize_t tpm_transmit(struct tpm_chip * chip, const char *buf,
  29.352 +static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
  29.353  			    size_t bufsiz)
  29.354  {
  29.355  	ssize_t rc;
  29.356 -	u32 count;
  29.357 +	u32 count, ordinal;
  29.358  	unsigned long stop;
  29.359  
  29.360  	count = be32_to_cpu(*((__be32 *) (buf + 2)));
  29.361 -
  29.362 +	ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
  29.363  	if (count == 0)
  29.364  		return -ENODATA;
  29.365  	if (count > bufsiz) {
  29.366 @@ -79,21 +389,23 @@ static ssize_t tpm_transmit(struct tpm_c
  29.367  
  29.368  	down(&chip->tpm_mutex);
  29.369  
  29.370 -	if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
  29.371 +	if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) {
  29.372  		dev_err(chip->dev,
  29.373  			"tpm_transmit: tpm_send: error %zd\n", rc);
  29.374  		goto out;
  29.375  	}
  29.376  
  29.377 -	stop = jiffies + 2 * 60 * HZ;
  29.378 +	if (chip->vendor.irq)
  29.379 +		goto out_recv;
  29.380 +
  29.381 +	stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal);
  29.382  	do {
  29.383 -		u8 status = chip->vendor->status(chip);
  29.384 -		if ((status & chip->vendor->req_complete_mask) ==
  29.385 -		    chip->vendor->req_complete_val) {
  29.386 +		u8 status = chip->vendor.status(chip);
  29.387 +		if ((status & chip->vendor.req_complete_mask) ==
  29.388 +		    chip->vendor.req_complete_val)
  29.389  			goto out_recv;
  29.390 -		}
  29.391  
  29.392 -		if ((status == chip->vendor->req_canceled)) {
  29.393 +		if ((status == chip->vendor.req_canceled)) {
  29.394  			dev_err(chip->dev, "Operation Canceled\n");
  29.395  			rc = -ECANCELED;
  29.396  			goto out;
  29.397 @@ -103,14 +415,13 @@ static ssize_t tpm_transmit(struct tpm_c
  29.398  		rmb();
  29.399  	} while (time_before(jiffies, stop));
  29.400  
  29.401 -
  29.402 -	chip->vendor->cancel(chip);
  29.403 +	chip->vendor.cancel(chip);
  29.404  	dev_err(chip->dev, "Operation Timed out\n");
  29.405  	rc = -ETIME;
  29.406  	goto out;
  29.407  
  29.408  out_recv:
  29.409 -	rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
  29.410 +	rc = chip->vendor.recv(chip, (u8 *) buf, bufsiz);
  29.411  	if (rc < 0)
  29.412  		dev_err(chip->dev,
  29.413  			"tpm_transmit: tpm_recv: error %zd\n", rc);
  29.414 @@ -120,17 +431,247 @@ out:
  29.415  }
  29.416  
  29.417  #define TPM_DIGEST_SIZE 20
  29.418 -#define CAP_PCR_RESULT_SIZE 18
  29.419 -static const u8 cap_pcr[] = {
  29.420 +#define TPM_ERROR_SIZE 10
  29.421 +#define TPM_RET_CODE_IDX 6
  29.422 +#define TPM_GET_CAP_RET_SIZE_IDX 10
  29.423 +#define TPM_GET_CAP_RET_UINT32_1_IDX 14
  29.424 +#define TPM_GET_CAP_RET_UINT32_2_IDX 18
  29.425 +#define TPM_GET_CAP_RET_UINT32_3_IDX 22
  29.426 +#define TPM_GET_CAP_RET_UINT32_4_IDX 26
  29.427 +#define TPM_GET_CAP_PERM_DISABLE_IDX 16
  29.428 +#define TPM_GET_CAP_PERM_INACTIVE_IDX 18
  29.429 +#define TPM_GET_CAP_RET_BOOL_1_IDX 14
  29.430 +#define TPM_GET_CAP_TEMP_INACTIVE_IDX 16
  29.431 +
  29.432 +#define TPM_CAP_IDX 13
  29.433 +#define TPM_CAP_SUBCAP_IDX 21
  29.434 +
  29.435 +enum tpm_capabilities {
  29.436 +	TPM_CAP_FLAG = 4,
  29.437 +	TPM_CAP_PROP = 5,
  29.438 +};
  29.439 +
  29.440 +enum tpm_sub_capabilities {
  29.441 +	TPM_CAP_PROP_PCR = 0x1,
  29.442 +	TPM_CAP_PROP_MANUFACTURER = 0x3,
  29.443 +	TPM_CAP_FLAG_PERM = 0x8,
  29.444 +	TPM_CAP_FLAG_VOL = 0x9,
  29.445 +	TPM_CAP_PROP_OWNER = 0x11,
  29.446 +	TPM_CAP_PROP_TIS_TIMEOUT = 0x15,
  29.447 +	TPM_CAP_PROP_TIS_DURATION = 0x20,
  29.448 +};
  29.449 +
  29.450 +/*
  29.451 + * This is a semi generic GetCapability command for use
  29.452 + * with the capability type TPM_CAP_PROP or TPM_CAP_FLAG
  29.453 + * and their associated sub_capabilities.
  29.454 + */
  29.455 +
  29.456 +static const u8 tpm_cap[] = {
  29.457  	0, 193,			/* TPM_TAG_RQU_COMMAND */
  29.458  	0, 0, 0, 22,		/* length */
  29.459  	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
  29.460 -	0, 0, 0, 5,
  29.461 -	0, 0, 0, 4,
  29.462 -	0, 0, 1, 1
  29.463 +	0, 0, 0, 0,		/* TPM_CAP_<TYPE> */
  29.464 +	0, 0, 0, 4,		/* TPM_CAP_SUB_<TYPE> size */
  29.465 +	0, 0, 1, 0		/* TPM_CAP_SUB_<TYPE> */
  29.466  };
  29.467  
  29.468 -#define READ_PCR_RESULT_SIZE 30
  29.469 +static ssize_t transmit_cmd(struct tpm_chip *chip, u8 *data, int len,
  29.470 +			    char *desc)
  29.471 +{
  29.472 +	int err;
  29.473 +
  29.474 +	len = tpm_transmit(chip, data, len);
  29.475 +	if (len <  0)
  29.476 +		return len;
  29.477 +	if (len == TPM_ERROR_SIZE) {
  29.478 +		err = be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX)));
  29.479 +		dev_dbg(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);
  29.480 +		return err;
  29.481 +	}
  29.482 +	return 0;
  29.483 +}
  29.484 +
  29.485 +void tpm_gen_interrupt(struct tpm_chip *chip)
  29.486 +{
  29.487 +	u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
  29.488 +	ssize_t rc;
  29.489 +
  29.490 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
  29.491 +	data[TPM_CAP_IDX] = TPM_CAP_PROP;
  29.492 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
  29.493 +
  29.494 +	rc = transmit_cmd(chip, data, sizeof(data),
  29.495 +			"attempting to determine the timeouts");
  29.496 +}
  29.497 +EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
  29.498 +
  29.499 +void tpm_get_timeouts(struct tpm_chip *chip)
  29.500 +{
  29.501 +	u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
  29.502 +	ssize_t rc;
  29.503 +	u32 timeout;
  29.504 +
  29.505 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
  29.506 +	data[TPM_CAP_IDX] = TPM_CAP_PROP;
  29.507 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
  29.508 +
  29.509 +	rc = transmit_cmd(chip, data, sizeof(data),
  29.510 +			"attempting to determine the timeouts");
  29.511 +	if (rc)
  29.512 +		goto duration;
  29.513 +
  29.514 +	if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
  29.515 +	    != 4 * sizeof(u32))
  29.516 +		goto duration;
  29.517 +
  29.518 +	/* Don't overwrite default if value is 0 */
  29.519 +	timeout =
  29.520 +	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
  29.521 +	if (timeout)
  29.522 +		chip->vendor.timeout_a = msecs_to_jiffies(timeout);
  29.523 +	timeout =
  29.524 +	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
  29.525 +	if (timeout)
  29.526 +		chip->vendor.timeout_b = msecs_to_jiffies(timeout);
  29.527 +	timeout =
  29.528 +	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
  29.529 +	if (timeout)
  29.530 +		chip->vendor.timeout_c = msecs_to_jiffies(timeout);
  29.531 +	timeout =
  29.532 +	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX)));
  29.533 +	if (timeout)
  29.534 +		chip->vendor.timeout_d = msecs_to_jiffies(timeout);
  29.535 +
  29.536 +duration:
  29.537 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
  29.538 +	data[TPM_CAP_IDX] = TPM_CAP_PROP;
  29.539 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_DURATION;
  29.540 +
  29.541 +	rc = transmit_cmd(chip, data, sizeof(data),
  29.542 +			"attempting to determine the durations");
  29.543 +	if (rc)
  29.544 +		return;
  29.545 +
  29.546 +	if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
  29.547 +	    != 3 * sizeof(u32))
  29.548 +		return;
  29.549 +
  29.550 +	chip->vendor.duration[TPM_SHORT] =
  29.551 +	    msecs_to_jiffies(be32_to_cpu
  29.552 +			     (*((__be32 *) (data +
  29.553 +					    TPM_GET_CAP_RET_UINT32_1_IDX))));
  29.554 +	chip->vendor.duration[TPM_MEDIUM] =
  29.555 +	    msecs_to_jiffies(be32_to_cpu
  29.556 +			     (*((__be32 *) (data +
  29.557 +					    TPM_GET_CAP_RET_UINT32_2_IDX))));
  29.558 +	chip->vendor.duration[TPM_LONG] =
  29.559 +	    msecs_to_jiffies(be32_to_cpu
  29.560 +			     (*((__be32 *) (data +
  29.561 +					    TPM_GET_CAP_RET_UINT32_3_IDX))));
  29.562 +}
  29.563 +EXPORT_SYMBOL_GPL(tpm_get_timeouts);
  29.564 +
  29.565 +void tpm_continue_selftest(struct tpm_chip *chip)
  29.566 +{
  29.567 +	u8 data[] = {
  29.568 +		0, 193,			/* TPM_TAG_RQU_COMMAND */
  29.569 +		0, 0, 0, 10,		/* length */
  29.570 +		0, 0, 0, 83,		/* TPM_ORD_GetCapability */
  29.571 +	};
  29.572 +
  29.573 +	tpm_transmit(chip, data, sizeof(data));
  29.574 +}
  29.575 +EXPORT_SYMBOL_GPL(tpm_continue_selftest);
  29.576 +
  29.577 +ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr,
  29.578 +			char *buf)
  29.579 +{
  29.580 +	u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
  29.581 +	ssize_t rc;
  29.582 +
  29.583 +	struct tpm_chip *chip = dev_get_drvdata(dev);
  29.584 +	if (chip == NULL)
  29.585 +		return -ENODEV;
  29.586 +
  29.587 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
  29.588 +	data[TPM_CAP_IDX] = TPM_CAP_FLAG;
  29.589 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
  29.590 +
  29.591 +	rc = transmit_cmd(chip, data, sizeof(data),
  29.592 +			"attemtping to determine the permanent state");
  29.593 +	if (rc)
  29.594 +		return 0;
  29.595 +	return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]);
  29.596 +}
  29.597 +EXPORT_SYMBOL_GPL(tpm_show_enabled);
  29.598 +
  29.599 +ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr,
  29.600 +			char *buf)
  29.601 +{
  29.602 +	u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
  29.603 +	ssize_t rc;
  29.604 +
  29.605 +	struct tpm_chip *chip = dev_get_drvdata(dev);
  29.606 +	if (chip == NULL)
  29.607 +		return -ENODEV;
  29.608 +
  29.609 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
  29.610 +	data[TPM_CAP_IDX] = TPM_CAP_FLAG;
  29.611 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
  29.612 +
  29.613 +	rc = transmit_cmd(chip, data, sizeof(data),
  29.614 +			"attemtping to determine the permanent state");
  29.615 +	if (rc)
  29.616 +		return 0;
  29.617 +	return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]);
  29.618 +}
  29.619 +EXPORT_SYMBOL_GPL(tpm_show_active);
  29.620 +
  29.621 +ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr,
  29.622 +			char *buf)
  29.623 +{
  29.624 +	u8 data[sizeof(tpm_cap)];
  29.625 +	ssize_t rc;
  29.626 +
  29.627 +	struct tpm_chip *chip = dev_get_drvdata(dev);
  29.628 +	if (chip == NULL)
  29.629 +		return -ENODEV;
  29.630 +
  29.631 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
  29.632 +	data[TPM_CAP_IDX] = TPM_CAP_PROP;
  29.633 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER;
  29.634 +
  29.635 +	rc = transmit_cmd(chip, data, sizeof(data),
  29.636 +			"attempting to determine the owner state");
  29.637 +	if (rc)
  29.638 +		return 0;
  29.639 +	return sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]);
  29.640 +}
  29.641 +EXPORT_SYMBOL_GPL(tpm_show_owned);
  29.642 +
  29.643 +ssize_t tpm_show_temp_deactivated(struct device * dev,
  29.644 +				struct device_attribute * attr, char *buf)
  29.645 +{
  29.646 +	u8 data[sizeof(tpm_cap)];
  29.647 +	ssize_t rc;
  29.648 +
  29.649 +	struct tpm_chip *chip = dev_get_drvdata(dev);
  29.650 +	if (chip == NULL)
  29.651 +		return -ENODEV;
  29.652 +
  29.653 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
  29.654 +	data[TPM_CAP_IDX] = TPM_CAP_FLAG;
  29.655 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL;
  29.656 +
  29.657 +	rc = transmit_cmd(chip, data, sizeof(data),
  29.658 +			"attempting to determine the temporary state");
  29.659 +	if (rc)
  29.660 +		return 0;
  29.661 +	return sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]);
  29.662 +}
  29.663 +EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);
  29.664 +
  29.665  static const u8 pcrread[] = {
  29.666  	0, 193,			/* TPM_TAG_RQU_COMMAND */
  29.667  	0, 0, 0, 14,		/* length */
  29.668 @@ -141,8 +682,8 @@ static const u8 pcrread[] = {
  29.669  ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
  29.670  		      char *buf)
  29.671  {
  29.672 -	u8 data[READ_PCR_RESULT_SIZE];
  29.673 -	ssize_t len;
  29.674 +	u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(pcrread)), 30)];
  29.675 +	ssize_t rc;
  29.676  	int i, j, num_pcrs;
  29.677  	__be32 index;
  29.678  	char *str = buf;
  29.679 @@ -151,29 +692,24 @@ ssize_t tpm_show_pcrs(struct device *dev
  29.680  	if (chip == NULL)
  29.681  		return -ENODEV;
  29.682  
  29.683 -	memcpy(data, cap_pcr, sizeof(cap_pcr));
  29.684 -	if ((len = tpm_transmit(chip, data, sizeof(data)))
  29.685 -	    < CAP_PCR_RESULT_SIZE) {
  29.686 -		dev_dbg(chip->dev, "A TPM error (%d) occurred "
  29.687 -				"attempting to determine the number of PCRS\n",
  29.688 -			be32_to_cpu(*((__be32 *) (data + 6))));
  29.689 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
  29.690 +	data[TPM_CAP_IDX] = TPM_CAP_PROP;
  29.691 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR;
  29.692 +
  29.693 +	rc = transmit_cmd(chip, data, sizeof(data),
  29.694 +			"attempting to determine the number of PCRS");
  29.695 +	if (rc)
  29.696  		return 0;
  29.697 -	}
  29.698  
  29.699  	num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
  29.700 -
  29.701  	for (i = 0; i < num_pcrs; i++) {
  29.702  		memcpy(data, pcrread, sizeof(pcrread));
  29.703  		index = cpu_to_be32(i);
  29.704  		memcpy(data + 10, &index, 4);
  29.705 -		if ((len = tpm_transmit(chip, data, sizeof(data)))
  29.706 -		    < READ_PCR_RESULT_SIZE){
  29.707 -			dev_dbg(chip->dev, "A TPM error (%d) occurred"
  29.708 -				" attempting to read PCR %d of %d\n",
  29.709 -				be32_to_cpu(*((__be32 *) (data + 6))),
  29.710 -				i, num_pcrs);
  29.711 +		rc = transmit_cmd(chip, data, sizeof(data),
  29.712 +				"attempting to read a PCR");
  29.713 +		if (rc)
  29.714  			goto out;
  29.715 -		}
  29.716  		str += sprintf(str, "PCR-%02d: ", i);
  29.717  		for (j = 0; j < TPM_DIGEST_SIZE; j++)
  29.718  			str += sprintf(str, "%02X ", *(data + 10 + j));
  29.719 @@ -195,7 +731,7 @@ ssize_t tpm_show_pubek(struct device *de
  29.720  		       char *buf)
  29.721  {
  29.722  	u8 *data;
  29.723 -	ssize_t len;
  29.724 +	ssize_t err;
  29.725  	int i, rc;
  29.726  	char *str = buf;
  29.727  
  29.728 @@ -209,14 +745,10 @@ ssize_t tpm_show_pubek(struct device *de
  29.729  
  29.730  	memcpy(data, readpubek, sizeof(readpubek));
  29.731  
  29.732 -	if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <
  29.733 -	    READ_PUBEK_RESULT_SIZE) {
  29.734 -		dev_dbg(chip->dev, "A TPM error (%d) occurred "
  29.735 -				"attempting to read the PUBEK\n",
  29.736 -			    be32_to_cpu(*((__be32 *) (data + 6))));
  29.737 -		rc = 0;
  29.738 +	err = transmit_cmd(chip, data, READ_PUBEK_RESULT_SIZE,
  29.739 +			"attempting to read the PUBEK");
  29.740 +	if (err)
  29.741  		goto out;
  29.742 -	}
  29.743  
  29.744  	/* 
  29.745  	   ignore header 10 bytes
  29.746 @@ -246,36 +778,68 @@ ssize_t tpm_show_pubek(struct device *de
  29.747  		if ((i + 1) % 16 == 0)
  29.748  			str += sprintf(str, "\n");
  29.749  	}
  29.750 +out:
  29.751  	rc = str - buf;
  29.752 -out:
  29.753  	kfree(data);
  29.754  	return rc;
  29.755  }
  29.756  EXPORT_SYMBOL_GPL(tpm_show_pubek);
  29.757  
  29.758 -#define CAP_VER_RESULT_SIZE 18
  29.759 +#define CAP_VERSION_1_1 6
  29.760 +#define CAP_VERSION_1_2 0x1A
  29.761 +#define CAP_VERSION_IDX 13
  29.762  static const u8 cap_version[] = {
  29.763  	0, 193,			/* TPM_TAG_RQU_COMMAND */
  29.764  	0, 0, 0, 18,		/* length */
  29.765  	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
  29.766 -	0, 0, 0, 6,
  29.767 +	0, 0, 0, 0,
  29.768  	0, 0, 0, 0
  29.769  };
  29.770  
  29.771 -#define CAP_MANUFACTURER_RESULT_SIZE 18
  29.772 -static const u8 cap_manufacturer[] = {
  29.773 -	0, 193,			/* TPM_TAG_RQU_COMMAND */
  29.774 -	0, 0, 0, 22,		/* length */
  29.775 -	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
  29.776 -	0, 0, 0, 5,
  29.777 -	0, 0, 0, 4,
  29.778 -	0, 0, 1, 3
  29.779 -};
  29.780 -
  29.781  ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
  29.782  		      char *buf)
  29.783  {
  29.784 -	u8 data[sizeof(cap_manufacturer)];
  29.785 +	u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)];
  29.786 +	ssize_t rc;
  29.787 +	char *str = buf;
  29.788 +
  29.789 +	struct tpm_chip *chip = dev_get_drvdata(dev);
  29.790 +	if (chip == NULL)
  29.791 +		return -ENODEV;
  29.792 +
  29.793 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
  29.794 +	data[TPM_CAP_IDX] = TPM_CAP_PROP;
  29.795 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
  29.796 +
  29.797 +	rc = transmit_cmd(chip, data, sizeof(data),
  29.798 +			"attempting to determine the manufacturer");
  29.799 +	if (rc)
  29.800 +		return 0;
  29.801 +
  29.802 +	str += sprintf(str, "Manufacturer: 0x%x\n",
  29.803 +		       be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
  29.804 +
  29.805 +	memcpy(data, cap_version, sizeof(cap_version));
  29.806 +	data[CAP_VERSION_IDX] = CAP_VERSION_1_1;
  29.807 +	rc = transmit_cmd(chip, data, sizeof(data),
  29.808 +			"attempting to determine the 1.1 version");
  29.809 +	if (rc)
  29.810 +		goto out;
  29.811 +
  29.812 +	str += sprintf(str,
  29.813 +		       "TCG version: %d.%d\nFirmware version: %d.%d\n",
  29.814 +		       (int) data[14], (int) data[15], (int) data[16],
  29.815 +		       (int) data[17]);
  29.816 +
  29.817 +out:
  29.818 +	return str - buf;
  29.819 +}
  29.820 +EXPORT_SYMBOL_GPL(tpm_show_caps);
  29.821 +
  29.822 +ssize_t tpm_show_caps_1_2(struct device * dev,
  29.823 +			  struct device_attribute * attr, char *buf)
  29.824 +{
  29.825 +	u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)];
  29.826  	ssize_t len;
  29.827  	char *str = buf;
  29.828  
  29.829 @@ -283,29 +847,40 @@ ssize_t tpm_show_caps(struct device *dev
  29.830  	if (chip == NULL)
  29.831  		return -ENODEV;
  29.832  
  29.833 -	memcpy(data, cap_manufacturer, sizeof(cap_manufacturer));
  29.834 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
  29.835 +	data[TPM_CAP_IDX] = TPM_CAP_PROP;
  29.836 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
  29.837  
  29.838 -	if ((len = tpm_transmit(chip, data, sizeof(data))) <
  29.839 -	    CAP_MANUFACTURER_RESULT_SIZE)
  29.840 -		return len;
  29.841 +	if ((len = tpm_transmit(chip, data, sizeof(data))) <=
  29.842 +	    TPM_ERROR_SIZE) {
  29.843 +		dev_dbg(chip->dev, "A TPM error (%d) occurred "
  29.844 +			"attempting to determine the manufacturer\n",
  29.845 +			be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
  29.846 +		return 0;
  29.847 +	}
  29.848  
  29.849  	str += sprintf(str, "Manufacturer: 0x%x\n",
  29.850 -		       be32_to_cpu(*((__be32 *) (data + 14))));
  29.851 +		       be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
  29.852  
  29.853  	memcpy(data, cap_version, sizeof(cap_version));
  29.854 -
  29.855 -	if ((len = tpm_transmit(chip, data, sizeof(data))) <
  29.856 -	    CAP_VER_RESULT_SIZE)
  29.857 -		return len;
  29.858 +	data[CAP_VERSION_IDX] = CAP_VERSION_1_2;
  29.859  
  29.860 -	str +=
  29.861 -	    sprintf(str, "TCG version: %d.%d\nFirmware version: %d.%d\n",
  29.862 -		    (int) data[14], (int) data[15], (int) data[16],
  29.863 -		    (int) data[17]);
  29.864 +	if ((len = tpm_transmit(chip, data, sizeof(data))) <=
  29.865 +	    TPM_ERROR_SIZE) {
  29.866 +		dev_err(chip->dev, "A TPM error (%d) occurred "
  29.867 +			"attempting to determine the 1.2 version\n",
  29.868 +			be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
  29.869 +		goto out;
  29.870 +	}
  29.871 +	str += sprintf(str,
  29.872 +		       "TCG version: %d.%d\nFirmware version: %d.%d\n",
  29.873 +		       (int) data[16], (int) data[17], (int) data[18],
  29.874 +		       (int) data[19]);
  29.875  
  29.876 +out:
  29.877  	return str - buf;
  29.878  }
  29.879 -EXPORT_SYMBOL_GPL(tpm_show_caps);
  29.880 +EXPORT_SYMBOL_GPL(tpm_show_caps_1_2);
  29.881  
  29.882  ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
  29.883  			const char *buf, size_t count)
  29.884 @@ -314,7 +889,7 @@ ssize_t tpm_store_cancel(struct device *
  29.885  	if (chip == NULL)
  29.886  		return 0;
  29.887  
  29.888 -	chip->vendor->cancel(chip);
  29.889 +	chip->vendor.cancel(chip);
  29.890  	return count;
  29.891  }
  29.892  EXPORT_SYMBOL_GPL(tpm_store_cancel);
  29.893 @@ -330,7 +905,7 @@ int tpm_open(struct inode *inode, struct
  29.894  	spin_lock(&driver_lock);
  29.895  
  29.896  	list_for_each_entry(pos, &tpm_chip_list, list) {
  29.897 -		if (pos->vendor->miscdev.minor == minor) {
  29.898 +		if (pos->vendor.miscdev.minor == minor) {
  29.899  			chip = pos;
  29.900  			break;
  29.901  		}
  29.902 @@ -352,7 +927,12 @@ int tpm_open(struct inode *inode, struct
  29.903  
  29.904  	spin_unlock(&driver_lock);
  29.905  
  29.906 -	chip->data_buffer = kmalloc(get_chip_buffersize(chip) * sizeof(u8), GFP_KERNEL);
  29.907 +#ifndef CONFIG_XEN
  29.908 +	chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
  29.909 +#else
  29.910 +	chip->data_buffer = kmalloc(get_chip_buffersize(chip) * sizeof(u8),
  29.911 +	                            GFP_KERNEL);
  29.912 +#endif
  29.913  	if (chip->data_buffer == NULL) {
  29.914  		chip->num_opens--;
  29.915  		put_device(chip->dev);
  29.916 @@ -388,7 +968,7 @@ int tpm_release(struct inode *inode, str
  29.917  EXPORT_SYMBOL_GPL(tpm_release);
  29.918  
  29.919  ssize_t tpm_write(struct file *file, const char __user *buf,
  29.920 -		  size_t size, loff_t * off)
  29.921 +		  size_t size, loff_t *off)
  29.922  {
  29.923  	struct tpm_chip *chip = file->private_data;
  29.924  	int in_size = size, out_size;
  29.925 @@ -400,8 +980,13 @@ ssize_t tpm_write(struct file *file, con
  29.926  
  29.927  	down(&chip->buffer_mutex);
  29.928  
  29.929 +#ifndef CONFIG_XEN
  29.930 +	if (in_size > TPM_BUFSIZE)
  29.931 +		in_size = TPM_BUFSIZE;
  29.932 +#else
  29.933  	if (in_size > get_chip_buffersize(chip))
  29.934  		in_size = get_chip_buffersize(chip);
  29.935 +#endif
  29.936  
  29.937  	if (copy_from_user
  29.938  	    (chip->data_buffer, (void __user *) buf, in_size)) {
  29.939 @@ -410,11 +995,17 @@ ssize_t tpm_write(struct file *file, con
  29.940  	}
  29.941  
  29.942  	/* atomic tpm command send and result receive */
  29.943 -	out_size = tpm_transmit(chip, chip->data_buffer, 
  29.944 +#ifndef CONFIG_XEN
  29.945 +	out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
  29.946 +#else
  29.947 +	out_size = tpm_transmit(chip, chip->data_buffer,
  29.948  	                        get_chip_buffersize(chip));
  29.949 +#endif
  29.950  
  29.951  	atomic_set(&chip->data_pending, out_size);
  29.952 +#ifdef CONFIG_XEN
  29.953  	atomic_set(&chip->data_position, 0);
  29.954 +#endif
  29.955  	up(&chip->buffer_mutex);
  29.956  
  29.957  	/* Set a timeout by which the reader must come claim the result */
  29.958 @@ -422,42 +1013,59 @@ ssize_t tpm_write(struct file *file, con
  29.959  
  29.960  	return in_size;
  29.961  }
  29.962 -
  29.963  EXPORT_SYMBOL_GPL(tpm_write);
  29.964  
  29.965 -ssize_t tpm_read(struct file * file, char __user *buf,
  29.966 -		 size_t size, loff_t * off)
  29.967 +ssize_t tpm_read(struct file *file, char __user *buf,
  29.968 +		 size_t size, loff_t *off)
  29.969  {
  29.970  	struct tpm_chip *chip = file->private_data;
  29.971  	int ret_size;
  29.972 +#ifdef CONFIG_XEN
  29.973  	int pos, pending = 0;
  29.974 +#endif
  29.975  
  29.976 +#ifndef CONFIG_XEN
  29.977 +	del_singleshot_timer_sync(&chip->user_read_timer);
  29.978 +	flush_scheduled_work();
  29.979 +#endif
  29.980  	ret_size = atomic_read(&chip->data_pending);
  29.981 +#ifndef CONFIG_XEN
  29.982 +	atomic_set(&chip->data_pending, 0);
  29.983 +#endif
  29.984  	if (ret_size > 0) {	/* relay data */
  29.985  		if (size < ret_size)
  29.986  			ret_size = size;
  29.987  
  29.988 +#ifdef CONFIG_XEN
  29.989  		pos = atomic_read(&chip->data_position);
  29.990 -
  29.991 +#endif
  29.992  		down(&chip->buffer_mutex);
  29.993 +#ifndef CONFIG_XEN
  29.994 +		if (copy_to_user(buf, chip->data_buffer, ret_size))
  29.995 +#else
  29.996  		if (copy_to_user(buf, &chip->data_buffer[pos], ret_size)) {
  29.997 +#endif
  29.998  			ret_size = -EFAULT;
  29.999 +#ifdef CONFIG_XEN
 29.1000  		} else {
 29.1001  			pending = atomic_read(&chip->data_pending) - ret_size;
 29.1002  			if ( pending ) {
 29.1003 -				atomic_set( &chip->data_pending, pending );
 29.1004 -				atomic_set( &chip->data_position, pos+ret_size );
 29.1005 +				atomic_set(&chip->data_pending, pending);
 29.1006 +				atomic_set(&chip->data_position,
 29.1007 +				           pos+ret_size);
 29.1008  			}
 29.1009  		}
 29.1010 +#endif
 29.1011  		up(&chip->buffer_mutex);
 29.1012  	}
 29.1013 -	
 29.1014 -	if ( ret_size <= 0 || pending == 0 ) {
 29.1015 -		atomic_set( &chip->data_pending, 0 );
 29.1016 +
 29.1017 +#ifdef CONFIG_XEN
 29.1018 + 	if ( ret_size <= 0 || pending == 0 ) {
 29.1019 +		atomic_set(&chip->data_pending, 0);
 29.1020  		del_singleshot_timer_sync(&chip->user_read_timer);
 29.1021  		flush_scheduled_work();
 29.1022  	}
 29.1023 -
 29.1024 +#endif
 29.1025  	return ret_size;
 29.1026  }
 29.1027  EXPORT_SYMBOL_GPL(tpm_read);
 29.1028 @@ -478,14 +1086,13 @@ void tpm_remove_hardware(struct device *
 29.1029  	spin_unlock(&driver_lock);
 29.1030  
 29.1031  	dev_set_drvdata(dev, NULL);
 29.1032 -	misc_deregister(&chip->vendor->miscdev);
 29.1033 -	kfree(chip->vendor->miscdev.name);
 29.1034 +	misc_deregister(&chip->vendor.miscdev);
 29.1035 +	kfree(chip->vendor.miscdev.name);
 29.1036  
 29.1037 -	sysfs_remove_group(&dev->kobj, chip->vendor->attr_group);
 29.1038 +	sysfs_remove_group(&dev->kobj, chip->vendor.attr_group);
 29.1039  	tpm_bios_log_teardown(chip->bios_dir);
 29.1040  
 29.1041 -	dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &=
 29.1042 -		~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
 29.1043 +	clear_bit(chip->dev_num, dev_mask);
 29.1044  
 29.1045  	kfree(chip);
 29.1046  
 29.1047 @@ -536,18 +1143,18 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume);
 29.1048   * upon errant exit from this function specific probe function should call
 29.1049   * pci_disable_device
 29.1050   */
 29.1051 -int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry)
 29.1052 +struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vendor_specific
 29.1053 +				       *entry)
 29.1054  {
 29.1055  #define DEVNAME_SIZE 7
 29.1056  
 29.1057  	char *devname;
 29.1058  	struct tpm_chip *chip;
 29.1059 -	int i, j;
 29.1060  
 29.1061  	/* Driver specific per-device data */
 29.1062  	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 29.1063  	if (chip == NULL)
 29.1064 -		return -ENOMEM;
 29.1065 +		return NULL;
 29.1066  
 29.1067  	init_MUTEX(&chip->buffer_mutex);
 29.1068  	init_MUTEX(&chip->tpm_mutex);
 29.1069 @@ -559,51 +1166,37 @@ int tpm_register_hardware(struct device 
 29.1070  	chip->user_read_timer.function = user_reader_timeout;
 29.1071  	chip->user_read_timer.data = (unsigned long) chip;
 29.1072  
 29.1073 -	chip->vendor = entry;
 29.1074 -	
 29.1075 -	if (entry->buffersize < TPM_MIN_BUFSIZE) {
 29.1076 -		entry->buffersize = TPM_MIN_BUFSIZE;
 29.1077 -	} else if (entry->buffersize > TPM_MAX_BUFSIZE) {
 29.1078 -		entry->buffersize = TPM_MAX_BUFSIZE;
 29.1079 -	}
 29.1080 -
 29.1081 -	chip->dev_num = -1;
 29.1082 +	memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));
 29.1083  
 29.1084 -	for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++)
 29.1085 -		for (j = 0; j < 8 * sizeof(int); j++)
 29.1086 -			if ((dev_mask[i] & (1 << j)) == 0) {
 29.1087 -				chip->dev_num =
 29.1088 -				    i * TPM_NUM_MASK_ENTRIES + j;
 29.1089 -				dev_mask[i] |= 1 << j;
 29.1090 -				goto dev_num_search_complete;
 29.1091 -			}
 29.1092 +	chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES);
 29.1093  
 29.1094 -dev_num_search_complete:
 29.1095 -	if (chip->dev_num < 0) {
 29.1096 +	if (chip->dev_num >= TPM_NUM_DEVICES) {
 29.1097  		dev_err(dev, "No available tpm device numbers\n");
 29.1098  		kfree(chip);
 29.1099 -		return -ENODEV;
 29.1100 +		return NULL;
 29.1101  	} else if (chip->dev_num == 0)
 29.1102 -		chip->vendor->miscdev.minor = TPM_MINOR;
 29.1103 +		chip->vendor.miscdev.minor = TPM_MINOR;
 29.1104  	else
 29.1105 -		chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
 29.1106 +		chip->vendor.miscdev.minor = MISC_DYNAMIC_MINOR;
 29.1107 +
 29.1108 +	set_bit(chip->dev_num, dev_mask);
 29.1109  
 29.1110  	devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
 29.1111  	scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
 29.1112 -	chip->vendor->miscdev.name = devname;
 29.1113 +	chip->vendor.miscdev.name = devname;
 29.1114  
 29.1115 -	chip->vendor->miscdev.dev = dev;
 29.1116 +	chip->vendor.miscdev.dev = dev;
 29.1117  	chip->dev = get_device(dev);
 29.1118  
 29.1119 -	if (misc_register(&chip->vendor->miscdev)) {
 29.1120 +	if (misc_register(&chip->vendor.miscdev)) {
 29.1121  		dev_err(chip->dev,
 29.1122  			"unable to misc_register %s, minor %d\n",
 29.1123 -			chip->vendor->miscdev.name,
 29.1124 -			chip->vendor->miscdev.minor);
 29.1125 +			chip->vendor.miscdev.name,
 29.1126 +			chip->vendor.miscdev.minor);
 29.1127  		put_device(dev);
 29.1128 +		clear_bit(chip->dev_num, dev_mask);
 29.1129  		kfree(chip);
 29.1130 -		dev_mask[i] &= !(1 << j);
 29.1131 -		return -ENODEV;
 29.1132 +		return NULL;
 29.1133  	}
 29.1134  
 29.1135  	spin_lock(&driver_lock);
 29.1136 @@ -614,11 +1207,11 @@ dev_num_search_complete:
 29.1137  
 29.1138  	spin_unlock(&driver_lock);
 29.1139  
 29.1140 -	sysfs_create_group(&dev->kobj, chip->vendor->attr_group);
 29.1141 +	sysfs_create_group(&dev->kobj, chip->vendor.attr_group);
 29.1142  
 29.1143  	chip->bios_dir = tpm_bios_log_setup(devname);
 29.1144  
 29.1145 -	return 0;
 29.1146 +	return chip;
 29.1147  }
 29.1148  EXPORT_SYMBOL_GPL(tpm_register_hardware);
 29.1149  
    30.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h	Wed Jul 05 10:23:54 2006 -0600
    30.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h	Wed Jul 05 20:11:37 2006 -0600
    30.3 @@ -24,6 +24,14 @@
    30.4  #include <linux/fs.h>
    30.5  #include <linux/miscdevice.h>
    30.6  #include <linux/platform_device.h>
    30.7 +#include <linux/io.h>
    30.8 +
    30.9 +#ifdef CONFIG_XEN
   30.10 +enum tpm_bufsize {
   30.11 +	TPM_MIN_BUFFERSIZE = 2048,
   30.12 +	TPM_MAX_BUFFERSIZE = 64 * 1024,
   30.13 +};
   30.14 +#endif
   30.15  
   30.16  enum tpm_timeout {
   30.17  	TPM_TIMEOUT = 5,	/* msecs */
   30.18 @@ -41,19 +49,33 @@ extern ssize_t tpm_show_pcrs(struct devi
   30.19  				char *);
   30.20  extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr,
   30.21  				char *);
   30.22 +extern ssize_t tpm_show_caps_1_2(struct device *, struct device_attribute *attr,
   30.23 +				char *);
   30.24  extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr,
   30.25  				const char *, size_t);
   30.26 +extern ssize_t tpm_show_enabled(struct device *, struct device_attribute *attr,
   30.27 +				char *);
   30.28 +extern ssize_t tpm_show_active(struct device *, struct device_attribute *attr,
   30.29 +				char *);
   30.30 +extern ssize_t tpm_show_owned(struct device *, struct device_attribute *attr,
   30.31 +				char *);
   30.32 +extern ssize_t tpm_show_temp_deactivated(struct device *,
   30.33 +					 struct device_attribute *attr, char *);
   30.34  
   30.35  struct tpm_chip;
   30.36  
   30.37  struct tpm_vendor_specific {
   30.38 -	u8 req_complete_mask;
   30.39 -	u8 req_complete_val;
   30.40 -	u8 req_canceled;
   30.41 +	const u8 req_complete_mask;
   30.42 +	const u8 req_complete_val;
   30.43 +	const u8 req_canceled;
   30.44 +#ifdef CONFIG_XEN
   30.45  	u32 buffersize;
   30.46 +#endif
   30.47  	void __iomem *iobase;		/* ioremapped address */
   30.48  	unsigned long base;		/* TPM base address */
   30.49  
   30.50 +	int irq;
   30.51 +
   30.52  	int region_size;
   30.53  	int have_region;
   30.54  
   30.55 @@ -63,6 +85,13 @@ struct tpm_vendor_specific {
   30.56  	u8 (*status) (struct tpm_chip *);
   30.57  	struct miscdevice miscdev;
   30.58  	struct attribute_group *attr_group;
   30.59 +	struct list_head list;
   30.60 +	int locality;
   30.61 +	unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* jiffies */
   30.62 +	unsigned long duration[3]; /* jiffies */
   30.63 +
   30.64 +	wait_queue_head_t read_queue;
   30.65 +	wait_queue_head_t int_queue;
   30.66  };
   30.67  
   30.68  struct tpm_chip {
   30.69 @@ -75,20 +104,27 @@ struct tpm_chip {
   30.70  	/* Data passed to and from the tpm via the read/write calls */
   30.71  	u8 *data_buffer;
   30.72  	atomic_t data_pending;
   30.73 +#ifdef CONFIG_XEN
   30.74  	atomic_t data_position;
   30.75 +#endif
   30.76  	struct semaphore buffer_mutex;
   30.77  
   30.78  	struct timer_list user_read_timer;	/* user needs to claim result */
   30.79  	struct work_struct work;
   30.80  	struct semaphore tpm_mutex;	/* tpm is processing */
   30.81  
   30.82 -	struct tpm_vendor_specific *vendor;
   30.83 +	struct tpm_vendor_specific vendor;
   30.84  
   30.85  	struct dentry **bios_dir;
   30.86  
   30.87  	struct list_head list;
   30.88 +#ifdef CONFIG_XEN
   30.89 +	void *priv;
   30.90 +#endif
   30.91  };
   30.92  
   30.93 +#define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor)
   30.94 +
   30.95  static inline int tpm_read_index(int base, int index)
   30.96  {
   30.97  	outb(index, base);
   30.98 @@ -101,13 +137,35 @@ static inline void tpm_write_index(int b
   30.99  	outb(value & 0xFF, base+1);
  30.100  }
  30.101  
  30.102 +#ifdef CONFIG_XEN
  30.103  static inline u32 get_chip_buffersize(struct tpm_chip *chip)
  30.104  {
  30.105 -	return chip->vendor->buffersize;
  30.106 +	u32 size = chip->vendor.buffersize;
  30.107 +	if (size > TPM_MAX_BUFFERSIZE) {
  30.108 +		return TPM_MAX_BUFFERSIZE;
  30.109 +	} else if (size < TPM_MIN_BUFFERSIZE) {
  30.110 +		return TPM_MIN_BUFFERSIZE;
  30.111 +	}
  30.112 +	return size;
  30.113  }
  30.114  
  30.115 -extern int tpm_register_hardware(struct device *,
  30.116 -				 struct tpm_vendor_specific *);
  30.117 +static inline void *chip_get_private(const struct tpm_chip *chip)
  30.118 +{
  30.119 +	return chip->priv;
  30.120 +}
  30.121 +
  30.122 +static inline void chip_set_private(struct tpm_chip *chip, void *priv)
  30.123 +{
  30.124 +	chip->priv = priv;
  30.125 +}
  30.126 +#endif
  30.127 +
  30.128 +extern void tpm_get_timeouts(struct tpm_chip *);
  30.129 +extern void tpm_gen_interrupt(struct tpm_chip *);
  30.130 +extern void tpm_continue_selftest(struct tpm_chip *);
  30.131 +extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32);
  30.132 +extern struct tpm_chip* tpm_register_hardware(struct device *,
  30.133 +				 const struct tpm_vendor_specific *);
  30.134  extern int tpm_open(struct inode *, struct file *);
  30.135  extern int tpm_release(struct inode *, struct file *);
  30.136  extern ssize_t tpm_write(struct file *, const char __user *, size_t,
  30.137 @@ -121,7 +179,7 @@ extern int tpm_pm_resume(struct device *
  30.138  extern struct dentry ** tpm_bios_log_setup(char *);
  30.139  extern void tpm_bios_log_teardown(struct dentry **);
  30.140  #else
  30.141 -static inline struct dentry* tpm_bios_log_setup(char *name)
  30.142 +static inline struct dentry ** tpm_bios_log_setup(char *name)
  30.143  {
  30.144  	return NULL;
  30.145  }
    31.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c	Wed Jul 05 10:23:54 2006 -0600
    31.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c	Wed Jul 05 20:11:37 2006 -0600
    31.3 @@ -29,8 +29,6 @@ enum {
    31.4  	STATUS_READY = 0x04
    31.5  };
    31.6  
    31.7 -#define MIN(x,y)  ((x) < (y)) ? (x) : (y)
    31.8 -
    31.9  struct transmission {
   31.10  	struct list_head next;
   31.11  
   31.12 @@ -49,26 +47,6 @@ enum {
   31.13  	TRANSMISSION_FLAG_WAS_QUEUED = 0x1
   31.14  };
   31.15  
   31.16 -struct vtpm_state {
   31.17 -	struct transmission *current_request;
   31.18 -	spinlock_t           req_list_lock;
   31.19 -	wait_queue_head_t    req_wait_queue;
   31.20 -
   31.21 -	struct list_head     queued_requests;
   31.22 -
   31.23 -	struct transmission *current_response;
   31.24 -	spinlock_t           resp_list_lock;
   31.25 -	wait_queue_head_t    resp_wait_queue;     // processes waiting for responses
   31.26 -
   31.27 -	struct transmission *req_cancelled;       // if a cancellation was encounterd
   31.28 -
   31.29 -	u8                   vd_status;
   31.30 -	u8                   flags;
   31.31 -
   31.32 -	unsigned long        disconnect_time;
   31.33 -
   31.34 -	struct tpm_virtual_device *tpmvd;
   31.35 -};
   31.36  
   31.37  enum {
   31.38  	DATAEX_FLAG_QUEUED_ONLY = 0x1
   31.39 @@ -76,7 +54,6 @@ enum {
   31.40  
   31.41  
   31.42  /* local variables */
   31.43 -static struct vtpm_state *vtpms;
   31.44  
   31.45  /* local function prototypes */
   31.46  static int _vtpm_send_queued(struct tpm_chip *chip);
   31.47 @@ -160,11 +137,16 @@ static inline void transmission_free(str
   31.48  /*
   31.49   * Lower layer uses this function to make a response available.
   31.50   */
   31.51 -int vtpm_vd_recv(const unsigned char *buffer, size_t count, const void *ptr)
   31.52 +int vtpm_vd_recv(const struct tpm_chip *chip,
   31.53 +                 const unsigned char *buffer, size_t count,
   31.54 +                 void *ptr)
   31.55  {
   31.56  	unsigned long flags;
   31.57  	int ret_size = 0;
   31.58  	struct transmission *t;
   31.59 +	struct vtpm_state *vtpms;
   31.60 +
   31.61 +	vtpms = (struct vtpm_state *)chip_get_private(chip);
   31.62  
   31.63  	/*
   31.64  	 * The list with requests must contain one request
   31.65 @@ -173,26 +155,11 @@ int vtpm_vd_recv(const unsigned char *bu
   31.66  	 */
   31.67  	spin_lock_irqsave(&vtpms->resp_list_lock, flags);
   31.68  	if (vtpms->current_request != ptr) {
   31.69 -		printk("WARNING: The request pointer is different than the "
   31.70 -		       "pointer the shared memory driver returned to me. "
   31.71 -		       "%p != %p\n",
   31.72 -		       vtpms->current_request, ptr);
   31.73 -	}
   31.74 -
   31.75 -	/*
   31.76 -	 * If the request has been cancelled, just quit here
   31.77 -	 */
   31.78 -	if (vtpms->req_cancelled == (struct transmission *)ptr) {
   31.79 -		if (vtpms->current_request == vtpms->req_cancelled) {
   31.80 -			vtpms->current_request = NULL;
   31.81 -		}
   31.82 -		transmission_free(vtpms->req_cancelled);
   31.83 -		vtpms->req_cancelled = NULL;
   31.84  		spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
   31.85  		return 0;
   31.86  	}
   31.87  
   31.88 -	if (NULL != (t = vtpms->current_request)) {
   31.89 +	if ((t = vtpms->current_request)) {
   31.90  		transmission_free(t);
   31.91  		vtpms->current_request = NULL;
   31.92  	}
   31.93 @@ -217,8 +184,12 @@ int vtpm_vd_recv(const unsigned char *bu
   31.94  /*
   31.95   * Lower layer indicates its status (connected/disconnected)
   31.96   */
   31.97 -void vtpm_vd_status(u8 vd_status)
   31.98 +void vtpm_vd_status(const struct tpm_chip *chip, u8 vd_status)
   31.99  {
  31.100 +	struct vtpm_state *vtpms;
  31.101 +
  31.102 +	vtpms = (struct vtpm_state *)chip_get_private(chip);
  31.103 +
  31.104  	vtpms->vd_status = vd_status;
  31.105  	if ((vtpms->vd_status & TPM_VD_STATUS_CONNECTED) == 0) {
  31.106  		vtpms->disconnect_time = jiffies;
  31.107 @@ -233,6 +204,9 @@ static int vtpm_recv(struct tpm_chip *ch
  31.108  {
  31.109  	int rc = 0;
  31.110  	unsigned long flags;
  31.111 +	struct vtpm_state *vtpms;
  31.112 +
  31.113 +	vtpms = (struct vtpm_state *)chip_get_private(chip);
  31.114  
  31.115  	/*
  31.116  	 * Check if the previous operation only queued the command
  31.117 @@ -251,7 +225,7 @@ static int vtpm_recv(struct tpm_chip *ch
  31.118  		 * Return a response of up to 30 '0's.
  31.119  		 */
  31.120  
  31.121 -		count = MIN(count, 30);
  31.122 +		count = min_t(size_t, count, 30);
  31.123  		memset(buf, 0x0, count);
  31.124  		return count;
  31.125  	}
  31.126 @@ -270,7 +244,7 @@ static int vtpm_recv(struct tpm_chip *ch
  31.127  	if (vtpms->current_response) {
  31.128  		struct transmission *t = vtpms->current_response;
  31.129  		vtpms->current_response = NULL;
  31.130 -		rc = MIN(count, t->response_len);
  31.131 +		rc = min(count, t->response_len);
  31.132  		memcpy(buf, t->response, rc);
  31.133  		transmission_free(t);
  31.134  	}
  31.135 @@ -284,6 +258,9 @@ static int vtpm_send(struct tpm_chip *ch
  31.136  	int rc = 0;
  31.137  	unsigned long flags;
  31.138  	struct transmission *t = transmission_alloc();
  31.139 +	struct vtpm_state *vtpms;
  31.140 +
  31.141 +	vtpms = (struct vtpm_state *)chip_get_private(chip);
  31.142  
  31.143  	if (!t)
  31.144  		return -ENOMEM;
  31.145 @@ -327,8 +304,7 @@ static int vtpm_send(struct tpm_chip *ch
  31.146  
  31.147  			vtpms->current_request = t;
  31.148  
  31.149 -			rc = vtpm_vd_send(chip,
  31.150 -			                  vtpms->tpmvd->tpm_private,
  31.151 +			rc = vtpm_vd_send(vtpms->tpm_private,
  31.152  			                  buf,
  31.153  			                  count,
  31.154  			                  t);
  31.155 @@ -373,6 +349,8 @@ static int _vtpm_send_queued(struct tpm_
  31.156  	int error = 0;
  31.157  	long flags;
  31.158  	unsigned char buffer[1];
  31.159 +	struct vtpm_state *vtpms;
  31.160 +	vtpms = (struct vtpm_state *)chip_get_private(chip);
  31.161  
  31.162  	spin_lock_irqsave(&vtpms->req_list_lock, flags);
  31.163  
  31.164 @@ -387,8 +365,7 @@ static int _vtpm_send_queued(struct tpm_
  31.165  		vtpms->current_request = qt;
  31.166  		spin_unlock_irqrestore(&vtpms->req_list_lock, flags);
  31.167  
  31.168 -		rc = vtpm_vd_send(chip,
  31.169 -		                  vtpms->tpmvd->tpm_private,
  31.170 +		rc = vtpm_vd_send(vtpms->tpm_private,
  31.171  		                  qt->request,
  31.172  		                  qt->request_len,
  31.173  		                  qt);
  31.174 @@ -427,9 +404,21 @@ static int _vtpm_send_queued(struct tpm_
  31.175  static void vtpm_cancel(struct tpm_chip *chip)
  31.176  {
  31.177  	unsigned long flags;
  31.178 +	struct vtpm_state *vtpms = (struct vtpm_state *)chip_get_private(chip);
  31.179 +
  31.180  	spin_lock_irqsave(&vtpms->resp_list_lock,flags);
  31.181  
  31.182 -	vtpms->req_cancelled = vtpms->current_request;
  31.183 +	if (!vtpms->current_response && vtpms->current_request) {
  31.184 +		spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
  31.185 +		interruptible_sleep_on(&vtpms->resp_wait_queue);
  31.186 +		spin_lock_irqsave(&vtpms->resp_list_lock,flags);
  31.187 +	}
  31.188 +
  31.189 +	if (vtpms->current_response) {
  31.190 +		struct transmission *t = vtpms->current_response;
  31.191 +		vtpms->current_response = NULL;
  31.192 +		transmission_free(t);
  31.193 +	}
  31.194  
  31.195  	spin_unlock_irqrestore(&vtpms->resp_list_lock,flags);
  31.196  }
  31.197 @@ -438,6 +427,9 @@ static u8 vtpm_status(struct tpm_chip *c
  31.198  {
  31.199  	u8 rc = 0;
  31.200  	unsigned long flags;
  31.201 +	struct vtpm_state *vtpms;
  31.202 +
  31.203 +	vtpms = (struct vtpm_state *)chip_get_private(chip);
  31.204  
  31.205  	spin_lock_irqsave(&vtpms->resp_list_lock, flags);
  31.206  	/*
  31.207 @@ -449,7 +441,10 @@ static u8 vtpm_status(struct tpm_chip *c
  31.208  	if (vtpms->current_response ||
  31.209  	    0 != (vtpms->flags & DATAEX_FLAG_QUEUED_ONLY)) {
  31.210  		rc = STATUS_DATA_AVAIL;
  31.211 +	} else if (!vtpms->current_response && !vtpms->current_request) {
  31.212 +		rc = STATUS_READY;
  31.213  	}
  31.214 +
  31.215  	spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
  31.216  	return rc;
  31.217  }
  31.218 @@ -465,12 +460,21 @@ static struct file_operations vtpm_ops =
  31.219  
  31.220  static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
  31.221  static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
  31.222 +static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
  31.223 +static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
  31.224 +static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
  31.225 +static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
  31.226 +		   NULL);
  31.227  static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
  31.228  static DEVICE_ATTR(cancel, S_IWUSR |S_IWGRP, NULL, tpm_store_cancel);
  31.229  
  31.230  static struct attribute *vtpm_attrs[] = {
  31.231  	&dev_attr_pubek.attr,
  31.232  	&dev_attr_pcrs.attr,
  31.233 +	&dev_attr_enabled.attr,
  31.234 +	&dev_attr_active.attr,
  31.235 +	&dev_attr_owned.attr,
  31.236 +	&dev_attr_temp_deactivated.attr,
  31.237  	&dev_attr_caps.attr,
  31.238  	&dev_attr_cancel.attr,
  31.239  	NULL,
  31.240 @@ -478,6 +482,8 @@ static struct attribute *vtpm_attrs[] = 
  31.241  
  31.242  static struct attribute_group vtpm_attr_grp = { .attrs = vtpm_attrs };
  31.243  
  31.244 +#define TPM_LONG_TIMEOUT   (10 * 60 * HZ)
  31.245 +
  31.246  static struct tpm_vendor_specific tpm_vtpm = {
  31.247  	.recv = vtpm_recv,
  31.248  	.send = vtpm_send,
  31.249 @@ -486,61 +492,56 @@ static struct tpm_vendor_specific tpm_vt
  31.250  	.req_complete_mask = STATUS_BUSY | STATUS_DATA_AVAIL,
  31.251  	.req_complete_val  = STATUS_DATA_AVAIL,
  31.252  	.req_canceled = STATUS_READY,
  31.253 -	.base = 0,
  31.254  	.attr_group = &vtpm_attr_grp,
  31.255  	.miscdev = {
  31.256  		.fops = &vtpm_ops,
  31.257  	},
  31.258 +	.duration = {
  31.259 +		TPM_LONG_TIMEOUT,
  31.260 +		TPM_LONG_TIMEOUT,
  31.261 +		TPM_LONG_TIMEOUT,
  31.262 +	},
  31.263  };
  31.264  
  31.265 -static struct platform_device *pdev;
  31.266 -
  31.267 -int __init init_vtpm(struct tpm_virtual_device *tvd)
  31.268 +struct tpm_chip *init_vtpm(struct device *dev,
  31.269 +                           struct tpm_virtual_device *tvd,
  31.270 +                           struct tpm_private *tp)
  31.271  {
  31.272 -	int rc;
  31.273 -
  31.274 -	/* vtpms is global - only allow one user */
  31.275 -	if (vtpms)
  31.276 -		return -EBUSY;
  31.277 +	long rc;
  31.278 +	struct tpm_chip *chip;
  31.279 +	struct vtpm_state *vtpms;
  31.280  
  31.281  	vtpms = kzalloc(sizeof(struct vtpm_state), GFP_KERNEL);
  31.282  	if (!vtpms)
  31.283 -		return -ENOMEM;
  31.284 +		return ERR_PTR(-ENOMEM);
  31.285  
  31.286  	vtpm_state_init(vtpms);
  31.287  	vtpms->tpmvd = tvd;
  31.288 -
  31.289 -	pdev = platform_device_register_simple("tpm_vtpm", -1, NULL, 0);
  31.290 -	if (IS_ERR(pdev)) {
  31.291 -		rc = PTR_ERR(pdev);
  31.292 -		goto err_free_mem;
  31.293 -	}
  31.294 +	vtpms->tpm_private = tp;
  31.295  
  31.296  	if (tvd)
  31.297  		tpm_vtpm.buffersize = tvd->max_tx_size;
  31.298  
  31.299 -	if ((rc = tpm_register_hardware(&pdev->dev, &tpm_vtpm)) < 0) {
  31.300 -		goto err_unreg_pdev;
  31.301 +	chip = tpm_register_hardware(dev, &tpm_vtpm);
  31.302 +	if (!chip) {
  31.303 +		rc = -ENODEV;
  31.304 +		goto err_free_mem;
  31.305  	}
  31.306  
  31.307 -	return 0;
  31.308 +	chip_set_private(chip, vtpms);
  31.309  
  31.310 -err_unreg_pdev:
  31.311 -	platform_device_unregister(pdev);
  31.312 +	return chip;
  31.313 +
  31.314  err_free_mem:
  31.315  	kfree(vtpms);
  31.316 -	vtpms = NULL;
  31.317  
  31.318 -	return rc;
  31.319 +	return ERR_PTR(rc);
  31.320  }
  31.321  
  31.322 -void __exit cleanup_vtpm(void)
  31.323 +void cleanup_vtpm(struct device *dev)
  31.324  {
  31.325 -	struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
  31.326 -	if (chip) {
  31.327 -		tpm_remove_hardware(chip->dev);
  31.328 -		platform_device_unregister(pdev);
  31.329 -	}
  31.330 +	struct tpm_chip *chip = dev_get_drvdata(dev);
  31.331 +	struct vtpm_state *vtpms = (struct vtpm_state*)chip_get_private(chip);
  31.332 +	tpm_remove_hardware(dev);
  31.333  	kfree(vtpms);
  31.334 -	vtpms = NULL;
  31.335  }
    32.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h	Wed Jul 05 10:23:54 2006 -0600
    32.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h	Wed Jul 05 20:11:37 2006 -0600
    32.3 @@ -12,6 +12,26 @@ struct tpm_virtual_device {
    32.4  	 * for allocation of buffers.
    32.5  	 */
    32.6  	unsigned int max_tx_size;
    32.7 +};
    32.8 +
    32.9 +struct vtpm_state {
   32.10 +	struct transmission *current_request;
   32.11 +	spinlock_t           req_list_lock;
   32.12 +	wait_queue_head_t    req_wait_queue;
   32.13 +
   32.14 +	struct list_head     queued_requests;
   32.15 +
   32.16 +	struct transmission *current_response;
   32.17 +	spinlock_t           resp_list_lock;
   32.18 +	wait_queue_head_t    resp_wait_queue;     // processes waiting for responses
   32.19 +
   32.20 +	u8                   vd_status;
   32.21 +	u8                   flags;
   32.22 +
   32.23 +	unsigned long        disconnect_time;
   32.24 +
   32.25 +	struct tpm_virtual_device *tpmvd;
   32.26 +
   32.27  	/*
   32.28  	 * The following is a private structure of the underlying
   32.29  	 * driver. It is passed as parameter in the send function.
   32.30 @@ -19,20 +39,30 @@ struct tpm_virtual_device {
   32.31  	struct tpm_private *tpm_private;
   32.32  };
   32.33  
   32.34 +
   32.35  enum vdev_status {
   32.36  	TPM_VD_STATUS_DISCONNECTED = 0x0,
   32.37  	TPM_VD_STATUS_CONNECTED = 0x1
   32.38  };
   32.39  
   32.40  /* this function is called from tpm_vtpm.c */
   32.41 -int vtpm_vd_send(struct tpm_chip *tc,
   32.42 -                 struct tpm_private * tp,
   32.43 +int vtpm_vd_send(struct tpm_private * tp,
   32.44                   const u8 * buf, size_t count, void *ptr);
   32.45  
   32.46  /* these functions are offered by tpm_vtpm.c */
   32.47 -int __init init_vtpm(struct tpm_virtual_device *);
   32.48 -void __exit cleanup_vtpm(void);
   32.49 -int vtpm_vd_recv(const unsigned char *buffer, size_t count, const void *ptr);
   32.50 -void vtpm_vd_status(u8 status);
   32.51 +struct tpm_chip *init_vtpm(struct device *,
   32.52 +                           struct tpm_virtual_device *,
   32.53 +                           struct tpm_private *);
   32.54 +void cleanup_vtpm(struct device *);
   32.55 +int vtpm_vd_recv(const struct tpm_chip* chip,
   32.56 +                 const unsigned char *buffer, size_t count, void *ptr);
   32.57 +void vtpm_vd_status(const struct tpm_chip *, u8 status);
   32.58 +
   32.59 +static inline struct tpm_private *tpm_private_from_dev(struct device *dev)
   32.60 +{
   32.61 +	struct tpm_chip *chip = dev_get_drvdata(dev);
   32.62 +	struct vtpm_state *vtpms = chip_get_private(chip);
   32.63 +	return vtpms->tpm_private;
   32.64 +}
   32.65  
   32.66  #endif
    33.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c	Wed Jul 05 10:23:54 2006 -0600
    33.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c	Wed Jul 05 20:11:37 2006 -0600
    33.3 @@ -34,6 +34,7 @@
    33.4   */
    33.5  
    33.6  #include <linux/errno.h>
    33.7 +#include <linux/err.h>
    33.8  #include <linux/interrupt.h>
    33.9  #include <linux/mutex.h>
   33.10  #include <asm/uaccess.h>
   33.11 @@ -41,12 +42,15 @@
   33.12  #include <xen/interface/grant_table.h>
   33.13  #include <xen/interface/io/tpmif.h>
   33.14  #include <xen/xenbus.h>
   33.15 +#include "tpm.h"
   33.16  #include "tpm_vtpm.h"
   33.17  
   33.18  #undef DEBUG
   33.19  
   33.20  /* local structures */
   33.21  struct tpm_private {
   33.22 +	struct tpm_chip *chip;
   33.23 +
   33.24  	tpmif_tx_interface_t *tx;
   33.25  	atomic_t refcnt;
   33.26  	unsigned int evtchn;
   33.27 @@ -60,6 +64,7 @@ struct tpm_private {
   33.28  
   33.29  	atomic_t tx_busy;
   33.30  	void *tx_remember;
   33.31 +
   33.32  	domid_t backend_id;
   33.33  	wait_queue_head_t wait_q;
   33.34  
   33.35 @@ -95,6 +100,7 @@ static int tpm_xmit(struct tpm_private *
   33.36                      const u8 * buf, size_t count, int userbuffer,
   33.37                      void *remember);
   33.38  static void destroy_tpmring(struct tpm_private *tp);
   33.39 +void __exit tpmif_exit(void);
   33.40  
   33.41  #define DPRINTK(fmt, args...) \
   33.42      pr_debug("xen_tpm_fr (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args)
   33.43 @@ -199,8 +205,7 @@ static DEFINE_MUTEX(suspend_lock);
   33.44  /*
   33.45   * Send data via this module by calling this function
   33.46   */
   33.47 -int vtpm_vd_send(struct tpm_chip *chip,
   33.48 -                 struct tpm_private *tp,
   33.49 +int vtpm_vd_send(struct tpm_private *tp,
   33.50                   const u8 * buf, size_t count, void *ptr)
   33.51  {
   33.52  	int sent;
   33.53 @@ -331,7 +336,7 @@ out:
   33.54  static void backend_changed(struct xenbus_device *dev,
   33.55  			    enum xenbus_state backend_state)
   33.56  {
   33.57 -	struct tpm_private *tp = dev->dev.driver_data;
   33.58 +	struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
   33.59  	DPRINTK("\n");
   33.60  
   33.61  	switch (backend_state) {
   33.62 @@ -358,6 +363,9 @@ static void backend_changed(struct xenbu
   33.63  	}
   33.64  }
   33.65  
   33.66 +struct tpm_virtual_device tvd = {
   33.67 +	.max_tx_size = PAGE_SIZE * TPMIF_TX_RING_SIZE,
   33.68 +};
   33.69  
   33.70  static int tpmfront_probe(struct xenbus_device *dev,
   33.71                            const struct xenbus_device_id *id)
   33.72 @@ -369,6 +377,12 @@ static int tpmfront_probe(struct xenbus_
   33.73  	if (!tp)
   33.74  		return -ENOMEM;
   33.75  
   33.76 +	tp->chip = init_vtpm(&dev->dev, &tvd, tp);
   33.77 +
   33.78 +	if (IS_ERR(tp->chip)) {
   33.79 +		return PTR_ERR(tp->chip);
   33.80 +	}
   33.81 +
   33.82  	err = xenbus_scanf(XBT_NIL, dev->nodename,
   33.83  	                   "handle", "%i", &handle);
   33.84  	if (XENBUS_EXIST_ERR(err))
   33.85 @@ -380,12 +394,10 @@ static int tpmfront_probe(struct xenbus_
   33.86  	}
   33.87  
   33.88  	tp->dev = dev;
   33.89 -	dev->dev.driver_data = tp;
   33.90  
   33.91  	err = talk_to_backend(dev, tp);
   33.92  	if (err) {
   33.93  		tpm_private_put();
   33.94 -		dev->dev.driver_data = NULL;
   33.95  		return err;
   33.96  	}
   33.97  	return 0;
   33.98 @@ -394,16 +406,16 @@ static int tpmfront_probe(struct xenbus_
   33.99  
  33.100  static int tpmfront_remove(struct xenbus_device *dev)
  33.101  {
  33.102 -	struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data;
  33.103 +	struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
  33.104  	destroy_tpmring(tp);
  33.105 +	cleanup_vtpm(&dev->dev);
  33.106  	return 0;
  33.107  }
  33.108  
  33.109  static int tpmfront_suspend(struct xenbus_device *dev)
  33.110  {
  33.111 -	struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data;
  33.112 +	struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
  33.113  	u32 ctr;
  33.114 -
  33.115  	/* lock, so no app can send */
  33.116  	mutex_lock(&suspend_lock);
  33.117  	tp->is_suspended = 1;
  33.118 @@ -431,7 +443,7 @@ static int tpmfront_suspend(struct xenbu
  33.119  
  33.120  static int tpmfront_resume(struct xenbus_device *dev)
  33.121  {
  33.122 -	struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data;
  33.123 +	struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
  33.124  	destroy_tpmring(tp);
  33.125  	return talk_to_backend(dev, tp);
  33.126  }
  33.127 @@ -548,7 +560,7 @@ static void tpmif_rx_action(unsigned lon
  33.128  		offset += tocopy;
  33.129  	}
  33.130  
  33.131 -	vtpm_vd_recv(buffer, received, tp->tx_remember);
  33.132 +	vtpm_vd_recv(tp->chip, buffer, received, tp->tx_remember);
  33.133  	kfree(buffer);
  33.134  
  33.135  exit:
  33.136 @@ -638,6 +650,7 @@ static int tpm_xmit(struct tpm_private *
  33.137  
  33.138  	atomic_set(&tp->tx_busy, 1);
  33.139  	tp->tx_remember = remember;
  33.140 +
  33.141  	mb();
  33.142  
  33.143  	DPRINTK("Notifying backend via event channel %d\n",
  33.144 @@ -657,9 +670,9 @@ static void tpmif_notify_upperlayer(stru
  33.145  	 * to the BE.
  33.146  	 */
  33.147  	if (tp->is_connected) {
  33.148 -		vtpm_vd_status(TPM_VD_STATUS_CONNECTED);
  33.149 +		vtpm_vd_status(tp->chip, TPM_VD_STATUS_CONNECTED);
  33.150  	} else {
  33.151 -		vtpm_vd_status(TPM_VD_STATUS_DISCONNECTED);
  33.152 +		vtpm_vd_status(tp->chip, TPM_VD_STATUS_DISCONNECTED);
  33.153  	}
  33.154  }
  33.155  
  33.156 @@ -699,13 +712,10 @@ static void tpmif_set_connected_state(st
  33.157   * =================================================================
  33.158   */
  33.159  
  33.160 -struct tpm_virtual_device tvd = {
  33.161 -	.max_tx_size = PAGE_SIZE * TPMIF_TX_RING_SIZE,
  33.162 -};
  33.163  
  33.164  static int __init tpmif_init(void)
  33.165  {
  33.166 -	int rc;
  33.167 +	long rc = 0;
  33.168  	struct tpm_private *tp;
  33.169  
  33.170  	if ((xen_start_info->flags & SIF_INITDOMAIN)) {
  33.171 @@ -718,11 +728,6 @@ static int __init tpmif_init(void)
  33.172  		goto failexit;
  33.173  	}
  33.174  
  33.175 -	tvd.tpm_private = tp;
  33.176 -	rc = init_vtpm(&tvd);
  33.177 -	if (rc)
  33.178 -		goto init_vtpm_failed;
  33.179 -
  33.180  	IPRINTK("Initialising the vTPM driver.\n");
  33.181  	if ( gnttab_alloc_grant_references ( TPMIF_TX_RING_SIZE,
  33.182  	                                     &gref_head ) < 0) {
  33.183 @@ -734,19 +739,16 @@ static int __init tpmif_init(void)
  33.184  	return 0;
  33.185  
  33.186  gnttab_alloc_failed:
  33.187 -	cleanup_vtpm();
  33.188 -init_vtpm_failed:
  33.189  	tpm_private_put();
  33.190  failexit:
  33.191  
  33.192 -	return rc;
  33.193 +	return (int)rc;
  33.194  }
  33.195  
  33.196  
  33.197 -static void __exit tpmif_exit(void)
  33.198 +void __exit tpmif_exit(void)
  33.199  {
  33.200  	exit_tpm_xenbus();
  33.201 -	cleanup_vtpm();
  33.202  	tpm_private_put();
  33.203  	gnttab_free_grant_references(gref_head);
  33.204  }
    34.1 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Wed Jul 05 10:23:54 2006 -0600
    34.2 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Wed Jul 05 20:11:37 2006 -0600
    34.3 @@ -75,6 +75,9 @@ DEFINE_SPINLOCK(balloon_lock);
    34.4  static unsigned long current_pages;
    34.5  static unsigned long target_pages;
    34.6  
    34.7 +/* We increase/decrease in batches which fit in a page */
    34.8 +static unsigned long frame_list[PAGE_SIZE / sizeof(unsigned long)]; 
    34.9 +
   34.10  /* VM /proc information for memory */
   34.11  extern unsigned long totalram_pages;
   34.12  
   34.13 @@ -96,6 +99,11 @@ static void balloon_process(void *unused
   34.14  static DECLARE_WORK(balloon_worker, balloon_process, NULL);
   34.15  static struct timer_list balloon_timer;
   34.16  
   34.17 +/* When ballooning out (allocating memory to return to Xen) we don't really 
   34.18 +   want the kernel to try too hard since that can trigger the oom killer. */
   34.19 +#define GFP_BALLOON \
   34.20 +	(GFP_HIGHUSER | __GFP_NOWARN | __GFP_NORETRY | __GFP_NOMEMALLOC)
   34.21 +
   34.22  #define PAGE_TO_LIST(p) (&(p)->lru)
   34.23  #define LIST_TO_PAGE(l) list_entry((l), struct page, lru)
   34.24  #define UNLIST_PAGE(p)				\
   34.25 @@ -172,7 +180,7 @@ static unsigned long current_target(void
   34.26  
   34.27  static int increase_reservation(unsigned long nr_pages)
   34.28  {
   34.29 -	unsigned long *frame_list, frame, pfn, i, flags;
   34.30 +	unsigned long  pfn, i, flags;
   34.31  	struct page   *page;
   34.32  	long           rc;
   34.33  	struct xen_memory_reservation reservation = {
   34.34 @@ -181,15 +189,8 @@ static int increase_reservation(unsigned
   34.35  		.domid        = DOMID_SELF
   34.36  	};
   34.37  
   34.38 -	if (nr_pages > (PAGE_SIZE / sizeof(unsigned long)))
   34.39 -		nr_pages = PAGE_SIZE / sizeof(unsigned long);
   34.40 -
   34.41 -	frame_list = (unsigned long *)__get_free_page(GFP_KERNEL);
   34.42 -	if (frame_list == NULL) {
   34.43 -		frame_list = &frame;
   34.44 -		if (nr_pages > 1)
   34.45 -			nr_pages = 1;
   34.46 -	}
   34.47 +	if (nr_pages > ARRAY_SIZE(frame_list))
   34.48 +		nr_pages = ARRAY_SIZE(frame_list);
   34.49  
   34.50  	balloon_lock(flags);
   34.51  
   34.52 @@ -253,15 +254,12 @@ static int increase_reservation(unsigned
   34.53   out:
   34.54  	balloon_unlock(flags);
   34.55  
   34.56 -	if (frame_list != &frame)
   34.57 -		free_page((unsigned long)frame_list);
   34.58 -
   34.59  	return 0;
   34.60  }
   34.61  
   34.62  static int decrease_reservation(unsigned long nr_pages)
   34.63  {
   34.64 -	unsigned long *frame_list, frame, pfn, i, flags;
   34.65 +	unsigned long  pfn, i, flags;
   34.66  	struct page   *page;
   34.67  	void          *v;
   34.68  	int            need_sleep = 0;
   34.69 @@ -272,18 +270,11 @@ static int decrease_reservation(unsigned
   34.70  		.domid        = DOMID_SELF
   34.71  	};
   34.72  
   34.73 -	if (nr_pages > (PAGE_SIZE / sizeof(unsigned long)))
   34.74 -		nr_pages = PAGE_SIZE / sizeof(unsigned long);
   34.75 -
   34.76 -	frame_list = (unsigned long *)__get_free_page(GFP_KERNEL);
   34.77 -	if (frame_list == NULL) {
   34.78 -		frame_list = &frame;
   34.79 -		if (nr_pages > 1)
   34.80 -			nr_pages = 1;
   34.81 -	}
   34.82 +	if (nr_pages > ARRAY_SIZE(frame_list))
   34.83 +		nr_pages = ARRAY_SIZE(frame_list);
   34.84  
   34.85  	for (i = 0; i < nr_pages; i++) {
   34.86 -		if ((page = alloc_page(GFP_HIGHUSER)) == NULL) {
   34.87 +		if ((page = alloc_page(GFP_BALLOON)) == NULL) {
   34.88  			nr_pages = i;
   34.89  			need_sleep = 1;
   34.90  			break;
   34.91 @@ -331,9 +322,6 @@ static int decrease_reservation(unsigned
   34.92  
   34.93  	balloon_unlock(flags);
   34.94  
   34.95 -	if (frame_list != &frame)
   34.96 -		free_page((unsigned long)frame_list);
   34.97 -
   34.98  	return need_sleep;
   34.99  }
  34.100  
    35.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Wed Jul 05 10:23:54 2006 -0600
    35.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Wed Jul 05 20:11:37 2006 -0600
    35.3 @@ -76,8 +76,6 @@ static void update_blkif_status(blkif_t 
    35.4   *  sysfs interface for VBD I/O requests
    35.5   */
    35.6  
    35.7 -#ifdef CONFIG_SYSFS
    35.8 -
    35.9  #define VBD_SHOW(name, format, args...)					\
   35.10  	static ssize_t show_##name(struct device *_dev,			\
   35.11  				   struct device_attribute *attr,	\
   35.12 @@ -106,57 +104,40 @@ static struct attribute_group vbdstat_gr
   35.13  	.attrs = vbdstat_attrs,
   35.14  };
   35.15  
   35.16 +VBD_SHOW(physical_device, "%x:%x\n", be->major, be->minor);
   35.17 +VBD_SHOW(mode, "%s\n", be->mode);
   35.18 +
   35.19  int xenvbd_sysfs_addif(struct xenbus_device *dev)
   35.20  {
   35.21 -	int error = 0;
   35.22 +	int error;
   35.23  	
   35.24 -	error = sysfs_create_group(&dev->dev.kobj,
   35.25 -				   &vbdstat_group);
   35.26 +	error = device_create_file(&dev->dev, &dev_attr_physical_device);
   35.27 + 	if (error)
   35.28 +		goto fail1;
   35.29 +
   35.30 +	error = device_create_file(&dev->dev, &dev_attr_mode);
   35.31  	if (error)
   35.32 -		goto fail;
   35.33 -	
   35.34 +		goto fail2;
   35.35 +
   35.36 +	error = sysfs_create_group(&dev->dev.kobj, &vbdstat_group);
   35.37 +	if (error)
   35.38 +		goto fail3;
   35.39 +
   35.40  	return 0;
   35.41 -	
   35.42 -fail:
   35.43 -	sysfs_remove_group(&dev->dev.kobj,
   35.44 -			   &vbdstat_group);
   35.45 +
   35.46 +fail3:	sysfs_remove_group(&dev->dev.kobj, &vbdstat_group);
   35.47 +fail2:	device_remove_file(&dev->dev, &dev_attr_mode);
   35.48 +fail1:	device_remove_file(&dev->dev, &dev_attr_physical_device);
   35.49  	return error;
   35.50  }
   35.51  
   35.52  void xenvbd_sysfs_delif(struct xenbus_device *dev)
   35.53  {
   35.54 -	sysfs_remove_group(&dev->dev.kobj,
   35.55 -			   &vbdstat_group);
   35.56 +	sysfs_remove_group(&dev->dev.kobj, &vbdstat_group);
   35.57 +	device_remove_file(&dev->dev, &dev_attr_mode);
   35.58 +	device_remove_file(&dev->dev, &dev_attr_physical_device);
   35.59  }
   35.60  
   35.61 -#else
   35.62 -
   35.63 -#define xenvbd_sysfs_addif(dev) (0)
   35.64 -#define xenvbd_sysfs_delif(dev) ((void)0)
   35.65 -
   35.66 -#endif /* CONFIG_SYSFS */
   35.67 -
   35.68 -static ssize_t show_physical_device(struct device *_dev,
   35.69 -				    struct device_attribute *attr, char *buf)
   35.70 -{
   35.71 -	struct xenbus_device *dev = to_xenbus_device(_dev);
   35.72 -	struct backend_info *be = dev->dev.driver_data;
   35.73 -	return sprintf(buf, "%x:%x\n", be->major, be->minor);
   35.74 -}
   35.75 -DEVICE_ATTR(physical_device, S_IRUSR | S_IRGRP | S_IROTH,
   35.76 -	    show_physical_device, NULL);
   35.77 -
   35.78 -
   35.79 -static ssize_t show_mode(struct device *_dev, struct device_attribute *attr,
   35.80 -			 char *buf)
   35.81 -{
   35.82 -	struct xenbus_device *dev = to_xenbus_device(_dev);
   35.83 -	struct backend_info *be = dev->dev.driver_data;
   35.84 -	return sprintf(buf, "%s\n", be->mode);
   35.85 -}
   35.86 -DEVICE_ATTR(mode, S_IRUSR | S_IRGRP | S_IROTH, show_mode, NULL);
   35.87 -
   35.88 -
   35.89  static int blkback_remove(struct xenbus_device *dev)
   35.90  {
   35.91  	struct backend_info *be = dev->dev.driver_data;
   35.92 @@ -176,9 +157,8 @@ static int blkback_remove(struct xenbus_
   35.93  		be->blkif = NULL;
   35.94  	}
   35.95  
   35.96 -	device_remove_file(&dev->dev, &dev_attr_physical_device);
   35.97 -	device_remove_file(&dev->dev, &dev_attr_mode);
   35.98 -	xenvbd_sysfs_delif(dev);
   35.99 +	if (be->major || be->minor)
  35.100 +		xenvbd_sysfs_delif(dev);
  35.101  
  35.102  	kfree(be);
  35.103  	dev->dev.driver_data = NULL;
  35.104 @@ -293,15 +273,18 @@ static void backend_changed(struct xenbu
  35.105  		err = vbd_create(be->blkif, handle, major, minor,
  35.106  				 (NULL == strchr(be->mode, 'w')));
  35.107  		if (err) {
  35.108 -			be->major = 0;
  35.109 -			be->minor = 0;
  35.110 +			be->major = be->minor = 0;
  35.111  			xenbus_dev_fatal(dev, err, "creating vbd structure");
  35.112  			return;
  35.113  		}
  35.114  
  35.115 -		device_create_file(&dev->dev, &dev_attr_physical_device);
  35.116 -		device_create_file(&dev->dev, &dev_attr_mode);
  35.117 -		xenvbd_sysfs_addif(dev);
  35.118 +		err = xenvbd_sysfs_addif(dev);
  35.119 +		if (err) {
  35.120 +			vbd_free(&be->blkif->vbd);
  35.121 +			be->major = be->minor = 0;
  35.122 +			xenbus_dev_fatal(dev, err, "creating sysfs entries");
  35.123 +			return;
  35.124 +		}
  35.125  
  35.126  		/* We're potentially connected now */
  35.127  		update_blkif_status(be->blkif); 
    36.1 --- a/linux-2.6-xen-sparse/drivers/xen/console/console.c	Wed Jul 05 10:23:54 2006 -0600
    36.2 +++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c	Wed Jul 05 20:11:37 2006 -0600
    36.3 @@ -267,7 +267,8 @@ void xencons_force_flush(void)
    36.4  /******************** User-space console driver (/dev/console) ************/
    36.5  
    36.6  #define DRV(_d)         (_d)
    36.7 -#define TTY_INDEX(_tty) ((_tty)->index)
    36.8 +#define DUMMY_TTY(_tty) ((xc_mode != XC_SERIAL) &&		\
    36.9 +			 ((_tty)->index != (xc_num - 1)))
   36.10  
   36.11  static struct termios *xencons_termios[MAX_NR_CONSOLES];
   36.12  static struct termios *xencons_termios_locked[MAX_NR_CONSOLES];
   36.13 @@ -391,7 +392,7 @@ static void xencons_send_xchar(struct tt
   36.14  {
   36.15  	unsigned long flags;
   36.16  
   36.17 -	if (TTY_INDEX(tty) != 0)
   36.18 +	if (DUMMY_TTY(tty))
   36.19  		return;
   36.20  
   36.21  	spin_lock_irqsave(&xencons_lock, flags);
   36.22 @@ -402,7 +403,7 @@ static void xencons_send_xchar(struct tt
   36.23  
   36.24  static void xencons_throttle(struct tty_struct *tty)
   36.25  {
   36.26 -	if (TTY_INDEX(tty) != 0)
   36.27 +	if (DUMMY_TTY(tty))
   36.28  		return;
   36.29  
   36.30  	if (I_IXOFF(tty))
   36.31 @@ -411,7 +412,7 @@ static void xencons_throttle(struct tty_
   36.32  
   36.33  static void xencons_unthrottle(struct tty_struct *tty)
   36.34  {
   36.35 -	if (TTY_INDEX(tty) != 0)
   36.36 +	if (DUMMY_TTY(tty))
   36.37  		return;
   36.38  
   36.39  	if (I_IXOFF(tty)) {
   36.40 @@ -426,7 +427,7 @@ static void xencons_flush_buffer(struct 
   36.41  {
   36.42  	unsigned long flags;
   36.43  
   36.44 -	if (TTY_INDEX(tty) != 0)
   36.45 +	if (DUMMY_TTY(tty))
   36.46  		return;
   36.47  
   36.48  	spin_lock_irqsave(&xencons_lock, flags);
   36.49 @@ -451,7 +452,7 @@ static int xencons_write(
   36.50  	int i;
   36.51  	unsigned long flags;
   36.52  
   36.53 -	if (TTY_INDEX(tty) != 0)
   36.54 +	if (DUMMY_TTY(tty))
   36.55  		return count;
   36.56  
   36.57  	spin_lock_irqsave(&xencons_lock, flags);
   36.58 @@ -472,7 +473,7 @@ static void xencons_put_char(struct tty_
   36.59  {
   36.60  	unsigned long flags;
   36.61  
   36.62 -	if (TTY_INDEX(tty) != 0)
   36.63 +	if (DUMMY_TTY(tty))
   36.64  		return;
   36.65  
   36.66  	spin_lock_irqsave(&xencons_lock, flags);
   36.67 @@ -484,7 +485,7 @@ static void xencons_flush_chars(struct t
   36.68  {
   36.69  	unsigned long flags;
   36.70  
   36.71 -	if (TTY_INDEX(tty) != 0)
   36.72 +	if (DUMMY_TTY(tty))
   36.73  		return;
   36.74  
   36.75  	spin_lock_irqsave(&xencons_lock, flags);
   36.76 @@ -496,7 +497,7 @@ static void xencons_wait_until_sent(stru
   36.77  {
   36.78  	unsigned long orig_jiffies = jiffies;
   36.79  
   36.80 -	if (TTY_INDEX(tty) != 0)
   36.81 +	if (DUMMY_TTY(tty))
   36.82  		return;
   36.83  
   36.84  	while (DRV(tty->driver)->chars_in_buffer(tty)) {
   36.85 @@ -515,7 +516,7 @@ static int xencons_open(struct tty_struc
   36.86  {
   36.87  	unsigned long flags;
   36.88  
   36.89 -	if (TTY_INDEX(tty) != 0)
   36.90 +	if (DUMMY_TTY(tty))
   36.91  		return 0;
   36.92  
   36.93  	spin_lock_irqsave(&xencons_lock, flags);
   36.94 @@ -532,7 +533,7 @@ static void xencons_close(struct tty_str
   36.95  {
   36.96  	unsigned long flags;
   36.97  
   36.98 -	if (TTY_INDEX(tty) != 0)
   36.99 +	if (DUMMY_TTY(tty))
  36.100  		return;
  36.101  
  36.102  	if (tty->count == 1) {
  36.103 @@ -588,8 +589,7 @@ static int __init xencons_init(void)
  36.104  	DRV(xencons_driver)->init_termios    = tty_std_termios;
  36.105  	DRV(xencons_driver)->flags           =
  36.106  		TTY_DRIVER_REAL_RAW |
  36.107 -		TTY_DRIVER_RESET_TERMIOS |
  36.108 -		TTY_DRIVER_NO_DEVFS;
  36.109 +		TTY_DRIVER_RESET_TERMIOS;
  36.110  	DRV(xencons_driver)->termios         = xencons_termios;
  36.111  	DRV(xencons_driver)->termios_locked  = xencons_termios_locked;
  36.112  
  36.113 @@ -599,8 +599,8 @@ static int __init xencons_init(void)
  36.114  		DRV(xencons_driver)->name_base   = 0 + xc_num;
  36.115  	} else {
  36.116  		DRV(xencons_driver)->name        = "tty";
  36.117 -		DRV(xencons_driver)->minor_start = xc_num;
  36.118 -		DRV(xencons_driver)->name_base   = xc_num;
  36.119 +		DRV(xencons_driver)->minor_start = 1;
  36.120 +		DRV(xencons_driver)->name_base   = 1;
  36.121  	}
  36.122  
  36.123  	tty_set_operations(xencons_driver, &xencons_ops);
  36.124 @@ -615,8 +615,6 @@ static int __init xencons_init(void)
  36.125  		return rc;
  36.126  	}
  36.127  
  36.128 -	tty_register_device(xencons_driver, 0, NULL);
  36.129 -
  36.130  	if (xen_start_info->flags & SIF_INITDOMAIN) {
  36.131  		xencons_priv_irq = bind_virq_to_irqhandler(
  36.132  			VIRQ_CONSOLE,
  36.133 @@ -629,8 +627,7 @@ static int __init xencons_init(void)
  36.134  	}
  36.135  
  36.136  	printk("Xen virtual console successfully installed as %s%d\n",
  36.137 -	       DRV(xencons_driver)->name,
  36.138 -	       DRV(xencons_driver)->name_base );
  36.139 +	       DRV(xencons_driver)->name, xc_num);
  36.140  
  36.141  	return 0;
  36.142  }
    37.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c	Wed Jul 05 10:23:54 2006 -0600
    37.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c	Wed Jul 05 20:11:37 2006 -0600
    37.3 @@ -219,7 +219,10 @@ asmlinkage void evtchn_do_upcall(struct 
    37.4  
    37.5  	vcpu_info->evtchn_upcall_pending = 0;
    37.6  
    37.7 -	/* NB. No need for a barrier here -- XCHG is a barrier on x86. */
    37.8 +#ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */
    37.9 +	/* Clear master pending flag /before/ clearing selector flag. */
   37.10 +	rmb();
   37.11 +#endif
   37.12  	l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
   37.13  	while (l1 != 0) {
   37.14  		l1i = __ffs(l1);
    38.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c	Wed Jul 05 10:23:54 2006 -0600
    38.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c	Wed Jul 05 20:11:37 2006 -0600
    38.3 @@ -169,7 +169,7 @@ int gnttab_end_foreign_access_ref(grant_
    38.4  			printk(KERN_ALERT "WARNING: g.e. still in use!\n");
    38.5  			return 0;
    38.6  		}
    38.7 -	} while ((nflags = synch_cmpxchg(&shared[ref].flags, flags, 0)) !=
    38.8 +	} while ((nflags = synch_cmpxchg_subword(&shared[ref].flags, flags, 0)) !=
    38.9  		 flags);
   38.10  
   38.11  	return 1;
   38.12 @@ -224,7 +224,7 @@ unsigned long gnttab_end_foreign_transfe
   38.13  	 * reference and return failure (== 0).
   38.14  	 */
   38.15  	while (!((flags = shared[ref].flags) & GTF_transfer_committed)) {
   38.16 -		if (synch_cmpxchg(&shared[ref].flags, flags, 0) == flags)
   38.17 +		if (synch_cmpxchg_subword(&shared[ref].flags, flags, 0) == flags)
   38.18  			return 0;
   38.19  		cpu_relax();
   38.20  	}
    39.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c	Wed Jul 05 10:23:54 2006 -0600
    39.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c	Wed Jul 05 20:11:37 2006 -0600
    39.3 @@ -8,12 +8,14 @@
    39.4   */
    39.5  
    39.6  #include <linux/config.h>
    39.7 +#include <linux/err.h>
    39.8  #include <linux/kernel.h>
    39.9  #include <linux/module.h>
   39.10  #include <linux/init.h>
   39.11  #include <asm/hypervisor.h>
   39.12  #include <xen/features.h>
   39.13  #include <xen/hypervisor_sysfs.h>
   39.14 +#include <xen/xenbus.h>
   39.15  
   39.16  MODULE_LICENSE("GPL");
   39.17  MODULE_AUTHOR("Mike D. Day <ncmike@us.ibm.com>");
   39.18 @@ -97,6 +99,37 @@ static void xen_sysfs_version_destroy(vo
   39.19  	sysfs_remove_group(&hypervisor_subsys.kset.kobj, &version_group);
   39.20  }
   39.21  
   39.22 +/* UUID */
   39.23 +
   39.24 +static ssize_t uuid_show(struct hyp_sysfs_attr *attr, char *buffer)
   39.25 +{
   39.26 +	char *vm, *val;
   39.27 +	int ret;
   39.28 +
   39.29 +	vm = xenbus_read(XBT_NIL, "vm", "", NULL);
   39.30 +	if (IS_ERR(vm))
   39.31 +		return PTR_ERR(vm);
   39.32 +	val = xenbus_read(XBT_NIL, vm, "uuid", NULL);
   39.33 +	kfree(vm);
   39.34 +	if (IS_ERR(val))
   39.35 +		return PTR_ERR(val);
   39.36 +	ret = sprintf(buffer, "%s\n", val);
   39.37 +	kfree(val);
   39.38 +	return ret;
   39.39 +}
   39.40 +
   39.41 +HYPERVISOR_ATTR_RO(uuid);
   39.42 +
   39.43 +static int __init xen_sysfs_uuid_init(void)
   39.44 +{
   39.45 +	return sysfs_create_file(&hypervisor_subsys.kset.kobj, &uuid_attr.attr);
   39.46 +}
   39.47 +
   39.48 +static void xen_sysfs_uuid_destroy(void)
   39.49 +{
   39.50 +	sysfs_remove_file(&hypervisor_subsys.kset.kobj, &uuid_attr.attr);
   39.51 +}
   39.52 +
   39.53  /* xen compilation attributes */
   39.54  
   39.55  static ssize_t compiler_show(struct hyp_sysfs_attr *attr, char *buffer)
   39.56 @@ -314,10 +347,15 @@ static int __init hyper_sysfs_init(void)
   39.57  	ret = xen_compilation_init();
   39.58  	if (ret)
   39.59  		goto comp_out;
   39.60 +	ret = xen_sysfs_uuid_init();
   39.61 +	if (ret)
   39.62 +		goto uuid_out;
   39.63  	ret = xen_properties_init();
   39.64  	if (!ret)
   39.65  		goto out;
   39.66  
   39.67 +	xen_sysfs_uuid_destroy();
   39.68 +uuid_out:
   39.69  	xen_compilation_destroy();
   39.70  comp_out:
   39.71  	xen_sysfs_version_destroy();
   39.72 @@ -331,6 +369,7 @@ static void hyper_sysfs_exit(void)
   39.73  {
   39.74  	xen_properties_destroy();
   39.75  	xen_compilation_destroy();
   39.76 +	xen_sysfs_uuid_destroy();
   39.77  	xen_sysfs_version_destroy();
   39.78  	xen_sysfs_type_destroy();
   39.79  
    40.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Wed Jul 05 10:23:54 2006 -0600
    40.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Wed Jul 05 20:11:37 2006 -0600
    40.3 @@ -496,9 +496,9 @@ static void netbk_tx_err(netif_t *netif,
    40.4  
    40.5  	do {
    40.6  		make_tx_response(netif, txp, NETIF_RSP_ERROR);
    40.7 -		if (++cons >= end)
    40.8 +		if (cons >= end)
    40.9  			break;
   40.10 -		txp = RING_GET_REQUEST(&netif->tx, cons);
   40.11 +		txp = RING_GET_REQUEST(&netif->tx, cons++);
   40.12  	} while (1);
   40.13  	netif->tx.req_cons = cons;
   40.14  	netif_schedule_work(netif);
   40.15 @@ -663,6 +663,57 @@ static void netbk_fill_frags(struct sk_b
   40.16  	}
   40.17  }
   40.18  
   40.19 +int netbk_get_extras(netif_t *netif, struct netif_extra_info *extras,
   40.20 +		     int work_to_do)
   40.21 +{
   40.22 +	struct netif_extra_info *extra;
   40.23 +	RING_IDX cons = netif->tx.req_cons;
   40.24 +
   40.25 +	do {
   40.26 +		if (unlikely(work_to_do-- <= 0)) {
   40.27 +			DPRINTK("Missing extra info\n");
   40.28 +			return -EBADR;
   40.29 +		}
   40.30 +
   40.31 +		extra = (struct netif_extra_info *)
   40.32 +			RING_GET_REQUEST(&netif->tx, cons);
   40.33 +		if (unlikely(!extra->type ||
   40.34 +			     extra->type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
   40.35 +			netif->tx.req_cons = ++cons;
   40.36 +			DPRINTK("Invalid extra type: %d\n", extra->type);
   40.37 +			return -EINVAL;
   40.38 +		}
   40.39 +
   40.40 +		memcpy(&extras[extra->type - 1], extra, sizeof(*extra));
   40.41 +		netif->tx.req_cons = ++cons;
   40.42 +	} while (extra->flags & XEN_NETIF_EXTRA_FLAG_MORE);
   40.43 +
   40.44 +	return work_to_do;
   40.45 +}
   40.46 +
   40.47 +static int netbk_set_skb_gso(struct sk_buff *skb, struct netif_extra_info *gso)
   40.48 +{
   40.49 +	if (!gso->u.gso.size) {
   40.50 +		DPRINTK("GSO size must not be zero.\n");
   40.51 +		return -EINVAL;
   40.52 +	}
   40.53 +
   40.54 +	/* Currently only TCPv4 S.O. is supported. */
   40.55 +	if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) {
   40.56 +		DPRINTK("Bad GSO type %d.\n", gso->u.gso.type);
   40.57 +		return -EINVAL;
   40.58 +	}
   40.59 +
   40.60 +	skb_shinfo(skb)->gso_size = gso->u.gso.size;
   40.61 +	skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
   40.62 +
   40.63 +	/* Header must be checked, and gso_segs computed. */
   40.64 +	skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
   40.65 +	skb_shinfo(skb)->gso_segs = 0;
   40.66 +
   40.67 +	return 0;
   40.68 +}
   40.69 +
   40.70  /* Called after netfront has transmitted */
   40.71  static void net_tx_action(unsigned long unused)
   40.72  {
   40.73 @@ -670,7 +721,7 @@ static void net_tx_action(unsigned long 
   40.74  	struct sk_buff *skb;
   40.75  	netif_t *netif;
   40.76  	netif_tx_request_t txreq;
   40.77 -	struct netif_tx_extra txtra;
   40.78 +	struct netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX - 1];
   40.79  	u16 pending_idx;
   40.80  	RING_IDX i;
   40.81  	gnttab_map_grant_ref_t *mop;
   40.82 @@ -732,16 +783,15 @@ static void net_tx_action(unsigned long 
   40.83  		work_to_do--;
   40.84  		netif->tx.req_cons = ++i;
   40.85  
   40.86 +		memset(extras, 0, sizeof(extras));
   40.87  		if (txreq.flags & NETTXF_extra_info) {
   40.88 -			if (work_to_do-- <= 0) {
   40.89 -				DPRINTK("Missing extra info\n");
   40.90 +			work_to_do = netbk_get_extras(netif, extras,
   40.91 +						      work_to_do);
   40.92 +			i = netif->tx.req_cons;
   40.93 +			if (unlikely(work_to_do < 0)) {
   40.94  				netbk_tx_err(netif, &txreq, i);
   40.95  				continue;
   40.96  			}
   40.97 -
   40.98 -			memcpy(&txtra, RING_GET_REQUEST(&netif->tx, i),
   40.99 -			       sizeof(txtra));
  40.100 -			netif->tx.req_cons = ++i;
  40.101  		}
  40.102  
  40.103  		ret = netbk_count_requests(netif, &txreq, work_to_do);
  40.104 @@ -751,7 +801,7 @@ static void net_tx_action(unsigned long 
  40.105  		}
  40.106  		i += ret;
  40.107  
  40.108 -		if (unlikely(ret > MAX_SKB_FRAGS + 1)) {
  40.109 +		if (unlikely(ret > MAX_SKB_FRAGS)) {
  40.110  			DPRINTK("Too many frags\n");
  40.111  			netbk_tx_err(netif, &txreq, i);
  40.112  			continue;
  40.113 @@ -788,10 +838,15 @@ static void net_tx_action(unsigned long 
  40.114  		/* Packets passed to netif_rx() must have some headroom. */
  40.115  		skb_reserve(skb, 16);
  40.116  
  40.117 -		if (txreq.flags & NETTXF_gso) {
  40.118 -			skb_shinfo(skb)->gso_size = txtra.u.gso.size;
  40.119 -			skb_shinfo(skb)->gso_segs = txtra.u.gso.segs;
  40.120 -			skb_shinfo(skb)->gso_type = txtra.u.gso.type;
  40.121 +		if (extras[XEN_NETIF_EXTRA_TYPE_GSO - 1].type) {
  40.122 +			struct netif_extra_info *gso;
  40.123 +			gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1];
  40.124 +
  40.125 +			if (netbk_set_skb_gso(skb, gso)) {
  40.126 +				kfree_skb(skb);
  40.127 +				netbk_tx_err(netif, &txreq, i);
  40.128 +				continue;
  40.129 +			}
  40.130  		}
  40.131  
  40.132  		gnttab_set_map_op(mop, MMAP_VADDR(pending_idx),
    41.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c	Wed Jul 05 10:23:54 2006 -0600
    41.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c	Wed Jul 05 20:11:37 2006 -0600
    41.3 @@ -101,11 +101,14 @@ static int netback_probe(struct xenbus_d
    41.4  			goto abort_transaction;
    41.5  		}
    41.6  
    41.7 -		err = xenbus_printf(xbt, dev->nodename, "feature-tso", "%d", 1);
    41.8 +#if 0 /* KAF: After the protocol is finalised. */
    41.9 +		err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4",
   41.10 +				    "%d", 1);
   41.11  		if (err) {
   41.12 -			message = "writing feature-tso";
   41.13 +			message = "writing feature-gso-tcpv4";
   41.14  			goto abort_transaction;
   41.15  		}
   41.16 +#endif
   41.17  
   41.18  		err = xenbus_transaction_end(xbt, 0);
   41.19  	} while (err == -EAGAIN);
    42.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Wed Jul 05 10:23:54 2006 -0600
    42.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Wed Jul 05 20:11:37 2006 -0600
    42.3 @@ -463,7 +463,7 @@ static int network_open(struct net_devic
    42.4  
    42.5  static inline int netfront_tx_slot_available(struct netfront_info *np)
    42.6  {
    42.7 -	return RING_FREE_REQUESTS(&np->tx) >= MAX_SKB_FRAGS + 1;
    42.8 +	return RING_FREE_REQUESTS(&np->tx) >= MAX_SKB_FRAGS + 2;
    42.9  }
   42.10  
   42.11  static inline void network_maybe_wake_tx(struct net_device *dev)
   42.12 @@ -491,7 +491,13 @@ static void network_tx_buf_gc(struct net
   42.13  		rmb(); /* Ensure we see responses up to 'rp'. */
   42.14  
   42.15  		for (cons = np->tx.rsp_cons; cons != prod; cons++) {
   42.16 -			id  = RING_GET_RESPONSE(&np->tx, cons)->id;
   42.17 +			struct netif_tx_response *txrsp;
   42.18 +
   42.19 +			txrsp = RING_GET_RESPONSE(&np->tx, cons);
   42.20 +			if (txrsp->status == NETIF_RSP_NULL)
   42.21 +				continue;
   42.22 +
   42.23 +			id  = txrsp->id;
   42.24  			skb = np->tx_skbs[id];
   42.25  			if (unlikely(gnttab_query_foreign_access(
   42.26  				np->grant_tx_ref[id]) != 0)) {
   42.27 @@ -719,6 +725,7 @@ static int network_start_xmit(struct sk_
   42.28  	unsigned short id;
   42.29  	struct netfront_info *np = netdev_priv(dev);
   42.30  	struct netif_tx_request *tx;
   42.31 +	struct netif_extra_info *extra;
   42.32  	char *data = skb->data;
   42.33  	RING_IDX i;
   42.34  	grant_ref_t ref;
   42.35 @@ -739,7 +746,8 @@ static int network_start_xmit(struct sk_
   42.36  	spin_lock_irq(&np->tx_lock);
   42.37  
   42.38  	if (unlikely(!netif_carrier_ok(dev) ||
   42.39 -		     (frags > 1 && !xennet_can_sg(dev)))) {
   42.40 +		     (frags > 1 && !xennet_can_sg(dev)) ||
   42.41 +		     netif_needs_gso(dev, skb))) {
   42.42  		spin_unlock_irq(&np->tx_lock);
   42.43  		goto drop;
   42.44  	}
   42.45 @@ -762,11 +770,30 @@ static int network_start_xmit(struct sk_
   42.46  	tx->size = len;
   42.47  
   42.48  	tx->flags = 0;
   42.49 +	extra = NULL;
   42.50 +
   42.51  	if (skb->ip_summed == CHECKSUM_HW) /* local packet? */
   42.52  		tx->flags |= NETTXF_csum_blank | NETTXF_data_validated;
   42.53  	if (skb->proto_data_valid) /* remote but checksummed? */
   42.54  		tx->flags |= NETTXF_data_validated;
   42.55  
   42.56 +	if (skb_shinfo(skb)->gso_size) {
   42.57 +		struct netif_extra_info *gso = (struct netif_extra_info *)
   42.58 +			RING_GET_REQUEST(&np->tx, ++i);
   42.59 +
   42.60 +		if (extra)
   42.61 +			extra->flags |= XEN_NETIF_EXTRA_FLAG_MORE;
   42.62 +		else
   42.63 +			tx->flags |= NETTXF_extra_info;
   42.64 +
   42.65 +		gso->u.gso.size = skb_shinfo(skb)->gso_size;
   42.66 +		gso->u.gso.type = XEN_NETIF_GSO_TYPE_TCPV4;
   42.67 +
   42.68 +		gso->type = XEN_NETIF_EXTRA_TYPE_GSO;
   42.69 +		gso->flags = 0;
   42.70 +		extra = gso;
   42.71 +	}
   42.72 +
   42.73  	np->tx.req_prod_pvt = i + 1;
   42.74  
   42.75  	xennet_make_frags(skb, dev, tx);
   42.76 @@ -1065,9 +1092,33 @@ static int xennet_set_sg(struct net_devi
   42.77  	return ethtool_op_set_sg(dev, data);
   42.78  }
   42.79  
   42.80 +static int xennet_set_tso(struct net_device *dev, u32 data)
   42.81 +{
   42.82 +	if (data) {
   42.83 +		struct netfront_info *np = netdev_priv(dev);
   42.84 +		int val;
   42.85 +
   42.86 +		if (xenbus_scanf(XBT_NIL, np->xbdev->otherend,
   42.87 +				 "feature-gso-tcpv4", "%d", &val) < 0)
   42.88 +			val = 0;
   42.89 +#if 0 /* KAF: After the protocol is finalised. */
   42.90 +		if (!val)
   42.91 +#endif
   42.92 +			return -ENOSYS;
   42.93 +	}
   42.94 +
   42.95 +	return ethtool_op_set_tso(dev, data);
   42.96 +}
   42.97 +
   42.98  static void xennet_set_features(struct net_device *dev)
   42.99  {
  42.100 -	xennet_set_sg(dev, 1);
  42.101 +	/* Turn off all GSO bits except ROBUST. */
  42.102 +	dev->features &= (1 << NETIF_F_GSO_SHIFT) - 1;
  42.103 +	dev->features |= NETIF_F_GSO_ROBUST;
  42.104 +	xennet_set_sg(dev, 0);
  42.105 +
  42.106 +	if (!xennet_set_sg(dev, 1))
  42.107 +		xennet_set_tso(dev, 1);
  42.108  }
  42.109  
  42.110  static void network_connect(struct net_device *dev)
  42.111 @@ -1148,6 +1199,8 @@ static struct ethtool_ops network_ethtoo
  42.112  	.set_tx_csum = ethtool_op_set_tx_csum,
  42.113  	.get_sg = ethtool_op_get_sg,
  42.114  	.set_sg = xennet_set_sg,
  42.115 +	.get_tso = ethtool_op_get_tso,
  42.116 +	.set_tso = xennet_set_tso,
  42.117  };
  42.118  
  42.119  #ifdef CONFIG_SYSFS
    43.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Wed Jul 05 10:23:54 2006 -0600
    43.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Wed Jul 05 20:11:37 2006 -0600
    43.3 @@ -886,29 +886,6 @@ void unregister_xenstore_notifier(struct
    43.4  EXPORT_SYMBOL_GPL(unregister_xenstore_notifier);
    43.5  
    43.6  
    43.7 -static int all_devices_ready_(struct device *dev, void *data)
    43.8 -{
    43.9 -	struct xenbus_device *xendev = to_xenbus_device(dev);
   43.10 -	int *result = data;
   43.11 -
   43.12 -	if (xendev->state != XenbusStateConnected) {
   43.13 -		*result = 0;
   43.14 -		return 1;
   43.15 -	}
   43.16 -
   43.17 -	return 0;
   43.18 -}
   43.19 -
   43.20 -
   43.21 -static int all_devices_ready(void)
   43.22 -{
   43.23 -	int ready = 1;
   43.24 -	bus_for_each_dev(&xenbus_frontend.bus, NULL, &ready,
   43.25 -			 all_devices_ready_);
   43.26 -	return ready;
   43.27 -}
   43.28 -
   43.29 -
   43.30  void xenbus_probe(void *unused)
   43.31  {
   43.32  	BUG_ON((xenstored_ready <= 0));
   43.33 @@ -1060,6 +1037,43 @@ static int __init xenbus_probe_init(void
   43.34  postcore_initcall(xenbus_probe_init);
   43.35  
   43.36  
   43.37 +static int is_disconnected_device(struct device *dev, void *data)
   43.38 +{
   43.39 +	struct xenbus_device *xendev = to_xenbus_device(dev);
   43.40 +
   43.41 +	/*
   43.42 +	 * A device with no driver will never connect. We care only about
   43.43 +	 * devices which should currently be in the process of connecting.
   43.44 +	 */
   43.45 +	if (!dev->driver)
   43.46 +		return 0;
   43.47 +
   43.48 +	return (xendev->state != XenbusStateConnected);
   43.49 +}
   43.50 +
   43.51 +static int exists_disconnected_device(void)
   43.52 +{
   43.53 +	return bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL,
   43.54 +				is_disconnected_device);
   43.55 +}
   43.56 +
   43.57 +static int print_device_status(struct device *dev, void *data)
   43.58 +{
   43.59 +	struct xenbus_device *xendev = to_xenbus_device(dev);
   43.60 +
   43.61 +	if (!dev->driver) {
   43.62 +		/* Information only: is this too noisy? */
   43.63 +		printk(KERN_INFO "XENBUS: Device with no driver: %s\n",
   43.64 +		       xendev->nodename);
   43.65 +	} else if (xendev->state != XenbusStateConnected) {
   43.66 +		printk(KERN_WARNING "XENBUS: Timeout connecting "
   43.67 +		       "to device: %s (state %d)\n",
   43.68 +		       xendev->nodename, xendev->state);
   43.69 +	}
   43.70 +
   43.71 +	return 0;
   43.72 +}
   43.73 +
   43.74  /*
   43.75   * On a 10 second timeout, wait for all devices currently configured.  We need
   43.76   * to do this to guarantee that the filesystems and / or network devices
   43.77 @@ -1081,13 +1095,12 @@ static int __init wait_for_devices(void)
   43.78  	if (!is_running_on_xen())
   43.79  		return -ENODEV;
   43.80  
   43.81 -	while (time_before(jiffies, timeout)) {
   43.82 -		if (all_devices_ready())
   43.83 -			return 0;
   43.84 +	while (time_before(jiffies, timeout) && exists_disconnected_device())
   43.85  		schedule_timeout_interruptible(HZ/10);
   43.86 -	}
   43.87  
   43.88 -	printk(KERN_WARNING "XENBUS: Timeout connecting to devices!\n");
   43.89 +	bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL,
   43.90 +			 print_device_status);
   43.91 +
   43.92  	return 0;
   43.93  }
   43.94  
    44.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/synch_bitops.h	Wed Jul 05 10:23:54 2006 -0600
    44.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/synch_bitops.h	Wed Jul 05 20:11:37 2006 -0600
    44.3 @@ -138,4 +138,6 @@ static __inline__ int synch_var_test_bit
    44.4   synch_const_test_bit((nr),(addr)) : \
    44.5   synch_var_test_bit((nr),(addr)))
    44.6  
    44.7 +#define synch_cmpxchg_subword synch_cmpxchg
    44.8 +
    44.9  #endif /* __XEN_SYNCH_BITOPS_H__ */
    45.1 --- a/linux-2.6-xen-sparse/include/asm-ia64/synch_bitops.h	Wed Jul 05 10:23:54 2006 -0600
    45.2 +++ b/linux-2.6-xen-sparse/include/asm-ia64/synch_bitops.h	Wed Jul 05 20:11:37 2006 -0600
    45.3 @@ -58,4 +58,6 @@ static __inline__ int synch_var_test_bit
    45.4   synch_const_test_bit((nr),(addr)) : \
    45.5   synch_var_test_bit((nr),(addr)))
    45.6  
    45.7 +#define synch_cmpxchg_subword synch_cmpxchg
    45.8 +
    45.9  #endif /* __XEN_SYNCH_BITOPS_H__ */
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/patches/linux-2.6.16.13/fix-hz-suspend.patch	Wed Jul 05 20:11:37 2006 -0600
    46.3 @@ -0,0 +1,26 @@
    46.4 +diff -pruN ../pristine-linux-2.6.16.13/kernel/timer.c ./kernel/timer.c
    46.5 +--- ../pristine-linux-2.6.16.13/kernel/timer.c	2006-05-02 22:38:44.000000000 +0100
    46.6 ++++ ./kernel/timer.c	2006-06-29 14:34:12.788957720 +0100
    46.7 +@@ -555,6 +555,22 @@ found:
    46.8 + 	}
    46.9 + 	spin_unlock(&base->t_base.lock);
   46.10 + 
   46.11 ++	/*
   46.12 ++	 * It can happen that other CPUs service timer IRQs and increment
   46.13 ++	 * jiffies, but we have not yet got a local timer tick to process
   46.14 ++	 * the timer wheels.  In that case, the expiry time can be before
   46.15 ++	 * jiffies, but since the high-resolution timer here is relative to
   46.16 ++	 * jiffies, the default expression when high-resolution timers are
   46.17 ++	 * not active,
   46.18 ++	 *
   46.19 ++	 *   time_before(MAX_JIFFY_OFFSET + jiffies, expires)
   46.20 ++	 *
   46.21 ++	 * would falsely evaluate to true.  If that is the case, just
   46.22 ++	 * return jiffies so that we can immediately fire the local timer
   46.23 ++	 */
   46.24 ++	if (time_before(expires, jiffies))
   46.25 ++		return jiffies;
   46.26 ++
   46.27 + 	if (time_before(hr_expires, expires))
   46.28 + 		return hr_expires;
   46.29 + 
    47.1 --- a/patches/linux-2.6.16.13/net-gso.patch	Wed Jul 05 10:23:54 2006 -0600
    47.2 +++ b/patches/linux-2.6.16.13/net-gso.patch	Wed Jul 05 20:11:37 2006 -0600
    47.3 @@ -2225,7 +2225,7 @@ index d64e2ec..7494823 100644
    47.4   	err = ipcomp_compress(x, skb);
    47.5   	iph = skb->nh.iph;
    47.6  diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
    47.7 -index 00aa80e..84130c9 100644
    47.8 +index 00aa80e..30c81a8 100644
    47.9  --- a/net/ipv4/tcp.c
   47.10  +++ b/net/ipv4/tcp.c
   47.11  @@ -257,6 +257,7 @@ #include <linux/smp_lock.h>
   47.12 @@ -2281,7 +2281,7 @@ index 00aa80e..84130c9 100644
   47.13   
   47.14   			from += copy;
   47.15   			copied += copy;
   47.16 -@@ -2026,6 +2021,71 @@ int tcp_getsockopt(struct sock *sk, int 
   47.17 +@@ -2026,6 +2021,77 @@ int tcp_getsockopt(struct sock *sk, int 
   47.18   }
   47.19   
   47.20   
   47.21 @@ -2306,13 +2306,19 @@ index 00aa80e..84130c9 100644
   47.22  +	if (!pskb_may_pull(skb, thlen))
   47.23  +		goto out;
   47.24  +
   47.25 -+	segs = NULL;
   47.26 -+	if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST))
   47.27 -+		goto out;
   47.28 -+
   47.29  +	oldlen = (u16)~skb->len;
   47.30  +	__skb_pull(skb, thlen);
   47.31  +
   47.32 ++	if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
   47.33 ++		/* Packet is from an untrusted source, reset gso_segs. */
   47.34 ++		int mss = skb_shinfo(skb)->gso_size;
   47.35 ++
   47.36 ++		skb_shinfo(skb)->gso_segs = (skb->len + mss - 1) / mss;
   47.37 ++
   47.38 ++		segs = NULL;
   47.39 ++		goto out;
   47.40 ++	}
   47.41 ++
   47.42  +	segs = skb_segment(skb, features);
   47.43  +	if (IS_ERR(segs))
   47.44  +		goto out;
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/patches/linux-2.6.16.13/tpm_plugin_2.6.17.patch	Wed Jul 05 20:11:37 2006 -0600
    48.3 @@ -0,0 +1,1546 @@
    48.4 +diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.c ./drivers/char/tpm/tpm_atmel.c
    48.5 +--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.c	2006-06-26 18:05:03.000000000 -0400
    48.6 ++++ ./drivers/char/tpm/tpm_atmel.c	2006-06-26 18:16:33.000000000 -0400
    48.7 +@@ -47,12 +47,12 @@ static int tpm_atml_recv(struct tpm_chip
    48.8 + 		return -EIO;
    48.9 + 
   48.10 + 	for (i = 0; i < 6; i++) {
   48.11 +-		status = ioread8(chip->vendor->iobase + 1);
   48.12 ++		status = ioread8(chip->vendor.iobase + 1);
   48.13 + 		if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
   48.14 + 			dev_err(chip->dev, "error reading header\n");
   48.15 + 			return -EIO;
   48.16 + 		}
   48.17 +-		*buf++ = ioread8(chip->vendor->iobase);
   48.18 ++		*buf++ = ioread8(chip->vendor.iobase);
   48.19 + 	}
   48.20 + 
   48.21 + 	/* size of the data received */
   48.22 +@@ -63,7 +63,7 @@ static int tpm_atml_recv(struct tpm_chip
   48.23 + 		dev_err(chip->dev,
   48.24 + 			"Recv size(%d) less than available space\n", size);
   48.25 + 		for (; i < size; i++) {	/* clear the waiting data anyway */
   48.26 +-			status = ioread8(chip->vendor->iobase + 1);
   48.27 ++			status = ioread8(chip->vendor.iobase + 1);
   48.28 + 			if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
   48.29 + 				dev_err(chip->dev, "error reading data\n");
   48.30 + 				return -EIO;
   48.31 +@@ -74,16 +74,16 @@ static int tpm_atml_recv(struct tpm_chip
   48.32 + 
   48.33 + 	/* read all the data available */
   48.34 + 	for (; i < size; i++) {
   48.35 +-		status = ioread8(chip->vendor->iobase + 1);
   48.36 ++		status = ioread8(chip->vendor.iobase + 1);
   48.37 + 		if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
   48.38 + 			dev_err(chip->dev, "error reading data\n");
   48.39 + 			return -EIO;
   48.40 + 		}
   48.41 +-		*buf++ = ioread8(chip->vendor->iobase);
   48.42 ++		*buf++ = ioread8(chip->vendor.iobase);
   48.43 + 	}
   48.44 + 
   48.45 + 	/* make sure data available is gone */
   48.46 +-	status = ioread8(chip->vendor->iobase + 1);
   48.47 ++	status = ioread8(chip->vendor.iobase + 1);
   48.48 + 
   48.49 + 	if (status & ATML_STATUS_DATA_AVAIL) {
   48.50 + 		dev_err(chip->dev, "data available is stuck\n");
   48.51 +@@ -100,7 +100,7 @@ static int tpm_atml_send(struct tpm_chip
   48.52 + 	dev_dbg(chip->dev, "tpm_atml_send:\n");
   48.53 + 	for (i = 0; i < count; i++) {
   48.54 + 		dev_dbg(chip->dev, "%d 0x%x(%d)\n",  i, buf[i], buf[i]);
   48.55 +- 		iowrite8(buf[i], chip->vendor->iobase);
   48.56 ++ 		iowrite8(buf[i], chip->vendor.iobase);
   48.57 + 	}
   48.58 + 
   48.59 + 	return count;
   48.60 +@@ -108,12 +108,12 @@ static int tpm_atml_send(struct tpm_chip
   48.61 + 
   48.62 + static void tpm_atml_cancel(struct tpm_chip *chip)
   48.63 + {
   48.64 +-	iowrite8(ATML_STATUS_ABORT, chip->vendor->iobase + 1);
   48.65 ++	iowrite8(ATML_STATUS_ABORT, chip->vendor.iobase + 1);
   48.66 + }
   48.67 + 
   48.68 + static u8 tpm_atml_status(struct tpm_chip *chip)
   48.69 + {
   48.70 +-	return ioread8(chip->vendor->iobase + 1);
   48.71 ++	return ioread8(chip->vendor.iobase + 1);
   48.72 + }
   48.73 + 
   48.74 + static struct file_operations atmel_ops = {
   48.75 +@@ -140,7 +140,7 @@ static struct attribute* atmel_attrs[] =
   48.76 + 
   48.77 + static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
   48.78 + 
   48.79 +-static struct tpm_vendor_specific tpm_atmel = {
   48.80 ++static const struct tpm_vendor_specific tpm_atmel = {
   48.81 + 	.recv = tpm_atml_recv,
   48.82 + 	.send = tpm_atml_send,
   48.83 + 	.cancel = tpm_atml_cancel,
   48.84 +@@ -159,10 +159,10 @@ static void atml_plat_remove(void)
   48.85 + 	struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
   48.86 + 
   48.87 + 	if (chip) {
   48.88 +-		if (chip->vendor->have_region)
   48.89 +-			atmel_release_region(chip->vendor->base,
   48.90 +-					     chip->vendor->region_size);
   48.91 +-		atmel_put_base_addr(chip->vendor);
   48.92 ++		if (chip->vendor.have_region)
   48.93 ++			atmel_release_region(chip->vendor.base,
   48.94 ++					     chip->vendor.region_size);
   48.95 ++		atmel_put_base_addr(chip->vendor.iobase);
   48.96 + 		tpm_remove_hardware(chip->dev);
   48.97 + 		platform_device_unregister(pdev);
   48.98 + 	}
   48.99 +@@ -179,18 +179,22 @@ static struct device_driver atml_drv = {
  48.100 + static int __init init_atmel(void)
  48.101 + {
  48.102 + 	int rc = 0;
  48.103 ++	void __iomem *iobase = NULL;
  48.104 ++	int have_region, region_size;
  48.105 ++	unsigned long base;
  48.106 ++	struct  tpm_chip *chip;
  48.107 + 
  48.108 + 	driver_register(&atml_drv);
  48.109 + 
  48.110 +-	if ((tpm_atmel.iobase = atmel_get_base_addr(&tpm_atmel)) == NULL) {
  48.111 ++	if ((iobase = atmel_get_base_addr(&base, &region_size)) == NULL) {
  48.112 + 		rc = -ENODEV;
  48.113 + 		goto err_unreg_drv;
  48.114 + 	}
  48.115 + 
  48.116 +-	tpm_atmel.have_region =
  48.117 ++	have_region =
  48.118 + 	    (atmel_request_region
  48.119 +-	     (tpm_atmel.base, tpm_atmel.region_size,
  48.120 +-	      "tpm_atmel0") == NULL) ? 0 : 1;
  48.121 ++	     (tpm_atmel.base, region_size, "tpm_atmel0") == NULL) ? 0 : 1;
  48.122 ++
  48.123 + 
  48.124 + 	if (IS_ERR
  48.125 + 	    (pdev =
  48.126 +@@ -199,17 +203,25 @@ static int __init init_atmel(void)
  48.127 + 		goto err_rel_reg;
  48.128 + 	}
  48.129 + 
  48.130 +-	if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0)
  48.131 ++	if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_atmel))) {
  48.132 ++		rc = -ENODEV;
  48.133 + 		goto err_unreg_dev;
  48.134 ++	}
  48.135 ++
  48.136 ++	chip->vendor.iobase = iobase;
  48.137 ++	chip->vendor.base = base;
  48.138 ++	chip->vendor.have_region = have_region;
  48.139 ++	chip->vendor.region_size = region_size;
  48.140 ++
  48.141 + 	return 0;
  48.142 + 
  48.143 + err_unreg_dev:
  48.144 + 	platform_device_unregister(pdev);
  48.145 + err_rel_reg:
  48.146 +-	atmel_put_base_addr(&tpm_atmel);
  48.147 +-	if (tpm_atmel.have_region)
  48.148 +-		atmel_release_region(tpm_atmel.base,
  48.149 +-				     tpm_atmel.region_size);
  48.150 ++	atmel_put_base_addr(iobase);
  48.151 ++	if (have_region)
  48.152 ++		atmel_release_region(base,
  48.153 ++				     region_size);
  48.154 + err_unreg_drv:
  48.155 + 	driver_unregister(&atml_drv);
  48.156 + 	return rc;
  48.157 +diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.h ./drivers/char/tpm/tpm_atmel.h
  48.158 +--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.h	2006-06-26 18:05:03.000000000 -0400
  48.159 ++++ ./drivers/char/tpm/tpm_atmel.h	2006-06-26 18:16:33.000000000 -0400
  48.160 +@@ -28,13 +28,12 @@
  48.161 + #define atmel_request_region request_mem_region
  48.162 + #define atmel_release_region release_mem_region
  48.163 + 
  48.164 +-static inline void atmel_put_base_addr(struct tpm_vendor_specific
  48.165 +-					 *vendor)
  48.166 ++static inline void atmel_put_base_addr(void __iomem *iobase)
  48.167 + {
  48.168 +-	iounmap(vendor->iobase);
  48.169 ++	iounmap(iobase);
  48.170 + }
  48.171 + 
  48.172 +-static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific *vendor)
  48.173 ++static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
  48.174 + {
  48.175 + 	struct device_node *dn;
  48.176 + 	unsigned long address, size;
  48.177 +@@ -71,9 +70,9 @@ static void __iomem * atmel_get_base_add
  48.178 + 	else
  48.179 + 		size = reg[naddrc];
  48.180 + 
  48.181 +-	vendor->base = address;
  48.182 +-	vendor->region_size = size;
  48.183 +-	return ioremap(vendor->base, vendor->region_size);
  48.184 ++	*base = address;
  48.185 ++	*region_size = size;
  48.186 ++	return ioremap(*base, *region_size);
  48.187 + }
  48.188 + #else
  48.189 + #define atmel_getb(chip, offset) inb(chip->vendor->base + offset)
  48.190 +@@ -106,14 +105,12 @@ static int atmel_verify_tpm11(void)
  48.191 + 	return 0;
  48.192 + }
  48.193 + 
  48.194 +-static inline void atmel_put_base_addr(struct tpm_vendor_specific
  48.195 +-					 *vendor)
  48.196 ++static inline void atmel_put_base_addr(void __iomem *iobase)
  48.197 + {
  48.198 + }
  48.199 + 
  48.200 + /* Determine where to talk to device */
  48.201 +-static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific
  48.202 +-					 *vendor)
  48.203 ++static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
  48.204 + {
  48.205 + 	int lo, hi;
  48.206 + 
  48.207 +@@ -123,9 +120,9 @@ static void __iomem * atmel_get_base_add
  48.208 + 	lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
  48.209 + 	hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
  48.210 + 
  48.211 +-	vendor->base = (hi << 8) | lo;
  48.212 +-	vendor->region_size = 2;
  48.213 ++	*base = (hi << 8) | lo;
  48.214 ++	*region_size = 2;
  48.215 + 
  48.216 +-	return ioport_map(vendor->base, vendor->region_size);
  48.217 ++	return ioport_map(*base, *region_size);
  48.218 + }
  48.219 + #endif
  48.220 +diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_bios.c ./drivers/char/tpm/tpm_bios.c
  48.221 +--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_bios.c	2006-06-26 18:05:03.000000000 -0400
  48.222 ++++ ./drivers/char/tpm/tpm_bios.c	2006-06-26 18:16:33.000000000 -0400
  48.223 +@@ -29,6 +29,11 @@
  48.224 + #define MAX_TEXT_EVENT		1000	/* Max event string length */
  48.225 + #define ACPI_TCPA_SIG		"TCPA"	/* 0x41504354 /'TCPA' */
  48.226 + 
  48.227 ++enum bios_platform_class {
  48.228 ++	BIOS_CLIENT = 0x00,
  48.229 ++	BIOS_SERVER = 0x01,
  48.230 ++};
  48.231 ++
  48.232 + struct tpm_bios_log {
  48.233 + 	void *bios_event_log;
  48.234 + 	void *bios_event_log_end;
  48.235 +@@ -36,9 +41,18 @@ struct tpm_bios_log {
  48.236 + 
  48.237 + struct acpi_tcpa {
  48.238 + 	struct acpi_table_header hdr;
  48.239 +-	u16 reserved;
  48.240 +-	u32 log_max_len __attribute__ ((packed));
  48.241 +-	u32 log_start_addr __attribute__ ((packed));
  48.242 ++	u16 platform_class;
  48.243 ++	union {
  48.244 ++		struct client_hdr {
  48.245 ++			u32 log_max_len __attribute__ ((packed));
  48.246 ++			u64 log_start_addr __attribute__ ((packed));
  48.247 ++		} client;
  48.248 ++		struct server_hdr {
  48.249 ++			u16 reserved;
  48.250 ++			u64 log_max_len __attribute__ ((packed));
  48.251 ++			u64 log_start_addr __attribute__ ((packed));
  48.252 ++		} server;
  48.253 ++	};
  48.254 + };
  48.255 + 
  48.256 + struct tcpa_event {
  48.257 +@@ -91,6 +105,12 @@ static const char* tcpa_event_type_strin
  48.258 + 	"Non-Host Info"
  48.259 + };
  48.260 + 
  48.261 ++struct tcpa_pc_event {
  48.262 ++	u32 event_id;
  48.263 ++	u32 event_size;
  48.264 ++	u8 event_data[0];
  48.265 ++};
  48.266 ++
  48.267 + enum tcpa_pc_event_ids {
  48.268 + 	SMBIOS = 1,
  48.269 + 	BIS_CERT,
  48.270 +@@ -100,14 +120,15 @@ enum tcpa_pc_event_ids {
  48.271 + 	NVRAM,
  48.272 + 	OPTION_ROM_EXEC,
  48.273 + 	OPTION_ROM_CONFIG,
  48.274 +-	OPTION_ROM_MICROCODE,
  48.275 ++	OPTION_ROM_MICROCODE = 10,
  48.276 + 	S_CRTM_VERSION,
  48.277 + 	S_CRTM_CONTENTS,
  48.278 + 	POST_CONTENTS,
  48.279 ++	HOST_TABLE_OF_DEVICES,
  48.280 + };
  48.281 + 
  48.282 + static const char* tcpa_pc_event_id_strings[] = {
  48.283 +-	""
  48.284 ++	"",
  48.285 + 	"SMBIOS",
  48.286 + 	"BIS Certificate",
  48.287 + 	"POST BIOS ",
  48.288 +@@ -116,10 +137,12 @@ static const char* tcpa_pc_event_id_stri
  48.289 + 	"NVRAM",
  48.290 + 	"Option ROM",
  48.291 + 	"Option ROM config",
  48.292 +-	"Option ROM microcode",
  48.293 ++	"",
  48.294 ++	"Option ROM microcode ",
  48.295 + 	"S-CRTM Version",
  48.296 +-	"S-CRTM Contents",
  48.297 +-	"S-CRTM POST Contents",
  48.298 ++	"S-CRTM Contents ",
  48.299 ++	"POST Contents ",
  48.300 ++	"Table of Devices",
  48.301 + };
  48.302 + 
  48.303 + /* returns pointer to start of pos. entry of tcg log */
  48.304 +@@ -191,7 +214,7 @@ static int get_event_name(char *dest, st
  48.305 + 	const char *name = "";
  48.306 + 	char data[40] = "";
  48.307 + 	int i, n_len = 0, d_len = 0;
  48.308 +-	u32 event_id;
  48.309 ++	struct tcpa_pc_event *pc_event;
  48.310 + 
  48.311 + 	switch(event->event_type) {
  48.312 + 	case PREBOOT:
  48.313 +@@ -220,31 +243,32 @@ static int get_event_name(char *dest, st
  48.314 + 		}
  48.315 + 		break;
  48.316 + 	case EVENT_TAG:
  48.317 +-		event_id = be32_to_cpu(*((u32 *)event_entry));
  48.318 ++		pc_event = (struct tcpa_pc_event *)event_entry;
  48.319 + 
  48.320 + 		/* ToDo Row data -> Base64 */
  48.321 + 
  48.322 +-		switch (event_id) {
  48.323 ++		switch (pc_event->event_id) {
  48.324 + 		case SMBIOS:
  48.325 + 		case BIS_CERT:
  48.326 + 		case CMOS:
  48.327 + 		case NVRAM:
  48.328 + 		case OPTION_ROM_EXEC:
  48.329 + 		case OPTION_ROM_CONFIG:
  48.330 +-		case OPTION_ROM_MICROCODE:
  48.331 + 		case S_CRTM_VERSION:
  48.332 +-		case S_CRTM_CONTENTS:
  48.333 +-		case POST_CONTENTS:
  48.334 +-			name = tcpa_pc_event_id_strings[event_id];
  48.335 ++			name = tcpa_pc_event_id_strings[pc_event->event_id];
  48.336 + 			n_len = strlen(name);
  48.337 + 			break;
  48.338 ++		/* hash data */
  48.339 + 		case POST_BIOS_ROM:
  48.340 + 		case ESCD:
  48.341 +-			name = tcpa_pc_event_id_strings[event_id];
  48.342 ++		case OPTION_ROM_MICROCODE:
  48.343 ++		case S_CRTM_CONTENTS:
  48.344 ++		case POST_CONTENTS:
  48.345 ++			name = tcpa_pc_event_id_strings[pc_event->event_id];
  48.346 + 			n_len = strlen(name);
  48.347 + 			for (i = 0; i < 20; i++)
  48.348 +-				d_len += sprintf(data, "%02x",
  48.349 +-						event_entry[8 + i]);
  48.350 ++				d_len += sprintf(&data[2*i], "%02x",
  48.351 ++						pc_event->event_data[i]);
  48.352 + 			break;
  48.353 + 		default:
  48.354 + 			break;
  48.355 +@@ -260,52 +284,13 @@ static int get_event_name(char *dest, st
  48.356 + 
  48.357 + static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v)
  48.358 + {
  48.359 ++	struct tcpa_event *event = v;
  48.360 ++	char *data = v;
  48.361 ++	int i;
  48.362 + 
  48.363 +-	char *eventname;
  48.364 +-	char data[4];
  48.365 +-	u32 help;
  48.366 +-	int i, len;
  48.367 +-	struct tcpa_event *event = (struct tcpa_event *) v;
  48.368 +-	unsigned char *event_entry =
  48.369 +-	    (unsigned char *) (v + sizeof(struct tcpa_event));
  48.370 +-
  48.371 +-	eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL);
  48.372 +-	if (!eventname) {
  48.373 +-		printk(KERN_ERR "%s: ERROR - No Memory for event name\n ",
  48.374 +-		       __func__);
  48.375 +-		return -ENOMEM;
  48.376 +-	}
  48.377 +-
  48.378 +-	/* 1st: PCR used is in little-endian format (4 bytes) */
  48.379 +-	help = le32_to_cpu(event->pcr_index);
  48.380 +-	memcpy(data, &help, 4);
  48.381 +-	for (i = 0; i < 4; i++)
  48.382 +-		seq_putc(m, data[i]);
  48.383 +-
  48.384 +-	/* 2nd: SHA1 (20 bytes) */
  48.385 +-	for (i = 0; i < 20; i++)
  48.386 +-		seq_putc(m, event->pcr_value[i]);
  48.387 +-
  48.388 +-	/* 3rd: event type identifier (4 bytes) */
  48.389 +-	help = le32_to_cpu(event->event_type);
  48.390 +-	memcpy(data, &help, 4);
  48.391 +-	for (i = 0; i < 4; i++)
  48.392 ++	for (i = 0; i < sizeof(struct tcpa_event) + event->event_size; i++)
  48.393 + 		seq_putc(m, data[i]);
  48.394 + 
  48.395 +-	len = 0;
  48.396 +-
  48.397 +-	len += get_event_name(eventname, event, event_entry);
  48.398 +-
  48.399 +-	/* 4th:  filename <= 255 + \'0' delimiter */
  48.400 +-	if (len > TCG_EVENT_NAME_LEN_MAX)
  48.401 +-		len = TCG_EVENT_NAME_LEN_MAX;
  48.402 +-
  48.403 +-	for (i = 0; i < len; i++)
  48.404 +-		seq_putc(m, eventname[i]);
  48.405 +-
  48.406 +-	/* 5th: delimiter */
  48.407 +-	seq_putc(m, '\0');
  48.408 +-
  48.409 + 	return 0;
  48.410 + }
  48.411 + 
  48.412 +@@ -353,6 +338,7 @@ static int tpm_ascii_bios_measurements_s
  48.413 + 	/* 4th: eventname <= max + \'0' delimiter */
  48.414 + 	seq_printf(m, " %s\n", eventname);
  48.415 + 
  48.416 ++	kfree(eventname);
  48.417 + 	return 0;
  48.418 + }
  48.419 + 
  48.420 +@@ -376,6 +362,7 @@ static int read_log(struct tpm_bios_log 
  48.421 + 	struct acpi_tcpa *buff;
  48.422 + 	acpi_status status;
  48.423 + 	struct acpi_table_header *virt;
  48.424 ++	u64 len, start;
  48.425 + 
  48.426 + 	if (log->bios_event_log != NULL) {
  48.427 + 		printk(KERN_ERR
  48.428 +@@ -396,27 +383,37 @@ static int read_log(struct tpm_bios_log 
  48.429 + 		return -EIO;
  48.430 + 	}
  48.431 + 
  48.432 +-	if (buff->log_max_len == 0) {
  48.433 ++	switch(buff->platform_class) {
  48.434 ++	case BIOS_SERVER:
  48.435 ++		len = buff->server.log_max_len;
  48.436 ++		start = buff->server.log_start_addr;
  48.437 ++		break;
  48.438 ++	case BIOS_CLIENT:
  48.439 ++	default:
  48.440 ++		len = buff->client.log_max_len;
  48.441 ++		start = buff->client.log_start_addr;
  48.442 ++		break;
  48.443 ++	}
  48.444 ++	if (!len) {
  48.445 + 		printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
  48.446 + 		return -EIO;
  48.447 + 	}
  48.448 + 
  48.449 + 	/* malloc EventLog space */
  48.450 +-	log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL);
  48.451 ++	log->bios_event_log = kmalloc(len, GFP_KERNEL);
  48.452 + 	if (!log->bios_event_log) {
  48.453 +-		printk
  48.454 +-		    ("%s: ERROR - Not enough  Memory for BIOS measurements\n",
  48.455 +-		     __func__);
  48.456 ++		printk("%s: ERROR - Not enough  Memory for BIOS measurements\n",
  48.457 ++			__func__);
  48.458 + 		return -ENOMEM;
  48.459 + 	}
  48.460 + 
  48.461 +-	log->bios_event_log_end = log->bios_event_log + buff->log_max_len;
  48.462 ++	log->bios_event_log_end = log->bios_event_log + len;
  48.463 + 
  48.464 +-	acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, (void *) &virt);
  48.465 ++	acpi_os_map_memory(start, len, (void *) &virt);
  48.466 + 
  48.467 +-	memcpy(log->bios_event_log, virt, buff->log_max_len);
  48.468 ++	memcpy(log->bios_event_log, virt, len);
  48.469 + 
  48.470 +-	acpi_os_unmap_memory(virt, buff->log_max_len);
  48.471 ++	acpi_os_unmap_memory(virt, len);
  48.472 + 	return 0;
  48.473 + }
  48.474 + 
  48.475 +diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_infineon.c ./drivers/char/tpm/tpm_infineon.c
  48.476 +--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_infineon.c	2006-06-26 18:05:03.000000000 -0400
  48.477 ++++ ./drivers/char/tpm/tpm_infineon.c	2006-06-26 18:16:33.000000000 -0400
  48.478 +@@ -15,6 +15,7 @@
  48.479 +  * License.
  48.480 +  */
  48.481 + 
  48.482 ++#include <linux/init.h>
  48.483 + #include <linux/pnp.h>
  48.484 + #include "tpm.h"
  48.485 + 
  48.486 +@@ -104,7 +105,7 @@ static int empty_fifo(struct tpm_chip *c
  48.487 + 
  48.488 + 	if (clear_wrfifo) {
  48.489 + 		for (i = 0; i < 4096; i++) {
  48.490 +-			status = inb(chip->vendor->base + WRFIFO);
  48.491 ++			status = inb(chip->vendor.base + WRFIFO);
  48.492 + 			if (status == 0xff) {
  48.493 + 				if (check == 5)
  48.494 + 					break;
  48.495 +@@ -124,8 +125,8 @@ static int empty_fifo(struct tpm_chip *c
  48.496 + 	 */
  48.497 + 	i = 0;
  48.498 + 	do {
  48.499 +-		status = inb(chip->vendor->base + RDFIFO);
  48.500 +-		status = inb(chip->vendor->base + STAT);
  48.501 ++		status = inb(chip->vendor.base + RDFIFO);
  48.502 ++		status = inb(chip->vendor.base + STAT);
  48.503 + 		i++;
  48.504 + 		if (i == TPM_MAX_TRIES)
  48.505 + 			return -EIO;
  48.506 +@@ -138,7 +139,7 @@ static int wait(struct tpm_chip *chip, i
  48.507 + 	int status;
  48.508 + 	int i;
  48.509 + 	for (i = 0; i < TPM_MAX_TRIES; i++) {
  48.510 +-		status = inb(chip->vendor->base + STAT);
  48.511 ++		status = inb(chip->vendor.base + STAT);
  48.512 + 		/* check the status-register if wait_for_bit is set */
  48.513 + 		if (status & 1 << wait_for_bit)
  48.514 + 			break;
  48.515 +@@ -157,7 +158,7 @@ static int wait(struct tpm_chip *chip, i
  48.516 + static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
  48.517 + {
  48.518 + 	wait(chip, STAT_XFE);
  48.519 +-	outb(sendbyte, chip->vendor->base + WRFIFO);
  48.520 ++	outb(sendbyte, chip->vendor.base + WRFIFO);
  48.521 + }
  48.522 + 
  48.523 +     /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
  48.524 +@@ -204,7 +205,7 @@ recv_begin:
  48.525 + 		ret = wait(chip, STAT_RDA);
  48.526 + 		if (ret)
  48.527 + 			return -EIO;
  48.528 +-		buf[i] = inb(chip->vendor->base + RDFIFO);
  48.529 ++		buf[i] = inb(chip->vendor.base + RDFIFO);
  48.530 + 	}
  48.531 + 
  48.532 + 	if (buf[0] != TPM_VL_VER) {
  48.533 +@@ -219,7 +220,7 @@ recv_begin:
  48.534 + 
  48.535 + 		for (i = 0; i < size; i++) {
  48.536 + 			wait(chip, STAT_RDA);
  48.537 +-			buf[i] = inb(chip->vendor->base + RDFIFO);
  48.538 ++			buf[i] = inb(chip->vendor.base + RDFIFO);
  48.539 + 		}
  48.540 + 
  48.541 + 		if ((size == 0x6D00) && (buf[1] == 0x80)) {
  48.542 +@@ -268,7 +269,7 @@ static int tpm_inf_send(struct tpm_chip 
  48.543 + 	u8 count_high, count_low, count_4, count_3, count_2, count_1;
  48.544 + 
  48.545 + 	/* Disabling Reset, LP and IRQC */
  48.546 +-	outb(RESET_LP_IRQC_DISABLE, chip->vendor->base + CMD);
  48.547 ++	outb(RESET_LP_IRQC_DISABLE, chip->vendor.base + CMD);
  48.548 + 
  48.549 + 	ret = empty_fifo(chip, 1);
  48.550 + 	if (ret) {
  48.551 +@@ -319,7 +320,7 @@ static void tpm_inf_cancel(struct tpm_ch
  48.552 + 
  48.553 + static u8 tpm_inf_status(struct tpm_chip *chip)
  48.554 + {
  48.555 +-	return inb(chip->vendor->base + STAT);
  48.556 ++	return inb(chip->vendor.base + STAT);
  48.557 + }
  48.558 + 
  48.559 + static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
  48.560 +@@ -346,7 +347,7 @@ static struct file_operations inf_ops = 
  48.561 + 	.release = tpm_release,
  48.562 + };
  48.563 + 
  48.564 +-static struct tpm_vendor_specific tpm_inf = {
  48.565 ++static const struct tpm_vendor_specific tpm_inf = {
  48.566 + 	.recv = tpm_inf_recv,
  48.567 + 	.send = tpm_inf_send,
  48.568 + 	.cancel = tpm_inf_cancel,
  48.569 +@@ -375,6 +376,7 @@ static int __devinit tpm_inf_pnp_probe(s
  48.570 + 	int version[2];
  48.571 + 	int productid[2];
  48.572 + 	char chipname[20];
  48.573 ++	struct tpm_chip *chip;
  48.574 + 
  48.575 + 	/* read IO-ports through PnP */
  48.576 + 	if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
  48.577 +@@ -395,14 +397,13 @@ static int __devinit tpm_inf_pnp_probe(s
  48.578 + 			goto err_last;
  48.579 + 		}
  48.580 + 		/* publish my base address and request region */
  48.581 +-		tpm_inf.base = TPM_INF_BASE;
  48.582 + 		if (request_region
  48.583 +-		    (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
  48.584 ++		    (TPM_INF_BASE, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
  48.585 + 			rc = -EINVAL;
  48.586 + 			goto err_last;
  48.587 + 		}
  48.588 +-		if (request_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN,
  48.589 +-				"tpm_infineon0") == NULL) {
  48.590 ++		if (request_region
  48.591 ++		    (TPM_INF_ADDR, TPM_INF_ADDR_LEN, "tpm_infineon0") == NULL) {
  48.592 + 			rc = -EINVAL;
  48.593 + 			goto err_last;
  48.594 + 		}
  48.595 +@@ -442,9 +443,9 @@ static int __devinit tpm_inf_pnp_probe(s
  48.596 + 
  48.597 + 		/* configure TPM with IO-ports */
  48.598 + 		outb(IOLIMH, TPM_INF_ADDR);
  48.599 +-		outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA);
  48.600 ++		outb(((TPM_INF_BASE >> 8) & 0xff), TPM_INF_DATA);
  48.601 + 		outb(IOLIML, TPM_INF_ADDR);
  48.602 +-		outb((tpm_inf.base & 0xff), TPM_INF_DATA);
  48.603 ++		outb((TPM_INF_BASE & 0xff), TPM_INF_DATA);
  48.604 + 
  48.605 + 		/* control if IO-ports are set correctly */
  48.606 + 		outb(IOLIMH, TPM_INF_ADDR);
  48.607 +@@ -452,10 +453,10 @@ static int __devinit tpm_inf_pnp_probe(s
  48.608 + 		outb(IOLIML, TPM_INF_ADDR);
  48.609 + 		iol = inb(TPM_INF_DATA);
  48.610 + 
  48.611 +-		if ((ioh << 8 | iol) != tpm_inf.base) {
  48.612 ++		if ((ioh << 8 | iol) != TPM_INF_BASE) {
  48.613 + 			dev_err(&dev->dev,
  48.614 +-				"Could not set IO-ports to 0x%lx\n",
  48.615 +-				tpm_inf.base);
  48.616 ++				"Could not set IO-ports to 0x%x\n",
  48.617 ++				TPM_INF_BASE);
  48.618 + 			rc = -EIO;
  48.619 + 			goto err_release_region;
  48.620 + 		}
  48.621 +@@ -466,15 +467,15 @@ static int __devinit tpm_inf_pnp_probe(s
  48.622 + 		outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
  48.623 + 
  48.624 + 		/* disable RESET, LP and IRQC */
  48.625 +-		outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD);
  48.626 ++		outb(RESET_LP_IRQC_DISABLE, TPM_INF_BASE + CMD);
  48.627 + 
  48.628 + 		/* Finally, we're done, print some infos */
  48.629 + 		dev_info(&dev->dev, "TPM found: "
  48.630 + 			 "config base 0x%x, "
  48.631 + 			 "io base 0x%x, "
  48.632 +-			 "chip version %02x%02x, "
  48.633 +-			 "vendor id %x%x (Infineon), "
  48.634 +-			 "product id %02x%02x"
  48.635 ++			 "chip version 0x%02x%02x, "
  48.636 ++			 "vendor id 0x%x%x (Infineon), "
  48.637 ++			 "product id 0x%02x%02x"
  48.638 + 			 "%s\n",
  48.639 + 			 TPM_INF_ADDR,
  48.640 + 			 TPM_INF_BASE,
  48.641 +@@ -482,11 +483,10 @@ static int __devinit tpm_inf_pnp_probe(s
  48.642 + 			 vendorid[0], vendorid[1],
  48.643 + 			 productid[0], productid[1], chipname);
  48.644 + 
  48.645 +-		rc = tpm_register_hardware(&dev->dev, &tpm_inf);
  48.646 +-		if (rc < 0) {
  48.647 +-			rc = -ENODEV;
  48.648 ++		if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) {
  48.649 + 			goto err_release_region;
  48.650 + 		}
  48.651 ++		chip->vendor.base = TPM_INF_BASE;
  48.652 + 		return 0;
  48.653 + 	} else {
  48.654 + 		rc = -ENODEV;
  48.655 +@@ -494,7 +494,7 @@ static int __devinit tpm_inf_pnp_probe(s
  48.656 + 	}
  48.657 + 
  48.658 + err_release_region:
  48.659 +-	release_region(tpm_inf.base, TPM_INF_PORT_LEN);
  48.660 ++	release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
  48.661 + 	release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
  48.662 + 
  48.663 + err_last:
  48.664 +@@ -506,7 +506,8 @@ static __devexit void tpm_inf_pnp_remove
  48.665 + 	struct tpm_chip *chip = pnp_get_drvdata(dev);
  48.666 + 
  48.667 + 	if (chip) {
  48.668 +-		release_region(chip->vendor->base, TPM_INF_PORT_LEN);
  48.669 ++		release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
  48.670 ++		release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
  48.671 + 		tpm_remove_hardware(chip->dev);
  48.672 + 	}
  48.673 + }
  48.674 +@@ -520,7 +521,7 @@ static struct pnp_driver tpm_inf_pnp = {
  48.675 + 	},
  48.676 + 	.id_table = tpm_pnp_tbl,
  48.677 + 	.probe = tpm_inf_pnp_probe,
  48.678 +-	.remove = tpm_inf_pnp_remove,
  48.679 ++	.remove = __devexit_p(tpm_inf_pnp_remove),
  48.680 + };
  48.681 + 
  48.682 + static int __init init_inf(void)
  48.683 +@@ -538,5 +539,5 @@ module_exit(cleanup_inf);
  48.684 + 
  48.685 + MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
  48.686 + MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
  48.687 +-MODULE_VERSION("1.7");
  48.688 ++MODULE_VERSION("1.8");
  48.689 + MODULE_LICENSE("GPL");
  48.690 +diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_nsc.c ./drivers/char/tpm/tpm_nsc.c
  48.691 +--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_nsc.c	2006-06-26 18:05:03.000000000 -0400
  48.692 ++++ ./drivers/char/tpm/tpm_nsc.c	2006-06-26 18:16:33.000000000 -0400
  48.693 +@@ -71,7 +71,7 @@ static int wait_for_stat(struct tpm_chip
  48.694 + 	unsigned long stop;
  48.695 + 
  48.696 + 	/* status immediately available check */
  48.697 +-	*data = inb(chip->vendor->base + NSC_STATUS);
  48.698 ++	*data = inb(chip->vendor.base + NSC_STATUS);
  48.699 + 	if ((*data & mask) == val)
  48.700 + 		return 0;
  48.701 + 
  48.702 +@@ -79,7 +79,7 @@ static int wait_for_stat(struct tpm_chip
  48.703 + 	stop = jiffies + 10 * HZ;
  48.704 + 	do {
  48.705 + 		msleep(TPM_TIMEOUT);
  48.706 +-		*data = inb(chip->vendor->base + 1);
  48.707 ++		*data = inb(chip->vendor.base + 1);
  48.708 + 		if ((*data & mask) == val)
  48.709 + 			return 0;
  48.710 + 	}
  48.711 +@@ -94,9 +94,9 @@ static int nsc_wait_for_ready(struct tpm
  48.712 + 	unsigned long stop;
  48.713 + 
  48.714 + 	/* status immediately available check */
  48.715 +-	status = inb(chip->vendor->base + NSC_STATUS);
  48.716 ++	status = inb(chip->vendor.base + NSC_STATUS);
  48.717 + 	if (status & NSC_STATUS_OBF)
  48.718 +-		status = inb(chip->vendor->base + NSC_DATA);
  48.719 ++		status = inb(chip->vendor.base + NSC_DATA);
  48.720 + 	if (status & NSC_STATUS_RDY)
  48.721 + 		return 0;
  48.722 + 
  48.723 +@@ -104,9 +104,9 @@ static int nsc_wait_for_ready(struct tpm
  48.724 + 	stop = jiffies + 100;
  48.725 + 	do {
  48.726 + 		msleep(TPM_TIMEOUT);
  48.727 +-		status = inb(chip->vendor->base + NSC_STATUS);
  48.728 ++		status = inb(chip->vendor.base + NSC_STATUS);
  48.729 + 		if (status & NSC_STATUS_OBF)
  48.730 +-			status = inb(chip->vendor->base + NSC_DATA);
  48.731 ++			status = inb(chip->vendor.base + NSC_DATA);
  48.732 + 		if (status & NSC_STATUS_RDY)
  48.733 + 			return 0;
  48.734 + 	}
  48.735 +@@ -132,7 +132,7 @@ static int tpm_nsc_recv(struct tpm_chip 
  48.736 + 		return -EIO;
  48.737 + 	}
  48.738 + 	if ((data =
  48.739 +-	     inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
  48.740 ++	     inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
  48.741 + 		dev_err(chip->dev, "not in normal mode (0x%x)\n",
  48.742 + 			data);
  48.743 + 		return -EIO;
  48.744 +@@ -148,7 +148,7 @@ static int tpm_nsc_recv(struct tpm_chip 
  48.745 + 		}
  48.746 + 		if (data & NSC_STATUS_F0)
  48.747 + 			break;
  48.748 +-		*p = inb(chip->vendor->base + NSC_DATA);
  48.749 ++		*p = inb(chip->vendor.base + NSC_DATA);
  48.750 + 	}
  48.751 + 
  48.752 + 	if ((data & NSC_STATUS_F0) == 0 &&
  48.753 +@@ -156,7 +156,7 @@ static int tpm_nsc_recv(struct tpm_chip 
  48.754 + 		dev_err(chip->dev, "F0 not set\n");
  48.755 + 		return -EIO;
  48.756 + 	}
  48.757 +-	if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) {
  48.758 ++	if ((data = inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_EOC) {
  48.759 + 		dev_err(chip->dev,
  48.760 + 			"expected end of command(0x%x)\n", data);
  48.761 + 		return -EIO;
  48.762 +@@ -182,7 +182,7 @@ static int tpm_nsc_send(struct tpm_chip 
  48.763 + 	 * fix it. Not sure why this is needed, we followed the flow
  48.764 + 	 * chart in the manual to the letter.
  48.765 + 	 */
  48.766 +-	outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
  48.767 ++	outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
  48.768 + 
  48.769 + 	if (nsc_wait_for_ready(chip) != 0)
  48.770 + 		return -EIO;
  48.771 +@@ -192,7 +192,7 @@ static int tpm_nsc_send(struct tpm_chip 
  48.772 + 		return -EIO;
  48.773 + 	}
  48.774 + 
  48.775 +-	outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND);
  48.776 ++	outb(NSC_COMMAND_NORMAL, chip->vendor.base + NSC_COMMAND);
  48.777 + 	if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
  48.778 + 		dev_err(chip->dev, "IBR timeout\n");
  48.779 + 		return -EIO;
  48.780 +@@ -204,26 +204,26 @@ static int tpm_nsc_send(struct tpm_chip 
  48.781 + 				"IBF timeout (while writing data)\n");
  48.782 + 			return -EIO;
  48.783 + 		}
  48.784 +-		outb(buf[i], chip->vendor->base + NSC_DATA);
  48.785 ++		outb(buf[i], chip->vendor.base + NSC_DATA);
  48.786 + 	}
  48.787 + 
  48.788 + 	if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
  48.789 + 		dev_err(chip->dev, "IBF timeout\n");
  48.790 + 		return -EIO;
  48.791 + 	}
  48.792 +-	outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND);
  48.793 ++	outb(NSC_COMMAND_EOC, chip->vendor.base + NSC_COMMAND);
  48.794 + 
  48.795 + 	return count;
  48.796 + }
  48.797 + 
  48.798 + static void tpm_nsc_cancel(struct tpm_chip *chip)
  48.799 + {
  48.800 +-	outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
  48.801 ++	outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
  48.802 + }
  48.803 + 
  48.804 + static u8 tpm_nsc_status(struct tpm_chip *chip)
  48.805 + {
  48.806 +-	return inb(chip->vendor->base + NSC_STATUS);
  48.807 ++	return inb(chip->vendor.base + NSC_STATUS);
  48.808 + }
  48.809 + 
  48.810 + static struct file_operations nsc_ops = {
  48.811 +@@ -250,7 +250,7 @@ static struct attribute * nsc_attrs[] = 
  48.812 + 
  48.813 + static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
  48.814 + 
  48.815 +-static struct tpm_vendor_specific tpm_nsc = {
  48.816 ++static const struct tpm_vendor_specific tpm_nsc = {
  48.817 + 	.recv = tpm_nsc_recv,
  48.818 + 	.send = tpm_nsc_send,
  48.819 + 	.cancel = tpm_nsc_cancel,
  48.820 +@@ -268,7 +268,7 @@ static void __devexit tpm_nsc_remove(str
  48.821 + {
  48.822 + 	struct tpm_chip *chip = dev_get_drvdata(dev);
  48.823 + 	if ( chip ) {
  48.824 +-		release_region(chip->vendor->base, 2);
  48.825 ++		release_region(chip->vendor.base, 2);
  48.826 + 		tpm_remove_hardware(chip->dev);
  48.827 + 	}
  48.828 + }
  48.829 +@@ -286,7 +286,8 @@ static int __init init_nsc(void)
  48.830 + 	int rc = 0;
  48.831 + 	int lo, hi;
  48.832 + 	int nscAddrBase = TPM_ADDR;
  48.833 +-
  48.834 ++	struct tpm_chip *chip;
  48.835 ++	unsigned long base;
  48.836 + 
  48.837 + 	/* verify that it is a National part (SID) */
  48.838 + 	if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
  48.839 +@@ -300,7 +301,7 @@ static int __init init_nsc(void)
  48.840 + 
  48.841 + 	hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
  48.842 + 	lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
  48.843 +-	tpm_nsc.base = (hi<<8) | lo;
  48.844 ++	base = (hi<<8) | lo;
  48.845 + 
  48.846 + 	/* enable the DPM module */
  48.847 + 	tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
  48.848 +@@ -320,13 +321,15 @@ static int __init init_nsc(void)
  48.849 + 	if ((rc = platform_device_register(pdev)) < 0)
  48.850 + 		goto err_free_dev;
  48.851 + 
  48.852 +-	if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) {
  48.853 ++	if (request_region(base, 2, "tpm_nsc0") == NULL ) {
  48.854 + 		rc = -EBUSY;
  48.855 + 		goto err_unreg_dev;
  48.856 + 	}
  48.857 + 
  48.858 +-	if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0)
  48.859 ++	if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_nsc))) {
  48.860 ++		rc = -ENODEV;
  48.861 + 		goto err_rel_reg;
  48.862 ++	}
  48.863 + 
  48.864 + 	dev_dbg(&pdev->dev, "NSC TPM detected\n");
  48.865 + 	dev_dbg(&pdev->dev,
  48.866 +@@ -361,10 +364,12 @@ static int __init init_nsc(void)
  48.867 + 		 "NSC TPM revision %d\n",
  48.868 + 		 tpm_read_index(nscAddrBase, 0x27) & 0x1F);
  48.869 + 
  48.870 ++	chip->vendor.base = base;
  48.871 ++
  48.872 + 	return 0;
  48.873 + 
  48.874 + err_rel_reg:
  48.875 +-	release_region(tpm_nsc.base, 2);
  48.876 ++	release_region(base, 2);
  48.877 + err_unreg_dev:
  48.878 + 	platform_device_unregister(pdev);
  48.879 + err_free_dev:
  48.880 +diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_tis.c ./drivers/char/tpm/tpm_tis.c
  48.881 +--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_tis.c	1969-12-31 19:00:00.000000000 -0500
  48.882 ++++ ./drivers/char/tpm/tpm_tis.c	2006-06-26 18:16:33.000000000 -0400
  48.883 +@@ -0,0 +1,665 @@
  48.884 ++/*
  48.885 ++ * Copyright (C) 2005, 2006 IBM Corporation
  48.886 ++ *
  48.887 ++ * Authors:
  48.888 ++ * Leendert van Doorn <leendert@watson.ibm.com>
  48.889 ++ * Kylene Hall <kjhall@us.ibm.com>
  48.890 ++ *
  48.891 ++ * Device driver for TCG/TCPA TPM (trusted platform module).
  48.892 ++ * Specifications at www.trustedcomputinggroup.org
  48.893 ++ *
  48.894 ++ * This device driver implements the TPM interface as defined in
  48.895 ++ * the TCG TPM Interface Spec version 1.2, revision 1.0.
  48.896 ++ *
  48.897 ++ * This program is free software; you can redistribute it and/or
  48.898 ++ * modify it under the terms of the GNU General Public License as
  48.899 ++ * published by the Free Software Foundation, version 2 of the
  48.900 ++ * License.
  48.901 ++ */
  48.902 ++#include <linux/init.h>
  48.903 ++#include <linux/module.h>
  48.904 ++#include <linux/moduleparam.h>
  48.905 ++#include <linux/pnp.h>
  48.906 ++#include <linux/interrupt.h>
  48.907 ++#include <linux/wait.h>
  48.908 ++#include "tpm.h"
  48.909 ++
  48.910 ++#define TPM_HEADER_SIZE 10
  48.911 ++
  48.912 ++enum tis_access {
  48.913 ++	TPM_ACCESS_VALID = 0x80,
  48.914 ++	TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
  48.915 ++	TPM_ACCESS_REQUEST_PENDING = 0x04,
  48.916 ++	TPM_ACCESS_REQUEST_USE = 0x02,
  48.917 ++};
  48.918 ++
  48.919 ++enum tis_status {
  48.920 ++	TPM_STS_VALID = 0x80,
  48.921 ++	TPM_STS_COMMAND_READY = 0x40,
  48.922 ++	TPM_STS_GO = 0x20,
  48.923 ++	TPM_STS_DATA_AVAIL = 0x10,
  48.924 ++	TPM_STS_DATA_EXPECT = 0x08,
  48.925 ++};
  48.926 ++
  48.927 ++enum tis_int_flags {
  48.928 ++	TPM_GLOBAL_INT_ENABLE = 0x80000000,
  48.929 ++	TPM_INTF_BURST_COUNT_STATIC = 0x100,
  48.930 ++	TPM_INTF_CMD_READY_INT = 0x080,
  48.931 ++	TPM_INTF_INT_EDGE_FALLING = 0x040,
  48.932 ++	TPM_INTF_INT_EDGE_RISING = 0x020,
  48.933 ++	TPM_INTF_INT_LEVEL_LOW = 0x010,
  48.934 ++	TPM_INTF_INT_LEVEL_HIGH = 0x008,
  48.935 ++	TPM_INTF_LOCALITY_CHANGE_INT = 0x004,
  48.936 ++	TPM_INTF_STS_VALID_INT = 0x002,
  48.937 ++	TPM_INTF_DATA_AVAIL_INT = 0x001,
  48.938 ++};
  48.939 ++
  48.940 ++enum tis_defaults {
  48.941 ++	TIS_MEM_BASE = 0xFED40000,
  48.942 ++	TIS_MEM_LEN = 0x5000,
  48.943 ++	TIS_SHORT_TIMEOUT = 750,	/* ms */
  48.944 ++	TIS_LONG_TIMEOUT = 2000,	/* 2 sec */
  48.945 ++};
  48.946 ++
  48.947 ++#define	TPM_ACCESS(l)			(0x0000 | ((l) << 12))
  48.948 ++#define	TPM_INT_ENABLE(l)		(0x0008 | ((l) << 12))
  48.949 ++#define	TPM_INT_VECTOR(l)		(0x000C | ((l) << 12))
  48.950 ++#define	TPM_INT_STATUS(l)		(0x0010 | ((l) << 12))
  48.951 ++#define	TPM_INTF_CAPS(l)		(0x0014 | ((l) << 12))
  48.952 ++#define	TPM_STS(l)			(0x0018 | ((l) << 12))
  48.953 ++#define	TPM_DATA_FIFO(l)		(0x0024 | ((l) << 12))
  48.954 ++
  48.955 ++#define	TPM_DID_VID(l)			(0x0F00 | ((l) << 12))
  48.956 ++#define	TPM_RID(l)			(0x0F04 | ((l) << 12))
  48.957 ++
  48.958 ++static LIST_HEAD(tis_chips);
  48.959 ++static DEFINE_SPINLOCK(tis_lock);
  48.960 ++
  48.961 ++static int check_locality(struct tpm_chip *chip, int l)
  48.962 ++{
  48.963 ++	if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
  48.964 ++	     (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
  48.965 ++	    (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID))
  48.966 ++		return chip->vendor.locality = l;
  48.967 ++
  48.968 ++	return -1;
  48.969 ++}
  48.970 ++
  48.971 ++static void release_locality(struct tpm_chip *chip, int l, int force)
  48.972 ++{
  48.973 ++	if (force || (ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
  48.974 ++		      (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
  48.975 ++	    (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID))
  48.976 ++		iowrite8(TPM_ACCESS_ACTIVE_LOCALITY,
  48.977 ++			 chip->vendor.iobase + TPM_ACCESS(l));
  48.978 ++}
  48.979 ++
  48.980 ++static int request_locality(struct tpm_chip *chip, int l)
  48.981 ++{
  48.982 ++	unsigned long stop;
  48.983 ++	long rc;
  48.984 ++
  48.985 ++	if (check_locality(chip, l) >= 0)
  48.986 ++		return l;
  48.987 ++
  48.988 ++	iowrite8(TPM_ACCESS_REQUEST_USE,
  48.989 ++		 chip->vendor.iobase + TPM_ACCESS(l));
  48.990 ++
  48.991 ++	if (chip->vendor.irq) {
  48.992 ++		rc = wait_event_interruptible_timeout(chip->vendor.int_queue,
  48.993 ++						      (check_locality
  48.994 ++						       (chip, l) >= 0),
  48.995 ++						      chip->vendor.timeout_a);
  48.996 ++		if (rc > 0)
  48.997 ++			return l;
  48.998 ++
  48.999 ++	} else {
 48.1000 ++		/* wait for burstcount */
 48.1001 ++		stop = jiffies + chip->vendor.timeout_a;
 48.1002 ++		do {
 48.1003 ++			if (check_locality(chip, l) >= 0)
 48.1004 ++				return l;
 48.1005 ++			msleep(TPM_TIMEOUT);
 48.1006 ++		}
 48.1007 ++		while (time_before(jiffies, stop));
 48.1008 ++	}
 48.1009 ++	return -1;
 48.1010 ++}
 48.1011 ++
 48.1012 ++static u8 tpm_tis_status(struct tpm_chip *chip)
 48.1013 ++{
 48.1014 ++	return ioread8(chip->vendor.iobase +
 48.1015 ++		       TPM_STS(chip->vendor.locality));
 48.1016 ++}
 48.1017 ++
 48.1018 ++static void tpm_tis_ready(struct tpm_chip *chip)
 48.1019 ++{
 48.1020 ++	/* this causes the current command to be aborted */
 48.1021 ++	iowrite8(TPM_STS_COMMAND_READY,
 48.1022 ++		 chip->vendor.iobase + TPM_STS(chip->vendor.locality));
 48.1023 ++}
 48.1024 ++
 48.1025 ++static int get_burstcount(struct tpm_chip *chip)
 48.1026 ++{
 48.1027 ++	unsigned long stop;
 48.1028 ++	int burstcnt;
 48.1029 ++
 48.1030 ++	/* wait for burstcount */
 48.1031 ++	/* which timeout value, spec has 2 answers (c & d) */
 48.1032 ++	stop = jiffies + chip->vendor.timeout_d;
 48.1033 ++	do {
 48.1034 ++		burstcnt = ioread8(chip->vendor.iobase +
 48.1035 ++				   TPM_STS(chip->vendor.locality) + 1);
 48.1036 ++		burstcnt += ioread8(chip->vendor.iobase +
 48.1037 ++				    TPM_STS(chip->vendor.locality) +
 48.1038 ++				    2) << 8;
 48.1039 ++		if (burstcnt)
 48.1040 ++			return burstcnt;
 48.1041 ++		msleep(TPM_TIMEOUT);
 48.1042 ++	} while (time_before(jiffies, stop));
 48.1043 ++	return -EBUSY;
 48.1044 ++}
 48.1045 ++
 48.1046 ++static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
 48.1047 ++			 wait_queue_head_t *queue)
 48.1048 ++{
 48.1049 ++	unsigned long stop;
 48.1050 ++	long rc;
 48.1051 ++	u8 status;
 48.1052 ++
 48.1053 ++	/* check current status */
 48.1054 ++	status = tpm_tis_status(chip);
 48.1055 ++	if ((status & mask) == mask)
 48.1056 ++		return 0;
 48.1057 ++
 48.1058 ++	if (chip->vendor.irq) {
 48.1059 ++		rc = wait_event_interruptible_timeout(*queue,
 48.1060 ++						      ((tpm_tis_status
 48.1061 ++							(chip) & mask) ==
 48.1062 ++						       mask), timeout);
 48.1063 ++		if (rc > 0)
 48.1064 ++			return 0;
 48.1065 ++	} else {
 48.1066 ++		stop = jiffies + timeout;
 48.1067 ++		do {
 48.1068 ++			msleep(TPM_TIMEOUT);
 48.1069 ++			status = tpm_tis_status(chip);
 48.1070 ++			if ((status & mask) == mask)
 48.1071 ++				return 0;
 48.1072 ++		} while (time_before(jiffies, stop));
 48.1073 ++	}
 48.1074 ++	return -ETIME;
 48.1075 ++}
 48.1076 ++
 48.1077 ++static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
 48.1078 ++{
 48.1079 ++	int size = 0, burstcnt;
 48.1080 ++	while (size < count &&
 48.1081 ++	       wait_for_stat(chip,
 48.1082 ++			     TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 48.1083 ++			     chip->vendor.timeout_c,
 48.1084 ++			     &chip->vendor.read_queue)
 48.1085 ++	       == 0) {
 48.1086 ++		burstcnt = get_burstcount(chip);
 48.1087 ++		for (; burstcnt > 0 && size < count; burstcnt--)
 48.1088 ++			buf[size++] = ioread8(chip->vendor.iobase +
 48.1089 ++					      TPM_DATA_FIFO(chip->vendor.
 48.1090 ++							    locality));
 48.1091 ++	}
 48.1092 ++	return size;
 48.1093 ++}
 48.1094 ++
 48.1095 ++static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 48.1096 ++{
 48.1097 ++	int size = 0;
 48.1098 ++	int expected, status;
 48.1099 ++
 48.1100 ++	if (count < TPM_HEADER_SIZE) {
 48.1101 ++		size = -EIO;
 48.1102 ++		goto out;
 48.1103 ++	}
 48.1104 ++
 48.1105 ++	/* read first 10 bytes, including tag, paramsize, and result */
 48.1106 ++	if ((size =
 48.1107 ++	     recv_data(chip, buf, TPM_HEADER_SIZE)) < TPM_HEADER_SIZE) {
 48.1108 ++		dev_err(chip->dev, "Unable to read header\n");
 48.1109 ++		goto out;
 48.1110 ++	}
 48.1111 ++
 48.1112 ++	expected = be32_to_cpu(*(__be32 *) (buf + 2));
 48.1113 ++	if (expected > count) {
 48.1114 ++		size = -EIO;
 48.1115 ++		goto out;
 48.1116 ++	}
 48.1117 ++
 48.1118 ++	if ((size +=
 48.1119 ++	     recv_data(chip, &buf[TPM_HEADER_SIZE],
 48.1120 ++		       expected - TPM_HEADER_SIZE)) < expected) {
 48.1121 ++		dev_err(chip->dev, "Unable to read remainder of result\n");
 48.1122 ++		size = -ETIME;
 48.1123 ++		goto out;
 48.1124 ++	}
 48.1125 ++
 48.1126 ++	wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
 48.1127 ++		      &chip->vendor.int_queue);
 48.1128 ++	status = tpm_tis_status(chip);
 48.1129 ++	if (status & TPM_STS_DATA_AVAIL) {	/* retry? */
 48.1130 ++		dev_err(chip->dev, "Error left over data\n");
 48.1131 ++		size = -EIO;
 48.1132 ++		goto out;
 48.1133 ++	}
 48.1134 ++
 48.1135 ++out:
 48.1136 ++	tpm_tis_ready(chip);
 48.1137 ++	release_locality(chip, chip->vendor.locality, 0);
 48.1138 ++	return size;
 48.1139 ++}
 48.1140 ++
 48.1141 ++/*
 48.1142 ++ * If interrupts are used (signaled by an irq set in the vendor structure)
 48.1143 ++ * tpm.c can skip polling for the data to be available as the interrupt is
 48.1144 ++ * waited for here
 48.1145 ++ */
 48.1146 ++static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
 48.1147 ++{
 48.1148 ++	int rc, status, burstcnt;
 48.1149 ++	size_t count = 0;
 48.1150 ++	u32 ordinal;
 48.1151 ++
 48.1152 ++	if (request_locality(chip, 0) < 0)
 48.1153 ++		return -EBUSY;
 48.1154 ++
 48.1155 ++	status = tpm_tis_status(chip);
 48.1156 ++	if ((status & TPM_STS_COMMAND_READY) == 0) {
 48.1157 ++		tpm_tis_ready(chip);
 48.1158 ++		if (wait_for_stat
 48.1159 ++		    (chip, TPM_STS_COMMAND_READY, chip->vendor.timeout_b,
 48.1160 ++		     &chip->vendor.int_queue) < 0) {
 48.1161 ++			rc = -ETIME;
 48.1162 ++			goto out_err;
 48.1163 ++		}
 48.1164 ++	}
 48.1165 ++
 48.1166 ++	while (count < len - 1) {
 48.1167 ++		burstcnt = get_burstcount(chip);
 48.1168 ++		for (; burstcnt > 0 && count < len - 1; burstcnt--) {
 48.1169 ++			iowrite8(buf[count], chip->vendor.iobase +
 48.1170 ++				 TPM_DATA_FIFO(chip->vendor.locality));
 48.1171 ++			count++;
 48.1172 ++		}
 48.1173 ++
 48.1174 ++		wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
 48.1175 ++			      &chip->vendor.int_queue);
 48.1176 ++		status = tpm_tis_status(chip);
 48.1177 ++		if ((status & TPM_STS_DATA_EXPECT) == 0) {
 48.1178 ++			rc = -EIO;
 48.1179 ++			goto out_err;
 48.1180 ++		}
 48.1181 ++	}
 48.1182 ++
 48.1183 ++	/* write last byte */
 48.1184 ++	iowrite8(buf[count],
 48.1185 ++		 chip->vendor.iobase +
 48.1186 ++		 TPM_DATA_FIFO(chip->vendor.locality));
 48.1187 ++	wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
 48.1188 ++		      &chip->vendor.int_queue);
 48.1189 ++	status = tpm_tis_status(chip);
 48.1190 ++	if ((status & TPM_STS_DATA_EXPECT) != 0) {
 48.1191 ++		rc = -EIO;
 48.1192 ++		goto out_err;
 48.1193 ++	}
 48.1194 ++
 48.1195 ++	/* go and do it */
 48.1196 ++	iowrite8(TPM_STS_GO,
 48.1197 ++		 chip->vendor.iobase + TPM_STS(chip->vendor.locality));
 48.1198 ++
 48.1199 ++	if (chip->vendor.irq) {
 48.1200 ++		ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
 48.1201 ++		if (wait_for_stat
 48.1202 ++		    (chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 48.1203 ++		     tpm_calc_ordinal_duration(chip, ordinal),
 48.1204 ++		     &chip->vendor.read_queue) < 0) {
 48.1205 ++			rc = -ETIME;
 48.1206 ++			goto out_err;
 48.1207 ++		}
 48.1208 ++	}
 48.1209 ++	return len;
 48.1210 ++out_err:
 48.1211 ++	tpm_tis_ready(chip);
 48.1212 ++	release_locality(chip, chip->vendor.locality, 0);
 48.1213 ++	return rc;
 48.1214 ++}
 48.1215 ++
 48.1216 ++static struct file_operations tis_ops = {
 48.1217 ++	.owner = THIS_MODULE,
 48.1218 ++	.llseek = no_llseek,
 48.1219 ++	.open = tpm_open,
 48.1220 ++	.read = tpm_read,
 48.1221 ++	.write = tpm_write,
 48.1222 ++	.release = tpm_release,
 48.1223 ++};
 48.1224 ++
 48.1225 ++static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
 48.1226 ++static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
 48.1227 ++static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
 48.1228 ++static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
 48.1229 ++static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
 48.1230 ++static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
 48.1231 ++		   NULL);
 48.1232 ++static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL);
 48.1233 ++static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
 48.1234 ++
 48.1235 ++static struct attribute *tis_attrs[] = {
 48.1236 ++	&dev_attr_pubek.attr,
 48.1237 ++	&dev_attr_pcrs.attr,
 48.1238 ++	&dev_attr_enabled.attr,
 48.1239 ++	&dev_attr_active.attr,
 48.1240 ++	&dev_attr_owned.attr,
 48.1241 ++	&dev_attr_temp_deactivated.attr,
 48.1242 ++	&dev_attr_caps.attr,
 48.1243 ++	&dev_attr_cancel.attr, NULL,
 48.1244 ++};
 48.1245 ++
 48.1246 ++static struct attribute_group tis_attr_grp = {
 48.1247 ++	.attrs = tis_attrs
 48.1248 ++};
 48.1249 ++
 48.1250 ++static struct tpm_vendor_specific tpm_tis = {
 48.1251 ++	.status = tpm_tis_status,
 48.1252 ++	.recv = tpm_tis_recv,
 48.1253 ++	.send = tpm_tis_send,
 48.1254 ++	.cancel = tpm_tis_ready,
 48.1255 ++	.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 48.1256 ++	.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 48.1257 ++	.req_canceled = TPM_STS_COMMAND_READY,
 48.1258 ++	.attr_group = &tis_attr_grp,
 48.1259 ++	.miscdev = {
 48.1260 ++		    .fops = &tis_ops,},
 48.1261 ++};
 48.1262 ++
 48.1263 ++static irqreturn_t tis_int_probe(int irq, void *dev_id, struct pt_regs *regs)
 48.1264 ++{
 48.1265 ++	struct tpm_chip *chip = (struct tpm_chip *) dev_id;
 48.1266 ++	u32 interrupt;
 48.1267 ++
 48.1268 ++	interrupt = ioread32(chip->vendor.iobase +
 48.1269 ++			     TPM_INT_STATUS(chip->vendor.locality));
 48.1270 ++
 48.1271 ++	if (interrupt == 0)
 48.1272 ++		return IRQ_NONE;
 48.1273 ++
 48.1274 ++	chip->vendor.irq = irq;
 48.1275 ++
 48.1276 ++	/* Clear interrupts handled with TPM_EOI */
 48.1277 ++	iowrite32(interrupt,
 48.1278 ++		  chip->vendor.iobase +
 48.1279 ++		  TPM_INT_STATUS(chip->vendor.locality));
 48.1280 ++	return IRQ_HANDLED;
 48.1281 ++}
 48.1282 ++
 48.1283 ++static irqreturn_t tis_int_handler(int irq, void *dev_id, struct pt_regs *regs)
 48.1284 ++{
 48.1285 ++	struct tpm_chip *chip = (struct tpm_chip *) dev_id;
 48.1286 ++	u32 interrupt;
 48.1287 ++	int i;
 48.1288 ++
 48.1289 ++	interrupt = ioread32(chip->vendor.iobase +
 48.1290 ++			     TPM_INT_STATUS(chip->vendor.locality));
 48.1291 ++
 48.1292 ++	if (interrupt == 0)
 48.1293 ++		return IRQ_NONE;
 48.1294 ++
 48.1295 ++	if (interrupt & TPM_INTF_DATA_AVAIL_INT)
 48.1296 ++		wake_up_interruptible(&chip->vendor.read_queue);
 48.1297 ++	if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT)
 48.1298 ++		for (i = 0; i < 5; i++)
 48.1299 ++			if (check_locality(chip, i) >= 0)
 48.1300 ++				break;
 48.1301 ++	if (interrupt &
 48.1302 ++	    (TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_STS_VALID_INT |
 48.1303 ++	     TPM_INTF_CMD_READY_INT))
 48.1304 ++		wake_up_interruptible(&chip->vendor.int_queue);
 48.1305 ++
 48.1306 ++	/* Clear interrupts handled with TPM_EOI */
 48.1307 ++	iowrite32(interrupt,
 48.1308 ++		  chip->vendor.iobase +
 48.1309 ++		  TPM_INT_STATUS(chip->vendor.locality));
 48.1310 ++	return IRQ_HANDLED;
 48.1311 ++}
 48.1312 ++
 48.1313 ++static int interrupts = 1;
 48.1314 ++module_param(interrupts, bool, 0444);
 48.1315 ++MODULE_PARM_DESC(interrupts, "Enable interrupts");
 48.1316 ++
 48.1317 ++static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
 48.1318 ++				      const struct pnp_device_id *pnp_id)
 48.1319 ++{
 48.1320 ++	u32 vendor, intfcaps, intmask;
 48.1321 ++	int rc, i;
 48.1322 ++	unsigned long start, len;
 48.1323 ++	struct tpm_chip *chip;
 48.1324 ++
 48.1325 ++	start = pnp_mem_start(pnp_dev, 0);
 48.1326 ++	len = pnp_mem_len(pnp_dev, 0);
 48.1327 ++
 48.1328 ++	if (!start)
 48.1329 ++		start = TIS_MEM_BASE;
 48.1330 ++	if (!len)
 48.1331 ++		len = TIS_MEM_LEN;
 48.1332 ++
 48.1333 ++	if (!(chip = tpm_register_hardware(&pnp_dev->dev, &tpm_tis)))
 48.1334 ++		return -ENODEV;
 48.1335 ++
 48.1336 ++	chip->vendor.iobase = ioremap(start, len);
 48.1337 ++	if (!chip->vendor.iobase) {
 48.1338 ++		rc = -EIO;
 48.1339 ++		goto out_err;
 48.1340 ++	}
 48.1341 ++
 48.1342 ++	vendor = ioread32(chip->vendor.iobase + TPM_DID_VID(0));
 48.1343 ++
 48.1344 ++	/* Default timeouts */
 48.1345 ++	chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
 48.1346 ++	chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT);
 48.1347 ++	chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
 48.1348 ++	chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
 48.1349 ++
 48.1350 ++	dev_info(&pnp_dev->dev,
 48.1351 ++		 "1.2 TPM (device-id 0x%X, rev-id %d)\n",
 48.1352 ++		 vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
 48.1353 ++
 48.1354 ++	/* Figure out the capabilities */
 48.1355 ++	intfcaps =
 48.1356 ++	    ioread32(chip->vendor.iobase +
 48.1357 ++		     TPM_INTF_CAPS(chip->vendor.locality));
 48.1358 ++	dev_dbg(&pnp_dev->dev, "TPM interface capabilities (0x%x):\n",
 48.1359 ++		intfcaps);
 48.1360 ++	if (intfcaps & TPM_INTF_BURST_COUNT_STATIC)
 48.1361 ++		dev_dbg(&pnp_dev->dev, "\tBurst Count Static\n");
 48.1362 ++	if (intfcaps & TPM_INTF_CMD_READY_INT)
 48.1363 ++		dev_dbg(&pnp_dev->dev, "\tCommand Ready Int Support\n");
 48.1364 ++	if (intfcaps & TPM_INTF_INT_EDGE_FALLING)
 48.1365 ++		dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Falling\n");
 48.1366 ++	if (intfcaps & TPM_INTF_INT_EDGE_RISING)
 48.1367 ++		dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Rising\n");
 48.1368 ++	if (intfcaps & TPM_INTF_INT_LEVEL_LOW)
 48.1369 ++		dev_dbg(&pnp_dev->dev, "\tInterrupt Level Low\n");
 48.1370 ++	if (intfcaps & TPM_INTF_INT_LEVEL_HIGH)
 48.1371 ++		dev_dbg(&pnp_dev->dev, "\tInterrupt Level High\n");
 48.1372 ++	if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT)
 48.1373 ++		dev_dbg(&pnp_dev->dev, "\tLocality Change Int Support\n");
 48.1374 ++	if (intfcaps & TPM_INTF_STS_VALID_INT)
 48.1375 ++		dev_dbg(&pnp_dev->dev, "\tSts Valid Int Support\n");
 48.1376 ++	if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
 48.1377 ++		dev_dbg(&pnp_dev->dev, "\tData Avail Int Support\n");
 48.1378 ++
 48.1379 ++	if (request_locality(chip, 0) != 0) {
 48.1380 ++		rc = -ENODEV;
 48.1381 ++		goto out_err;
 48.1382 ++	}
 48.1383 ++
 48.1384 ++	/* INTERRUPT Setup */
 48.1385 ++	init_waitqueue_head(&chip->vendor.read_queue);
 48.1386 ++	init_waitqueue_head(&chip->vendor.int_queue);
 48.1387 ++
 48.1388 ++	intmask =
 48.1389 ++	    ioread32(chip->vendor.iobase +
 48.1390 ++		     TPM_INT_ENABLE(chip->vendor.locality));
 48.1391 ++
 48.1392 ++	intmask |= TPM_INTF_CMD_READY_INT
 48.1393 ++	    | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
 48.1394 ++	    | TPM_INTF_STS_VALID_INT;
 48.1395 ++
 48.1396 ++	iowrite32(intmask,
 48.1397 ++		  chip->vendor.iobase +
 48.1398 ++		  TPM_INT_ENABLE(chip->vendor.locality));
 48.1399 ++	if (interrupts) {
 48.1400 ++		chip->vendor.irq =
 48.1401 ++		    ioread8(chip->vendor.iobase +
 48.1402 ++			    TPM_INT_VECTOR(chip->vendor.locality));
 48.1403 ++
 48.1404 ++		for (i = 3; i < 16 && chip->vendor.irq == 0; i++) {
 48.1405 ++			iowrite8(i, chip->vendor.iobase +
 48.1406 ++				    TPM_INT_VECTOR(chip->vendor.locality));
 48.1407 ++			if (request_irq
 48.1408 ++			    (i, tis_int_probe, SA_SHIRQ,
 48.1409 ++			     chip->vendor.miscdev.name, chip) != 0) {
 48.1410 ++				dev_info(chip->dev,
 48.1411 ++					 "Unable to request irq: %d for probe\n",
 48.1412 ++					 i);
 48.1413 ++				continue;
 48.1414 ++			}
 48.1415 ++
 48.1416 ++			/* Clear all existing */
 48.1417 ++			iowrite32(ioread32
 48.1418 ++				  (chip->vendor.iobase +
 48.1419 ++				   TPM_INT_STATUS(chip->vendor.locality)),
 48.1420 ++				  chip->vendor.iobase +
 48.1421 ++				  TPM_INT_STATUS(chip->vendor.locality));
 48.1422 ++
 48.1423 ++			/* Turn on */
 48.1424 ++			iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
 48.1425 ++				  chip->vendor.iobase +
 48.1426 ++				  TPM_INT_ENABLE(chip->vendor.locality));
 48.1427 ++
 48.1428 ++			/* Generate Interrupts */
 48.1429 ++			tpm_gen_interrupt(chip);
 48.1430 ++
 48.1431 ++			/* Turn off */
 48.1432 ++			iowrite32(intmask,
 48.1433 ++				  chip->vendor.iobase +
 48.1434 ++				  TPM_INT_ENABLE(chip->vendor.locality));
 48.1435 ++			free_irq(i, chip);
 48.1436 ++		}
 48.1437 ++	}
 48.1438 ++	if (chip->vendor.irq) {
 48.1439 ++		iowrite8(chip->vendor.irq,
 48.1440 ++			 chip->vendor.iobase +
 48.1441 ++			 TPM_INT_VECTOR(chip->vendor.locality));
 48.1442 ++		if (request_irq
 48.1443 ++		    (chip->vendor.irq, tis_int_handler, SA_SHIRQ,
 48.1444 ++		     chip->vendor.miscdev.name, chip) != 0) {
 48.1445 ++			dev_info(chip->dev,
 48.1446 ++				 "Unable to request irq: %d for use\n",
 48.1447 ++				 chip->vendor.irq);
 48.1448 ++			chip->vendor.irq = 0;
 48.1449 ++		} else {
 48.1450 ++			/* Clear all existing */
 48.1451 ++			iowrite32(ioread32
 48.1452 ++				  (chip->vendor.iobase +
 48.1453 ++				   TPM_INT_STATUS(chip->vendor.locality)),
 48.1454 ++				  chip->vendor.iobase +
 48.1455 ++				  TPM_INT_STATUS(chip->vendor.locality));
 48.1456 ++
 48.1457 ++			/* Turn on */
 48.1458 ++			iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
 48.1459 ++				  chip->vendor.iobase +
 48.1460 ++				  TPM_INT_ENABLE(chip->vendor.locality));
 48.1461 ++		}
 48.1462 ++	}
 48.1463 ++
 48.1464 ++	INIT_LIST_HEAD(&chip->vendor.list);
 48.1465 ++	spin_lock(&tis_lock);
 48.1466 ++	list_add(&chip->vendor.list, &tis_chips);
 48.1467 ++	spin_unlock(&tis_lock);
 48.1468 ++
 48.1469 ++	tpm_get_timeouts(chip);
 48.1470 ++	tpm_continue_selftest(chip);
 48.1471 ++
 48.1472 ++	return 0;
 48.1473 ++out_err:
 48.1474 ++	if (chip->vendor.iobase)
 48.1475 ++		iounmap(chip->vendor.iobase);
 48.1476 ++	tpm_remove_hardware(chip->dev);
 48.1477 ++	return rc;
 48.1478 ++}
 48.1479 ++
 48.1480 ++static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg)
 48.1481 ++{
 48.1482 ++	return tpm_pm_suspend(&dev->dev, msg);
 48.1483 ++}
 48.1484 ++
 48.1485 ++static int tpm_tis_pnp_resume(struct pnp_dev *dev)
 48.1486 ++{
 48.1487 ++	return tpm_pm_resume(&dev->dev);
 48.1488 ++}
 48.1489 ++
 48.1490 ++static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
 48.1491 ++	{"PNP0C31", 0},		/* TPM */
 48.1492 ++	{"ATM1200", 0},		/* Atmel */
 48.1493 ++	{"IFX0102", 0},		/* Infineon */
 48.1494 ++	{"BCM0101", 0},		/* Broadcom */
 48.1495 ++	{"NSC1200", 0},		/* National */
 48.1496 ++	/* Add new here */
 48.1497 ++	{"", 0},		/* User Specified */
 48.1498 ++	{"", 0}			/* Terminator */
 48.1499 ++};
 48.1500 ++
 48.1501 ++static struct pnp_driver tis_pnp_driver = {
 48.1502 ++	.name = "tpm_tis",
 48.1503 ++	.id_table = tpm_pnp_tbl,
 48.1504 ++	.probe = tpm_tis_pnp_init,
 48.1505 ++	.suspend = tpm_tis_pnp_suspend,
 48.1506 ++	.resume = tpm_tis_pnp_resume,
 48.1507 ++};
 48.1508 ++
 48.1509 ++#define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2
 48.1510 ++module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
 48.1511 ++		    sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
 48.1512 ++MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
 48.1513 ++
 48.1514 ++static int __init init_tis(void)
 48.1515 ++{
 48.1516 ++	return pnp_register_driver(&tis_pnp_driver);
 48.1517 ++}
 48.1518 ++
 48.1519 ++static void __exit cleanup_tis(void)
 48.1520 ++{
 48.1521 ++	struct tpm_vendor_specific *i, *j;
 48.1522 ++	struct tpm_chip *chip;
 48.1523 ++	spin_lock(&tis_lock);
 48.1524 ++	list_for_each_entry_safe(i, j, &tis_chips, list) {
 48.1525 ++		chip = to_tpm_chip(i);
 48.1526 ++		iowrite32(~TPM_GLOBAL_INT_ENABLE &
 48.1527 ++			  ioread32(chip->vendor.iobase +
 48.1528 ++				   TPM_INT_ENABLE(chip->vendor.
 48.1529 ++						  locality)),
 48.1530 ++			  chip->vendor.iobase +
 48.1531 ++			  TPM_INT_ENABLE(chip->vendor.locality));
 48.1532 ++		release_locality(chip, chip->vendor.locality, 1);
 48.1533 ++		if (chip->vendor.irq)
 48.1534 ++			free_irq(chip->vendor.irq, chip);
 48.1535 ++		iounmap(i->iobase);
 48.1536 ++		list_del(&i->list);
 48.1537 ++		tpm_remove_hardware(chip->dev);
 48.1538 ++	}
 48.1539 ++	spin_unlock(&tis_lock);
 48.1540 ++	pnp_unregister_driver(&tis_pnp_driver);
 48.1541 ++}
 48.1542 ++
 48.1543 ++module_init(init_tis);
 48.1544 ++module_exit(cleanup_tis);
 48.1545 ++MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
 48.1546 ++MODULE_DESCRIPTION("TPM Driver");
 48.1547 ++MODULE_VERSION("2.0");
 48.1548 ++MODULE_LICENSE("GPL");
 48.1549 +
    49.1 --- a/patches/linux-2.6.16.13/xenoprof-generic.patch	Wed Jul 05 10:23:54 2006 -0600
    49.2 +++ b/patches/linux-2.6.16.13/xenoprof-generic.patch	Wed Jul 05 20:11:37 2006 -0600
    49.3 @@ -123,6 +123,21 @@ diff -pru ../pristine-linux-2.6.16.13/dr
    49.4   				}
    49.5   			}
    49.6   		}
    49.7 +diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.h ./drivers/oprofile/buffer_sync.h
    49.8 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.h	2006-05-03 05:38:44.000000000 +0800
    49.9 ++++ ./drivers/oprofile/buffer_sync.h	2006-06-27 12:12:09.000000000 +0800
   49.10 +@@ -9,6 +9,11 @@
   49.11 + 
   49.12 + #ifndef OPROFILE_BUFFER_SYNC_H
   49.13 + #define OPROFILE_BUFFER_SYNC_H
   49.14 ++
   49.15 ++#define NO_DOMAIN_SWITCH		-1
   49.16 ++#define DOMAIN_SWITCH_START_EVENT1	0
   49.17 ++#define DOMAIN_SWITCH_START_EVENT2	1
   49.18 ++#define DOMAIN_SWITCH_STOP_EVENT1	2
   49.19 +  
   49.20 + /* add the necessary profiling hooks */
   49.21 + int sync_start(void);
   49.22  diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c ./drivers/oprofile/cpu_buffer.c
   49.23  --- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c	2006-05-03 05:38:44.000000000 +0800
   49.24  +++ ./drivers/oprofile/cpu_buffer.c	2006-06-19 22:43:53.000000000 +0800
    50.1 --- a/tools/examples/Makefile	Wed Jul 05 10:23:54 2006 -0600
    50.2 +++ b/tools/examples/Makefile	Wed Jul 05 20:11:37 2006 -0600
    50.3 @@ -26,7 +26,7 @@ XEN_SCRIPTS += network-route vif-route
    50.4  XEN_SCRIPTS += network-nat vif-nat
    50.5  XEN_SCRIPTS += block
    50.6  XEN_SCRIPTS += block-enbd block-nbd
    50.7 -XEN_SCRIPTS += vtpm vtpm-delete
    50.8 +XEN_SCRIPTS += vtpm vtpm-delete vtpm-addtodb
    50.9  XEN_SCRIPTS += xen-hotplug-cleanup
   50.10  XEN_SCRIPTS += external-device-migrate
   50.11  XEN_SCRIPT_DATA = xen-script-common.sh locking.sh logging.sh
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/tools/examples/vtpm-addtodb	Wed Jul 05 20:11:37 2006 -0600
    51.3 @@ -0,0 +1,10 @@
    51.4 +#!/bin/sh
    51.5 +
    51.6 +# This script must be called with the following parameters to have
    51.7 +# an entry added to the TPM-to-domain associations table in /etc/xen/vtpm.db
    51.8 +# vtpm-addtodb <dom name> <instance number>
    51.9 +
   51.10 +dir=$(dirname "$0")
   51.11 +. "$dir/vtpm-common.sh"
   51.12 +
   51.13 +vtpmdb_add_instance $1 $2
    52.1 --- a/tools/examples/vtpm-common.sh	Wed Jul 05 10:23:54 2006 -0600
    52.2 +++ b/tools/examples/vtpm-common.sh	Wed Jul 05 20:11:37 2006 -0600
    52.3 @@ -347,16 +347,9 @@ function isLocalAddress() {
    52.4  # 2nd: name of the domain to migrate
    52.5  # 3rd: the migration step to perform
    52.6  function vtpm_migration_step() {
    52.7 -	local instance res
    52.8 -	instance=$(vtpmdb_find_instance $2)
    52.9 -	if [ "$instance" == "" ]; then
   52.10 -		echo "Error: Translation of domain name ($2) to instance failed. Check /etc/xen/vtpm.db"
   52.11 -		log err "Error during translation of domain name"
   52.12 -	else
   52.13 -		res=$(isLocalAddress $1)
   52.14 -		if [ "$res" == "0" ]; then
   52.15 -			vtpm_migrate $1 $2 $3
   52.16 -		fi
   52.17 +	local res=$(isLocalAddress $1)
   52.18 +	if [ "$res" == "0" ]; then
   52.19 +		vtpm_migrate $1 $2 $3
   52.20  	fi
   52.21  }
   52.22  
    53.1 --- a/tools/firmware/hvmloader/Makefile	Wed Jul 05 10:23:54 2006 -0600
    53.2 +++ b/tools/firmware/hvmloader/Makefile	Wed Jul 05 20:11:37 2006 -0600
    53.3 @@ -45,9 +45,9 @@ LDFLAGS  = -m32 -nostdlib -Wl,-N -Wl,-Tt
    53.4  .PHONY: all
    53.5  all: hvmloader
    53.6  
    53.7 -hvmloader: roms.h hvmloader.c acpi_madt.c
    53.8 -	$(CC) $(CFLAGS) -c hvmloader.c acpi_madt.c
    53.9 -	$(CC) $(LDFLAGS) -o hvmloader.tmp hvmloader.o acpi_madt.o
   53.10 +hvmloader: roms.h hvmloader.c acpi_madt.c mp_tables.c
   53.11 +	$(CC) $(CFLAGS) -c hvmloader.c acpi_madt.c mp_tables.c
   53.12 +	$(CC) $(LDFLAGS) -o hvmloader.tmp hvmloader.o acpi_madt.o mp_tables.o
   53.13  	$(OBJCOPY) hvmloader.tmp hvmloader
   53.14  	rm -f hvmloader.tmp
   53.15  
    54.1 --- a/tools/firmware/hvmloader/acpi_madt.c	Wed Jul 05 10:23:54 2006 -0600
    54.2 +++ b/tools/firmware/hvmloader/acpi_madt.c	Wed Jul 05 20:11:37 2006 -0600
    54.3 @@ -51,7 +51,7 @@ static int validate_hvm_info(struct hvm_
    54.4  }
    54.5  
    54.6  /* xc_vmx_builder wrote hvm info at 0x9F800. Return it. */
    54.7 -static struct hvm_info_table *
    54.8 +struct hvm_info_table *
    54.9  get_hvm_info_table(void)
   54.10  {
   54.11  	struct hvm_info_table *t;
    55.1 --- a/tools/firmware/hvmloader/hvmloader.c	Wed Jul 05 10:23:54 2006 -0600
    55.2 +++ b/tools/firmware/hvmloader/hvmloader.c	Wed Jul 05 20:11:37 2006 -0600
    55.3 @@ -23,6 +23,7 @@
    55.4   */
    55.5  #include "roms.h"
    55.6  #include "../acpi/acpi2_0.h"  /* for ACPI_PHYSICAL_ADDRESS */
    55.7 +#include <xen/hvm/hvm_info_table.h>
    55.8  
    55.9  /* memory map */
   55.10  #define VGABIOS_PHYSICAL_ADDRESS	0x000C0000
   55.11 @@ -71,6 +72,8 @@ asm(
   55.12  
   55.13  extern int get_acpi_enabled(void);
   55.14  extern int acpi_madt_update(unsigned char* acpi_start);
   55.15 +extern void create_mp_tables(void);
   55.16 +struct hvm_info_table *get_hvm_info_table(void);
   55.17  
   55.18  static inline void
   55.19  outw(unsigned short addr, unsigned short val)
   55.20 @@ -162,10 +165,15 @@ check_amd(void)
   55.21  int
   55.22  main(void)
   55.23  {
   55.24 +	struct hvm_info_table *t = get_hvm_info_table();
   55.25 +
   55.26  	puts("HVM Loader\n");
   55.27  
   55.28  	puts("Loading ROMBIOS ...\n");
   55.29  	memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios));
   55.30 +	if (t->apic_enabled)
   55.31 +		create_mp_tables();
   55.32 +	
   55.33  	if (cirrus_check()) {
   55.34  		puts("Loading Cirrus VGABIOS ...\n");
   55.35  		memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/tools/firmware/hvmloader/mp_tables.c	Wed Jul 05 20:11:37 2006 -0600
    56.3 @@ -0,0 +1,426 @@
    56.4 +/*
    56.5 + * mp_tables.c: Dynamically writes MP table info into the ROMBIOS.
    56.6 + *
    56.7 + * In order to work with various VCPU counts, this code reads the VCPU count
    56.8 + * for the HVM partition and creates the correct MP tables for the VCPU count
    56.9 + * and places the information into a predetermined location set aside in the
   56.10 + * ROMBIOS during build time.
   56.11 + *
   56.12 + * Please note that many of the values, such as the CPU's
   56.13 + * family/model/stepping, are hard-coded based upon the values that were used
   56.14 + * in the ROMBIOS and may need to be modified or calculated dynamically to
   56.15 + * correspond with what an HVM guest's CPUID returns.
   56.16 + *
   56.17 + * Travis Betak, travis.betak@amd.com
   56.18 + * Copyright (c) 2006, AMD.
   56.19 + *
   56.20 + * This program is free software; you can redistribute it and/or modify it
   56.21 + * under the terms and conditions of the GNU General Public License,
   56.22 + * version 2, as published by the Free Software Foundation.
   56.23 + *
   56.24 + * This program is distributed in the hope it will be useful, but WITHOUT
   56.25 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   56.26 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   56.27 + * more details.
   56.28 + *
   56.29 + * You should have received a copy of the GNU General Public License along with
   56.30 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   56.31 + * Place - Suite 330, Boston, MA 02111-1307 USA.
   56.32 + */
   56.33 +
   56.34 +
   56.35 +/* FIXME find a header that already has types defined!!! */
   56.36 +typedef unsigned char  uint8_t;
   56.37 +typedef   signed char  int8_t;
   56.38 +typedef unsigned short uint16_t;
   56.39 +typedef   signed short int16_t;
   56.40 +typedef unsigned int   uint32_t;
   56.41 +typedef   signed int   int32_t;
   56.42 +#ifdef __i386__
   56.43 +typedef unsigned long long uint64_t;
   56.44 +typedef   signed long long int64_t;
   56.45 +#else
   56.46 +typedef unsigned long uint64_t;
   56.47 +typedef   signed long int64_t;
   56.48 +#endif
   56.49 +
   56.50 +#define ROMBIOS_SEG              0xF000
   56.51 +#define ROMBIOS_BEGIN            0x000F0000
   56.52 +#define ROMBIOS_SIZE             0x00010000 
   56.53 +#define ROMBIOS_MAXOFFSET        0x0000FFFF
   56.54 +#define ROMBIOS_END             (ROMBIOS_BEGIN + ROMBIOS_SIZE)
   56.55 +
   56.56 +/* number of non-processor MP table entries */
   56.57 +#define NR_NONPROC_ENTRIES     18
   56.58 +
   56.59 +#define ENTRY_TYPE_PROCESSOR   0
   56.60 +#define ENTRY_TYPE_BUS         1
   56.61 +#define ENTRY_TYPE_IOAPIC      2
   56.62 +#define ENTRY_TYPE_IO_INTR     3
   56.63 +#define ENTRY_TYPE_LOCAL_INTR  4
   56.64 +
   56.65 +#define CPU_FLAG_ENABLED       0x01
   56.66 +#define CPU_FLAG_BSP           0x02
   56.67 +
   56.68 +/* TODO change this to correspond with what the guest's see's from CPUID */
   56.69 +#define CPU_SIG_FAMILY         0x06
   56.70 +#define CPU_SIG_MODEL          0x00
   56.71 +#define CPU_SIG_STEPPING       0x00
   56.72 +#define CPU_SIGNATURE        ((CPU_SIG_FAMILY << 8)  \
   56.73 +                             | (CPU_SIG_MODEL << 4)  \
   56.74 +                             | (CPU_SIG_STEPPING))
   56.75 +#define CPU_FEATURE_FPU       (1U << 0)
   56.76 +#define CPU_FEATURE_MCE       (1U << 7)
   56.77 +#define CPU_FEATURE_CX8       (1U << 8)
   56.78 +#define CPU_FEATURE_APIC      (1U << 9)
   56.79 +#define CPU_FEATURES          (CPU_FEATURE_FPU | CPU_FEATURE_APIC)
   56.80 +
   56.81 +#define BUS_TYPE_LENGTH        6
   56.82 +#define BUS_TYPE_STR_ISA       "ISA   "
   56.83 +
   56.84 +#define LAPIC_BASE_ADDR        0xFEE00000
   56.85 +
   56.86 +#define IOAPIC_VERSION         0x11
   56.87 +#define IOAPIC_BASE_ADDR       0xFEC00000
   56.88 +#define IOAPIC_FLAG_ENABLED   (1U << 0)
   56.89 +
   56.90 +#define INTR_TYPE_INT          0
   56.91 +#define INTR_TYPE_NMI          1
   56.92 +#define INTR_TYPE_SMI          2
   56.93 +#define INTR_TYPE_EXTINT       3
   56.94 +
   56.95 +#define INTR_FLAGS             0
   56.96 +
   56.97 +#define INTR_MAX_NR            16
   56.98 +
   56.99 +extern int puts(const char *); /* for printing */
  56.100 +extern int get_vcpu_nr(void);  /* for the guest's VCPU count */
  56.101 +
  56.102 +/*
  56.103 + * The following structures are defined in the MuliProcessor Specifiation v1.4
  56.104 + */
  56.105 +
  56.106 +/* MP Floating Pointer Structure */
  56.107 +struct mp_floating_pointer_struct {
  56.108 +	uint8_t signature[4];
  56.109 +	uint32_t mp_table;
  56.110 +	uint8_t length;
  56.111 +	uint8_t revision;
  56.112 +	uint8_t checksum;
  56.113 +	uint8_t feature[5];
  56.114 +};
  56.115 +
  56.116 +/* MP Configuration Table */
  56.117 +struct mp_config_table {
  56.118 +	uint8_t signature[4];
  56.119 +	uint16_t length;
  56.120 +	uint8_t revision;
  56.121 +	uint8_t checksum;
  56.122 +	uint8_t oem_id[8];
  56.123 +	uint8_t vendor_id[12];
  56.124 +	uint32_t oem_table;
  56.125 +	uint16_t oem_table_sz;
  56.126 +	uint16_t nr_entries;
  56.127 +	uint32_t lapic;
  56.128 +	uint16_t extended_length;
  56.129 +	uint8_t extended_checksum;
  56.130 +	uint8_t reserved;
  56.131 +};
  56.132 +
  56.133 +/* MP Processor Entry */
  56.134 +struct mp_proc_entry {
  56.135 +	uint8_t type;
  56.136 +	uint8_t lapic_id;
  56.137 +	uint8_t lapic_version;
  56.138 +	uint8_t cpu_flags;
  56.139 +	uint32_t cpu_signature;
  56.140 +	uint32_t feature_flags;
  56.141 +	uint8_t reserved[8];
  56.142 +};
  56.143 +
  56.144 +/* MP Bus Entry */
  56.145 +struct mp_bus_entry {
  56.146 +	uint8_t type;
  56.147 +	uint8_t bus_id;
  56.148 +	uint8_t bus_type_str[6];
  56.149 +};
  56.150 +
  56.151 +/* MP IOAPIC Entry */
  56.152 +struct mp_ioapic_entry {
  56.153 +	uint8_t type;
  56.154 +	uint8_t ioapic_id;
  56.155 +	uint8_t ioapic_version;
  56.156 +	uint8_t ioapic_flags;
  56.157 +	uint32_t ioapic_addr;
  56.158 +};
  56.159 +
  56.160 +/* MP IO Interrupt Entry */
  56.161 +struct mp_io_intr_entry {
  56.162 +	uint8_t type;
  56.163 +	uint8_t intr_type;
  56.164 +	uint16_t io_intr_flags;
  56.165 +	uint8_t src_bus_id;
  56.166 +	uint8_t src_bus_irq;
  56.167 +	uint8_t dst_ioapic_id;
  56.168 +	uint8_t dst_ioapic_intin;
  56.169 +};
  56.170 +
  56.171 +/* MP Local Interrupt Entry */
  56.172 +struct mp_local_intr_entry {
  56.173 +	uint8_t type;
  56.174 +	uint8_t intr_type;
  56.175 +	uint16_t local_intr_flags;
  56.176 +	uint8_t src_bus_id;
  56.177 +	uint8_t src_bus_irq;
  56.178 +	uint8_t dst_lapic_id;
  56.179 +	uint8_t dst_lapic_lintin;
  56.180 +};
  56.181 +
  56.182 +
  56.183 +/* 
  56.184 + * fill_mp_config_table - fills in the information for the MP config table
  56.185 + *    
  56.186 + * When calculating the length and nr_entries fields, keep in mind that there
  56.187 + * are always 18 non-processor entries and N processor entries
  56.188 + * 
  56.189 + *    N vcpu entries
  56.190 + *    1 bus entry 
  56.191 + *    1 IOAPIC entry 
  56.192 + * + 16 IO intr. entries
  56.193 + * ----------------------
  56.194 + * 18 + N total entries
  56.195 + */
  56.196 +void fill_mp_config_table(struct mp_config_table *mpct)
  56.197 +{
  56.198 +	int vcpu_nr;
  56.199 +
  56.200 +	vcpu_nr = get_vcpu_nr();
  56.201 +
  56.202 +	/* fill in the MP configuration table signature, "PCMP" */
  56.203 +	mpct->signature[0] = 'P';
  56.204 +	mpct->signature[1] = 'C';
  56.205 +	mpct->signature[2] = 'M';
  56.206 +	mpct->signature[3] = 'P';
  56.207 +
  56.208 +	mpct->length =    sizeof(struct mp_config_table)
  56.209 +			+ vcpu_nr * sizeof(struct mp_proc_entry)
  56.210 +			+ sizeof(struct mp_ioapic_entry)
  56.211 +			+ sizeof(struct mp_bus_entry)
  56.212 +			+ 16 * sizeof(struct mp_local_intr_entry);
  56.213 +
  56.214 +	mpct->revision = 4;
  56.215 +
  56.216 +	/* 
  56.217 +	 * We'll fill in the checksum later after all of the 
  56.218 +	 * entries have been created
  56.219 +	 */
  56.220 +	mpct->checksum = 0;
  56.221 +
  56.222 +	/* fill in the OEM ID string, "_HVMCPU_" */
  56.223 +	mpct->oem_id[0] = '_'; mpct->oem_id[3] = 'M'; mpct->oem_id[6] = 'U';
  56.224 +	mpct->oem_id[1] = 'H'; mpct->oem_id[4] = 'C'; mpct->oem_id[7] = '_';
  56.225 +	mpct->oem_id[2] = 'V'; mpct->oem_id[5] = 'P';
  56.226 +
  56.227 +	/* fill in the Vendor ID string, "XEN         " */
  56.228 +	mpct->vendor_id[0] = 'X'; mpct->vendor_id[6] =  ' ';
  56.229 +	mpct->vendor_id[1] = 'E'; mpct->vendor_id[7] =  ' ';
  56.230 +	mpct->vendor_id[2] = 'N'; mpct->vendor_id[8] =  ' ';
  56.231 +	mpct->vendor_id[3] = ' '; mpct->vendor_id[9] =  ' ';
  56.232 +	mpct->vendor_id[4] = ' '; mpct->vendor_id[10] = ' ';
  56.233 +	mpct->vendor_id[5] = ' '; mpct->vendor_id[11] = ' ';
  56.234 +
  56.235 +	mpct->oem_table = 0;
  56.236 +	mpct->oem_table_sz = 0;
  56.237 +
  56.238 +	mpct->nr_entries = vcpu_nr + NR_NONPROC_ENTRIES;
  56.239 +
  56.240 +	mpct->lapic = LAPIC_BASE_ADDR;
  56.241 +	mpct->extended_length = 0;
  56.242 +	mpct->extended_checksum = 0;
  56.243 +}
  56.244 +
  56.245 +
  56.246 +/* calculates the checksum for the MP configuration table */
  56.247 +void fill_mp_config_table_checksum(struct mp_config_table *mpct)
  56.248 +{
  56.249 +	int i;
  56.250 +	uint8_t checksum;
  56.251 +
  56.252 +	checksum = 0;
  56.253 +	for (i = 0; i < mpct->length; ++i)
  56.254 +		checksum += ((uint8_t *)(mpct))[i];
  56.255 +	mpct->checksum = -checksum;
  56.256 +}
  56.257 +
  56.258 +
  56.259 +/* fills in an MP processor entry for VCPU 'vcpu_id' */
  56.260 +void fill_mp_proc_entry(struct mp_proc_entry *mppe, int vcpu_id)
  56.261 +{
  56.262 +	mppe->type = ENTRY_TYPE_PROCESSOR;
  56.263 +	mppe->lapic_id = vcpu_id;
  56.264 +	mppe->lapic_version = 0x11;
  56.265 +	mppe->cpu_flags = CPU_FLAG_ENABLED;
  56.266 +	if (vcpu_id == 0)
  56.267 +		mppe->cpu_flags |= CPU_FLAG_BSP;
  56.268 +	mppe->cpu_signature = CPU_SIGNATURE;
  56.269 +	mppe->feature_flags = CPU_FEATURES;
  56.270 +}
  56.271 +
  56.272 +
  56.273 +/* fills in an MP bus entry of type 'type' and bus ID 'bus_id' */
  56.274 +void fill_mp_bus_entry(struct mp_bus_entry *mpbe, int bus_id, const char *type)
  56.275 +{
  56.276 +	int i;
  56.277 +
  56.278 +	mpbe->type = ENTRY_TYPE_BUS;
  56.279 +	mpbe->bus_id = bus_id;
  56.280 +	for (i = 0; i < BUS_TYPE_LENGTH; ++i)
  56.281 +		mpbe->bus_type_str[i] = type[i]; /* FIXME length check? */
  56.282 +}
  56.283 +
  56.284 +
  56.285 +/* fills in an MP IOAPIC entry for IOAPIC 'ioapic_id' */
  56.286 +void fill_mp_ioapic_entry(struct mp_ioapic_entry *mpie, int ioapic_id)
  56.287 +{
  56.288 +	mpie->type = ENTRY_TYPE_IOAPIC;
  56.289 +	mpie->ioapic_id = ioapic_id;
  56.290 +	mpie->ioapic_version = IOAPIC_VERSION;
  56.291 +	mpie->ioapic_flags = IOAPIC_FLAG_ENABLED;
  56.292 +	mpie->ioapic_addr = IOAPIC_BASE_ADDR;
  56.293 +}
  56.294 +
  56.295 +
  56.296 +/* fills in an IO interrupt entry for IOAPIC 'ioapic_id' */
  56.297 +void fill_mp_io_intr_entry(struct mp_io_intr_entry *mpiie,
  56.298 +		int src_bus_irq, int ioapic_id, int dst_ioapic_intin)
  56.299 +{
  56.300 +	mpiie->type = ENTRY_TYPE_IO_INTR;
  56.301 +	mpiie->intr_type = INTR_TYPE_INT;
  56.302 +	mpiie->io_intr_flags = INTR_FLAGS;
  56.303 +	mpiie->src_bus_id = 0;
  56.304 +	mpiie->src_bus_irq = src_bus_irq;
  56.305 +	mpiie->dst_ioapic_id = ioapic_id;
  56.306 +	mpiie->dst_ioapic_intin = dst_ioapic_intin;
  56.307 +}
  56.308 +
  56.309 +
  56.310 +/* fill in the mp floating processor structure */
  56.311 +void fill_mpfps(struct mp_floating_pointer_struct *mpfps, uint32_t mpct)
  56.312 +{
  56.313 +	int i;
  56.314 +	uint8_t checksum;
  56.315 +
  56.316 +
  56.317 +	mpfps->signature[0] = '_';
  56.318 +	mpfps->signature[1] = 'M';
  56.319 +	mpfps->signature[2] = 'P';
  56.320 +	mpfps->signature[3] = '_';
  56.321 +
  56.322 +	mpfps->mp_table = mpct; 
  56.323 +	mpfps->length = 1;
  56.324 +	mpfps->revision = 4;
  56.325 +	mpfps->checksum = 0;
  56.326 +	for (i = 0; i < 5; ++i)
  56.327 +		mpfps->feature[i] = 0;
  56.328 +
  56.329 +	/* compute the checksum for our new table */
  56.330 +	checksum = 0;
  56.331 +	for (i = 0; i < sizeof(struct mp_floating_pointer_struct); ++i)
  56.332 +		checksum += ((uint8_t *)(mpfps))[i];
  56.333 +	mpfps->checksum = -checksum;
  56.334 +}
  56.335 +
  56.336 +
  56.337 +/*
  56.338 + * find_mp_table_start - searchs through BIOS memory for '___HVMMP' signature
  56.339 + *
  56.340 + * The '___HVMMP' signature is created by the ROMBIOS and designates a chunk
  56.341 + * of space inside the ROMBIOS that is safe for us to write our MP table info
  56.342 + */
  56.343 +void* get_mp_table_start(void)
  56.344 +{
  56.345 +	char *bios_mem;
  56.346 +	for (bios_mem = (char *)ROMBIOS_BEGIN; 
  56.347 +	     bios_mem != (char *)ROMBIOS_END; 
  56.348 +	     ++bios_mem)
  56.349 +		if (bios_mem[0] == '_' && bios_mem[1] == '_' &&
  56.350 +		    bios_mem[2] == '_' && bios_mem[3] == 'H' &&
  56.351 +		    bios_mem[4] == 'V' && bios_mem[5] == 'M' &&
  56.352 +		    bios_mem[6] == 'M' && bios_mem[7] == 'P')
  56.353 +			return bios_mem;
  56.354 +
  56.355 +	return (void *)-1;
  56.356 +}
  56.357 +
  56.358 +
  56.359 +/* recalculate the new ROMBIOS checksum after adding MP tables */
  56.360 +void reset_bios_checksum(void)
  56.361 +{
  56.362 +	uint32_t i;
  56.363 +	uint8_t checksum;
  56.364 +
  56.365 +	checksum = 0;
  56.366 +	for (i = 0; i < ROMBIOS_MAXOFFSET; ++i)
  56.367 +		checksum += ((uint8_t *)(ROMBIOS_BEGIN))[i];
  56.368 +	
  56.369 +	*((uint8_t *)(ROMBIOS_BEGIN + ROMBIOS_MAXOFFSET)) = -checksum;
  56.370 +}
  56.371 +
  56.372 +
  56.373 +/* create_mp_tables - creates MP tables for the guest based upon config data */
  56.374 +void create_mp_tables(void)
  56.375 +{
  56.376 +	void *mp_table_base;
  56.377 +	char *p;
  56.378 +	struct mp_config_table *mp_config_table;
  56.379 +	int vcpu_nr;
  56.380 +	int i;
  56.381 +
  56.382 +	vcpu_nr = get_vcpu_nr();
  56.383 +	
  56.384 +	puts("Creating MP tables ...\n");
  56.385 +
  56.386 +	/* find the 'safe' place in ROMBIOS for the MP tables */
  56.387 +	mp_table_base = get_mp_table_start();
  56.388 +	if (mp_table_base == (void *)-1) {
  56.389 +		puts("Couldn't find start point for MP tables\n");
  56.390 +		return;
  56.391 +	}
  56.392 +	p = mp_table_base;
  56.393 +
  56.394 +	fill_mp_config_table((struct mp_config_table *)p);
  56.395 +
  56.396 + 	/* save the location of the MP config table for a little later*/
  56.397 +	mp_config_table = (struct mp_config_table *)p;
  56.398 +	p += sizeof(struct mp_config_table);
  56.399 +
  56.400 +	for (i = 0; i < vcpu_nr; ++i) {
  56.401 +		fill_mp_proc_entry((struct mp_proc_entry *)p, i);
  56.402 +		p += sizeof(struct mp_proc_entry);
  56.403 +	}
  56.404 +
  56.405 +	fill_mp_bus_entry((struct mp_bus_entry *)p, 0, BUS_TYPE_STR_ISA);
  56.406 +	p += sizeof(struct mp_bus_entry);
  56.407 +
  56.408 +	fill_mp_ioapic_entry((struct mp_ioapic_entry *)p, vcpu_nr);
  56.409 +	p += sizeof(struct mp_ioapic_entry);
  56.410 +
  56.411 +	for (i = 0; i < INTR_MAX_NR; ++i) {
  56.412 +		fill_mp_io_intr_entry((struct mp_io_intr_entry *)p, 
  56.413 +				i, vcpu_nr, i);
  56.414 +		p += sizeof(struct mp_io_intr_entry);
  56.415 +	}
  56.416 +
  56.417 +	/* find the next 16-byte boundary to place the mp floating pointer */
  56.418 +	while ((unsigned long)p & 0xF)
  56.419 +		++p;
  56.420 +	
  56.421 +	fill_mpfps((struct mp_floating_pointer_struct *)p, 
  56.422 +			(uint32_t)mp_table_base);
  56.423 +
  56.424 +	/* calculate the MP configuration table's checksum */
  56.425 +	fill_mp_config_table_checksum(mp_config_table);
  56.426 +
  56.427 +	/* finally, recalculate the ROMBIOS checksum */
  56.428 +	reset_bios_checksum();
  56.429 +}
    57.1 --- a/tools/firmware/rombios/Makefile	Wed Jul 05 10:23:54 2006 -0600
    57.2 +++ b/tools/firmware/rombios/Makefile	Wed Jul 05 20:11:37 2006 -0600
    57.3 @@ -1,13 +1,9 @@
    57.4 -BIOS_BUILDS = BIOS-bochs-latest
    57.5 -#BIOS_BUILDS += BIOS-bochs-2-processors
    57.6 -#BIOS_BUILDS += BIOS-bochs-4-processors
    57.7 -#BIOS_BUILDS += BIOS-bochs-8-processors
    57.8  
    57.9  .PHONY: all
   57.10  all: bios
   57.11  
   57.12  .PHONY: bios
   57.13 -bios: biossums ${BIOS_BUILDS}
   57.14 +bios: biossums BIOS-bochs-latest
   57.15  
   57.16  .PHONY: clean
   57.17  clean:
   57.18 @@ -26,36 +22,6 @@ BIOS-bochs-latest: rombios.c biossums
   57.19  	./biossums BIOS-bochs-latest
   57.20  	rm -f _rombios_.s
   57.21  
   57.22 -BIOS-bochs-2-processors: rombios.c biossums
   57.23 -	gcc -DBX_SMP_PROCESSORS=2 -E -P $< > _rombios2_.c
   57.24 -	bcc -o rombios2.s -C-c -D__i86__ -0 -S _rombios2_.c
   57.25 -	sed -e 's/^\.text//' -e 's/^\.data//' rombios2.s > _rombios2_.s
   57.26 -	as86 _rombios2_.s -b tmp2.bin -u- -w- -g -0 -j -O -l rombios2.txt
   57.27 -	-perl makesym.perl < rombios2.txt > rombios2.sym
   57.28 -	mv tmp2.bin BIOS-bochs-2-processors
   57.29 -	./biossums BIOS-bochs-2-processors
   57.30 -	rm -f _rombios2_.s
   57.31 -
   57.32 -BIOS-bochs-4-processors: rombios.c biossums
   57.33 -	gcc -DBX_SMP_PROCESSORS=4 -E -P $< > _rombios4_.c
   57.34 -	bcc -o rombios4.s -C-c -D__i86__ -0 -S _rombios4_.c
   57.35 -	sed -e 's/^\.text//' -e 's/^\.data//' rombios4.s > _rombios4_.s
   57.36 -	as86 _rombios4_.s -b tmp4.bin -u- -w- -g -0 -j -O -l rombios4.txt
   57.37 -	-perl makesym.perl < rombios4.txt > rombios4.sym
   57.38 -	mv tmp4.bin BIOS-bochs-4-processors
   57.39 -	./biossums BIOS-bochs-4-processors
   57.40 -	rm -f _rombios4_.s
   57.41 -
   57.42 -BIOS-bochs-8-processors: rombios.c biossums
   57.43 -	gcc -DBX_SMP_PROCESSORS=8 -E -P $< > _rombios8_.c
   57.44 -	bcc -o rombios8.s -C-c -D__i86__ -0 -S _rombios8_.c
   57.45 -	sed -e 's/^\.text//' -e 's/^\.data//' rombios8.s > _rombios8_.s
   57.46 -	as86 _rombios8_.s -b tmp8.bin -u- -w- -g -0 -j -O -l rombios8.txt
   57.47 -	-perl makesym.perl < rombios8.txt > rombios8.sym
   57.48 -	mv tmp8.bin BIOS-bochs-8-processors
   57.49 -	./biossums BIOS-bochs-8-processors
   57.50 -	rm -f _rombios8_.s
   57.51 -
   57.52  biossums: biossums.c
   57.53  	gcc -o biossums biossums.c
   57.54  
    58.1 --- a/tools/firmware/rombios/rombios.c	Wed Jul 05 10:23:54 2006 -0600
    58.2 +++ b/tools/firmware/rombios/rombios.c	Wed Jul 05 20:11:37 2006 -0600
    58.3 @@ -10514,6 +10514,34 @@ static Bit8u vgafont8[128*8]=
    58.4   0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00,
    58.5  };
    58.6  
    58.7 +#ifdef HVMASSIST
    58.8 +//
    58.9 +// MP Tables
   58.10 +// just carve out some blank space for HVMLOADER to write the MP tables to
   58.11 +//
   58.12 +// NOTE: There should be enough space for a 32 processor entry MP table
   58.13 +//
   58.14 +ASM_START
   58.15 +.org 0xcc00
   58.16 +db 0x5F, 0x5F, 0x5F, 0x48, 0x56, 0x4D, 0x4D, 0x50 ;; ___HVMMP
   58.17 +dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;;  64 bytes
   58.18 +dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 128 bytes
   58.19 +dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 192 bytes
   58.20 +dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 256 bytes
   58.21 +dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 320 bytes
   58.22 +dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 384 bytes
   58.23 +dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 448 bytes
   58.24 +dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 512 bytes
   58.25 +dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 576 bytes
   58.26 +dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 640 bytes
   58.27 +dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 704 bytes
   58.28 +dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 768 bytes
   58.29 +dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 832 bytes
   58.30 +dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 896 bytes
   58.31 +ASM_END
   58.32 +
   58.33 +#else // !HVMASSIST
   58.34 +
   58.35  ASM_START
   58.36  .org 0xcc00
   58.37  // bcc-generated data will be placed here
   58.38 @@ -10835,3 +10863,5 @@ db 0,0,0,0     ;; MP feature bytes 2-5.
   58.39  #endif
   58.40  
   58.41  ASM_END
   58.42 +
   58.43 +#endif // HVMASSIST
    59.1 --- a/tools/ioemu/hw/piix4acpi.c	Wed Jul 05 10:23:54 2006 -0600
    59.2 +++ b/tools/ioemu/hw/piix4acpi.c	Wed Jul 05 20:11:37 2006 -0600
    59.3 @@ -476,6 +476,6 @@ void pci_piix4_acpi_init(PCIBus *bus)
    59.4  
    59.5      pci_register_io_region((PCIDevice *)d, 4, 0x10,
    59.6                             PCI_ADDRESS_SPACE_IO, acpi_map);
    59.7 -    pmtimer_state = pmtimer_init();
    59.8 +    /*pmtimer_state = pmtimer_init();*/
    59.9      acpi_reset (d);
   59.10  }
    60.1 --- a/tools/libxc/xc_hvm_build.c	Wed Jul 05 10:23:54 2006 -0600
    60.2 +++ b/tools/libxc/xc_hvm_build.c	Wed Jul 05 20:11:37 2006 -0600
    60.3 @@ -4,6 +4,7 @@
    60.4  
    60.5  #define ELFSIZE 32
    60.6  #include <stddef.h>
    60.7 +#include <inttypes.h>
    60.8  #include "xg_private.h"
    60.9  #include "xc_elf.h"
   60.10  #include <stdlib.h>
   60.11 @@ -188,7 +189,7 @@ static int setup_guest(int xc_handle,
   60.12      unsigned char e820_map_nr;
   60.13  
   60.14      struct domain_setup_info dsi;
   60.15 -    unsigned long long v_end;
   60.16 +    uint64_t v_end;
   60.17  
   60.18      unsigned long shared_page_frame = 0;
   60.19      shared_iopage_t *sp;
   60.20 @@ -208,11 +209,11 @@ static int setup_guest(int xc_handle,
   60.21      v_end = (unsigned long long)memsize << 20;
   60.22  
   60.23      IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"
   60.24 -           "  Loaded HVM loader:    %08lx->%08lx\n"
   60.25 -           "  TOTAL:                %08lx->%016llx\n",
   60.26 +           "  Loaded HVM loader:    %016"PRIx64"->%016"PRIx64"\n"
   60.27 +           "  TOTAL:                %016"PRIx64"->%016"PRIx64"\n",
   60.28             dsi.v_kernstart, dsi.v_kernend,
   60.29             dsi.v_start, v_end);
   60.30 -    IPRINTF("  ENTRY ADDRESS:        %08lx\n", dsi.v_kernentry);
   60.31 +    IPRINTF("  ENTRY ADDRESS:        %016"PRIx64"\n", dsi.v_kernentry);
   60.32  
   60.33      if ( (v_end - dsi.v_start) > ((unsigned long long)nr_pages << PAGE_SHIFT) )
   60.34      {
    61.1 --- a/tools/libxc/xc_linux_build.c	Wed Jul 05 10:23:54 2006 -0600
    61.2 +++ b/tools/libxc/xc_linux_build.c	Wed Jul 05 20:11:37 2006 -0600
    61.3 @@ -13,6 +13,9 @@
    61.4  #include <inttypes.h>
    61.5  #include <zlib.h>
    61.6  
    61.7 +/* Handy for printing out '0' prepended values at native pointer size */
    61.8 +#define _p(a) ((void *) ((ulong)a))
    61.9 +
   61.10  #if defined(__i386__)
   61.11  #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
   61.12  #define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
   61.13 @@ -519,8 +522,6 @@ static int setup_guest(int xc_handle,
   61.14          goto error_out;
   61.15      }
   61.16  
   61.17 -#define _p(a) ((void *) (a))
   61.18 -
   61.19      IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"
   61.20             " Loaded kernel: %p->%p\n"
   61.21             " Init. ramdisk: %p->%p\n"
   61.22 @@ -795,9 +796,9 @@ static int setup_guest(int xc_handle,
   61.23                  goto error_out;
   61.24          }
   61.25  
   61.26 -#define NR(_l,_h,_s) \
   61.27 -    (((((_h) + ((1UL<<(_s))-1)) & ~((1UL<<(_s))-1)) - \
   61.28 -    ((_l) & ~((1UL<<(_s))-1))) >> (_s))
   61.29 +#define NR(_l,_h,_s)                                                    \
   61.30 +    (((((unsigned long)(_h) + ((1UL<<(_s))-1)) & ~((1UL<<(_s))-1)) -    \
   61.31 +    ((unsigned long)(_l) & ~((1UL<<(_s))-1))) >> (_s))
   61.32  #if defined(__i386__)
   61.33          if ( dsi.pae_kernel != PAEKERN_no )
   61.34          {
   61.35 @@ -826,8 +827,6 @@ static int setup_guest(int xc_handle,
   61.36  #endif
   61.37      }
   61.38  
   61.39 -#define _p(a) ((void *) (a))
   61.40 -
   61.41      IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n");
   61.42      IPRINTF(" Loaded kernel:    %p->%p\n", _p(dsi.v_kernstart),
   61.43             _p(dsi.v_kernend));
   61.44 @@ -848,8 +847,8 @@ static int setup_guest(int xc_handle,
   61.45      if ( ((v_end - dsi.v_start)>>PAGE_SHIFT) > nr_pages )
   61.46      {
   61.47          PERROR("Initial guest OS requires too much space\n"
   61.48 -               "(%luMB is greater than %luMB limit)\n",
   61.49 -               (v_end-dsi.v_start)>>20, nr_pages>>(20-PAGE_SHIFT));
   61.50 +               "(%pMB is greater than %luMB limit)\n",
   61.51 +               _p((v_end-dsi.v_start)>>20), nr_pages>>(20-PAGE_SHIFT));
   61.52          goto error_out;
   61.53      }
   61.54  
   61.55 @@ -1083,7 +1082,8 @@ static int setup_guest(int xc_handle,
   61.56          if ( hypercall_pfn >= nr_pages )
   61.57              goto error_out;
   61.58          op.u.hypercall_init.domain = (domid_t)dom;
   61.59 -        op.u.hypercall_init.mfn    = page_array[hypercall_pfn];
   61.60 +        op.u.hypercall_init.gmfn   = shadow_mode_enabled ?
   61.61 +            hypercall_pfn : page_array[hypercall_pfn];
   61.62          op.cmd = DOM0_HYPERCALL_INIT;
   61.63          if ( xc_dom0_op(xc_handle, &op) )
   61.64              goto error_out;
    62.1 --- a/tools/libxc/xc_linux_save.c	Wed Jul 05 10:23:54 2006 -0600
    62.2 +++ b/tools/libxc/xc_linux_save.c	Wed Jul 05 20:11:37 2006 -0600
    62.3 @@ -415,11 +415,11 @@ static int suspend_and_state(int (*suspe
    62.4  ** which entries do not require canonicalization (in particular, those
    62.5  ** entries which map the virtual address reserved for the hypervisor).
    62.6  */
    62.7 -void canonicalize_pagetable(unsigned long type, unsigned long pfn,
    62.8 -                             const void *spage, void *dpage)
    62.9 +int canonicalize_pagetable(unsigned long type, unsigned long pfn,
   62.10 +                           const void *spage, void *dpage)
   62.11  {
   62.12  
   62.13 -    int i, pte_last, xen_start, xen_end;
   62.14 +    int i, pte_last, xen_start, xen_end, race = 0; 
   62.15      uint64_t pte;
   62.16  
   62.17      /*
   62.18 @@ -481,7 +481,8 @@ void canonicalize_pagetable(unsigned lon
   62.19                     is quite feasible under live migration */
   62.20                  DPRINTF("PT Race: [%08lx,%d] pte=%llx, mfn=%08lx\n",
   62.21                          type, i, (unsigned long long)pte, mfn);
   62.22 -                pfn = 0; /* zap it - we'll retransmit this page later */
   62.23 +                pfn  = 0;  /* zap it - we'll retransmit this page later */
   62.24 +                race = 1;  /* inform the caller of race; fatal if !live */ 
   62.25              } else
   62.26                  pfn = mfn_to_pfn(mfn);
   62.27  
   62.28 @@ -496,7 +497,7 @@ void canonicalize_pagetable(unsigned lon
   62.29  
   62.30      }
   62.31  
   62.32 -    return;
   62.33 +    return race; 
   62.34  }
   62.35  
   62.36  
   62.37 @@ -567,7 +568,7 @@ int xc_linux_save(int xc_handle, int io_
   62.38      int rc = 1, i, j, last_iter, iter = 0;
   62.39      int live  = (flags & XCFLAGS_LIVE);
   62.40      int debug = (flags & XCFLAGS_DEBUG);
   62.41 -    int sent_last_iter, skip_this_iter;
   62.42 +    int race = 0, sent_last_iter, skip_this_iter;
   62.43  
   62.44      /* The new domain's shared-info frame number. */
   62.45      unsigned long shared_info_frame;
   62.46 @@ -1000,7 +1001,11 @@ int xc_linux_save(int xc_handle, int io_
   62.47                  if (pagetype >= L1TAB && pagetype <= L4TAB) {
   62.48  
   62.49                      /* We have a pagetable page: need to rewrite it. */
   62.50 -                    canonicalize_pagetable(pagetype, pfn, spage, page);
   62.51 +                    race = 
   62.52 +                        canonicalize_pagetable(pagetype, pfn, spage, page); 
   62.53 +
   62.54 +                    if(race && !live) 
   62.55 +                        goto out; 
   62.56  
   62.57                      if (ratewrite(io_fd, page, PAGE_SIZE) != PAGE_SIZE) {
   62.58                          ERR("Error when writing to state file (4)");
    63.1 --- a/tools/libxc/xc_load_elf.c	Wed Jul 05 10:23:54 2006 -0600
    63.2 +++ b/tools/libxc/xc_load_elf.c	Wed Jul 05 20:11:37 2006 -0600
    63.3 @@ -68,7 +68,7 @@ static int parseelfimage(const char *ima
    63.4      Elf_Ehdr *ehdr = (Elf_Ehdr *)image;
    63.5      Elf_Phdr *phdr;
    63.6      Elf_Shdr *shdr;
    63.7 -    unsigned long kernstart = ~0UL, kernend=0UL, vaddr, virt_base, elf_pa_off;
    63.8 +    Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_base, elf_pa_off;
    63.9      const char *shstrtab;
   63.10      char *guestinfo=NULL, *p;
   63.11      int h, virt_base_defined, elf_pa_off_defined;
   63.12 @@ -162,15 +162,19 @@ static int parseelfimage(const char *ima
   63.13      /* Initial guess for virt_base is 0 if it is not explicitly defined. */
   63.14      p = strstr(guestinfo, "VIRT_BASE=");
   63.15      virt_base_defined = (p != NULL);
   63.16 -    virt_base = virt_base_defined ? strtoul(p+10, &p, 0) : 0;
   63.17 +    virt_base = virt_base_defined ? strtoull(p+10, &p, 0) : 0;
   63.18  
   63.19      /* Initial guess for elf_pa_off is virt_base if not explicitly defined. */
   63.20      p = strstr(guestinfo, "ELF_PADDR_OFFSET=");
   63.21      elf_pa_off_defined = (p != NULL);
   63.22 -    elf_pa_off = elf_pa_off_defined ? strtoul(p+17, &p, 0) : virt_base;
   63.23 +    elf_pa_off = elf_pa_off_defined ? strtoull(p+17, &p, 0) : virt_base;
   63.24  
   63.25      if ( elf_pa_off_defined && !virt_base_defined )
   63.26 -        goto bad_image;
   63.27 +    {
   63.28 +        ERROR("Neither ELF_PADDR_OFFSET nor VIRT_BASE found in __xen_guest"
   63.29 +              " section.");
   63.30 +        return -EINVAL;
   63.31 +    }
   63.32  
   63.33      for ( h = 0; h < ehdr->e_phnum; h++ )
   63.34      {
   63.35 @@ -179,7 +183,11 @@ static int parseelfimage(const char *ima
   63.36              continue;
   63.37          vaddr = phdr->p_paddr - elf_pa_off + virt_base;
   63.38          if ( (vaddr + phdr->p_memsz) < vaddr )
   63.39 -            goto bad_image;
   63.40 +        {
   63.41 +            ERROR("ELF program header %d is too large.", h);
   63.42 +            return -EINVAL;
   63.43 +        }
   63.44 +
   63.45          if ( vaddr < kernstart )
   63.46              kernstart = vaddr;
   63.47          if ( (vaddr + phdr->p_memsz) > kernend )
   63.48 @@ -196,13 +204,16 @@ static int parseelfimage(const char *ima
   63.49  
   63.50      dsi->v_kernentry = ehdr->e_entry;
   63.51      if ( (p = strstr(guestinfo, "VIRT_ENTRY=")) != NULL )
   63.52 -        dsi->v_kernentry = strtoul(p+11, &p, 0);
   63.53 +        dsi->v_kernentry = strtoull(p+11, &p, 0);
   63.54  
   63.55      if ( (kernstart > kernend) ||
   63.56           (dsi->v_kernentry < kernstart) ||
   63.57           (dsi->v_kernentry > kernend) ||
   63.58           (dsi->v_start > kernstart) )
   63.59 -        goto bad_image;
   63.60 +    {
   63.61 +        ERROR("ELF start or entries are out of bounds.");
   63.62 +        return -EINVAL;
   63.63 +    }
   63.64  
   63.65      if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL )
   63.66          dsi->load_symtab = 1;
   63.67 @@ -214,10 +225,6 @@ static int parseelfimage(const char *ima
   63.68      loadelfsymtab(image, 0, 0, NULL, dsi);
   63.69  
   63.70      return 0;
   63.71 -
   63.72 - bad_image:
   63.73 -    ERROR("Malformed ELF image.");
   63.74 -    return -EINVAL;
   63.75  }
   63.76  
   63.77  static int
    64.1 --- a/tools/libxc/xc_private.c	Wed Jul 05 10:23:54 2006 -0600
    64.2 +++ b/tools/libxc/xc_private.c	Wed Jul 05 20:11:37 2006 -0600
    64.3 @@ -26,7 +26,7 @@ unsigned int get_pfn_type(int xc_handle,
    64.4  {
    64.5      DECLARE_DOM0_OP;
    64.6      op.cmd = DOM0_GETPAGEFRAMEINFO;
    64.7 -    op.u.getpageframeinfo.mfn    = mfn;
    64.8 +    op.u.getpageframeinfo.gmfn   = mfn;
    64.9      op.u.getpageframeinfo.domain = (domid_t)dom;
   64.10      if ( do_dom0_op(xc_handle, &op) < 0 )
   64.11      {
    65.1 --- a/tools/libxc/xg_private.h	Wed Jul 05 10:23:54 2006 -0600
    65.2 +++ b/tools/libxc/xg_private.h	Wed Jul 05 20:11:37 2006 -0600
    65.3 @@ -132,13 +132,13 @@ typedef unsigned long l4_pgentry_t;
    65.4  
    65.5  struct domain_setup_info
    65.6  {
    65.7 -    unsigned long v_start;
    65.8 -    unsigned long v_end;
    65.9 -    unsigned long v_kernstart;
   65.10 -    unsigned long v_kernend;
   65.11 -    unsigned long v_kernentry;
   65.12 +    uint64_t v_start;
   65.13 +    uint64_t v_end;
   65.14 +    uint64_t v_kernstart;
   65.15 +    uint64_t v_kernend;
   65.16 +    uint64_t v_kernentry;
   65.17  
   65.18 -    unsigned long elf_paddr_offset;
   65.19 +    uint64_t elf_paddr_offset;
   65.20  
   65.21  #define PAEKERN_no           0
   65.22  #define PAEKERN_yes          1
    66.1 --- a/tools/python/xen/xend/XendLogging.py	Wed Jul 05 10:23:54 2006 -0600
    66.2 +++ b/tools/python/xen/xend/XendLogging.py	Wed Jul 05 20:11:37 2006 -0600
    66.3 @@ -43,7 +43,7 @@ MAX_BYTES = 1 << 20  # 1MB
    66.4  BACKUP_COUNT = 5
    66.5  
    66.6  STDERR_FORMAT = "[%(name)s] %(levelname)s (%(module)s:%(lineno)d) %(message)s"
    66.7 -LOGFILE_FORMAT = "[%(asctime)s %(name)s] %(levelname)s (%(module)s:%(lineno)d) %(message)s"
    66.8 +LOGFILE_FORMAT = "[%(asctime)s %(name)s %(process)d] %(levelname)s (%(module)s:%(lineno)d) %(message)s"
    66.9  DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
   66.10  
   66.11  
    67.1 --- a/tools/python/xen/xm/cfgbootpolicy.py	Wed Jul 05 10:23:54 2006 -0600
    67.2 +++ b/tools/python/xen/xm/cfgbootpolicy.py	Wed Jul 05 20:11:37 2006 -0600
    67.3 @@ -22,8 +22,6 @@ import sys
    67.4  import traceback
    67.5  import tempfile
    67.6  import os, stat
    67.7 -import re
    67.8 -import commands
    67.9  import shutil
   67.10  import string
   67.11  from xen.util.security import ACMError, err
    68.1 --- a/tools/python/xen/xm/create.py	Wed Jul 05 10:23:54 2006 -0600
    68.2 +++ b/tools/python/xen/xm/create.py	Wed Jul 05 20:11:37 2006 -0600
    68.3 @@ -21,11 +21,8 @@
    68.4  """
    68.5  import os
    68.6  import os.path
    68.7 -import string
    68.8  import sys
    68.9  import socket
   68.10 -import commands
   68.11 -import time
   68.12  import re
   68.13  import xmlrpclib
   68.14  
    69.1 --- a/tools/python/xen/xm/dumppolicy.py	Wed Jul 05 10:23:54 2006 -0600
    69.2 +++ b/tools/python/xen/xm/dumppolicy.py	Wed Jul 05 20:11:37 2006 -0600
    69.3 @@ -19,10 +19,6 @@
    69.4  """
    69.5  import sys
    69.6  import traceback
    69.7 -import os
    69.8 -import commands
    69.9 -import shutil
   69.10 -import string
   69.11  from xen.util.security import ACMError, err, dump_policy
   69.12  
   69.13  
    70.1 --- a/tools/python/xen/xm/labels.py	Wed Jul 05 10:23:54 2006 -0600
    70.2 +++ b/tools/python/xen/xm/labels.py	Wed Jul 05 20:11:37 2006 -0600
    70.3 @@ -20,9 +20,6 @@
    70.4  """
    70.5  import sys
    70.6  import traceback
    70.7 -import os
    70.8 -import commands
    70.9 -import shutil
   70.10  import string
   70.11  from xen.util.security import ACMError, err, list_labels, active_policy
   70.12  from xen.util.security import vm_label_re, res_label_re, all_label_re
    71.1 --- a/tools/python/xen/xm/loadpolicy.py	Wed Jul 05 10:23:54 2006 -0600
    71.2 +++ b/tools/python/xen/xm/loadpolicy.py	Wed Jul 05 20:11:37 2006 -0600
    71.3 @@ -20,10 +20,6 @@
    71.4  """
    71.5  import sys
    71.6  import traceback
    71.7 -import os
    71.8 -import commands
    71.9 -import shutil
   71.10 -import string
   71.11  from xen.util.security import ACMError, err, load_policy
   71.12  
   71.13  
    72.1 --- a/tools/python/xen/xm/main.py	Wed Jul 05 10:23:54 2006 -0600
    72.2 +++ b/tools/python/xen/xm/main.py	Wed Jul 05 20:11:37 2006 -0600
    72.3 @@ -556,7 +556,7 @@ def xm_vcpu_list(args):
    72.4  
    72.5  
    72.6  def xm_reboot(args):
    72.7 -    arg_check(args, "reboot", 1, 4)
    72.8 +    arg_check(args, "reboot", 1, 3)
    72.9      from xen.xm import shutdown
   72.10      shutdown.main(["shutdown", "-R"] + args)
   72.11  
    73.1 --- a/tools/python/xen/xm/makepolicy.py	Wed Jul 05 10:23:54 2006 -0600
    73.2 +++ b/tools/python/xen/xm/makepolicy.py	Wed Jul 05 20:11:37 2006 -0600
    73.3 @@ -19,10 +19,6 @@
    73.4  """
    73.5  import sys
    73.6  import traceback
    73.7 -import os
    73.8 -import commands
    73.9 -import shutil
   73.10 -import string
   73.11  from xen.util.security import ACMError, err, make_policy
   73.12  
   73.13  
    74.1 --- a/tools/python/xen/xm/shutdown.py	Wed Jul 05 10:23:54 2006 -0600
    74.2 +++ b/tools/python/xen/xm/shutdown.py	Wed Jul 05 20:11:37 2006 -0600
    74.3 @@ -17,8 +17,6 @@
    74.4  
    74.5  """Domain shutdown.
    74.6  """
    74.7 -import string
    74.8 -import sys
    74.9  import time
   74.10  
   74.11  from xen.xend.XendClient import server
   74.12 @@ -92,7 +90,8 @@ def main_all(opts, args):
   74.13      shutdown(opts, None, mode, opts.vals.wait)
   74.14  
   74.15  def main_dom(opts, args):
   74.16 -    if len(args) < 1: opts.err('Missing domain')
   74.17 +    if len(args) == 0: opts.err('No domain parameter given')
   74.18 +    if len(args) >  1: opts.err('No multiple domain parameters allowed')
   74.19      dom = args[0]
   74.20      mode = shutdown_mode(opts)  
   74.21      shutdown(opts, [ dom ], mode, opts.vals.wait)
    75.1 --- a/tools/xenmon/xenmon.py	Wed Jul 05 10:23:54 2006 -0600
    75.2 +++ b/tools/xenmon/xenmon.py	Wed Jul 05 20:11:37 2006 -0600
    75.3 @@ -36,6 +36,7 @@ import sys
    75.4  # constants
    75.5  NSAMPLES = 100
    75.6  NDOMAINS = 32
    75.7 +IDLE_DOMAIN = 31 # idle domain's ID
    75.8  
    75.9  # the struct strings for qos_info
   75.10  ST_DOM_INFO = "6Q4i32s"
   75.11 @@ -253,6 +254,14 @@ def display(scr, row, col, str, attr=0):
   75.12          sys.exit(1)
   75.13  
   75.14  
   75.15 +# diplay domain id
   75.16 +def display_domain_id(scr, row, col, dom):
   75.17 +    if dom == IDLE_DOMAIN:
   75.18 +        display(scr, row, col-1, "Idle")
   75.19 +    else:
   75.20 +        display(scr, row, col, "%d" % dom)
   75.21 +
   75.22 +
   75.23  # the live monitoring code
   75.24  def show_livestats(cpu):
   75.25      ncpu = 1         # number of cpu's on this platform
   75.26 @@ -361,7 +370,7 @@ def show_livestats(cpu):
   75.27                  # display gotten
   75.28                  row += 1 
   75.29                  col = 2
   75.30 -                display(stdscr, row, col, "%d" % dom)
   75.31 +                display_domain_id(stdscr, row, col, dom)
   75.32                  col += 4
   75.33                  display(stdscr, row, col, "%s" % time_scale(h2[dom][0][0]))
   75.34                  col += 12
   75.35 @@ -386,7 +395,7 @@ def show_livestats(cpu):
   75.36                  if options.allocated:
   75.37                      row += 1
   75.38                      col = 2
   75.39 -                    display(stdscr, row, col, "%d" % dom)
   75.40 +                    display_domain_id(stdscr, row, col, dom)
   75.41                      col += 28
   75.42                      display(stdscr, row, col, "%s/ex" % time_scale(h2[dom][1]))
   75.43                      col += 42
   75.44 @@ -398,7 +407,7 @@ def show_livestats(cpu):
   75.45                  if options.blocked:
   75.46                      row += 1
   75.47                      col = 2
   75.48 -                    display(stdscr, row, col, "%d" % dom)
   75.49 +                    display_domain_id(stdscr, row, col, dom)
   75.50                      col += 4
   75.51                      display(stdscr, row, col, "%s" % time_scale(h2[dom][2][0]))
   75.52                      col += 12
   75.53 @@ -418,7 +427,7 @@ def show_livestats(cpu):
   75.54                  if options.waited:
   75.55                      row += 1
   75.56                      col = 2
   75.57 -                    display(stdscr, row, col, "%d" % dom)
   75.58 +                    display_domain_id(stdscr, row, col, dom)
   75.59                      col += 4
   75.60                      display(stdscr, row, col, "%s" % time_scale(h2[dom][3][0]))
   75.61                      col += 12
   75.62 @@ -438,7 +447,7 @@ def show_livestats(cpu):
   75.63                  if options.excount:
   75.64                      row += 1
   75.65                      col = 2
   75.66 -                    display(stdscr, row, col, "%d" % dom)
   75.67 +                    display_domain_id(stdscr, row, col, dom)
   75.68                      
   75.69                      col += 28
   75.70                      display(stdscr, row, col, "%d/s" % h2[dom][4])
   75.71 @@ -451,7 +460,7 @@ def show_livestats(cpu):
   75.72                  if options.iocount:
   75.73                      row += 1
   75.74                      col = 2
   75.75 -                    display(stdscr, row, col, "%d" % dom)
   75.76 +                    display_domain_id(stdscr, row, col, dom)
   75.77                      col += 4
   75.78                      display(stdscr, row, col, "%d/s" % h2[dom][5][0])
   75.79                      col += 24
   75.80 @@ -558,7 +567,10 @@ def writelog():
   75.81      curr = last = time.time()
   75.82      outfiles = {}
   75.83      for dom in range(0, NDOMAINS):
   75.84 -        outfiles[dom] = Delayed("%s-dom%d.log" % (options.prefix, dom), 'w')
   75.85 +        if dom == IDLE_DOMAIN:
   75.86 +            outfiles[dom] = Delayed("%s-idle.log" % options.prefix, 'w')
   75.87 +        else:
   75.88 +            outfiles[dom] = Delayed("%s-dom%d.log" % (options.prefix, dom), 'w')
   75.89          outfiles[dom].delayed_write("# passed cpu dom cpu(tot) cpu(%) cpu/ex allocated/ex blocked(tot) blocked(%) blocked/io waited(tot) waited(%) waited/ex ex/s io(tot) io/ex\n")
   75.90  
   75.91      while options.duration == 0 or interval < (options.duration * 1000):
    76.1 --- a/tools/xenstat/libxenstat/src/xenstat.c	Wed Jul 05 10:23:54 2006 -0600
    76.2 +++ b/tools/xenstat/libxenstat/src/xenstat.c	Wed Jul 05 20:11:37 2006 -0600
    76.3 @@ -20,6 +20,11 @@
    76.4  #include <stdio.h>
    76.5  #include <string.h>
    76.6  #include <unistd.h>
    76.7 +#include <linux/compiler.h>
    76.8 +#include <fcntl.h>
    76.9 +#include <dirent.h>
   76.10 +#include <sys/types.h>
   76.11 +#include <sys/stat.h>
   76.12  #include <xs.h>
   76.13  #include "xenstat.h"
   76.14  
   76.15 @@ -36,6 +41,7 @@ struct xenstat_handle {
   76.16  	struct xs_handle *xshandle; /* xenstore handle */
   76.17  	int page_size;
   76.18  	FILE *procnetdev;
   76.19 +	DIR *sysfsvbd;
   76.20  	char xen_version[VERSION_SIZE]; /* xen version running on this node */
   76.21  };
   76.22  
   76.23 @@ -62,6 +68,8 @@ struct xenstat_domain {
   76.24  	unsigned int ssid;
   76.25  	unsigned int num_networks;
   76.26  	xenstat_network *networks;	/* Array of length num_networks */
   76.27 +	unsigned int num_vbds;
   76.28 +	xenstat_vbd *vbds;
   76.29  };
   76.30  
   76.31  struct xenstat_vcpu {
   76.32 @@ -83,6 +91,15 @@ struct xenstat_network {
   76.33  	unsigned long long tdrop;
   76.34  };
   76.35  
   76.36 +struct xenstat_vbd {
   76.37 +       unsigned int dev;
   76.38 +       unsigned long long oo_reqs;
   76.39 +       unsigned long long rd_reqs;
   76.40 +       unsigned long long wr_reqs;
   76.41 +};
   76.42 +#define SYSFS_VBD_PATH "/sys/devices/xen-backend/"
   76.43 +
   76.44 +
   76.45  /*
   76.46   * Data-collection types
   76.47   */
   76.48 @@ -108,12 +125,15 @@ typedef struct xenstat_collector {
   76.49  static int  xenstat_collect_vcpus(xenstat_node * node);
   76.50  static int  xenstat_collect_networks(xenstat_node * node);
   76.51  static int  xenstat_collect_xen_version(xenstat_node * node);
   76.52 +static int  xenstat_collect_vbds(xenstat_node * node);
   76.53  static void xenstat_free_vcpus(xenstat_node * node);
   76.54  static void xenstat_free_networks(xenstat_node * node);
   76.55  static void xenstat_free_xen_version(xenstat_node * node);
   76.56 +static void xenstat_free_vbds(xenstat_node * node);
   76.57  static void xenstat_uninit_vcpus(xenstat_handle * handle);
   76.58  static void xenstat_uninit_networks(xenstat_handle * handle);
   76.59  static void xenstat_uninit_xen_version(xenstat_handle * handle);
   76.60 +static void xenstat_uninit_vbds(xenstat_handle * handle);
   76.61  static char *xenstat_get_domain_name(xenstat_handle * handle, unsigned int domain_id);
   76.62  
   76.63  static xenstat_collector collectors[] = {
   76.64 @@ -122,7 +142,9 @@ static xenstat_collector collectors[] = 
   76.65  	{ XENSTAT_NETWORK, xenstat_collect_networks,
   76.66  	  xenstat_free_networks, xenstat_uninit_networks },
   76.67  	{ XENSTAT_XEN_VERSION, xenstat_collect_xen_version,
   76.68 -	  xenstat_free_xen_version, xenstat_uninit_xen_version }
   76.69 +	  xenstat_free_xen_version, xenstat_uninit_xen_version },
   76.70 +	{ XENSTAT_VBD, xenstat_collect_vbds,
   76.71 +	  xenstat_free_vbds, xenstat_uninit_vbds }
   76.72  };
   76.73  
   76.74  #define NUM_COLLECTORS (sizeof(collectors)/sizeof(xenstat_collector))
   76.75 @@ -259,6 +281,8 @@ xenstat_node *xenstat_get_node(xenstat_h
   76.76  			domain->ssid = domaininfo[i].ssidref;
   76.77  			domain->num_networks = 0;
   76.78  			domain->networks = NULL;
   76.79 +			domain->num_vbds = 0;
   76.80 +			domain->vbds = NULL;
   76.81  
   76.82  			domain++;
   76.83  		}
   76.84 @@ -451,6 +475,21 @@ xenstat_network *xenstat_domain_network(
   76.85  	return NULL;
   76.86  }
   76.87  
   76.88 +/* Get the number of VBDs for a given domain */
   76.89 +unsigned int xenstat_domain_num_vbds(xenstat_domain * domain)
   76.90 +{
   76.91 +	return domain->num_vbds;
   76.92 +}
   76.93 +
   76.94 +/* Get the VBD handle to obtain VBD stats */
   76.95 +xenstat_vbd *xenstat_domain_vbd(xenstat_domain * domain,
   76.96 +				unsigned int vbd)
   76.97 +{
   76.98 +	if (domain->vbds && 0 <= vbd && vbd < domain->num_vbds)
   76.99 +		return &(domain->vbds[vbd]);
  76.100 +	return NULL;
  76.101 +}
  76.102 +
  76.103  /*
  76.104   * VCPU functions
  76.105   */
  76.106 @@ -710,6 +749,139 @@ static void xenstat_uninit_xen_version(x
  76.107  {
  76.108  }
  76.109  
  76.110 +/*
  76.111 + * VBD functions
  76.112 + */
  76.113 +
  76.114 +static int read_attributes_vbd(const char *vbd_directory, const char *what, char *ret, int cap)
  76.115 +{
  76.116 +	static char file_name[80];
  76.117 +	int fd, num_read;
  76.118 +
  76.119 +	sprintf(file_name, "%s/%s/%s", SYSFS_VBD_PATH, vbd_directory, what);
  76.120 +	fd = open(file_name, O_RDONLY, 0);
  76.121 +	if (fd==-1) return -1;
  76.122 +	num_read = read(fd, ret, cap - 1);
  76.123 +	close(fd);
  76.124 +	if (num_read<=0) return -1;
  76.125 +	ret[num_read] = '\0';
  76.126 +	return num_read;
  76.127 +}
  76.128 +
  76.129 +/* Collect information about VBDs */
  76.130 +static int xenstat_collect_vbds(xenstat_node * node)
  76.131 +{
  76.132 +	struct dirent *dp;
  76.133 +
  76.134 +	if (node->handle->sysfsvbd == NULL) {
  76.135 +		node->handle->sysfsvbd = opendir(SYSFS_VBD_PATH);
  76.136 +		if (node->handle->sysfsvbd == NULL) {
  76.137 +			perror("Error opening " SYSFS_VBD_PATH);
  76.138 +			return 0;
  76.139 +		}
  76.140 +	}
  76.141 +
  76.142 +	rewinddir(node->handle->sysfsvbd);
  76.143 +
  76.144 +	for(dp = readdir(node->handle->sysfsvbd); dp != NULL ;
  76.145 +	    dp = readdir(node->handle->sysfsvbd)) {
  76.146 +		xenstat_domain *domain;
  76.147 +		xenstat_vbd vbd;
  76.148 +		unsigned int domid;
  76.149 +		int ret;
  76.150 +		char buf[256];
  76.151 +
  76.152 +
  76.153 +		ret = sscanf(dp->d_name, "vbd-%u-%u", &domid, &vbd.dev);
  76.154 +		if (ret != 2) {
  76.155 +			continue;
  76.156 +		}
  76.157 +		printf("%s is VBD.\n",dp->d_name);
  76.158 +
  76.159 +		domain = xenstat_node_domain(node, domid);
  76.160 +		if (domain == NULL) {
  76.161 +			fprintf(stderr,
  76.162 +				"Found interface vbd-%u-%u but domain %u"
  76.163 +				" does not exist.\n",
  76.164 +				domid, vbd.dev, domid);
  76.165 +			continue;
  76.166 +		}
  76.167 +
  76.168 +		if((read_attributes_vbd(dp->d_name, "statistics/oo_req", buf, 256)<=0)
  76.169 +		   || ((ret = sscanf(buf, "%llu", &vbd.oo_reqs)) != 1))
  76.170 +		{
  76.171 +			continue;
  76.172 +		}
  76.173 +
  76.174 +		if((read_attributes_vbd(dp->d_name, "statistics/rd_req", buf, 256)<=0)
  76.175 +		   || ((ret = sscanf(buf, "%llu", &vbd.rd_reqs)) != 1))
  76.176 +		{
  76.177 +			continue;
  76.178 +		}
  76.179 +
  76.180 +		if((read_attributes_vbd(dp->d_name, "statistics/wr_req", buf, 256)<=0)
  76.181 +		   || ((ret = sscanf(buf, "%llu", &vbd.wr_reqs)) != 1))
  76.182 +		{
  76.183 +			continue;
  76.184 +		}
  76.185 +
  76.186 +
  76.187 +		if (domain->vbds == NULL) {
  76.188 +			domain->num_vbds = 1;
  76.189 +			domain->vbds = malloc(sizeof(xenstat_vbd));
  76.190 +		} else {
  76.191 +			domain->num_vbds++;
  76.192 +			domain->vbds = realloc(domain->vbds,
  76.193 +					       domain->num_vbds *
  76.194 +					       sizeof(xenstat_vbd));
  76.195 +		}
  76.196 +		if (domain->vbds == NULL)
  76.197 +			return 0;
  76.198 +		domain->vbds[domain->num_vbds - 1] = vbd;
  76.199 +	}
  76.200 +
  76.201 +	return 1;	
  76.202 +}
  76.203 +
  76.204 +/* Free VBD information */
  76.205 +static void xenstat_free_vbds(xenstat_node * node)
  76.206 +{
  76.207 +	unsigned int i;
  76.208 +	for (i = 0; i < node->num_domains; i++)
  76.209 +		free(node->domains[i].vbds);
  76.210 +}
  76.211 +
  76.212 +/* Free VBD information in handle */
  76.213 +static void xenstat_uninit_vbds(xenstat_handle * handle)
  76.214 +{
  76.215 +	if (handle->sysfsvbd)
  76.216 +		closedir(handle->sysfsvbd);
  76.217 +}
  76.218 +
  76.219 +/* Get the major number of VBD device */
  76.220 +unsigned int xenstat_vbd_dev(xenstat_vbd * vbd)
  76.221 +{
  76.222 +	return vbd->dev;
  76.223 +}
  76.224 +
  76.225 +/* Get the number of OO(Out of) requests */
  76.226 +unsigned long long xenstat_vbd_oo_reqs(xenstat_vbd * vbd)
  76.227 +{
  76.228 +	return vbd->oo_reqs;
  76.229 +}
  76.230 +
  76.231 +/* Get the number of READ requests */
  76.232 +unsigned long long xenstat_vbd_rd_reqs(xenstat_vbd * vbd)
  76.233 +{
  76.234 +	return vbd->rd_reqs;
  76.235 +}
  76.236 +
  76.237 +/* Get the number of WRITE requests */
  76.238 +unsigned long long xenstat_vbd_wr_reqs(xenstat_vbd * vbd)
  76.239 +{
  76.240 +	return vbd->wr_reqs;
  76.241 +}
  76.242 +
  76.243  static char *xenstat_get_domain_name(xenstat_handle *handle, unsigned int domain_id)
  76.244  {
  76.245  	char path[80];
    77.1 --- a/tools/xenstat/libxenstat/src/xenstat.h	Wed Jul 05 10:23:54 2006 -0600
    77.2 +++ b/tools/xenstat/libxenstat/src/xenstat.h	Wed Jul 05 20:11:37 2006 -0600
    77.3 @@ -23,6 +23,7 @@ typedef struct xenstat_domain xenstat_do
    77.4  typedef struct xenstat_node xenstat_node;
    77.5  typedef struct xenstat_vcpu xenstat_vcpu;
    77.6  typedef struct xenstat_network xenstat_network;
    77.7 +typedef struct xenstat_vbd xenstat_vbd;
    77.8  
    77.9  /* Initialize the xenstat library.  Returns a handle to be used with
   77.10   * subsequent calls to the xenstat library, or NULL if an error occurs. */
   77.11 @@ -35,7 +36,8 @@ void xenstat_uninit(xenstat_handle * han
   77.12  #define XENSTAT_VCPU 0x1
   77.13  #define XENSTAT_NETWORK 0x2
   77.14  #define XENSTAT_XEN_VERSION 0x4
   77.15 -#define XENSTAT_ALL (XENSTAT_VCPU|XENSTAT_NETWORK|XENSTAT_XEN_VERSION)
   77.16 +#define XENSTAT_VBD 0x8
   77.17 +#define XENSTAT_ALL (XENSTAT_VCPU|XENSTAT_NETWORK|XENSTAT_XEN_VERSION|XENSTAT_VBD)
   77.18  
   77.19  /* Get all available information about a node */
   77.20  xenstat_node *xenstat_get_node(xenstat_handle * handle, unsigned int flags);
   77.21 @@ -117,6 +119,13 @@ unsigned int xenstat_domain_num_networks
   77.22  xenstat_network *xenstat_domain_network(xenstat_domain * domain,
   77.23  					unsigned int network);
   77.24  
   77.25 +/* Get the number of VBDs for a given domain */
   77.26 +unsigned int xenstat_domain_num_vbds(xenstat_domain *);
   77.27 +
   77.28 +/* Get the VBD handle to obtain VBD stats */
   77.29 +xenstat_vbd *xenstat_domain_vbd(xenstat_domain * domain,
   77.30 +				    unsigned int vbd);
   77.31 +
   77.32  /*
   77.33   * VCPU functions - extract information from a xenstat_vcpu
   77.34   */
   77.35 @@ -156,3 +165,14 @@ unsigned long long xenstat_network_terrs
   77.36  
   77.37  /* Get the number of transmit drops for this network */
   77.38  unsigned long long xenstat_network_tdrop(xenstat_network * network);
   77.39 +
   77.40 +/*
   77.41 + * VBD functions - extract information from a xen_vbd
   77.42 + */
   77.43 +/* Get the device number for Virtual Block Device */
   77.44 +unsigned int xenstat_vbd_dev(xenstat_vbd * vbd);
   77.45 +
   77.46 +/* Get the number of OO/RD/WR requests for vbd */
   77.47 +unsigned long long xenstat_vbd_oo_reqs(xenstat_vbd * vbd);
   77.48 +unsigned long long xenstat_vbd_rd_reqs(xenstat_vbd * vbd);
   77.49 +unsigned long long xenstat_vbd_wr_reqs(xenstat_vbd * vbd);
    78.1 --- a/tools/xenstat/xentop/xentop.c	Wed Jul 05 10:23:54 2006 -0600
    78.2 +++ b/tools/xenstat/xentop/xentop.c	Wed Jul 05 20:11:37 2006 -0600
    78.3 @@ -27,6 +27,7 @@
    78.4  #include <sys/time.h>
    78.5  #include <time.h>
    78.6  #include <unistd.h>
    78.7 +#include <linux/kdev_t.h>
    78.8  
    78.9  #include <xenstat.h>
   78.10  
   78.11 @@ -65,6 +66,7 @@ static int handle_key(int);
   78.12  static int compare(unsigned long long, unsigned long long);
   78.13  static int compare_domains(xenstat_domain **, xenstat_domain **);
   78.14  static unsigned long long tot_net_bytes( xenstat_domain *, int);
   78.15 +static unsigned long long tot_vbd_reqs( xenstat_domain *, int);
   78.16  
   78.17  /* Field functions */
   78.18  static int compare_state(xenstat_domain *domain1, xenstat_domain *domain2);
   78.19 @@ -91,6 +93,15 @@ static int compare_ssid(xenstat_domain *
   78.20  static void print_ssid(xenstat_domain *domain);
   78.21  static int compare_name(xenstat_domain *domain1, xenstat_domain *domain2);
   78.22  static void print_name(xenstat_domain *domain);
   78.23 +static int compare_vbds(xenstat_domain *domain1, xenstat_domain *domain2);
   78.24 +static void print_vbds(xenstat_domain *domain);
   78.25 +static int compare_vbd_oo(xenstat_domain *domain1, xenstat_domain *domain2);
   78.26 +static void print_vbd_oo(xenstat_domain *domain);
   78.27 +static int compare_vbd_rd(xenstat_domain *domain1, xenstat_domain *domain2);
   78.28 +static void print_vbd_rd(xenstat_domain *domain);
   78.29 +static int compare_vbd_wr(xenstat_domain *domain1, xenstat_domain *domain2);
   78.30 +static void print_vbd_wr(xenstat_domain *domain);
   78.31 +
   78.32  
   78.33  /* Section printing functions */
   78.34  static void do_summary(void);
   78.35 @@ -99,6 +110,7 @@ static void do_bottom_line(void);
   78.36  static void do_domain(xenstat_domain *);
   78.37  static void do_vcpu(xenstat_domain *);
   78.38  static void do_network(xenstat_domain *);
   78.39 +static void do_vbd(xenstat_domain *);
   78.40  static void top(void);
   78.41  
   78.42  /* Field types */
   78.43 @@ -116,6 +128,10 @@ typedef enum field_id {
   78.44  	FIELD_NETS,
   78.45  	FIELD_NET_TX,
   78.46  	FIELD_NET_RX,
   78.47 +	FIELD_VBDS,
   78.48 +	FIELD_VBD_OO,
   78.49 +	FIELD_VBD_RD,
   78.50 +	FIELD_VBD_WR,
   78.51  	FIELD_SSID
   78.52  } field_id;
   78.53  
   78.54 @@ -140,6 +156,10 @@ field fields[] = {
   78.55  	{ FIELD_NETS,    "NETS",       4, compare_nets,    print_nets    },
   78.56  	{ FIELD_NET_TX,  "NETTX(k)",   8, compare_net_tx,  print_net_tx  },
   78.57  	{ FIELD_NET_RX,  "NETRX(k)",   8, compare_net_rx,  print_net_rx  },
   78.58 +	{ FIELD_VBDS,    "VBDS",       4, compare_vbds,    print_vbds    },
   78.59 +	{ FIELD_VBD_OO,  "VBD_OO",     8, compare_vbd_oo,  print_vbd_oo  },
   78.60 +	{ FIELD_VBD_RD,  "VBD_RD",     8, compare_vbd_rd,  print_vbd_rd  },
   78.61 +	{ FIELD_VBD_WR,  "VBD_WR",     8, compare_vbd_wr,  print_vbd_wr  },
   78.62  	{ FIELD_SSID,    "SSID",       4, compare_ssid,    print_ssid    }
   78.63  };
   78.64  
   78.65 @@ -158,6 +178,7 @@ unsigned int loop = 1;
   78.66  unsigned int iterations = 0;
   78.67  int show_vcpus = 0;
   78.68  int show_networks = 0;
   78.69 +int show_vbds = 0;
   78.70  int repeat_header = 0;
   78.71  #define PROMPT_VAL_LEN 80
   78.72  char *prompt = NULL;
   78.73 @@ -180,6 +201,7 @@ static void usage(const char *program)
   78.74  	       "-V, --version        output version information and exit\n"
   78.75  	       "-d, --delay=SECONDS  seconds between updates (default 3)\n"
   78.76  	       "-n, --networks       output vif network data\n"
   78.77 +	       "-b, --vbds           output vbd block device data\n"
   78.78  	       "-r, --repeat-header  repeat table header before each domain\n"
   78.79  	       "-v, --vcpus          output vcpu data\n"
   78.80  	       "-b, --batch	     output in batch mode, no user input accepted\n"
   78.81 @@ -290,6 +312,9 @@ static int handle_key(int ch)
   78.82  		case 'n': case 'N':
   78.83  			show_networks ^= 1;
   78.84  			break;
   78.85 +		case 'b': case 'B':
   78.86 +			show_vbds ^= 1;
   78.87 +			break;
   78.88  		case 'r': case 'R':
   78.89  			repeat_header ^= 1;
   78.90  			break;
   78.91 @@ -585,6 +610,96 @@ static unsigned long long tot_net_bytes(
   78.92  	return total;
   78.93  }
   78.94  
   78.95 +/* Compares number of virtual block devices of two domains,
   78.96 +   returning -1,0,1 for * <,=,> */
   78.97 +static int compare_vbds(xenstat_domain *domain1, xenstat_domain *domain2)
   78.98 +{
   78.99 +	return -compare(xenstat_domain_num_vbds(domain1),
  78.100 +	                xenstat_domain_num_vbds(domain2));
  78.101 +}
  78.102 +
  78.103 +/* Prints number of virtual block devices statistic */
  78.104 +static void print_vbds(xenstat_domain *domain)
  78.105 +{
  78.106 +	print("%4u", xenstat_domain_num_vbds(domain));
  78.107 +}
  78.108 +
  78.109 +/* Compares number of total VBD OO requests of two domains,
  78.110 +   returning -1,0,1 * for <,=,> */
  78.111 +static int compare_vbd_oo(xenstat_domain *domain1, xenstat_domain *domain2)
  78.112 +{
  78.113 +  return -compare(tot_vbd_reqs(domain1, FIELD_VBD_OO),
  78.114 +		  tot_vbd_reqs(domain2, FIELD_VBD_OO));
  78.115 +}
  78.116 +
  78.117 +/* Prints number of total VBD OO requests statistic */
  78.118 +static void print_vbd_oo(xenstat_domain *domain)
  78.119 +{
  78.120 +	print("%8llu", tot_vbd_reqs(domain, FIELD_VBD_OO));
  78.121 +}
  78.122 +
  78.123 +/* Compares number of total VBD READ requests of two domains,
  78.124 +   returning -1,0,1 * for <,=,> */
  78.125 +static int compare_vbd_rd(xenstat_domain *domain1, xenstat_domain *domain2)
  78.126 +{
  78.127 +	return -compare(tot_vbd_reqs(domain1, FIELD_VBD_RD),
  78.128 +			tot_vbd_reqs(domain2, FIELD_VBD_RD));
  78.129 +}
  78.130 +
  78.131 +/* Prints number of total VBD READ requests statistic */
  78.132 +static void print_vbd_rd(xenstat_domain *domain)
  78.133 +{
  78.134 +	print("%8llu", tot_vbd_reqs(domain, FIELD_VBD_RD));
  78.135 +}
  78.136 +
  78.137 +/* Compares number of total VBD WRITE requests of two domains,
  78.138 +   returning -1,0,1 * for <,=,> */
  78.139 +static int compare_vbd_wr(xenstat_domain *domain1, xenstat_domain *domain2)
  78.140 +{
  78.141 +	return -compare(tot_vbd_reqs(domain1,FIELD_VBD_WR),
  78.142 +			tot_vbd_reqs(domain2,FIELD_VBD_WR));
  78.143 +}
  78.144 +
  78.145 +/* Prints number of total VBD WRITE requests statistic */
  78.146 +static void print_vbd_wr(xenstat_domain *domain)
  78.147 +{
  78.148 +	print("%8llu", tot_vbd_reqs(domain,FIELD_VBD_WR));
  78.149 +}
  78.150 +
  78.151 +/* Gets number of total VBD requests statistic, 
  78.152 + *   if flag is FIELD_VBD_OO, then OO requests,
  78.153 + *   if flag is FIELD_VBD_RD, then READ requests and
  78.154 + *   if flag is FIELD_VBD_WR, then WRITE requests.
  78.155 + */
  78.156 +static unsigned long long tot_vbd_reqs(xenstat_domain *domain, int flag)
  78.157 +{
  78.158 +	int i = 0;
  78.159 +	xenstat_vbd *vbd;
  78.160 +	unsigned num_vbds = 0;
  78.161 +	unsigned long long total = 0;
  78.162 +	
  78.163 +	num_vbds = xenstat_domain_num_vbds(domain);
  78.164 +	
  78.165 +	for ( i=0 ; i < num_vbds ; i++) {
  78.166 +		vbd = xenstat_domain_vbd(domain,i);
  78.167 +		switch(flag) {
  78.168 +		case FIELD_VBD_OO:
  78.169 +			total += xenstat_vbd_oo_reqs(vbd);
  78.170 +			break;
  78.171 +		case FIELD_VBD_RD:
  78.172 +			total += xenstat_vbd_rd_reqs(vbd);
  78.173 +			break;
  78.174 +		case FIELD_VBD_WR:
  78.175 +			total += xenstat_vbd_wr_reqs(vbd);
  78.176 +			break;
  78.177 +		default:
  78.178 +			break;
  78.179 +		}
  78.180 +	}
  78.181 +	
  78.182 +	return total;
  78.183 +}
  78.184 +
  78.185  /* Compares security id (ssid) of two domains, returning -1,0,1 for <,=,> */
  78.186  static int compare_ssid(xenstat_domain *domain1, xenstat_domain *domain2)
  78.187  {
  78.188 @@ -680,6 +795,13 @@ void do_bottom_line(void)
  78.189  		addch(A_REVERSE | 'N');
  78.190  		attr_addstr(show_networks ? COLOR_PAIR(1) : 0, "etworks");
  78.191  		addstr("  ");
  78.192 +		
  78.193 +		/* VBDs */
  78.194 +		attr_addstr(show_vbds ? COLOR_PAIR(1) : 0, "v");
  78.195 +		addch(A_REVERSE | 'B');
  78.196 +		attr_addstr(show_vbds ? COLOR_PAIR(1) : 0, "ds");
  78.197 +		addstr("  ");
  78.198 +
  78.199  
  78.200  		/* vcpus */
  78.201  		addch(A_REVERSE | 'V');
  78.202 @@ -769,6 +891,28 @@ void do_network(xenstat_domain *domain)
  78.203  	}
  78.204  }
  78.205  
  78.206 +
  78.207 +/* Output all VBD information */
  78.208 +void do_vbd(xenstat_domain *domain)
  78.209 +{
  78.210 +	int i = 0;
  78.211 +	xenstat_vbd *vbd;
  78.212 +	unsigned num_vbds = 0;
  78.213 +
  78.214 +	num_vbds = xenstat_domain_num_vbds(domain);
  78.215 +
  78.216 +	for (i=0 ; i< num_vbds; i++) {
  78.217 +		vbd = xenstat_domain_vbd(domain,i);
  78.218 +				
  78.219 +		print("VBD %4u [%2x:%2x]  OO: %8llu   RD: %8llu   WR: %8llu\n",
  78.220 +		      xenstat_vbd_dev(vbd),
  78.221 +		      MAJOR(xenstat_vbd_dev(vbd)), MINOR(xenstat_vbd_dev(vbd)),
  78.222 +		      xenstat_vbd_oo_reqs(vbd),
  78.223 +		      xenstat_vbd_rd_reqs(vbd),
  78.224 +		      xenstat_vbd_wr_reqs(vbd));
  78.225 +	}
  78.226 +}
  78.227 +
  78.228  static void top(void)
  78.229  {
  78.230  	xenstat_domain **domains;
  78.231 @@ -812,6 +956,8 @@ static void top(void)
  78.232  			do_vcpu(domains[i]);
  78.233  		if (show_networks)
  78.234  			do_network(domains[i]);
  78.235 +		if (show_vbds)
  78.236 +			do_vbd(domains[i]);
  78.237  	}
  78.238  
  78.239  	if(!batch)
  78.240 @@ -827,6 +973,7 @@ int main(int argc, char **argv)
  78.241  		{ "help",          no_argument,       NULL, 'h' },
  78.242  		{ "version",       no_argument,       NULL, 'V' },
  78.243  		{ "networks",      no_argument,       NULL, 'n' },
  78.244 + 		{ "vbds",          no_argument,       NULL, 'x' },
  78.245  		{ "repeat-header", no_argument,       NULL, 'r' },
  78.246  		{ "vcpus",         no_argument,       NULL, 'v' },
  78.247  		{ "delay",         required_argument, NULL, 'd' },
  78.248 @@ -834,7 +981,7 @@ int main(int argc, char **argv)
  78.249  		{ "iterations",	   required_argument, NULL, 'i' },
  78.250  		{ 0, 0, 0, 0 },
  78.251  	};
  78.252 -	const char *sopts = "hVbnvd:bi:";
  78.253 +	const char *sopts = "hVnxrvd:bi:";
  78.254  
  78.255  	if (atexit(cleanup) != 0)
  78.256  		fail("Failed to install cleanup handler.\n");
  78.257 @@ -852,6 +999,9 @@ int main(int argc, char **argv)
  78.258  		case 'n':
  78.259  			show_networks = 1;
  78.260  			break;
  78.261 +		case 'x':
  78.262 +			show_vbds = 1;
  78.263 +			break;
  78.264  		case 'r':
  78.265  			repeat_header = 1;
  78.266  			break;
    79.1 --- a/tools/xm-test/tests/vtpm/02_vtpm-cat_pcrs.py	Wed Jul 05 10:23:54 2006 -0600
    79.2 +++ b/tools/xm-test/tests/vtpm/02_vtpm-cat_pcrs.py	Wed Jul 05 20:11:37 2006 -0600
    79.3 @@ -14,16 +14,15 @@ import os.path
    79.4  
    79.5  config = {"vtpm":"instance=1,backend=0"}
    79.6  domain = XmTestDomain(extraConfig=config)
    79.7 +domName = domain.getName()
    79.8  
    79.9  try:
   79.10      console = domain.start()
   79.11  except DomainError, e:
   79.12      if verbose:
   79.13          print e.extra
   79.14 -    vtpm_cleanup(domain.getName())
   79.15 -    FAIL("Unable to create domain")
   79.16 -
   79.17 -domName = domain.getName()
   79.18 +    vtpm_cleanup(domName)
   79.19 +    FAIL("Unable to create domain (%s)" % domName)
   79.20  
   79.21  try:
   79.22      console.sendInput("input")
   79.23 @@ -33,11 +32,11 @@ except ConsoleError, e:
   79.24      FAIL(str(e))
   79.25  
   79.26  try:
   79.27 -    run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
   79.28 +    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
   79.29  except ConsoleError, e:
   79.30      saveLog(console.getHistory())
   79.31      vtpm_cleanup(domName)
   79.32 -    FAIL(str(e))
   79.33 +    FAIL("No result from dumping the PCRs")
   79.34  
   79.35  if re.search("No such file",run["output"]):
   79.36      vtpm_cleanup(domName)
    80.1 --- a/tools/xm-test/tests/vtpm/03_vtpm-susp_res.py	Wed Jul 05 10:23:54 2006 -0600
    80.2 +++ b/tools/xm-test/tests/vtpm/03_vtpm-susp_res.py	Wed Jul 05 20:11:37 2006 -0600
    80.3 @@ -15,6 +15,7 @@ import os.path
    80.4  
    80.5  config = {"vtpm":"instance=1,backend=0"}
    80.6  domain = XmTestDomain(extraConfig=config)
    80.7 +domName = domain.getName()
    80.8  consoleHistory = ""
    80.9  
   80.10  try:
   80.11 @@ -22,10 +23,8 @@ try:
   80.12  except DomainError, e:
   80.13      if verbose:
   80.14          print e.extra
   80.15 -    vtpm_cleanup(domain.getName())
   80.16 -    FAIL("Unable to create domain")
   80.17 -
   80.18 -domName = domain.getName()
   80.19 +    vtpm_cleanup(domName)
   80.20 +    FAIL("Unable to create domain (%s)" % domName)
   80.21  
   80.22  try:
   80.23      console.sendInput("input")
   80.24 @@ -35,11 +34,11 @@ except ConsoleError, e:
   80.25      FAIL(str(e))
   80.26  
   80.27  try:
   80.28 -    run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
   80.29 +    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
   80.30  except ConsoleError, e:
   80.31      saveLog(console.getHistory())
   80.32      vtpm_cleanup(domName)
   80.33 -    FAIL(str(e))
   80.34 +    FAIL("No result from dumping the PCRs")
   80.35  
   80.36  if re.search("No such file",run["output"]):
   80.37      vtpm_cleanup(domName)
   80.38 @@ -48,50 +47,59 @@ if re.search("No such file",run["output"
   80.39  consoleHistory = console.getHistory()
   80.40  domain.closeConsole()
   80.41  
   80.42 -try:
   80.43 -    status, ouptut = traceCommand("xm save %s %s.save" %
   80.44 -                                  (domName, domName),
   80.45 -                                  timeout=30)
   80.46 -
   80.47 -except TimeoutError, e:
   80.48 -    saveLog(consoleHistory)
   80.49 -    vtpm_cleanup(domName)
   80.50 -    FAIL(str(e))
   80.51 +loop = 0
   80.52 +while loop < 3:
   80.53 +    try:
   80.54 +        status, ouptut = traceCommand("xm save %s %s.save" %
   80.55 +                                      (domName, domName),
   80.56 +                                      timeout=30)
   80.57  
   80.58 -if status != 0:
   80.59 -    saveLog(consoleHistory)
   80.60 -    vtpm_cleanup(domName)
   80.61 -    FAIL("xm save did not succeed")
   80.62 +    except TimeoutError, e:
   80.63 +        saveLog(consoleHistory)
   80.64 +        vtpm_cleanup(domName)
   80.65 +        FAIL(str(e))
   80.66  
   80.67 -try:
   80.68 -    status, ouptut = traceCommand("xm restore %s.save" %
   80.69 -                                  (domName),
   80.70 -                                  timeout=30)
   80.71 -except TimeoutError, e:
   80.72 +    if status != 0:
   80.73 +        saveLog(consoleHistory)
   80.74 +        vtpm_cleanup(domName)
   80.75 +        FAIL("xm save did not succeed")
   80.76 +
   80.77 +    try:
   80.78 +        status, ouptut = traceCommand("xm restore %s.save" %
   80.79 +                                      (domName),
   80.80 +                                      timeout=30)
   80.81 +    except TimeoutError, e:
   80.82 +        os.remove("%s.save" % domName)
   80.83 +        saveLog(consoleHistory)
   80.84 +        vtpm_cleanup(domName)
   80.85 +        FAIL(str(e))
   80.86 +
   80.87      os.remove("%s.save" % domName)
   80.88 -    saveLog(consoleHistory)
   80.89 -    vtpm_cleanup(domName)
   80.90 -    FAIL(str(e))
   80.91 -
   80.92 -os.remove("%s.save" % domName)
   80.93 -
   80.94 -if status != 0:
   80.95 -    saveLog(consoleHistory)
   80.96 -    vtpm_cleanup(domName)
   80.97 -    FAIL("xm restore did not succeed")
   80.98  
   80.99 -try:
  80.100 -    console = domain.getConsole()
  80.101 -except ConsoleError, e:
  80.102 -    vtpm_cleanup(domName)
  80.103 -    FAIL(str(e))
  80.104 +    if status != 0:
  80.105 +        saveLog(consoleHistory)
  80.106 +        vtpm_cleanup(domName)
  80.107 +        FAIL("xm restore did not succeed")
  80.108  
  80.109 -try:
  80.110 -    run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
  80.111 -except ConsoleError, e:
  80.112 -    saveLog(console.getHistory())
  80.113 -    vtpm_cleanup(domName)
  80.114 -    FAIL(str(e))
  80.115 +    try:
  80.116 +        console = domain.getConsole()
  80.117 +    except ConsoleError, e:
  80.118 +        vtpm_cleanup(domName)
  80.119 +        FAIL(str(e))
  80.120 +
  80.121 +    try:
  80.122 +        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
  80.123 +    except ConsoleError, e:
  80.124 +        saveLog(console.getHistory())
  80.125 +        vtpm_cleanup(domName)
  80.126 +        FAIL(str(e))
  80.127 +
  80.128 +    if not re.search("PCR-00:",run["output"]):
  80.129 +        saveLog(console.getHistory())
  80.130 +        vtpm_cleanup(domName)
  80.131 +	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
  80.132 +
  80.133 +    loop += 1
  80.134  
  80.135  domain.closeConsole()
  80.136  
  80.137 @@ -99,5 +107,3 @@ domain.stop()
  80.138  
  80.139  vtpm_cleanup(domName)
  80.140  
  80.141 -if not re.search("PCR-00:",run["output"]):
  80.142 -	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
    81.1 --- a/tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py	Wed Jul 05 10:23:54 2006 -0600
    81.2 +++ b/tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py	Wed Jul 05 20:11:37 2006 -0600
    81.3 @@ -16,6 +16,7 @@ import os.path
    81.4  
    81.5  config = {"vtpm":"instance=1,backend=0"}
    81.6  domain = XmTestDomain(extraConfig=config)
    81.7 +domName = domain.getName()
    81.8  consoleHistory = ""
    81.9  
   81.10  try:
   81.11 @@ -23,10 +24,8 @@ try:
   81.12  except DomainError, e:
   81.13      if verbose:
   81.14          print e.extra
   81.15 -    vtpm_cleanup(domain.getName())
   81.16 -    FAIL("Unable to create domain")
   81.17 -
   81.18 -domName = domain.getName()
   81.19 +    vtpm_cleanup(domName)
   81.20 +    FAIL("Unable to create domain (%s)" % domName)
   81.21  
   81.22  try:
   81.23      console.sendInput("input")
   81.24 @@ -36,11 +35,11 @@ except ConsoleError, e:
   81.25      FAIL(str(e))
   81.26  
   81.27  try:
   81.28 -    run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
   81.29 +    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
   81.30  except ConsoleError, e:
   81.31      saveLog(console.getHistory())
   81.32      vtpm_cleanup(domName)
   81.33 -    FAIL(str(e))
   81.34 +    FAIL("No result from dumping the PCRs")
   81.35  
   81.36  if re.search("No such file",run["output"]):
   81.37      vtpm_cleanup(domName)
   81.38 @@ -83,11 +82,17 @@ while loop < 3:
   81.39          FAIL(str(e))
   81.40  
   81.41      try:
   81.42 -        run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
   81.43 +        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
   81.44      except ConsoleError, e:
   81.45          saveLog(console.getHistory())
   81.46          vtpm_cleanup(domName)
   81.47 -        FAIL(str(e))
   81.48 +        FAIL("No result from dumping the PCRs")
   81.49 +
   81.50 +    if not re.search("PCR-00:",run["output"]):
   81.51 +        saveLog(console.getHistory())
   81.52 +        vtpm_cleanup(domName)
   81.53 +	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
   81.54 +
   81.55      loop += 1
   81.56  
   81.57  domain.closeConsole()
   81.58 @@ -95,6 +100,3 @@ domain.closeConsole()
   81.59  domain.stop()
   81.60  
   81.61  vtpm_cleanup(domName)
   81.62 -
   81.63 -if not re.search("PCR-00:",run["output"]):
   81.64 -	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
    82.1 --- a/tools/xm-test/tests/vtpm/05_vtpm-loc_migr.py	Wed Jul 05 10:23:54 2006 -0600
    82.2 +++ b/tools/xm-test/tests/vtpm/05_vtpm-loc_migr.py	Wed Jul 05 20:11:37 2006 -0600
    82.3 @@ -16,6 +16,7 @@ import os.path
    82.4  
    82.5  config = {"vtpm":"instance=1,backend=0"}
    82.6  domain = XmTestDomain(extraConfig=config)
    82.7 +domName = domain.getName()
    82.8  consoleHistory = ""
    82.9  
   82.10  try:
   82.11 @@ -23,10 +24,8 @@ try:
   82.12  except DomainError, e:
   82.13      if verbose:
   82.14          print e.extra
   82.15 -    vtpm_cleanup(domain.getName())
   82.16 -    FAIL("Unable to create domain")
   82.17 -
   82.18 -domName = domain.getName()
   82.19 +    vtpm_cleanup(domName)
   82.20 +    FAIL("Unable to create domain (%s)" % domName)
   82.21  
   82.22  try:
   82.23      console.sendInput("input")
   82.24 @@ -36,11 +35,11 @@ except ConsoleError, e:
   82.25      FAIL(str(e))
   82.26  
   82.27  try:
   82.28 -    run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
   82.29 +    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
   82.30  except ConsoleError, e:
   82.31      saveLog(console.getHistory())
   82.32      vtpm_cleanup(domName)
   82.33 -    FAIL(str(e))
   82.34 +    FAIL("No result from dumping the PCRs")
   82.35  
   82.36  if re.search("No such file",run["output"]):
   82.37      vtpm_cleanup(domName)
   82.38 @@ -83,11 +82,17 @@ while loop < 3:
   82.39          FAIL(str(e))
   82.40  
   82.41      try:
   82.42 -        run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
   82.43 +        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
   82.44      except ConsoleError, e:
   82.45          saveLog(console.getHistory())
   82.46          vtpm_cleanup(domName)
   82.47 -        FAIL(str(e))
   82.48 +        FAIL("No result from dumping the PCRs")
   82.49 +
   82.50 +    if not re.search("PCR-00:",run["output"]):
   82.51 +        saveLog(console.getHistory())
   82.52 +        vtpm_cleanup(domName)
   82.53 +	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
   82.54 +
   82.55      loop += 1
   82.56  
   82.57  domain.closeConsole()
   82.58 @@ -95,6 +100,3 @@ domain.closeConsole()
   82.59  domain.stop()
   82.60  
   82.61  vtpm_cleanup(domName)
   82.62 -
   82.63 -if not re.search("PCR-00:",run["output"]):
   82.64 -	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
    83.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    83.2 +++ b/tools/xm-test/tests/vtpm/06_vtpm-susp_res_pcrs.py	Wed Jul 05 20:11:37 2006 -0600
    83.3 @@ -0,0 +1,139 @@
    83.4 +#!/usr/bin/python
    83.5 +
    83.6 +# Copyright (C) International Business Machines Corp., 2006
    83.7 +# Author: Stefan Berger <stefanb@us.ibm.com>
    83.8 +
    83.9 +# Positive Test: create domain with virtual TPM attached at build time,
   83.10 +#                extend a pcr
   83.11 +#                check list of pcrs; suspend and resume the domain and
   83.12 +#                check list of pcrs again and validate extended pcr
   83.13 +
   83.14 +from XmTestLib import *
   83.15 +from vtpm_utils import *
   83.16 +import commands
   83.17 +import os
   83.18 +import os.path
   83.19 +
   83.20 +config = {"vtpm":"instance=1,backend=0"}
   83.21 +domain = XmTestDomain(extraConfig=config)
   83.22 +domName = domain.getName()
   83.23 +consoleHistory = ""
   83.24 +
   83.25 +try:
   83.26 +    console = domain.start()
   83.27 +except DomainError, e:
   83.28 +    if verbose:
   83.29 +        print e.extra
   83.30 +    vtpm_cleanup(domName)
   83.31 +    FAIL("Unable to create domain (%s)" % domName)
   83.32 +
   83.33 +try:
   83.34 +    console.sendInput("input")
   83.35 +except ConsoleError, e:
   83.36 +    saveLog(console.getHistory())
   83.37 +    vtpm_cleanup(domName)
   83.38 +    FAIL(str(e))
   83.39 +
   83.40 +try:
   83.41 +    run = console.runCmd("mknod /dev/tpm0 c 10 224")
   83.42 +except ConsoleError, e:
   83.43 +    saveLog(console.getHistory())
   83.44 +    vtpm_cleanup(domName)
   83.45 +    FAIL("Error while creating /dev/tpm0")
   83.46 +
   83.47 +try:
   83.48 +    run = console.runCmd("echo -ne \"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\" > /dev/tpm0")
   83.49 +except ConsoleError, e:
   83.50 +    saveLog(console.getHistory())
   83.51 +    vtpm_cleanup(domName)
   83.52 +    FAIL("Error while extending PCR 0")
   83.53 +
   83.54 +try:
   83.55 +    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
   83.56 +except ConsoleError, e:
   83.57 +    saveLog(console.getHistory())
   83.58 +    vtpm_cleanup(domName)
   83.59 +    FAIL("No result from dumping the PCRs")
   83.60 +
   83.61 +
   83.62 +if re.search("No such file",run["output"]):
   83.63 +    vtpm_cleanup(domName)
   83.64 +    FAIL("TPM frontend support not compiled into (domU?) kernel")
   83.65 +
   83.66 +if not re.search("PCR-00:",run["output"]):
   83.67 +    saveLog(console.getHistory())
   83.68 +    vtpm_cleanup(domName)
   83.69 +    FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side: \n%s" % run["output"])
   83.70 +
   83.71 +if not re.search("PCR-00: 1E A7 BD",run["output"]):
   83.72 +    saveLog(console.getHistory())
   83.73 +    FAIL("Extend did not lead to expected result (1E A7 BD ...): \n%s" % run["output"])
   83.74 +
   83.75 +consoleHistory = console.getHistory()
   83.76 +domain.closeConsole()
   83.77 +
   83.78 +loop = 0
   83.79 +while loop < 3:
   83.80 +    try:
   83.81 +        status, ouptut = traceCommand("xm save %s %s.save" %
   83.82 +                                      (domName, domName),
   83.83 +                                      timeout=30)
   83.84 +
   83.85 +    except TimeoutError, e:
   83.86 +        saveLog(consoleHistory)
   83.87 +        vtpm_cleanup(domName)
   83.88 +        FAIL(str(e))
   83.89 +
   83.90 +    if status != 0:
   83.91 +        saveLog(consoleHistory)
   83.92 +        vtpm_cleanup(domName)
   83.93 +        FAIL("xm save did not succeed")
   83.94 +
   83.95 +    try:
   83.96 +        status, ouptut = traceCommand("xm restore %s.save" %
   83.97 +                                      (domName),
   83.98 +                                      timeout=30)
   83.99 +    except TimeoutError, e:
  83.100 +        os.remove("%s.save" % domName)
  83.101 +        saveLog(consoleHistory)
  83.102 +        vtpm_cleanup(domName)
  83.103 +        FAIL(str(e))
  83.104 +
  83.105 +    os.remove("%s.save" % domName)
  83.106 +
  83.107 +    if status != 0:
  83.108 +        saveLog(consoleHistory)
  83.109 +        vtpm_cleanup(domName)
  83.110 +        FAIL("xm restore did not succeed")
  83.111 +
  83.112 +    try:
  83.113 +        console = domain.getConsole()
  83.114 +    except ConsoleError, e:
  83.115 +        vtpm_cleanup(domName)
  83.116 +        FAIL(str(e))
  83.117 +
  83.118 +    try:
  83.119 +        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
  83.120 +    except ConsoleError, e:
  83.121 +        saveLog(console.getHistory())
  83.122 +        vtpm_cleanup(domName)
  83.123 +        FAIL(str(e))
  83.124 +
  83.125 +    if not re.search("PCR-00:",run["output"]):
  83.126 +        saveLog(console.getHistory())
  83.127 +        vtpm_cleanup(domName)
  83.128 +	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
  83.129 +
  83.130 +    if not re.search("PCR-00: 1E A7 BD",run["output"]):
  83.131 +        saveLog(console.getHistory())
  83.132 +        vtpm_cleanup(domName)
  83.133 +	FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
  83.134 +
  83.135 +    loop += 1
  83.136 +
  83.137 +domain.closeConsole()
  83.138 +
  83.139 +domain.stop()
  83.140 +
  83.141 +vtpm_cleanup(domName)
  83.142 +
    84.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    84.2 +++ b/tools/xm-test/tests/vtpm/07_vtpm-mig_pcrs.py	Wed Jul 05 20:11:37 2006 -0600
    84.3 @@ -0,0 +1,132 @@
    84.4 +#!/usr/bin/python
    84.5 +
    84.6 +# Copyright (C) International Business Machines Corp., 2006
    84.7 +# Author: Stefan Berger <stefanb@us.ibm.com>
    84.8 +
    84.9 +# Positive Test: create domain with virtual TPM attached at build time,
   84.10 +#                extend a pcr
   84.11 +#                check list of pcrs; locally migrate the domain and
   84.12 +#                check list of pcrs again and validate extended pcr
   84.13 +#                This test does local live migration.
   84.14 +
   84.15 +from XmTestLib import *
   84.16 +from vtpm_utils import *
   84.17 +import commands
   84.18 +import os
   84.19 +import os.path
   84.20 +
   84.21 +config = {"vtpm":"instance=1,backend=0"}
   84.22 +domain = XmTestDomain(extraConfig=config)
   84.23 +domName = domain.getName()
   84.24 +consoleHistory = ""
   84.25 +
   84.26 +try:
   84.27 +    console = domain.start()
   84.28 +except DomainError, e:
   84.29 +    if verbose:
   84.30 +        print e.extra
   84.31 +    vtpm_cleanup(domName)
   84.32 +    FAIL("Unable to create domain (%s)" % domName)
   84.33 +
   84.34 +try:
   84.35 +    console.sendInput("input")
   84.36 +except ConsoleError, e:
   84.37 +    saveLog(console.getHistory())
   84.38 +    vtpm_cleanup(domName)
   84.39 +    FAIL(str(e))
   84.40 +
   84.41 +try:
   84.42 +    run = console.runCmd("mknod /dev/tpm0 c 10 224")
   84.43 +except ConsoleError, e:
   84.44 +    saveLog(console.getHistory())
   84.45 +    vtpm_cleanup(domName)
   84.46 +    FAIL("Error while creating /dev/tpm0")
   84.47 +
   84.48 +try:
   84.49 +    run = console.runCmd("echo -ne \"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\" > /dev/tpm0")
   84.50 +except ConsoleError, e:
   84.51 +    saveLog(console.getHistory())
   84.52 +    vtpm_cleanup(domName)
   84.53 +    FAIL("Error while extending PCR 0")
   84.54 +
   84.55 +try:
   84.56 +    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
   84.57 +except ConsoleError, e:
   84.58 +    saveLog(console.getHistory())
   84.59 +    vtpm_cleanup(domName)
   84.60 +    FAIL("No result from dumping the PCRs")
   84.61 +
   84.62 +
   84.63 +if re.search("No such file",run["output"]):
   84.64 +    vtpm_cleanup(domName)
   84.65 +    FAIL("TPM frontend support not compiled into (domU?) kernel")
   84.66 +
   84.67 +if not re.search("PCR-00:",run["output"]):
   84.68 +    saveLog(console.getHistory())
   84.69 +    vtpm_cleanup(domName)
   84.70 +    FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side: \n%s" % run["output"])
   84.71 +
   84.72 +if not re.search("PCR-00: 1E A7 BD",run["output"]):
   84.73 +    saveLog(console.getHistory())
   84.74 +    FAIL("Extend did not lead to expected result (1E A7 BD ...): \n%s" % run["output"])
   84.75 +
   84.76 +consoleHistory = console.getHistory()
   84.77 +domain.closeConsole()
   84.78 +
   84.79 +old_domid = domid(domName)
   84.80 +
   84.81 +loop = 0
   84.82 +while loop < 3:
   84.83 +    try:
   84.84 +        status, ouptut = traceCommand("xm migrate -l %s localhost" %
   84.85 +                                      domName,
   84.86 +                                      timeout=90)
   84.87 +    except TimeoutError, e:
   84.88 +        saveLog(consoleHistory)
   84.89 +        vtpm_cleanup(domName)
   84.90 +        FAIL(str(e))
   84.91 +
   84.92 +    if status != 0:
   84.93 +        saveLog(consoleHistory)
   84.94 +        vtpm_cleanup(domName)
   84.95 +        FAIL("xm migrate did not succeed. External device migration activated?")
   84.96 +
   84.97 +
   84.98 +    domName = domain.getName()
   84.99 +    new_domid = domid(domName)
  84.100 +
  84.101 +    if (old_domid == new_domid):
  84.102 +        vtpm_cleanup(domName)
  84.103 +        FAIL("xm migrate failed, domain id is still %s (loop=%d)" %
  84.104 +             (old_domid,loop))
  84.105 +
  84.106 +    try:
  84.107 +        console = domain.getConsole()
  84.108 +    except ConsoleError, e:
  84.109 +        vtpm_cleanup(domName)
  84.110 +        FAIL(str(e))
  84.111 +
  84.112 +    try:
  84.113 +        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
  84.114 +    except ConsoleError, e:
  84.115 +        saveLog(console.getHistory())
  84.116 +        vtpm_cleanup(domName)
  84.117 +        FAIL("No result from dumping the PCRs")
  84.118 +
  84.119 +    if not re.search("PCR-00:",run["output"]):
  84.120 +        saveLog(console.getHistory())
  84.121 +        vtpm_cleanup(domName)
  84.122 +	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
  84.123 +
  84.124 +    if not re.search("PCR-00: 1E A7 BD",run["output"]):
  84.125 +        saveLog(console.getHistory())
  84.126 +        vtpm_cleanup(domName)
  84.127 +	FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
  84.128 +
  84.129 +    loop += 1
  84.130 +
  84.131 +domain.closeConsole()
  84.132 +
  84.133 +domain.stop()
  84.134 +
  84.135 +vtpm_cleanup(domName)
    85.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    85.2 +++ b/tools/xm-test/tests/vtpm/08_vtpm-mig_pcrs.py	Wed Jul 05 20:11:37 2006 -0600
    85.3 @@ -0,0 +1,132 @@
    85.4 +#!/usr/bin/python
    85.5 +
    85.6 +# Copyright (C) International Business Machines Corp., 2006
    85.7 +# Author: Stefan Berger <stefanb@us.ibm.com>
    85.8 +
    85.9 +# Positive Test: create domain with virtual TPM attached at build time,
   85.10 +#                extend a pcr
   85.11 +#                check list of pcrs; locally migrate the domain and
   85.12 +#                check list of pcrs again and validate extended pcr
   85.13 +#                This test does local (non-live) migration.
   85.14 +
   85.15 +from XmTestLib import *
   85.16 +from vtpm_utils import *
   85.17 +import commands
   85.18 +import os
   85.19 +import os.path
   85.20 +
   85.21 +config = {"vtpm":"instance=1,backend=0"}
   85.22 +domain = XmTestDomain(extraConfig=config)
   85.23 +domName = domain.getName()
   85.24 +consoleHistory = ""
   85.25 +
   85.26 +try:
   85.27 +    console = domain.start()
   85.28 +except DomainError, e:
   85.29 +    if verbose:
   85.30 +        print e.extra
   85.31 +    vtpm_cleanup(domName)
   85.32 +    FAIL("Unable to create domain (%s)" % domName)
   85.33 +
   85.34 +try:
   85.35 +    console.sendInput("input")
   85.36 +except ConsoleError, e:
   85.37 +    saveLog(console.getHistory())
   85.38 +    vtpm_cleanup(domName)
   85.39 +    FAIL(str(e))
   85.40 +
   85.41 +try:
   85.42 +    run = console.runCmd("mknod /dev/tpm0 c 10 224")
   85.43 +except ConsoleError, e:
   85.44 +    saveLog(console.getHistory())
   85.45 +    vtpm_cleanup(domName)
   85.46 +    FAIL("Error while creating /dev/tpm0")
   85.47 +
   85.48 +try:
   85.49 +    run = console.runCmd("echo -ne \"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\" > /dev/tpm0")
   85.50 +except ConsoleError, e:
   85.51 +    saveLog(console.getHistory())
   85.52 +    vtpm_cleanup(domName)
   85.53 +    FAIL("Error while extending PCR 0")
   85.54 +
   85.55 +try:
   85.56 +    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
   85.57 +except ConsoleError, e:
   85.58 +    saveLog(console.getHistory())
   85.59 +    vtpm_cleanup(domName)
   85.60 +    FAIL("No result from dumping the PCRs")
   85.61 +
   85.62 +
   85.63 +if re.search("No such file",run["output"]):
   85.64 +    vtpm_cleanup(domName)
   85.65 +    FAIL("TPM frontend support not compiled into (domU?) kernel")
   85.66 +
   85.67 +if not re.search("PCR-00:",run["output"]):
   85.68 +    saveLog(console.getHistory())
   85.69 +    vtpm_cleanup(domName)
   85.70 +    FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side: \n%s" % run["output"])
   85.71 +
   85.72 +if not re.search("PCR-00: 1E A7 BD",run["output"]):
   85.73 +    saveLog(console.getHistory())
   85.74 +    FAIL("Extend did not lead to expected result (1E A7 BD ...): \n%s" % run["output"])
   85.75 +
   85.76 +consoleHistory = console.getHistory()
   85.77 +domain.closeConsole()
   85.78 +
   85.79 +old_domid = domid(domName)
   85.80 +
   85.81 +loop = 0
   85.82 +while loop < 3:
   85.83 +    try:
   85.84 +        status, ouptut = traceCommand("xm migrate %s localhost" %
   85.85 +                                      domName,
   85.86 +                                      timeout=90)
   85.87 +    except TimeoutError, e:
   85.88 +        saveLog(consoleHistory)
   85.89 +        vtpm_cleanup(domName)
   85.90 +        FAIL(str(e))
   85.91 +
   85.92 +    if status != 0:
   85.93 +        saveLog(consoleHistory)
   85.94 +        vtpm_cleanup(domName)
   85.95 +        FAIL("xm migrate did not succeed. External device migration activated?")
   85.96 +
   85.97 +
   85.98 +    domName = domain.getName()
   85.99 +    new_domid = domid(domName)
  85.100 +
  85.101 +    if (old_domid == new_domid):
  85.102 +        vtpm_cleanup(domName)
  85.103 +        FAIL("xm migrate failed, domain id is still %s (loop=%d)" %
  85.104 +             (old_domid,loop))
  85.105 +
  85.106 +    try:
  85.107 +        console = domain.getConsole()
  85.108 +    except ConsoleError, e:
  85.109 +        vtpm_cleanup(domName)
  85.110 +        FAIL(str(e))
  85.111 +
  85.112 +    try:
  85.113 +        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
  85.114 +    except ConsoleError, e:
  85.115 +        saveLog(console.getHistory())
  85.116 +        vtpm_cleanup(domName)
  85.117 +        FAIL("No result from dumping the PCRs")
  85.118 +
  85.119 +    if not re.search("PCR-00:",run["output"]):
  85.120 +        saveLog(console.getHistory())
  85.121 +        vtpm_cleanup(domName)
  85.122 +	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
  85.123 +
  85.124 +    if not re.search("PCR-00: 1E A7 BD",run["output"]):
  85.125 +        saveLog(console.getHistory())
  85.126 +        vtpm_cleanup(domName)
  85.127 +	FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
  85.128 +
  85.129 +    loop += 1
  85.130 +
  85.131 +domain.closeConsole()
  85.132 +
  85.133 +domain.stop()
  85.134 +
  85.135 +vtpm_cleanup(domName)
    86.1 --- a/tools/xm-test/tests/vtpm/Makefile.am	Wed Jul 05 10:23:54 2006 -0600
    86.2 +++ b/tools/xm-test/tests/vtpm/Makefile.am	Wed Jul 05 20:11:37 2006 -0600
    86.3 @@ -4,7 +4,10 @@ TESTS = 01_vtpm-list_pos.test \
    86.4          02_vtpm-cat_pcrs.test \
    86.5          03_vtpm-susp_res.test \
    86.6          04_vtpm-loc_migr.test \
    86.7 -        05_vtpm-loc_migr.test
    86.8 +        05_vtpm-loc_migr.test \
    86.9 +        06_vtpm-susp_res_pcrs.test \
   86.10 +        07_vtpm-mig_pcrs.test \
   86.11 +        08_vtpm-mig_pcrs.test
   86.12  
   86.13  XFAIL_TESTS =
   86.14  
    87.1 --- a/tools/xm-test/tests/vtpm/vtpm_utils.py	Wed Jul 05 10:23:54 2006 -0600
    87.2 +++ b/tools/xm-test/tests/vtpm/vtpm_utils.py	Wed Jul 05 20:11:37 2006 -0600
    87.3 @@ -16,4 +16,4 @@ if output == "":
    87.4      FAIL("virtual TPM manager must be started to run this test")
    87.5  
    87.6  def vtpm_cleanup(domName):
    87.7 -	traceCommand("/etc/xen/scripts/vtpm-delete %s" % domName)
    87.8 +    traceCommand("/etc/xen/scripts/vtpm-delete %s" % domName)
    88.1 --- a/xen/arch/ia64/xen/dom0_ops.c	Wed Jul 05 10:23:54 2006 -0600
    88.2 +++ b/xen/arch/ia64/xen/dom0_ops.c	Wed Jul 05 20:11:37 2006 -0600
    88.3 @@ -36,7 +36,7 @@ long arch_do_dom0_op(dom0_op_t *op, XEN_
    88.4      case DOM0_GETPAGEFRAMEINFO:
    88.5      {
    88.6          struct page_info *page;
    88.7 -        unsigned long mfn = op->u.getpageframeinfo.mfn;
    88.8 +        unsigned long mfn = op->u.getpageframeinfo.gmfn;
    88.9          domid_t dom = op->u.getpageframeinfo.domain;
   88.10          struct domain *d;
   88.11  
    89.1 --- a/xen/arch/ia64/xen/xensetup.c	Wed Jul 05 10:23:54 2006 -0600
    89.2 +++ b/xen/arch/ia64/xen/xensetup.c	Wed Jul 05 20:11:37 2006 -0600
    89.3 @@ -425,8 +425,9 @@ void start_kernel(void)
    89.4  
    89.5      scheduler_init();
    89.6      idle_vcpu[0] = (struct vcpu*) ia64_r13;
    89.7 -    idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
    89.8 -    BUG_ON(idle_domain == NULL);
    89.9 +    idle_domain = domain_create(IDLE_DOMAIN_ID);
   89.10 +    if ( (idle_domain == NULL) || (alloc_vcpu(idle_domain, 0, 0) == NULL) )
   89.11 +        BUG();
   89.12  
   89.13      late_setup_arch(&cmdline);
   89.14      alloc_dom_xen_and_dom_io();
   89.15 @@ -503,9 +504,8 @@ printk("num_online_cpus=%d, max_cpus=%d\
   89.16      }
   89.17  
   89.18      /* Create initial domain 0. */
   89.19 -    dom0 = domain_create(0, 0);
   89.20 -
   89.21 -    if ( dom0 == NULL )
   89.22 +    dom0 = domain_create(0);
   89.23 +    if ( (dom0 == NULL) || (alloc_vcpu(dom0, 0, 0) == NULL) )
   89.24          panic("Error creating domain 0\n");
   89.25  
   89.26      set_bit(_DOMF_privileged, &dom0->domain_flags);
    90.1 --- a/xen/arch/x86/dom0_ops.c	Wed Jul 05 10:23:54 2006 -0600
    90.2 +++ b/xen/arch/x86/dom0_ops.c	Wed Jul 05 20:11:37 2006 -0600
    90.3 @@ -207,7 +207,7 @@ long arch_do_dom0_op(struct dom0_op *op,
    90.4      case DOM0_GETPAGEFRAMEINFO:
    90.5      {
    90.6          struct page_info *page;
    90.7 -        unsigned long mfn = op->u.getpageframeinfo.mfn;
    90.8 +        unsigned long mfn = op->u.getpageframeinfo.gmfn;
    90.9          domid_t dom = op->u.getpageframeinfo.domain;
   90.10          struct domain *d;
   90.11  
   90.12 @@ -407,15 +407,17 @@ long arch_do_dom0_op(struct dom0_op *op,
   90.13  
   90.14      case DOM0_HYPERCALL_INIT:
   90.15      {
   90.16 -        struct domain *d; 
   90.17 -        unsigned long mfn = op->u.hypercall_init.mfn;
   90.18 +        struct domain *d = find_domain_by_id(op->u.hypercall_init.domain);
   90.19 +        unsigned long gmfn = op->u.hypercall_init.gmfn;
   90.20 +        unsigned long mfn;
   90.21          void *hypercall_page;
   90.22  
   90.23          ret = -ESRCH;
   90.24 -        if ( unlikely((d = find_domain_by_id(
   90.25 -            op->u.hypercall_init.domain)) == NULL) )
   90.26 +        if ( unlikely(d == NULL) )
   90.27              break;
   90.28  
   90.29 +        mfn = gmfn_to_mfn(d, gmfn);
   90.30 +
   90.31          ret = -EACCES;
   90.32          if ( !mfn_valid(mfn) ||
   90.33               !get_page_and_type(mfn_to_page(mfn), d, PGT_writable_page) )
    91.1 --- a/xen/arch/x86/domain.c	Wed Jul 05 10:23:54 2006 -0600
    91.2 +++ b/xen/arch/x86/domain.c	Wed Jul 05 20:11:37 2006 -0600
    91.3 @@ -67,16 +67,11 @@ static void default_idle(void)
    91.4  
    91.5  void idle_loop(void)
    91.6  {
    91.7 -    int cpu = smp_processor_id();
    91.8 -
    91.9      for ( ; ; )
   91.10      {
   91.11          page_scrub_schedule_work();
   91.12 -
   91.13          default_idle();
   91.14 -
   91.15 -        if ( softirq_pending(cpu) )
   91.16 -            do_softirq();
   91.17 +        do_softirq();
   91.18      }
   91.19  }
   91.20  
   91.21 @@ -956,7 +951,7 @@ void domain_relinquish_resources(struct 
   91.22          }
   91.23      }
   91.24  
   91.25 -    if ( hvm_guest(d->vcpu[0]) )
   91.26 +    if ( d->vcpu[0] && hvm_guest(d->vcpu[0]) )
   91.27          hvm_relinquish_guest_resources(d);
   91.28  
   91.29      shadow_mode_disable(d);
    92.1 --- a/xen/arch/x86/hvm/svm/svm.c	Wed Jul 05 10:23:54 2006 -0600
    92.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Wed Jul 05 20:11:37 2006 -0600
    92.3 @@ -962,8 +962,8 @@ static void svm_vmexit_do_cpuid(struct v
    92.4                  !vlapic_global_enabled((VLAPIC(v))) )
    92.5          {
    92.6              /* Since the apic is disabled, avoid any confusion 
    92.7 -	       about SMP cpus being available */
    92.8 -	    clear_bit(X86_FEATURE_APIC, &edx);
    92.9 +               about SMP cpus being available */
   92.10 +            clear_bit(X86_FEATURE_APIC, &edx);
   92.11          }
   92.12  
   92.13  #if CONFIG_PAGING_LEVELS < 3
   92.14 @@ -974,52 +974,51 @@ static void svm_vmexit_do_cpuid(struct v
   92.15          if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 )
   92.16          {
   92.17              if ( !v->domain->arch.hvm_domain.pae_enabled )
   92.18 -            {
   92.19 -		clear_bit(X86_FEATURE_PAE, &edx);
   92.20 -            }
   92.21 +                clear_bit(X86_FEATURE_PAE, &edx);
   92.22              clear_bit(X86_FEATURE_PSE, &edx);
   92.23              clear_bit(X86_FEATURE_PSE36, &edx);
   92.24          }
   92.25 -#endif	
   92.26 +#endif
   92.27          /* Clear out reserved bits. */
   92.28          ecx &= ~SVM_VCPU_CPUID_L1_ECX_RESERVED;
   92.29          edx &= ~SVM_VCPU_CPUID_L1_EDX_RESERVED;
   92.30  
   92.31          clear_bit(X86_FEATURE_MWAIT & 31, &ecx);
   92.32  
   92.33 -	/* Guest should only see one logical processor.
   92.34 -	 * See details on page 23 of AMD CPUID Specification. 
   92.35 -	*/
   92.36 -	clear_bit(X86_FEATURE_HT, &edx);  /* clear the hyperthread bit */
   92.37 -	ebx &= 0xFF00FFFF;  /* clear the logical processor count when HTT=0 */
   92.38 -	ebx |= 0x00010000;  /* set to 1 just for precaution */
   92.39 -
   92.40 -	/* Disable machine check architecture */
   92.41 -	clear_bit(X86_FEATURE_MCA, &edx);
   92.42 -	clear_bit(X86_FEATURE_MCE, &edx);
   92.43 +        /* Guest should only see one logical processor.
   92.44 +         * See details on page 23 of AMD CPUID Specification. 
   92.45 +         */
   92.46 +        clear_bit(X86_FEATURE_HT, &edx);  /* clear the hyperthread bit */
   92.47 +        ebx &= 0xFF00FFFF;  /* clear the logical processor count when HTT=0 */
   92.48 +        ebx |= 0x00010000;  /* set to 1 just for precaution */
   92.49 +
   92.50 +        /* Disable machine check architecture */
   92.51 +        clear_bit(X86_FEATURE_MCA, &edx);
   92.52 +        clear_bit(X86_FEATURE_MCE, &edx);
   92.53      }
   92.54 -    else if ( ( input > 0x00000005 ) && ( input < 0x80000000 ) )
   92.55 +    else if ( (input > 0x00000005) && (input < 0x80000000) )
   92.56      {
   92.57 -	eax = ebx = ecx = edx = 0x0;
   92.58 +        if ( !cpuid_hypervisor_leaves(input, &eax, &ebx, &ecx, &edx) )
   92.59 +            eax = ebx = ecx = edx = 0;
   92.60      }
   92.61      else if ( input == 0x80000001 )
   92.62      {
   92.63 -	/* We duplicate some CPUID_00000001 code because many bits of 
   92.64 -	   CPUID_80000001_EDX overlaps with CPUID_00000001_EDX. */
   92.65 +        /* We duplicate some CPUID_00000001 code because many bits of 
   92.66 +           CPUID_80000001_EDX overlaps with CPUID_00000001_EDX. */
   92.67  
   92.68          if ( !hvm_apic_support(v->domain) ||
   92.69 -	     !vlapic_global_enabled((VLAPIC(v))) )
   92.70 +             !vlapic_global_enabled((VLAPIC(v))) )
   92.71          {
   92.72              /* Since the apic is disabled, avoid any confusion 
   92.73 -	       about SMP cpus being available */
   92.74 -	    clear_bit(X86_FEATURE_APIC, &edx);
   92.75 +               about SMP cpus being available */
   92.76 +            clear_bit(X86_FEATURE_APIC, &edx);
   92.77          }
   92.78  
   92.79 -	/* Clear the Cmp_Legacy bit 
   92.80 -	 * This bit is supposed to be zero when HTT = 0.
   92.81 -	 * See details on page 23 of AMD CPUID Specification. 
   92.82 -	*/
   92.83 -	clear_bit(X86_FEATURE_CMP_LEGACY & 31, &ecx);
   92.84 +        /* Clear the Cmp_Legacy bit 
   92.85 +         * This bit is supposed to be zero when HTT = 0.
   92.86 +         * See details on page 23 of AMD CPUID Specification. 
   92.87 +         */
   92.88 +        clear_bit(X86_FEATURE_CMP_LEGACY & 31, &ecx);
   92.89  
   92.90  #ifdef __i386__
   92.91          /* Mask feature for Intel ia32e or AMD long mode. */
   92.92 @@ -1030,7 +1029,7 @@ static void svm_vmexit_do_cpuid(struct v
   92.93  #endif
   92.94  
   92.95  #if CONFIG_PAGING_LEVELS < 3
   92.96 -	clear_bit(X86_FEATURE_NX & 31, &edx);
   92.97 +        clear_bit(X86_FEATURE_NX & 31, &edx);
   92.98          clear_bit(X86_FEATURE_PAE, &edx);
   92.99          clear_bit(X86_FEATURE_PSE, &edx);
  92.100          clear_bit(X86_FEATURE_PSE36, &edx);
  92.101 @@ -1039,29 +1038,29 @@ static void svm_vmexit_do_cpuid(struct v
  92.102          {
  92.103              if ( !v->domain->arch.hvm_domain.pae_enabled )
  92.104              {
  92.105 -		clear_bit(X86_FEATURE_NX & 31, &edx);
  92.106 -		clear_bit(X86_FEATURE_PAE, &edx);
  92.107 +                clear_bit(X86_FEATURE_NX & 31, &edx);
  92.108 +                clear_bit(X86_FEATURE_PAE, &edx);
  92.109              }
  92.110              clear_bit(X86_FEATURE_PSE, &edx);
  92.111              clear_bit(X86_FEATURE_PSE36, &edx);
  92.112          }
  92.113 -#endif	
  92.114 +#endif
  92.115  
  92.116          /* Make SVM feature invisible to the guest. */
  92.117          clear_bit(X86_FEATURE_SVME & 31, &ecx);
  92.118 -	
  92.119 -	/* So far, we do not support 3DNow for the guest. */
  92.120 -	clear_bit(X86_FEATURE_3DNOW & 31, &edx);
  92.121 -	clear_bit(X86_FEATURE_3DNOWEXT & 31, &edx);
  92.122 +
  92.123 +        /* So far, we do not support 3DNow for the guest. */
  92.124 +        clear_bit(X86_FEATURE_3DNOW & 31, &edx);
  92.125 +        clear_bit(X86_FEATURE_3DNOWEXT & 31, &edx);
  92.126      }
  92.127      else if ( ( input == 0x80000007 ) || ( input == 0x8000000A  ) )
  92.128      {
  92.129 -	/* Mask out features of power management and SVM extension. */
  92.130 -	eax = ebx = ecx = edx = 0;
  92.131 +        /* Mask out features of power management and SVM extension. */
  92.132 +        eax = ebx = ecx = edx = 0;
  92.133      }
  92.134      else if ( input == 0x80000008 )
  92.135      {
  92.136 -	ecx &= 0xFFFFFF00; /* Make sure Number of CPU core is 1 when HTT=0 */
  92.137 +        ecx &= 0xFFFFFF00; /* Make sure Number of CPU core is 1 when HTT=0 */
  92.138      }
  92.139  
  92.140      regs->eax = (unsigned long)eax;
  92.141 @@ -1214,8 +1213,9 @@ static void svm_dr_access (struct vcpu *
  92.142  }
  92.143  
  92.144  
  92.145 -static void svm_get_prefix_info(struct vmcb_struct *vmcb, 
  92.146 -		unsigned int dir, segment_selector_t **seg, unsigned int *asize)
  92.147 +static void svm_get_prefix_info(
  92.148 +    struct vmcb_struct *vmcb, 
  92.149 +    unsigned int dir, segment_selector_t **seg, unsigned int *asize)
  92.150  {
  92.151      unsigned char inst[MAX_INST_LEN];
  92.152      int i;
  92.153 @@ -1287,9 +1287,10 @@ static void svm_get_prefix_info(struct v
  92.154  
  92.155  
  92.156  /* Get the address of INS/OUTS instruction */
  92.157 -static inline int svm_get_io_address(struct vcpu *v, 
  92.158 -		struct cpu_user_regs *regs, unsigned int dir, 
  92.159 -        unsigned long *count, unsigned long *addr)
  92.160 +static inline int svm_get_io_address(
  92.161 +    struct vcpu *v, 
  92.162 +    struct cpu_user_regs *regs, unsigned int dir, 
  92.163 +    unsigned long *count, unsigned long *addr)
  92.164  {
  92.165      unsigned long        reg;
  92.166      unsigned int         asize = 0;
  92.167 @@ -2697,9 +2698,9 @@ asmlinkage void svm_vmexit_handler(struc
  92.168  
  92.169      if (exit_reason == -1)
  92.170      {
  92.171 +        svm_dump_vmcb(__func__, vmcb);
  92.172          printk("%s: exit_reason == -1 - Did someone clobber the VMCB\n", 
  92.173                  __func__);
  92.174 -        BUG();
  92.175          domain_crash_synchronous();
  92.176      }
  92.177  
    93.1 --- a/xen/arch/x86/hvm/vmx/vmcs.c	Wed Jul 05 10:23:54 2006 -0600
    93.2 +++ b/xen/arch/x86/hvm/vmx/vmcs.c	Wed Jul 05 20:11:37 2006 -0600
    93.3 @@ -36,38 +36,57 @@
    93.4  #include <xen/kernel.h>
    93.5  #include <asm/shadow.h>
    93.6  #include <xen/keyhandler.h>
    93.7 +
    93.8  #if CONFIG_PAGING_LEVELS >= 3
    93.9  #include <asm/shadow_64.h>
   93.10  #endif
   93.11  
   93.12 -int vmcs_size;
   93.13 +static int vmcs_size;
   93.14 +static int vmcs_order;
   93.15 +static u32 vmcs_revision_id;
   93.16  
   93.17 -struct vmcs_struct *vmx_alloc_vmcs(void)
   93.18 +void vmx_init_vmcs_config(void)
   93.19 +{
   93.20 +    u32 vmx_msr_low, vmx_msr_high;
   93.21 +
   93.22 +    if ( vmcs_size )
   93.23 +        return;
   93.24 +
   93.25 +    rdmsr(MSR_IA32_VMX_BASIC_MSR, vmx_msr_low, vmx_msr_high);
   93.26 +
   93.27 +    vmcs_revision_id = vmx_msr_low;
   93.28 +
   93.29 +    vmcs_size  = vmx_msr_high & 0x1fff;
   93.30 +    vmcs_order = get_order_from_bytes(vmcs_size);
   93.31 +}
   93.32 +
   93.33 +static struct vmcs_struct *vmx_alloc_vmcs(void)
   93.34  {
   93.35      struct vmcs_struct *vmcs;
   93.36 -    u32 vmx_msr_low, vmx_msr_high;
   93.37  
   93.38 -    rdmsr(MSR_IA32_VMX_BASIC_MSR, vmx_msr_low, vmx_msr_high);
   93.39 -    vmcs_size = vmx_msr_high & 0x1fff;
   93.40 -    vmcs = alloc_xenheap_pages(get_order_from_bytes(vmcs_size));
   93.41 -    memset((char *)vmcs, 0, vmcs_size); /* don't remove this */
   93.42 +    if ( (vmcs = alloc_xenheap_pages(vmcs_order)) == NULL )
   93.43 +    {
   93.44 +        DPRINTK("Failed to allocate VMCS.\n");
   93.45 +        return NULL;
   93.46 +    }
   93.47  
   93.48 -    vmcs->vmcs_revision_id = vmx_msr_low;
   93.49 +    memset(vmcs, 0, vmcs_size); /* don't remove this */
   93.50 +    vmcs->vmcs_revision_id = vmcs_revision_id;
   93.51 +
   93.52      return vmcs;
   93.53  }
   93.54  
   93.55 -static void free_vmcs(struct vmcs_struct *vmcs)
   93.56 +static void vmx_free_vmcs(struct vmcs_struct *vmcs)
   93.57  {
   93.58 -    int order;
   93.59 -
   93.60 -    order = get_order_from_bytes(vmcs_size);
   93.61 -    free_xenheap_pages(vmcs, order);
   93.62 +    free_xenheap_pages(vmcs, vmcs_order);
   93.63  }
   93.64  
   93.65  static void __vmx_clear_vmcs(void *info)
   93.66  {
   93.67      struct vcpu *v = info;
   93.68 +
   93.69      __vmpclear(virt_to_maddr(v->arch.hvm_vmx.vmcs));
   93.70 +
   93.71      v->arch.hvm_vmx.active_cpu = -1;
   93.72      v->arch.hvm_vmx.launched   = 0;
   93.73  }
   93.74 @@ -127,11 +146,19 @@ void vmx_vmcs_exit(struct vcpu *v)
   93.75      vcpu_unpause(v);
   93.76  }
   93.77  
   93.78 +struct vmcs_struct *vmx_alloc_host_vmcs(void)
   93.79 +{
   93.80 +    return vmx_alloc_vmcs();
   93.81 +}
   93.82 +
   93.83 +void vmx_free_host_vmcs(struct vmcs_struct *vmcs)
   93.84 +{
   93.85 +    vmx_free_vmcs(vmcs);
   93.86 +}
   93.87 +
   93.88  static inline int construct_vmcs_controls(struct arch_vmx_struct *arch_vmx)
   93.89  {
   93.90      int error = 0;
   93.91 -    void *io_bitmap_a;
   93.92 -    void *io_bitmap_b;
   93.93  
   93.94      error |= __vmwrite(PIN_BASED_VM_EXEC_CONTROL,
   93.95                         MONITOR_PIN_BASED_EXEC_CONTROLS);
   93.96 @@ -140,19 +167,8 @@ static inline int construct_vmcs_control
   93.97  
   93.98      error |= __vmwrite(VM_ENTRY_CONTROLS, MONITOR_VM_ENTRY_CONTROLS);
   93.99  
  93.100 -    /* need to use 0x1000 instead of PAGE_SIZE */
  93.101 -    io_bitmap_a = (void*) alloc_xenheap_pages(get_order_from_bytes(0x1000));
  93.102 -    io_bitmap_b = (void*) alloc_xenheap_pages(get_order_from_bytes(0x1000));
  93.103 -    memset(io_bitmap_a, 0xff, 0x1000);
  93.104 -    /* don't bother debug port access */
  93.105 -    clear_bit(PC_DEBUG_PORT, io_bitmap_a);
  93.106 -    memset(io_bitmap_b, 0xff, 0x1000);
  93.107 -
  93.108 -    error |= __vmwrite(IO_BITMAP_A, (u64) virt_to_maddr(io_bitmap_a));
  93.109 -    error |= __vmwrite(IO_BITMAP_B, (u64) virt_to_maddr(io_bitmap_b));
  93.110 -
  93.111 -    arch_vmx->io_bitmap_a = io_bitmap_a;
  93.112 -    arch_vmx->io_bitmap_b = io_bitmap_b;
  93.113 +    error |= __vmwrite(IO_BITMAP_A, (u64)virt_to_maddr(arch_vmx->io_bitmap_a));
  93.114 +    error |= __vmwrite(IO_BITMAP_B, (u64)virt_to_maddr(arch_vmx->io_bitmap_b));
  93.115  
  93.116      return error;
  93.117  }
  93.118 @@ -428,84 +444,71 @@ static inline int construct_vmcs_host(vo
  93.119  }
  93.120  
  93.121  /*
  93.122 - * Need to extend to support full virtualization.
  93.123 + * the working VMCS pointer has been set properly
  93.124 + * just before entering this function.
  93.125   */
  93.126  static int construct_vmcs(struct vcpu *v,
  93.127                            cpu_user_regs_t *regs)
  93.128  {
  93.129      struct arch_vmx_struct *arch_vmx = &v->arch.hvm_vmx;
  93.130      int error;
  93.131 -    long rc;
  93.132 -
  93.133 -    memset(arch_vmx, 0, sizeof(struct arch_vmx_struct));
  93.134 -
  93.135 -    spin_lock_init(&arch_vmx->vmcs_lock);
  93.136 -    arch_vmx->active_cpu = -1;
  93.137  
  93.138 -    /*
  93.139 -     * Create a new VMCS
  93.140 -     */
  93.141 -    if (!(arch_vmx->vmcs = vmx_alloc_vmcs())) {
  93.142 -        printk("Failed to create a new VMCS\n");
  93.143 -        return -ENOMEM;
  93.144 -    }
  93.145 -
  93.146 -    vmx_clear_vmcs(v);
  93.147 -    vmx_load_vmcs(v);
  93.148 -
  93.149 -    if ((error = construct_vmcs_controls(arch_vmx))) {
  93.150 -        printk("construct_vmcs: construct_vmcs_controls failed\n");
  93.151 -        rc = -EINVAL;
  93.152 -        goto err_out;
  93.153 +    if ( (error = construct_vmcs_controls(arch_vmx)) ) {
  93.154 +        printk("construct_vmcs: construct_vmcs_controls failed.\n");
  93.155 +        return error;
  93.156      }
  93.157  
  93.158      /* host selectors */
  93.159 -    if ((error = construct_vmcs_host())) {
  93.160 -        printk("construct_vmcs: construct_vmcs_host failed\n");
  93.161 -        rc = -EINVAL;
  93.162 -        goto err_out;
  93.163 +    if ( (error = construct_vmcs_host()) ) {
  93.164 +        printk("construct_vmcs: construct_vmcs_host failed.\n");
  93.165 +        return error;
  93.166      }
  93.167  
  93.168      /* guest selectors */
  93.169 -    if ((error = construct_init_vmcs_guest(regs))) {
  93.170 -        printk("construct_vmcs: construct_vmcs_guest failed\n");
  93.171 -        rc = -EINVAL;
  93.172 -        goto err_out;
  93.173 +    if ( (error = construct_init_vmcs_guest(regs)) ) {
  93.174 +        printk("construct_vmcs: construct_vmcs_guest failed.\n");
  93.175 +        return error;
  93.176      }
  93.177  
  93.178 -    if ((error |= __vmwrite(EXCEPTION_BITMAP,
  93.179 -                            MONITOR_DEFAULT_EXCEPTION_BITMAP))) {
  93.180 -        printk("construct_vmcs: setting Exception bitmap failed\n");
  93.181 -        rc = -EINVAL;
  93.182 -        goto err_out;
  93.183 +    if ( (error = __vmwrite(EXCEPTION_BITMAP,
  93.184 +                            MONITOR_DEFAULT_EXCEPTION_BITMAP)) ) {
  93.185 +        printk("construct_vmcs: setting exception bitmap failed.\n");
  93.186 +        return error;
  93.187      }
  93.188  
  93.189 -    if (regs->eflags & EF_TF)
  93.190 -        __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
  93.191 +    if ( regs->eflags & EF_TF )
  93.192 +        error = __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
  93.193      else
  93.194 -        __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
  93.195 +        error = __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
  93.196  
  93.197 -    return 0;
  93.198 +    return error;
  93.199 +}
  93.200  
  93.201 -err_out:
  93.202 -    vmx_destroy_vmcs(v);
  93.203 -    return rc;
  93.204 +int vmx_create_vmcs(struct vcpu *v)
  93.205 +{
  93.206 +    if ( (v->arch.hvm_vmx.vmcs = vmx_alloc_vmcs()) == NULL )
  93.207 +        return -ENOMEM;
  93.208 +    __vmx_clear_vmcs(v);
  93.209 +    return 0;
  93.210  }
  93.211  
  93.212  void vmx_destroy_vmcs(struct vcpu *v)
  93.213  {
  93.214      struct arch_vmx_struct *arch_vmx = &v->arch.hvm_vmx;
  93.215  
  93.216 +    if ( arch_vmx->vmcs == NULL )
  93.217 +        return;
  93.218 +
  93.219      vmx_clear_vmcs(v);
  93.220  
  93.221 -    free_vmcs(arch_vmx->vmcs);
  93.222 -    arch_vmx->vmcs = NULL;
  93.223 +    free_xenheap_pages(arch_vmx->io_bitmap_a, IO_BITMAP_ORDER);
  93.224 +    free_xenheap_pages(arch_vmx->io_bitmap_b, IO_BITMAP_ORDER);
  93.225  
  93.226 -    free_xenheap_pages(arch_vmx->io_bitmap_a, get_order_from_bytes(0x1000));
  93.227      arch_vmx->io_bitmap_a = NULL;
  93.228 +    arch_vmx->io_bitmap_b = NULL;
  93.229  
  93.230 -    free_xenheap_pages(arch_vmx->io_bitmap_b, get_order_from_bytes(0x1000));
  93.231 -    arch_vmx->io_bitmap_b = NULL;
  93.232 +    vmx_free_vmcs(arch_vmx->vmcs);
  93.233 +    arch_vmx->vmcs = NULL;
  93.234  }
  93.235  
  93.236  void vm_launch_fail(unsigned long eflags)
  93.237 @@ -544,19 +547,20 @@ void arch_vmx_do_resume(struct vcpu *v)
  93.238  
  93.239  void arch_vmx_do_launch(struct vcpu *v)
  93.240  {
  93.241 -    int error;
  93.242      cpu_user_regs_t *regs = &current->arch.guest_context.user_regs;
  93.243  
  93.244 -    error = construct_vmcs(v, regs);
  93.245 -    if ( error < 0 )
  93.246 +    vmx_load_vmcs(v);
  93.247 +
  93.248 +    if ( construct_vmcs(v, regs) < 0 )
  93.249      {
  93.250 -        if (v->vcpu_id == 0) {
  93.251 -            printk("Failed to construct a new VMCS for BSP.\n");
  93.252 +        if ( v->vcpu_id == 0 ) {
  93.253 +            printk("Failed to construct VMCS for BSP.\n");
  93.254          } else {
  93.255 -            printk("Failed to construct a new VMCS for AP %d\n", v->vcpu_id);
  93.256 +            printk("Failed to construct VMCS for AP %d.\n", v->vcpu_id);
  93.257          }
  93.258          domain_crash_synchronous();
  93.259      }
  93.260 +
  93.261      vmx_do_launch(v);
  93.262      reset_stack_and_jump(vmx_asm_do_vmentry);
  93.263  }
    94.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Wed Jul 05 10:23:54 2006 -0600
    94.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Wed Jul 05 20:11:37 2006 -0600
    94.3 @@ -54,34 +54,73 @@ static unsigned long trace_values[NR_CPU
    94.4  static void vmx_ctxt_switch_from(struct vcpu *v);
    94.5  static void vmx_ctxt_switch_to(struct vcpu *v);
    94.6  
    94.7 -void vmx_final_setup_guest(struct vcpu *v)
    94.8 +static int vmx_initialize_guest_resources(struct vcpu *v)
    94.9  {
   94.10 +    struct domain *d = v->domain;
   94.11 +    struct vcpu *vc;
   94.12 +    void *io_bitmap_a, *io_bitmap_b;
   94.13 +    int rc;
   94.14 +
   94.15      v->arch.schedule_tail    = arch_vmx_do_launch;
   94.16      v->arch.ctxt_switch_from = vmx_ctxt_switch_from;
   94.17      v->arch.ctxt_switch_to   = vmx_ctxt_switch_to;
   94.18  
   94.19 -    if ( v->vcpu_id == 0 )
   94.20 -    {
   94.21 -        struct domain *d = v->domain;
   94.22 -        struct vcpu *vc;
   94.23 -
   94.24 -        /* Initialize monitor page table */
   94.25 -        for_each_vcpu(d, vc)
   94.26 -            vc->arch.monitor_table = pagetable_null();
   94.27 +    if ( v->vcpu_id != 0 )
   94.28 +        return 1;
   94.29  
   94.30 -        /*
   94.31 -         * Required to do this once per domain
   94.32 -         * XXX todo: add a seperate function to do these.
   94.33 -         */
   94.34 -        memset(&d->shared_info->evtchn_mask[0], 0xff,
   94.35 -               sizeof(d->shared_info->evtchn_mask));
   94.36 +    for_each_vcpu ( d, vc )
   94.37 +    {
   94.38 +        /* Initialize monitor page table */
   94.39 +        vc->arch.monitor_table = pagetable_null();
   94.40  
   94.41 -        /* Put the domain in shadow mode even though we're going to be using
   94.42 -         * the shared 1:1 page table initially. It shouldn't hurt */
   94.43 -        shadow_mode_enable(d,
   94.44 -                           SHM_enable|SHM_refcounts|
   94.45 -                           SHM_translate|SHM_external|SHM_wr_pt_pte);
   94.46 +        memset(&vc->arch.hvm_vmx, 0, sizeof(struct arch_vmx_struct));
   94.47 +
   94.48 +        if ( (rc = vmx_create_vmcs(vc)) != 0 )
   94.49 +        {
   94.50 +            DPRINTK("Failed to create VMCS for vcpu %d: err=%d.\n",
   94.51 +                    vc->vcpu_id, rc);
   94.52 +            return 0;
   94.53 +        }
   94.54 +
   94.55 +        spin_lock_init(&vc->arch.hvm_vmx.vmcs_lock);
   94.56 +
   94.57 +        if ( (io_bitmap_a = alloc_xenheap_pages(IO_BITMAP_ORDER)) == NULL )
   94.58 +        {
   94.59 +            DPRINTK("Failed to allocate io bitmap b for vcpu %d.\n",
   94.60 +                    vc->vcpu_id);
   94.61 +            return 0;
   94.62 +        }
   94.63 +
   94.64 +        if ( (io_bitmap_b = alloc_xenheap_pages(IO_BITMAP_ORDER)) == NULL )
   94.65 +        {
   94.66 +            DPRINTK("Failed to allocate io bitmap b for vcpu %d.\n",
   94.67 +                    vc->vcpu_id);
   94.68 +            return 0;
   94.69 +        }
   94.70 +
   94.71 +        memset(io_bitmap_a, 0xff, 0x1000);
   94.72 +        memset(io_bitmap_b, 0xff, 0x1000);
   94.73 +
   94.74 +        /* don't bother debug port access */
   94.75 +        clear_bit(PC_DEBUG_PORT, io_bitmap_a);
   94.76 +
   94.77 +        vc->arch.hvm_vmx.io_bitmap_a = io_bitmap_a;
   94.78 +        vc->arch.hvm_vmx.io_bitmap_b = io_bitmap_b;
   94.79      }
   94.80 +
   94.81 +    /*
   94.82 +     * Required to do this once per domain XXX todo: add a seperate function 
   94.83 +     * to do these.
   94.84 +     */
   94.85 +    memset(&d->shared_info->evtchn_mask[0], 0xff,
   94.86 +           sizeof(d->shared_info->evtchn_mask));
   94.87 +
   94.88 +    /* Put the domain in shadow mode even though we're going to be using
   94.89 +     * the shared 1:1 page table initially. It shouldn't hurt */
   94.90 +    shadow_mode_enable(
   94.91 +        d, SHM_enable|SHM_refcounts|SHM_translate|SHM_external|SHM_wr_pt_pte);
   94.92 +
   94.93 +    return 1;
   94.94  }
   94.95  
   94.96  static void vmx_relinquish_guest_resources(struct domain *d)
   94.97 @@ -90,9 +129,9 @@ static void vmx_relinquish_guest_resourc
   94.98  
   94.99      for_each_vcpu ( d, v )
  94.100      {
  94.101 +        vmx_destroy_vmcs(v);
  94.102          if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
  94.103              continue;
  94.104 -        vmx_destroy_vmcs(v);
  94.105          free_monitor_pagetable(v);
  94.106          kill_timer(&v->arch.hvm_vmx.hlt_timer);
  94.107          if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) )
  94.108 @@ -444,12 +483,6 @@ void stop_vmx(void)
  94.109          __vmxoff();
  94.110  }
  94.111  
  94.112 -int vmx_initialize_guest_resources(struct vcpu *v)
  94.113 -{
  94.114 -    vmx_final_setup_guest(v);
  94.115 -    return 1;
  94.116 -}
  94.117 -
  94.118  void vmx_migrate_timers(struct vcpu *v)
  94.119  {
  94.120      struct periodic_time *pt = &(v->domain->arch.hvm_domain.pl_time.periodic_tm);
  94.121 @@ -638,58 +671,61 @@ static int check_vmx_controls(u32 ctrls,
  94.122  
  94.123  int start_vmx(void)
  94.124  {
  94.125 +    u32 eax, edx;
  94.126      struct vmcs_struct *vmcs;
  94.127 -    u32 ecx;
  94.128 -    u32 eax, edx;
  94.129 -    u64 phys_vmcs;      /* debugging */
  94.130  
  94.131      /*
  94.132       * Xen does not fill x86_capability words except 0.
  94.133       */
  94.134 -    ecx = cpuid_ecx(1);
  94.135 -    boot_cpu_data.x86_capability[4] = ecx;
  94.136 +    boot_cpu_data.x86_capability[4] = cpuid_ecx(1);
  94.137  
  94.138      if (!(test_bit(X86_FEATURE_VMXE, &boot_cpu_data.x86_capability)))
  94.139          return 0;
  94.140  
  94.141      rdmsr(IA32_FEATURE_CONTROL_MSR, eax, edx);
  94.142  
  94.143 -    if (eax & IA32_FEATURE_CONTROL_MSR_LOCK) {
  94.144 -        if ((eax & IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON) == 0x0) {
  94.145 +    if ( eax & IA32_FEATURE_CONTROL_MSR_LOCK )
  94.146 +    {
  94.147 +        if ( (eax & IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON) == 0x0 )
  94.148 +        {
  94.149              printk("VMX disabled by Feature Control MSR.\n");
  94.150              return 0;
  94.151          }
  94.152      }
  94.153 -    else {
  94.154 +    else
  94.155 +    {
  94.156          wrmsr(IA32_FEATURE_CONTROL_MSR,
  94.157                IA32_FEATURE_CONTROL_MSR_LOCK |
  94.158                IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON, 0);
  94.159      }
  94.160  
  94.161 -    if (!check_vmx_controls(MONITOR_PIN_BASED_EXEC_CONTROLS,
  94.162 -                            MSR_IA32_VMX_PINBASED_CTLS_MSR))
  94.163 +    if ( !check_vmx_controls(MONITOR_PIN_BASED_EXEC_CONTROLS,
  94.164 +                             MSR_IA32_VMX_PINBASED_CTLS_MSR) )
  94.165          return 0;
  94.166 -    if (!check_vmx_controls(MONITOR_CPU_BASED_EXEC_CONTROLS,
  94.167 -                            MSR_IA32_VMX_PROCBASED_CTLS_MSR))
  94.168 +    if ( !check_vmx_controls(MONITOR_CPU_BASED_EXEC_CONTROLS,
  94.169 +                             MSR_IA32_VMX_PROCBASED_CTLS_MSR) )
  94.170          return 0;
  94.171 -    if (!check_vmx_controls(MONITOR_VM_EXIT_CONTROLS,
  94.172 -                            MSR_IA32_VMX_EXIT_CTLS_MSR))
  94.173 +    if ( !check_vmx_controls(MONITOR_VM_EXIT_CONTROLS,
  94.174 +                             MSR_IA32_VMX_EXIT_CTLS_MSR) )
  94.175          return 0;
  94.176 -    if (!check_vmx_controls(MONITOR_VM_ENTRY_CONTROLS,
  94.177 -                            MSR_IA32_VMX_ENTRY_CTLS_MSR))
  94.178 +    if ( !check_vmx_controls(MONITOR_VM_ENTRY_CONTROLS,
  94.179 +                             MSR_IA32_VMX_ENTRY_CTLS_MSR) )
  94.180          return 0;
  94.181  
  94.182 -    set_in_cr4(X86_CR4_VMXE);   /* Enable VMXE */
  94.183 +    set_in_cr4(X86_CR4_VMXE);
  94.184  
  94.185 -    if (!(vmcs = vmx_alloc_vmcs())) {
  94.186 -        printk("Failed to allocate VMCS\n");
  94.187 +    vmx_init_vmcs_config();
  94.188 +
  94.189 +    if ( (vmcs = vmx_alloc_host_vmcs()) == NULL )
  94.190 +    {
  94.191 +        printk("Failed to allocate host VMCS\n");
  94.192          return 0;
  94.193      }
  94.194  
  94.195 -    phys_vmcs = (u64) virt_to_maddr(vmcs);
  94.196 -
  94.197 -    if (__vmxon(phys_vmcs)) {
  94.198 +    if ( __vmxon(virt_to_maddr(vmcs)) )
  94.199 +    {
  94.200          printk("VMXON failed\n");
  94.201 +        vmx_free_host_vmcs(vmcs);
  94.202          return 0;
  94.203      }
  94.204  
  94.205 @@ -832,7 +868,7 @@ static void vmx_vmexit_do_cpuid(struct c
  94.206          cpuid_count(input, count, &eax, &ebx, &ecx, &edx);
  94.207          eax &= NUM_CORES_RESET_MASK;  
  94.208      }
  94.209 -    else
  94.210 +    else if ( !cpuid_hypervisor_leaves(input, &eax, &ebx, &ecx, &edx) )
  94.211      {
  94.212          cpuid(input, &eax, &ebx, &ecx, &edx);
  94.213  
  94.214 @@ -857,10 +893,14 @@ static void vmx_vmexit_do_cpuid(struct c
  94.215  #else
  94.216              if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 )
  94.217              {
  94.218 -                if ( !v->domain->arch.hvm_domain.pae_enabled )
  94.219 +                if ( v->domain->arch.hvm_domain.pae_enabled )
  94.220 +                    clear_bit(X86_FEATURE_PSE36, &edx);
  94.221 +                else
  94.222 +                {
  94.223                      clear_bit(X86_FEATURE_PAE, &edx);
  94.224 -                clear_bit(X86_FEATURE_PSE, &edx);
  94.225 -                clear_bit(X86_FEATURE_PSE36, &edx);
  94.226 +                    clear_bit(X86_FEATURE_PSE, &edx);
  94.227 +                    clear_bit(X86_FEATURE_PSE36, &edx);
  94.228 +                }
  94.229              }
  94.230  #endif
  94.231  
  94.232 @@ -2053,8 +2093,26 @@ asmlinkage void vmx_vmexit_handler(struc
  94.233  
  94.234      if ( unlikely(exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) )
  94.235      {
  94.236 -        printk("Failed vm entry (reason 0x%x)\n", exit_reason);
  94.237 -        printk("*********** VMCS Area **************\n");
  94.238 +        unsigned int failed_vmentry_reason = exit_reason & 0xFFFF;
  94.239 +
  94.240 +        __vmread(EXIT_QUALIFICATION, &exit_qualification);
  94.241 +        printk("Failed vm entry (exit reason 0x%x) ", exit_reason);
  94.242 +        switch ( failed_vmentry_reason ) {
  94.243 +        case EXIT_REASON_INVALID_GUEST_STATE:
  94.244 +            printk("caused by invalid guest state (%ld).\n", exit_qualification);
  94.245 +            break;
  94.246 +        case EXIT_REASON_MSR_LOADING:
  94.247 +            printk("caused by MSR entry %ld loading.\n", exit_qualification);
  94.248 +            break;
  94.249 +        case EXIT_REASON_MACHINE_CHECK:
  94.250 +            printk("caused by machine check.\n");
  94.251 +            break;
  94.252 +        default:
  94.253 +            printk("reason not known yet!");
  94.254 +            break;
  94.255 +        }
  94.256 +
  94.257 +        printk("************* VMCS Area **************\n");
  94.258          vmcs_dump_vcpu();
  94.259          printk("**************************************\n");
  94.260          domain_crash_synchronous();
    95.1 --- a/xen/arch/x86/setup.c	Wed Jul 05 10:23:54 2006 -0600
    95.2 +++ b/xen/arch/x86/setup.c	Wed Jul 05 20:11:37 2006 -0600
    95.3 @@ -439,8 +439,9 @@ void __init __start_xen(multiboot_info_t
    95.4  
    95.5      scheduler_init();
    95.6  
    95.7 -    idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
    95.8 -    BUG_ON(idle_domain == NULL);
    95.9 +    idle_domain = domain_create(IDLE_DOMAIN_ID);
   95.10 +    if ( (idle_domain == NULL) || (alloc_vcpu(idle_domain, 0, 0) == NULL) )
   95.11 +        BUG();
   95.12  
   95.13      set_current(idle_domain->vcpu[0]);
   95.14      this_cpu(curr_vcpu) = idle_domain->vcpu[0];
   95.15 @@ -537,8 +538,8 @@ void __init __start_xen(multiboot_info_t
   95.16      acm_init(&initrdidx, mbi, initial_images_start);
   95.17  
   95.18      /* Create initial domain 0. */
   95.19 -    dom0 = domain_create(0, 0);
   95.20 -    if ( dom0 == NULL )
   95.21 +    dom0 = domain_create(0);
   95.22 +    if ( (dom0 == NULL) || (alloc_vcpu(dom0, 0, 0) == NULL) )
   95.23          panic("Error creating domain 0\n");
   95.24  
   95.25      set_bit(_DOMF_privileged, &dom0->domain_flags);
   95.26 @@ -624,7 +625,7 @@ void arch_get_xen_caps(xen_capabilities_
   95.27      if ( hvm_enabled )
   95.28      {
   95.29          p += sprintf(p, "hvm-%d.%d-x86_32 ", XEN_VERSION, XEN_SUBVERSION);
   95.30 -        //p += sprintf(p, "hvm-%d.%d-x86_32p ", XEN_VERSION, XEN_SUBVERSION);
   95.31 +        p += sprintf(p, "hvm-%d.%d-x86_32p ", XEN_VERSION, XEN_SUBVERSION);
   95.32      }
   95.33  
   95.34  #elif defined(CONFIG_X86_64)
    96.1 --- a/xen/arch/x86/shadow.c	Wed Jul 05 10:23:54 2006 -0600
    96.2 +++ b/xen/arch/x86/shadow.c	Wed Jul 05 20:11:37 2006 -0600
    96.3 @@ -1726,6 +1726,7 @@ static int resync_all(struct domain *d, 
    96.4                      {
    96.5                          guest_l1_pgentry_t tmp_gl1e = guest_l1e_empty();
    96.6                          validate_pte_change(d, tmp_gl1e, sl1e_p);
    96.7 +                        unshadow_l1 = 1;
    96.8                          continue;
    96.9                      }
   96.10  #endif
   96.11 @@ -3676,20 +3677,19 @@ static inline int l2e_rw_fault(
   96.12                  put_page_from_l1e(old_sl1e, d);
   96.13          }
   96.14  
   96.15 -        l1_p[gpfn - start_gpfn] = sl1e;
   96.16 -
   96.17          if (rw) {
   96.18              /* shadow_mark_va_out_of_sync() need modificatin for 2M pages*/
   96.19              if ( mfn_is_page_table(mfn) )
   96.20                  shadow_mark_va_out_of_sync_2mp(v, gpfn, mfn,
   96.21                    l2e_get_paddr(sl2e) | (sizeof(l1_pgentry_t) * (gpfn - start_gpfn)));
   96.22          }
   96.23 +
   96.24 +        l1_p[gpfn - start_gpfn] = sl1e;
   96.25      }
   96.26  
   96.27      unmap_domain_page(l1_p);
   96.28      *gl2e_p = gl2e;
   96.29      return 1;
   96.30 -
   96.31  }
   96.32  
   96.33  /*
   96.34 @@ -3724,7 +3724,13 @@ static inline int guest_page_fault(
   96.35      }
   96.36  
   96.37      if ( guest_l2e_get_flags(*gpl2e) & _PAGE_PSE )
   96.38 +    {
   96.39 +        printk("None-PAE HVM guests can NOT use PSE, "
   96.40 +               "because we don't support 4MBytes PSE pages.\n");
   96.41 +        printk("remove pae=1 from your config file.\n");
   96.42 +        domain_crash_synchronous();
   96.43          return 0;
   96.44 +    }
   96.45  
   96.46      __guest_get_l1e(v, va, gpl1e);
   96.47  
    97.1 --- a/xen/arch/x86/smpboot.c	Wed Jul 05 10:23:54 2006 -0600
    97.2 +++ b/xen/arch/x86/smpboot.c	Wed Jul 05 20:11:37 2006 -0600
    97.3 @@ -1197,8 +1197,7 @@ int __devinit __cpu_up(unsigned int cpu)
    97.4  	cpu_set(cpu, smp_commenced_mask);
    97.5  	while (!cpu_isset(cpu, cpu_online_map)) {
    97.6  		mb();
    97.7 -		if (softirq_pending(0))
    97.8 -			do_softirq();
    97.9 +		process_pending_timers();
   97.10  	}
   97.11  	return 0;
   97.12  }
    98.1 --- a/xen/arch/x86/traps.c	Wed Jul 05 10:23:54 2006 -0600
    98.2 +++ b/xen/arch/x86/traps.c	Wed Jul 05 20:11:37 2006 -0600
    98.3 @@ -426,10 +426,32 @@ DO_ERROR_NOCODE(16, "fpu error", coproce
    98.4  DO_ERROR(17, "alignment check", alignment_check)
    98.5  DO_ERROR_NOCODE(19, "simd error", simd_coprocessor_error)
    98.6  
    98.7 +int cpuid_hypervisor_leaves(
    98.8 +    uint32_t idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
    98.9 +{
   98.10 +    if ( (idx < 0x40000000) || (idx > 0x40000000) )
   98.11 +        return 0;
   98.12 +
   98.13 +    switch ( idx - 0x40000000 )
   98.14 +    {
   98.15 +    case 0:
   98.16 +        *eax = 0x40000000;
   98.17 +        *ebx = 0x006e6558; /* "Xen\0" */
   98.18 +        *ecx = *edx = 0;
   98.19 +        break;
   98.20 +
   98.21 +    default:
   98.22 +        BUG();
   98.23 +    }
   98.24 +
   98.25 +    return 1;
   98.26 +}
   98.27 +
   98.28  static int emulate_forced_invalid_op(struct cpu_user_regs *regs)
   98.29  {
   98.30      char signature[5], instr[2];
   98.31 -    unsigned long a, b, c, d, eip;
   98.32 +    uint32_t a, b, c, d;
   98.33 +    unsigned long eip;
   98.34  
   98.35      a = regs->eax;
   98.36      b = regs->ebx;
   98.37 @@ -466,6 +488,10 @@ static int emulate_forced_invalid_op(str
   98.38          if ( !IS_PRIV(current->domain) )
   98.39              clear_bit(X86_FEATURE_MTRR, &d);
   98.40      }
   98.41 +    else
   98.42 +    {
   98.43 +        (void)cpuid_hypervisor_leaves(regs->eax, &a, &b, &c, &d);
   98.44 +    }
   98.45  
   98.46      regs->eax = a;
   98.47      regs->ebx = b;
   98.48 @@ -1397,13 +1423,14 @@ static void nmi_softirq(void)
   98.49  static void nmi_dom0_report(unsigned int reason_idx)
   98.50  {
   98.51      struct domain *d;
   98.52 +    struct vcpu   *v;
   98.53  
   98.54 -    if ( (d = dom0) == NULL )
   98.55 +    if ( ((d = dom0) == NULL) || ((v = d->vcpu[0]) == NULL) )
   98.56          return;
   98.57  
   98.58      set_bit(reason_idx, &d->shared_info->arch.nmi_reason);
   98.59  
   98.60 -    if ( test_and_set_bit(_VCPUF_nmi_pending, &d->vcpu[0]->vcpu_flags) )
   98.61 +    if ( test_and_set_bit(_VCPUF_nmi_pending, &v->vcpu_flags) )
   98.62          raise_softirq(NMI_SOFTIRQ); /* not safe to wake up a vcpu here */
   98.63  }
   98.64  
    99.1 --- a/xen/arch/x86/x86_emulate.c	Wed Jul 05 10:23:54 2006 -0600
    99.2 +++ b/xen/arch/x86/x86_emulate.c	Wed Jul 05 20:11:37 2006 -0600
    99.3 @@ -118,7 +118,7 @@ static uint8_t opcode_table[256] = {
    99.4      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    99.5      /* 0xC0 - 0xC7 */
    99.6      ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM, 0, 0,
    99.7 -    0, 0, ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImm|ModRM,
    99.8 +    0, 0, ByteOp|DstMem|SrcImm|ModRM|Mov, DstMem|SrcImm|ModRM|Mov,
    99.9      /* 0xC8 - 0xCF */
   99.10      0, 0, 0, 0, 0, 0, 0, 0,
   99.11      /* 0xD0 - 0xD7 */
   100.1 --- a/xen/common/dom0_ops.c	Wed Jul 05 10:23:54 2006 -0600
   100.2 +++ b/xen/common/dom0_ops.c	Wed Jul 05 20:11:37 2006 -0600
   100.3 @@ -90,6 +90,44 @@ static void getdomaininfo(struct domain 
   100.4      memcpy(info->handle, d->handle, sizeof(xen_domain_handle_t));
   100.5  }
   100.6  
   100.7 +static unsigned int default_vcpu0_location(void)
   100.8 +{
   100.9 +    struct domain *d;
  100.10 +    struct vcpu   *v;
  100.11 +    unsigned int   i, cpu, cnt[NR_CPUS] = { 0 };
  100.12 +    cpumask_t      cpu_exclude_map;
  100.13 +
  100.14 +    /* Do an initial CPU placement. Pick the least-populated CPU. */
  100.15 +    read_lock(&domlist_lock);
  100.16 +    for_each_domain ( d )
  100.17 +        for_each_vcpu ( d, v )
  100.18 +        if ( !test_bit(_VCPUF_down, &v->vcpu_flags) )
  100.19 +            cnt[v->processor]++;
  100.20 +    read_unlock(&domlist_lock);
  100.21 +
  100.22 +    /*
  100.23 +     * If we're on a HT system, we only auto-allocate to a non-primary HT. We 
  100.24 +     * favour high numbered CPUs in the event of a tie.
  100.25 +     */
  100.26 +    cpu = first_cpu(cpu_sibling_map[0]);
  100.27 +    if ( cpus_weight(cpu_sibling_map[0]) > 1 )
  100.28 +        cpu = next_cpu(cpu, cpu_sibling_map[0]);
  100.29 +    cpu_exclude_map = cpu_sibling_map[0];
  100.30 +    for_each_online_cpu ( i )
  100.31 +    {
  100.32 +        if ( cpu_isset(i, cpu_exclude_map) )
  100.33 +            continue;
  100.34 +        if ( (i == first_cpu(cpu_sibling_map[i])) &&
  100.35 +             (cpus_weight(cpu_sibling_map[i]) > 1) )
  100.36 +            continue;
  100.37 +        cpus_or(cpu_exclude_map, cpu_exclude_map, cpu_sibling_map[i]);
  100.38 +        if ( cnt[i] <= cnt[cpu] )
  100.39 +            cpu = i;
  100.40 +    }
  100.41 +
  100.42 +    return cpu;
  100.43 +}
  100.44 +
  100.45  long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op)
  100.46  {
  100.47      long ret = 0;
  100.48 @@ -150,7 +188,7 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op
  100.49          if ( d != NULL )
  100.50          {
  100.51              ret = -EINVAL;
  100.52 -            if ( (d != current->domain) && 
  100.53 +            if ( (d != current->domain) && (d->vcpu[0] != NULL) &&
  100.54                   test_bit(_VCPUF_initialised, &d->vcpu[0]->vcpu_flags) )
  100.55              {
  100.56                  domain_unpause_by_systemcontroller(d);
  100.57 @@ -164,11 +202,7 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op
  100.58      case DOM0_CREATEDOMAIN:
  100.59      {
  100.60          struct domain *d;
  100.61 -        unsigned int   pro;
  100.62          domid_t        dom;
  100.63 -        struct vcpu   *v;
  100.64 -        unsigned int   i, cnt[NR_CPUS] = { 0 };
  100.65 -        cpumask_t      cpu_exclude_map;
  100.66          static domid_t rover = 0;
  100.67  
  100.68          /*
  100.69 @@ -202,36 +236,8 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op
  100.70              rover = dom;
  100.71          }
  100.72  
  100.73 -        /* Do an initial CPU placement. Pick the least-populated CPU. */
  100.74 -        read_lock(&domlist_lock);
  100.75 -        for_each_domain ( d )
  100.76 -            for_each_vcpu ( d, v )
  100.77 -                if ( !test_bit(_VCPUF_down, &v->vcpu_flags) )
  100.78 -                    cnt[v->processor]++;
  100.79 -        read_unlock(&domlist_lock);
  100.80 -        
  100.81 -        /*
  100.82 -         * If we're on a HT system, we only auto-allocate to a non-primary HT.
  100.83 -         * We favour high numbered CPUs in the event of a tie.
  100.84 -         */
  100.85 -        pro = first_cpu(cpu_sibling_map[0]);
  100.86 -        if ( cpus_weight(cpu_sibling_map[0]) > 1 )
  100.87 -            pro = next_cpu(pro, cpu_sibling_map[0]);
  100.88 -        cpu_exclude_map = cpu_sibling_map[0];
  100.89 -        for_each_online_cpu ( i )
  100.90 -        {
  100.91 -            if ( cpu_isset(i, cpu_exclude_map) )
  100.92 -                continue;
  100.93 -            if ( (i == first_cpu(cpu_sibling_map[i])) &&
  100.94 -                 (cpus_weight(cpu_sibling_map[i]) > 1) )
  100.95 -                continue;
  100.96 -            cpus_or(cpu_exclude_map, cpu_exclude_map, cpu_sibling_map[i]);
  100.97 -            if ( cnt[i] <= cnt[pro] )
  100.98 -                pro = i;
  100.99 -        }
 100.100 -
 100.101          ret = -ENOMEM;
 100.102 -        if ( (d = domain_create(dom, pro)) == NULL )
 100.103 +        if ( (d = domain_create(dom)) == NULL )
 100.104              break;
 100.105  
 100.106          memcpy(d->handle, op->u.createdomain.handle,
 100.107 @@ -258,14 +264,8 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op
 100.108          if ( (d = find_domain_by_id(op->u.max_vcpus.domain)) == NULL )
 100.109              break;
 100.110  
 100.111 -        /*
 100.112 -         * Can only create new VCPUs while the domain is not fully constructed
 100.113 -         * (and hence not runnable). Xen needs auditing for races before
 100.114 -         * removing this check.
 100.115 -         */
 100.116 -        ret = -EINVAL;
 100.117 -        if ( test_bit(_VCPUF_initialised, &d->vcpu[0]->vcpu_flags) )
 100.118 -            goto maxvcpu_out;
 100.119 +        /* Needed, for example, to ensure writable p.t. state is synced. */
 100.120 +        domain_pause(d);
 100.121  
 100.122          /* We cannot reduce maximum VCPUs. */
 100.123          ret = -EINVAL;
 100.124 @@ -275,17 +275,21 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op
 100.125          ret = -ENOMEM;
 100.126          for ( i = 0; i < max; i++ )
 100.127          {
 100.128 -            if ( d->vcpu[i] == NULL )
 100.129 -            {
 100.130 -                cpu = (d->vcpu[i-1]->processor + 1) % num_online_cpus();
 100.131 -                if ( alloc_vcpu(d, i, cpu) == NULL )
 100.132 -                    goto maxvcpu_out;
 100.133 -            }
 100.134 +            if ( d->vcpu[i] != NULL )
 100.135 +                continue;
 100.136 +
 100.137 +            cpu = (i == 0) ?
 100.138 +                default_vcpu0_location() :
 100.139 +                (d->vcpu[i-1]->processor + 1) % num_online_cpus();
 100.140 +
 100.141 +            if ( alloc_vcpu(d, i, cpu) == NULL )
 100.142 +                goto maxvcpu_out;
 100.143          }
 100.144  
 100.145          ret = 0;
 100.146  
 100.147      maxvcpu_out:
 100.148 +        domain_unpause(d);
 100.149          put_domain(d);
 100.150      }
 100.151      break;
   101.1 --- a/xen/common/domain.c	Wed Jul 05 10:23:54 2006 -0600
   101.2 +++ b/xen/common/domain.c	Wed Jul 05 20:11:37 2006 -0600
   101.3 @@ -46,6 +46,7 @@ struct domain *alloc_domain(domid_t domi
   101.4      atomic_set(&d->refcnt, 1);
   101.5      spin_lock_init(&d->big_lock);
   101.6      spin_lock_init(&d->page_alloc_lock);
   101.7 +    spin_lock_init(&d->pause_lock);
   101.8      INIT_LIST_HEAD(&d->page_list);
   101.9      INIT_LIST_HEAD(&d->xenpage_list);
  101.10  
  101.11 @@ -81,8 +82,8 @@ struct vcpu *alloc_vcpu(
  101.12      v->domain = d;
  101.13      v->vcpu_id = vcpu_id;
  101.14      v->processor = cpu_id;
  101.15 -    atomic_set(&v->pausecnt, 0);
  101.16      v->vcpu_info = &d->shared_info->vcpu_info[vcpu_id];
  101.17 +    spin_lock_init(&v->pause_lock);
  101.18  
  101.19      v->cpu_affinity = is_idle_domain(d) ?
  101.20          cpumask_of_cpu(cpu_id) : CPU_MASK_ALL;
  101.21 @@ -110,30 +111,22 @@ struct vcpu *alloc_idle_vcpu(unsigned in
  101.22  {
  101.23      struct domain *d;
  101.24      struct vcpu *v;
  101.25 -    unsigned int vcpu_id;
  101.26 +    unsigned int vcpu_id = cpu_id % MAX_VIRT_CPUS;
  101.27  
  101.28 -    if ((vcpu_id = cpu_id % MAX_VIRT_CPUS) == 0)
  101.29 -    {
  101.30 -        d = domain_create(IDLE_DOMAIN_ID, cpu_id);
  101.31 -        BUG_ON(d == NULL);
  101.32 -        v = d->vcpu[0];
  101.33 -    }
  101.34 -    else
  101.35 -    {
  101.36 -        d = idle_vcpu[cpu_id - vcpu_id]->domain;
  101.37 -        BUG_ON(d == NULL);
  101.38 -        v = alloc_vcpu(d, vcpu_id, cpu_id);
  101.39 -    }
  101.40 +    d = (vcpu_id == 0) ?
  101.41 +        domain_create(IDLE_DOMAIN_ID) :
  101.42 +        idle_vcpu[cpu_id - vcpu_id]->domain;
  101.43 +    BUG_ON(d == NULL);
  101.44  
  101.45 +    v = alloc_vcpu(d, vcpu_id, cpu_id);
  101.46      idle_vcpu[cpu_id] = v;
  101.47  
  101.48      return v;
  101.49  }
  101.50  
  101.51 -struct domain *domain_create(domid_t domid, unsigned int cpu)
  101.52 +struct domain *domain_create(domid_t domid)
  101.53  {
  101.54      struct domain *d, **pd;
  101.55 -    struct vcpu *v;
  101.56  
  101.57      if ( (d = alloc_domain(domid)) == NULL )
  101.58          return NULL;
  101.59 @@ -152,13 +145,10 @@ struct domain *domain_create(domid_t dom
  101.60      if ( arch_domain_create(d) != 0 )
  101.61          goto fail3;
  101.62  
  101.63 -    if ( (v = alloc_vcpu(d, 0, cpu)) == NULL )
  101.64 -        goto fail4;
  101.65 -
  101.66      d->iomem_caps = rangeset_new(d, "I/O Memory", RANGESETF_prettyprint_hex);
  101.67      d->irq_caps   = rangeset_new(d, "Interrupts", 0);
  101.68      if ( (d->iomem_caps == NULL) || (d->irq_caps == NULL) )
  101.69 -        goto fail4; /* NB. alloc_vcpu() is undone in free_domain() */
  101.70 +        goto fail4;
  101.71  
  101.72      if ( !is_idle_domain(d) )
  101.73      {
  101.74 @@ -327,11 +317,12 @@ void domain_shutdown(struct domain *d, u
  101.75      d->shutdown_code = reason;
  101.76  
  101.77      /* Put every vcpu to sleep, but don't wait (avoids inter-vcpu deadlock). */
  101.78 +    spin_lock(&d->pause_lock);
  101.79 +    d->pause_count++;
  101.80 +    set_bit(_DOMF_paused, &d->domain_flags);
  101.81 +    spin_unlock(&d->pause_lock);
  101.82      for_each_vcpu ( d, v )
  101.83 -    {
  101.84 -        atomic_inc(&v->pausecnt);
  101.85          vcpu_sleep_nosync(v);
  101.86 -    }
  101.87  
  101.88      get_knownalive_domain(d);
  101.89      domain_shuttingdown[smp_processor_id()] = d;
  101.90 @@ -398,34 +389,65 @@ void domain_destroy(struct domain *d)
  101.91  
  101.92  void vcpu_pause(struct vcpu *v)
  101.93  {
  101.94 -    BUG_ON(v == current);
  101.95 -    atomic_inc(&v->pausecnt);
  101.96 +    ASSERT(v != current);
  101.97 +
  101.98 +    spin_lock(&v->pause_lock);
  101.99 +    if ( v->pause_count++ == 0 )
 101.100 +        set_bit(_VCPUF_paused, &v->vcpu_flags);
 101.101 +    spin_unlock(&v->pause_lock);
 101.102 +
 101.103      vcpu_sleep_sync(v);
 101.104  }
 101.105  
 101.106 +void vcpu_unpause(struct vcpu *v)
 101.107 +{
 101.108 +    int wake;
 101.109 +
 101.110 +    ASSERT(v != current);
 101.111 +
 101.112 +    spin_lock(&v->pause_lock);
 101.113 +    wake = (--v->pause_count == 0);
 101.114 +    if ( wake )
 101.115 +        clear_bit(_VCPUF_paused, &v->vcpu_flags);
 101.116 +    spin_unlock(&v->pause_lock);
 101.117 +
 101.118 +    if ( wake )
 101.119 +        vcpu_wake(v);
 101.120 +}
 101.121 +
 101.122  void domain_pause(struct domain *d)
 101.123  {
 101.124      struct vcpu *v;
 101.125  
 101.126 +    ASSERT(d != current->domain);
 101.127 +
 101.128 +    spin_lock(&d->pause_lock);
 101.129 +    if ( d->pause_count++ == 0 )
 101.130 +        set_bit(_DOMF_paused, &d->domain_flags);
 101.131 +    spin_unlock(&d->pause_lock);
 101.132 +
 101.133      for_each_vcpu( d, v )
 101.134 -        vcpu_pause(v);
 101.135 +        vcpu_sleep_sync(v);
 101.136  
 101.137      sync_pagetable_state(d);
 101.138  }
 101.139  
 101.140 -void vcpu_unpause(struct vcpu *v)
 101.141 -{
 101.142 -    BUG_ON(v == current);
 101.143 -    if ( atomic_dec_and_test(&v->pausecnt) )
 101.144 -        vcpu_wake(v);
 101.145 -}
 101.146 -
 101.147  void domain_unpause(struct domain *d)
 101.148  {
 101.149      struct vcpu *v;
 101.150 +    int wake;
 101.151  
 101.152 -    for_each_vcpu( d, v )
 101.153 -        vcpu_unpause(v);
 101.154 +    ASSERT(d != current->domain);
 101.155 +
 101.156 +    spin_lock(&d->pause_lock);
 101.157 +    wake = (--d->pause_count == 0);
 101.158 +    if ( wake )
 101.159 +        clear_bit(_DOMF_paused, &d->domain_flags);
 101.160 +    spin_unlock(&d->pause_lock);
 101.161 +
 101.162 +    if ( wake )
 101.163 +        for_each_vcpu( d, v )
 101.164 +            vcpu_wake(v);
 101.165  }
 101.166  
 101.167  void domain_pause_by_systemcontroller(struct domain *d)
   102.1 --- a/xen/common/elf.c	Wed Jul 05 10:23:54 2006 -0600
   102.2 +++ b/xen/common/elf.c	Wed Jul 05 20:11:37 2006 -0600
   102.3 @@ -23,7 +23,7 @@ int parseelfimage(struct domain_setup_in
   102.4      Elf_Ehdr *ehdr = (Elf_Ehdr *)dsi->image_addr;
   102.5      Elf_Phdr *phdr;
   102.6      Elf_Shdr *shdr;
   102.7 -    unsigned long kernstart = ~0UL, kernend=0UL, vaddr, virt_base, elf_pa_off;
   102.8 +    Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_base, elf_pa_off;
   102.9      char *shstrtab, *guestinfo=NULL, *p;
  102.10      char *elfbase = (char *)dsi->image_addr;
  102.11      int h, virt_base_defined, elf_pa_off_defined;
  102.12 @@ -95,7 +95,11 @@ int parseelfimage(struct domain_setup_in
  102.13      elf_pa_off = elf_pa_off_defined ? simple_strtoul(p+17, &p, 0) : virt_base;
  102.14  
  102.15      if ( elf_pa_off_defined && !virt_base_defined )
  102.16 -        goto bad_image;
  102.17 +    {
  102.18 +        printk("ERROR: Neither ELF_PADDR_OFFSET nor VIRT_BASE found in"
  102.19 +               " __xen_guest section.\n");
  102.20 +        return -EINVAL;
  102.21 +    }
  102.22  
  102.23      for ( h = 0; h < ehdr->e_phnum; h++ )
  102.24      {
  102.25 @@ -104,7 +108,11 @@ int parseelfimage(struct domain_setup_in
  102.26              continue;
  102.27          vaddr = phdr->p_paddr - elf_pa_off + virt_base;
  102.28          if ( (vaddr + phdr->p_memsz) < vaddr )
  102.29 -            goto bad_image;
  102.30 +        {
  102.31 +            printk("ERROR: ELF program header %d is too large.\n", h);
  102.32 +            return -EINVAL;
  102.33 +        }
  102.34 +
  102.35          if ( vaddr < kernstart )
  102.36              kernstart = vaddr;
  102.37          if ( (vaddr + phdr->p_memsz) > kernend )
  102.38 @@ -127,7 +135,10 @@ int parseelfimage(struct domain_setup_in
  102.39           (dsi->v_kernentry < kernstart) ||
  102.40           (dsi->v_kernentry > kernend) ||
  102.41           (dsi->v_start > kernstart) )
  102.42 -        goto bad_image;
  102.43 +    {
  102.44 +        printk("ERROR: ELF start or entries are out of bounds.\n");
  102.45 +        return -EINVAL;
  102.46 +    }
  102.47  
  102.48      if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL )
  102.49              dsi->load_symtab = 1;
  102.50 @@ -139,10 +150,6 @@ int parseelfimage(struct domain_setup_in
  102.51      loadelfsymtab(dsi, 0);
  102.52  
  102.53      return 0;
  102.54 -
  102.55 - bad_image:
  102.56 -    printk("Malformed ELF image.\n");
  102.57 -    return -EINVAL;
  102.58  }
  102.59  
  102.60  int loadelfimage(struct domain_setup_info *dsi)
   103.1 --- a/xen/common/event_channel.c	Wed Jul 05 10:23:54 2006 -0600
   103.2 +++ b/xen/common/event_channel.c	Wed Jul 05 20:11:37 2006 -0600
   103.3 @@ -525,11 +525,16 @@ void send_guest_vcpu_virq(struct vcpu *v
   103.4  void send_guest_global_virq(struct domain *d, int virq)
   103.5  {
   103.6      int port;
   103.7 +    struct vcpu *v;
   103.8      struct evtchn *chn;
   103.9  
  103.10      ASSERT(virq_is_global(virq));
  103.11  
  103.12 -    port = d->vcpu[0]->virq_to_evtchn[virq];
  103.13 +    v = d->vcpu[0];
  103.14 +    if ( unlikely(v == NULL) )
  103.15 +        return;
  103.16 +
  103.17 +    port = v->virq_to_evtchn[virq];
  103.18      if ( unlikely(port == 0) )
  103.19          return;
  103.20  
   104.1 --- a/xen/common/grant_table.c	Wed Jul 05 10:23:54 2006 -0600
   104.2 +++ b/xen/common/grant_table.c	Wed Jul 05 20:11:37 2006 -0600
   104.3 @@ -287,10 +287,10 @@ static void
   104.4  
   104.5      if ( !(op->flags & GNTMAP_readonly) &&
   104.6           !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) )
   104.7 -        clear_bit(_GTF_writing, &sha->flags);
   104.8 +        gnttab_clear_flag(_GTF_writing, &sha->flags);
   104.9  
  104.10      if ( !act->pin )
  104.11 -        clear_bit(_GTF_reading, &sha->flags);
  104.12 +        gnttab_clear_flag(_GTF_reading, &sha->flags);
  104.13  
  104.14   unlock_out:
  104.15      spin_unlock(&rd->grant_table->lock);
  104.16 @@ -425,10 +425,10 @@ static void
  104.17  
  104.18      if ( ((act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0) &&
  104.19           !(flags & GNTMAP_readonly) )
  104.20 -        clear_bit(_GTF_writing, &sha->flags);
  104.21 +        gnttab_clear_flag(_GTF_writing, &sha->flags);
  104.22  
  104.23      if ( act->pin == 0 )
  104.24 -        clear_bit(_GTF_reading, &sha->flags);
  104.25 +        gnttab_clear_flag(_GTF_reading, &sha->flags);
  104.26  
  104.27   unmap_out:
  104.28      op->status = rc;
  104.29 @@ -889,11 +889,11 @@ gnttab_release_mappings(
  104.30              }
  104.31  
  104.32              if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 )
  104.33 -                clear_bit(_GTF_writing, &sha->flags);
  104.34 +                gnttab_clear_flag(_GTF_writing, &sha->flags);
  104.35          }
  104.36  
  104.37          if ( act->pin == 0 )
  104.38 -            clear_bit(_GTF_reading, &sha->flags);
  104.39 +            gnttab_clear_flag(_GTF_reading, &sha->flags);
  104.40  
  104.41          spin_unlock(&rd->grant_table->lock);
  104.42  
   105.1 --- a/xen/common/memory.c	Wed Jul 05 10:23:54 2006 -0600
   105.2 +++ b/xen/common/memory.c	Wed Jul 05 20:11:37 2006 -0600
   105.3 @@ -170,6 +170,15 @@ guest_remove_page(
   105.4      if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
   105.5          put_page(page);
   105.6  
   105.7 +    if ( unlikely((page->count_info & PGC_count_mask) != 1) )
   105.8 +    {
   105.9 +        /* We'll make this a guest-visible error in future, so take heed! */
  105.10 +        DPRINTK("Dom%d freeing in-use page %lx (pseudophys %lx):"
  105.11 +                " count=%x type=%lx\n",
  105.12 +                d->domain_id, mfn, get_gpfn_from_mfn(mfn),
  105.13 +                page->count_info, page->u.inuse.type_info);
  105.14 +    }
  105.15 +
  105.16      guest_physmap_remove_page(d, gmfn, mfn);
  105.17  
  105.18      put_page(page);
   106.1 --- a/xen/common/page_alloc.c	Wed Jul 05 10:23:54 2006 -0600
   106.2 +++ b/xen/common/page_alloc.c	Wed Jul 05 20:11:37 2006 -0600
   106.3 @@ -388,7 +388,6 @@ void scrub_heap_pages(void)
   106.4  {
   106.5      void *p;
   106.6      unsigned long pfn;
   106.7 -    int cpu = smp_processor_id();
   106.8  
   106.9      printk("Scrubbing Free RAM: ");
  106.10  
  106.11 @@ -398,8 +397,7 @@ void scrub_heap_pages(void)
  106.12          if ( (pfn % ((100*1024*1024)/PAGE_SIZE)) == 0 )
  106.13              printk(".");
  106.14  
  106.15 -        if ( unlikely(softirq_pending(cpu)) )
  106.16 -            do_softirq();
  106.17 +        process_pending_timers();
  106.18  
  106.19          /* Quick lock-free check. */
  106.20          if ( allocated_in_map(pfn) )
   107.1 --- a/xen/common/sched_credit.c	Wed Jul 05 10:23:54 2006 -0600
   107.2 +++ b/xen/common/sched_credit.c	Wed Jul 05 20:11:37 2006 -0600
   107.3 @@ -622,9 +622,12 @@ csched_dom_cntl(
   107.4  
   107.5          if ( cmd->u.credit.weight != 0 )
   107.6          {
   107.7 -            csched_priv.weight -= sdom->weight;
   107.8 +            if ( !list_empty(&sdom->active_sdom_elem) )
   107.9 +            {
  107.10 +                csched_priv.weight -= sdom->weight;
  107.11 +                csched_priv.weight += cmd->u.credit.weight;
  107.12 +            }
  107.13              sdom->weight = cmd->u.credit.weight;
  107.14 -            csched_priv.weight += sdom->weight;
  107.15          }
  107.16  
  107.17          if ( cmd->u.credit.cap != (uint16_t)~0U )
   108.1 --- a/xen/common/sched_sedf.c	Wed Jul 05 10:23:54 2006 -0600
   108.2 +++ b/xen/common/sched_sedf.c	Wed Jul 05 20:11:37 2006 -0600
   108.3 @@ -1429,6 +1429,8 @@ static int sedf_adjdom(struct domain *p,
   108.4      }
   108.5      else if ( cmd->direction == SCHED_INFO_GET )
   108.6      {
   108.7 +        if ( p->vcpu[0] == NULL )
   108.8 +            return -EINVAL;
   108.9          cmd->u.sedf.period    = EDOM_INFO(p->vcpu[0])->period;
  108.10          cmd->u.sedf.slice     = EDOM_INFO(p->vcpu[0])->slice;
  108.11          cmd->u.sedf.extratime = EDOM_INFO(p->vcpu[0])->status & EXTRA_AWARE;
   109.1 --- a/xen/common/schedule.c	Wed Jul 05 10:23:54 2006 -0600
   109.2 +++ b/xen/common/schedule.c	Wed Jul 05 20:11:37 2006 -0600
   109.3 @@ -389,11 +389,32 @@ long do_sched_op(int cmd, XEN_GUEST_HAND
   109.4  long do_set_timer_op(s_time_t timeout)
   109.5  {
   109.6      struct vcpu *v = current;
   109.7 +    s_time_t offset = timeout - NOW();
   109.8  
   109.9      if ( timeout == 0 )
  109.10 +    {
  109.11          stop_timer(&v->timer);
  109.12 +    }
  109.13 +    else if ( unlikely(timeout < 0) || /* overflow into 64th bit? */
  109.14 +              unlikely((offset > 0) && ((uint32_t)(offset >> 50) != 0)) )
  109.15 +    {
  109.16 +        /*
  109.17 +         * Linux workaround: occasionally we will see timeouts a long way in 
  109.18 +         * the future due to wrapping in Linux's jiffy time handling. We check 
  109.19 +         * for timeouts wrapped negative, and for positive timeouts more than 
  109.20 +         * about 13 days in the future (2^50ns). The correct fix is to trigger 
  109.21 +         * an interrupt immediately (since Linux in fact has pending work to 
  109.22 +         * do in this situation).
  109.23 +         */
  109.24 +        DPRINTK("Warning: huge timeout set by domain %d (vcpu %d):"
  109.25 +                " %"PRIx64"\n",
  109.26 +                v->domain->domain_id, v->vcpu_id, (uint64_t)timeout);
  109.27 +        send_timer_event(v);
  109.28 +    }
  109.29      else
  109.30 +    {
  109.31          set_timer(&v->timer, timeout);
  109.32 +    }
  109.33  
  109.34      return 0;
  109.35  }
   110.1 --- a/xen/common/softirq.c	Wed Jul 05 10:23:54 2006 -0600
   110.2 +++ b/xen/common/softirq.c	Wed Jul 05 20:11:37 2006 -0600
   110.3 @@ -23,17 +23,23 @@ static softirq_handler softirq_handlers[
   110.4  
   110.5  asmlinkage void do_softirq(void)
   110.6  {
   110.7 -    unsigned int i, cpu = smp_processor_id();
   110.8 +    unsigned int i, cpu;
   110.9      unsigned long pending;
  110.10  
  110.11 -    pending = softirq_pending(cpu);
  110.12 -    ASSERT(pending != 0);
  110.13 +    for ( ; ; )
  110.14 +    {
  110.15 +        /*
  110.16 +         * Initialise @cpu on every iteration: SCHEDULE_SOFTIRQ may move
  110.17 +         * us to another processor.
  110.18 +         */
  110.19 +        cpu = smp_processor_id();
  110.20 +        if ( (pending = softirq_pending(cpu)) == 0 )
  110.21 +            break;
  110.22  
  110.23 -    do {
  110.24          i = find_first_set_bit(pending);
  110.25          clear_bit(i, &softirq_pending(cpu));
  110.26          (*softirq_handlers[i])();
  110.27 -    } while ( (pending = softirq_pending(cpu)) != 0 );
  110.28 +    }
  110.29  }
  110.30  
  110.31  void open_softirq(int nr, softirq_handler handler)
   111.1 --- a/xen/common/timer.c	Wed Jul 05 10:23:54 2006 -0600
   111.2 +++ b/xen/common/timer.c	Wed Jul 05 20:11:37 2006 -0600
   111.3 @@ -327,6 +327,15 @@ static void timer_softirq_action(void)
   111.4  }
   111.5  
   111.6  
   111.7 +void process_pending_timers(void)
   111.8 +{
   111.9 +    unsigned int cpu = smp_processor_id();
  111.10 +    ASSERT(!in_irq() && local_irq_is_enabled());
  111.11 +    if ( test_and_clear_bit(TIMER_SOFTIRQ, &softirq_pending(cpu)) )
  111.12 +        timer_softirq_action();
  111.13 +}
  111.14 +
  111.15 +
  111.16  static void dump_timerq(unsigned char key)
  111.17  {
  111.18      struct timer *t;
   112.1 --- a/xen/drivers/char/console.c	Wed Jul 05 10:23:54 2006 -0600
   112.2 +++ b/xen/drivers/char/console.c	Wed Jul 05 20:11:37 2006 -0600
   112.3 @@ -279,7 +279,7 @@ static void switch_serial_input(void)
   112.4  {
   112.5      static char *input_str[2] = { "DOM0", "Xen" };
   112.6      xen_rx = !xen_rx;
   112.7 -    if ( SWITCH_CODE != 0 )
   112.8 +    if ( (SWITCH_CODE != 0) && (dom0 != NULL) )
   112.9      {
  112.10          printk("*** Serial input -> %s "
  112.11                 "(type 'CTRL-%c' three times to switch input to %s).\n",
  112.12 @@ -528,8 +528,7 @@ void console_endboot(void)
  112.13              printk("%d... ", 3-i);
  112.14              for ( j = 0; j < 100; j++ )
  112.15              {
  112.16 -                if ( softirq_pending(smp_processor_id()) )
  112.17 -                    do_softirq();
  112.18 +                process_pending_timers();
  112.19                  mdelay(10);
  112.20              }
  112.21          }
  112.22 @@ -741,6 +740,15 @@ void panic(const char *fmt, ...)
  112.23      machine_restart(0);
  112.24  }
  112.25  
  112.26 +void __bug(char *file, int line)
  112.27 +{
  112.28 +    console_start_sync();
  112.29 +    debugtrace_dump();
  112.30 +    printk("BUG at %s:%d\n", file, line);
  112.31 +    FORCE_CRASH();
  112.32 +    for ( ; ; ) ;
  112.33 +}
  112.34 +
  112.35  /*
  112.36   * Local variables:
  112.37   * mode: C
   113.1 --- a/xen/include/asm-ia64/grant_table.h	Wed Jul 05 10:23:54 2006 -0600
   113.2 +++ b/xen/include/asm-ia64/grant_table.h	Wed Jul 05 20:11:37 2006 -0600
   113.3 @@ -55,4 +55,9 @@ void guest_physmap_add_page(struct domai
   113.4  
   113.5  #define gnttab_log_dirty(d, f) ((void)0)
   113.6  
   113.7 +static inline void gnttab_clear_flag(unsigned long nr, uint16_t *addr)
   113.8 +{
   113.9 +	clear_bit(nr, addr);
  113.10 +}
  113.11 +
  113.12  #endif /* __ASM_GRANT_TABLE_H__ */
   114.1 --- a/xen/include/asm-x86/grant_table.h	Wed Jul 05 10:23:54 2006 -0600
   114.2 +++ b/xen/include/asm-x86/grant_table.h	Wed Jul 05 20:11:37 2006 -0600
   114.3 @@ -33,4 +33,9 @@ int destroy_grant_host_mapping(
   114.4  
   114.5  #define gnttab_log_dirty(d, f) mark_dirty((d), (f))
   114.6  
   114.7 +static inline void gnttab_clear_flag(unsigned long nr, uint16_t *addr)
   114.8 +{
   114.9 +	clear_bit(nr, addr);
  114.10 +}
  114.11 +
  114.12  #endif /* __ASM_GRANT_TABLE_H__ */
   115.1 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h	Wed Jul 05 10:23:54 2006 -0600
   115.2 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h	Wed Jul 05 20:11:37 2006 -0600
   115.3 @@ -27,9 +27,7 @@
   115.4  extern int start_vmx(void);
   115.5  extern void stop_vmx(void);
   115.6  extern void vmcs_dump_vcpu(void);
   115.7 -void vmx_final_setup_guest(struct vcpu *v);
   115.8 -
   115.9 -void vmx_enter_scheduler(void);
  115.10 +extern void vmx_init_vmcs_config(void);
  115.11  
  115.12  enum {
  115.13      VMX_CPU_STATE_PAE_ENABLED=0,
  115.14 @@ -46,8 +44,6 @@ struct vmcs_struct {
  115.15      unsigned char data [0]; /* vmcs size is read from MSR */
  115.16  };
  115.17  
  115.18 -extern int vmcs_size;
  115.19 -
  115.20  enum {
  115.21      VMX_INDEX_MSR_LSTAR = 0,
  115.22      VMX_INDEX_MSR_STAR,
  115.23 @@ -64,6 +60,10 @@ struct vmx_msr_state {
  115.24      unsigned long shadow_gs;
  115.25  };
  115.26  
  115.27 +/* io bitmap is 4KBytes in size */
  115.28 +#define IO_BITMAP_SIZE      0x1000
  115.29 +#define IO_BITMAP_ORDER     (get_order_from_bytes(IO_BITMAP_SIZE))
  115.30 +
  115.31  struct arch_vmx_struct {
  115.32      /* Virtual address of VMCS. */
  115.33      struct vmcs_struct  *vmcs;
  115.34 @@ -101,7 +101,10 @@ struct arch_vmx_struct {
  115.35  
  115.36  void vmx_do_resume(struct vcpu *);
  115.37  
  115.38 -struct vmcs_struct *vmx_alloc_vmcs(void);
  115.39 +struct vmcs_struct *vmx_alloc_host_vmcs(void);
  115.40 +void vmx_free_host_vmcs(struct vmcs_struct *vmcs);
  115.41 +
  115.42 +int vmx_create_vmcs(struct vcpu *v);
  115.43  void vmx_destroy_vmcs(struct vcpu *v);
  115.44  void vmx_vmcs_enter(struct vcpu *v);
  115.45  void vmx_vmcs_exit(struct vcpu *v);
   116.1 --- a/xen/include/asm-x86/hvm/vmx/vmx.h	Wed Jul 05 10:23:54 2006 -0600
   116.2 +++ b/xen/include/asm-x86/hvm/vmx/vmx.h	Wed Jul 05 20:11:37 2006 -0600
   116.3 @@ -133,6 +133,11 @@ extern unsigned int cpu_rev;
   116.4  #define EXIT_REASON_MSR_WRITE           32
   116.5  #define EXIT_REASON_MWAIT_INSTRUCTION   36
   116.6  
   116.7 +#define EXIT_REASON_INVALID_GUEST_STATE 33
   116.8 +#define EXIT_REASON_MSR_LOADING         34
   116.9 +#define EXIT_REASON_MACHINE_CHECK       41
  116.10 +
  116.11 +
  116.12  /*
  116.13   * Interruption-information format
  116.14   */
   117.1 --- a/xen/include/asm-x86/processor.h	Wed Jul 05 10:23:54 2006 -0600
   117.2 +++ b/xen/include/asm-x86/processor.h	Wed Jul 05 20:11:37 2006 -0600
   117.3 @@ -545,6 +545,9 @@ extern void mtrr_bp_init(void);
   117.4  
   117.5  extern void mcheck_init(struct cpuinfo_x86 *c);
   117.6  
   117.7 +int cpuid_hypervisor_leaves(
   117.8 +    uint32_t idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
   117.9 +
  117.10  #endif /* !__ASSEMBLY__ */
  117.11  
  117.12  #endif /* __ASM_X86_PROCESSOR_H */
   118.1 --- a/xen/include/public/arch-ia64.h	Wed Jul 05 10:23:54 2006 -0600
   118.2 +++ b/xen/include/public/arch-ia64.h	Wed Jul 05 20:11:37 2006 -0600
   118.3 @@ -40,6 +40,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
   118.4  
   118.5  #ifndef __ASSEMBLY__
   118.6  
   118.7 +typedef unsigned long xen_ulong_t;
   118.8 +
   118.9  #define GPFN_MEM          (0UL << 56) /* Guest pfn is normal mem */
  118.10  #define GPFN_FRAME_BUFFER (1UL << 56) /* VGA framebuffer */
  118.11  #define GPFN_LOW_MMIO     (2UL << 56) /* Low MMIO range */
   119.1 --- a/xen/include/public/arch-x86_32.h	Wed Jul 05 10:23:54 2006 -0600
   119.2 +++ b/xen/include/public/arch-x86_32.h	Wed Jul 05 20:11:37 2006 -0600
   119.3 @@ -98,6 +98,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
   119.4  
   119.5  #ifndef __ASSEMBLY__
   119.6  
   119.7 +typedef unsigned long xen_ulong_t;
   119.8 +
   119.9  /*
  119.10   * Send an array of these to HYPERVISOR_set_trap_table()
  119.11   */
   120.1 --- a/xen/include/public/arch-x86_64.h	Wed Jul 05 10:23:54 2006 -0600
   120.2 +++ b/xen/include/public/arch-x86_64.h	Wed Jul 05 20:11:37 2006 -0600
   120.3 @@ -105,6 +105,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
   120.4  
   120.5  #ifndef __ASSEMBLY__
   120.6  
   120.7 +typedef unsigned long xen_ulong_t;
   120.8 +
   120.9  /*
  120.10   * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base)
  120.11   *  @which == SEGBASE_*  ;  @base == 64-bit base address
   121.1 --- a/xen/include/public/dom0_ops.h	Wed Jul 05 10:23:54 2006 -0600
   121.2 +++ b/xen/include/public/dom0_ops.h	Wed Jul 05 20:11:37 2006 -0600
   121.3 @@ -162,7 +162,7 @@ DEFINE_XEN_GUEST_HANDLE(dom0_settime_t);
   121.4  
   121.5  struct dom0_getpageframeinfo {
   121.6      /* IN variables. */
   121.7 -    xen_pfn_t mfn;         /* Machine page frame number to query.       */
   121.8 +    xen_pfn_t gmfn;        /* GMFN to query.                            */
   121.9      domid_t domain;        /* To which domain does the frame belong?    */
  121.10      /* OUT variables. */
  121.11      /* Is the page PINNED to a type? */
  121.12 @@ -177,9 +177,9 @@ DEFINE_XEN_GUEST_HANDLE(dom0_getpagefram
  121.13  #define DOM0_READCONSOLE      19
  121.14  struct dom0_readconsole {
  121.15      /* IN variables. */
  121.16 -    uint32_t clear;            /* Non-zero -> clear after reading. */
  121.17 +    uint32_t clear;                /* Non-zero -> clear after reading. */
  121.18 +    XEN_GUEST_HANDLE(char) buffer; /* Buffer start */
  121.19      /* IN/OUT variables. */
  121.20 -    XEN_GUEST_HANDLE(char) buffer; /* In: Buffer start; Out: Used buffer start */
  121.21      uint32_t count;            /* In: Buffer size;  Out: Used buffer size  */
  121.22  };
  121.23  typedef struct dom0_readconsole dom0_readconsole_t;
  121.24 @@ -509,8 +509,8 @@ DEFINE_XEN_GUEST_HANDLE(dom0_iomem_permi
  121.25  
  121.26  #define DOM0_HYPERCALL_INIT   48
  121.27  struct dom0_hypercall_init {
  121.28 -    domid_t  domain;          /* domain to be affected */
  121.29 -    xen_pfn_t mfn;            /* machine frame to be initialised */
  121.30 +    domid_t   domain;          /* domain to be affected */
  121.31 +    xen_pfn_t gmfn;            /* GMFN to be initialised */
  121.32  };
  121.33  typedef struct dom0_hypercall_init dom0_hypercall_init_t;
  121.34  DEFINE_XEN_GUEST_HANDLE(dom0_hypercall_init_t);
   122.1 --- a/xen/include/public/io/netif.h	Wed Jul 05 10:23:54 2006 -0600
   122.2 +++ b/xen/include/public/io/netif.h	Wed Jul 05 20:11:37 2006 -0600
   122.3 @@ -23,8 +23,9 @@
   122.4   * This is the 'wire' format for packets:
   122.5   *  Request 1: netif_tx_request -- NETTXF_* (any flags)
   122.6   * [Request 2: netif_tx_extra]  (only if request 1 has NETTXF_extra_info)
   122.7 - *  Request 3: netif_tx_request -- NETTXF_more_data
   122.8 + * [Request 3: netif_tx_extra]  (only if request 2 has XEN_NETIF_EXTRA_MORE)
   122.9   *  Request 4: netif_tx_request -- NETTXF_more_data
  122.10 + *  Request 5: netif_tx_request -- NETTXF_more_data
  122.11   *  ...
  122.12   *  Request N: netif_tx_request -- 0
  122.13   */
  122.14 @@ -41,12 +42,9 @@
  122.15  #define _NETTXF_more_data      (2)
  122.16  #define  NETTXF_more_data      (1U<<_NETTXF_more_data)
  122.17  
  122.18 -/* Packet has GSO fields in the following descriptor (netif_tx_extra.u.gso). */
  122.19 -#define _NETTXF_gso            (3)
  122.20 -#define  NETTXF_gso            (1U<<_NETTXF_gso)
  122.21 -
  122.22 -/* This descriptor is followed by an extra-info descriptor (netif_tx_extra). */
  122.23 -#define  NETTXF_extra_info     (NETTXF_gso)
  122.24 +/* Packet to be followed by extra descriptor(s). */
  122.25 +#define _NETTXF_extra_info     (3)
  122.26 +#define  NETTXF_extra_info     (1U<<_NETTXF_extra_info)
  122.27  
  122.28  struct netif_tx_request {
  122.29      grant_ref_t gref;      /* Reference to buffer page */
  122.30 @@ -57,15 +55,51 @@ struct netif_tx_request {
  122.31  };
  122.32  typedef struct netif_tx_request netif_tx_request_t;
  122.33  
  122.34 -/* This structure needs to fit within netif_tx_request for compatibility. */