ia64/xen-unstable

changeset 7913:878a9891b056

Merge
author djm@kirby.fc.hp.com
date Fri Nov 18 23:16:29 2005 -0600 (2005-11-18)
parents e62c54ab862f 04a7decd0645
children c35a32f96d20
files xen/arch/ia64/xen/domain.c
line diff
     1.1 --- a/.hgignore	Fri Nov 18 23:06:09 2005 -0600
     1.2 +++ b/.hgignore	Fri Nov 18 23:16:29 2005 -0600
     1.3 @@ -148,6 +148,8 @@
     1.4  ^tools/vtpm_manager/manager/vtpm_managerd$
     1.5  ^tools/xcutils/xc_restore$
     1.6  ^tools/xcutils/xc_save$
     1.7 +^tools/xenmon/setmask$
     1.8 +^tools/xenmon/xenbaked$
     1.9  ^tools/xenstat/xentop/xentop$
    1.10  ^tools/xenstore/testsuite/tmp/.*$
    1.11  ^tools/xenstore/xen$
    1.12 @@ -169,6 +171,7 @@
    1.13  ^tools/xentrace/tbctl$
    1.14  ^tools/xentrace/xenctx$
    1.15  ^tools/xentrace/xentrace$
    1.16 +^tools/xm-test/ramdisk/buildroot
    1.17  ^xen/BLOG$
    1.18  ^xen/TAGS$
    1.19  ^xen/arch/x86/asm-offsets\.s$
     2.1 --- a/Makefile	Fri Nov 18 23:06:09 2005 -0600
     2.2 +++ b/Makefile	Fri Nov 18 23:16:29 2005 -0600
     2.3 @@ -167,6 +167,9 @@ uninstall:
     2.4  	[ -d $(D)/etc/xen ] && mv -f $(D)/etc/xen $(D)/etc/xen.old-`date +%s` || true
     2.5  	rm -rf $(D)/etc/init.d/xend*
     2.6  	rm -rf $(D)/etc/hotplug/xen-backend.agent
     2.7 +	rm -f  $(D)/etc/udev/rules.d/xen-backend.rules
     2.8 +	rm -f  $(D)/etc/udev/xen-backend.rules
     2.9 +	rm -f  $(D)/etc/sysconfig/xendomains
    2.10  	rm -rf $(D)/var/run/xen* $(D)/var/lib/xen*
    2.11  	rm -rf $(D)/boot/*xen*
    2.12  	rm -rf $(D)/lib/modules/*xen*
    2.13 @@ -179,7 +182,8 @@ uninstall:
    2.14  	rm -rf $(D)/usr/$(LIBDIR)/libxenctrl* $(D)/usr/$(LIBDIR)/libxenguest*
    2.15  	rm -rf $(D)/usr/$(LIBDIR)/libxenstore*
    2.16  	rm -rf $(D)/usr/$(LIBDIR)/python/xen $(D)/usr/$(LIBDIR)/xen 
    2.17 -	rm -rf $(D)/usr/$(LIBDIR)/xen/bin
    2.18 +	rm -rf $(D)/usr/$(LIBDIR)/xen/
    2.19 +	rm -rf $(D)/usr/lib/xen/
    2.20  	rm -rf $(D)/usr/sbin/xen* $(D)/usr/sbin/netfix $(D)/usr/sbin/xm
    2.21  	rm -rf $(D)/usr/share/doc/xen
    2.22  	rm -rf $(D)/usr/share/xen
     3.1 --- a/buildconfigs/Rules.mk	Fri Nov 18 23:06:09 2005 -0600
     3.2 +++ b/buildconfigs/Rules.mk	Fri Nov 18 23:16:29 2005 -0600
     3.3 @@ -84,7 +84,7 @@ ref-%/.valid-ref: pristine-%/.valid-pris
     3.4  	rm -rf $(@D)
     3.5  	cp -al $(<D) $(@D)
     3.6  	if [ -d patches/$* ] ; then \
     3.7 -	    for i in patches/$*/*.patch ; do ( cd $(@D) ; patch -p1 <../$$i || exit 1 ) ; done ; \
     3.8 +	    for i in patches/$*/*.patch ; do patch -d $(@D) -p1 <$$i || exit 1 ; done ; \
     3.9  	fi
    3.10  	touch $@ # update timestamp to avoid rebuild
    3.11  endif
     4.1 --- a/docs/man/xm.pod.1	Fri Nov 18 23:06:09 2005 -0600
     4.2 +++ b/docs/man/xm.pod.1	Fri Nov 18 23:16:29 2005 -0600
     4.3 @@ -8,122 +8,385 @@ xm <subcommand> [args]
     4.4  
     4.5  =head1 DESCRIPTION
     4.6  
     4.7 -The B<xm> program is the main interface for managing Xen guest domains. The program can be used to create, pause, and shutdown domains. It can also be used to list current domains, enable or pin VCPUs, and attach or detach virtual block devices. The B<xm> program relies upon B<xend>. The daemon must be running in order for the program to work.
     4.8 +The B<xm> program is the main interface for managing Xen guest
     4.9 +domains. The program can be used to create, pause, and shutdown
    4.10 +domains. It can also be used to list current domains, enable or pin
    4.11 +VCPUs, and attach or detach virtual block devices.
    4.12 +
    4.13 +The basic structure of every xm command is almost always:
    4.14 +
    4.15 +  xm <subcommand> <domain-id> [OPTIONS]
    4.16 +
    4.17 +Where I<subcommand> is one of the sub commands listed below, I<domain-id>
    4.18 +is the numeric domain id, or the domain name (which will be internally
    4.19 +translated to domain id), and I<OPTIONS> are sub command specific
    4.20 +options.  There are a few exceptions to this rule in the cases where
    4.21 +the sub command in question acts on all domains, the entire machine,
    4.22 +or directly on the xen hypervisor.  Those exceptions will be clear for
    4.23 +each of those sub commands.
    4.24  
    4.25 -Domain name <DomName> can be substituted in the subcommands for Domain id <DomId>.
    4.26 +=head1 NOTES
    4.27 +
    4.28 +All B<xm> opperations rely upon the Xen control daemon, aka B<xend>.
    4.29 +For any xm commands to run xend must also be running.  For this reason
    4.30 +you should start xend as a service when your system first boots using
    4.31 +xen.
    4.32 +
    4.33 +Most B<xm> commands require root privledges to run due to the
    4.34 +communications channels used to talk to the hypervisor.  Running as
    4.35 +non root will return an error.
    4.36 +
    4.37 +Most B<xm> commands act asynchronously, so just because the B<xm>
    4.38 +command returned, doesn't mean the action is complete.  This is
    4.39 +important, as many operations on domains, like create and shutdown,
    4.40 +can take considerable time (30 seconds or more) to bring the machine
    4.41 +into a fully compliant state.  If you want to know when one of these
    4.42 +actions has finished you must poll through xm list periodically.
    4.43  
    4.44  =head1 DOMAIN SUBCOMMANDS
    4.45  
    4.46 +The following sub commands manipulate domains directly, as stated
    4.47 +previously most commands take domain-id as the first parameter.
    4.48 +
    4.49  =over 4
    4.50  
    4.51 -=item I<console> <DomId>
    4.52 -
    4.53 -Attach to domain DomId's console.
    4.54 +=item B<console> I<domain-id>
    4.55  
    4.56 -=item I<create> <CfgFile>
    4.57 -
    4.58 -Create a domain based on B<xmdomain.cfg> configuration file.
    4.59 -
    4.60 -=item I<destroy> <DomId>
    4.61 +Attach to domain domain-id's console.  If you've set up your Domains to
    4.62 +have a traditional log in console this will look much like a normal
    4.63 +text log in screen.
    4.64  
    4.65 -Terminate domain DomId immediately.
    4.66 -
    4.67 -=item I<domid> <DomName>
    4.68 +This uses the back end xenconsole service which currently only
    4.69 +works for para-virtual domains.  
    4.70  
    4.71 -Converts a domain name to a domain id.
    4.72 +The attached console will perform much like a standard serial console,
    4.73 +so running curses based interfaces over the console B<is not
    4.74 +advised>.  Vi tends to get very odd when using it over this interface.
    4.75  
    4.76 -=item I<domname> <DomId>
    4.77 -
    4.78 -Converts a domain id to a domain name.
    4.79 +=item B<create> I<[-c]> I<configfile> I<[name=value]>..
    4.80  
    4.81 -=item I<help> [--long]
    4.82 -
    4.83 -Displays command's help message. The long option prints out the complete set of B<xm> subcommands.
    4.84 +The create sub command requires a configfile and can optional take a
    4.85 +series of name value pairs that add to or override variables defined
    4.86 +in the config file.  See L<xmdomain.cfg> for full details of that file
    4.87 +format, and possible options used in either the configfile or
    4.88 +Name=Value combinations.
    4.89  
    4.90 -=item I<list> [DomId, ...]
    4.91 +Configfile can either be an absolute path to a file, or a relative
    4.92 +path to a file located in /etc/xen.
    4.93  
    4.94 -List information about domains.
    4.95 -
    4.96 -=item I<mem-max> <DomId> <Mem>
    4.97 +Create will return B<as soon> as the domain is started.  This B<does
    4.98 +not> mean the guest OS in the domain has actually booted, or is
    4.99 +available for input.
   4.100  
   4.101 -Set domain maximum memory limit to Mem. Mem is in Megabytes. This is the upper memory mark for how much memory a domain can have.
   4.102 +B<OPTIONS>
   4.103  
   4.104 -=item I<mem-set> <DomId> <Mem>
   4.105 +=over 4 
   4.106 +
   4.107 +=item B<-c>
   4.108  
   4.109 -Set domain's memory, in Megabytes. Mem must be less than or equal to the maximum memory for the domain.
   4.110 +Attache console to the domain as soon as it has started.  This is
   4.111 +useful for determining issues with crashing domains.
   4.112  
   4.113 -=item I<migrate> <DomId> <Host> [Options]
   4.114 +=back
   4.115  
   4.116 -Migrate a domain to another Host machine. B<Xend> must be running on other host machine and there must be sufficient resources as well.
   4.117 +B<EXAMPLES>
   4.118  
   4.119  =over 4
   4.120  
   4.121 -Additional Options:
   4.122 +=item I<with config file>
   4.123 +
   4.124 +  xm create Fedora4
   4.125 +
   4.126 +This creates a domain with the file /etc/xen/Fedora4, and returns as
   4.127 +soon as it is run.
   4.128  
   4.129 -    -l, --live                    Use live migration.
   4.130 -    -r, --resource <Mbit value>   Set resource level.
   4.131 +=item I<without config file>
   4.132 + 
   4.133 +  xm create /dev/null ramdisk=initrd.img \
   4.134 +     kernel=/boot/vmlinuz-2.6.12.6-xenU \
   4.135 +     name=ramdisk nics=0 vcpus=1 \
   4.136 +     memory=64 root=/dev/ram0
   4.137 +
   4.138 +This creates the domain without using a config file (more specifically
   4.139 +using /dev/null as an empty config file), kernel and ramdisk as
   4.140 +specified, setting the name of the domain to "ramdisk", also disabling
   4.141 +virtual networking.  (This example comes from the xm-test test suite.)
   4.142  
   4.143  =back
   4.144  
   4.145 -=item I<pause> <DomId>
   4.146 +=item B<destroy> I<domain-id>
   4.147 +
   4.148 +Immediately terminate the domain domain-id.  This doesn't give the domain
   4.149 +OS any chance to react, and it the equivalent of ripping the power
   4.150 +cord out on a physical machine.  In most cases you will want to use
   4.151 +the B<shutdown> command instead.
   4.152 +
   4.153 +=item B<domid> I<domain-name>
   4.154 +
   4.155 +Converts a domain name to a domain id using xend's internal mapping.
   4.156  
   4.157 -Pause a domain's execution.
   4.158 +=item B<domname> I<domain-id>
   4.159 +
   4.160 +Converts a domain id to a domain name using xend's internal mapping.
   4.161 +
   4.162 +=item B<help> I<[--long]>
   4.163 +
   4.164 +Displays the short help message (i.e. common commands).
   4.165 +
   4.166 +The I<--long> option prints out the complete set of B<xm> subcommands,
   4.167 +grouped by function.
   4.168  
   4.169 -=item I<reboot> [Options] <DomId>
   4.170 +=item B<list> I<[--long]> I<[domain-id, ...]>
   4.171 +
   4.172 +Prints information about one or more domains.  If no domains are
   4.173 +specified it prints out information about all domains.
   4.174 +
   4.175 +An example format for the list is as follows:
   4.176  
   4.177 -Reboot a domain.
   4.178 +    Name                         ID Mem(MiB) VCPUs State  Time(s)
   4.179 +    Domain-0                      0       98     1 r-----  5068.6
   4.180 +    Fedora3                     164      128     1 r-----     7.6
   4.181 +    Fedora4                     165      128     1 ------     0.6
   4.182 +    Mandrake2006                166      128     1 -b----     3.6
   4.183 +    Mandrake10.2                167      128     1 ------     2.5
   4.184 +    Suse9.2                     168      100     1 ------     1.8
   4.185 +
   4.186 +Name is the name of the domain.  ID the domain numeric id.  Mem is the
   4.187 +size of the memory allocated to the domain.  VCPUS is the number of
   4.188 +VCPUS allocated to domain.  State is the run state (see below).  Time
   4.189 +is the total run time of the domain as accounted for by Xen.
   4.190 +
   4.191 +B<STATES>
   4.192  
   4.193  =over 4
   4.194  
   4.195 -Additional Options:
   4.196 +The State field lists 6 states for a Xen Domain, and which ones the
   4.197 +current Domain is in.
   4.198 +
   4.199 +=item B<r - running>
   4.200 +
   4.201 +The domain is currently running on a CPU
   4.202 +
   4.203 +=item B<b - blocked>
   4.204 +
   4.205 +The domain is blocked, and not running or runable.  This can be caused
   4.206 +because the domain is waiting on IO (a traditional wait state) or has
   4.207 +gone to sleep because there was nothing else for it to do.
   4.208 +
   4.209 +=item B<p - paused>
   4.210 +
   4.211 +The domain has been paused, usually occurring through the administrator
   4.212 +running B<xm pause>.  When in a paused state the domain will still
   4.213 +consume allocated resources like memory, but will not be eligible for
   4.214 +scheduling by the Xen hypervisor.
   4.215 +
   4.216 +=item B<s - shutdown>
   4.217 +
   4.218 +FIXME: Why would you ever see this state?
   4.219 +
   4.220 +=item B<c - crashed>
   4.221 +
   4.222 +The domain has crashed, which is always a violent ending.  Usually
   4.223 +this state can only occur if the domain has been configured not to
   4.224 +restart on crash.  See L<xmdomain.cfg> for more info.
   4.225 +
   4.226 +=item B<d - dying>
   4.227  
   4.228 -    -a, --all        reboot all domains.
   4.229 -    -w, --wait       Wait for shutdown to complete.
   4.230 +The domain is in process of dying, but hasn't completely shutdown or
   4.231 +crashed.
   4.232 +
   4.233 +FIXME: Is this right?
   4.234 +
   4.235 +=back
   4.236 +
   4.237 +B<LONG OUTPUT>
   4.238 +
   4.239 +=over 4
   4.240 +
   4.241 +If I<--long> is specified, the output for xm list is not the table
   4.242 +view shown above, but instead is an S-Expression representing all
   4.243 +information known about all domains asked for.  This is mostly only
   4.244 +useful for external programs to parse the data.
   4.245 +
   4.246 +B<Note:> there is no stable guarantees on the format of this data.
   4.247 +Use at your own risk.
   4.248 +
   4.249 +=back
   4.250 +
   4.251 +B<NOTES>
   4.252 +
   4.253 +=over 4
   4.254 +
   4.255 +The Time column is deceptive.  Virtual IO (network and block devices)
   4.256 +used by Domains requires coordination by Domain0, which means that
   4.257 +Domain0 is actually charged for much of the time that a DomainU is
   4.258 +doing IO.  Use of this time value to determine relative utilizations
   4.259 +by domains is thus very suspect, as a high IO workload may show as
   4.260 +less utilized than a high CPU workload.  Consider yourself warned.
   4.261  
   4.262  =back
   4.263  
   4.264 -=item I<restore> <File>
   4.265 +=item B<mem-max> I<domain-id> I<mem>
   4.266 +
   4.267 +Specify the maximum amount of memory the Domain is able to use.  Mem
   4.268 +is specified in megabytes. 
   4.269 +
   4.270 +The mem-max value may not correspond to the actual memory used in the
   4.271 +Domain, as it may balloon down it's memory to give more back to the OS.
   4.272 +
   4.273 +=item B<mem-set> I<domain-id> I<mem>
   4.274 +
   4.275 +Set the domain's used memory using the balloon driver.  Because this
   4.276 +operation requires cooperation from the domain operating system, there
   4.277 +is no guarantee that it will succeed.
   4.278  
   4.279 -Create a domain from saved state File.
   4.280 +B<Warning:> there is no good way to know in advance how small of a
   4.281 +mem-set will make a domain unstable and cause it to crash.  Be very
   4.282 +careful when using this command on running domains.
   4.283 +
   4.284 +=item B<migrate> I<domain-id> I<host> I<[options]>
   4.285  
   4.286 -=item I<save> <DomId> <File>
   4.287 +Migrate a domain to another Host machine. B<Xend> must be running on
   4.288 +other host machine, it must be running the same version of xen, it
   4.289 +must have the migration tcp port open and accepting connections from
   4.290 +the source host, and there must be sufficient resources for the domain
   4.291 +to run (memory, disk, etc).
   4.292 +
   4.293 +Migration is pretty complicated, and has many security implications,
   4.294 +please read the Xen Users Guide to ensure you understand the
   4.295 +ramifications and limitations on migration before attempting it in
   4.296 +production.
   4.297 +
   4.298 +B<OPTIONS>
   4.299  
   4.300 -Save domain state to File. Saves domain configuration to File as well.
   4.301 +=over 4
   4.302 +
   4.303 +=item B<-l, --live>
   4.304 +
   4.305 +Use live migration.  This will migrate the domain between hosts
   4.306 +without shutting down the domain.  See the Xen Users Guide for more
   4.307 +information.
   4.308 +
   4.309 +=item B<-r, --resource> I<Mbs>
   4.310 +
   4.311 +Set maximum Mbs allowed for migrating the domain.  This ensures that
   4.312 +the network link is not saturated with migration traffic while
   4.313 +attempting to do other useful work.
   4.314 +
   4.315 +=back
   4.316  
   4.317 -=item I<shutdown> [Options] <DomId>
   4.318 +=item B<pause> I<domain-id>
   4.319 +
   4.320 +Pause a domain.  When in a paused state the domain will still consume
   4.321 +allocated resources such as memory, but will not be eligible for
   4.322 +scheduling by the Xen hypervisor.
   4.323 +
   4.324 +=item B<reboot> I<[options]> I<domain-id>
   4.325  
   4.326 -Shutdown a domain.
   4.327 +Reboot a domain.  This acts just as if the domain had the B<reboot>
   4.328 +command run from the console.  The command returns as soon as it has
   4.329 +executed the reboot action, which may be significantly before the
   4.330 +domain actually reboots.
   4.331 +
   4.332 +The behavior of what happens to a domain when it reboots is set by the
   4.333 +I<on_reboot> parameter of the xmdomain.cfg file when the domain was
   4.334 +created.
   4.335 +
   4.336 +B<OPTIONS>
   4.337  
   4.338  =over 4
   4.339  
   4.340 -Additional Options:
   4.341 +=item B<-a, --all>
   4.342 +
   4.343 +Reboot all domains
   4.344  
   4.345 -    -a, --all        Shutdown all domains.
   4.346 -    -H, --halt       Shutdown domain without reboot.
   4.347 -    -R, --reboot     Shutdown and reboot domain.
   4.348 -    -w, --wait       Wait for shutdown to complete.
   4.349 +=item B<-w, --wait>
   4.350 +
   4.351 +Wait for reboot to complete before returning.  This may take a while,
   4.352 +as all services in the domain will have to be shut down cleanly.
   4.353  
   4.354  =back
   4.355  
   4.356 -=item I<sysrq> <DomId> <letter>
   4.357 +=item B<restore> I<state-file>
   4.358 +
   4.359 +Build a domain from an B<xm save> state file.  See I<save> for more info.
   4.360 +
   4.361 +=item B<save> I<domain-id> I<state-file>
   4.362  
   4.363 -Send a sysrq to a domain.
   4.364 +Saves a running domain to a state file so that it can be restored
   4.365 +later.  Once saved, the domain will no longer be running on the
   4.366 +system, thus the memory allocated for the domain will be free for
   4.367 +other domains to use.  B<xm restore> restores from this state file.
   4.368 +
   4.369 +This is roughly equivalent to doing a hibernate on a running computer,
   4.370 +with all the same limitations.  Open network connections may be
   4.371 +severed upon restore, as TCP timeouts may have expired.
   4.372 +
   4.373 +=item B<shutdown> I<[options]> I<domain-id>
   4.374  
   4.375 -=item I<unpause> <DomId>
   4.376 +Gracefully shuts down a domain.  This coordinates with the domain OS
   4.377 +to perform graceful shutdown, so there is no guaruntee that it will
   4.378 +succeed, and may take a variable length of time depending on what
   4.379 +services must be shutdown in the domain.  The command returns
   4.380 +immediately after signally the domain unless that I<-w> flag is used.
   4.381 +
   4.382 +The behavior of what happens to a domain when it reboots is set by the
   4.383 +I<on_shutdown> parameter of the xmdomain.cfg file when the domain was
   4.384 +created.
   4.385  
   4.386 -Unpause a paused domain.
   4.387 +B<OPTIONS>
   4.388 +
   4.389 +=over 4
   4.390 +
   4.391 +=item B<-a> 
   4.392  
   4.393 -=item I<set-vcpus> <DomId> <VCPUs>
   4.394 +Shutdown B<all> domains.  Often used when doing a complete shutdown of
   4.395 +a Xen system.
   4.396 +
   4.397 +=item B<-w>
   4.398 +
   4.399 +Wait for the domain to complete shutdown before returning.
   4.400  
   4.401 -Enable a specific number of VCPUs for a domain. Subcommand only enables or disables already configured VCPUs for domain.
   4.402 +=back
   4.403 +
   4.404 +=item B<sysrq> I<domain-id> I<letter>
   4.405 +
   4.406 +Send a I<Magic System Request> signal to the domain.  For more
   4.407 +information on available magic sys req operations, see sysrq.txt in
   4.408 +your Linux Kernel sources.
   4.409  
   4.410 -=item I<vpcu-list> [DomID]
   4.411 +=item B<unpause> I<domain-id>
   4.412 +
   4.413 +Moves a domain out of the paused state.  This will allow a previously
   4.414 +paused domain to now be eligible for scheduling by the Xen hypervisor.
   4.415 +
   4.416 +=item B<set-vcpus> I<domain-id> I<vcpu-count>
   4.417 +
   4.418 +Enables the I<vcpu-count> virtual CPUs for the domain in question.
   4.419 +Like mem-set, this command can only allocate up to the maximum virtual
   4.420 +CPU count configured at boot for the domain.
   4.421  
   4.422 -Lists VCPU information for a specific domain or all domains if DomID not given.
   4.423 +If the I<vcpu-count> is smaller than the current number of active
   4.424 +VCPUs, the highest number VCPUs will be hotplug removed.  This may be
   4.425 +important for pinning purposes.
   4.426 +
   4.427 +Attempting to set-vcpus to a number larger than the initially
   4.428 +configured VCPU count is an error.  Trying to set-vcpus to < 1 will be
   4.429 +quietly ignored.
   4.430 +
   4.431 +=item B<vpcu-list> I<[domain-id]>
   4.432  
   4.433 -=item I<vcpu-pin> <DomId> <VCPU> <CPUs>
   4.434 +Lists VCPU information for a specific domain.  If no domain is
   4.435 +specified, VCPU information for all domains will be provided.
   4.436 +
   4.437 +=item B<vcpu-pin> I<domain-id> I<vcpu> I<cpus>
   4.438  
   4.439 -Sets VCPU to only run on specific CPUs.
   4.440 +Pins the the VCPU to only run on the specific CPUs.  
   4.441 +
   4.442 +Normally VCPUs can float between available CPUs whenever Xen deems a
   4.443 +different run state is appropriate.  Pinning can be used to restrict
   4.444 +this, by ensuring certain VCPUs can only run on certain physical
   4.445 +CPUs.
   4.446  
   4.447  =back
   4.448  
   4.449 @@ -131,124 +394,395 @@ Sets VCPU to only run on specific CPUs.
   4.450  
   4.451  =over 4
   4.452  
   4.453 -=item I<dmesg> [OPTION]
   4.454 +=item B<dmesg> I<[-c]>
   4.455  
   4.456 -Read or clear Xen's message buffer. The buffer contains Xen boot, warning, and error messages.
   4.457 +Reads the Xen message buffer, similar to dmesg on a Linux system.  The
   4.458 +buffer contains informational, warning, and error messages created
   4.459 +during Xen's boot process.  If you are having problems with Xen, this
   4.460 +is one of the first places to look as part of problem determination.
   4.461 +
   4.462 +B<OPTIONS>
   4.463  
   4.464  =over 4
   4.465  
   4.466 -Additional Option:
   4.467 +=item B<-c, --clear>
   4.468  
   4.469 -    -c, --clear        Clears Xen's message buffer.
   4.470 +Clears Xen's message buffer.
   4.471  
   4.472  =back
   4.473  
   4.474 -=item I<info>
   4.475 +=item B<info>
   4.476 +
   4.477 +Print information about the Xen host in I<name : value> format.  When
   4.478 +reporting a Xen bug, please provide this information as part of the
   4.479 +bug report.
   4.480 +
   4.481 +Sample xen domain info looks as follows (lines wrapped manually to
   4.482 +make the man page more readable):
   4.483  
   4.484 -Get information about Xen host.
   4.485 + system                 : Linux
   4.486 + host                   : talon
   4.487 + release                : 2.6.12.6-xen0
   4.488 + version                : #1 Mon Nov 14 14:26:26 EST 2005
   4.489 + machine                : i686
   4.490 + nr_cpus                : 2
   4.491 + nr_nodes               : 1
   4.492 + sockets_per_node       : 2
   4.493 + cores_per_socket       : 1
   4.494 + threads_per_core       : 1
   4.495 + cpu_mhz                : 696
   4.496 + hw_caps                : 0383fbff:00000000:00000000:00000040
   4.497 + memory                 : 767
   4.498 + free_memory            : 37
   4.499 + xen_major              : 3
   4.500 + xen_minor              : 0
   4.501 + xen_extra              : -devel
   4.502 + xen_caps               : xen-3.0-x86_32
   4.503 + xen_params             : virt_start=0xfc000000
   4.504 + xen_changeset          : Mon Nov 14 18:13:38 2005 +0100 
   4.505 +                          7793:090e44133d40
   4.506 + cc_compiler            : gcc version 3.4.3 (Mandrakelinux 
   4.507 +                          10.2 3.4.3-7mdk)
   4.508 + cc_compile_by          : sdague
   4.509 + cc_compile_domain      : (none)
   4.510 + cc_compile_date        : Mon Nov 14 14:16:48 EST 2005
   4.511  
   4.512 -=item I<log>
   4.513 +B<FIELDS>
   4.514  
   4.515 -Print B<xend> log.
   4.516 +=over 4
   4.517 +
   4.518 +Not all fields will be explained here, but some of the less obvious
   4.519 +ones deserve explanation:
   4.520 +
   4.521 +=item I<hw_caps>
   4.522 +
   4.523 +A vector showing what hardware capabilities are supported by your
   4.524 +processor.  This is equivalent to, though more cryptic, the flags
   4.525 +field in /proc/cpuinfo on a normal Linux machine.
   4.526 +
   4.527 +=item I<free_memory>
   4.528 +
   4.529 +Available memory (in MB) not allocated to Xen, or any other Domains.
   4.530 +
   4.531 +=item I<xen_caps>
   4.532  
   4.533 -=item I<top>
   4.534 +The xen version, architecture.  Architecture values can be one of:
   4.535 +x86_32, x86_32p (i.e. PAE enabled), x86_64, ia64.
   4.536 +
   4.537 +=item I<xen_changeset>
   4.538 +
   4.539 +The xen mercurial changeset id.  Very useful for determining exactly
   4.540 +what version of code your Xen system was built from.
   4.541 +
   4.542 +=back
   4.543  
   4.544 -Monitor system and domains in real-time.
   4.545 +=item B<log>
   4.546 +
   4.547 +Print out the B<xend> log.  This log file can be found in
   4.548 +/var/log/xend.log.
   4.549 +
   4.550 +=item B<top>
   4.551 +
   4.552 +Executes the xentop command, which provides real time monitoring of
   4.553 +domains.  Xentop is a curses interface, and reasonably self
   4.554 +explanatory.
   4.555  
   4.556  =back
   4.557  
   4.558  =head1 SCHEDULER SUBCOMMANDS
   4.559  
   4.560 -=over 4
   4.561 +Xen ships with a number of domain schedulers, which can be set at boot
   4.562 +time with the I<sched=> parameter on the Xen command line.  By
   4.563 +default I<sedf> is used for scheduling.
   4.564  
   4.565 -=item I<sched-bvt> <Parameters>
   4.566 -
   4.567 -Set Borrowed Virtual Time (BVT) scheduler parameters. There are five parameters, which are given in order below.
   4.568 +FIXME: we really need a scheduler expert to write up this section.
   4.569  
   4.570  =over 4
   4.571  
   4.572 -Parameters:
   4.573 +=item B<sched-bvt> I<mcuadv> I<warpback> I<warpvalue> I<warpl> I<warpu>
   4.574 +
   4.575 +Performs runtime adjustments to the default parameters for the
   4.576 +Borrowed Virtual Time (BVT) scheduler.  For full information on the
   4.577 +BVT concept, please consult the base paper listed in the B<SEE ALSO>
   4.578 +section.
   4.579 +
   4.580 +Set Borrowed Virtual Time (BVT) scheduler parameters. There are five
   4.581 +required parameters, which are given in order below.
   4.582 +
   4.583 +FIXME: what units are all the BVT params in?
   4.584 +
   4.585 +B<PARAMETERS>
   4.586 +
   4.587 +=over 4
   4.588 +
   4.589 +=item I<mcuadv>
   4.590  
   4.591 -    mcuadv - Minimum Charging Unit (MCU) advance.
   4.592 -    warpback - Warp back time allowed.
   4.593 -    warpvalue - Warp value.
   4.594 -    warpl - Warp maximum limit.
   4.595 -    warpu - Unwarped minimum limit.
   4.596 +The MCU (Minimum Charging Unit) advance determines the proportional
   4.597 +share of the CPU that a domain receives. It is set inversely
   4.598 +proportionally to a domain's sharing weight.
   4.599 +
   4.600 +=item I<warpback>
   4.601 +
   4.602 +The amount of `virtual time' the domain is allowed to warp backwards.
   4.603 +
   4.604 +=item I<warpvalue>
   4.605 +
   4.606 +Warp value (FIXME: what does this really mean?)
   4.607 +
   4.608 +=item I<warpl>
   4.609 +
   4.610 +The warp limit is the maximum time a domain can run warped for.
   4.611 +
   4.612 +=item I<warpu>
   4.613 +
   4.614 +The unwarp requirement is the minimum time a domain must run unwarped
   4.615 +for before it can warp again.
   4.616  
   4.617  =back 
   4.618  
   4.619 -=item I<sched-bvt-ctxallow> <Allow>
   4.620 +=item B<sched-bvt-ctxallow> I<allow>
   4.621 +
   4.622 +Sets the BVT scheduler's context switch allowance. 
   4.623  
   4.624 -Sets the BVT scheduler's context switch allowance. Allow is the minimum time slice allowed to run before being pre-empted.
   4.625 +The context switch allowance is similar to the ``quantum'' in
   4.626 +traditional schedulers. It is the minimum time that a scheduled domain
   4.627 +will be allowed to run before being preempted.
   4.628  
   4.629 -=item I<sched-sedf> <Parameters>
   4.630 +=item B<sched-sedf> I<period> I<slice> I<latency-hint> I<extratime> I<weight>
   4.631  
   4.632 -Set simple sEDF scheduler parameters. Use the following parametersin order.
   4.633 +Set Simple EDF (Earliest Deadline First) scheduler parameters.  This
   4.634 +scheduler provides weighted CPU sharing in an intuitive way and uses
   4.635 +realtime-algorithms to ensure time guarantees.  For more information
   4.636 +see docs/misc/sedf_scheduler_mini-HOWTO.txt in the Xen distribution.
   4.637 +
   4.638 +B<PARAMETERS>
   4.639  
   4.640  =over 4
   4.641  
   4.642 -Parameters:
   4.643 +=item I<period>
   4.644 +
   4.645 +The normal EDF scheduling usage in nanosecs
   4.646 +
   4.647 +=item I<slice>
   4.648 +
   4.649 +The normal EDF scheduling usage in nanosecs
   4.650 +
   4.651 +FIXME: these are lame, should explain more.
   4.652  
   4.653 -    period - in nanoseconds
   4.654 -    slice - in nanoseconds
   4.655 -    latency-hint - scaled period if domain is doing heavy I/O
   4.656 -    extratime - flag for allowing domain to run in extra time.
   4.657 -    weight - another way of setting cpu slice.
   4.658 +=item I<latency-hint>
   4.659 +
   4.660 +Scaled period if domain is doing heavy I/O.
   4.661 +
   4.662 +=item I<extratime>
   4.663 +
   4.664 +Flag for allowing domain to run in extra time.
   4.665 +
   4.666 +=item I<weight>
   4.667 +
   4.668 +Another way of setting cpu slice.
   4.669  
   4.670  =back
   4.671  
   4.672 +B<EXAMPLES>
   4.673 +
   4.674 +I<normal EDF (20ms/5ms):>
   4.675 +
   4.676 +    xm sched-sedf <dom-id> 20000000 5000000 0 0 0
   4.677 +  
   4.678 +I<best-effort domains (i.e. non-realtime):>
   4.679 +
   4.680 +    xm sched-sedf <dom-id> 20000000 0 0 1 0
   4.681    4.682 +I<normal EDF (20ms/5ms) + share of extra-time:>
   4.683    4.684 +    xm sched-sedf <dom-id> 20000000 5000000 0 1 0
   4.685 +
   4.686 +I<4 domains with weights 2:3:4:2>
   4.687 +
   4.688 +    xm sched-sedf <d1> 0 0 0 0 2
   4.689 +    xm sched-sedf <d2> 0 0 0 0 3
   4.690 +    xm sched-sedf <d3> 0 0 0 0 4
   4.691 +    xm sched-sedf <d4> 0 0 0 0 2
   4.692 +  
   4.693 +I<1 fully-specified (10ms/3ms) domain, 3 other domains share available
   4.694 +rest in 2:7:3 ratio:>
   4.695 +
   4.696 +    xm sched-sedf <d1> 10000000 3000000 0 0 0   
   4.697 +    xm sched-sedf <d2> 0 0 0 0 2   
   4.698 +    xm sched-sedf <d3> 0 0 0 0 7
   4.699 +    xm sched-sedf <d4> 0 0 0 0 3
   4.700 +
   4.701  =back
   4.702  
   4.703  =head1 VIRTUAL DEVICE COMMANDS
   4.704  
   4.705 +Most virtual devices can be added and removed while guests are
   4.706 +running.  The effect to the guest OS is much the same as any hotplug
   4.707 +event.
   4.708 +
   4.709 +=head2 BLOCK DEVICES
   4.710 +
   4.711 +=over 4
   4.712 +
   4.713 +=item B<block-attach> I<domain-id> I<be-dev> I<fe-dev> I<mode> I<[bedomain-id]>
   4.714 +
   4.715 +Create a new virtual block device.  This will trigger a hotplug event
   4.716 +for the guest.
   4.717 +
   4.718 +B<OPTIONS>
   4.719 +
   4.720 +=over 4
   4.721 +
   4.722 +=item I<domain-id>
   4.723 +
   4.724 +The domain id of the guest domain that the device will be attached to.
   4.725 +
   4.726 +=item I<be-dev>
   4.727 +
   4.728 +The device in the backend domain (usually domain 0) to be exported.
   4.729 +This can be specified as a physical partition (phy:sda7) or as a file
   4.730 +mounted as loopback (file://path/to/loop.iso).
   4.731 +
   4.732 +=item I<fe-dev>
   4.733 +
   4.734 +How the device should be presented to the guest domain.  It can be
   4.735 +specified as either a symbolic name, such as /dev/hdc, for common
   4.736 +devices, or by device id, such as 0x1400 (/dev/hdc device id in hex).
   4.737 +
   4.738 +=item I<mode>
   4.739 +
   4.740 +The access mode for the device from the guest domain.  Supported modes
   4.741 +are I<rw> (read/write) or I<ro> (read-only).
   4.742 +
   4.743 +=item I<bedomain-id>
   4.744 +
   4.745 +The back end domain hosting the device.  This defaults to domain 0.
   4.746 +
   4.747 +=back
   4.748 +
   4.749 +B<EXAMPLES>
   4.750 +
   4.751  =over 4
   4.752  
   4.753 -=item I<block-attach <DomId> <BackDev> <FrontDev> <Mode> [BackDomId]
   4.754 +=item I<Mount an ISO as a Disk>
   4.755 +
   4.756 +xm block-attach guestdomain file://path/to/dsl-2.0RC2.iso /dev/hdc ro
   4.757 +
   4.758 +This will mount the dsl iso as /dev/hdc in the guestdomain as a read
   4.759 +only device.  This will probably not be detected as a cdrom by the
   4.760 +guest, but mounting /dev/hdc manually will work.
   4.761  
   4.762 -Create a new virtual block device.
   4.763 +=back
   4.764 +
   4.765 +=item B<block-detach> I<domain-id> I<devid>
   4.766 +
   4.767 +Destroy a domain's virtual block device. devid B<must> be the device
   4.768 +id given to the device by domain 0.  You will need to run I<xm
   4.769 +block-list> to determine that number.
   4.770 +
   4.771 +FIXME: this is currently B<broken>.  Even though a block device is
   4.772 +removed from domU, it appears to still be allocated in the domain 0.
   4.773  
   4.774 -=item I<block-detach> <DomId> <DevId>
   4.775 +=item B<block-list> I<domain-id>
   4.776 +
   4.777 +List virtual block devices for a domain.  The returned output is
   4.778 +sexpression formatted.
   4.779 +
   4.780 +=head2 NETWORK DEVICES
   4.781  
   4.782 -Destroy a domain's virtual block device. DevId may either be a device ID or the device name as mounted in the guest.
   4.783 +=item B<network-attach> I<domain-id> I<[script=scriptname]> I<[ip=ipaddr]>
   4.784 +I<[mac=macaddr]> I<[bridge=bridge-name]> I<[backend=bedomain-id]>
   4.785 +
   4.786 +Creates a new network device in the domain specified by domain-id.  It
   4.787 +takes the following optional options:
   4.788  
   4.789 -=item I<block-list> <DomId>
   4.790 +B<OPTIONS>
   4.791 +
   4.792 +=over 4
   4.793 +
   4.794 +=item I<script=scriptname>
   4.795  
   4.796 -List virtual block devices for a domain.
   4.797 +Use the specified script name to bring up the network.  Defaults to
   4.798 +the default setting in xend-config.sxp for I<vif-script>.
   4.799 +
   4.800 +=item I<ip=ipaddr>
   4.801 +
   4.802 +Passes the specified IP Address to the adapter on creation.  
   4.803  
   4.804 -=item I<network-limit> <DomId> <Vif> <Credit> <Period>
   4.805 +FIXME: this currently appears to be B<broken>.  I'm not sure under what
   4.806 +circumstances this should actually work.
   4.807 +
   4.808 +=item I<mac=macaddr>
   4.809 +
   4.810 +The MAC address that the domain will see on its ethernet device.  If
   4.811 +the device is not specified it will be randomly generated with the
   4.812 +00:16:3e vendor id prefix.
   4.813 +
   4.814 +=item I<bridge=bridge-name>
   4.815  
   4.816 -Limit the transmission rate of a virtual network interface.
   4.817 +The name of the bridge to attach the vif to, in case you have more
   4.818 +than one.  This defaults to 
   4.819 +
   4.820 +=item I<backend=bedomain-id>
   4.821 +
   4.822 +The backend domain id.  By default this is domain 0.
   4.823 +
   4.824 +=back
   4.825 +
   4.826 +=item B<network-detach> I<domain-id> I<devid>
   4.827  
   4.828 -=item I<network-list> <DomId>
   4.829 +Removes the network device from the domain specified by I<domain-id>.
   4.830 +I<devid> is the virtual interface device number within the domain
   4.831 +(i.e. the 3 in vif22.3).
   4.832  
   4.833 -List virtual network interfaces for a domain.
   4.834 +FIXME: this is currently B<broken>.  Network devices aren't completely
   4.835 +removed from domain 0.
   4.836 +
   4.837 +=item B<network-list> I<domain-id>
   4.838 +
   4.839 +List virtual network interfaces for a domain.  The returned output is
   4.840 +sexpression formatted.
   4.841  
   4.842  =back
   4.843  
   4.844  =head1 VNET COMMANDS
   4.845  
   4.846 +The Virtual Network interfaces for Xen.
   4.847 +
   4.848 +FIXME: This needs a lot more explaination, or it needs to be ripped
   4.849 +out entirely.
   4.850 +
   4.851  =over 4
   4.852  
   4.853 -=item I<vnet-list> [-l|--long]
   4.854 +=item B<vnet-list> I<[-l|--long]>
   4.855  
   4.856  List vnets.
   4.857  
   4.858 -=item I<vnet-create> <config>
   4.859 +=item B<vnet-create> I<config>
   4.860  
   4.861  Create a vnet from a config file.
   4.862  
   4.863 -=item I<vnet-delete> <vnetid>
   4.864 +=item B<vnet-delete> I<vnetid>
   4.865  
   4.866  Delete a vnet.
   4.867  
   4.868  =back
   4.869  
   4.870 +=head1 EXAMPLES
   4.871 +
   4.872  =head1 SEE ALSO
   4.873  
   4.874 -B<xmdomain.cfg>(5)
   4.875 +B<xmdomain.cfg>(5), B<xentop>(1)
   4.876 +
   4.877 +BVT scheduling paper: K.J. Duda and D.R. Cheriton. Borrowed Virtual
   4.878 +Time (BVT) scheduling: supporting latency-sensitive threads in a
   4.879 +general purpose scheduler. In proceedings of the 17th ACM SIGOPS
   4.880 +Symposium on Operating Systems principles, volume 33(5) of ACM
   4.881 +Operating Systems Review, pages 261-267
   4.882  
   4.883  =head1 AUTHOR
   4.884  
   4.885 +  Sean Dague <sean at dague dot net>
   4.886    Daniel Stekloff <dsteklof at us dot ibm dot com>
   4.887  
   4.888  =head1 BUGS
     5.1 --- a/docs/man/xmdomain.cfg.pod.5	Fri Nov 18 23:06:09 2005 -0600
     5.2 +++ b/docs/man/xmdomain.cfg.pod.5	Fri Nov 18 23:16:29 2005 -0600
     5.3 @@ -1,6 +1,6 @@
     5.4  =head1 NAME
     5.5  
     5.6 -xmdomain.cfg - xm domain create config file format
     5.7 +xmdomain.cfg - xm domain config file format
     5.8  
     5.9  =head1 SYNOPSIS
    5.10  
    5.11 @@ -10,17 +10,22 @@ xmdomain.cfg - xm domain create config f
    5.12  
    5.13  =head1 DESCRIPTION
    5.14  
    5.15 -The xm(1) program uses python executable config files to define
    5.16 +The B<xm>(1) program uses python executable config files to define
    5.17  domains to create from scratch.  Each of these config files needs to
    5.18  contain a number of required options, and may specify many more.
    5.19  
    5.20 -Domain configuration files live in /etc/xen by default, though the
    5.21 -full path to the config file must be specified in the I<xm create>
    5.22 -command, so they can exist anywhere in the filesystem.
    5.23 +Domain configuration files live in /etc/xen by default, if you store
    5.24 +config files anywhere else the full path to the config file must be
    5.25 +specified in the I<xm create> command.
    5.26  
    5.27 -/etc/xen/auto is a special case however, as domain config files in
    5.28 -that directory will be started automatically at system boot if the
    5.29 -xendomain init script is enabled.
    5.30 +/etc/xen/auto is a special case.  Domain config files in that
    5.31 +directory will be started automatically at system boot if the
    5.32 +xendomain init script is enabled.  The contents of /etc/xen/auto
    5.33 +should be symlinks to files in /etc/xen to allow I<xm create> to be
    5.34 +used without full paths.
    5.35 +
    5.36 +Options are specified by I<name = value> statements in the
    5.37 +xmdomain.cfg files.
    5.38  
    5.39  =head1 OPTIONS
    5.40  
    5.41 @@ -29,50 +34,157 @@ file.
    5.42  
    5.43  =over 4
    5.44  
    5.45 -=item I<kernel>
    5.46 +=item B<kernel>
    5.47  
    5.48 -The kernel image used in the domain.
    5.49 +The kernel image for the domain.  The format of the parameter is the
    5.50 +fully qualified path to the kernel image file,
    5.51 +i.e. I</boot/vmlinuz-2.6.12-xenU>.
    5.52  
    5.53 -=item I<ramdisk>
    5.54 +
    5.55 +=item B<ramdisk>
    5.56  
    5.57 -The initial ramdisk to be used in the domain.  Default xen domU
    5.58 -kernels do not usually need a ramdisk.
    5.59 +The initial ramdisk for the domain.  The format of the parameter is
    5.60 +the fully qualified path to the initrd, i.e. I</boot/initrd.gz>.  On
    5.61 +many Linux distros you will not need a ramdisk if using the default
    5.62 +xen kernel.
    5.63  
    5.64 -=item I<memory>
    5.65 +=item B<memory>
    5.66  
    5.67 -The amount of memory, in megabytes to allocate to the domain when it
    5.68 +The amount of RAM, in megabytes, to allocate to the domain when it
    5.69  starts.  Allocating insufficient memory for a domain may produce
    5.70 -extremely bizarre behavior.
    5.71 +extremely bizarre behavior.  If there isn't enough free memory left on
    5.72 +the machine to fulfill this request, the domain will fail to start.
    5.73 +
    5.74 +Xen does not support overcommit of memory, so the total memory of all
    5.75 +guests (+ 64 MB needed for Xen) must be less than or equal to the
    5.76 +physical RAM in the machine.
    5.77 +
    5.78 +=item B<name>
    5.79 +
    5.80 +A unique name for the domain.  Attempting to create two domains with
    5.81 +the same name will cause an error.
    5.82 +
    5.83 +=item B<root>
    5.84  
    5.85 -=item I<name>
    5.86 +Specifies the root device for the domain.  This is required for Linux
    5.87 +domains, and possibly other OSes.
    5.88 +
    5.89 +=item B<nics>
    5.90  
    5.91 -A unique name for the domain.  You can not create 2 domains with the
    5.92 -same name.
    5.93 +The number of network interfaces allocated to the domain on boot.  It
    5.94 +defaults to 1.
    5.95 +
    5.96 +=item B<disk>
    5.97 +
    5.98 +An array of block device stanzas, in the form:
    5.99 +
   5.100 +    disk = [ "stanza1", "stanza2", ... ]
   5.101  
   5.102 -=item I<root>
   5.103 +Each stanza has 3 terms, seperated by commas,
   5.104 +"backend-dev,frontend-dev,mode".
   5.105 +
   5.106 +=over 4
   5.107 +
   5.108 +=item I<backend-dev>
   5.109  
   5.110 -Root stanza for the domain (required for Linux domains).
   5.111 +The device in the backend domain that will be exported to the guest
   5.112 +(frontend) domain.  Supported formats include:
   5.113 +
   5.114 +I<phy:device> - export the physical device listed.  The device can be
   5.115 +in symbolic form, as in sda7, or as the hex major/minor number, as in
   5.116 +0x301 (which is hda1).
   5.117  
   5.118 -=item I<disk>
   5.119 +I<file://path/to/file> - export the file listed as a loopback device.
   5.120 +This will take care of the loopback setup before exporting the device.
   5.121 +
   5.122 +=item I<frontend-dev>
   5.123  
   5.124 -An array of disk stanzas 
   5.125 +How the device should appear in the guest domain.  The device can be
   5.126 +in symbolic form, as in sda7, or as the hex major/minor number, as in
   5.127 +0x301 (which is hda1).
   5.128 +
   5.129 +=item I<mode>
   5.130 +
   5.131 +The access mode for the device.  There are currently 2 valid options,
   5.132 +I<r> (read-only), I<w> (read/write).
   5.133  
   5.134  =back
   5.135  
   5.136 -A bare minimal config file example might be as follows:
   5.137 +=item B<vif>
   5.138 +
   5.139 +An arrray of virtual interface stanzas in the form:
   5.140 +
   5.141 +    vif = [ "stanza1", "stanza2", ... ]
   5.142 +
   5.143 +Each stanza specifies a set of I<name = value> options separated by
   5.144 +commas, in the form: "name1=value1, name2=value2, ..."
   5.145 +
   5.146 +B<OPTIONS>
   5.147 +
   5.148 +=over 4
   5.149  
   5.150 -    kernel = "/boot/vmlinuz-2.6-xenU"
   5.151 -    memory = 128
   5.152 -    name = "MyLinux"      
   5.153 -    root = "/dev/hda1 ro"
   5.154 +=item I<bridge>
   5.155 +
   5.156 +The network bridge to be used for this device.  This is especially
   5.157 +needed if multiple bridges exist on the machine.
   5.158 +
   5.159 +=item I<mac>
   5.160 +
   5.161 +The MAC address for the virtual interface.  If mac is not specified,
   5.162 +one will be randomly chosen by xen with the 00:16:3e vendor id prefix.
   5.163 +
   5.164 +=back
   5.165 +
   5.166 +=back
   5.167  
   5.168  =head1 ADDITIONAL OPTIONS
   5.169  
   5.170 +The following options are also supported in the config file, though
   5.171 +are far more rarely used.
   5.172 +
   5.173  =over 4
   5.174  
   5.175 -=item I<builder>
   5.176 +=item B<builder>
   5.177 +
   5.178 +Which builder should be used to construct the domain.  This defaults
   5.179 +to the I<linux> if not specified, which is the builder for
   5.180 +paravirtualized Linux domains.
   5.181 +
   5.182 +=item B<cpu>
   5.183 +
   5.184 +Specifies which CPU the domain should be started on, where 0 specifies
   5.185 +the first cpu, 1 the second, and so on.  This defaults to -1, which
   5.186 +means Xen is free to pick which CPU to start on.
   5.187 +
   5.188 +=item B<extra>
   5.189 +
   5.190 +Extra information to append to the end of the kernel parameter line.
   5.191 +The format is a string, the contents of which can be anything that the
   5.192 +kernel supports.  For instance:
   5.193 +
   5.194 +    extra = "4"
   5.195  
   5.196 -=back 
   5.197 +Will cause the domain to boot to runlevel 4.
   5.198 +
   5.199 +=item B<nfs_server>
   5.200 +
   5.201 +The IP address of the NFS server to use as the root device for the
   5.202 +domain.  In order to do this you'll need to specify I<root=/dev/nfs>,
   5.203 +and specify I<nfs_root>.
   5.204 +
   5.205 +=item B<nfs_root>
   5.206 +
   5.207 +The directory on the NFS server to be used as the root filesystem.
   5.208 +Specified as a fully qualified path, i.e. I</full/path/to/root/dir>.
   5.209 +
   5.210 +=item B<vcpus>
   5.211 +
   5.212 +The number of virtual cpus to allocate to the domain.  In order to use
   5.213 +this the xen kernel must be compiled with SMP support.
   5.214 +
   5.215 +This defaults to 1, meaning running the domain as a UP.
   5.216 +
   5.217 +=back
   5.218  
   5.219  =head1 DOMAIN SHUTDOWN OPTIONS
   5.220  
   5.221 @@ -81,17 +193,17 @@ unplanned) under certain events.  The 3 
   5.222  
   5.223  =over 4
   5.224  
   5.225 -=item I<shutdown>
   5.226 +=item B<on_shutdown>
   5.227  
   5.228  Triggered on either an I<xm shutdown> or graceful shutdown from inside
   5.229  the DomU.
   5.230  
   5.231 -=item I<reboot>
   5.232 +=item B<on_reboot>
   5.233  
   5.234  Triggered on either an I<xm reboot> or graceful reboot from inside the
   5.235  DomU.
   5.236  
   5.237 -=item I<crash>
   5.238 +=item B<on_crash>
   5.239  
   5.240  Triggered when a DomU goes to the crashed state for any reason.
   5.241  
   5.242 @@ -101,23 +213,23 @@ All of them take one of 4 valid states l
   5.243  
   5.244  =over 4
   5.245  
   5.246 -=item I<destroy>
   5.247 +=item B<destroy>
   5.248  
   5.249  The domain will be cleaned up completely.  No attempt at respawning
   5.250  will occur.  This is what a typical shutdown would look like.
   5.251  
   5.252 -=item I<restart>
   5.253 +=item B<restart>
   5.254  
   5.255  The domain will be restarted with the same name as the old domain.
   5.256  This is what a typical reboot would look like.
   5.257  
   5.258 -=item I<preserve>
   5.259 +=item B<preserve>
   5.260  
   5.261  The domain will not be cleaned up at all.  This is often useful for
   5.262  crash state domains which ensures that enough evidence is to debug the
   5.263  real issue.
   5.264  
   5.265 -=item I<rename-restart>
   5.266 +=item B<rename-restart>
   5.267  
   5.268  The old domain will not be cleaned up, but will be renamed so a new
   5.269  domain can be restarted in it's place.  The old domain will be renamed with
   5.270 @@ -127,6 +239,39 @@ it holds, so that the new one may take t
   5.271  
   5.272  =back
   5.273  
   5.274 +=head1 EXAMPLES
   5.275 +
   5.276 +The following are quick examples of ways that domains might be
   5.277 +configured.  They should not be considered an exhaustive set.
   5.278 +
   5.279 +=over 4
   5.280 +
   5.281 +=item I<A Loopback File as Root>
   5.282 +
   5.283 +    kernel = "/boot/vmlinuz-2.6-xenU"
   5.284 +    memory = 128
   5.285 +    name = "MyLinux"      
   5.286 +    root = "/dev/hda1 ro"
   5.287 +    disk = [ "file:/var/xen/mylinux.img,hda1,w" ]
   5.288 +
   5.289 +This creates a domain called MyLinux with 128 MB of memory using a
   5.290 +default xen kernel, and the file /var/xen/mylinux.img loopback mounted
   5.291 +at hda1, which is the root filesystem.
   5.292 +
   5.293 +=item I<NFS Root>
   5.294 +
   5.295 +FIXME: write me
   5.296 +
   5.297 +=item I<LVM Root>
   5.298 +
   5.299 +FIXME: write me
   5.300 +
   5.301 +=item I<Two Networks>
   5.302 +
   5.303 +FIXME: write me
   5.304 +
   5.305 +=back
   5.306 +
   5.307  =head1 SEE ALSO
   5.308  
   5.309  B<xm>(1)
     6.1 --- a/docs/src/user.tex	Fri Nov 18 23:06:09 2005 -0600
     6.2 +++ b/docs/src/user.tex	Fri Nov 18 23:16:29 2005 -0600
     6.3 @@ -9,7 +9,6 @@
     6.4  \latexhtml{\newcommand{\path}[1]{{\small {\tt #1}}}}{\newcommand{\path}[1]{{\tt #1}}}
     6.5  
     6.6  
     6.7 -
     6.8  \begin{document}
     6.9  
    6.10  % TITLE PAGE
    6.11 @@ -21,24 +20,24 @@
    6.12  \vfill
    6.13  \vfill
    6.14  \begin{tabular}{l}
    6.15 -{\Huge \bf Users' manual} \\[4mm]
    6.16 -{\huge Xen v2.0 for x86} \\[80mm]
    6.17 +{\Huge \bf Users' Manual} \\[4mm]
    6.18 +{\huge Xen v3.0} \\[80mm]
    6.19  
    6.20 -{\Large Xen is Copyright (c) 2002-2004, The Xen Team} \\[3mm]
    6.21 +{\Large Xen is Copyright (c) 2002-2005, The Xen Team} \\[3mm]
    6.22  {\Large University of Cambridge, UK} \\[20mm]
    6.23  \end{tabular}
    6.24  \end{center}
    6.25  
    6.26 -{\bf
    6.27 -DISCLAIMER: This documentation is currently under active development
    6.28 -and as such there may be mistakes and omissions --- watch out for
    6.29 -these and please report any you find to the developer's mailing list.
    6.30 -Contributions of material, suggestions and corrections are welcome.
    6.31 -}
    6.32 +{\bf DISCLAIMER: This documentation is currently under active
    6.33 +  development and as such there may be mistakes and omissions ---
    6.34 +  watch out for these and please report any you find to the
    6.35 +  developers' mailing list.  Contributions of material, suggestions
    6.36 +  and corrections are welcome.}
    6.37  
    6.38  \vfill
    6.39  \cleardoublepage
    6.40  
    6.41 +
    6.42  % TABLE OF CONTENTS
    6.43  \pagestyle{plain}
    6.44  \pagenumbering{roman}
    6.45 @@ -46,6 +45,7 @@ Contributions of material, suggestions a
    6.46    \tableofcontents }
    6.47  \cleardoublepage
    6.48  
    6.49 +
    6.50  % PREPARE FOR MAIN TEXT
    6.51  \pagenumbering{arabic}
    6.52  \raggedbottom
    6.53 @@ -68,7 +68,7 @@ Contributions of material, suggestions a
    6.54  %% Chapter Installation moved to installation.tex
    6.55  \include{src/user/installation}
    6.56  
    6.57 -%% Chapter Starting Additional Domains  moved to start_addl_dom.tex
    6.58 +%% Chapter Starting Additional Domains moved to start_addl_dom.tex
    6.59  \include{src/user/start_addl_dom}
    6.60  
    6.61  %% Chapter Domain Management Tools moved to domain_mgmt.tex
    6.62 @@ -87,6 +87,9 @@ Contributions of material, suggestions a
    6.63  %% Chapter Domain Configuration moved to domain_configuration.tex
    6.64  \include{src/user/domain_configuration}
    6.65  
    6.66 +%% Chapter Securing Xen
    6.67 +\include{src/user/securing_xen}
    6.68 +
    6.69  %% Chapter Build, Boot and Debug Options moved to build.tex
    6.70  \include{src/user/build}
    6.71  
    6.72 @@ -99,25 +102,25 @@ that bug reports, suggestions and contri
    6.73  software (or the documentation) should be sent to the Xen developers'
    6.74  mailing list (address below).
    6.75  
    6.76 +
    6.77  \section{Other Documentation}
    6.78  
    6.79  For developers interested in porting operating systems to Xen, the
    6.80 -{\em Xen Interface Manual} is distributed in the \path{docs/}
    6.81 -directory of the Xen source distribution.  
    6.82 +\emph{Xen Interface Manual} is distributed in the \path{docs/}
    6.83 +directory of the Xen source distribution.
    6.84  
    6.85 -%Various HOWTOs are available in \path{docs/HOWTOS} but this content is
    6.86 -%being integrated into this manual.
    6.87 +% Various HOWTOs are available in \path{docs/HOWTOS} but this content
    6.88 +% is being integrated into this manual.
    6.89  
    6.90  
    6.91  \section{Online References}
    6.92  
    6.93  The official Xen web site is found at:
    6.94 -\begin{quote}
    6.95 -{\tt http://www.cl.cam.ac.uk/netos/xen/}
    6.96 +\begin{quote} {\tt http://www.cl.cam.ac.uk/netos/xen/}
    6.97  \end{quote}
    6.98  
    6.99 -This contains links to the latest versions of all on-line 
   6.100 -documentation (including the lateset version of the FAQ). 
   6.101 +This contains links to the latest versions of all online
   6.102 +documentation, including the latest version of the FAQ.
   6.103  
   6.104  
   6.105  \section{Mailing Lists}
   6.106 @@ -126,17 +129,17 @@ There are currently four official Xen ma
   6.107  
   6.108  \begin{description}
   6.109  \item[xen-devel@lists.xensource.com] Used for development
   6.110 -discussions and bug reports.  Subscribe at: \\
   6.111 -{\small {\tt http://lists.xensource.com/xen-devel}}
   6.112 +  discussions and bug reports.  Subscribe at: \\
   6.113 +  {\small {\tt http://lists.xensource.com/xen-devel}}
   6.114  \item[xen-users@lists.xensource.com] Used for installation and usage
   6.115 -discussions and requests for help.  Subscribe at: \\
   6.116 -{\small {\tt http://lists.xensource.com/xen-users}}
   6.117 +  discussions and requests for help.  Subscribe at: \\
   6.118 +  {\small {\tt http://lists.xensource.com/xen-users}}
   6.119  \item[xen-announce@lists.xensource.com] Used for announcements only.
   6.120 -Subscribe at: \\
   6.121 -{\small {\tt http://lists.xensource.com/xen-announce}}
   6.122 -\item[xen-changelog@lists.xensource.com]  Changelog feed
   6.123 -from the unstable and 2.0 trees - developer oriented.  Subscribe at: \\
   6.124 -{\small {\tt http://lists.xensource.com/xen-changelog}}
   6.125 +  Subscribe at: \\
   6.126 +  {\small {\tt http://lists.xensource.com/xen-announce}}
   6.127 +\item[xen-changelog@lists.xensource.com] Changelog feed
   6.128 +  from the unstable and 2.0 trees - developer oriented.  Subscribe at: \\
   6.129 +  {\small {\tt http://lists.xensource.com/xen-changelog}}
   6.130  \end{description}
   6.131  
   6.132  
   6.133 @@ -149,11 +152,11 @@ from the unstable and 2.0 trees - develo
   6.134  %% Chapter Installing Xen on Red Hat moved to redhat.tex
   6.135  \include{src/user/redhat}
   6.136  
   6.137 -
   6.138  %% Chapter Glossary of Terms moved to glossary.tex
   6.139  \include{src/user/glossary}
   6.140  
   6.141  
   6.142 +
   6.143  \end{document}
   6.144  
   6.145  
   6.146 @@ -181,36 +184,35 @@ from the unstable and 2.0 trees - develo
   6.147  %% # import xenctl.utils
   6.148  %% # help(xenctl.utils)
   6.149  
   6.150 -%% You can use these modules to write your own custom scripts or you can
   6.151 -%% customise the scripts supplied in the Xen distribution.
   6.152 +%% You can use these modules to write your own custom scripts or you
   6.153 +%% can customise the scripts supplied in the Xen distribution.
   6.154  
   6.155  
   6.156  
   6.157  % Explain about AGP GART
   6.158  
   6.159  
   6.160 -%% If you're not intending to configure the new domain with an IP address
   6.161 -%% on your LAN, then you'll probably want to use NAT. The
   6.162 -%% 'xen_nat_enable' installs a few useful iptables rules into domain0 to
   6.163 -%% enable NAT. [NB: We plan to support RSIP in future]
   6.164 -
   6.165 +%% If you're not intending to configure the new domain with an IP
   6.166 +%% address on your LAN, then you'll probably want to use NAT. The
   6.167 +%% 'xen_nat_enable' installs a few useful iptables rules into domain0
   6.168 +%% to enable NAT. [NB: We plan to support RSIP in future]
   6.169  
   6.170  
   6.171  
   6.172  %% Installing the file systems from the CD
   6.173  %% =======================================
   6.174  
   6.175 -%% If you haven't got an existing Linux installation onto which you can
   6.176 -%% just drop down the Xen and Xenlinux images, then the file systems on
   6.177 -%% the CD provide a quick way of doing an install. However, you would be
   6.178 -%% better off in the long run doing a proper install of your preferred
   6.179 -%% distro and installing Xen onto that, rather than just doing the hack
   6.180 -%% described below:
   6.181 +%% If you haven't got an existing Linux installation onto which you
   6.182 +%% can just drop down the Xen and Xenlinux images, then the file
   6.183 +%% systems on the CD provide a quick way of doing an install. However,
   6.184 +%% you would be better off in the long run doing a proper install of
   6.185 +%% your preferred distro and installing Xen onto that, rather than
   6.186 +%% just doing the hack described below:
   6.187  
   6.188 -%% Choose one or two partitions, depending on whether you want a separate
   6.189 -%% /usr or not. Make file systems on it/them e.g.: 
   6.190 -%%   mkfs -t ext3 /dev/hda3
   6.191 -%%   [or mkfs -t ext2 /dev/hda3 && tune2fs -j /dev/hda3 if using an old
   6.192 +%% Choose one or two partitions, depending on whether you want a
   6.193 +%% separate /usr or not. Make file systems on it/them e.g.:
   6.194 +%% mkfs -t ext3 /dev/hda3
   6.195 +%% [or mkfs -t ext2 /dev/hda3 && tune2fs -j /dev/hda3 if using an old
   6.196  %% version of mkfs]
   6.197  
   6.198  %% Next, mount the file system(s) e.g.:
   6.199 @@ -224,12 +226,14 @@ from the unstable and 2.0 trees - develo
   6.200  %% configuration. Changing the password file (etc/shadow) is probably a
   6.201  %% good idea too.
   6.202  
   6.203 -%% To install the usr file system, copy the file system from CD on /usr,
   6.204 -%% though leaving out the "XenDemoCD" and "boot" directories:
   6.205 -%%   cd /usr && cp -a X11R6 etc java libexec root src bin dict kerberos local sbin tmp doc include lib man share /mnt/usr
   6.206 +%% To install the usr file system, copy the file system from CD on
   6.207 +%% /usr, though leaving out the "XenDemoCD" and "boot" directories:
   6.208 +%%   cd /usr && cp -a X11R6 etc java libexec root src bin dict kerberos
   6.209 +%%    local sbin tmp doc include lib man share /mnt/usr
   6.210  
   6.211  %% If you intend to boot off these file systems (i.e. use them for
   6.212 -%% domain 0), then you probably want to copy the /usr/boot directory on
   6.213 -%% the cd over the top of the current symlink to /boot on your root
   6.214 -%% filesystem (after deleting the current symlink) i.e.:
   6.215 +%% domain 0), then you probably want to copy the /usr/boot
   6.216 +%% directory on the cd over the top of the current symlink to /boot
   6.217 +%% on your root filesystem (after deleting the current symlink)
   6.218 +%% i.e.:
   6.219  %%   cd /mnt/root ; rm boot ; cp -a /usr/boot .
     7.1 --- a/docs/src/user/installation.tex	Fri Nov 18 23:06:09 2005 -0600
     7.2 +++ b/docs/src/user/installation.tex	Fri Nov 18 23:16:29 2005 -0600
     7.3 @@ -17,42 +17,37 @@ want to run more than one virtual machin
     7.4  required if you wish to build from source.
     7.5  \begin{itemize}
     7.6  \item A working Linux distribution using the GRUB bootloader and
     7.7 -  running on a P6-class (or newer) CPU.
     7.8 +  running on a P6-class or newer CPU\@.
     7.9  \item [$\dag$] The \path{iproute2} package.
    7.10  \item [$\dag$] The Linux bridge-utils\footnote{Available from {\tt
    7.11        http://bridge.sourceforge.net}} (e.g., \path{/sbin/brctl})
    7.12  \item [$\dag$] The Linux hotplug system\footnote{Available from {\tt
    7.13        http://linux-hotplug.sourceforge.net/}} (e.g., \path{/sbin/hotplug}
    7.14        and related scripts)
    7.15 -\item [$\dag$] An installation of Twisted~v1.3 or
    7.16 -  above\footnote{Available from {\tt http://www.twistedmatrix.com}}.
    7.17 -  There may be a binary package available for your distribution;
    7.18 -  alternatively it can be installed by running `{\sl make
    7.19 -    install-twisted}' in the root of the Xen source tree.
    7.20  \item [$*$] Build tools (gcc v3.2.x or v3.3.x, binutils, GNU make).
    7.21 -\item [$*$] Development installation of libcurl (e.g., libcurl-devel)
    7.22 -\item [$*$] Development installation of zlib (e.g., zlib-dev).
    7.23 -\item [$*$] Development installation of Python v2.2 or later (e.g.,
    7.24 +\item [$*$] Development installation of libcurl (e.g.,\ libcurl-devel).
    7.25 +\item [$*$] Development installation of zlib (e.g.,\ zlib-dev).
    7.26 +\item [$*$] Development installation of Python v2.2 or later (e.g.,\ 
    7.27    python-dev).
    7.28  \item [$*$] \LaTeX\ and transfig are required to build the
    7.29    documentation.
    7.30  \end{itemize}
    7.31  
    7.32 -Once you have satisfied the relevant prerequisites, you can now
    7.33 -install either a binary or source distribution of Xen.
    7.34 +Once you have satisfied these prerequisites, you can now install
    7.35 +either a binary or source distribution of Xen.
    7.36  
    7.37  
    7.38  \section{Installing from Binary Tarball}
    7.39  
    7.40  Pre-built tarballs are available for download from the Xen download
    7.41 -page
    7.42 -\begin{quote} {\tt http://xen.sf.net}
    7.43 +page:
    7.44 +\begin{quote} {\tt http://www.xensource.com/downloads/}
    7.45  \end{quote}
    7.46  
    7.47  Once you've downloaded the tarball, simply unpack and install:
    7.48  \begin{verbatim}
    7.49 -# tar zxvf xen-2.0-install.tgz
    7.50 -# cd xen-2.0-install
    7.51 +# tar zxvf xen-3.0-install.tgz
    7.52 +# cd xen-3.0-install
    7.53  # sh ./install.sh
    7.54  \end{verbatim}
    7.55  
    7.56 @@ -62,48 +57,29 @@ as described in Section~\ref{s:configure
    7.57  
    7.58  \section{Installing from Source}
    7.59  
    7.60 -This section describes how to obtain, build, and install Xen from
    7.61 +This section describes how to obtain, build and install Xen from
    7.62  source.
    7.63  
    7.64  \subsection{Obtaining the Source}
    7.65  
    7.66 -The Xen source tree is available as either a compressed source tar
    7.67 -ball or as a clone of our master BitKeeper repository.
    7.68 +The Xen source tree is available as either a compressed source tarball
    7.69 +or as a clone of our master Mercurial repository.
    7.70  
    7.71  \begin{description}
    7.72  \item[Obtaining the Source Tarball]\mbox{} \\
    7.73 -  Stable versions (and daily snapshots) of the Xen source tree are
    7.74 -  available as compressed tarballs from the Xen download page
    7.75 -  \begin{quote} {\tt http://xen.sf.net}
    7.76 +  Stable versions and daily snapshots of the Xen source tree are
    7.77 +  available from the Xen download page:
    7.78 +  \begin{quote} {\tt \tt http://www.xensource.com/downloads/}
    7.79    \end{quote}
    7.80 -
    7.81 -\item[Using BitKeeper]\mbox{} \\
    7.82 -  If you wish to install Xen from a clone of our latest BitKeeper
    7.83 -  repository then you will need to install the BitKeeper tools.
    7.84 -  Download instructions for BitKeeper can be obtained by filling out
    7.85 -  the form at:
    7.86 -  \begin{quote} {\tt http://www.bitmover.com/cgi-bin/download.cgi}
    7.87 -\end{quote}
    7.88 -The public master BK repository for the 2.0 release lives at:
    7.89 -\begin{quote} {\tt bk://xen.bkbits.net/xen-2.0.bk}
    7.90 -\end{quote} 
    7.91 -You can use BitKeeper to download it and keep it updated with the
    7.92 -latest features and fixes.
    7.93 -
    7.94 -Change to the directory in which you want to put the source code, then
    7.95 -run:
    7.96 -\begin{verbatim}
    7.97 -# bk clone bk://xen.bkbits.net/xen-2.0.bk
    7.98 -\end{verbatim}
    7.99 -
   7.100 -Under your current directory, a new directory named \path{xen-2.0.bk}
   7.101 -has been created, which contains all the source code for Xen, the OS
   7.102 -ports, and the control tools. You can update your repository with the
   7.103 -latest changes at any time by running:
   7.104 -\begin{verbatim}
   7.105 -# cd xen-2.0.bk # to change into the local repository
   7.106 -# bk pull       # to update the repository
   7.107 -\end{verbatim}
   7.108 +\item[Obtaining the source via Mercurial]\mbox{} \\
   7.109 +  The source tree may also be obtained via the public Mercurial
   7.110 +  repository hosted at:
   7.111 +  \begin{quote}{\tt http://xenbits.xensource.com}.
   7.112 +  \end{quote} See the instructions and the Getting Started Guide
   7.113 +  referenced at:
   7.114 +  \begin{quote}
   7.115 +    {\tt http://www.xensource.com/downloads/}.
   7.116 +  \end{quote}
   7.117  \end{description}
   7.118  
   7.119  % \section{The distribution}
   7.120 @@ -124,7 +100,7 @@ latest changes at any time by running:
   7.121  
   7.122  \subsection{Building from Source}
   7.123  
   7.124 -The top-level Xen Makefile includes a target `world' that will do the
   7.125 +The top-level Xen Makefile includes a target ``world'' that will do the
   7.126  following:
   7.127  
   7.128  \begin{itemize}
   7.129 @@ -132,17 +108,17 @@ following:
   7.130  \item Build the control tools, including \xend.
   7.131  \item Download (if necessary) and unpack the Linux 2.6 source code,
   7.132    and patch it for use with Xen.
   7.133 -\item Build a Linux kernel to use in domain 0 and a smaller
   7.134 +\item Build a Linux kernel to use in domain~0 and a smaller
   7.135    unprivileged kernel, which can optionally be used for unprivileged
   7.136    virtual machines.
   7.137  \end{itemize}
   7.138  
   7.139  After the build has completed you should have a top-level directory
   7.140 -called \path{dist/} in which all resulting targets will be placed; of
   7.141 -particular interest are the two kernels XenLinux kernel images, one
   7.142 -with a `-xen0' extension which contains hardware device drivers and
   7.143 -drivers for Xen's virtual devices, and one with a `-xenU' extension
   7.144 -that just contains the virtual ones. These are found in
   7.145 +called \path{dist/} in which all resulting targets will be placed. Of
   7.146 +particular interest are the two XenLinux kernel images, one with a
   7.147 +``-xen0'' extension which contains hardware device drivers and drivers
   7.148 +for Xen's virtual devices, and one with a ``-xenU'' extension that
   7.149 +just contains the virtual ones. These are found in
   7.150  \path{dist/install/boot/} along with the image for Xen itself and the
   7.151  configuration files used during the build.
   7.152  
   7.153 @@ -150,17 +126,15 @@ The NetBSD port can be built using:
   7.154  \begin{quote}
   7.155  \begin{verbatim}
   7.156  # make netbsd20
   7.157 -\end{verbatim}
   7.158 -\end{quote}
   7.159 +\end{verbatim}\end{quote}
   7.160  NetBSD port is built using a snapshot of the netbsd-2-0 cvs branch.
   7.161 -The snapshot is downloaded as part of the build process, if it is not
   7.162 +The snapshot is downloaded as part of the build process if it is not
   7.163  yet present in the \path{NETBSD\_SRC\_PATH} search path.  The build
   7.164 -process also downloads a toolchain which includes all the tools
   7.165 +process also downloads a toolchain which includes all of the tools
   7.166  necessary to build the NetBSD kernel under Linux.
   7.167  
   7.168 -To customize further the set of kernels built you need to edit the
   7.169 -top-level Makefile. Look for the line:
   7.170 -
   7.171 +To customize the set of kernels built you need to edit the top-level
   7.172 +Makefile. Look for the line:
   7.173  \begin{quote}
   7.174  \begin{verbatim}
   7.175  KERNELS ?= mk.linux-2.6-xen0 mk.linux-2.6-xenU
   7.176 @@ -189,7 +163,6 @@ kernel containing only virtual device dr
   7.177  %% After untaring the pristine kernel tree, the makefile uses the {\tt
   7.178  %%   mkbuildtree} script to add the Xen patches to the kernel.
   7.179  
   7.180 -
   7.181  %% \framebox{\parbox{5in}{
   7.182  %%     {\bf Distro specific:} \\
   7.183  %%     {\it Gentoo} --- if not using udev (most installations,
   7.184 @@ -201,7 +174,7 @@ kernel containing only virtual device dr
   7.185  % If you have an SMP machine you may wish to give the {\tt '-j4'}
   7.186  % argument to make to get a parallel build.
   7.187  
   7.188 -If you wish to build a customized XenLinux kernel (e.g. to support
   7.189 +If you wish to build a customized XenLinux kernel (e.g.\ to support
   7.190  additional devices or enable distribution-required features), you can
   7.191  use the standard Linux configuration mechanisms, specifying that the
   7.192  architecture being built for is \path{xen}, e.g:
   7.193 @@ -215,21 +188,21 @@ architecture being built for is \path{xe
   7.194  \end{quote}
   7.195  
   7.196  You can also copy an existing Linux configuration (\path{.config})
   7.197 -into \path{linux-2.6.11-xen0} and execute:
   7.198 +into e.g.\ \path{linux-2.6.11-xen0} and execute:
   7.199  \begin{quote}
   7.200  \begin{verbatim}
   7.201  # make ARCH=xen oldconfig
   7.202  \end{verbatim}
   7.203  \end{quote}
   7.204  
   7.205 -You may be prompted with some Xen-specific options; we advise
   7.206 +You may be prompted with some Xen-specific options. We advise
   7.207  accepting the defaults for these options.
   7.208  
   7.209 -Note that the only difference between the two types of Linux kernel
   7.210 -that are built is the configuration file used for each.  The `U'
   7.211 +Note that the only difference between the two types of Linux kernels
   7.212 +that are built is the configuration file used for each.  The ``U''
   7.213  suffixed (unprivileged) versions don't contain any of the physical
   7.214  hardware device drivers, leading to a 30\% reduction in size; hence
   7.215 -you may prefer these for your non-privileged domains.  The `0'
   7.216 +you may prefer these for your non-privileged domains.  The ``0''
   7.217  suffixed privileged versions can be used to boot the system, as well
   7.218  as in driver domains and unprivileged domains.
   7.219  
   7.220 @@ -259,10 +232,10 @@ destinations.
   7.221  
   7.222  The \path{dist/install/boot} directory will also contain the config
   7.223  files used for building the XenLinux kernels, and also versions of Xen
   7.224 -and XenLinux kernels that contain debug symbols (\path{xen-syms-2.0.6}
   7.225 -and \path{vmlinux-syms-2.6.11.11-xen0}) which are essential for
   7.226 -interpreting crash dumps.  Retain these files as the developers may
   7.227 -wish to see them if you post on the mailing list.
   7.228 +and XenLinux kernels that contain debug symbols such as
   7.229 +(\path{xen-syms-2.0.6} and \path{vmlinux-syms-2.6.11.11-xen0}) which
   7.230 +are essential for interpreting crash dumps.  Retain these files as the
   7.231 +developers may wish to see them if you post on the mailing list.
   7.232  
   7.233  
   7.234  \section{Configuration}
   7.235 @@ -280,23 +253,23 @@ distribution.  The entry should look som
   7.236  
   7.237  {\small
   7.238  \begin{verbatim}
   7.239 -title Xen 2.0 / XenLinux 2.6
   7.240 -  kernel /boot/xen-2.0.gz dom0_mem=131072
   7.241 +title Xen 3.0 / XenLinux 2.6
   7.242 +  kernel /boot/xen-3.0.gz dom0_mem=131072
   7.243    module /boot/vmlinuz-2.6-xen0 root=/dev/sda4 ro console=tty0
   7.244  \end{verbatim}
   7.245  }
   7.246  
   7.247  The kernel line tells GRUB where to find Xen itself and what boot
   7.248 -parameters should be passed to it (in this case, setting domain 0's
   7.249 +parameters should be passed to it (in this case, setting the domain~0
   7.250  memory allocation in kilobytes and the settings for the serial port).
   7.251  For more details on the various Xen boot parameters see
   7.252  Section~\ref{s:xboot}.
   7.253  
   7.254  The module line of the configuration describes the location of the
   7.255  XenLinux kernel that Xen should start and the parameters that should
   7.256 -be passed to it (these are standard Linux parameters, identifying the
   7.257 +be passed to it. Tthese are standard Linux parameters, identifying the
   7.258  root device and specifying it be initially mounted read only and
   7.259 -instructing that console output be sent to the screen).  Some
   7.260 +instructing that console output be sent to the screen. Some
   7.261  distributions such as SuSE do not require the \path{ro} parameter.
   7.262  
   7.263  %% \framebox{\parbox{5in}{
   7.264 @@ -307,25 +280,22 @@ distributions such as SuSE do not requir
   7.265  
   7.266  
   7.267  If you want to use an initrd, just add another \path{module} line to
   7.268 -the configuration, as usual:
   7.269 -
   7.270 +the configuration, like:
   7.271  {\small
   7.272  \begin{verbatim}
   7.273    module /boot/my_initrd.gz
   7.274  \end{verbatim}
   7.275  }
   7.276  
   7.277 -As always when installing a new kernel, it is recommended that you do
   7.278 -not delete existing menu options from \path{menu.lst} --- you may want
   7.279 -to boot your old Linux kernel in future, particularly if you have
   7.280 -problems.
   7.281 +When installing a new kernel, it is recommended that you do not delete
   7.282 +existing menu options from \path{menu.lst}, as you may wish to boot
   7.283 +your old Linux kernel in future, particularly if you have problems.
   7.284  
   7.285  \subsection{Serial Console (optional)}
   7.286  
   7.287  %% kernel /boot/xen-2.0.gz dom0_mem=131072 com1=115200,8n1
   7.288  %% module /boot/vmlinuz-2.6-xen0 root=/dev/sda4 ro
   7.289  
   7.290 -
   7.291  In order to configure Xen serial console output, it is necessary to
   7.292  add an boot option to your GRUB config; e.g.\ replace the above kernel
   7.293  line with:
   7.294 @@ -343,24 +313,23 @@ One can also configure XenLinux to share
   7.295  achieve this append ``\path{console=ttyS0}'' to your module line.
   7.296  
   7.297  If you wish to be able to log in over the XenLinux serial console it
   7.298 -is necessary to add a line into \path{/etc/inittab}, just as per
   7.299 -regular Linux. Simply add the line:
   7.300 +is necessary to add a line into \path{/etc/inittab}. Add the line:
   7.301  \begin{quote} {\small {\tt c:2345:respawn:/sbin/mingetty ttyS0}}
   7.302  \end{quote}
   7.303  
   7.304 -and you should be able to log in. Note that to successfully log in as
   7.305 -root over the serial line will require adding \path{ttyS0} to
   7.306 -\path{/etc/securetty} in most modern distributions.
   7.307 +and you should be able to log in. To successfully log in as root over
   7.308 +the serial line will require adding \path{ttyS0} to
   7.309 +\path{/etc/securetty} if it is not already there.
   7.310  
   7.311  \subsection{TLS Libraries}
   7.312  
   7.313  Users of the XenLinux 2.6 kernel should disable Thread Local Storage
   7.314 -(e.g.\ by doing a \path{mv /lib/tls /lib/tls.disabled}) before
   7.315 -attempting to run with a XenLinux kernel\footnote{If you boot without
   7.316 +(TLS) (e.g.\ by doing a \path{mv /lib/tls /lib/tls.disabled}) before
   7.317 +attempting to boot a XenLinux kernel\footnote{If you boot without
   7.318    first disabling TLS, you will get a warning message during the boot
   7.319    process. In this case, simply perform the rename after the machine
   7.320    is up and then run \texttt{/sbin/ldconfig} to make it take effect.}.
   7.321 -You can always reenable it by restoring the directory to its original
   7.322 +You can always reenable TLS by restoring the directory to its original
   7.323  location (i.e.\ \path{mv /lib/tls.disabled /lib/tls}).
   7.324  
   7.325  The reason for this is that the current TLS implementation uses
   7.326 @@ -369,19 +338,19 @@ not disabled, an emulation mode is used 
   7.327  performance substantially.
   7.328  
   7.329  We hope that this issue can be resolved by working with Linux
   7.330 -distribution vendors to implement a minor backward-compatible change
   7.331 +distributions to implement a minor backward-compatible change
   7.332  to the TLS library.
   7.333  
   7.334  
   7.335  \section{Booting Xen}
   7.336  
   7.337  It should now be possible to restart the system and use Xen.  Reboot
   7.338 -as usual but choose the new Xen option when the Grub screen appears.
   7.339 +and choose the new Xen option when the Grub screen appears.
   7.340  
   7.341  What follows should look much like a conventional Linux boot.  The
   7.342  first portion of the output comes from Xen itself, supplying low level
   7.343 -information about itself and the machine it is running on.  The
   7.344 -following portion of the output comes from XenLinux.
   7.345 +information about itself and the underlying hardware.  The last
   7.346 +portion of the output comes from XenLinux.
   7.347  
   7.348  You may see some errors during the XenLinux boot.  These are not
   7.349  necessarily anything to worry about --- they may result from kernel
   7.350 @@ -389,5 +358,5 @@ configuration differences between your X
   7.351  usually use.
   7.352  
   7.353  When the boot completes, you should be able to log into your system as
   7.354 -usual.  If you are unable to log in to your system running Xen, you
   7.355 -should still be able to reboot with your normal Linux kernel.
   7.356 +usual.  If you are unable to log in, you should still be able to
   7.357 +reboot with your normal Linux kernel.
     8.1 --- a/docs/src/user/introduction.tex	Fri Nov 18 23:06:09 2005 -0600
     8.2 +++ b/docs/src/user/introduction.tex	Fri Nov 18 23:16:29 2005 -0600
     8.3 @@ -2,7 +2,7 @@
     8.4  
     8.5  
     8.6  Xen is a \emph{paravirtualising} virtual machine monitor (VMM), or
     8.7 -`hypervisor', for the x86 processor architecture.  Xen can securely
     8.8 +``hypervisor'', for the x86 processor architecture.  Xen can securely
     8.9  execute multiple virtual machines on a single physical system with
    8.10  close-to-native performance.  The virtual machine technology
    8.11  facilitates enterprise-grade functionality, including:
    8.12 @@ -11,7 +11,7 @@ facilitates enterprise-grade functionali
    8.13  \item Virtual machines with performance close to native hardware.
    8.14  \item Live migration of running virtual machines between physical
    8.15    hosts.
    8.16 -\item Excellent hardware support (supports most Linux device drivers).
    8.17 +\item Excellent hardware support. Supports most Linux device drivers.
    8.18  \item Sandboxed, re-startable device drivers.
    8.19  \end{itemize}
    8.20  
    8.21 @@ -28,7 +28,7 @@ system kernels must explicitly support X
    8.22  space applications and libraries \emph{do not} require modification.
    8.23  
    8.24  Xen support is available for increasingly many operating systems:
    8.25 -right now, Linux and NetBSD are available for Xen 2.0.
    8.26 +right now, Linux and NetBSD are available for Xen 3.0.
    8.27  A FreeBSD port is undergoing testing and will be incorporated into the
    8.28  release soon. Other OS ports, including Plan 9, are in progress.  We
    8.29  hope that that arch-xen patches will be incorporated into the
    8.30 @@ -43,14 +43,14 @@ Possible usage scenarios for Xen include
    8.31  \item [Multiple OS configurations.] Run multiple operating systems
    8.32    simultaneously, for instance for compatibility or QA purposes.
    8.33  \item [Server consolidation.] Move multiple servers onto a single
    8.34 -  physical host with performance and fault isolation provided at
    8.35 +  physical host with performance and fault isolation provided at the
    8.36    virtual machine boundaries.
    8.37  \item [Cluster computing.] Management at VM granularity provides more
    8.38    flexibility than separately managing each physical host, but better
    8.39    control and isolation than single-system image solutions,
    8.40    particularly by using live migration for load balancing.
    8.41  \item [Hardware support for custom OSes.] Allow development of new
    8.42 -  OSes while benefiting from the wide-ranging hardware support of
    8.43 +  OSes while benefitting from the wide-ranging hardware support of
    8.44    existing OSes such as Linux.
    8.45  \end{description}
    8.46  
    8.47 @@ -58,44 +58,44 @@ Possible usage scenarios for Xen include
    8.48  \section{Structure of a Xen-Based System}
    8.49  
    8.50  A Xen system has multiple layers, the lowest and most privileged of
    8.51 -which is Xen itself. 
    8.52 +which is Xen itself.
    8.53  
    8.54 -Xen in turn may host multiple \emph{guest} operating systems, each of
    8.55 -which is executed within a secure virtual machine (in Xen terminology,
    8.56 -a \emph{domain}). Domains are scheduled by Xen to make effective use
    8.57 -of the available physical CPUs.  Each guest OS manages its own
    8.58 -applications, which includes responsibility for scheduling each
    8.59 -application within the time allotted to the VM by Xen.
    8.60 +Xen may host multiple \emph{guest} operating systems, each of which is
    8.61 +executed within a secure virtual machine. In Xen terminology, a
    8.62 +\emph{domain}. Domains are scheduled by Xen to make effective use of
    8.63 +the available physical CPUs.  Each guest OS manages its own
    8.64 +applications. This management includes the responsibility of
    8.65 +scheduling each application within the time allotted to the VM by Xen.
    8.66  
    8.67 -The first domain, \emph{domain 0}, is created automatically when the
    8.68 -system boots and has special management privileges. Domain 0 builds
    8.69 +The first domain, \emph{domain~0}, is created automatically when the
    8.70 +system boots and has special management privileges. Domain~0 builds
    8.71  other domains and manages their virtual devices. It also performs
    8.72  administrative tasks such as suspending, resuming and migrating other
    8.73  virtual machines.
    8.74  
    8.75 -Within domain 0, a process called \emph{xend} runs to manage the
    8.76 -system.  \Xend is responsible for managing virtual machines and
    8.77 -providing access to their consoles.  Commands are issued to \xend over
    8.78 -an HTTP interface, either from a command-line tool or from a web
    8.79 +Within domain~0, a process called \emph{xend} runs to manage the
    8.80 +system.  \Xend\ is responsible for managing virtual machines and
    8.81 +providing access to their consoles.  Commands are issued to \xend\ 
    8.82 +over an HTTP interface, either from a command-line tool or from a web
    8.83  browser.
    8.84  
    8.85  
    8.86  \section{Hardware Support}
    8.87  
    8.88  Xen currently runs only on the x86 architecture, requiring a `P6' or
    8.89 -newer processor (e.g. Pentium Pro, Celeron, Pentium II, Pentium III,
    8.90 -Pentium IV, Xeon, AMD Athlon, AMD Duron).  Multiprocessor machines are
    8.91 -supported, and we also have basic support for HyperThreading (SMT),
    8.92 +newer processor (e.g.\ Pentium Pro, Celeron, Pentium~II, Pentium~III,
    8.93 +Pentium~IV, Xeon, AMD~Athlon, AMD~Duron).  Multiprocessor machines are
    8.94 +supported, and there is basic support for HyperThreading (SMT),
    8.95  although this remains a topic for ongoing research. A port
    8.96 -specifically for x86/64 is in progress, although Xen already runs on
    8.97 -such systems in 32-bit legacy mode. In addition a port to the IA64
    8.98 +specifically for x86/64 is in progress. Xen already runs on such
    8.99 +systems in 32-bit legacy mode. In addition, a port to the IA64
   8.100  architecture is approaching completion. We hope to add other
   8.101  architectures such as PPC and ARM in due course.
   8.102  
   8.103  Xen can currently use up to 4GB of memory.  It is possible for x86
   8.104  machines to address up to 64GB of physical memory but there are no
   8.105 -current plans to support these systems: The x86/64 port is the planned
   8.106 -route to supporting larger memory sizes.
   8.107 +plans to support these systems: The x86/64 port is the planned route
   8.108 +to supporting larger memory sizes.
   8.109  
   8.110  Xen offloads most of the hardware support issues to the guest OS
   8.111  running in Domain~0.  Xen itself contains only the code required to
   8.112 @@ -112,23 +112,22 @@ other hardware by configuring your XenLi
   8.113  
   8.114  Xen was originally developed by the Systems Research Group at the
   8.115  University of Cambridge Computer Laboratory as part of the XenoServers
   8.116 -project, funded by the UK-EPSRC.
   8.117 +project, funded by the UK-EPSRC\@.
   8.118  
   8.119 -XenoServers aim to provide a `public infrastructure for global
   8.120 -distributed computing', and Xen plays a key part in that, allowing us
   8.121 -to efficiently partition a single machine to enable multiple
   8.122 -independent clients to run their operating systems and applications in
   8.123 -an environment providing protection, resource isolation and
   8.124 -accounting.  The project web page contains further information along
   8.125 -with pointers to papers and technical reports:
   8.126 +XenoServers aim to provide a ``public infrastructure for global
   8.127 +distributed computing''. Xen plays a key part in that, allowing one to
   8.128 +efficiently partition a single machine to enable multiple independent
   8.129 +clients to run their operating systems and applications in an
   8.130 +environment. This environment provides protection, resource isolation
   8.131 +and accounting.  The project web page contains further information
   8.132 +along with pointers to papers and technical reports:
   8.133  \path{http://www.cl.cam.ac.uk/xeno}
   8.134  
   8.135 -Xen has since grown into a fully-fledged project in its own right,
   8.136 -enabling us to investigate interesting research issues regarding the
   8.137 -best techniques for virtualising resources such as the CPU, memory,
   8.138 -disk and network.  The project has been bolstered by support from
   8.139 -Intel Research Cambridge, and HP Labs, who are now working closely
   8.140 -with us.
   8.141 +Xen has grown into a fully-fledged project in its own right, enabling
   8.142 +us to investigate interesting research issues regarding the best
   8.143 +techniques for virtualising resources such as the CPU, memory, disk
   8.144 +and network.  The project has been bolstered by support from Intel
   8.145 +Research Cambridge and HP Labs, who are now working closely with us.
   8.146  
   8.147  Xen was first described in a paper presented at SOSP in
   8.148  2003\footnote{\tt
   8.149 @@ -137,7 +136,7 @@ first public release (1.0) was made that
   8.150  significantly matured and is now used in production scenarios on many
   8.151  sites.
   8.152  
   8.153 -Xen 2.0 features greatly enhanced hardware support, configuration
   8.154 +Xen 3.0 features greatly enhanced hardware support, configuration
   8.155  flexibility, usability and a larger complement of supported operating
   8.156  systems. This latest release takes Xen a step closer to becoming the
   8.157  definitive open source solution for virtualisation.
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/docs/src/user/securing_xen.tex	Fri Nov 18 23:16:29 2005 -0600
     9.3 @@ -0,0 +1,85 @@
     9.4 +\chapter{Securing Xen}
     9.5 +
     9.6 +This chapter describes how to secure a Xen system. It describes a number
     9.7 +of scenarios and provides a corresponding set of best practices. It
     9.8 +begins with a section devoted to understanding the security implications
     9.9 +of a Xen system.
    9.10 +
    9.11 +
    9.12 +\section{Xen Security Considerations}
    9.13 +
    9.14 +When deploying a Xen system, one must be sure to secure the management
    9.15 +domain (Domain-0) as much as possible. If the management domain is
    9.16 +compromised, all other domains are also vulnerable. The following are a
    9.17 +set of best practices for Domain-0:
    9.18 +
    9.19 +\begin{enumerate}
    9.20 +\item \textbf{Run the smallest number of necessary services.} The less
    9.21 +  things that are present in a management partition, the better.
    9.22 +  Remember, a service running as root in the management domain has full
    9.23 +  access to all other domains on the system.
    9.24 +\item \textbf{Use a firewall to restrict the traffic to the management
    9.25 +    domain.} A firewall with default-reject rules will help prevent
    9.26 +  attacks on the management domain.
    9.27 +\item \textbf{Do not allow users to access Domain-0.} The Linux kernel
    9.28 +  has been known to have local-user root exploits. If you allow normal
    9.29 +  users to access Domain-0 (even as unprivileged users) you run the risk
    9.30 +  of a kernel exploit making all of your domains vulnerable.
    9.31 +\end{enumerate}
    9.32 +
    9.33 +\section{Security Scenarios}
    9.34 +
    9.35 +
    9.36 +\subsection{The Isolated Management Network}
    9.37 +
    9.38 +In this scenario, each node has two network cards in the cluster. One
    9.39 +network card is connected to the outside world and one network card is a
    9.40 +physically isolated management network specifically for Xen instances to
    9.41 +use.
    9.42 +
    9.43 +As long as all of the management partitions are trusted equally, this is
    9.44 +the most secure scenario. No additional configuration is needed other
    9.45 +than forcing Xend to bind to the management interface for relocation.
    9.46 +
    9.47 +\textbf{FIXME:} What is the option to allow for this?
    9.48 +
    9.49 +
    9.50 +\subsection{A Subnet Behind a Firewall}
    9.51 +
    9.52 +In this scenario, each node has only one network card but the entire
    9.53 +cluster sits behind a firewall. This firewall should do at least the
    9.54 +following:
    9.55 +
    9.56 +\begin{enumerate}
    9.57 +\item Prevent IP spoofing from outside of the subnet.
    9.58 +\item Prevent access to the relocation port of any of the nodes in the
    9.59 +  cluster except from within the cluster.
    9.60 +\end{enumerate}
    9.61 +
    9.62 +The following iptables rules can be used on each node to prevent
    9.63 +migrations to that node from outside the subnet assuming the main
    9.64 +firewall does not do this for you:
    9.65 +
    9.66 +\begin{verbatim}
    9.67 +# this command disables all access to the Xen relocation
    9.68 +# port:
    9.69 +iptables -A INPUT -p tcp --destination-port 8002 -j REJECT
    9.70 +
    9.71 +# this command enables Xen relocations only from the specific
    9.72 +# subnet:
    9.73 +iptables -I INPUT -p tcp -{}-source 192.168.1.1/8 \
    9.74 +    --destination-port 8002 -j ACCEPT
    9.75 +\end{verbatim}
    9.76 +
    9.77 +\subsection{Nodes on an Untrusted Subnet}
    9.78 +
    9.79 +Migration on an untrusted subnet is not safe in current versions of Xen.
    9.80 +It may be possible to perform migrations through a secure tunnel via an
    9.81 +VPN or SSH. The only safe option in the absence of a secure tunnel is to
    9.82 +disable migration completely. The easiest way to do this is with
    9.83 +iptables:
    9.84 +
    9.85 +\begin{verbatim}
    9.86 +# this command disables all access to the Xen relocation port
    9.87 +iptables -A INPUT -p tcp -{}-destination-port 8002 -j REJECT
    9.88 +\end{verbatim}
    10.1 --- a/docs/src/user/start_addl_dom.tex	Fri Nov 18 23:06:09 2005 -0600
    10.2 +++ b/docs/src/user/start_addl_dom.tex	Fri Nov 18 23:16:29 2005 -0600
    10.3 @@ -40,8 +40,7 @@ configuration file. We provide two examp
    10.4  a starting point:
    10.5  \begin{itemize}
    10.6  \item \path{/etc/xen/xmexample1} is a simple template configuration
    10.7 -  file for describing a single VM.
    10.8 -
    10.9 +  file for describing a single VM\@.
   10.10  \item \path{/etc/xen/xmexample2} file is a template description that
   10.11    is intended to be reused for multiple virtual machines.  Setting the
   10.12    value of the \path{vmid} variable on the \path{xm} command line
   10.13 @@ -54,17 +53,17 @@ you may wish to edit include:
   10.14  \begin{quote}
   10.15  \begin{description}
   10.16  \item[kernel] Set this to the path of the kernel you compiled for use
   10.17 -  with Xen (e.g.\ \path{kernel = `/boot/vmlinuz-2.6-xenU'})
   10.18 +  with Xen (e.g.\ \path{kernel = ``/boot/vmlinuz-2.6-xenU''})
   10.19  \item[memory] Set this to the size of the domain's memory in megabytes
   10.20    (e.g.\ \path{memory = 64})
   10.21  \item[disk] Set the first entry in this list to calculate the offset
   10.22 -  of the domain's root partition, based on the domain ID.  Set the
   10.23 +  of the domain's root partition, based on the domain ID\@.  Set the
   10.24    second to the location of \path{/usr} if you are sharing it between
   10.25 -  domains (e.g.\ \path{disk = [`phy:your\_hard\_drive\%d,sda1,w' \%
   10.26 +  domains (e.g.\ \path{disk = ['phy:your\_hard\_drive\%d,sda1,w' \%
   10.27      (base\_partition\_number + vmid),
   10.28 -    `phy:your\_usr\_partition,sda6,r' ]}
   10.29 +    'phy:your\_usr\_partition,sda6,r' ]}
   10.30  \item[dhcp] Uncomment the dhcp variable, so that the domain will
   10.31 -  receive its IP address from a DHCP server (e.g.\ \path{dhcp=`dhcp'})
   10.32 +  receive its IP address from a DHCP server (e.g.\ \path{dhcp=``dhcp''})
   10.33  \end{description}
   10.34  \end{quote}
   10.35  
   10.36 @@ -72,7 +71,7 @@ You may also want to edit the {\bf vif} 
   10.37  the MAC address of the virtual ethernet interface yourself.  For
   10.38  example:
   10.39  \begin{quote}
   10.40 -\verb_vif = [`mac=00:06:AA:F6:BB:B3']_
   10.41 +\verb_vif = ['mac=00:06:AA:F6:BB:B3']_
   10.42  \end{quote}
   10.43  If you do not set this variable, \xend\ will automatically generate a
   10.44  random MAC address from an unused range.
   10.45 @@ -116,6 +115,7 @@ distribution once they have mastered the
   10.46    section of the project's SourceForge site (see
   10.47    \path{http://sf.net/projects/xen/}).
   10.48  \item Create a configuration file like the following:
   10.49 +  \begin{quote}
   10.50  \begin{verbatim}
   10.51  kernel = "/boot/vmlinuz-2.6-xenU"
   10.52  memory = 64
   10.53 @@ -124,11 +124,14 @@ nics = 1
   10.54  ip = "1.2.3.4"
   10.55  disk = ['file:/path/to/ttylinux/rootfs,sda1,w']
   10.56  root = "/dev/sda1 ro"
   10.57 -\end{verbatim}
   10.58 +\end{verbatim}    
   10.59 +  \end{quote}
   10.60  \item Now start the domain and connect to its console:
   10.61 +  \begin{quote}
   10.62  \begin{verbatim}
   10.63  xm create configfile -c
   10.64  \end{verbatim}
   10.65 +  \end{quote}
   10.66  \item Login as root, password root.
   10.67  \end{enumerate}
   10.68  
    11.1 --- a/install.sh	Fri Nov 18 23:06:09 2005 -0600
    11.2 +++ b/install.sh	Fri Nov 18 23:16:29 2005 -0600
    11.3 @@ -27,7 +27,7 @@ echo "Installing Xen from '$src' to '$ds
    11.4  cp -fdRL $src/etc/init.d/* $dst/etc/init.d/
    11.5  echo "All done."
    11.6  
    11.7 -if [ -x /sbin/udev ] && [ ! -z `udev -V` ] && [ `/sbin/udev -V` -ge 059 ]; then
    11.8 +if [ -x /sbin/udev ] && [ ! -z `/sbin/udev -V` ] && [ `/sbin/udev -V` -ge 059 ]; then
    11.9    cp -f $src/etc/udev/rules.d/*.rules $dst/etc/udev/rules.d/
   11.10  else
   11.11    cp -f $src/etc/hotplug/*.agent $dst/etc/hotplug/
    12.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/cpu/common.c	Fri Nov 18 23:06:09 2005 -0600
    12.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/cpu/common.c	Fri Nov 18 23:16:29 2005 -0600
    12.3 @@ -572,7 +572,7 @@ void __cpuinit cpu_gdt_init(struct Xgt_d
    12.4  	     va < gdt_descr->address + gdt_descr->size;
    12.5  	     va += PAGE_SIZE, f++) {
    12.6  		frames[f] = virt_to_mfn(va);
    12.7 -		make_page_readonly((void *)va);
    12.8 +		make_lowmem_page_readonly((void *)va);
    12.9  	}
   12.10  	if (HYPERVISOR_set_gdt(frames, gdt_descr->size / 8))
   12.11  		BUG();
    13.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S	Fri Nov 18 23:06:09 2005 -0600
    13.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S	Fri Nov 18 23:16:29 2005 -0600
    13.3 @@ -81,7 +81,7 @@ VM_MASK		= 0x00020000
    13.4  #define evtchn_upcall_pending		/* 0 */
    13.5  #define evtchn_upcall_mask		1
    13.6  
    13.7 -#define sizeof_vcpu_shift		3
    13.8 +#define sizeof_vcpu_shift		4
    13.9  
   13.10  #ifdef CONFIG_SMP
   13.11  #define preempt_disable(reg)	incl TI_preempt_count(reg)
   13.12 @@ -813,35 +813,9 @@ ENTRY(alignment_check)
   13.13  	pushl $do_alignment_check
   13.14  	jmp error_code
   13.15  
   13.16 -# This handler is special, because it gets an extra value on its stack,
   13.17 -# which is the linear faulting address.
   13.18 -# fastcall register usage:  %eax = pt_regs, %edx = error code,
   13.19 -#			    %ecx = fault address
   13.20  ENTRY(page_fault)
   13.21 -	pushl %ds
   13.22 -	pushl %eax
   13.23 -	xorl %eax, %eax
   13.24 -	pushl %ebp
   13.25 -	pushl %edi
   13.26 -	pushl %esi
   13.27 -	pushl %edx
   13.28 -	decl %eax			/* eax = -1 */
   13.29 -	pushl %ecx
   13.30 -	pushl %ebx
   13.31 -	cld
   13.32 -	pushl %es
   13.33 -#	UNWIND_ESPFIX_STACK
   13.34 -	popl %edi
   13.35 -	movl ES(%esp), %ecx		/* get the faulting address */
   13.36 -	movl ORIG_EAX(%esp), %edx	/* get the error code */
   13.37 -	movl %eax, ORIG_EAX(%esp)
   13.38 -	movl %edi, ES(%esp)
   13.39 -	movl $(__KERNEL_DS),%eax
   13.40 -	movl %eax, %ds
   13.41 -	movl %eax, %es
   13.42 -	movl %esp,%eax			/* pt_regs pointer */
   13.43 -	call do_page_fault
   13.44 -	jmp ret_from_exception
   13.45 +	pushl $do_page_fault
   13.46 +	jmp error_code
   13.47  
   13.48  #ifdef CONFIG_X86_MCE
   13.49  ENTRY(machine_check)
    14.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c	Fri Nov 18 23:06:09 2005 -0600
    14.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c	Fri Nov 18 23:16:29 2005 -0600
    14.3 @@ -15,6 +15,7 @@
    14.4  #include <asm/io.h>
    14.5  #include <asm-xen/balloon.h>
    14.6  #include <asm/tlbflush.h>
    14.7 +#include <asm/swiotlb.h>
    14.8  
    14.9  struct dma_coherent_mem {
   14.10  	void		*virt_base;
    15.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c	Fri Nov 18 23:06:09 2005 -0600
    15.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c	Fri Nov 18 23:16:29 2005 -0600
    15.3 @@ -650,7 +650,7 @@ fastcall void do_int3(struct pt_regs *re
    15.4  
    15.5  static inline void conditional_sti(struct pt_regs *regs)
    15.6  {
    15.7 -	if ((uint8_t)(regs->xcs >> 16) == 0)
    15.8 +	if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
    15.9  		local_irq_enable();
   15.10  }
   15.11  
   15.12 @@ -972,7 +972,7 @@ void __init trap_init_f00f_bug(void)
   15.13  
   15.14  
   15.15  /*
   15.16 - * NB. All these are "trap gates" (i.e. events_mask isn't cleared) except
   15.17 + * NB. All these are "trap gates" (i.e. events_mask isn't set) except
   15.18   * for those that specify <dpl>|4 in the second field.
   15.19   */
   15.20  static trap_info_t trap_table[] = {
   15.21 @@ -988,7 +988,7 @@ static trap_info_t trap_table[] = {
   15.22  	{ 11, 0, __KERNEL_CS, (unsigned long)segment_not_present	},
   15.23  	{ 12, 0, __KERNEL_CS, (unsigned long)stack_segment		},
   15.24  	{ 13, 0, __KERNEL_CS, (unsigned long)general_protection		},
   15.25 -	{ 14, 0, __KERNEL_CS, (unsigned long)page_fault			},
   15.26 +	{ 14, 0|4, __KERNEL_CS, (unsigned long)page_fault		},
   15.27  	{ 15, 0, __KERNEL_CS, (unsigned long)fixup_4gb_segment		},
   15.28  	{ 16, 0, __KERNEL_CS, (unsigned long)coprocessor_error		},
   15.29  	{ 17, 0, __KERNEL_CS, (unsigned long)alignment_check		},
    16.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c	Fri Nov 18 23:06:09 2005 -0600
    16.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c	Fri Nov 18 23:16:29 2005 -0600
    16.3 @@ -208,6 +208,7 @@ fastcall void do_invalid_op(struct pt_re
    16.4  static void dump_fault_path(unsigned long address)
    16.5  {
    16.6  	unsigned long *p, page;
    16.7 +	unsigned long mfn; 
    16.8  
    16.9  	preempt_disable();
   16.10  	page = __pa(per_cpu(cur_pgd, smp_processor_id()));
   16.11 @@ -217,20 +218,22 @@ static void dump_fault_path(unsigned lon
   16.12  	p += (address >> 30) * 2;
   16.13  	printk(KERN_ALERT "%08lx -> *pde = %08lx:%08lx\n", page, p[1], p[0]);
   16.14  	if (p[0] & 1) {
   16.15 -		page = p[0] & PAGE_MASK;
   16.16 +		mfn  = (p[0] >> PAGE_SHIFT) | ((p[1] & 0x7) << 20); 
   16.17 +		page = mfn_to_pfn(mfn) << PAGE_SHIFT; 
   16.18 +		p  = (unsigned long *)__va(page);
   16.19  		address &= 0x3fffffff;
   16.20 -		page = machine_to_phys(page);
   16.21 -		p  = (unsigned long *)__va(page);
   16.22  		p += (address >> 21) * 2;
   16.23 -		printk(KERN_ALERT "%08lx -> *pme = %08lx:%08lx\n", page, p[1], p[0]);
   16.24 +		printk(KERN_ALERT "%08lx -> *pme = %08lx:%08lx\n", 
   16.25 +		       page, p[1], p[0]);
   16.26  #ifndef CONFIG_HIGHPTE
   16.27  		if (p[0] & 1) {
   16.28 -			page = p[0] & PAGE_MASK;
   16.29 +			mfn  = (p[0] >> PAGE_SHIFT) | ((p[1] & 0x7) << 20); 
   16.30 +			page = mfn_to_pfn(mfn) << PAGE_SHIFT; 
   16.31 +			p  = (unsigned long *) __va(page);
   16.32  			address &= 0x001fffff;
   16.33 -			page = machine_to_phys(page);
   16.34 -			p  = (unsigned long *) __va(page);
   16.35  			p += (address >> 12) * 2;
   16.36 -			printk(KERN_ALERT "%08lx -> *pte = %08lx:%08lx\n", page, p[1], p[0]);
   16.37 +			printk(KERN_ALERT "%08lx -> *pte = %08lx:%08lx\n",
   16.38 +			       page, p[1], p[0]);
   16.39  		}
   16.40  #endif
   16.41  	}
   16.42 @@ -279,15 +282,18 @@ static void dump_fault_path(unsigned lon
   16.43   *	bit 1 == 0 means read, 1 means write
   16.44   *	bit 2 == 0 means kernel, 1 means user-mode
   16.45   */
   16.46 -fastcall void do_page_fault(struct pt_regs *regs, unsigned long error_code,
   16.47 -			      unsigned long address)
   16.48 +fastcall void do_page_fault(struct pt_regs *regs, unsigned long error_code)
   16.49  {
   16.50  	struct task_struct *tsk;
   16.51  	struct mm_struct *mm;
   16.52  	struct vm_area_struct * vma;
   16.53 +	unsigned long address;
   16.54  	int write;
   16.55  	siginfo_t info;
   16.56  
   16.57 +	address = HYPERVISOR_shared_info->vcpu_data[
   16.58 +		smp_processor_id()].arch.cr2;
   16.59 +
   16.60  	/* Set the "privileged fault" bit to something sane. */
   16.61  	error_code &= ~4;
   16.62  	error_code |= (regs->xcs & 2) << 1;
   16.63 @@ -297,11 +303,9 @@ fastcall void do_page_fault(struct pt_re
   16.64  	if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
   16.65  					SIGSEGV) == NOTIFY_STOP)
   16.66  		return;
   16.67 -#if 0
   16.68  	/* It's safe to allow irq's after cr2 has been saved */
   16.69  	if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
   16.70  		local_irq_enable();
   16.71 -#endif
   16.72  
   16.73  	tsk = current;
   16.74  
    17.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c	Fri Nov 18 23:06:09 2005 -0600
    17.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c	Fri Nov 18 23:16:29 2005 -0600
    17.3 @@ -37,16 +37,10 @@
    17.4  #include <asm-xen/balloon.h>
    17.5  #include <asm-xen/xen-public/memory.h>
    17.6  #include <linux/module.h>
    17.7 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
    17.8  #include <linux/percpu.h>
    17.9  #include <asm/tlbflush.h>
   17.10 -#endif
   17.11  
   17.12 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
   17.13 -#define pte_offset_kernel pte_offset
   17.14 -#define pud_t pgd_t
   17.15 -#define pud_offset(d, va) d
   17.16 -#elif defined(CONFIG_X86_64)
   17.17 +#ifdef CONFIG_X86_64
   17.18  #define pmd_val_ma(v) (v).pmd
   17.19  #else
   17.20  #ifdef CONFIG_X86_PAE
   17.21 @@ -342,8 +336,8 @@ int xen_create_contiguous_region(
   17.22  		mfn = pte_mfn(*pte);
   17.23  		BUG_ON(HYPERVISOR_update_va_mapping(
   17.24  			vstart + (i*PAGE_SIZE), __pte_ma(0), 0));
   17.25 -		phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] =
   17.26 -			INVALID_P2M_ENTRY;
   17.27 +		set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i,
   17.28 +			INVALID_P2M_ENTRY);
   17.29  		BUG_ON(HYPERVISOR_memory_op(
   17.30  			XENMEM_decrease_reservation, &reservation) != 1);
   17.31  	}
   17.32 @@ -361,7 +355,7 @@ int xen_create_contiguous_region(
   17.33  			vstart + (i*PAGE_SIZE),
   17.34  			pfn_pte_ma(mfn+i, PAGE_KERNEL), 0));
   17.35  		xen_machphys_update(mfn+i, (__pa(vstart)>>PAGE_SHIFT)+i);
   17.36 -		phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] = mfn+i;
   17.37 +		set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i, mfn+i);
   17.38  	}
   17.39  
   17.40  	flush_tlb_all();
   17.41 @@ -383,7 +377,7 @@ int xen_create_contiguous_region(
   17.42  			vstart + (i*PAGE_SIZE),
   17.43  			pfn_pte_ma(mfn, PAGE_KERNEL), 0));
   17.44  		xen_machphys_update(mfn, (__pa(vstart)>>PAGE_SHIFT)+i);
   17.45 -		phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] = mfn;
   17.46 +		set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i, mfn);
   17.47  	}
   17.48  
   17.49  	flush_tlb_all();
   17.50 @@ -422,8 +416,8 @@ void xen_destroy_contiguous_region(unsig
   17.51  		mfn = pte_mfn(*pte);
   17.52  		BUG_ON(HYPERVISOR_update_va_mapping(
   17.53  			vstart + (i*PAGE_SIZE), __pte_ma(0), 0));
   17.54 -		phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] =
   17.55 -			INVALID_P2M_ENTRY;
   17.56 +		set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i,
   17.57 +			INVALID_P2M_ENTRY);
   17.58  		BUG_ON(HYPERVISOR_memory_op(
   17.59  			XENMEM_decrease_reservation, &reservation) != 1);
   17.60  	}
   17.61 @@ -436,7 +430,7 @@ void xen_destroy_contiguous_region(unsig
   17.62  			vstart + (i*PAGE_SIZE),
   17.63  			pfn_pte_ma(mfn, PAGE_KERNEL), 0));
   17.64  		xen_machphys_update(mfn, (__pa(vstart)>>PAGE_SHIFT)+i);
   17.65 -		phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] = mfn;
   17.66 +		set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i, mfn);
   17.67  	}
   17.68  
   17.69  	flush_tlb_all();
    18.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c	Fri Nov 18 23:06:09 2005 -0600
    18.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c	Fri Nov 18 23:16:29 2005 -0600
    18.3 @@ -68,7 +68,7 @@ static pmd_t * __init one_md_table_init(
    18.4  
    18.5  #ifdef CONFIG_X86_PAE
    18.6  	pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
    18.7 -	make_page_readonly(pmd_table);
    18.8 +	make_lowmem_page_readonly(pmd_table);
    18.9  	set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
   18.10  	pud = pud_offset(pgd, 0);
   18.11  	if (pmd_table != pmd_offset(pud, 0)) 
   18.12 @@ -89,7 +89,7 @@ static pte_t * __init one_page_table_ini
   18.13  {
   18.14  	if (pmd_none(*pmd)) {
   18.15  		pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
   18.16 -		make_page_readonly(page_table);
   18.17 +		make_lowmem_page_readonly(page_table);
   18.18  		set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
   18.19  		if (page_table != pte_offset_kernel(pmd, 0))
   18.20  			BUG();	
    19.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c	Fri Nov 18 23:06:09 2005 -0600
    19.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c	Fri Nov 18 23:16:29 2005 -0600
    19.3 @@ -136,21 +136,19 @@ int direct_kernel_remap_pfn_range(unsign
    19.4  }
    19.5  EXPORT_SYMBOL(direct_kernel_remap_pfn_range);
    19.6  
    19.7 -/* FIXME: This is horribly broken on PAE */ 
    19.8  static int lookup_pte_fn(
    19.9  	pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
   19.10  {
   19.11 -	unsigned long *ptep = (unsigned long *)data;
   19.12 +	uint64_t *ptep = (uint64_t *)data;
   19.13  	if (ptep)
   19.14 -		*ptep = (pfn_to_mfn(page_to_pfn(pte_page)) <<
   19.15 -			 PAGE_SHIFT) |
   19.16 -			((unsigned long)pte & ~PAGE_MASK);
   19.17 +		*ptep = ((uint64_t)pfn_to_mfn(page_to_pfn(pte_page)) <<
   19.18 +			 PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
   19.19  	return 0;
   19.20  }
   19.21  
   19.22  int create_lookup_pte_addr(struct mm_struct *mm, 
   19.23  			   unsigned long address,
   19.24 -			   unsigned long *ptep)
   19.25 +			   uint64_t *ptep)
   19.26  {
   19.27  	return generic_page_range(mm, address, PAGE_SIZE, lookup_pte_fn, ptep);
   19.28  }
    20.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c	Fri Nov 18 23:06:09 2005 -0600
    20.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c	Fri Nov 18 23:16:29 2005 -0600
    20.3 @@ -199,7 +199,7 @@ pte_t *pte_alloc_one_kernel(struct mm_st
    20.4  {
    20.5  	pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
    20.6  	if (pte)
    20.7 -		make_page_readonly(pte);
    20.8 +		make_lowmem_page_readonly(pte);
    20.9  	return pte;
   20.10  }
   20.11  
   20.12 @@ -336,7 +336,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
   20.13  		spin_lock_irqsave(&pgd_lock, flags);
   20.14  		memcpy(pmd, copy_pmd, PAGE_SIZE);
   20.15  		spin_unlock_irqrestore(&pgd_lock, flags);
   20.16 -		make_page_readonly(pmd);
   20.17 +		make_lowmem_page_readonly(pmd);
   20.18  		set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd)));
   20.19  	}
   20.20  
   20.21 @@ -367,12 +367,12 @@ void pgd_free(pgd_t *pgd)
   20.22  	if (PTRS_PER_PMD > 1) {
   20.23  		for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
   20.24  			pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
   20.25 -			make_page_writable(pmd);
   20.26 +			make_lowmem_page_writable(pmd);
   20.27  			kmem_cache_free(pmd_cache, pmd);
   20.28  		}
   20.29  		if (!HAVE_SHARED_KERNEL_PMD) {
   20.30  			pmd_t *pmd = (void *)__va(pgd_val(pgd[USER_PTRS_PER_PGD])-1);
   20.31 -			make_page_writable(pmd);
   20.32 +			make_lowmem_page_writable(pmd);
   20.33  			memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
   20.34  			kmem_cache_free(pmd_cache, pmd);
   20.35  		}
   20.36 @@ -382,52 +382,62 @@ void pgd_free(pgd_t *pgd)
   20.37  }
   20.38  
   20.39  #ifndef CONFIG_XEN_SHADOW_MODE
   20.40 +asmlinkage int xprintk(const char *fmt, ...);
   20.41  void make_lowmem_page_readonly(void *va)
   20.42  {
   20.43  	pte_t *pte = virt_to_ptep(va);
   20.44 -	set_pte(pte, pte_wrprotect(*pte));
   20.45 +	int rc = HYPERVISOR_update_va_mapping(
   20.46 +		(unsigned long)va, pte_wrprotect(*pte), 0);
   20.47 +	BUG_ON(rc);
   20.48  }
   20.49  
   20.50  void make_lowmem_page_writable(void *va)
   20.51  {
   20.52  	pte_t *pte = virt_to_ptep(va);
   20.53 -	set_pte(pte, pte_mkwrite(*pte));
   20.54 +	int rc = HYPERVISOR_update_va_mapping(
   20.55 +		(unsigned long)va, pte_mkwrite(*pte), 0);
   20.56 +	BUG_ON(rc);
   20.57  }
   20.58  
   20.59  void make_page_readonly(void *va)
   20.60  {
   20.61  	pte_t *pte = virt_to_ptep(va);
   20.62 -	set_pte(pte, pte_wrprotect(*pte));
   20.63 -	if ( (unsigned long)va >= (unsigned long)high_memory )
   20.64 -	{
   20.65 -		unsigned long phys;
   20.66 -		phys = machine_to_phys(*(unsigned long *)pte & PAGE_MASK);
   20.67 +	int rc = HYPERVISOR_update_va_mapping(
   20.68 +		(unsigned long)va, pte_wrprotect(*pte), 0);
   20.69 +	if (rc) /* fallback? */
   20.70 +		xen_l1_entry_update(pte, pte_wrprotect(*pte));
   20.71 +	if ((unsigned long)va >= (unsigned long)high_memory) {
   20.72 +		unsigned long pfn = pte_pfn(*pte);
   20.73  #ifdef CONFIG_HIGHMEM
   20.74 -		if ( (phys >> PAGE_SHIFT) < highstart_pfn )
   20.75 +		if (pfn >= highstart_pfn)
   20.76 +			kmap_flush_unused(); /* flush stale writable kmaps */
   20.77 +		else
   20.78  #endif
   20.79 -			make_lowmem_page_readonly(phys_to_virt(phys));
   20.80 +			make_lowmem_page_readonly(
   20.81 +				phys_to_virt(pfn << PAGE_SHIFT)); 
   20.82  	}
   20.83  }
   20.84  
   20.85  void make_page_writable(void *va)
   20.86  {
   20.87  	pte_t *pte = virt_to_ptep(va);
   20.88 -	set_pte(pte, pte_mkwrite(*pte));
   20.89 -	if ( (unsigned long)va >= (unsigned long)high_memory )
   20.90 -	{
   20.91 -		unsigned long phys;
   20.92 -		phys = machine_to_phys(*(unsigned long *)pte & PAGE_MASK);
   20.93 +	int rc = HYPERVISOR_update_va_mapping(
   20.94 +		(unsigned long)va, pte_mkwrite(*pte), 0);
   20.95 +	if (rc) /* fallback? */
   20.96 +		xen_l1_entry_update(pte, pte_mkwrite(*pte));
   20.97 +	if ((unsigned long)va >= (unsigned long)high_memory) {
   20.98 +		unsigned long pfn = pte_pfn(*pte); 
   20.99  #ifdef CONFIG_HIGHMEM
  20.100 -		if ( (phys >> PAGE_SHIFT) < highstart_pfn )
  20.101 +		if (pfn < highstart_pfn)
  20.102  #endif
  20.103 -			make_lowmem_page_writable(phys_to_virt(phys));
  20.104 +			make_lowmem_page_writable(
  20.105 +				phys_to_virt(pfn << PAGE_SHIFT)); 
  20.106  	}
  20.107  }
  20.108  
  20.109  void make_pages_readonly(void *va, unsigned int nr)
  20.110  {
  20.111 -	while ( nr-- != 0 )
  20.112 -	{
  20.113 +	while (nr-- != 0) {
  20.114  		make_page_readonly(va);
  20.115  		va = (void *)((unsigned long)va + PAGE_SIZE);
  20.116  	}
  20.117 @@ -435,8 +445,7 @@ void make_pages_readonly(void *va, unsig
  20.118  
  20.119  void make_pages_writable(void *va, unsigned int nr)
  20.120  {
  20.121 -	while ( nr-- != 0 )
  20.122 -	{
  20.123 +	while (nr-- != 0) {
  20.124  		make_page_writable(va);
  20.125  		va = (void *)((unsigned long)va + PAGE_SIZE);
  20.126  	}
    21.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/devmem.c	Fri Nov 18 23:06:09 2005 -0600
    21.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/devmem.c	Fri Nov 18 23:16:29 2005 -0600
    21.3 @@ -79,7 +79,7 @@ static ssize_t write_mem(struct file * f
    21.4  
    21.5  	if ((v = ioremap(p, count)) == NULL)
    21.6  		return -EFAULT;
    21.7 -	if (copy_to_user(v, buf, count))
    21.8 +	if (copy_from_user(v, buf, count))
    21.9  		goto out;
   21.10  
   21.11  	written = count;
    22.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c	Fri Nov 18 23:06:09 2005 -0600
    22.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c	Fri Nov 18 23:16:29 2005 -0600
    22.3 @@ -121,11 +121,7 @@ static void init_evtchn_cpu_bindings(voi
    22.4  
    22.5  /* Upcall to generic IRQ layer. */
    22.6  #ifdef CONFIG_X86
    22.7 -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)
    22.8  extern fastcall unsigned int do_IRQ(struct pt_regs *regs);
    22.9 -#else
   22.10 -extern asmlinkage unsigned int do_IRQ(struct pt_regs *regs);
   22.11 -#endif
   22.12  #if defined (__i386__)
   22.13  #define IRQ_REG orig_eax
   22.14  #elif defined (__x86_64__)
   22.15 @@ -752,7 +748,7 @@ void __init init_IRQ(void)
   22.16  		irq_bindcount[dynirq_to_irq(i)] = 0;
   22.17  
   22.18  		irq_desc[dynirq_to_irq(i)].status  = IRQ_DISABLED;
   22.19 -		irq_desc[dynirq_to_irq(i)].action  = 0;
   22.20 +		irq_desc[dynirq_to_irq(i)].action  = NULL;
   22.21  		irq_desc[dynirq_to_irq(i)].depth   = 1;
   22.22  		irq_desc[dynirq_to_irq(i)].handler = &dynirq_type;
   22.23  	}
   22.24 @@ -770,7 +766,7 @@ void __init init_IRQ(void)
   22.25  #endif
   22.26  
   22.27  		irq_desc[pirq_to_irq(i)].status  = IRQ_DISABLED;
   22.28 -		irq_desc[pirq_to_irq(i)].action  = 0;
   22.29 +		irq_desc[pirq_to_irq(i)].action  = NULL;
   22.30  		irq_desc[pirq_to_irq(i)].depth   = 1;
   22.31  		irq_desc[pirq_to_irq(i)].handler = &pirq_type;
   22.32  	}
    23.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c	Fri Nov 18 23:06:09 2005 -0600
    23.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c	Fri Nov 18 23:16:29 2005 -0600
    23.3 @@ -15,6 +15,7 @@
    23.4  #include <asm-xen/xenbus.h>
    23.5  #include <linux/cpu.h>
    23.6  #include <linux/kthread.h>
    23.7 +#include <asm-xen/xencons.h>
    23.8  
    23.9  #define SHUTDOWN_INVALID  -1
   23.10  #define SHUTDOWN_POWEROFF  0
   23.11 @@ -29,7 +30,6 @@
   23.12  void machine_restart(char * __unused)
   23.13  {
   23.14  	/* We really want to get pending console data out before we die. */
   23.15 -	extern void xencons_force_flush(void);
   23.16  	xencons_force_flush();
   23.17  	HYPERVISOR_sched_op(SCHEDOP_shutdown, SHUTDOWN_reboot);
   23.18  }
   23.19 @@ -42,7 +42,6 @@ void machine_halt(void)
   23.20  void machine_power_off(void)
   23.21  {
   23.22  	/* We really want to get pending console data out before we die. */
   23.23 -	extern void xencons_force_flush(void);
   23.24  	xencons_force_flush();
   23.25  	HYPERVISOR_sched_op(SCHEDOP_shutdown, SHUTDOWN_poweroff);
   23.26  }
   23.27 @@ -85,8 +84,6 @@ static int __do_suspend(void *ignore)
   23.28  	int vcpu_prepare(int vcpu);
   23.29  #endif
   23.30  
   23.31 -	extern void xencons_resume(void);
   23.32 -
   23.33  	int err = 0;
   23.34  
   23.35  	BUG_ON(smp_processor_id() != 0);
   23.36 @@ -185,12 +182,20 @@ static int __do_suspend(void *ignore)
   23.37  
   23.38  	xencons_resume();
   23.39  
   23.40 +#ifdef CONFIG_SMP
   23.41 +	for_each_cpu(i)
   23.42 +		vcpu_prepare(i);
   23.43 +
   23.44 +#endif
   23.45 +
   23.46 +	/* 
   23.47 +	** Only resume xenbus /after/ we've prepared our VCPUs; otherwise
   23.48 +	** the VCPU hotplug callback can race with our vcpu_prepare
   23.49 +	*/
   23.50  	xenbus_resume();
   23.51  
   23.52 +
   23.53  #ifdef CONFIG_SMP
   23.54 -	for_each_present_cpu(i)
   23.55 -		vcpu_prepare(i);
   23.56 -
   23.57   out_reenable_cpus:
   23.58  	for_each_cpu_mask(i, prev_online_cpus) {
   23.59  		j = cpu_up(i);
    24.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/skbuff.c	Fri Nov 18 23:06:09 2005 -0600
    24.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/skbuff.c	Fri Nov 18 23:16:29 2005 -0600
    24.3 @@ -17,7 +17,7 @@
    24.4  /* Referenced in netback.c. */
    24.5  /*static*/ kmem_cache_t *skbuff_cachep;
    24.6  
    24.7 -#define MAX_SKBUFF_ORDER 2
    24.8 +#define MAX_SKBUFF_ORDER 4
    24.9  static kmem_cache_t *skbuff_order_cachep[MAX_SKBUFF_ORDER + 1];
   24.10  
   24.11  static struct {
    25.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c	Fri Nov 18 23:06:09 2005 -0600
    25.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c	Fri Nov 18 23:16:29 2005 -0600
    25.3 @@ -277,6 +277,18 @@ void __devinit smp_prepare_boot_cpu(void
    25.4  
    25.5  #ifdef CONFIG_HOTPLUG_CPU
    25.6  
    25.7 +/*
    25.8 + * Initialize cpu_present_map late to skip SMP boot code in init/main.c.
    25.9 + * But do it early enough to catch critical for_each_present_cpu() loops
   25.10 + * in i386-specific code.
   25.11 + */
   25.12 +static int __init initialize_cpu_present_map(void)
   25.13 +{
   25.14 +	cpu_present_map = cpu_possible_map;
   25.15 +	return 0;
   25.16 +}
   25.17 +core_initcall(initialize_cpu_present_map);
   25.18 +
   25.19  static void vcpu_hotplug(unsigned int cpu)
   25.20  {
   25.21  	int err;
   25.22 @@ -293,7 +305,6 @@ static void vcpu_hotplug(unsigned int cp
   25.23  	}
   25.24  
   25.25  	if (strcmp(state, "online") == 0) {
   25.26 -		cpu_set(cpu, cpu_present_map);
   25.27  		(void)cpu_up(cpu);
   25.28  	} else if (strcmp(state, "offline") == 0) {
   25.29  		(void)cpu_down(cpu);
   25.30 @@ -344,7 +355,7 @@ static int __init setup_vcpu_hotplug_eve
   25.31  	return 0;
   25.32  }
   25.33  
   25.34 -subsys_initcall(setup_vcpu_hotplug_event);
   25.35 +arch_initcall(setup_vcpu_hotplug_event);
   25.36  
   25.37  int __cpu_disable(void)
   25.38  {
   25.39 @@ -399,7 +410,8 @@ int __devinit __cpu_up(unsigned int cpu)
   25.40  
   25.41  	xen_smp_intr_init(cpu);
   25.42  	cpu_set(cpu, cpu_online_map);
   25.43 -	HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL);
   25.44 +	if (HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL) != 0)
   25.45 +		BUG();
   25.46  
   25.47  	return 0;
   25.48  }
    26.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/xen_proc.c	Fri Nov 18 23:06:09 2005 -0600
    26.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/xen_proc.c	Fri Nov 18 23:16:29 2005 -0600
    26.3 @@ -1,6 +1,7 @@
    26.4  
    26.5  #include <linux/config.h>
    26.6  #include <linux/proc_fs.h>
    26.7 +#include <asm-xen/xen_proc.h>
    26.8  
    26.9  static struct proc_dir_entry *xen_base;
   26.10  
    27.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/entry.S	Fri Nov 18 23:06:09 2005 -0600
    27.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/entry.S	Fri Nov 18 23:16:29 2005 -0600
    27.3 @@ -874,42 +874,8 @@ 1:      RESTORE_ARGS
    27.4  	ret
    27.5  	CFI_ENDPROC
    27.6  
    27.7 -
    27.8 - /*
    27.9 - * Copy error_entry because of the different stack frame
   27.10 - */                        
   27.11  ENTRY(page_fault)
   27.12 -        movq (%rsp),%rcx
   27.13 -        movq 8(%rsp),%r11
   27.14 -        addq $0x10,%rsp         # now %rsp points to %cr2
   27.15 -        pushq %rax
   27.16 -        leaq do_page_fault(%rip),%rax
   27.17 -	cld	
   27.18 -	subq  $13*8,%rsp
   27.19 -	movq %rdx,12*8(%rsp)    # save %rdx
   27.20 -	movq 13*8(%rsp),%rdx	# load rax
   27.21 -	movq %rcx,11*8(%rsp)
   27.22 -	movq %rdx,10*8(%rsp)	# store rax
   27.23 -        movq %rsi,13*8(%rsp)    # now save %rsi
   27.24 -        movq 14*8(%rsp),%rdx    # load %cr2, 3rd argument
   27.25 -	movq %r8, 9*8(%rsp)
   27.26 -	movq %r9, 8*8(%rsp)
   27.27 -	movq %r10,7*8(%rsp)
   27.28 -	movq %r11,6*8(%rsp)
   27.29 -	movq %rbx,5*8(%rsp) 
   27.30 -	movq %rbp,4*8(%rsp) 
   27.31 -	movq %r12,3*8(%rsp) 
   27.32 -	movq %r13,2*8(%rsp) 
   27.33 -	movq %r14,1*8(%rsp) 
   27.34 -	movq %r15,(%rsp)
   27.35 -#if 0        
   27.36 -	cmpl $__KERNEL_CS,CS(%rsp)
   27.37 -	je  error_kernelspace
   27.38 -#endif
   27.39 -        /*
   27.40 -         * 1st and 2nd arguments are set by error_call_handler
   27.41 -         */
   27.42 -        jmp error_call_handler
   27.43 +	errorentry do_page_fault
   27.44  
   27.45  ENTRY(coprocessor_error)
   27.46  	zeroentry do_coprocessor_error
   27.47 @@ -948,24 +914,15 @@ ENTRY(nmi)
   27.48  paranoid_exit:
   27.49  	testl %ebx,%ebx				/* swapgs needed? */
   27.50  	jnz paranoid_restore
   27.51 +	testl $3,CS(%rsp)
   27.52 +	jnz   paranoid_userspace
   27.53  paranoid_swapgs:	
   27.54 -/*	swapgs */
   27.55 +	swapgs
   27.56  paranoid_restore:	
   27.57  	RESTORE_ALL 8
   27.58 -/*	iretq */
   27.59 +	iretq
   27.60  paranoid_userspace:	
   27.61  	GET_THREAD_INFO(%rcx)
   27.62 -#	movl threadinfo_flags(%rcx),%edx
   27.63 -#	testl $_TIF_NEED_RESCHED,%edx
   27.64 -#	jnz paranoid_resched
   27.65 -#	testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
   27.66 -#	jnz paranoid_signal
   27.67 -#	jmp paranoid_swapgs
   27.68 -#paranoid_resched:		
   27.69 -#/*	sti */
   27.70 -#	call schedule
   27.71 -#	jmp paranoid_exit
   27.72 -#paranoid_signal:		
   27.73  	movl threadinfo_flags(%rcx),%ebx
   27.74  	andl $_TIF_WORK_MASK,%ebx
   27.75  	jz paranoid_swapgs
   27.76 @@ -975,13 +932,10 @@ paranoid_userspace:
   27.77  	testl $_TIF_NEED_RESCHED,%ebx
   27.78  	jnz paranoid_schedule
   27.79  	movl %ebx,%edx			/* arg3: thread flags */
   27.80 -/*	sti */
   27.81 -#	xorl %esi,%esi /* oldset */
   27.82 -#	movq %rsp,%rdi /* &pt_regs */
   27.83 +	sti
   27.84  	xorl %esi,%esi 			/* arg2: oldset */
   27.85  	movq %rsp,%rdi 			/* arg1: &pt_regs */
   27.86  	call do_notify_resume
   27.87 -#	jmp paranoid_exit
   27.88  	cli
   27.89  	jmp paranoid_userspace
   27.90  paranoid_schedule:
   27.91 @@ -1057,4 +1011,3 @@ ENTRY(machine_check)
   27.92  ENTRY(call_debug)
   27.93         zeroentry do_call_debug
   27.94  
   27.95 -
    28.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c	Fri Nov 18 23:06:09 2005 -0600
    28.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c	Fri Nov 18 23:16:29 2005 -0600
    28.3 @@ -770,9 +770,9 @@ void __init setup_arch(char **cmdline_p)
    28.4  		pfn_to_mfn_frame_list_list = alloc_bootmem(PAGE_SIZE);
    28.5  		HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
    28.6  		  virt_to_mfn(pfn_to_mfn_frame_list_list);
    28.7 -	       
    28.8 +
    28.9  		fpp = PAGE_SIZE/sizeof(unsigned long);
   28.10 -		for ( i=0, j=0, k=-1; i< max_pfn; i+=fpp, j++ )
   28.11 +		for ( i=0, j=0, k=-1; i< end_pfn; i+=fpp, j++ )
   28.12  		{
   28.13  			if ( (j % fpp) == 0 )
   28.14  			{
   28.15 @@ -786,9 +786,12 @@ void __init setup_arch(char **cmdline_p)
   28.16  			pfn_to_mfn_frame_list[k][j] = 
   28.17  				virt_to_mfn(&phys_to_machine_mapping[i]);
   28.18  		}
   28.19 -		HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
   28.20 +		HYPERVISOR_shared_info->arch.max_pfn = end_pfn;
   28.21 +
   28.22  	}
   28.23  
   28.24 +
   28.25 +
   28.26  	if ( ! (xen_start_info->flags & SIF_INITDOMAIN))
   28.27  	{
   28.28  		acpi_disabled = 1;
    29.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c	Fri Nov 18 23:06:09 2005 -0600
    29.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c	Fri Nov 18 23:16:29 2005 -0600
    29.3 @@ -905,30 +905,33 @@ void do_call_debug(struct pt_regs *regs)
    29.4  }
    29.5  
    29.6  
    29.7 +/*
    29.8 + * NB. All these are "interrupt gates" (i.e. events_mask is set) because we
    29.9 + * specify <dpl>|4 in the second field.
   29.10 + */
   29.11  static trap_info_t trap_table[] = {
   29.12 -        {  0, 0, (__KERNEL_CS|0x3), (unsigned long)divide_error               },
   29.13 -        {  1, 0, (__KERNEL_CS|0x3), (unsigned long)debug                      },
   29.14 -        {  3, 3, (__KERNEL_CS|0x3), (unsigned long)int3                       },
   29.15 -        {  4, 3, (__KERNEL_CS|0x3), (unsigned long)overflow                   },
   29.16 -        {  5, 3, (__KERNEL_CS|0x3), (unsigned long)bounds                     },
   29.17 -        {  6, 0, (__KERNEL_CS|0x3), (unsigned long)invalid_op                 },
   29.18 -        {  7, 0, (__KERNEL_CS|0x3), (unsigned long)device_not_available       },
   29.19 -        {  9, 0, (__KERNEL_CS|0x3), (unsigned long)coprocessor_segment_overrun},
   29.20 -        { 10, 0, (__KERNEL_CS|0x3), (unsigned long)invalid_TSS                },
   29.21 -        { 11, 0, (__KERNEL_CS|0x3), (unsigned long)segment_not_present        },
   29.22 -        { 12, 0, (__KERNEL_CS|0x3), (unsigned long)stack_segment              },
   29.23 -        { 13, 0, (__KERNEL_CS|0x3), (unsigned long)general_protection         },
   29.24 -        { 14, 0, (__KERNEL_CS|0x3), (unsigned long)page_fault                 },
   29.25 -        { 15, 0, (__KERNEL_CS|0x3), (unsigned long)spurious_interrupt_bug     },
   29.26 -        { 16, 0, (__KERNEL_CS|0x3), (unsigned long)coprocessor_error          },
   29.27 -        { 17, 0, (__KERNEL_CS|0x3), (unsigned long)alignment_check            },
   29.28 +        {  0, 0|4, (__KERNEL_CS|0x3), (unsigned long)divide_error               },
   29.29 +        {  1, 0|4, (__KERNEL_CS|0x3), (unsigned long)debug                      },
   29.30 +        {  3, 3|4, (__KERNEL_CS|0x3), (unsigned long)int3                       },
   29.31 +        {  4, 3|4, (__KERNEL_CS|0x3), (unsigned long)overflow                   },
   29.32 +        {  5, 3|4, (__KERNEL_CS|0x3), (unsigned long)bounds                     },
   29.33 +        {  6, 0|4, (__KERNEL_CS|0x3), (unsigned long)invalid_op                 },
   29.34 +        {  7, 0|4, (__KERNEL_CS|0x3), (unsigned long)device_not_available       },
   29.35 +        {  9, 0|4, (__KERNEL_CS|0x3), (unsigned long)coprocessor_segment_overrun},
   29.36 +        { 10, 0|4, (__KERNEL_CS|0x3), (unsigned long)invalid_TSS                },
   29.37 +        { 11, 0|4, (__KERNEL_CS|0x3), (unsigned long)segment_not_present        },
   29.38 +        { 12, 0|4, (__KERNEL_CS|0x3), (unsigned long)stack_segment              },
   29.39 +        { 13, 0|4, (__KERNEL_CS|0x3), (unsigned long)general_protection         },
   29.40 +        { 14, 0|4, (__KERNEL_CS|0x3), (unsigned long)page_fault                 },
   29.41 +        { 15, 0|4, (__KERNEL_CS|0x3), (unsigned long)spurious_interrupt_bug     },
   29.42 +        { 16, 0|4, (__KERNEL_CS|0x3), (unsigned long)coprocessor_error          },
   29.43 +        { 17, 0|4, (__KERNEL_CS|0x3), (unsigned long)alignment_check            },
   29.44  #ifdef CONFIG_X86_MCE
   29.45 -        { 18, 0, (__KERNEL_CS|0x3), (unsigned long)machine_check              },
   29.46 +        { 18, 0|4, (__KERNEL_CS|0x3), (unsigned long)machine_check              },
   29.47  #endif
   29.48 -        { 19, 0, (__KERNEL_CS|0x3), (unsigned long)simd_coprocessor_error     },
   29.49 -        { SYSCALL_VECTOR, 3, (__KERNEL_CS|0x3), (unsigned long)system_call   },
   29.50 +        { 19, 0|4, (__KERNEL_CS|0x3), (unsigned long)simd_coprocessor_error     },
   29.51  #ifdef CONFIG_IA32_EMULATION
   29.52 -	{ IA32_SYSCALL_VECTOR, 3, (__KERNEL_CS|0x3), (unsigned long)ia32_syscall},
   29.53 +	{ IA32_SYSCALL_VECTOR, 3|4, (__KERNEL_CS|0x3), (unsigned long)ia32_syscall},
   29.54  #endif
   29.55          {  0, 0,           0, 0                                              }
   29.56  };
    30.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/x8664_ksyms.c	Fri Nov 18 23:06:09 2005 -0600
    30.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/x8664_ksyms.c	Fri Nov 18 23:16:29 2005 -0600
    30.3 @@ -128,8 +128,10 @@ EXPORT_SYMBOL(get_wchan);
    30.4  
    30.5  EXPORT_SYMBOL(rtc_lock);
    30.6  
    30.7 -/* EXPORT_SYMBOL_GPL(set_nmi_callback);
    30.8 -   EXPORT_SYMBOL_GPL(unset_nmi_callback); */
    30.9 +#ifdef CONFIG_X86_LOCAL_APIC
   30.10 +EXPORT_SYMBOL_GPL(set_nmi_callback);
   30.11 +EXPORT_SYMBOL_GPL(unset_nmi_callback);
   30.12 +#endif
   30.13  
   30.14  /* Export string functions. We normally rely on gcc builtin for most of these,
   30.15     but gcc sometimes decides not to inline them. */    
    31.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/xen_entry.S	Fri Nov 18 23:06:09 2005 -0600
    31.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/xen_entry.S	Fri Nov 18 23:16:29 2005 -0600
    31.3 @@ -5,7 +5,7 @@
    31.4  #define evtchn_upcall_pending		0
    31.5  #define evtchn_upcall_mask		1
    31.6  
    31.7 -#define sizeof_vcpu_shift		4
    31.8 +#define sizeof_vcpu_shift		5
    31.9  
   31.10  #ifdef CONFIG_SMP
   31.11  //#define preempt_disable(reg)	incl threadinfo_preempt_count(reg)
    32.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c	Fri Nov 18 23:06:09 2005 -0600
    32.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c	Fri Nov 18 23:16:29 2005 -0600
    32.3 @@ -318,12 +318,12 @@ int exception_trace = 1;
    32.4   *	bit 2 == 0 means kernel, 1 means user-mode
    32.5   *      bit 3 == 1 means fault was an instruction fetch
    32.6   */
    32.7 -asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code,
    32.8 -       unsigned long address)
    32.9 +asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
   32.10  {
   32.11  	struct task_struct *tsk;
   32.12  	struct mm_struct *mm;
   32.13  	struct vm_area_struct * vma;
   32.14 +	unsigned long address;
   32.15  	const struct exception_table_entry *fixup;
   32.16  	int write;
   32.17  	siginfo_t info;
   32.18 @@ -342,6 +342,11 @@ asmlinkage void do_page_fault(struct pt_
   32.19  		}
   32.20  	}
   32.21  #endif
   32.22 +
   32.23 +	/* get the address */
   32.24 +	address = HYPERVISOR_shared_info->vcpu_data[
   32.25 +		smp_processor_id()].arch.cr2;
   32.26 +
   32.27  	if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
   32.28  					SIGSEGV) == NOTIFY_STOP)
   32.29  		return;
    33.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c	Fri Nov 18 23:06:09 2005 -0600
    33.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c	Fri Nov 18 23:16:29 2005 -0600
    33.3 @@ -55,11 +55,9 @@ extern char _stext[];
    33.4  DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
    33.5  extern unsigned long start_pfn;
    33.6  
    33.7 -static int init_mapping_done;
    33.8 -
    33.9  /*
   33.10   * Use this until direct mapping is established, i.e. before __va() is 
   33.11 - * avaialble in init_memory_mapping().
   33.12 + * available in init_memory_mapping().
   33.13   */
   33.14  
   33.15  #define addr_to_page(addr, page)				\
   33.16 @@ -68,91 +66,65 @@ static int init_mapping_done;
   33.17  	(((mfn_to_pfn((addr) >> PAGE_SHIFT)) << PAGE_SHIFT) +	\
   33.18  	__START_KERNEL_map)))
   33.19  
   33.20 -static void __make_page_readonly(unsigned long va)
   33.21 +static void early_make_page_readonly(void *va)
   33.22  {
   33.23 -	unsigned long addr;
   33.24 -	pte_t pte, *ptep;
   33.25 -	unsigned long *page = (unsigned long *) init_level4_pgt;
   33.26 -
   33.27 -	addr = (unsigned long) page[pgd_index(va)];
   33.28 -	addr_to_page(addr, page);
   33.29 -
   33.30 -	addr = page[pud_index(va)];
   33.31 -	addr_to_page(addr, page);
   33.32 -
   33.33 -	addr = page[pmd_index(va)];
   33.34 -	addr_to_page(addr, page);
   33.35 -
   33.36 -	ptep = (pte_t *) &page[pte_index(va)];
   33.37 -	pte.pte = (ptep->pte & ~_PAGE_RW);
   33.38 -	xen_l1_entry_update(ptep, pte);
   33.39 -	__flush_tlb_one(addr);
   33.40 -}
   33.41 -
   33.42 -static void __make_page_writable(unsigned long va)
   33.43 -{
   33.44 -	unsigned long addr;
   33.45 +	unsigned long addr, _va = (unsigned long)va;
   33.46  	pte_t pte, *ptep;
   33.47  	unsigned long *page = (unsigned long *) init_level4_pgt;
   33.48  
   33.49 -	addr = (unsigned long) page[pgd_index(va)];
   33.50 +	addr = (unsigned long) page[pgd_index(_va)];
   33.51  	addr_to_page(addr, page);
   33.52  
   33.53 -	addr = page[pud_index(va)];
   33.54 -	addr_to_page(addr, page);
   33.55 - 
   33.56 -	addr = page[pmd_index(va)];
   33.57 +	addr = page[pud_index(_va)];
   33.58  	addr_to_page(addr, page);
   33.59  
   33.60 -	ptep = (pte_t *) &page[pte_index(va)];
   33.61 -	pte.pte = (ptep->pte | _PAGE_RW);
   33.62 -	xen_l1_entry_update(ptep, pte);
   33.63 -	__flush_tlb_one(addr);
   33.64 +	addr = page[pmd_index(_va)];
   33.65 +	addr_to_page(addr, page);
   33.66 +
   33.67 +	ptep = (pte_t *) &page[pte_index(_va)];
   33.68 +
   33.69 +	pte.pte = ptep->pte & ~_PAGE_RW;
   33.70 +	if (HYPERVISOR_update_va_mapping(_va, pte, 0))
   33.71 +		BUG();
   33.72  }
   33.73  
   33.74 -
   33.75 -/*
   33.76 - * Assume the translation is already established.
   33.77 - */
   33.78  void make_page_readonly(void *va)
   33.79  {
   33.80 -	pgd_t* pgd; pud_t *pud; pmd_t* pmd; pte_t pte, *ptep;
   33.81 +	pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t pte, *ptep;
   33.82  	unsigned long addr = (unsigned long) va;
   33.83  
   33.84 -	if (!init_mapping_done) {
   33.85 -		__make_page_readonly(addr);
   33.86 -		return;
   33.87 -	}
   33.88 -  
   33.89 -	pgd = pgd_offset_k(addr);
   33.90 -	pud = pud_offset(pgd, addr);
   33.91 -	pmd = pmd_offset(pud, addr);
   33.92 -	ptep = pte_offset_kernel(pmd, addr);
   33.93 -	pte.pte = (ptep->pte & ~_PAGE_RW);
   33.94 -	xen_l1_entry_update(ptep, pte);
   33.95 -	__flush_tlb_one(addr);
   33.96 -}
   33.97 -
   33.98 -void make_page_writable(void *va)
   33.99 -{
  33.100 -	pgd_t* pgd; pud_t *pud; pmd_t* pmd; pte_t pte, *ptep;
  33.101 -	unsigned long addr = (unsigned long) va;
  33.102 -
  33.103 -	if (!init_mapping_done) {
  33.104 -		__make_page_writable(addr);
  33.105 -		return;
  33.106 -	}
  33.107 -
  33.108  	pgd = pgd_offset_k(addr);
  33.109  	pud = pud_offset(pgd, addr);
  33.110  	pmd = pmd_offset(pud, addr);
  33.111  	ptep = pte_offset_kernel(pmd, addr);
  33.112 -	pte.pte = (ptep->pte | _PAGE_RW);
  33.113 -	xen_l1_entry_update(ptep, pte);
  33.114 -	__flush_tlb_one(addr);
  33.115 +
  33.116 +	pte.pte = ptep->pte & ~_PAGE_RW;
  33.117 +	if (HYPERVISOR_update_va_mapping(addr, pte, 0))
  33.118 +		xen_l1_entry_update(ptep, pte); /* fallback */
  33.119 +
  33.120 +	if ((addr >= VMALLOC_START) && (addr < VMALLOC_END))
  33.121 +		make_page_readonly(__va(pte_pfn(pte) << PAGE_SHIFT));
  33.122  }
  33.123  
  33.124 -void make_pages_readonly(void* va, unsigned nr)
  33.125 +void make_page_writable(void *va)
  33.126 +{
  33.127 +	pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t pte, *ptep;
  33.128 +	unsigned long addr = (unsigned long) va;
  33.129 +
  33.130 +	pgd = pgd_offset_k(addr);
  33.131 +	pud = pud_offset(pgd, addr);
  33.132 +	pmd = pmd_offset(pud, addr);
  33.133 +	ptep = pte_offset_kernel(pmd, addr);
  33.134 +
  33.135 +	pte.pte = ptep->pte | _PAGE_RW;
  33.136 +	if (HYPERVISOR_update_va_mapping(addr, pte, 0))
  33.137 +		xen_l1_entry_update(ptep, pte); /* fallback */
  33.138 +
  33.139 +	if ((addr >= VMALLOC_START) && (addr < VMALLOC_END))
  33.140 +		make_page_writable(__va(pte_pfn(pte) << PAGE_SHIFT));
  33.141 +}
  33.142 +
  33.143 +void make_pages_readonly(void *va, unsigned nr)
  33.144  {
  33.145  	while (nr-- != 0) {
  33.146  		make_page_readonly(va);
  33.147 @@ -160,7 +132,7 @@ void make_pages_readonly(void* va, unsig
  33.148  	}
  33.149  }
  33.150  
  33.151 -void make_pages_writable(void* va, unsigned nr)
  33.152 +void make_pages_writable(void *va, unsigned nr)
  33.153  {
  33.154  	while (nr-- != 0) {
  33.155  		make_page_writable(va);
  33.156 @@ -457,7 +429,7 @@ static void __init phys_pud_init(pud_t *
  33.157  		} 
  33.158  
  33.159  		pmd = alloc_static_page(&pmd_phys);
  33.160 -                make_page_readonly(pmd);
  33.161 +                early_make_page_readonly(pmd);
  33.162                  xen_pmd_pin(pmd_phys);
  33.163  		set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE));
  33.164  
  33.165 @@ -487,7 +459,7 @@ static void __init phys_pud_init(pud_t *
  33.166                                  __set_pte(pte, __pte(paddr | _KERNPG_TABLE));
  33.167                          }
  33.168                          pte = pte_save;
  33.169 -                        make_page_readonly(pte);  
  33.170 +                        early_make_page_readonly(pte);  
  33.171                          xen_pte_pin(pte_phys);
  33.172  			set_pmd(pmd, __pmd(pte_phys | _KERNPG_TABLE));
  33.173  		}
  33.174 @@ -536,11 +508,11 @@ void __init xen_init_pt(void)
  33.175  		      _KERNPG_TABLE | _PAGE_USER);
  33.176          memcpy((void *)level2_kernel_pgt, page, PAGE_SIZE);
  33.177  
  33.178 -	make_page_readonly(init_level4_pgt);
  33.179 -	make_page_readonly(init_level4_user_pgt);
  33.180 -	make_page_readonly(level3_kernel_pgt);
  33.181 -	make_page_readonly(level3_user_pgt);
  33.182 -	make_page_readonly(level2_kernel_pgt);
  33.183 +	early_make_page_readonly(init_level4_pgt);
  33.184 +	early_make_page_readonly(init_level4_user_pgt);
  33.185 +	early_make_page_readonly(level3_kernel_pgt);
  33.186 +	early_make_page_readonly(level3_user_pgt);
  33.187 +	early_make_page_readonly(level2_kernel_pgt);
  33.188  
  33.189  	xen_pgd_pin(__pa_symbol(init_level4_pgt));
  33.190  	xen_pgd_pin(__pa_symbol(init_level4_user_pgt));
  33.191 @@ -578,7 +550,7 @@ void __init extend_init_mapping(void)
  33.192  		pmd = (pmd_t *)&page[pmd_index(va)];
  33.193  		if (pmd_none(*pmd)) {
  33.194  			pte_page = alloc_static_page(&phys);
  33.195 -			make_page_readonly(pte_page);
  33.196 +			early_make_page_readonly(pte_page);
  33.197  			xen_pte_pin(phys);
  33.198  			set_pmd(pmd, __pmd(phys | _KERNPG_TABLE | _PAGE_USER));
  33.199  		} else {
  33.200 @@ -625,7 +597,7 @@ void __init init_memory_mapping(unsigned
  33.201  	for (; start < end; start = next) {
  33.202  		unsigned long pud_phys; 
  33.203  		pud_t *pud = alloc_static_page(&pud_phys);
  33.204 -		make_page_readonly(pud);
  33.205 +		early_make_page_readonly(pud);
  33.206  		xen_pud_pin(pud_phys);
  33.207  		next = start + PGDIR_SIZE;
  33.208  		if (next > end) 
  33.209 @@ -640,7 +612,6 @@ void __init init_memory_mapping(unsigned
  33.210  	BUG_ON(start_pfn != (table_start + (tables_space >> PAGE_SHIFT)));
  33.211  
  33.212  	__flush_tlb_all();
  33.213 -	init_mapping_done = 1;
  33.214  }
  33.215  
  33.216  extern struct x8664_pda cpu_pda[NR_CPUS];
    34.1 --- a/linux-2.6-xen-sparse/drivers/acpi/tables.c	Fri Nov 18 23:06:09 2005 -0600
    34.2 +++ b/linux-2.6-xen-sparse/drivers/acpi/tables.c	Fri Nov 18 23:16:29 2005 -0600
    34.3 @@ -565,7 +565,7 @@ acpi_table_get_sdt (
    34.4   * 
    34.5   * result: sdt_entry[] is initialized
    34.6   */
    34.7 -#if CONFIG_XEN
    34.8 +#if defined(CONFIG_XEN_X86) || defined(CONFIG_XEN_X86_64)
    34.9  #define acpi_rsdp_phys_to_va(rsdp_phys) (__fix_to_virt(FIX_ACPI_RSDP_PAGE) + \
   34.10  					   (rsdp_phys & ~PAGE_MASK))
   34.11  #else
    35.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c	Fri Nov 18 23:06:09 2005 -0600
    35.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c	Fri Nov 18 23:16:29 2005 -0600
    35.3 @@ -97,9 +97,7 @@ static inline unsigned char *
    35.4  transmission_set_buffer(struct transmission *t,
    35.5                          unsigned char *buffer, unsigned int len)
    35.6  {
    35.7 -	if (NULL != t->request) {
    35.8 -		kfree(t->request);
    35.9 -	}
   35.10 +	kfree(t->request);
   35.11  	t->request = kmalloc(len, GFP_KERNEL);
   35.12  	if (t->request) {
   35.13  		memcpy(t->request,
   35.14 @@ -113,12 +111,8 @@ transmission_set_buffer(struct transmiss
   35.15  static inline void
   35.16  transmission_free(struct transmission *t)
   35.17  {
   35.18 -	if (t->request) {
   35.19 -		kfree(t->request);
   35.20 -	}
   35.21 -	if (t->rcv_buffer) {
   35.22 -		kfree(t->rcv_buffer);
   35.23 -	}
   35.24 +	kfree(t->request);
   35.25 +	kfree(t->rcv_buffer);
   35.26  	kfree(t);
   35.27  }
   35.28  
   35.29 @@ -444,7 +438,7 @@ static struct attribute* xen_attrs[] = {
   35.30  	&dev_attr_pcrs.attr,
   35.31  	&dev_attr_caps.attr,
   35.32  	&dev_attr_cancel.attr,
   35.33 -	0,
   35.34 +	NULL,
   35.35  };
   35.36  
   35.37  static struct attribute_group xen_attr_grp = { .attrs = xen_attrs };
    36.1 --- a/linux-2.6-xen-sparse/drivers/xen/Makefile	Fri Nov 18 23:06:09 2005 -0600
    36.2 +++ b/linux-2.6-xen-sparse/drivers/xen/Makefile	Fri Nov 18 23:16:29 2005 -0600
    36.3 @@ -1,4 +1,5 @@
    36.4  
    36.5 +obj-y	+= net_driver_util.o
    36.6  obj-y	+= util.o
    36.7  
    36.8  obj-y	+= console/
    37.1 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Fri Nov 18 23:06:09 2005 -0600
    37.2 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Fri Nov 18 23:16:29 2005 -0600
    37.3 @@ -91,7 +91,6 @@ static void balloon_process(void *unused
    37.4  static DECLARE_WORK(balloon_worker, balloon_process, NULL);
    37.5  static struct timer_list balloon_timer;
    37.6  
    37.7 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
    37.8  /* Use the private and mapping fields of struct page as a list. */
    37.9  #define PAGE_TO_LIST(p) ((struct list_head *)&p->private)
   37.10  #define LIST_TO_PAGE(l)				\
   37.11 @@ -102,19 +101,6 @@ static struct timer_list balloon_timer;
   37.12  		p->mapping = NULL;		\
   37.13  		p->private = 0;			\
   37.14  	} while(0)
   37.15 -#else
   37.16 -/* There's a dedicated list field in struct page we can use.    */
   37.17 -#define PAGE_TO_LIST(p) ( &p->list )
   37.18 -#define LIST_TO_PAGE(l) ( list_entry(l, struct page, list) )
   37.19 -#define UNLIST_PAGE(p)  ( list_del(&p->list) )
   37.20 -#define pte_offset_kernel pte_offset
   37.21 -#define pud_t pgd_t
   37.22 -#define pud_offset(d, va) d
   37.23 -#define pud_none(d) 0
   37.24 -#define pud_bad(d) 0
   37.25 -#define subsys_initcall(_fn) __initcall(_fn)
   37.26 -#define pfn_to_page(_pfn) (mem_map + (_pfn))
   37.27 -#endif
   37.28  
   37.29  #define IPRINTK(fmt, args...) \
   37.30  	printk(KERN_INFO "xen_mem: " fmt, ##args)
   37.31 @@ -210,7 +196,7 @@ static int increase_reservation(unsigned
   37.32  		BUG_ON(phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY);
   37.33  
   37.34  		/* Update P->M and M->P tables. */
   37.35 -		phys_to_machine_mapping[pfn] = mfn_list[i];
   37.36 +		set_phys_to_machine(pfn, mfn_list[i]);
   37.37  		xen_machphys_update(mfn_list[i], pfn);
   37.38              
   37.39  		/* Link back into the page tables if not highmem. */
   37.40 @@ -295,7 +281,7 @@ static int decrease_reservation(unsigned
   37.41  	/* No more mappings: invalidate P2M and add to balloon. */
   37.42  	for (i = 0; i < nr_pages; i++) {
   37.43  		pfn = mfn_to_pfn(mfn_list[i]);
   37.44 -		phys_to_machine_mapping[pfn] = INVALID_P2M_ENTRY;
   37.45 +		set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
   37.46  		balloon_append(pfn_to_page(pfn));
   37.47  	}
   37.48  
   37.49 @@ -381,9 +367,9 @@ static void watch_target(struct xenbus_w
   37.50      
   37.51  }
   37.52  
   37.53 -int balloon_init_watcher(struct notifier_block *notifier,
   37.54 -                         unsigned long event,
   37.55 -                         void *data)
   37.56 +static int balloon_init_watcher(struct notifier_block *notifier,
   37.57 +                                unsigned long event,
   37.58 +                                void *data)
   37.59  {
   37.60  	int err;
   37.61  
   37.62 @@ -515,8 +501,7 @@ static int dealloc_pte_fn(
   37.63  		.domid        = DOMID_SELF
   37.64  	};
   37.65  	set_pte_at(&init_mm, addr, pte, __pte_ma(0));
   37.66 -	phys_to_machine_mapping[__pa(addr) >> PAGE_SHIFT] =
   37.67 -		INVALID_P2M_ENTRY;
   37.68 +	set_phys_to_machine(__pa(addr) >> PAGE_SHIFT, INVALID_P2M_ENTRY);
   37.69  	ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
   37.70  	BUG_ON(ret != 1);
   37.71  	return 0;
    38.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Fri Nov 18 23:06:09 2005 -0600
    38.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Fri Nov 18 23:16:29 2005 -0600
    38.3 @@ -386,9 +386,9 @@ static void dispatch_rw_block_io(blkif_t
    38.4  #ifdef __ia64__
    38.5  			MMAP_VADDR(pending_idx,i) = gnttab_map_vaddr(map[i]);
    38.6  #else
    38.7 -			phys_to_machine_mapping[__pa(MMAP_VADDR(
    38.8 -				pending_idx, i)) >> PAGE_SHIFT] =
    38.9 -				FOREIGN_FRAME(map[i].dev_bus_addr>>PAGE_SHIFT);
   38.10 +			set_phys_to_machine(__pa(MMAP_VADDR(
   38.11 +				pending_idx, i)) >> PAGE_SHIFT,
   38.12 +				FOREIGN_FRAME(map[i].dev_bus_addr>>PAGE_SHIFT));
   38.13  #endif
   38.14  			fas        = req->frame_and_sects[i];
   38.15  			seg[i].buf = map[i].dev_bus_addr | 
   38.16 @@ -543,7 +543,7 @@ static int __init blkif_init(void)
   38.17  	spin_lock_init(&blkio_schedule_list_lock);
   38.18  	INIT_LIST_HEAD(&blkio_schedule_list);
   38.19  
   38.20 -	ret = kernel_thread(blkio_schedule, 0, CLONE_FS | CLONE_FILES);
   38.21 +	ret = kernel_thread(blkio_schedule, NULL, CLONE_FS | CLONE_FILES);
   38.22  	BUG_ON(ret < 0);
   38.23  
   38.24  	blkif_xenbus_init();
    39.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Fri Nov 18 23:06:09 2005 -0600
    39.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Fri Nov 18 23:16:29 2005 -0600
    39.3 @@ -1,5 +1,6 @@
    39.4  /*  Xenbus code for blkif backend
    39.5      Copyright (C) 2005 Rusty Russell <rusty@rustcorp.com.au>
    39.6 +    Copyright (C) 2005 XenSource Ltd
    39.7  
    39.8      This program is free software; you can redistribute it and/or modify
    39.9      it under the terms of the GNU General Public License as published by
   39.10 @@ -15,161 +16,142 @@
   39.11      along with this program; if not, write to the Free Software
   39.12      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   39.13  */
   39.14 +
   39.15 +
   39.16  #include <stdarg.h>
   39.17  #include <linux/module.h>
   39.18  #include <asm-xen/xenbus.h>
   39.19  #include "common.h"
   39.20  
   39.21 +
   39.22 +#if 0
   39.23 +#undef DPRINTK
   39.24 +#define DPRINTK(fmt, args...) \
   39.25 +    printk("blkback/xenbus (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
   39.26 +#endif
   39.27 +
   39.28 +
   39.29  struct backend_info
   39.30  {
   39.31  	struct xenbus_device *dev;
   39.32 +	blkif_t *blkif;
   39.33 +	struct xenbus_watch backend_watch;
   39.34  
   39.35 -	/* our communications channel */
   39.36 -	blkif_t *blkif;
   39.37 -
   39.38 -	long int frontend_id;
   39.39  	long int pdev;
   39.40  	long int readonly;
   39.41 +};
   39.42  
   39.43 -	/* watch back end for changes */
   39.44 -	struct xenbus_watch backend_watch;
   39.45  
   39.46 -	/* watch front end for changes */
   39.47 -	struct xenbus_watch watch;
   39.48 -	char *frontpath;
   39.49 -};
   39.50 +static void maybe_connect(struct backend_info *);
   39.51 +static void connect(struct backend_info *);
   39.52 +static int connect_ring(struct backend_info *);
   39.53 +static void backend_changed(struct xenbus_watch *, const char **,
   39.54 +			    unsigned int);
   39.55 +
   39.56  
   39.57  static int blkback_remove(struct xenbus_device *dev)
   39.58  {
   39.59  	struct backend_info *be = dev->data;
   39.60  
   39.61 -	if (be->watch.node)
   39.62 -		unregister_xenbus_watch(&be->watch);
   39.63 -	unregister_xenbus_watch(&be->backend_watch);
   39.64 -	if (be->blkif)
   39.65 +	DPRINTK("");
   39.66 +
   39.67 +	if (be->backend_watch.node) {
   39.68 +		unregister_xenbus_watch(&be->backend_watch);
   39.69 +		kfree(be->backend_watch.node);
   39.70 +		be->backend_watch.node = NULL;
   39.71 +	}
   39.72 +	if (be->blkif) {
   39.73  		blkif_put(be->blkif);
   39.74 -	if (be->frontpath)
   39.75 -		kfree(be->frontpath);
   39.76 +		be->blkif = NULL;
   39.77 +	}
   39.78  	kfree(be);
   39.79 +	dev->data = NULL;
   39.80  	return 0;
   39.81  }
   39.82  
   39.83 -/* Front end tells us frame. */
   39.84 -static void frontend_changed(struct xenbus_watch *watch,
   39.85 -			     const char **vec, unsigned int len)
   39.86 -{
   39.87 -	unsigned long ring_ref;
   39.88 -	unsigned int evtchn;
   39.89 -	int err;
   39.90 -	struct xenbus_transaction *xbt;
   39.91 -	struct backend_info *be
   39.92 -		= container_of(watch, struct backend_info, watch);
   39.93 -
   39.94 -	/* If other end is gone, delete ourself. */
   39.95 -	if (vec && !xenbus_exists(NULL, be->frontpath, "")) {
   39.96 -		device_unregister(&be->dev->dev);
   39.97 -		return;
   39.98 -	}
   39.99 -	if (be->blkif == NULL || be->blkif->status == CONNECTED)
  39.100 -		return;
  39.101  
  39.102 -	err = xenbus_gather(NULL, be->frontpath, "ring-ref", "%lu", &ring_ref,
  39.103 -			    "event-channel", "%u", &evtchn, NULL);
  39.104 -	if (err) {
  39.105 -		xenbus_dev_error(be->dev, err,
  39.106 -				 "reading %s/ring-ref and event-channel",
  39.107 -				 be->frontpath);
  39.108 -		return;
  39.109 +/**
  39.110 + * Entry point to this code when a new device is created.  Allocate the basic
  39.111 + * structures, and watch the store waiting for the hotplug scripts to tell us
  39.112 + * the device's physical-device.  Switch to InitWait.
  39.113 + */
  39.114 +static int blkback_probe(struct xenbus_device *dev,
  39.115 +			 const struct xenbus_device_id *id)
  39.116 +{
  39.117 +	int err;
  39.118 +	struct backend_info *be = kmalloc(sizeof(struct backend_info),
  39.119 +					  GFP_KERNEL);
  39.120 +	if (!be) {
  39.121 +		xenbus_dev_fatal(dev, -ENOMEM,
  39.122 +				 "allocating backend structure");
  39.123 +		return -ENOMEM;
  39.124  	}
  39.125 +	memset(be, 0, sizeof(*be));
  39.126  
  39.127 -	/* Map the shared frame, irq etc. */
  39.128 -	err = blkif_map(be->blkif, ring_ref, evtchn);
  39.129 -	if (err) {
  39.130 -		xenbus_dev_error(be->dev, err,
  39.131 -				 "mapping ring-ref %lu port %u",
  39.132 -				 ring_ref, evtchn);
  39.133 -		return;
  39.134 -	}
  39.135 -	/* XXX From here on should 'blkif_unmap' on error. */
  39.136 +	be->dev = dev;
  39.137 +	dev->data = be;
  39.138  
  39.139 -again:
  39.140 -	/* Supply the information about the device the frontend needs */
  39.141 -	xbt = xenbus_transaction_start();
  39.142 -	if (IS_ERR(xbt)) {
  39.143 -		xenbus_dev_error(be->dev, err, "starting transaction");
  39.144 -		return;
  39.145 +	be->blkif = alloc_blkif(dev->otherend_id);
  39.146 +	if (IS_ERR(be->blkif)) {
  39.147 +		err = PTR_ERR(be->blkif);
  39.148 +		be->blkif = NULL;
  39.149 +		xenbus_dev_fatal(dev, err, "creating block interface");
  39.150 +		goto fail;
  39.151  	}
  39.152  
  39.153 -	err = xenbus_printf(xbt, be->dev->nodename, "sectors", "%lu",
  39.154 -			    vbd_size(&be->blkif->vbd));
  39.155 -	if (err) {
  39.156 -		xenbus_dev_error(be->dev, err, "writing %s/sectors",
  39.157 -				 be->dev->nodename);
  39.158 -		goto abort;
  39.159 -	}
  39.160 +	err = xenbus_watch_path2(dev, dev->nodename, "physical-device",
  39.161 +				 &be->backend_watch, backend_changed);
  39.162 +	if (err)
  39.163 +		goto fail;
  39.164  
  39.165 -	/* FIXME: use a typename instead */
  39.166 -	err = xenbus_printf(xbt, be->dev->nodename, "info", "%u",
  39.167 -			    vbd_info(&be->blkif->vbd));
  39.168 -	if (err) {
  39.169 -		xenbus_dev_error(be->dev, err, "writing %s/info",
  39.170 -				 be->dev->nodename);
  39.171 -		goto abort;
  39.172 -	}
  39.173 -	err = xenbus_printf(xbt, be->dev->nodename, "sector-size", "%lu",
  39.174 -			    vbd_secsize(&be->blkif->vbd));
  39.175 -	if (err) {
  39.176 -		xenbus_dev_error(be->dev, err, "writing %s/sector-size",
  39.177 -				 be->dev->nodename);
  39.178 -		goto abort;
  39.179 -	}
  39.180 +	err = xenbus_switch_state(dev, NULL, XenbusStateInitWait);
  39.181 +	if (err)
  39.182 +		goto fail;
  39.183  
  39.184 -	err = xenbus_transaction_end(xbt, 0);
  39.185 -	if (err == -EAGAIN)
  39.186 -		goto again;
  39.187 -	if (err) {
  39.188 -		xenbus_dev_error(be->dev, err, "ending transaction",
  39.189 -				 ring_ref, evtchn);
  39.190 -		goto abort;
  39.191 -	}
  39.192 +	return 0;
  39.193  
  39.194 -	xenbus_dev_ok(be->dev);
  39.195 -
  39.196 -	return;
  39.197 -
  39.198 - abort:
  39.199 -	xenbus_transaction_end(xbt, 1);
  39.200 +fail:
  39.201 +	DPRINTK("failed");
  39.202 +	blkback_remove(dev);
  39.203 +	return err;
  39.204  }
  39.205  
  39.206 -/* 
  39.207 -   Setup supplies physical device.  
  39.208 -   We provide event channel and device details to front end.
  39.209 -   Frontend supplies shared frame and event channel.
  39.210 +
  39.211 +/**
  39.212 + * Callback received when the hotplug scripts have placed the physical-device
  39.213 + * node.  Read it and the read-only node, and create a vbd.  If the frontend
  39.214 + * is ready, connect.
  39.215   */
  39.216  static void backend_changed(struct xenbus_watch *watch,
  39.217  			    const char **vec, unsigned int len)
  39.218  {
  39.219  	int err;
  39.220  	char *p;
  39.221 -	long int handle, pdev;
  39.222 +	long pdev;
  39.223  	struct backend_info *be
  39.224  		= container_of(watch, struct backend_info, backend_watch);
  39.225  	struct xenbus_device *dev = be->dev;
  39.226  
  39.227 +	DPRINTK("");
  39.228 +
  39.229  	err = xenbus_scanf(NULL, dev->nodename,
  39.230  			   "physical-device", "%li", &pdev);
  39.231 -	if (XENBUS_EXIST_ERR(err))
  39.232 +	if (XENBUS_EXIST_ERR(err)) {
  39.233 +		/* Since this watch will fire once immediately after it is
  39.234 +		   registered, we expect this.  Ignore it, and wait for the
  39.235 +		   hotplug scripts. */
  39.236  		return;
  39.237 -	if (err < 0) {
  39.238 -		xenbus_dev_error(dev, err, "reading physical-device");
  39.239 +	}
  39.240 +	if (err != 1) {
  39.241 +		xenbus_dev_fatal(dev, err, "reading physical-device");
  39.242  		return;
  39.243  	}
  39.244  	if (be->pdev && be->pdev != pdev) {
  39.245  		printk(KERN_WARNING
  39.246 -		       "changing physical-device not supported\n");
  39.247 +		       "blkback: changing physical-device (from %ld to %ld) "
  39.248 +		       "not supported.\n", be->pdev, pdev);
  39.249  		return;
  39.250  	}
  39.251 -	be->pdev = pdev;
  39.252  
  39.253  	/* If there's a read-only node, we're read only. */
  39.254  	p = xenbus_read(NULL, dev->nodename, "read-only", NULL);
  39.255 @@ -178,126 +160,198 @@ static void backend_changed(struct xenbu
  39.256  		kfree(p);
  39.257  	}
  39.258  
  39.259 -	if (be->blkif == NULL) {
  39.260 +	if (be->pdev == 0L) {
  39.261  		/* Front end dir is a number, which is used as the handle. */
  39.262 -		p = strrchr(be->frontpath, '/') + 1;
  39.263 +
  39.264 +		long handle;
  39.265 +
  39.266 +		p = strrchr(dev->otherend, '/') + 1;
  39.267  		handle = simple_strtoul(p, NULL, 0);
  39.268  
  39.269 -		be->blkif = alloc_blkif(be->frontend_id);
  39.270 -		if (IS_ERR(be->blkif)) {
  39.271 -			err = PTR_ERR(be->blkif);
  39.272 -			be->blkif = NULL;
  39.273 -			xenbus_dev_error(dev, err,
  39.274 -					 "creating block interface");
  39.275 -			return;
  39.276 -		}
  39.277 +		be->pdev = pdev;
  39.278  
  39.279  		err = vbd_create(be->blkif, handle, be->pdev, be->readonly);
  39.280  		if (err) {
  39.281 -			blkif_put(be->blkif);
  39.282 -			be->blkif = NULL;
  39.283 -			xenbus_dev_error(dev, err,
  39.284 +			be->pdev = 0L;
  39.285 +			xenbus_dev_fatal(dev, err,
  39.286  					 "creating vbd structure");
  39.287  			return;
  39.288  		}
  39.289  
  39.290 -		/* Pass in NULL node to skip exist test. */
  39.291 -		frontend_changed(&be->watch, NULL, 0);
  39.292 +		maybe_connect(be);
  39.293 +	}
  39.294 +}
  39.295 +
  39.296 +
  39.297 +/**
  39.298 + * Callback received when the frontend's state changes.
  39.299 + */
  39.300 +static void frontend_changed(struct xenbus_device *dev,
  39.301 +			     XenbusState frontend_state)
  39.302 +{
  39.303 +	struct backend_info *be = dev->data;
  39.304 +	int err;
  39.305 +
  39.306 +	DPRINTK("");
  39.307 +
  39.308 +	switch (frontend_state) {
  39.309 +	case XenbusStateInitialising:
  39.310 +	case XenbusStateConnected:
  39.311 +		break;
  39.312 +
  39.313 +	case XenbusStateInitialised:
  39.314 +		err = connect_ring(be);
  39.315 +		if (err) {
  39.316 +			return;
  39.317 +		}
  39.318 +		maybe_connect(be);
  39.319 +		break;
  39.320 +
  39.321 +	case XenbusStateClosing:
  39.322 +		xenbus_switch_state(dev, NULL, XenbusStateClosing);
  39.323 +		break;
  39.324 +
  39.325 +	case XenbusStateClosed:
  39.326 +		device_unregister(&dev->dev);
  39.327 +		break;
  39.328 +
  39.329 +	case XenbusStateUnknown:
  39.330 +	case XenbusStateInitWait:
  39.331 +	default:
  39.332 +		xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend",
  39.333 +				 frontend_state);
  39.334 +		break;
  39.335 +	}
  39.336 +}
  39.337 +
  39.338 +
  39.339 +/* ** Connection ** */
  39.340 +
  39.341 +
  39.342 +static void maybe_connect(struct backend_info *be)
  39.343 +{
  39.344 +	if (be->pdev != 0L && be->blkif->status == CONNECTED) {
  39.345 +		connect(be);
  39.346  	}
  39.347  }
  39.348  
  39.349 -static int blkback_probe(struct xenbus_device *dev,
  39.350 -			 const struct xenbus_device_id *id)
  39.351 +
  39.352 +/**
  39.353 + * Write the physical details regarding the block device to the store, and
  39.354 + * switch to Connected state.
  39.355 + */
  39.356 +static void connect(struct backend_info *be)
  39.357  {
  39.358 -	struct backend_info *be;
  39.359 -	char *frontend;
  39.360 +	struct xenbus_transaction *xbt;
  39.361  	int err;
  39.362 +	struct xenbus_device *dev = be->dev;
  39.363  
  39.364 -	be = kmalloc(sizeof(*be), GFP_KERNEL);
  39.365 -	if (!be) {
  39.366 -		xenbus_dev_error(dev, -ENOMEM,
  39.367 -				 "allocating backend structure");
  39.368 -		return -ENOMEM;
  39.369 +	DPRINTK("%s", dev->otherend);
  39.370 +
  39.371 +	/* Supply the information about the device the frontend needs */
  39.372 +again:
  39.373 +	xbt = xenbus_transaction_start();
  39.374 +
  39.375 +	if (IS_ERR(xbt)) {
  39.376 +		err = PTR_ERR(xbt);
  39.377 +		xenbus_dev_fatal(dev, err, "starting transaction");
  39.378 +		return;
  39.379  	}
  39.380 -	memset(be, 0, sizeof(*be));
  39.381  
  39.382 -	frontend = NULL;
  39.383 -	err = xenbus_gather(NULL, dev->nodename,
  39.384 -			    "frontend-id", "%li", &be->frontend_id,
  39.385 -			    "frontend", NULL, &frontend,
  39.386 -			    NULL);
  39.387 -	if (XENBUS_EXIST_ERR(err))
  39.388 -		goto free_be;
  39.389 -	if (err < 0) {
  39.390 -		xenbus_dev_error(dev, err,
  39.391 -				 "reading %s/frontend or frontend-id",
  39.392 +	err = xenbus_printf(xbt, dev->nodename, "sectors", "%lu",
  39.393 +			    vbd_size(&be->blkif->vbd));
  39.394 +	if (err) {
  39.395 +		xenbus_dev_fatal(dev, err, "writing %s/sectors",
  39.396  				 dev->nodename);
  39.397 -		goto free_be;
  39.398 +		goto abort;
  39.399  	}
  39.400 -	if (strlen(frontend) == 0 || !xenbus_exists(NULL, frontend, "")) {
  39.401 -		/* If we can't get a frontend path and a frontend-id,
  39.402 -		 * then our bus-id is no longer valid and we need to
  39.403 -		 * destroy the backend device.
  39.404 -		 */
  39.405 -		err = -ENOENT;
  39.406 -		goto free_be;
  39.407 +
  39.408 +	/* FIXME: use a typename instead */
  39.409 +	err = xenbus_printf(xbt, dev->nodename, "info", "%u",
  39.410 +			    vbd_info(&be->blkif->vbd));
  39.411 +	if (err) {
  39.412 +		xenbus_dev_fatal(dev, err, "writing %s/info",
  39.413 +				 dev->nodename);
  39.414 +		goto abort;
  39.415 +	}
  39.416 +	err = xenbus_printf(xbt, dev->nodename, "sector-size", "%lu",
  39.417 +			    vbd_secsize(&be->blkif->vbd));
  39.418 +	if (err) {
  39.419 +		xenbus_dev_fatal(dev, err, "writing %s/sector-size",
  39.420 +				 dev->nodename);
  39.421 +		goto abort;
  39.422  	}
  39.423  
  39.424 -	be->dev = dev;
  39.425 -	be->backend_watch.node = dev->nodename;
  39.426 -	be->backend_watch.callback = backend_changed;
  39.427 -	/* Will implicitly call backend_changed once. */
  39.428 -	err = register_xenbus_watch(&be->backend_watch);
  39.429 +	err = xenbus_switch_state(dev, xbt, XenbusStateConnected);
  39.430 +	if (err)
  39.431 +		goto abort;
  39.432 +
  39.433 +	err = xenbus_transaction_end(xbt, 0);
  39.434 +	if (err == -EAGAIN)
  39.435 +		goto again;
  39.436 +	if (err)
  39.437 +		xenbus_dev_fatal(dev, err, "ending transaction");
  39.438 +	return;
  39.439 + abort:
  39.440 +	xenbus_transaction_end(xbt, 1);
  39.441 +}
  39.442 +
  39.443 +
  39.444 +static int connect_ring(struct backend_info *be)
  39.445 +{
  39.446 +	struct xenbus_device *dev = be->dev;
  39.447 +	unsigned long ring_ref;
  39.448 +	unsigned int evtchn;
  39.449 +	int err;
  39.450 +
  39.451 +	DPRINTK("%s", dev->otherend);
  39.452 +
  39.453 +	err = xenbus_gather(NULL, dev->otherend, "ring-ref", "%lu", &ring_ref,
  39.454 +			    "event-channel", "%u", &evtchn, NULL);
  39.455  	if (err) {
  39.456 -		be->backend_watch.node = NULL;
  39.457 -		xenbus_dev_error(dev, err,
  39.458 -				 "adding backend watch on %s",
  39.459 -				 dev->nodename);
  39.460 -		goto free_be;
  39.461 +		xenbus_dev_fatal(dev, err,
  39.462 +				 "reading %s/ring-ref and event-channel",
  39.463 +				 dev->otherend);
  39.464 +		return err;
  39.465  	}
  39.466  
  39.467 -	be->frontpath = frontend;
  39.468 -	be->watch.node = be->frontpath;
  39.469 -	be->watch.callback = frontend_changed;
  39.470 -	err = register_xenbus_watch(&be->watch);
  39.471 +	/* Map the shared frame, irq etc. */
  39.472 +	err = blkif_map(be->blkif, ring_ref, evtchn);
  39.473  	if (err) {
  39.474 -		be->watch.node = NULL;
  39.475 -		xenbus_dev_error(dev, err,
  39.476 -				 "adding frontend watch on %s",
  39.477 -				 be->frontpath);
  39.478 -		goto free_be;
  39.479 +		xenbus_dev_fatal(dev, err, "mapping ring-ref %lu port %u",
  39.480 +				 ring_ref, evtchn);
  39.481 +		return err;
  39.482  	}
  39.483  
  39.484 -	dev->data = be;
  39.485  	return 0;
  39.486 +}
  39.487  
  39.488 - free_be:
  39.489 -	if (be->backend_watch.node)
  39.490 -		unregister_xenbus_watch(&be->backend_watch);
  39.491 -	if (frontend)
  39.492 -		kfree(frontend);
  39.493 -	kfree(be);
  39.494 -	return err;
  39.495 -}
  39.496 +
  39.497 +/* ** Driver Registration ** */
  39.498 +
  39.499  
  39.500  static struct xenbus_device_id blkback_ids[] = {
  39.501  	{ "vbd" },
  39.502  	{ "" }
  39.503  };
  39.504  
  39.505 +
  39.506  static struct xenbus_driver blkback = {
  39.507  	.name = "vbd",
  39.508  	.owner = THIS_MODULE,
  39.509  	.ids = blkback_ids,
  39.510  	.probe = blkback_probe,
  39.511  	.remove = blkback_remove,
  39.512 +	.otherend_changed = frontend_changed
  39.513  };
  39.514  
  39.515 +
  39.516  void blkif_xenbus_init(void)
  39.517  {
  39.518  	xenbus_register_backend(&blkback);
  39.519  }
  39.520  
  39.521 +
  39.522  /*
  39.523   * Local variables:
  39.524   *  c-file-style: "linux"
    40.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Fri Nov 18 23:06:09 2005 -0600
    40.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Fri Nov 18 23:16:29 2005 -0600
    40.3 @@ -8,6 +8,7 @@
    40.4   * Copyright (c) 2004, Christian Limpach
    40.5   * Copyright (c) 2004, Andrew Warfield
    40.6   * Copyright (c) 2005, Christopher Clark
    40.7 + * Copyright (c) 2005, XenSource Ltd
    40.8   * 
    40.9   * This file may be distributed separately from the Linux kernel, or
   40.10   * incorporated into other software packages, subject to the following license:
   40.11 @@ -31,6 +32,7 @@
   40.12   * IN THE SOFTWARE.
   40.13   */
   40.14  
   40.15 +
   40.16  #if 1
   40.17  #define ASSERT(p)							   \
   40.18  	if (!(p)) { printk("Assertion '%s' failed, line %d, file %s", #p , \
   40.19 @@ -39,6 +41,7 @@
   40.20  #define ASSERT(_p)
   40.21  #endif
   40.22  
   40.23 +
   40.24  #include <linux/version.h>
   40.25  #include "block.h"
   40.26  #include <linux/cdrom.h>
   40.27 @@ -51,16 +54,315 @@
   40.28  #include <asm-xen/gnttab.h>
   40.29  #include <asm/hypervisor.h>
   40.30  
   40.31 +
   40.32  #define BLKIF_STATE_DISCONNECTED 0
   40.33  #define BLKIF_STATE_CONNECTED    1
   40.34 +#define BLKIF_STATE_SUSPENDED    2
   40.35  
   40.36  #define MAXIMUM_OUTSTANDING_BLOCK_REQS \
   40.37      (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLKIF_RING_SIZE)
   40.38  #define GRANT_INVALID_REF	0
   40.39  
   40.40 -static void kick_pending_request_queues(struct blkfront_info *info);
   40.41 +
   40.42 +static void connect(struct blkfront_info *);
   40.43 +static void blkfront_closing(struct xenbus_device *);
   40.44 +static int blkfront_remove(struct xenbus_device *);
   40.45 +static int talk_to_backend(struct xenbus_device *, struct blkfront_info *);
   40.46 +static int setup_blkring(struct xenbus_device *, struct blkfront_info *);
   40.47 +
   40.48 +static void kick_pending_request_queues(struct blkfront_info *);
   40.49 +
   40.50 +static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs);
   40.51 +static void blkif_restart_queue(void *arg);
   40.52 +static void blkif_recover(struct blkfront_info *);
   40.53 +static void blkif_completion(struct blk_shadow *);
   40.54 +static void blkif_free(struct blkfront_info *, int);
   40.55 +
   40.56 +
   40.57 +/**
   40.58 + * Entry point to this code when a new device is created.  Allocate the basic
   40.59 + * structures and the ring buffer for communication with the backend, and
   40.60 + * inform the backend of the appropriate details for those.  Switch to
   40.61 + * Initialised state.
   40.62 + */
   40.63 +static int blkfront_probe(struct xenbus_device *dev,
   40.64 +			  const struct xenbus_device_id *id)
   40.65 +{
   40.66 +	int err, vdevice, i;
   40.67 +	struct blkfront_info *info;
   40.68 +
   40.69 +	/* FIXME: Use dynamic device id if this is not set. */
   40.70 +	err = xenbus_scanf(NULL, dev->nodename,
   40.71 +			   "virtual-device", "%i", &vdevice);
   40.72 +	if (err != 1) {
   40.73 +		xenbus_dev_fatal(dev, err, "reading virtual-device");
   40.74 +		return err;
   40.75 +	}
   40.76 +
   40.77 +	info = kmalloc(sizeof(*info), GFP_KERNEL);
   40.78 +	if (!info) {
   40.79 +		xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure");
   40.80 +		return -ENOMEM;
   40.81 +	}
   40.82 +	info->xbdev = dev;
   40.83 +	info->vdevice = vdevice;
   40.84 +	info->connected = BLKIF_STATE_DISCONNECTED;
   40.85 +	info->mi = NULL;
   40.86 +	info->gd = NULL;
   40.87 +	INIT_WORK(&info->work, blkif_restart_queue, (void *)info);
   40.88 +
   40.89 +	info->shadow_free = 0;
   40.90 +	memset(info->shadow, 0, sizeof(info->shadow));
   40.91 +	for (i = 0; i < BLK_RING_SIZE; i++)
   40.92 +		info->shadow[i].req.id = i+1;
   40.93 +	info->shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
   40.94 +
   40.95 +	/* Front end dir is a number, which is used as the id. */
   40.96 +	info->handle = simple_strtoul(strrchr(dev->nodename,'/')+1, NULL, 0);
   40.97 +	dev->data = info;
   40.98 +
   40.99 +	err = talk_to_backend(dev, info);
  40.100 +	if (err) {
  40.101 +		kfree(info);
  40.102 +		dev->data = NULL;
  40.103 +		return err;
  40.104 +	}
  40.105 +
  40.106 +	return 0;
  40.107 +}
  40.108 +
  40.109 +
  40.110 +/**
  40.111 + * We are reconnecting to the backend, due to a suspend/resume, or a backend
  40.112 + * driver restart.  We tear down our blkif structure and recreate it, but
  40.113 + * leave the device-layer structures intact so that this is transparent to the
  40.114 + * rest of the kernel.
  40.115 + */
  40.116 +static int blkfront_resume(struct xenbus_device *dev)
  40.117 +{
  40.118 +	struct blkfront_info *info = dev->data;
  40.119 +	int err;
  40.120 +
  40.121 +	DPRINTK("blkfront_resume: %s\n", dev->nodename);
  40.122 +
  40.123 +	blkif_free(info, 1);
  40.124 +
  40.125 +	err = talk_to_backend(dev, info);
  40.126 +	if (!err)
  40.127 +		blkif_recover(info);
  40.128 +
  40.129 +	return err;
  40.130 +}
  40.131 +
  40.132 +
  40.133 +/* Common code used when first setting up, and when resuming. */
  40.134 +static int talk_to_backend(struct xenbus_device *dev,
  40.135 +			   struct blkfront_info *info)
  40.136 +{
  40.137 +	const char *message = NULL;
  40.138 +	struct xenbus_transaction *xbt;
  40.139 +	int err;
  40.140 +
  40.141 +	/* Create shared ring, alloc event channel. */
  40.142 +	err = setup_blkring(dev, info);
  40.143 +	if (err)
  40.144 +		goto out;
  40.145 +
  40.146 +again:
  40.147 +	xbt = xenbus_transaction_start();
  40.148 +	if (IS_ERR(xbt)) {
  40.149 +		xenbus_dev_fatal(dev, err, "starting transaction");
  40.150 +		goto destroy_blkring;
  40.151 +	}
  40.152 +
  40.153 +	err = xenbus_printf(xbt, dev->nodename,
  40.154 +			    "ring-ref","%u", info->ring_ref);
  40.155 +	if (err) {
  40.156 +		message = "writing ring-ref";
  40.157 +		goto abort_transaction;
  40.158 +	}
  40.159 +	err = xenbus_printf(xbt, dev->nodename,
  40.160 +			    "event-channel", "%u", info->evtchn);
  40.161 +	if (err) {
  40.162 +		message = "writing event-channel";
  40.163 +		goto abort_transaction;
  40.164 +	}
  40.165 +
  40.166 +	err = xenbus_switch_state(dev, xbt, XenbusStateInitialised);
  40.167 +	if (err) {
  40.168 +		goto abort_transaction;
  40.169 +	}
  40.170 +
  40.171 +	err = xenbus_transaction_end(xbt, 0);
  40.172 +	if (err) {
  40.173 +		if (err == -EAGAIN)
  40.174 +			goto again;
  40.175 +		xenbus_dev_fatal(dev, err, "completing transaction");
  40.176 +		goto destroy_blkring;
  40.177 +	}
  40.178 +
  40.179 +	return 0;
  40.180 +
  40.181 + abort_transaction:
  40.182 +	xenbus_transaction_end(xbt, 1);
  40.183 +	if (message)
  40.184 +		xenbus_dev_fatal(dev, err, "%s", message);
  40.185 + destroy_blkring:
  40.186 +	blkif_free(info, 0);
  40.187 + out:
  40.188 +	return err;
  40.189 +}
  40.190  
  40.191 -static void blkif_completion(struct blk_shadow *s);
  40.192 +
  40.193 +static int setup_blkring(struct xenbus_device *dev,
  40.194 +			 struct blkfront_info *info)
  40.195 +{
  40.196 +	blkif_sring_t *sring;
  40.197 +	int err;
  40.198 +
  40.199 +	info->ring_ref = GRANT_INVALID_REF;
  40.200 +
  40.201 +	sring = (blkif_sring_t *)__get_free_page(GFP_KERNEL);
  40.202 +	if (!sring) {
  40.203 +		xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring");
  40.204 +		return -ENOMEM;
  40.205 +	}
  40.206 +	SHARED_RING_INIT(sring);
  40.207 +	FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE);
  40.208 +
  40.209 +	err = xenbus_grant_ring(dev, virt_to_mfn(info->ring.sring));
  40.210 +	if (err < 0) {
  40.211 +		free_page((unsigned long)sring);
  40.212 +		info->ring.sring = NULL;
  40.213 +		goto fail;
  40.214 +	}
  40.215 +	info->ring_ref = err;
  40.216 +
  40.217 +	err = xenbus_alloc_evtchn(dev, &info->evtchn);
  40.218 +	if (err)
  40.219 +		goto fail;
  40.220 +
  40.221 +	err = bind_evtchn_to_irqhandler(
  40.222 +		info->evtchn, blkif_int, SA_SAMPLE_RANDOM, "blkif", info);
  40.223 +	if (err <= 0) {
  40.224 +		xenbus_dev_fatal(dev, err,
  40.225 +				 "bind_evtchn_to_irqhandler failed");
  40.226 +		goto fail;
  40.227 +	}
  40.228 +	info->irq = err;
  40.229 +
  40.230 +	return 0;
  40.231 +fail:
  40.232 +	blkif_free(info, 0);
  40.233 +	return err;
  40.234 +}
  40.235 +
  40.236 +
  40.237 +/**
  40.238 + * Callback received when the backend's state changes.
  40.239 + */
  40.240 +static void backend_changed(struct xenbus_device *dev,
  40.241 +			    XenbusState backend_state)
  40.242 +{
  40.243 +	struct blkfront_info *info = dev->data;
  40.244 +
  40.245 +	DPRINTK("blkfront:backend_changed.\n");
  40.246 +
  40.247 +	switch (backend_state) {
  40.248 +	case XenbusStateUnknown:
  40.249 +	case XenbusStateInitialising:
  40.250 +	case XenbusStateInitWait:
  40.251 +	case XenbusStateInitialised:
  40.252 +	case XenbusStateClosed:
  40.253 +		break;
  40.254 +
  40.255 +	case XenbusStateConnected:
  40.256 +		connect(info);
  40.257 +		break;
  40.258 +
  40.259 +	case XenbusStateClosing:
  40.260 +		blkfront_closing(dev);
  40.261 +		break;
  40.262 +	}
  40.263 +}
  40.264 +
  40.265 +
  40.266 +/* ** Connection ** */
  40.267 +
  40.268 +
  40.269 +static void connect(struct blkfront_info *info)
  40.270 +{
  40.271 +	unsigned long sectors, sector_size;
  40.272 +	unsigned int binfo;
  40.273 +	int err;
  40.274 +
  40.275 +        if( (info->connected == BLKIF_STATE_CONNECTED) || 
  40.276 +	    (info->connected == BLKIF_STATE_SUSPENDED) ) 
  40.277 +		return;
  40.278 +
  40.279 +	DPRINTK("blkfront.c:connect:%s.\n", info->xbdev->otherend);
  40.280 +
  40.281 +	err = xenbus_gather(NULL, info->xbdev->otherend,
  40.282 +			    "sectors", "%lu", &sectors,
  40.283 +			    "info", "%u", &binfo,
  40.284 +			    "sector-size", "%lu", &sector_size,
  40.285 +			    NULL);
  40.286 +	if (err) {
  40.287 +		xenbus_dev_fatal(info->xbdev, err,
  40.288 +				 "reading backend fields at %s",
  40.289 +				 info->xbdev->otherend);
  40.290 +		return;
  40.291 +	}
  40.292 +	
  40.293 +        info->connected = BLKIF_STATE_CONNECTED;
  40.294 +        xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
  40.295 +	
  40.296 +	err = xenbus_switch_state(info->xbdev, NULL, XenbusStateConnected);
  40.297 +	if (err)
  40.298 +		return;
  40.299 +	
  40.300 +	/* Kick pending requests. */
  40.301 +	spin_lock_irq(&blkif_io_lock);
  40.302 +	kick_pending_request_queues(info);
  40.303 +	spin_unlock_irq(&blkif_io_lock);
  40.304 +}
  40.305 +
  40.306 +
  40.307 +/**
  40.308 + * Handle the change of state of the backend to Closing.  We must delete our
  40.309 + * device-layer structures now, to ensure that writes are flushed through to
  40.310 + * the backend.  Once is this done, we can switch to Closed in
  40.311 + * acknowledgement.
  40.312 + */
  40.313 +static void blkfront_closing(struct xenbus_device *dev)
  40.314 +{
  40.315 +	struct blkfront_info *info = dev->data;
  40.316 +
  40.317 +	DPRINTK("blkfront_closing: %s removed\n", dev->nodename);
  40.318 +
  40.319 +	if (info->mi) {
  40.320 +		DPRINTK("Calling xlvbd_del\n");
  40.321 +		xlvbd_del(info);
  40.322 +		info->mi = NULL;
  40.323 +	}
  40.324 +
  40.325 +	xenbus_switch_state(dev, NULL, XenbusStateClosed);
  40.326 +}
  40.327 +
  40.328 +
  40.329 +static int blkfront_remove(struct xenbus_device *dev)
  40.330 +{
  40.331 +	struct blkfront_info *info = dev->data;
  40.332 +
  40.333 +	DPRINTK("blkfront_remove: %s removed\n", dev->nodename);
  40.334 +
  40.335 +	blkif_free(info, 0);
  40.336 +
  40.337 +	kfree(info);
  40.338 +
  40.339 +	return 0;
  40.340 +}
  40.341 +
  40.342  
  40.343  static inline int GET_ID_FROM_FREELIST(
  40.344  	struct blkfront_info *info)
  40.345 @@ -214,7 +516,7 @@ static int blkif_queue_request(struct re
  40.346  
  40.347  			gnttab_grant_foreign_access_ref(
  40.348  				ref,
  40.349 -				info->backend_id,
  40.350 +				info->xbdev->otherend_id,
  40.351  				buffer_mfn,
  40.352  				rq_data_dir(req) );
  40.353  
  40.354 @@ -269,6 +571,7 @@ void do_blkif_request(request_queue_t *r
  40.355  			req->nr_sectors, req->buffer,
  40.356  			rq_data_dir(req) ? "write" : "read");
  40.357  
  40.358 +
  40.359  		blkdev_dequeue_request(req);
  40.360  		if (blkif_queue_request(req)) {
  40.361  			blk_requeue_request(rq, req);
  40.362 @@ -343,11 +646,12 @@ static irqreturn_t blkif_int(int irq, vo
  40.363  	return IRQ_HANDLED;
  40.364  }
  40.365  
  40.366 -static void blkif_free(struct blkfront_info *info)
  40.367 +static void blkif_free(struct blkfront_info *info, int suspend)
  40.368  {
  40.369  	/* Prevent new requests being issued until we fix things up. */
  40.370  	spin_lock_irq(&blkif_io_lock);
  40.371 -	info->connected = BLKIF_STATE_DISCONNECTED;
  40.372 +	info->connected = suspend ? 
  40.373 +		BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED; 
  40.374  	spin_unlock_irq(&blkif_io_lock);
  40.375  
  40.376  	/* Free resources associated with old device channel. */
  40.377 @@ -360,6 +664,15 @@ static void blkif_free(struct blkfront_i
  40.378  	if (info->irq)
  40.379  		unbind_from_irqhandler(info->irq, info); 
  40.380  	info->evtchn = info->irq = 0;
  40.381 +
  40.382 +}
  40.383 +
  40.384 +static void blkif_completion(struct blk_shadow *s)
  40.385 +{
  40.386 +	int i;
  40.387 +	for (i = 0; i < s->req.nr_segments; i++)
  40.388 +		gnttab_end_foreign_access(
  40.389 +			blkif_gref_from_fas(s->req.frame_and_sects[i]), 0, 0UL);
  40.390  }
  40.391  
  40.392  static void blkif_recover(struct blkfront_info *info)
  40.393 @@ -370,7 +683,7 @@ static void blkif_recover(struct blkfron
  40.394  	int j;
  40.395  
  40.396  	/* Stage 1: Make a safe copy of the shadow state. */
  40.397 -	copy = (struct blk_shadow *)kmalloc(sizeof(info->shadow), GFP_KERNEL);
  40.398 +	copy = kmalloc(sizeof(info->shadow), GFP_KERNEL);
  40.399  	BUG_ON(copy == NULL);
  40.400  	memcpy(copy, info->shadow, sizeof(info->shadow));
  40.401  
  40.402 @@ -400,7 +713,7 @@ static void blkif_recover(struct blkfron
  40.403  		for (j = 0; j < req->nr_segments; j++)
  40.404  			gnttab_grant_foreign_access_ref(
  40.405  				blkif_gref_from_fas(req->frame_and_sects[j]),
  40.406 -				info->backend_id,
  40.407 +				info->xbdev->otherend_id,
  40.408  				pfn_to_mfn(info->shadow[req->id].frame[j]),
  40.409  				rq_data_dir(
  40.410  					(struct request *)
  40.411 @@ -422,21 +735,8 @@ static void blkif_recover(struct blkfron
  40.412  	info->connected = BLKIF_STATE_CONNECTED;
  40.413  }
  40.414  
  40.415 -static void blkif_connect(struct blkfront_info *info, u16 evtchn)
  40.416 -{
  40.417 -	int err = 0;
  40.418  
  40.419 -	info->evtchn = evtchn;
  40.420 -
  40.421 -	err = bind_evtchn_to_irqhandler(
  40.422 -		info->evtchn, blkif_int, SA_SAMPLE_RANDOM, "blkif", info);
  40.423 -	if (err <= 0) {
  40.424 -		WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
  40.425 -		return;
  40.426 -	}
  40.427 -
  40.428 -	info->irq = err;
  40.429 -}
  40.430 +/* ** Driver Registration ** */
  40.431  
  40.432  
  40.433  static struct xenbus_device_id blkfront_ids[] = {
  40.434 @@ -444,279 +744,6 @@ static struct xenbus_device_id blkfront_
  40.435  	{ "" }
  40.436  };
  40.437  
  40.438 -static void watch_for_status(struct xenbus_watch *watch,
  40.439 -			     const char **vec, unsigned int len)
  40.440 -{
  40.441 -	struct blkfront_info *info;
  40.442 -	unsigned int binfo;
  40.443 -	unsigned long sectors, sector_size;
  40.444 -	int err;
  40.445 -	const char *node;
  40.446 -
  40.447 -	node = vec[XS_WATCH_PATH];
  40.448 -
  40.449 -	info = container_of(watch, struct blkfront_info, watch);
  40.450 -	node += strlen(watch->node);
  40.451 -
  40.452 -	/* FIXME: clean up when error on the other end. */
  40.453 -	if ((info->connected == BLKIF_STATE_CONNECTED) || info->mi)
  40.454 -		return;
  40.455 -
  40.456 -	err = xenbus_gather(NULL, watch->node,
  40.457 -			    "sectors", "%lu", &sectors,
  40.458 -			    "info", "%u", &binfo,
  40.459 -			    "sector-size", "%lu", &sector_size,
  40.460 -			    NULL);
  40.461 -	if (err) {
  40.462 -		xenbus_dev_error(info->xbdev, err,
  40.463 -				 "reading backend fields at %s", watch->node);
  40.464 -		return;
  40.465 -	}
  40.466 -
  40.467 -	info->connected = BLKIF_STATE_CONNECTED;
  40.468 -	xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
  40.469 -
  40.470 -	xenbus_dev_ok(info->xbdev);
  40.471 -
  40.472 -	/* Kick pending requests. */
  40.473 -	spin_lock_irq(&blkif_io_lock);
  40.474 -	kick_pending_request_queues(info);
  40.475 -	spin_unlock_irq(&blkif_io_lock);
  40.476 -}
  40.477 -
  40.478 -static int setup_blkring(struct xenbus_device *dev, struct blkfront_info *info)
  40.479 -{
  40.480 -	blkif_sring_t *sring;
  40.481 -	int err;
  40.482 -	evtchn_op_t op = {
  40.483 -		.cmd = EVTCHNOP_alloc_unbound,
  40.484 -		.u.alloc_unbound.dom = DOMID_SELF,
  40.485 -		.u.alloc_unbound.remote_dom = info->backend_id };
  40.486 -
  40.487 -	info->ring_ref = GRANT_INVALID_REF;
  40.488 -
  40.489 -	sring = (void *)__get_free_page(GFP_KERNEL);
  40.490 -	if (!sring) {
  40.491 -		xenbus_dev_error(dev, -ENOMEM, "allocating shared ring");
  40.492 -		return -ENOMEM;
  40.493 -	}
  40.494 -	SHARED_RING_INIT(sring);
  40.495 -	FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE);
  40.496 -
  40.497 -	err = gnttab_grant_foreign_access(info->backend_id,
  40.498 -					  virt_to_mfn(info->ring.sring), 0);
  40.499 -	if (err == -ENOSPC) {
  40.500 -		free_page((unsigned long)info->ring.sring);
  40.501 -		info->ring.sring = 0;
  40.502 -		xenbus_dev_error(dev, err, "granting access to ring page");
  40.503 -		return err;
  40.504 -	}
  40.505 -	info->ring_ref = err;
  40.506 -
  40.507 -	err = HYPERVISOR_event_channel_op(&op);
  40.508 -	if (err) {
  40.509 -		gnttab_end_foreign_access(info->ring_ref, 0,
  40.510 -					  (unsigned long)info->ring.sring);
  40.511 -		info->ring_ref = GRANT_INVALID_REF;
  40.512 -		info->ring.sring = NULL;
  40.513 -		xenbus_dev_error(dev, err, "allocating event channel");
  40.514 -		return err;
  40.515 -	}
  40.516 -
  40.517 -	blkif_connect(info, op.u.alloc_unbound.port);
  40.518 -
  40.519 -	return 0;
  40.520 -}
  40.521 -
  40.522 -/* Common code used when first setting up, and when resuming. */
  40.523 -static int talk_to_backend(struct xenbus_device *dev,
  40.524 -			   struct blkfront_info *info)
  40.525 -{
  40.526 -	char *backend;
  40.527 -	const char *message;
  40.528 -	struct xenbus_transaction *xbt;
  40.529 -	int err;
  40.530 -
  40.531 -	backend = NULL;
  40.532 -	err = xenbus_gather(NULL, dev->nodename,
  40.533 -			    "backend-id", "%i", &info->backend_id,
  40.534 -			    "backend", NULL, &backend,
  40.535 -			    NULL);
  40.536 -	if (XENBUS_EXIST_ERR(err))
  40.537 -		goto out;
  40.538 -	if (backend && strlen(backend) == 0) {
  40.539 -		err = -ENOENT;
  40.540 -		goto out;
  40.541 -	}
  40.542 -	if (err < 0) {
  40.543 -		xenbus_dev_error(dev, err, "reading %s/backend or backend-id",
  40.544 -				 dev->nodename);
  40.545 -		goto out;
  40.546 -	}
  40.547 -
  40.548 -	/* Create shared ring, alloc event channel. */
  40.549 -	err = setup_blkring(dev, info);
  40.550 -	if (err) {
  40.551 -		xenbus_dev_error(dev, err, "setting up block ring");
  40.552 -		goto out;
  40.553 -	}
  40.554 -
  40.555 -again:
  40.556 -	xbt = xenbus_transaction_start();
  40.557 -	if (IS_ERR(xbt)) {
  40.558 -		xenbus_dev_error(dev, err, "starting transaction");
  40.559 -		goto destroy_blkring;
  40.560 -	}
  40.561 -
  40.562 -	err = xenbus_printf(xbt, dev->nodename,
  40.563 -			    "ring-ref","%u", info->ring_ref);
  40.564 -	if (err) {
  40.565 -		message = "writing ring-ref";
  40.566 -		goto abort_transaction;
  40.567 -	}
  40.568 -	err = xenbus_printf(xbt, dev->nodename,
  40.569 -			    "event-channel", "%u", info->evtchn);
  40.570 -	if (err) {
  40.571 -		message = "writing event-channel";
  40.572 -		goto abort_transaction;
  40.573 -	}
  40.574 -
  40.575 -	err = xenbus_transaction_end(xbt, 0);
  40.576 -	if (err) {
  40.577 -		if (err == -EAGAIN)
  40.578 -			goto again;
  40.579 -		xenbus_dev_error(dev, err, "completing transaction");
  40.580 -		goto destroy_blkring;
  40.581 -	}
  40.582 -
  40.583 -	info->watch.node = backend;
  40.584 -	info->watch.callback = watch_for_status;
  40.585 -	err = register_xenbus_watch(&info->watch);
  40.586 -	if (err) {
  40.587 -		message = "registering watch on backend";
  40.588 -		goto destroy_blkring;
  40.589 -	}
  40.590 -
  40.591 -	info->backend = backend;
  40.592 -
  40.593 -	return 0;
  40.594 -
  40.595 - abort_transaction:
  40.596 -	xenbus_transaction_end(xbt, 1);
  40.597 -	xenbus_dev_error(dev, err, "%s", message);
  40.598 - destroy_blkring:
  40.599 -	blkif_free(info);
  40.600 - out:
  40.601 -	if (backend)
  40.602 -		kfree(backend);
  40.603 -	return err;
  40.604 -}
  40.605 -
  40.606 -/* Setup supplies the backend dir, virtual device.
  40.607 -
  40.608 -   We place an event channel and shared frame entries.
  40.609 -   We watch backend to wait if it's ok. */
  40.610 -static int blkfront_probe(struct xenbus_device *dev,
  40.611 -			  const struct xenbus_device_id *id)
  40.612 -{
  40.613 -	int err, vdevice, i;
  40.614 -	struct blkfront_info *info;
  40.615 -
  40.616 -	/* FIXME: Use dynamic device id if this is not set. */
  40.617 -	err = xenbus_scanf(NULL, dev->nodename,
  40.618 -			   "virtual-device", "%i", &vdevice);
  40.619 -	if (XENBUS_EXIST_ERR(err))
  40.620 -		return err;
  40.621 -	if (err < 0) {
  40.622 -		xenbus_dev_error(dev, err, "reading virtual-device");
  40.623 -		return err;
  40.624 -	}
  40.625 -
  40.626 -	info = kmalloc(sizeof(*info), GFP_KERNEL);
  40.627 -	if (!info) {
  40.628 -		xenbus_dev_error(dev, err, "allocating info structure");
  40.629 -		return err;
  40.630 -	}
  40.631 -	info->xbdev = dev;
  40.632 -	info->vdevice = vdevice;
  40.633 -	info->connected = BLKIF_STATE_DISCONNECTED;
  40.634 -	info->mi = NULL;
  40.635 - 	info->gd = NULL;
  40.636 -	INIT_WORK(&info->work, blkif_restart_queue, (void *)info);
  40.637 -
  40.638 -	info->shadow_free = 0;
  40.639 -	memset(info->shadow, 0, sizeof(info->shadow));
  40.640 -	for (i = 0; i < BLK_RING_SIZE; i++)
  40.641 -		info->shadow[i].req.id = i+1;
  40.642 -	info->shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
  40.643 -
  40.644 -	/* Front end dir is a number, which is used as the id. */
  40.645 -	info->handle = simple_strtoul(strrchr(dev->nodename,'/')+1, NULL, 0);
  40.646 -	dev->data = info;
  40.647 -
  40.648 -	err = talk_to_backend(dev, info);
  40.649 -	if (err) {
  40.650 -		kfree(info);
  40.651 -		dev->data = NULL;
  40.652 -		return err;
  40.653 -	}
  40.654 -
  40.655 -	{
  40.656 -		unsigned int len = max(XS_WATCH_PATH, XS_WATCH_TOKEN) + 1;
  40.657 -		const char *vec[len];
  40.658 -
  40.659 -		vec[XS_WATCH_PATH] = info->watch.node;
  40.660 -		vec[XS_WATCH_TOKEN] = NULL;
  40.661 -
  40.662 -		/* Call once in case entries already there. */
  40.663 -		watch_for_status(&info->watch, vec, len);
  40.664 -	}
  40.665 -
  40.666 -	return 0;
  40.667 -}
  40.668 -
  40.669 -static int blkfront_remove(struct xenbus_device *dev)
  40.670 -{
  40.671 -	struct blkfront_info *info = dev->data;
  40.672 -
  40.673 -	if (info->backend)
  40.674 -		unregister_xenbus_watch(&info->watch);
  40.675 -
  40.676 -	if (info->mi)
  40.677 -		xlvbd_del(info);
  40.678 -
  40.679 -	blkif_free(info);
  40.680 -
  40.681 -	kfree(info->backend);
  40.682 -	kfree(info);
  40.683 -
  40.684 -	return 0;
  40.685 -}
  40.686 -
  40.687 -static int blkfront_suspend(struct xenbus_device *dev)
  40.688 -{
  40.689 -	struct blkfront_info *info = dev->data;
  40.690 -
  40.691 -	unregister_xenbus_watch(&info->watch);
  40.692 -	kfree(info->backend);
  40.693 -	info->backend = NULL;
  40.694 -
  40.695 -	return 0;
  40.696 -}
  40.697 -
  40.698 -static int blkfront_resume(struct xenbus_device *dev)
  40.699 -{
  40.700 -	struct blkfront_info *info = dev->data;
  40.701 -	int err;
  40.702 -
  40.703 -	blkif_free(info);
  40.704 -
  40.705 -	err = talk_to_backend(dev, info);
  40.706 -	if (!err)
  40.707 -		blkif_recover(info);
  40.708 -
  40.709 -	return err;
  40.710 -}
  40.711  
  40.712  static struct xenbus_driver blkfront = {
  40.713  	.name = "vbd",
  40.714 @@ -725,27 +752,28 @@ static struct xenbus_driver blkfront = {
  40.715  	.probe = blkfront_probe,
  40.716  	.remove = blkfront_remove,
  40.717  	.resume = blkfront_resume,
  40.718 -	.suspend = blkfront_suspend,
  40.719 +	.otherend_changed = backend_changed,
  40.720  };
  40.721  
  40.722 +
  40.723  static int __init xlblk_init(void)
  40.724  {
  40.725  	if (xen_init() < 0)
  40.726  		return -ENODEV;
  40.727  
  40.728 -	xenbus_register_driver(&blkfront);
  40.729 -	return 0;
  40.730 +	return xenbus_register_frontend(&blkfront);
  40.731  }
  40.732 -
  40.733  module_init(xlblk_init);
  40.734  
  40.735 -static void blkif_completion(struct blk_shadow *s)
  40.736 +
  40.737 +static void xlblk_exit(void)
  40.738  {
  40.739 -	int i;
  40.740 -	for (i = 0; i < s->req.nr_segments; i++)
  40.741 -		gnttab_end_foreign_access(
  40.742 -			blkif_gref_from_fas(s->req.frame_and_sects[i]), 0, 0UL);
  40.743 +	return xenbus_unregister_driver(&blkfront);
  40.744  }
  40.745 +module_exit(xlblk_exit);
  40.746 +
  40.747 +MODULE_LICENSE("BSD");
  40.748 +
  40.749  
  40.750  /*
  40.751   * Local variables:
    41.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h	Fri Nov 18 23:06:09 2005 -0600
    41.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h	Fri Nov 18 23:16:29 2005 -0600
    41.3 @@ -113,15 +113,11 @@ struct blk_shadow {
    41.4  struct blkfront_info
    41.5  {
    41.6  	struct xenbus_device *xbdev;
    41.7 -	/* We watch the backend */
    41.8 -	struct xenbus_watch watch;
    41.9  	dev_t dev;
   41.10   	struct gendisk *gd;
   41.11  	int vdevice;
   41.12  	blkif_vdev_t handle;
   41.13  	int connected;
   41.14 -	char *backend;
   41.15 -	int backend_id;
   41.16  	int ring_ref;
   41.17  	blkif_front_ring_t ring;
   41.18  	unsigned int evtchn, irq;
    42.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c	Fri Nov 18 23:06:09 2005 -0600
    42.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c	Fri Nov 18 23:16:29 2005 -0600
    42.3 @@ -412,7 +412,7 @@ static void fast_flush_area(int idx, int
    42.4  	struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST*2];
    42.5  	unsigned int i, op = 0;
    42.6  	struct grant_handle_pair *handle;
    42.7 -	unsigned long ptep;
    42.8 +	uint64_t ptep;
    42.9  	int ret;
   42.10  
   42.11  	for ( i = 0; i < nr_pages; i++)
   42.12 @@ -427,9 +427,9 @@ static void fast_flush_area(int idx, int
   42.13  		op++;
   42.14  
   42.15  		if (create_lookup_pte_addr(
   42.16 -			blktap_vma->vm_mm,
   42.17 -			MMAP_VADDR(user_vstart, idx, i), 
   42.18 -			&ptep) !=0) {
   42.19 +			    blktap_vma->vm_mm,
   42.20 +			    MMAP_VADDR(user_vstart, idx, i), 
   42.21 +			    &ptep) !=0) {
   42.22  			DPRINTK("Couldn't get a pte addr!\n");
   42.23  			return;
   42.24  		}
   42.25 @@ -705,7 +705,7 @@ static void dispatch_rw_block_io(blkif_t
   42.26  
   42.27  		unsigned long uvaddr;
   42.28  		unsigned long kvaddr;
   42.29 -		unsigned long ptep;
   42.30 +		uint64_t ptep;
   42.31  
   42.32  		uvaddr = MMAP_VADDR(user_vstart, pending_idx, i);
   42.33  		kvaddr = MMAP_VADDR(mmap_vstart, pending_idx, i);
   42.34 @@ -777,8 +777,8 @@ static void dispatch_rw_block_io(blkif_t
   42.35  		/* Set the necessary mappings in p2m and in the VM_FOREIGN 
   42.36  		 * vm_area_struct to allow user vaddr -> struct page lookups
   42.37  		 * to work.  This is needed for direct IO to foreign pages. */
   42.38 -		phys_to_machine_mapping[__pa(kvaddr) >> PAGE_SHIFT] =
   42.39 -			FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT);
   42.40 +		set_phys_to_machine(__pa(kvaddr) >> PAGE_SHIFT,
   42.41 +				FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT));
   42.42  
   42.43  		offset = (uvaddr - blktap_vma->vm_start) >> PAGE_SHIFT;
   42.44  		((struct page **)blktap_vma->vm_private_data)[offset] =
    43.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c	Fri Nov 18 23:06:09 2005 -0600
    43.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c	Fri Nov 18 23:16:29 2005 -0600
    43.3 @@ -52,8 +52,7 @@ static int blkback_remove(struct xenbus_
    43.4  	unregister_xenbus_watch(&be->backend_watch);
    43.5  	if (be->blkif)
    43.6  		blkif_put(be->blkif);
    43.7 -	if (be->frontpath)
    43.8 -		kfree(be->frontpath);
    43.9 +	kfree(be->frontpath);
   43.10  	kfree(be);
   43.11  	return 0;
   43.12  }
   43.13 @@ -201,8 +200,7 @@ static int blkback_probe(struct xenbus_d
   43.14   free_be:
   43.15  	if (be->backend_watch.node)
   43.16  		unregister_xenbus_watch(&be->backend_watch);
   43.17 -	if (frontend)
   43.18 -		kfree(frontend);
   43.19 +	kfree(frontend);
   43.20  	kfree(be);
   43.21  	return err;
   43.22  }
    44.1 --- a/linux-2.6-xen-sparse/drivers/xen/console/console.c	Fri Nov 18 23:06:09 2005 -0600
    44.2 +++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c	Fri Nov 18 23:16:29 2005 -0600
    44.3 @@ -53,6 +53,7 @@
    44.4  #include <asm-xen/xen-public/event_channel.h>
    44.5  #include <asm/hypervisor.h>
    44.6  #include <asm-xen/evtchn.h>
    44.7 +#include <asm-xen/xencons.h>
    44.8  
    44.9  #include "xencons_ring.h"
   44.10  /*
   44.11 @@ -127,12 +128,7 @@ static spinlock_t xencons_lock = SPIN_LO
   44.12  /* Common transmit-kick routine. */
   44.13  static void __xencons_tx_flush(void);
   44.14  
   44.15 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   44.16  static struct tty_driver *xencons_driver;
   44.17 -#else
   44.18 -static struct tty_driver xencons_driver;
   44.19 -#endif
   44.20 -
   44.21  
   44.22  /******************** Kernel console driver ********************************/
   44.23  
   44.24 @@ -169,18 +165,11 @@ static void kcons_write_dom0(
   44.25  	}
   44.26  }
   44.27  
   44.28 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   44.29  static struct tty_driver *kcons_device(struct console *c, int *index)
   44.30  {
   44.31  	*index = c->index;
   44.32  	return xencons_driver;
   44.33  }
   44.34 -#else
   44.35 -static kdev_t kcons_device(struct console *c)
   44.36 -{
   44.37 -	return MKDEV(TTY_MAJOR, (xc_mode == XC_SERIAL) ? 64 : 1);
   44.38 -}
   44.39 -#endif
   44.40  
   44.41  static struct console kcons_info = {
   44.42  	.device	= kcons_device,
   44.43 @@ -188,13 +177,8 @@ static struct console kcons_info = {
   44.44  	.index	= -1,
   44.45  };
   44.46  
   44.47 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   44.48  #define __RETCODE 0
   44.49  static int __init xen_console_init(void)
   44.50 -#else
   44.51 -#define __RETCODE
   44.52 -void xen_console_init(void)
   44.53 -#endif
   44.54  {
   44.55  	if (xen_init() < 0)
   44.56  		return __RETCODE;
   44.57 @@ -203,10 +187,8 @@ void xen_console_init(void)
   44.58  		if (xc_mode == XC_DEFAULT)
   44.59  			xc_mode = XC_SERIAL;
   44.60  		kcons_info.write = kcons_write_dom0;
   44.61 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   44.62  		if (xc_mode == XC_SERIAL)
   44.63  			kcons_info.flags |= CON_ENABLED;
   44.64 -#endif
   44.65  	} else {
   44.66  		if (xc_mode == XC_DEFAULT)
   44.67  			xc_mode = XC_TTY;
   44.68 @@ -236,16 +218,10 @@ void xen_console_init(void)
   44.69  
   44.70  	return __RETCODE;
   44.71  }
   44.72 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   44.73  console_initcall(xen_console_init);
   44.74 -#endif
   44.75  
   44.76  /*** Useful function for console debugging -- goes straight to Xen. ***/
   44.77 -#ifdef CONFIG_XEN_PRIVILEGED_GUEST
   44.78  asmlinkage int xprintk(const char *fmt, ...)
   44.79 -#else
   44.80 -asmlinkage int xprintk(const char *fmt, ...)
   44.81 -#endif
   44.82  {
   44.83  	va_list args;
   44.84  	int printk_len;
   44.85 @@ -286,15 +262,8 @@ void xencons_force_flush(void)
   44.86  
   44.87  /******************** User-space console driver (/dev/console) ************/
   44.88  
   44.89 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   44.90  #define DRV(_d)         (_d)
   44.91  #define TTY_INDEX(_tty) ((_tty)->index)
   44.92 -#else
   44.93 -static int xencons_refcount;
   44.94 -static struct tty_struct *xencons_table[MAX_NR_CONSOLES];
   44.95 -#define DRV(_d)         (&(_d))
   44.96 -#define TTY_INDEX(_tty) (MINOR((_tty)->device) - xencons_driver.minor_start)
   44.97 -#endif
   44.98  
   44.99  static struct termios *xencons_termios[MAX_NR_CONSOLES];
  44.100  static struct termios *xencons_termios_locked[MAX_NR_CONSOLES];
  44.101 @@ -487,7 +456,6 @@ static inline int __xencons_put_char(int
  44.102  	return 1;
  44.103  }
  44.104  
  44.105 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
  44.106  static int xencons_write(
  44.107  	struct tty_struct *tty,
  44.108  	const unsigned char *buf,
  44.109 @@ -512,42 +480,6 @@ static int xencons_write(
  44.110  
  44.111  	return i;
  44.112  }
  44.113 -#else
  44.114 -static int xencons_write(
  44.115 -	struct tty_struct *tty, 
  44.116 -	int from_user,
  44.117 -	const u_char *buf, 
  44.118 -	int count)
  44.119 -{
  44.120 -	int i;
  44.121 -	unsigned long flags;
  44.122 -
  44.123 -	if (from_user && verify_area(VERIFY_READ, buf, count))
  44.124 -		return -EINVAL;
  44.125 -
  44.126 -	if (TTY_INDEX(tty) != 0)
  44.127 -		return count;
  44.128 -
  44.129 -	spin_lock_irqsave(&xencons_lock, flags);
  44.130 -
  44.131 -	for (i = 0; i < count; i++) {
  44.132 -		char ch;
  44.133 -		if (from_user)
  44.134 -			__get_user(ch, buf + i);
  44.135 -		else
  44.136 -			ch = buf[i];
  44.137 -		if (!__xencons_put_char(ch))
  44.138 -			break;
  44.139 -	}
  44.140 -
  44.141 -	if (i != 0)
  44.142 -		__xencons_tx_flush();
  44.143 -
  44.144 -	spin_unlock_irqrestore(&xencons_lock, flags);
  44.145 -
  44.146 -	return i;
  44.147 -}
  44.148 -#endif
  44.149  
  44.150  static void xencons_put_char(struct tty_struct *tty, u_char ch)
  44.151  {
  44.152 @@ -632,7 +564,6 @@ static void xencons_close(struct tty_str
  44.153  	}
  44.154  }
  44.155  
  44.156 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
  44.157  static struct tty_operations xencons_ops = {
  44.158  	.open = xencons_open,
  44.159  	.close = xencons_close,
  44.160 @@ -688,7 +619,6 @@ const struct consw xennull_con = {
  44.161  	.con_scrolldelta =	DUMMY,
  44.162  };
  44.163  #endif
  44.164 -#endif
  44.165  
  44.166  static int __init xencons_init(void)
  44.167  {
  44.168 @@ -702,19 +632,10 @@ static int __init xencons_init(void)
  44.169  
  44.170  	xencons_ring_init();
  44.171  
  44.172 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
  44.173  	xencons_driver = alloc_tty_driver((xc_mode == XC_SERIAL) ? 
  44.174  					  1 : MAX_NR_CONSOLES);
  44.175  	if (xencons_driver == NULL)
  44.176  		return -ENOMEM;
  44.177 -#else
  44.178 -	memset(&xencons_driver, 0, sizeof(struct tty_driver));
  44.179 -	xencons_driver.magic       = TTY_DRIVER_MAGIC;
  44.180 -	xencons_driver.refcount    = &xencons_refcount;
  44.181 -	xencons_driver.table       = xencons_table;
  44.182 -	xencons_driver.num         =
  44.183 -		(xc_mode == XC_SERIAL) ? 1 : MAX_NR_CONSOLES;
  44.184 -#endif
  44.185  
  44.186  	DRV(xencons_driver)->major           = TTY_MAJOR;
  44.187  	DRV(xencons_driver)->type            = TTY_DRIVER_TYPE_SERIAL;
  44.188 @@ -738,37 +659,18 @@ static int __init xencons_init(void)
  44.189  		DRV(xencons_driver)->name_base   = xc_num;
  44.190  	}
  44.191  
  44.192 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
  44.193  	tty_set_operations(xencons_driver, &xencons_ops);
  44.194 -#else
  44.195 -	xencons_driver.open            = xencons_open;
  44.196 -	xencons_driver.close           = xencons_close;
  44.197 -	xencons_driver.write           = xencons_write;
  44.198 -	xencons_driver.write_room      = xencons_write_room;
  44.199 -	xencons_driver.put_char        = xencons_put_char;
  44.200 -	xencons_driver.flush_chars     = xencons_flush_chars;
  44.201 -	xencons_driver.chars_in_buffer = xencons_chars_in_buffer;
  44.202 -	xencons_driver.send_xchar      = xencons_send_xchar;
  44.203 -	xencons_driver.flush_buffer    = xencons_flush_buffer;
  44.204 -	xencons_driver.throttle        = xencons_throttle;
  44.205 -	xencons_driver.unthrottle      = xencons_unthrottle;
  44.206 -	xencons_driver.wait_until_sent = xencons_wait_until_sent;
  44.207 -#endif
  44.208  
  44.209  	if ((rc = tty_register_driver(DRV(xencons_driver))) != 0) {
  44.210  		printk("WARNING: Failed to register Xen virtual "
  44.211  		       "console driver as '%s%d'\n",
  44.212  		       DRV(xencons_driver)->name, DRV(xencons_driver)->name_base);
  44.213 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
  44.214  		put_tty_driver(xencons_driver);
  44.215  		xencons_driver = NULL;
  44.216 -#endif
  44.217  		return rc;
  44.218  	}
  44.219  
  44.220 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
  44.221  	tty_register_device(xencons_driver, 0, NULL);
  44.222 -#endif
  44.223  
  44.224  	if (xen_start_info->flags & SIF_INITDOMAIN) {
  44.225  		xencons_priv_irq = bind_virq_to_irqhandler(
    45.1 --- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c	Fri Nov 18 23:06:09 2005 -0600
    45.2 +++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c	Fri Nov 18 23:16:29 2005 -0600
    45.3 @@ -30,6 +30,12 @@ static inline struct xencons_interface *
    45.4  	return mfn_to_virt(xen_start_info->console_mfn);
    45.5  }
    45.6  
    45.7 +static inline void notify_daemon(void)
    45.8 +{
    45.9 +	/* Use evtchn: this is called early, before irq is set up. */
   45.10 +	notify_remote_via_evtchn(xen_start_info->console_evtchn);
   45.11 +}
   45.12 +
   45.13  int xencons_ring_send(const char *data, unsigned len)
   45.14  {
   45.15  	int sent = 0;
   45.16 @@ -47,8 +53,7 @@ int xencons_ring_send(const char *data, 
   45.17  	wmb();
   45.18  	intf->out_prod = prod;
   45.19  
   45.20 -	/* Use evtchn: this is called early, before irq is set up. */
   45.21 -	notify_remote_via_evtchn(xen_start_info->console_evtchn);
   45.22 +	notify_daemon();
   45.23  
   45.24  	return sent;
   45.25  }	
   45.26 @@ -70,9 +75,11 @@ static irqreturn_t handle_input(int irq,
   45.27  				1, regs);
   45.28  	}
   45.29  
   45.30 -	wmb();
   45.31 +	mb();
   45.32  	intf->in_cons = cons;
   45.33  
   45.34 +	notify_daemon();
   45.35 +
   45.36  	return IRQ_HANDLED;
   45.37  }
   45.38  
   45.39 @@ -102,6 +109,9 @@ int xencons_ring_init(void)
   45.40  
   45.41  	xencons_irq = err;
   45.42  
   45.43 +	/* In case we have in-flight data after save/restore... */
   45.44 +	notify_daemon();
   45.45 +
   45.46  	return 0;
   45.47  }
   45.48  
    46.1 --- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c	Fri Nov 18 23:06:09 2005 -0600
    46.2 +++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c	Fri Nov 18 23:16:29 2005 -0600
    46.3 @@ -436,9 +436,7 @@ static struct miscdevice evtchn_miscdev 
    46.4  	.minor        = EVTCHN_MINOR,
    46.5  	.name         = "evtchn",
    46.6  	.fops         = &evtchn_fops,
    46.7 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
    46.8  	.devfs_name   = "misc/evtchn",
    46.9 -#endif
   46.10  };
   46.11  
   46.12  static int __init evtchn_init(void)
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/linux-2.6-xen-sparse/drivers/xen/net_driver_util.c	Fri Nov 18 23:16:29 2005 -0600
    47.3 @@ -0,0 +1,67 @@
    47.4 +/*****************************************************************************
    47.5 + *
    47.6 + * Utility functions for Xen network devices.
    47.7 + *
    47.8 + * Copyright (c) 2005 XenSource Ltd.
    47.9 + * 
   47.10 + * This file may be distributed separately from the Linux kernel, or
   47.11 + * incorporated into other software packages, subject to the following
   47.12 + * license:
   47.13 + * 
   47.14 + * Permission is hereby granted, free of charge, to any person obtaining a
   47.15 + * copy of this source file (the "Software"), to deal in the Software without
   47.16 + * restriction, including without limitation the rights to use, copy, modify,
   47.17 + * merge, publish, distribute, sublicense, and/or sell copies of the Software,
   47.18 + * and to permit persons to whom the Software is furnished to do so, subject
   47.19 + * to the following conditions:
   47.20 + * 
   47.21 + * The above copyright notice and this permission notice shall be included in
   47.22 + * all copies or substantial portions of the Software.
   47.23 + * 
   47.24 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   47.25 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   47.26 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   47.27 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   47.28 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   47.29 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   47.30 + * DEALINGS IN THE SOFTWARE.
   47.31 + */
   47.32 +
   47.33 +
   47.34 +#include <linux/if_ether.h>
   47.35 +#include <linux/err.h>
   47.36 +#include <asm-xen/net_driver_util.h>
   47.37 +
   47.38 +
   47.39 +int xen_net_read_mac(struct xenbus_device *dev, u8 mac[])
   47.40 +{
   47.41 +	char *s;
   47.42 +	int i;
   47.43 +	char *e;
   47.44 +	char *macstr = xenbus_read(NULL, dev->nodename, "mac", NULL);
   47.45 +	if (IS_ERR(macstr)) {
   47.46 +		return PTR_ERR(macstr);
   47.47 +	}
   47.48 +	s = macstr;
   47.49 +	for (i = 0; i < ETH_ALEN; i++) {
   47.50 +		mac[i] = simple_strtoul(s, &e, 16);
   47.51 +		if (s == e || (e[0] != ':' && e[0] != 0)) {
   47.52 +			kfree(macstr);
   47.53 +			return -ENOENT;
   47.54 +		}
   47.55 +		s = &e[1];
   47.56 +	}
   47.57 +	kfree(macstr);
   47.58 +	return 0;
   47.59 +}
   47.60 +
   47.61 +
   47.62 +/*
   47.63 + * Local variables:
   47.64 + *  c-file-style: "linux"
   47.65 + *  indent-tabs-mode: t
   47.66 + *  c-indent-level: 8
   47.67 + *  c-basic-offset: 8
   47.68 + *  tab-width: 8
   47.69 + * End:
   47.70 + */
    48.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c	Fri Nov 18 23:06:09 2005 -0600
    48.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c	Fri Nov 18 23:16:29 2005 -0600
    48.3 @@ -160,10 +160,8 @@ static int __init make_loopback(int i)
    48.4  	return 0;
    48.5  
    48.6   fail:
    48.7 -	if (dev1 != NULL)
    48.8 -		kfree(dev1);
    48.9 -	if (dev2 != NULL)
   48.10 -		kfree(dev2);
   48.11 +	kfree(dev1);
   48.12 +	kfree(dev2);
   48.13  	return err;
   48.14  }
   48.15  
    49.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Fri Nov 18 23:06:09 2005 -0600
    49.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Fri Nov 18 23:16:29 2005 -0600
    49.3 @@ -248,8 +248,7 @@ static void net_rx_action(unsigned long 
    49.4  		 * Set the new P2M table entry before reassigning the old data
    49.5  		 * page. Heed the comment in pgtable-2level.h:pte_page(). :-)
    49.6  		 */
    49.7 -		phys_to_machine_mapping[__pa(skb->data) >> PAGE_SHIFT] =
    49.8 -			new_mfn;
    49.9 +		set_phys_to_machine(__pa(skb->data) >> PAGE_SHIFT, new_mfn);
   49.10  
   49.11  		MULTI_update_va_mapping(mcl, vdata,
   49.12  					pfn_pte_ma(new_mfn, PAGE_KERNEL), 0);
   49.13 @@ -631,9 +630,9 @@ static void net_tx_action(unsigned long 
   49.14  				pending_idx;
   49.15  			continue;
   49.16  		}
   49.17 -		phys_to_machine_mapping[
   49.18 -			__pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT] =
   49.19 -			FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT);
   49.20 +		set_phys_to_machine(
   49.21 +			__pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT,
   49.22 +			FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT));
   49.23  		grant_tx_ref[pending_idx] = mop->handle;
   49.24  
   49.25  		data_len = (txreq.size > PKT_PROT_LEN) ?
    50.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c	Fri Nov 18 23:06:09 2005 -0600
    50.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c	Fri Nov 18 23:16:29 2005 -0600
    50.3 @@ -1,5 +1,6 @@
    50.4  /*  Xenbus code for netif backend
    50.5      Copyright (C) 2005 Rusty Russell <rusty@rustcorp.com.au>
    50.6 +    Copyright (C) 2005 XenSource Ltd
    50.7  
    50.8      This program is free software; you can redistribute it and/or modify
    50.9      it under the terms of the GNU General Public License as published by
   50.10 @@ -15,160 +16,116 @@
   50.11      along with this program; if not, write to the Free Software
   50.12      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   50.13  */
   50.14 +
   50.15 +
   50.16  #include <stdarg.h>
   50.17  #include <linux/module.h>
   50.18  #include <asm-xen/xenbus.h>
   50.19 +#include <asm-xen/net_driver_util.h>
   50.20  #include "common.h"
   50.21  
   50.22 +
   50.23 +#if 0
   50.24 +#undef DPRINTK
   50.25 +#define DPRINTK(fmt, args...) \
   50.26 +    printk("netback/xenbus (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
   50.27 +#endif
   50.28 +
   50.29 +
   50.30  struct backend_info
   50.31  {
   50.32  	struct xenbus_device *dev;
   50.33 +	netif_t *netif;
   50.34 +	struct xenbus_watch backend_watch;
   50.35 +	XenbusState frontend_state;
   50.36 +};
   50.37  
   50.38 -	/* our communications channel */
   50.39 -	netif_t *netif;
   50.40 -
   50.41 -	long int frontend_id;
   50.42  
   50.43 -	/* watch back end for changes */
   50.44 -	struct xenbus_watch backend_watch;
   50.45 +static int connect_rings(struct backend_info *);
   50.46 +static void connect(struct backend_info *);
   50.47 +static void maybe_connect(struct backend_info *);
   50.48 +static void backend_changed(struct xenbus_watch *, const char **,
   50.49 +			    unsigned int);
   50.50  
   50.51 -	/* watch front end for changes */
   50.52 -	struct xenbus_watch watch;
   50.53 -	char *frontpath;
   50.54 -};
   50.55  
   50.56  static int netback_remove(struct xenbus_device *dev)
   50.57  {
   50.58  	struct backend_info *be = dev->data;
   50.59  
   50.60 -	if (be->watch.node)
   50.61 -		unregister_xenbus_watch(&be->watch);
   50.62 -	unregister_xenbus_watch(&be->backend_watch);
   50.63 -	if (be->netif)
   50.64 +	if (be->backend_watch.node) {
   50.65 +		unregister_xenbus_watch(&be->backend_watch);
   50.66 +		kfree(be->backend_watch.node);
   50.67 +		be->backend_watch.node = NULL;
   50.68 +	}
   50.69 +	if (be->netif) {
   50.70  		netif_disconnect(be->netif);
   50.71 -	if (be->frontpath)
   50.72 -		kfree(be->frontpath);
   50.73 +		be->netif = NULL;
   50.74 +	}
   50.75  	kfree(be);
   50.76 +	dev->data = NULL;
   50.77  	return 0;
   50.78  }
   50.79  
   50.80 -/* Front end tells us frame. */
   50.81 -static void frontend_changed(struct xenbus_watch *watch, 
   50.82 -			     const char **vec, unsigned int len)
   50.83 -{
   50.84 -	unsigned long tx_ring_ref, rx_ring_ref;
   50.85 -	unsigned int evtchn;
   50.86 -	int err;
   50.87 -	struct backend_info *be
   50.88 -		= container_of(watch, struct backend_info, watch);
   50.89 -	char *mac, *e, *s;
   50.90 -	int i;
   50.91 -
   50.92 -	/* If other end is gone, delete ourself. */
   50.93 -	if (vec && !xenbus_exists(NULL, be->frontpath, "")) {
   50.94 -		xenbus_rm(NULL, be->dev->nodename, "");
   50.95 -		device_unregister(&be->dev->dev);
   50.96 -		return;
   50.97 -	}
   50.98 -	if (be->netif == NULL || be->netif->status == CONNECTED)
   50.99 -		return;
  50.100  
  50.101 -	mac = xenbus_read(NULL, be->frontpath, "mac", NULL);
  50.102 -	if (IS_ERR(mac)) {
  50.103 -		err = PTR_ERR(mac);
  50.104 -		xenbus_dev_error(be->dev, err, "reading %s/mac",
  50.105 -				 be->dev->nodename);
  50.106 -		return;
  50.107 +/**
  50.108 + * Entry point to this code when a new device is created.  Allocate the basic
  50.109 + * structures, and watch the store waiting for the hotplug scripts to tell us
  50.110 + * the device's handle.  Switch to InitWait.
  50.111 + */
  50.112 +static int netback_probe(struct xenbus_device *dev,
  50.113 +			 const struct xenbus_device_id *id)
  50.114 +{
  50.115 +	int err;
  50.116 +	struct backend_info *be = kmalloc(sizeof(struct backend_info),
  50.117 +					  GFP_KERNEL);
  50.118 +	if (!be) {
  50.119 +		xenbus_dev_fatal(dev, -ENOMEM,
  50.120 +				 "allocating backend structure");
  50.121 +		return -ENOMEM;
  50.122  	}
  50.123 -	s = mac;
  50.124 -	for (i = 0; i < ETH_ALEN; i++) {
  50.125 -		be->netif->fe_dev_addr[i] = simple_strtoul(s, &e, 16);
  50.126 -		if (s == e || (e[0] != ':' && e[0] != 0)) {
  50.127 -			kfree(mac);
  50.128 -			err = -ENOENT;
  50.129 -			xenbus_dev_error(be->dev, err, "parsing %s/mac",
  50.130 -					 be->dev->nodename);
  50.131 -			return;
  50.132 -		}
  50.133 -		s = &e[1];
  50.134 -	}
  50.135 -	kfree(mac);
  50.136 +	memset(be, 0, sizeof(*be));
  50.137 +
  50.138 +	be->dev = dev;
  50.139 +	dev->data = be;
  50.140  
  50.141 -	err = xenbus_gather(NULL, be->frontpath,
  50.142 -			    "tx-ring-ref", "%lu", &tx_ring_ref,
  50.143 -			    "rx-ring-ref", "%lu", &rx_ring_ref,
  50.144 -			    "event-channel", "%u", &evtchn, NULL);
  50.145 +	err = xenbus_watch_path2(dev, dev->nodename, "handle",
  50.146 +				 &be->backend_watch, backend_changed);
  50.147 +	if (err)
  50.148 +		goto fail;
  50.149 +
  50.150 +	err = xenbus_switch_state(dev, NULL, XenbusStateInitWait);
  50.151  	if (err) {
  50.152 -		xenbus_dev_error(be->dev, err,
  50.153 -				 "reading %s/ring-ref and event-channel",
  50.154 -				 be->frontpath);
  50.155 -		return;
  50.156 +		goto fail;
  50.157  	}
  50.158  
  50.159 -	/* Map the shared frame, irq etc. */
  50.160 -	err = netif_map(be->netif, tx_ring_ref, rx_ring_ref, evtchn);
  50.161 -	if (err) {
  50.162 -		xenbus_dev_error(be->dev, err,
  50.163 -				 "mapping shared-frames %lu/%lu port %u",
  50.164 -				 tx_ring_ref, rx_ring_ref, evtchn);
  50.165 -		return;
  50.166 -	}
  50.167 +	return 0;
  50.168  
  50.169 -	xenbus_dev_ok(be->dev);
  50.170 -
  50.171 -	return;
  50.172 +fail:
  50.173 +	DPRINTK("failed");
  50.174 +	netback_remove(dev);
  50.175 +	return err;
  50.176  }
  50.177  
  50.178 -/* 
  50.179 -   Setup supplies physical device.  
  50.180 -   We provide event channel and device details to front end.
  50.181 -   Frontend supplies shared frame and event channel.
  50.182 +
  50.183 +/**
  50.184 + * Handle the creation of the hotplug script environment.  We add the script
  50.185 + * and vif variables to the environment, for the benefit of the vif-* hotplug
  50.186 + * scripts.
  50.187   */
  50.188 -static void backend_changed(struct xenbus_watch *watch,
  50.189 -			    const char **vec, unsigned int len)
  50.190 -{
  50.191 -	int err;
  50.192 -	long int handle;
  50.193 -	struct backend_info *be
  50.194 -		= container_of(watch, struct backend_info, backend_watch);
  50.195 -	struct xenbus_device *dev = be->dev;
  50.196 -	u8 be_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
  50.197 -
  50.198 -	err = xenbus_scanf(NULL, dev->nodename, "handle", "%li", &handle);
  50.199 -	if (XENBUS_EXIST_ERR(err))
  50.200 -		return;
  50.201 -	if (err < 0) {
  50.202 -		xenbus_dev_error(dev, err, "reading handle");
  50.203 -		return;
  50.204 -	}
  50.205 -
  50.206 -	if (be->netif == NULL) {
  50.207 -		be->netif = alloc_netif(be->frontend_id, handle, be_mac);
  50.208 -		if (IS_ERR(be->netif)) {
  50.209 -			err = PTR_ERR(be->netif);
  50.210 -			be->netif = NULL;
  50.211 -			xenbus_dev_error(dev, err, "creating interface");
  50.212 -			return;
  50.213 -		}
  50.214 -
  50.215 -		kobject_hotplug(&dev->dev.kobj, KOBJ_ONLINE);
  50.216 -
  50.217 -		/* Pass in NULL node to skip exist test. */
  50.218 -		frontend_changed(&be->watch, NULL, 0);
  50.219 -	}
  50.220 -}
  50.221 -
  50.222  static int netback_hotplug(struct xenbus_device *xdev, char **envp,
  50.223  			   int num_envp, char *buffer, int buffer_size)
  50.224  {
  50.225  	struct backend_info *be = xdev->data;
  50.226  	netif_t *netif = be->netif;
  50.227  	int i = 0, length = 0;
  50.228 +	char *val;
  50.229  
  50.230 -	char *val = xenbus_read(NULL, xdev->nodename, "script", NULL);
  50.231 +	DPRINTK("netback_hotplug");
  50.232 +
  50.233 +	val = xenbus_read(NULL, xdev->nodename, "script", NULL);
  50.234  	if (IS_ERR(val)) {
  50.235  		int err = PTR_ERR(val);
  50.236 -		xenbus_dev_error(xdev, err, "reading script");
  50.237 +		xenbus_dev_fatal(xdev, err, "reading script");
  50.238  		return err;
  50.239  	}
  50.240  	else {
  50.241 @@ -187,83 +144,162 @@ static int netback_hotplug(struct xenbus
  50.242  	return 0;
  50.243  }
  50.244  
  50.245 -static int netback_probe(struct xenbus_device *dev,
  50.246 -			 const struct xenbus_device_id *id)
  50.247 -{
  50.248 -	struct backend_info *be;
  50.249 -	char *frontend;
  50.250 -	int err;
  50.251 -
  50.252 -	be = kmalloc(sizeof(*be), GFP_KERNEL);
  50.253 -	if (!be) {
  50.254 -		xenbus_dev_error(dev, -ENOMEM, "allocating backend structure");
  50.255 -		return -ENOMEM;
  50.256 -	}
  50.257 -	memset(be, 0, sizeof(*be));
  50.258  
  50.259 -	frontend = NULL;
  50.260 -	err = xenbus_gather(NULL, dev->nodename,
  50.261 -			    "frontend-id", "%li", &be->frontend_id,
  50.262 -			    "frontend", NULL, &frontend,
  50.263 -			    NULL);
  50.264 -	if (XENBUS_EXIST_ERR(err))
  50.265 -		goto free_be;
  50.266 -	if (err < 0) {
  50.267 -		xenbus_dev_error(dev, err,
  50.268 -				 "reading %s/frontend or frontend-id",
  50.269 -				 dev->nodename);
  50.270 -		goto free_be;
  50.271 +/**
  50.272 + * Callback received when the hotplug scripts have placed the handle node.
  50.273 + * Read it, and create a netif structure.  If the frontend is ready, connect.
  50.274 + */
  50.275 +static void backend_changed(struct xenbus_watch *watch,
  50.276 +			    const char **vec, unsigned int len)
  50.277 +{
  50.278 +	int err;
  50.279 +	long handle;
  50.280 +	struct backend_info *be
  50.281 +		= container_of(watch, struct backend_info, backend_watch);
  50.282 +	struct xenbus_device *dev = be->dev;
  50.283 +
  50.284 +	DPRINTK("");
  50.285 +
  50.286 +	err = xenbus_scanf(NULL, dev->nodename, "handle", "%li", &handle);
  50.287 +	if (XENBUS_EXIST_ERR(err)) {
  50.288 +		/* Since this watch will fire once immediately after it is
  50.289 +		   registered, we expect this.  Ignore it, and wait for the
  50.290 +		   hotplug scripts. */
  50.291 +		return;
  50.292  	}
  50.293 -	if (strlen(frontend) == 0 || !xenbus_exists(NULL, frontend, "")) {
  50.294 -		/* If we can't get a frontend path and a frontend-id,
  50.295 -		 * then our bus-id is no longer valid and we need to
  50.296 -		 * destroy the backend device.
  50.297 -		 */
  50.298 -		err = -ENOENT;
  50.299 -		goto free_be;
  50.300 +	if (err != 1) {
  50.301 +		xenbus_dev_fatal(dev, err, "reading handle");
  50.302 +		return;
  50.303  	}
  50.304  
  50.305 -	be->dev = dev;
  50.306 -	be->backend_watch.node = dev->nodename;
  50.307 -	be->backend_watch.callback = backend_changed;
  50.308 -	/* Registration implicitly calls backend_changed. */
  50.309 -	err = register_xenbus_watch(&be->backend_watch);
  50.310 +	if (be->netif == NULL) {
  50.311 +		u8 be_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
  50.312 +
  50.313 +		be->netif = alloc_netif(dev->otherend_id, handle, be_mac);
  50.314 +		if (IS_ERR(be->netif)) {
  50.315 +			err = PTR_ERR(be->netif);
  50.316 +			be->netif = NULL;
  50.317 +			xenbus_dev_fatal(dev, err, "creating interface");
  50.318 +			return;
  50.319 +		}
  50.320 +
  50.321 +		kobject_hotplug(&dev->dev.kobj, KOBJ_ONLINE);
  50.322 +
  50.323 +		maybe_connect(be);
  50.324 +	}
  50.325 +}
  50.326 +
  50.327 +
  50.328 +/**
  50.329 + * Callback received when the frontend's state changes.
  50.330 + */
  50.331 +static void frontend_changed(struct xenbus_device *dev,
  50.332 +			     XenbusState frontend_state)
  50.333 +{
  50.334 +	struct backend_info *be = dev->data;
  50.335 +
  50.336 +	DPRINTK("");
  50.337 +
  50.338 +	be->frontend_state = frontend_state;
  50.339 +
  50.340 +	switch (frontend_state) {
  50.341 +	case XenbusStateInitialising:
  50.342 +	case XenbusStateInitialised:
  50.343 +		break;
  50.344 +
  50.345 +	case XenbusStateConnected:
  50.346 +		maybe_connect(be);
  50.347 +		break;
  50.348 +
  50.349 +	case XenbusStateClosing:
  50.350 +		xenbus_switch_state(dev, NULL, XenbusStateClosing);
  50.351 +		break;
  50.352 +
  50.353 +	case XenbusStateClosed:
  50.354 +		device_unregister(&be->dev->dev);
  50.355 +		break;
  50.356 +
  50.357 +	case XenbusStateUnknown:
  50.358 +	case XenbusStateInitWait:
  50.359 +	default:
  50.360 +		xenbus_dev_fatal(be->dev, -EINVAL, "saw state %d at frontend",
  50.361 +				 frontend_state);
  50.362 +		break;
  50.363 +	}
  50.364 +}
  50.365 +
  50.366 +
  50.367 +/* ** Connection ** */
  50.368 +
  50.369 +
  50.370 +static void maybe_connect(struct backend_info *be)
  50.371 +{
  50.372 +	if (be->netif != NULL && be->frontend_state == XenbusStateConnected) {
  50.373 +		connect(be);
  50.374 +	}
  50.375 +}
  50.376 +
  50.377 +
  50.378 +static void connect(struct backend_info *be)
  50.379 +{
  50.380 +	int err;
  50.381 +	struct xenbus_device *dev = be->dev;
  50.382 +
  50.383 +	err = connect_rings(be);
  50.384 +	if (err)
  50.385 +		return;
  50.386 +
  50.387 +	err = xen_net_read_mac(dev, be->netif->fe_dev_addr);
  50.388  	if (err) {
  50.389 -		be->backend_watch.node = NULL;
  50.390 -		xenbus_dev_error(dev, err, "adding backend watch on %s",
  50.391 -				 dev->nodename);
  50.392 -		goto free_be;
  50.393 +		xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename);
  50.394 +		return;
  50.395  	}
  50.396  
  50.397 -	be->frontpath = frontend;
  50.398 -	be->watch.node = be->frontpath;
  50.399 -	be->watch.callback = frontend_changed;
  50.400 -	err = register_xenbus_watch(&be->watch);
  50.401 +	xenbus_switch_state(dev, NULL, XenbusStateConnected);
  50.402 +}
  50.403 +
  50.404 +
  50.405 +static int connect_rings(struct backend_info *be)
  50.406 +{
  50.407 +	struct xenbus_device *dev = be->dev;
  50.408 +	unsigned long tx_ring_ref, rx_ring_ref;
  50.409 +	unsigned int evtchn;
  50.410 +	int err;
  50.411 +
  50.412 +	DPRINTK("");
  50.413 +
  50.414 +	err = xenbus_gather(NULL, dev->otherend,
  50.415 +			    "tx-ring-ref", "%lu", &tx_ring_ref,
  50.416 +			    "rx-ring-ref", "%lu", &rx_ring_ref,
  50.417 +			    "event-channel", "%u", &evtchn, NULL);
  50.418  	if (err) {
  50.419 -		be->watch.node = NULL;
  50.420 -		xenbus_dev_error(dev, err,
  50.421 -				 "adding frontend watch on %s",
  50.422 -				 be->frontpath);
  50.423 -		goto free_be;
  50.424 +		xenbus_dev_fatal(dev, err,
  50.425 +				 "reading %s/ring-ref and event-channel",
  50.426 +				 dev->otherend);
  50.427 +		return err;
  50.428  	}
  50.429  
  50.430 -	dev->data = be;
  50.431 +	/* Map the shared frame, irq etc. */
  50.432 +	err = netif_map(be->netif, tx_ring_ref, rx_ring_ref, evtchn);
  50.433 +	if (err) {
  50.434 +		xenbus_dev_fatal(dev, err,
  50.435 +				 "mapping shared-frames %lu/%lu port %u",
  50.436 +				 tx_ring_ref, rx_ring_ref, evtchn);
  50.437 +		return err;
  50.438 +	}
  50.439  	return 0;
  50.440 +}
  50.441  
  50.442 - free_be:
  50.443 -	if (be->backend_watch.node)
  50.444 -		unregister_xenbus_watch(&be->backend_watch);
  50.445 -	if (frontend)
  50.446 -		kfree(frontend);
  50.447 -	kfree(be);
  50.448 -	return err;
  50.449 -}
  50.450 +
  50.451 +/* ** Driver Registration ** */
  50.452 +
  50.453  
  50.454  static struct xenbus_device_id netback_ids[] = {
  50.455  	{ "vif" },
  50.456  	{ "" }
  50.457  };
  50.458  
  50.459 +
  50.460  static struct xenbus_driver netback = {
  50.461  	.name = "vif",
  50.462  	.owner = THIS_MODULE,
  50.463 @@ -271,13 +307,16 @@ static struct xenbus_driver netback = {
  50.464  	.probe = netback_probe,
  50.465  	.remove = netback_remove,
  50.466  	.hotplug = netback_hotplug,
  50.467 +	.otherend_changed = frontend_changed,
  50.468  };
  50.469  
  50.470 +
  50.471  void netif_xenbus_init(void)
  50.472  {
  50.473  	xenbus_register_backend(&netback);
  50.474  }
  50.475  
  50.476 +
  50.477  /*
  50.478   * Local variables:
  50.479   *  c-file-style: "linux"
    51.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Fri Nov 18 23:06:09 2005 -0600
    51.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Fri Nov 18 23:16:29 2005 -0600
    51.3 @@ -2,6 +2,7 @@
    51.4   * Virtual network driver for conversing with remote driver backends.
    51.5   * 
    51.6   * Copyright (c) 2002-2005, K A Fraser
    51.7 + * Copyright (c) 2005, XenSource Ltd
    51.8   * 
    51.9   * This file may be distributed separately from the Linux kernel, or
   51.10   * incorporated into other software packages, subject to the following license:
   51.11 @@ -56,6 +57,7 @@
   51.12  #include <asm/uaccess.h>
   51.13  #include <asm-xen/xen-public/grant_table.h>
   51.14  #include <asm-xen/gnttab.h>
   51.15 +#include <asm-xen/net_driver_util.h>
   51.16  
   51.17  #define GRANT_INVALID_REF	0
   51.18  
   51.19 @@ -87,26 +89,11 @@
   51.20  #define TX_TEST_IDX req_cons  /* conservative: not seen all our requests? */
   51.21  #endif
   51.22  
   51.23 -
   51.24 -static void network_tx_buf_gc(struct net_device *dev);
   51.25 -static void network_alloc_rx_buffers(struct net_device *dev);
   51.26 -
   51.27  static unsigned long rx_pfn_array[NETIF_RX_RING_SIZE];
   51.28  static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE+1];
   51.29  static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE];
   51.30  
   51.31 -#ifdef CONFIG_PROC_FS
   51.32 -static int xennet_proc_init(void);
   51.33 -static int xennet_proc_addif(struct net_device *dev);
   51.34 -static void xennet_proc_delif(struct net_device *dev);
   51.35 -#else
   51.36 -#define xennet_proc_init()   (0)
   51.37 -#define xennet_proc_addif(d) (0)
   51.38 -#define xennet_proc_delif(d) ((void)0)
   51.39 -#endif
   51.40 -
   51.41 -#define netfront_info net_private
   51.42 -struct net_private
   51.43 +struct netfront_info
   51.44  {
   51.45  	struct list_head list;
   51.46  	struct net_device *netdev;
   51.47 @@ -154,9 +141,6 @@ struct net_private
   51.48  	grant_ref_t grant_rx_ref[NETIF_TX_RING_SIZE + 1]; 
   51.49  
   51.50  	struct xenbus_device *xbdev;
   51.51 -	char *backend;
   51.52 -	int backend_id;
   51.53 -	struct xenbus_watch watch;
   51.54  	int tx_ring_ref;
   51.55  	int rx_ring_ref;
   51.56  	u8 mac[ETH_ALEN];
   51.57 @@ -181,16 +165,256 @@ static char *be_state_name[] = {
   51.58  
   51.59  #ifdef DEBUG
   51.60  #define DPRINTK(fmt, args...) \
   51.61 -	printk(KERN_ALERT "xen_net (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args)
   51.62 +	printk(KERN_ALERT "netfront (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args)
   51.63  #else
   51.64  #define DPRINTK(fmt, args...) ((void)0)
   51.65  #endif
   51.66  #define IPRINTK(fmt, args...) \
   51.67 -	printk(KERN_INFO "xen_net: " fmt, ##args)
   51.68 +	printk(KERN_INFO "netfront: " fmt, ##args)
   51.69  #define WPRINTK(fmt, args...) \
   51.70 -	printk(KERN_WARNING "xen_net: " fmt, ##args)
   51.71 +	printk(KERN_WARNING "netfront: " fmt, ##args)
   51.72 +
   51.73 +
   51.74 +static int talk_to_backend(struct xenbus_device *, struct netfront_info *);
   51.75 +static int setup_device(struct xenbus_device *, struct netfront_info *);
   51.76 +static int create_netdev(int, struct xenbus_device *, struct net_device **);
   51.77 +
   51.78 +static void netfront_closing(struct xenbus_device *);
   51.79 +
   51.80 +static void end_access(int, void *);
   51.81 +static void netif_disconnect_backend(struct netfront_info *);
   51.82 +static void close_netdev(struct netfront_info *);
   51.83 +static void netif_free(struct netfront_info *);
   51.84 +
   51.85 +static void show_device(struct netfront_info *);
   51.86 +
   51.87 +static void network_connect(struct net_device *);
   51.88 +static void network_tx_buf_gc(struct net_device *);
   51.89 +static void network_alloc_rx_buffers(struct net_device *);
   51.90 +static int send_fake_arp(struct net_device *);
   51.91 +
   51.92 +static irqreturn_t netif_int(int irq, void *dev_id, struct pt_regs *ptregs);
   51.93 +
   51.94 +#ifdef CONFIG_PROC_FS
   51.95 +static int xennet_proc_init(void);
   51.96 +static int xennet_proc_addif(struct net_device *dev);
   51.97 +static void xennet_proc_delif(struct net_device *dev);
   51.98 +#else
   51.99 +#define xennet_proc_init()   (0)
  51.100 +#define xennet_proc_addif(d) (0)
  51.101 +#define xennet_proc_delif(d) ((void)0)
  51.102 +#endif
  51.103 +
  51.104 +
  51.105 +/**
  51.106 + * Entry point to this code when a new device is created.  Allocate the basic
  51.107 + * structures and the ring buffers for communication with the backend, and
  51.108 + * inform the backend of the appropriate details for those.  Switch to
  51.109 + * Connected state.
  51.110 + */
  51.111 +static int netfront_probe(struct xenbus_device *dev,
  51.112 +			  const struct xenbus_device_id *id)
  51.113 +{
  51.114 +	int err;
  51.115 +	struct net_device *netdev;
  51.116 +	struct netfront_info *info;
  51.117 +	unsigned int handle;
  51.118 +
  51.119 +	err = xenbus_scanf(NULL, dev->nodename, "handle", "%u", &handle);
  51.120 +	if (err != 1) {
  51.121 +		xenbus_dev_fatal(dev, err, "reading handle");
  51.122 +		return err;
  51.123 +	}
  51.124 +
  51.125 +	err = create_netdev(handle, dev, &netdev);
  51.126 +	if (err) {
  51.127 +		xenbus_dev_fatal(dev, err, "creating netdev");
  51.128 +		return err;
  51.129 +	}
  51.130 +
  51.131 +	info = netdev_priv(netdev);
  51.132 +	dev->data = info;
  51.133 +
  51.134 +	err = talk_to_backend(dev, info);
  51.135 +	if (err) {
  51.136 +		kfree(info);
  51.137 +		dev->data = NULL;
  51.138 +		return err;
  51.139 +	}
  51.140 +
  51.141 +	return 0;
  51.142 +}
  51.143 +
  51.144 +
  51.145 +/**
  51.146 + * We are reconnecting to the backend, due to a suspend/resume, or a backend
  51.147 + * driver restart.  We tear down our netif structure and recreate it, but
  51.148 + * leave the device-layer structures intact so that this is transparent to the
  51.149 + * rest of the kernel.
  51.150 + */
  51.151 +static int netfront_resume(struct xenbus_device *dev)
  51.152 +{
  51.153 +	struct netfront_info *info = dev->data;
  51.154 +
  51.155 +	DPRINTK("%s\n", dev->nodename);
  51.156 +
  51.157 +	netif_disconnect_backend(info);
  51.158 +	return talk_to_backend(dev, info);
  51.159 +}
  51.160 +
  51.161 +
  51.162 +/* Common code used when first setting up, and when resuming. */
  51.163 +static int talk_to_backend(struct xenbus_device *dev,
  51.164 +			   struct netfront_info *info)
  51.165 +{
  51.166 +	const char *message;
  51.167 +	struct xenbus_transaction *xbt;
  51.168 +	int err;
  51.169 +
  51.170 +	err = xen_net_read_mac(dev, info->mac);
  51.171 +	if (err) {
  51.172 +		xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename);
  51.173 +		goto out;
  51.174 +	}
  51.175 +
  51.176 +	/* Create shared ring, alloc event channel. */
  51.177 +	err = setup_device(dev, info);
  51.178 +	if (err)
  51.179 +		goto out;
  51.180 +
  51.181 +again:
  51.182 +	xbt = xenbus_transaction_start();
  51.183 +	if (IS_ERR(xbt)) {
  51.184 +		xenbus_dev_fatal(dev, err, "starting transaction");
  51.185 +		goto destroy_ring;
  51.186 +	}
  51.187  
  51.188 -static void netif_free(struct netfront_info *info);
  51.189 +	err = xenbus_printf(xbt, dev->nodename, "tx-ring-ref","%u",
  51.190 +			    info->tx_ring_ref);
  51.191 +	if (err) {
  51.192 +		message = "writing tx ring-ref";
  51.193 +		goto abort_transaction;
  51.194 +	}
  51.195 +	err = xenbus_printf(xbt, dev->nodename, "rx-ring-ref","%u",
  51.196 +			    info->rx_ring_ref);
  51.197 +	if (err) {
  51.198 +		message = "writing rx ring-ref";
  51.199 +		goto abort_transaction;
  51.200 +	}
  51.201 +	err = xenbus_printf(xbt, dev->nodename,
  51.202 +			    "event-channel", "%u", info->evtchn);
  51.203 +	if (err) {
  51.204 +		message = "writing event-channel";
  51.205 +		goto abort_transaction;
  51.206 +	}
  51.207 +
  51.208 +	err = xenbus_printf(xbt, dev->nodename,
  51.209 +			    "state", "%d", XenbusStateConnected);
  51.210 +	if (err) {
  51.211 +		message = "writing frontend XenbusStateConnected";
  51.212 +		goto abort_transaction;
  51.213 +	}
  51.214 +
  51.215 +	err = xenbus_transaction_end(xbt, 0);
  51.216 +	if (err) {
  51.217 +		if (err == -EAGAIN)
  51.218 +			goto again;
  51.219 +		xenbus_dev_fatal(dev, err, "completing transaction");
  51.220 +		goto destroy_ring;
  51.221 +	}
  51.222 +
  51.223 +	return 0;
  51.224 +
  51.225 + abort_transaction:
  51.226 +	xenbus_transaction_end(xbt, 1);
  51.227 +	xenbus_dev_fatal(dev, err, "%s", message);
  51.228 + destroy_ring:
  51.229 +	netif_free(info);
  51.230 + out:
  51.231 +	return err;
  51.232 +}
  51.233 +
  51.234 +
  51.235 +static int setup_device(struct xenbus_device *dev, struct netfront_info *info)
  51.236 +{
  51.237 +	int err;
  51.238 +	struct net_device *netdev = info->netdev;
  51.239 +
  51.240 +	info->tx_ring_ref = GRANT_INVALID_REF;
  51.241 +	info->rx_ring_ref = GRANT_INVALID_REF;
  51.242 +	info->rx = NULL;
  51.243 +	info->tx = NULL;
  51.244 +	info->irq = 0;
  51.245 +
  51.246 +	info->tx = (netif_tx_interface_t *)__get_free_page(GFP_KERNEL);
  51.247 +	if (!info->tx) {
  51.248 +		err = -ENOMEM;
  51.249 +		xenbus_dev_fatal(dev, err, "allocating tx ring page");
  51.250 +		goto fail;
  51.251 +	}
  51.252 +	info->rx = (netif_rx_interface_t *)__get_free_page(GFP_KERNEL);
  51.253 +	if (!info->rx) {
  51.254 +		err = -ENOMEM;
  51.255 +		xenbus_dev_fatal(dev, err, "allocating rx ring page");
  51.256 +		goto fail;
  51.257 +	}
  51.258 +	memset(info->tx, 0, PAGE_SIZE);
  51.259 +	memset(info->rx, 0, PAGE_SIZE);
  51.260 +	info->backend_state = BEST_DISCONNECTED;
  51.261 +
  51.262 +	err = xenbus_grant_ring(dev, virt_to_mfn(info->tx));
  51.263 +	if (err < 0)
  51.264 +		goto fail;
  51.265 +	info->tx_ring_ref = err;
  51.266 +
  51.267 +	err = xenbus_grant_ring(dev, virt_to_mfn(info->rx));
  51.268 +	if (err < 0)
  51.269 +		goto fail;
  51.270 +	info->rx_ring_ref = err;
  51.271 +
  51.272 +	err = xenbus_alloc_evtchn(dev, &info->evtchn);
  51.273 +	if (err)
  51.274 +		goto fail;
  51.275 +
  51.276 +	memcpy(netdev->dev_addr, info->mac, ETH_ALEN);
  51.277 +	network_connect(netdev);
  51.278 +	info->irq = bind_evtchn_to_irqhandler(
  51.279 +		info->evtchn, netif_int, SA_SAMPLE_RANDOM, netdev->name,
  51.280 +		netdev);
  51.281 +	(void)send_fake_arp(netdev);
  51.282 +	show_device(info);
  51.283 +
  51.284 +	return 0;
  51.285 +
  51.286 + fail:
  51.287 +	netif_free(info);
  51.288 +	return err;
  51.289 +}
  51.290 +
  51.291 +
  51.292 +/**
  51.293 + * Callback received when the backend's state changes.
  51.294 + */
  51.295 +static void backend_changed(struct xenbus_device *dev,
  51.296 +			    XenbusState backend_state)
  51.297 +{
  51.298 +	DPRINTK("\n");
  51.299 +
  51.300 +	switch (backend_state) {
  51.301 +	case XenbusStateInitialising:
  51.302 +	case XenbusStateInitWait:
  51.303 +	case XenbusStateInitialised:
  51.304 +	case XenbusStateConnected:
  51.305 +	case XenbusStateUnknown:
  51.306 +	case XenbusStateClosed:
  51.307 +		break;
  51.308 +
  51.309 +	case XenbusStateClosing:
  51.310 +		netfront_closing(dev);
  51.311 +		break;
  51.312 +	}
  51.313 +}
  51.314 +
  51.315  
  51.316  /** Send a packet on a net device to encourage switches to learn the
  51.317   * MAC. We send a fake ARP request.
  51.318 @@ -220,9 +444,10 @@ static int send_fake_arp(struct net_devi
  51.319  	return dev_queue_xmit(skb);
  51.320  }
  51.321  
  51.322 +
  51.323  static int network_open(struct net_device *dev)
  51.324  {
  51.325 -	struct net_private *np = netdev_priv(dev);
  51.326 +	struct netfront_info *np = netdev_priv(dev);
  51.327  
  51.328  	memset(&np->stats, 0, sizeof(np->stats));
  51.329  
  51.330 @@ -240,7 +465,7 @@ static void network_tx_buf_gc(struct net
  51.331  {
  51.332  	NETIF_RING_IDX i, prod;
  51.333  	unsigned short id;
  51.334 -	struct net_private *np = netdev_priv(dev);
  51.335 +	struct netfront_info *np = netdev_priv(dev);
  51.336  	struct sk_buff *skb;
  51.337  
  51.338  	if (np->backend_state != BEST_CONNECTED)
  51.339 @@ -295,7 +520,7 @@ static void network_tx_buf_gc(struct net
  51.340  static void network_alloc_rx_buffers(struct net_device *dev)
  51.341  {
  51.342  	unsigned short id;
  51.343 -	struct net_private *np = netdev_priv(dev);
  51.344 +	struct netfront_info *np = netdev_priv(dev);
  51.345  	struct sk_buff *skb;
  51.346  	int i, batch_target;
  51.347  	NETIF_RING_IDX req_prod = np->rx->req_prod;
  51.348 @@ -337,13 +562,13 @@ static void network_alloc_rx_buffers(str
  51.349  		ref = gnttab_claim_grant_reference(&np->gref_rx_head);
  51.350  		BUG_ON((signed short)ref < 0);
  51.351  		np->grant_rx_ref[id] = ref;
  51.352 -		gnttab_grant_foreign_transfer_ref(ref, np->backend_id);
  51.353 +		gnttab_grant_foreign_transfer_ref(ref,
  51.354 +						  np->xbdev->otherend_id);
  51.355  		np->rx->ring[MASK_NETIF_RX_IDX(req_prod + i)].req.gref = ref;
  51.356  		rx_pfn_array[i] = virt_to_mfn(skb->head);
  51.357  
  51.358  		/* Remove this page from map before passing back to Xen. */
  51.359 -		phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] 
  51.360 -			= INVALID_P2M_ENTRY;
  51.361 +		set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT, INVALID_P2M_ENTRY);
  51.362  
  51.363  		MULTI_update_va_mapping(rx_mcl+i, (unsigned long)skb->head,
  51.364  					__pte(0), 0);
  51.365 @@ -386,7 +611,7 @@ static void network_alloc_rx_buffers(str
  51.366  static int network_start_xmit(struct sk_buff *skb, struct net_device *dev)
  51.367  {
  51.368  	unsigned short id;
  51.369 -	struct net_private *np = netdev_priv(dev);
  51.370 +	struct netfront_info *np = netdev_priv(dev);
  51.371  	netif_tx_request_t *tx;
  51.372  	NETIF_RING_IDX i;
  51.373  	grant_ref_t ref;
  51.374 @@ -430,7 +655,7 @@ static int network_start_xmit(struct sk_
  51.375  	BUG_ON((signed short)ref < 0);
  51.376  	mfn = virt_to_mfn(skb->data);
  51.377  	gnttab_grant_foreign_access_ref(
  51.378 -		ref, np->backend_id, mfn, GNTMAP_readonly);
  51.379 +		ref, np->xbdev->otherend_id, mfn, GNTMAP_readonly);
  51.380  	tx->gref = np->grant_tx_ref[id] = ref;
  51.381  	tx->offset = (unsigned long)skb->data & ~PAGE_MASK;
  51.382  	tx->size = skb->len;
  51.383 @@ -467,7 +692,7 @@ static int network_start_xmit(struct sk_
  51.384  static irqreturn_t netif_int(int irq, void *dev_id, struct pt_regs *ptregs)
  51.385  {
  51.386  	struct net_device *dev = dev_id;
  51.387 -	struct net_private *np = netdev_priv(dev);
  51.388 +	struct netfront_info *np = netdev_priv(dev);
  51.389  	unsigned long flags;
  51.390  
  51.391  	spin_lock_irqsave(&np->tx_lock, flags);
  51.392 @@ -484,7 +709,7 @@ static irqreturn_t netif_int(int irq, vo
  51.393  
  51.394  static int netif_poll(struct net_device *dev, int *pbudget)
  51.395  {
  51.396 -	struct net_private *np = netdev_priv(dev);
  51.397 +	struct netfront_info *np = netdev_priv(dev);
  51.398  	struct sk_buff *skb, *nskb;
  51.399  	netif_rx_response_t *rx;
  51.400  	NETIF_RING_IDX i, rp;
  51.401 @@ -535,7 +760,7 @@ static int netif_poll(struct net_device 
  51.402  		if(ref == GRANT_INVALID_REF) { 
  51.403  			printk(KERN_WARNING "Bad rx grant reference %d "
  51.404  			       "from dom %d.\n",
  51.405 -			       ref, np->backend_id);
  51.406 +			       ref, np->xbdev->otherend_id);
  51.407  			np->rx->ring[MASK_NETIF_RX_IDX(np->rx->req_prod)].
  51.408  				req.id = rx->id;
  51.409  			wmb();
  51.410 @@ -570,7 +795,7 @@ static int netif_poll(struct net_device 
  51.411  					pfn_pte_ma(mfn, PAGE_KERNEL), 0);
  51.412  		mcl++;
  51.413  
  51.414 -		phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] = mfn;
  51.415 +		set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT, mfn);
  51.416  
  51.417  		__skb_queue_tail(&rxq, skb);
  51.418  	}
  51.419 @@ -679,7 +904,7 @@ static int netif_poll(struct net_device 
  51.420  
  51.421  static int network_close(struct net_device *dev)
  51.422  {
  51.423 -	struct net_private *np = netdev_priv(dev);
  51.424 +	struct netfront_info *np = netdev_priv(dev);
  51.425  	np->user_state = UST_CLOSED;
  51.426  	netif_stop_queue(np->netdev);
  51.427  	return 0;
  51.428 @@ -688,13 +913,13 @@ static int network_close(struct net_devi
  51.429  
  51.430  static struct net_device_stats *network_get_stats(struct net_device *dev)
  51.431  {
  51.432 -	struct net_private *np = netdev_priv(dev);
  51.433 +	struct netfront_info *np = netdev_priv(dev);
  51.434  	return &np->stats;
  51.435  }
  51.436  
  51.437  static void network_connect(struct net_device *dev)
  51.438  {
  51.439 -	struct net_private *np;
  51.440 +	struct netfront_info *np;
  51.441  	int i, requeue_idx;
  51.442  	netif_tx_request_t *tx;
  51.443  	struct sk_buff *skb;
  51.444 @@ -737,7 +962,7 @@ static void network_connect(struct net_d
  51.445  
  51.446  		tx->id = i;
  51.447  		gnttab_grant_foreign_access_ref(
  51.448 -			np->grant_tx_ref[i], np->backend_id, 
  51.449 +			np->grant_tx_ref[i], np->xbdev->otherend_id, 
  51.450  			virt_to_mfn(np->tx_skbs[i]->data),
  51.451  			GNTMAP_readonly); 
  51.452  		tx->gref = np->grant_tx_ref[i];
  51.453 @@ -756,7 +981,7 @@ static void network_connect(struct net_d
  51.454  		if ((unsigned long)np->rx_skbs[i] < __PAGE_OFFSET)
  51.455  			continue;
  51.456  		gnttab_grant_foreign_transfer_ref(
  51.457 -			np->grant_rx_ref[i], np->backend_id);
  51.458 +			np->grant_rx_ref[i], np->xbdev->otherend_id);
  51.459  		np->rx->ring[requeue_idx].req.gref =
  51.460  			np->grant_rx_ref[i];
  51.461  		np->rx->ring[requeue_idx].req.id = i;
  51.462 @@ -783,7 +1008,7 @@ static void network_connect(struct net_d
  51.463  	spin_unlock_irq(&np->tx_lock);
  51.464  }
  51.465  
  51.466 -static void show_device(struct net_private *np)
  51.467 +static void show_device(struct netfront_info *np)
  51.468  {
  51.469  #ifdef DEBUG
  51.470  	if (np) {
  51.471 @@ -800,27 +1025,9 @@ static void show_device(struct net_priva
  51.472  #endif
  51.473  }
  51.474  
  51.475 -/*
  51.476 - * Move the vif into connected state.
  51.477 - * Sets the mac and event channel from the message.
  51.478 - * Binds the irq to the event channel.
  51.479 - */
  51.480 -static void 
  51.481 -connect_device(struct net_private *np, unsigned int evtchn)
  51.482 -{
  51.483 -	struct net_device *dev = np->netdev;
  51.484 -	memcpy(dev->dev_addr, np->mac, ETH_ALEN);
  51.485 -	np->evtchn = evtchn;
  51.486 -	network_connect(dev);
  51.487 -	np->irq = bind_evtchn_to_irqhandler(
  51.488 -		np->evtchn, netif_int, SA_SAMPLE_RANDOM, dev->name, dev);
  51.489 -	(void)send_fake_arp(dev);
  51.490 -	show_device(np);
  51.491 -}
  51.492 -
  51.493  static void netif_uninit(struct net_device *dev)
  51.494  {
  51.495 -	struct net_private *np = netdev_priv(dev);
  51.496 +	struct netfront_info *np = netdev_priv(dev);
  51.497  	gnttab_free_grant_references(np->gref_tx_head);
  51.498  	gnttab_free_grant_references(np->gref_rx_head);
  51.499  }
  51.500 @@ -841,9 +1048,9 @@ static int create_netdev(int handle, str
  51.501  {
  51.502  	int i, err = 0;
  51.503  	struct net_device *netdev = NULL;
  51.504 -	struct net_private *np = NULL;
  51.505 +	struct netfront_info *np = NULL;
  51.506  
  51.507 -	if ((netdev = alloc_etherdev(sizeof(struct net_private))) == NULL) {
  51.508 +	if ((netdev = alloc_etherdev(sizeof(struct netfront_info))) == NULL) {
  51.509  		printk(KERN_WARNING "%s> alloc_etherdev failed.\n",
  51.510  		       __FUNCTION__);
  51.511  		err = -ENOMEM;
  51.512 @@ -918,7 +1125,7 @@ static int create_netdev(int handle, str
  51.513  	np->netdev = netdev;
  51.514  
  51.515   exit:
  51.516 -	if ((err != 0) && (netdev != NULL))
  51.517 +	if (err != 0)
  51.518  		kfree(netdev);
  51.519  	else if (val != NULL)
  51.520  		*val = netdev;
  51.521 @@ -930,15 +1137,6 @@ static int create_netdev(int handle, str
  51.522  	goto exit;
  51.523  }
  51.524  
  51.525 -static int destroy_netdev(struct net_device *netdev)
  51.526 -{
  51.527 -#ifdef CONFIG_PROC_FS
  51.528 -	xennet_proc_delif(netdev);
  51.529 -#endif
  51.530 -        unregister_netdev(netdev);
  51.531 -	return 0;
  51.532 -}
  51.533 -
  51.534  /*
  51.535   * We use this notifier to send out a fake ARP reply to reset switches and
  51.536   * router ARP caches when an IP interface is brought up on a VIF.
  51.537 @@ -956,91 +1154,70 @@ inetdev_notify(struct notifier_block *th
  51.538  	return NOTIFY_DONE;
  51.539  }
  51.540  
  51.541 -static struct notifier_block notifier_inetdev = {
  51.542 -	.notifier_call  = inetdev_notify,
  51.543 -	.next           = NULL,
  51.544 -	.priority       = 0
  51.545 -};
  51.546 +
  51.547 +/* ** Close down ** */
  51.548 +
  51.549  
  51.550 -static struct xenbus_device_id netfront_ids[] = {
  51.551 -	{ "vif" },
  51.552 -	{ "" }
  51.553 -};
  51.554 +/**
  51.555 + * Handle the change of state of the backend to Closing.  We must delete our
  51.556 + * device-layer structures now, to ensure that writes are flushed through to
  51.557 + * the backend.  Once is this done, we can switch to Closed in
  51.558 + * acknowledgement.
  51.559 + */
  51.560 +static void netfront_closing(struct xenbus_device *dev)
  51.561 +{
  51.562 +	struct netfront_info *info = dev->data;
  51.563  
  51.564 -static void watch_for_status(struct xenbus_watch *watch,
  51.565 -			     const char **vec, unsigned int len)
  51.566 -{
  51.567 +	DPRINTK("netfront_closing: %s removed\n", dev->nodename);
  51.568 +
  51.569 +	close_netdev(info);
  51.570 +
  51.571 +	xenbus_switch_state(dev, NULL, XenbusStateClosed);
  51.572  }
  51.573  
  51.574 -static int setup_device(struct xenbus_device *dev, struct netfront_info *info)
  51.575 +
  51.576 +static int netfront_remove(struct xenbus_device *dev)
  51.577  {
  51.578 -	int err;
  51.579 -	evtchn_op_t op = {
  51.580 -		.cmd = EVTCHNOP_alloc_unbound,
  51.581 -		.u.alloc_unbound.dom = DOMID_SELF,
  51.582 -		.u.alloc_unbound.remote_dom = info->backend_id };
  51.583 -
  51.584 -	info->tx_ring_ref = GRANT_INVALID_REF;
  51.585 -	info->rx_ring_ref = GRANT_INVALID_REF;
  51.586 -	info->rx = NULL;
  51.587 -	info->tx = NULL;
  51.588 -	info->irq = 0;
  51.589 +	struct netfront_info *info = dev->data;
  51.590  
  51.591 -	info->tx = (netif_tx_interface_t *)__get_free_page(GFP_KERNEL);
  51.592 -	if (info->tx == 0) {
  51.593 -		err = -ENOMEM;
  51.594 -		xenbus_dev_error(dev, err, "allocating tx ring page");
  51.595 -		goto out;
  51.596 -	}
  51.597 -	info->rx = (netif_rx_interface_t *)__get_free_page(GFP_KERNEL);
  51.598 -	if (info->rx == 0) {
  51.599 -		err = -ENOMEM;
  51.600 -		xenbus_dev_error(dev, err, "allocating rx ring page");
  51.601 -		goto out;
  51.602 -	}
  51.603 -	memset(info->tx, 0, PAGE_SIZE);
  51.604 -	memset(info->rx, 0, PAGE_SIZE);
  51.605 -	info->backend_state = BEST_DISCONNECTED;
  51.606 +	DPRINTK("%s\n", dev->nodename);
  51.607  
  51.608 -	err = gnttab_grant_foreign_access(info->backend_id,
  51.609 -					  virt_to_mfn(info->tx), 0);
  51.610 -	if (err < 0) {
  51.611 -		xenbus_dev_error(dev, err, "granting access to tx ring page");
  51.612 -		goto out;
  51.613 -	}
  51.614 -	info->tx_ring_ref = err;
  51.615 -
  51.616 -	err = gnttab_grant_foreign_access(info->backend_id,
  51.617 -					  virt_to_mfn(info->rx), 0);
  51.618 -	if (err < 0) {
  51.619 -		xenbus_dev_error(dev, err, "granting access to rx ring page");
  51.620 -		goto out;
  51.621 -	}
  51.622 -	info->rx_ring_ref = err;
  51.623 -
  51.624 -	err = HYPERVISOR_event_channel_op(&op);
  51.625 -	if (err) {
  51.626 -		xenbus_dev_error(dev, err, "allocating event channel");
  51.627 -		goto out;
  51.628 -	}
  51.629 -
  51.630 -	connect_device(info, op.u.alloc_unbound.port);
  51.631 +	netif_free(info);
  51.632 +	kfree(info);
  51.633  
  51.634  	return 0;
  51.635 -
  51.636 - out:
  51.637 -	netif_free(info);
  51.638 -	return err;
  51.639  }
  51.640  
  51.641 -static void end_access(int ref, void *page)
  51.642 -{
  51.643 -	if (ref != GRANT_INVALID_REF)
  51.644 -		gnttab_end_foreign_access(ref, 0, (unsigned long)page);
  51.645 -}
  51.646  
  51.647  static void netif_free(struct netfront_info *info)
  51.648  {
  51.649 +	netif_disconnect_backend(info);
  51.650 +	close_netdev(info);
  51.651 +}
  51.652 +
  51.653 +
  51.654 +static void close_netdev(struct netfront_info *info)
  51.655 +{
  51.656 +	if (info->netdev) {
  51.657 +#ifdef CONFIG_PROC_FS
  51.658 +		xennet_proc_delif(info->netdev);
  51.659 +#endif
  51.660 +		unregister_netdev(info->netdev);
  51.661 +		info->netdev = NULL;
  51.662 +	}
  51.663 +}
  51.664 +
  51.665 +
  51.666 +static void netif_disconnect_backend(struct netfront_info *info)
  51.667 +{
  51.668 +	/* Stop old i/f to prevent errors whilst we rebuild the state. */
  51.669 +	spin_lock_irq(&info->tx_lock);
  51.670 +	spin_lock(&info->rx_lock);
  51.671 +	netif_stop_queue(info->netdev);
  51.672 +	/* info->backend_state = BEST_DISCONNECTED; */
  51.673 +	spin_unlock(&info->rx_lock);
  51.674 +	spin_unlock_irq(&info->tx_lock);
  51.675 +    
  51.676  	end_access(info->tx_ring_ref, info->tx);
  51.677  	end_access(info->rx_ring_ref, info->rx);
  51.678  	info->tx_ring_ref = GRANT_INVALID_REF;
  51.679 @@ -1053,203 +1230,22 @@ static void netif_free(struct netfront_i
  51.680  	info->evtchn = info->irq = 0;
  51.681  }
  51.682  
  51.683 -/* Stop network device and free tx/rx queues and irq. */
  51.684 -static void shutdown_device(struct net_private *np)
  51.685 +
  51.686 +static void end_access(int ref, void *page)
  51.687  {
  51.688 -	/* Stop old i/f to prevent errors whilst we rebuild the state. */
  51.689 -	spin_lock_irq(&np->tx_lock);
  51.690 -	spin_lock(&np->rx_lock);
  51.691 -	netif_stop_queue(np->netdev);
  51.692 -	/* np->backend_state = BEST_DISCONNECTED; */
  51.693 -	spin_unlock(&np->rx_lock);
  51.694 -	spin_unlock_irq(&np->tx_lock);
  51.695 -    
  51.696 -	/* Free resources. */
  51.697 -	netif_free(np);
  51.698 +	if (ref != GRANT_INVALID_REF)
  51.699 +		gnttab_end_foreign_access(ref, 0, (unsigned long)page);
  51.700  }
  51.701  
  51.702 -/* Common code used when first setting up, and when resuming. */
  51.703 -static int talk_to_backend(struct xenbus_device *dev,
  51.704 -			   struct netfront_info *info)
  51.705 -{
  51.706 -	char *backend, *mac, *e, *s;
  51.707 -	const char *message;
  51.708 -	struct xenbus_transaction *xbt;
  51.709 -	int err, i;
  51.710 -
  51.711 -	backend = NULL;
  51.712 -	err = xenbus_gather(NULL, dev->nodename,
  51.713 -			    "backend-id", "%i", &info->backend_id,
  51.714 -			    "backend", NULL, &backend,
  51.715 -			    NULL);
  51.716 -	if (XENBUS_EXIST_ERR(err))
  51.717 -		goto out;
  51.718 -	if (backend && strlen(backend) == 0) {
  51.719 -		err = -ENOENT;
  51.720 -		goto out;
  51.721 -	}
  51.722 -	if (err < 0) {
  51.723 -		xenbus_dev_error(dev, err, "reading %s/backend or backend-id",
  51.724 -				 dev->nodename);
  51.725 -		goto out;
  51.726 -	}
  51.727  
  51.728 -	mac = xenbus_read(NULL, dev->nodename, "mac", NULL);
  51.729 -	if (IS_ERR(mac)) {
  51.730 -		err = PTR_ERR(mac);
  51.731 -		xenbus_dev_error(dev, err, "reading %s/mac",
  51.732 -				 dev->nodename);
  51.733 -		goto out;
  51.734 -	}
  51.735 -	s = mac;
  51.736 -	for (i = 0; i < ETH_ALEN; i++) {
  51.737 -		info->mac[i] = simple_strtoul(s, &e, 16);
  51.738 -		if (s == e || (e[0] != ':' && e[0] != 0)) {
  51.739 -			kfree(mac);
  51.740 -			err = -ENOENT;
  51.741 -			xenbus_dev_error(dev, err, "parsing %s/mac",
  51.742 -					 dev->nodename);
  51.743 -			goto out;
  51.744 -		}
  51.745 -		s = &e[1];
  51.746 -	}
  51.747 -	kfree(mac);
  51.748 -
  51.749 -	/* Create shared ring, alloc event channel. */
  51.750 -	err = setup_device(dev, info);
  51.751 -	if (err) {
  51.752 -		xenbus_dev_error(dev, err, "setting up ring");
  51.753 -		goto out;
  51.754 -	}
  51.755 +/* ** Driver registration ** */
  51.756  
  51.757 -again:
  51.758 -	xbt = xenbus_transaction_start();
  51.759 -	if (IS_ERR(xbt)) {
  51.760 -		xenbus_dev_error(dev, err, "starting transaction");
  51.761 -		goto destroy_ring;
  51.762 -	}
  51.763 -
  51.764 -	err = xenbus_printf(xbt, dev->nodename, "tx-ring-ref","%u",
  51.765 -			    info->tx_ring_ref);
  51.766 -	if (err) {
  51.767 -		message = "writing tx ring-ref";
  51.768 -		goto abort_transaction;
  51.769 -	}
  51.770 -	err = xenbus_printf(xbt, dev->nodename, "rx-ring-ref","%u",
  51.771 -			    info->rx_ring_ref);
  51.772 -	if (err) {
  51.773 -		message = "writing rx ring-ref";
  51.774 -		goto abort_transaction;
  51.775 -	}
  51.776 -	err = xenbus_printf(xbt, dev->nodename,
  51.777 -			    "event-channel", "%u", info->evtchn);
  51.778 -	if (err) {
  51.779 -		message = "writing event-channel";
  51.780 -		goto abort_transaction;
  51.781 -	}
  51.782 -
  51.783 -	err = xenbus_transaction_end(xbt, 0);
  51.784 -	if (err) {
  51.785 -		if (err == -EAGAIN)
  51.786 -			goto again;
  51.787 -		xenbus_dev_error(dev, err, "completing transaction");
  51.788 -		goto destroy_ring;
  51.789 -	}
  51.790  
  51.791 -	info->watch.node = backend;
  51.792 -	info->watch.callback = watch_for_status;
  51.793 -	err = register_xenbus_watch(&info->watch);
  51.794 -	if (err) {
  51.795 -		message = "registering watch on backend";
  51.796 -		goto destroy_ring;
  51.797 -	}
  51.798 -
  51.799 -	info->backend = backend;
  51.800 -
  51.801 -	return 0;
  51.802 -
  51.803 - abort_transaction:
  51.804 -	xenbus_transaction_end(xbt, 1);
  51.805 -	xenbus_dev_error(dev, err, "%s", message);
  51.806 - destroy_ring:
  51.807 -	shutdown_device(info);
  51.808 - out:
  51.809 -	if (backend)
  51.810 -		kfree(backend);
  51.811 -	return err;
  51.812 -}
  51.813 -
  51.814 -/*
  51.815 - * Setup supplies the backend dir, virtual device.
  51.816 - * We place an event channel and shared frame entries.
  51.817 - * We watch backend to wait if it's ok.
  51.818 - */
  51.819 -static int netfront_probe(struct xenbus_device *dev,
  51.820 -			  const struct xenbus_device_id *id)
  51.821 -{
  51.822 -	int err;
  51.823 -	struct net_device *netdev;
  51.824 -	struct netfront_info *info;
  51.825 -	unsigned int handle;
  51.826 -
  51.827 -	err = xenbus_scanf(NULL, dev->nodename, "handle", "%u", &handle);
  51.828 -	if (XENBUS_EXIST_ERR(err))
  51.829 -		return err;
  51.830 -	if (err < 0) {
  51.831 -		xenbus_dev_error(dev, err, "reading handle");
  51.832 -		return err;
  51.833 -	}
  51.834 +static struct xenbus_device_id netfront_ids[] = {
  51.835 +	{ "vif" },
  51.836 +	{ "" }
  51.837 +};
  51.838  
  51.839 -	err = create_netdev(handle, dev, &netdev);
  51.840 -	if (err) {
  51.841 -		xenbus_dev_error(dev, err, "creating netdev");
  51.842 -		return err;
  51.843 -	}
  51.844 -
  51.845 -	info = netdev_priv(netdev);
  51.846 -	dev->data = info;
  51.847 -
  51.848 -	err = talk_to_backend(dev, info);
  51.849 -	if (err) {
  51.850 -		destroy_netdev(netdev);
  51.851 -		kfree(netdev);
  51.852 -		dev->data = NULL;
  51.853 -		return err;
  51.854 -	}
  51.855 -
  51.856 -	return 0;
  51.857 -}
  51.858 -
  51.859 -static int netfront_remove(struct xenbus_device *dev)
  51.860 -{
  51.861 -	struct netfront_info *info = dev->data;
  51.862 -
  51.863 -	if (info->backend)
  51.864 -		unregister_xenbus_watch(&info->watch);
  51.865 -
  51.866 -	netif_free(info);
  51.867 -
  51.868 -	kfree(info->backend);
  51.869 -	kfree(info);
  51.870 -
  51.871 -	return 0;
  51.872 -}
  51.873 -
  51.874 -static int netfront_suspend(struct xenbus_device *dev)
  51.875 -{
  51.876 -	struct netfront_info *info = dev->data;
  51.877 -	unregister_xenbus_watch(&info->watch);
  51.878 -	kfree(info->backend);
  51.879 -	info->backend = NULL;
  51.880 -	return 0;
  51.881 -}
  51.882 -
  51.883 -static int netfront_resume(struct xenbus_device *dev)
  51.884 -{
  51.885 -	struct netfront_info *info = dev->data;
  51.886 -	netif_free(info);
  51.887 -	return talk_to_backend(dev, info);
  51.888 -}
  51.889  
  51.890  static struct xenbus_driver netfront = {
  51.891  	.name = "vif",
  51.892 @@ -1258,13 +1254,15 @@ static struct xenbus_driver netfront = {
  51.893  	.probe = netfront_probe,
  51.894  	.remove = netfront_remove,
  51.895  	.resume = netfront_resume,
  51.896 -	.suspend = netfront_suspend,
  51.897 +	.otherend_changed = backend_changed,
  51.898  };
  51.899  
  51.900 -static void __init init_net_xenbus(void)
  51.901 -{
  51.902 -	xenbus_register_driver(&netfront);
  51.903 -}
  51.904 +
  51.905 +static struct notifier_block notifier_inetdev = {
  51.906 +	.notifier_call  = inetdev_notify,
  51.907 +	.next           = NULL,
  51.908 +	.priority       = 0
  51.909 +};
  51.910  
  51.911  static int __init netif_init(void)
  51.912  {
  51.913 @@ -1280,14 +1278,24 @@ static int __init netif_init(void)
  51.914  
  51.915  	(void)register_inetaddr_notifier(&notifier_inetdev);
  51.916  
  51.917 -	init_net_xenbus();
  51.918 +	return xenbus_register_frontend(&netfront);
  51.919 +}
  51.920 +module_init(netif_init);
  51.921  
  51.922 -	return err;
  51.923 -}
  51.924  
  51.925  static void netif_exit(void)
  51.926  {
  51.927 +	unregister_inetaddr_notifier(&notifier_inetdev);
  51.928 +
  51.929 +	return xenbus_unregister_driver(&netfront);
  51.930  }
  51.931 +module_exit(netif_exit);
  51.932 +
  51.933 +MODULE_LICENSE("BSD");
  51.934 + 
  51.935 + 
  51.936 +/* ** /proc **/
  51.937 +
  51.938  
  51.939  #ifdef CONFIG_PROC_FS
  51.940  
  51.941 @@ -1300,7 +1308,7 @@ static int xennet_proc_read(
  51.942  {
  51.943  	struct net_device *dev =
  51.944  		(struct net_device *)((unsigned long)data & ~3UL);
  51.945 -	struct net_private *np = netdev_priv(dev);
  51.946 +	struct netfront_info *np = netdev_priv(dev);
  51.947  	int len = 0, which_target = (long)data & 3;
  51.948      
  51.949  	switch (which_target)
  51.950 @@ -1326,7 +1334,7 @@ static int xennet_proc_write(
  51.951  {
  51.952  	struct net_device *dev =
  51.953  		(struct net_device *)((unsigned long)data & ~3UL);
  51.954 -	struct net_private *np = netdev_priv(dev);
  51.955 +	struct netfront_info *np = netdev_priv(dev);
  51.956  	int which_target = (long)data & 3;
  51.957  	char string[64];
  51.958  	long target;
  51.959 @@ -1440,8 +1448,6 @@ static void xennet_proc_delif(struct net
  51.960  
  51.961  #endif
  51.962  
  51.963 -module_init(netif_init);
  51.964 -module_exit(netif_exit);
  51.965  
  51.966  /*
  51.967   * Local variables:
    52.1 --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Fri Nov 18 23:06:09 2005 -0600
    52.2 +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Fri Nov 18 23:16:29 2005 -0600
    52.3 @@ -32,11 +32,6 @@
    52.4  #include <asm-xen/xen-public/dom0_ops.h>
    52.5  #include <asm-xen/xen_proc.h>
    52.6  
    52.7 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
    52.8 -#define pud_t pgd_t
    52.9 -#define pud_offset(d, va) d
   52.10 -#endif
   52.11 -
   52.12  static struct proc_dir_entry *privcmd_intf;
   52.13  
   52.14  static int privcmd_ioctl(struct inode *inode, struct file *file,
   52.15 @@ -152,7 +147,8 @@ static int privcmd_ioctl(struct inode *i
   52.16  		privcmd_mmapbatch_t m;
   52.17  		struct vm_area_struct *vma = NULL;
   52.18  		unsigned long *p, addr;
   52.19 -		unsigned long mfn, ptep;
   52.20 +		unsigned long mfn; 
   52.21 +		uint64_t ptep;
   52.22  		int i;
   52.23  
   52.24  		if (copy_from_user(&m, (void *)data, sizeof(m))) {
   52.25 @@ -217,15 +213,38 @@ static int privcmd_ioctl(struct inode *i
   52.26  #endif
   52.27  
   52.28  #ifndef __ia64__
   52.29 -	case IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN: {
   52.30 -		unsigned long m2pv = (unsigned long)machine_to_phys_mapping;
   52.31 -		pgd_t *pgd = pgd_offset_k(m2pv);
   52.32 -		pud_t *pud = pud_offset(pgd, m2pv);
   52.33 -		pmd_t *pmd = pmd_offset(pud, m2pv);
   52.34 -		unsigned long m2p_start_mfn =
   52.35 -			(*(unsigned long *)pmd) >> PAGE_SHIFT; 
   52.36 -		ret = put_user(m2p_start_mfn, (unsigned long *)data) ?
   52.37 -			-EFAULT: 0;
   52.38 +	case IOCTL_PRIVCMD_GET_MACH2PHYS_MFNS: {
   52.39 +		pgd_t *pgd; 
   52.40 +		pud_t *pud; 
   52.41 +		pmd_t *pmd; 
   52.42 +		unsigned long m2pv, m2p_mfn; 	
   52.43 +		privcmd_m2pmfns_t m; 
   52.44 +		unsigned long *p; 
   52.45 +		int i; 
   52.46 +
   52.47 +		if (copy_from_user(&m, (void *)data, sizeof(m)))
   52.48 +			return -EFAULT;
   52.49 +
   52.50 +		m2pv = (unsigned long)machine_to_phys_mapping;
   52.51 +
   52.52 +		p = m.arr; 
   52.53 +
   52.54 +		for (i=0; i < m.num; i++) { 
   52.55 +			pgd = pgd_offset_k(m2pv);
   52.56 +			pud = pud_offset(pgd, m2pv);
   52.57 +			pmd = pmd_offset(pud, m2pv);
   52.58 +			m2p_mfn  = (*(uint64_t *)pmd >> PAGE_SHIFT)&0xFFFFFFFF;
   52.59 +			m2p_mfn += pte_index(m2pv);
   52.60 +
   52.61 +			if (put_user(m2p_mfn, p + i))
   52.62 +				return -EFAULT;
   52.63 +
   52.64 +			m2pv += (1 << 21); 
   52.65 +		}
   52.66 +
   52.67 +		ret = 0; 
   52.68 +		break; 
   52.69 +
   52.70  	}
   52.71  	break;
   52.72  #endif
    53.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c	Fri Nov 18 23:06:09 2005 -0600
    53.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c	Fri Nov 18 23:16:29 2005 -0600
    53.3 @@ -167,9 +167,7 @@ static void inline
    53.4  packet_free(struct packet *pak)
    53.5  {
    53.6  	del_singleshot_timer_sync(&pak->processing_timer);
    53.7 -	if (pak->data_buffer) {
    53.8 -		kfree(pak->data_buffer);
    53.9 -	}
   53.10 +	kfree(pak->data_buffer);
   53.11  	/*
   53.12  	 * cannot do tpmif_put(pak->tpmif); bad things happen
   53.13  	 * on the last tpmif_put()
   53.14 @@ -296,9 +294,8 @@ static int
   53.15  			DPRINTK(" Grant table operation failure !\n");
   53.16  			return 0;
   53.17  		}
   53.18 -		phys_to_machine_mapping[__pa(MMAP_VADDR(tpmif,i)) >>
   53.19 -					PAGE_SHIFT] =
   53.20 -			FOREIGN_FRAME(map_op.dev_bus_addr >> PAGE_SHIFT);
   53.21 +		set_phys_to_machine(__pa(MMAP_VADDR(tpmif,i)) >> PAGE_SHIFT,
   53.22 +			FOREIGN_FRAME(map_op.dev_bus_addr >> PAGE_SHIFT));
   53.23  
   53.24  		tocopy = MIN(size - offset, PAGE_SIZE);
   53.25  
    54.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c	Fri Nov 18 23:06:09 2005 -0600
    54.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c	Fri Nov 18 23:16:29 2005 -0600
    54.3 @@ -41,19 +41,16 @@ static int tpmback_remove(struct xenbus_
    54.4  {
    54.5  	struct backend_info *be = dev->data;
    54.6  
    54.7 -	if (be->watch.node) {
    54.8 +	if (be->watch.node)
    54.9  		unregister_xenbus_watch(&be->watch);
   54.10 -	}
   54.11  	unregister_xenbus_watch(&be->backend_watch);
   54.12  
   54.13  	tpmif_vtpm_close(be->instance);
   54.14  
   54.15 -	if (be->tpmif) {
   54.16 +	if (be->tpmif)
   54.17  		tpmif_put(be->tpmif);
   54.18 -	}
   54.19  
   54.20 -	if (be->frontpath)
   54.21 -		kfree(be->frontpath);
   54.22 +	kfree(be->frontpath);
   54.23  	kfree(be);
   54.24  	return 0;
   54.25  }
   54.26 @@ -258,8 +255,7 @@ static int tpmback_probe(struct xenbus_d
   54.27  free_be:
   54.28  	if (be->backend_watch.node)
   54.29  		unregister_xenbus_watch(&be->backend_watch);
   54.30 -	if (frontend)
   54.31 -		kfree(frontend);
   54.32 +	kfree(frontend);
   54.33  	kfree(be);
   54.34  	return err;
   54.35  }
    55.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c	Fri Nov 18 23:06:09 2005 -0600
    55.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c	Fri Nov 18 23:16:29 2005 -0600
    55.3 @@ -387,8 +387,7 @@ abort_transaction:
    55.4  destroy_tpmring:
    55.5  	destroy_tpmring(info, &my_private);
    55.6  out:
    55.7 -	if (backend)
    55.8 -		kfree(backend);
    55.9 +	kfree(backend);
   55.10  	return err;
   55.11  }
   55.12  
    56.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile	Fri Nov 18 23:06:09 2005 -0600
    56.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile	Fri Nov 18 23:16:29 2005 -0600
    56.3 @@ -1,6 +1,7 @@
    56.4  obj-y	+= xenbus.o
    56.5  
    56.6  xenbus-objs =
    56.7 +xenbus-objs += xenbus_client.o 
    56.8  xenbus-objs += xenbus_comms.o
    56.9  xenbus-objs += xenbus_xs.o
   56.10  xenbus-objs += xenbus_probe.o 
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c	Fri Nov 18 23:16:29 2005 -0600
    57.3 @@ -0,0 +1,253 @@
    57.4 +/******************************************************************************
    57.5 + * Client-facing interface for the Xenbus driver.  In other words, the
    57.6 + * interface between the Xenbus and the device-specific code, be it the
    57.7 + * frontend or the backend of that driver.
    57.8 + *
    57.9 + * Copyright (C) 2005 XenSource Ltd
   57.10 + * 
   57.11 + * This file may be distributed separately from the Linux kernel, or
   57.12 + * incorporated into other software packages, subject to the following license:
   57.13 + * 
   57.14 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   57.15 + * of this source file (the "Software"), to deal in the Software without
   57.16 + * restriction, including without limitation the rights to use, copy, modify,
   57.17 + * merge, publish, distribute, sublicense, and/or sell copies of the Software,
   57.18 + * and to permit persons to whom the Software is furnished to do so, subject to
   57.19 + * the following conditions:
   57.20 + * 
   57.21 + * The above copyright notice and this permission notice shall be included in
   57.22 + * all copies or substantial portions of the Software.
   57.23 + * 
   57.24 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   57.25 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   57.26 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   57.27 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   57.28 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   57.29 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   57.30 + * IN THE SOFTWARE.
   57.31 + */
   57.32 +
   57.33 +
   57.34 +#if 0
   57.35 +#define DPRINTK(fmt, args...) \
   57.36 +    printk("xenbus_client (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
   57.37 +#else
   57.38 +#define DPRINTK(fmt, args...) ((void)0)
   57.39 +#endif
   57.40 +
   57.41 +
   57.42 +#include <asm-xen/evtchn.h>
   57.43 +#include <asm-xen/gnttab.h>
   57.44 +#include <asm-xen/xenbus.h>
   57.45 +
   57.46 +
   57.47 +int xenbus_watch_path(struct xenbus_device *dev, const char *path,
   57.48 +		      struct xenbus_watch *watch, 
   57.49 +		      void (*callback)(struct xenbus_watch *,
   57.50 +				       const char **, unsigned int))
   57.51 +{
   57.52 +	int err;
   57.53 +
   57.54 +	watch->node = path;
   57.55 +	watch->callback = callback;
   57.56 +
   57.57 +	err = register_xenbus_watch(watch);
   57.58 +
   57.59 +	if (err) {
   57.60 +		watch->node = NULL;
   57.61 +		watch->callback = NULL;
   57.62 +		xenbus_dev_fatal(dev, err, "adding watch on %s", path);
   57.63 +	}
   57.64 +
   57.65 +	return err;
   57.66 +}
   57.67 +EXPORT_SYMBOL(xenbus_watch_path);
   57.68 +
   57.69 +
   57.70 +int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
   57.71 +		       const char *path2, struct xenbus_watch *watch, 
   57.72 +		       void (*callback)(struct xenbus_watch *,
   57.73 +					const char **, unsigned int))
   57.74 +{
   57.75 +	int err;
   57.76 +	char *state =
   57.77 +		kmalloc(strlen(path) + 1 + strlen(path2) + 1, GFP_KERNEL);
   57.78 +	if (!state) {
   57.79 +		xenbus_dev_fatal(dev, -ENOMEM, "allocating path for watch");
   57.80 +		return -ENOMEM;
   57.81 +	}
   57.82 +	strcpy(state, path);
   57.83 +	strcat(state, "/");
   57.84 +	strcat(state, path2);
   57.85 +
   57.86 +	err = xenbus_watch_path(dev, state, watch, callback);
   57.87 +
   57.88 +	if (err) {
   57.89 +		kfree(state);
   57.90 +	}
   57.91 +	return err;
   57.92 +}
   57.93 +EXPORT_SYMBOL(xenbus_watch_path2);
   57.94 +
   57.95 +
   57.96 +int xenbus_switch_state(struct xenbus_device *dev,
   57.97 +			struct xenbus_transaction *xbt,
   57.98 +			XenbusState state)
   57.99 +{
  57.100 +	/* We check whether the state is currently set to the given value, and
  57.101 +	   if not, then the state is set.  We don't want to unconditionally
  57.102 +	   write the given state, because we don't want to fire watches
  57.103 +	   unnecessarily.
  57.104 +	 */
  57.105 +
  57.106 +	int current_state;
  57.107 +
  57.108 +	int err = xenbus_scanf(xbt, dev->nodename, "state", "%d",
  57.109 +			       &current_state);
  57.110 +	if (err == 1 && (XenbusState)current_state == state)
  57.111 +		return 0;
  57.112 +
  57.113 +	err = xenbus_printf(xbt, dev->nodename, "state", "%d", state);
  57.114 +	if (err) {
  57.115 +		xenbus_dev_fatal(dev, err, "writing new state");
  57.116 +		return err;
  57.117 +	}
  57.118 +	return 0;
  57.119 +}
  57.120 +EXPORT_SYMBOL(xenbus_switch_state);
  57.121 +
  57.122 +
  57.123 +/**
  57.124 + * Return the path to the error node for the given device, or NULL on failure.
  57.125 + * If the value returned is non-NULL, then it is the caller's to kfree.
  57.126 + */
  57.127 +static char *error_path(struct xenbus_device *dev)
  57.128 +{
  57.129 +	char *path_buffer = kmalloc(strlen("error/") + strlen(dev->nodename) +
  57.130 +				    1, GFP_KERNEL);
  57.131 +	if (path_buffer == NULL) {
  57.132 +		return NULL;
  57.133 +	}
  57.134 +
  57.135 +	strcpy(path_buffer, "error/");
  57.136 +	strcpy(path_buffer + strlen("error/"), dev->nodename);
  57.137 +
  57.138 +	return path_buffer;
  57.139 +}
  57.140 +
  57.141 +
  57.142 +void _dev_error(struct xenbus_device *dev, int err, const char *fmt,
  57.143 +		va_list ap)
  57.144 +{
  57.145 +	int ret;
  57.146 +	unsigned int len;
  57.147 +	char *printf_buffer = NULL, *path_buffer = NULL;
  57.148 +
  57.149 +#define PRINTF_BUFFER_SIZE 4096
  57.150 +	printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL);
  57.151 +	if (printf_buffer == NULL)
  57.152 +		goto fail;
  57.153 +
  57.154 +	len = sprintf(printf_buffer, "%i ", -err);
  57.155 +	ret = vsnprintf(printf_buffer+len, PRINTF_BUFFER_SIZE-len, fmt, ap);
  57.156 +
  57.157 +	BUG_ON(len + ret > PRINTF_BUFFER_SIZE-1);
  57.158 +	dev->has_error = 1;
  57.159 +
  57.160 +	path_buffer = error_path(dev);
  57.161 +
  57.162 +	if (path_buffer == NULL) {
  57.163 +		printk("xenbus: failed to write error node for %s (%s)\n",
  57.164 +		       dev->nodename, printf_buffer);
  57.165 +		goto fail;
  57.166 +	}
  57.167 +
  57.168 +	if (xenbus_write(NULL, path_buffer, "error", printf_buffer) != 0) {
  57.169 +		printk("xenbus: failed to write error node for %s (%s)\n",
  57.170 +		       dev->nodename, printf_buffer);
  57.171 +		goto fail;
  57.172 +	}
  57.173 +
  57.174 +fail:
  57.175 +	if (printf_buffer)
  57.176 +		kfree(printf_buffer);
  57.177 +	if (path_buffer)
  57.178 +		kfree(path_buffer);
  57.179 +}
  57.180 +
  57.181 +
  57.182 +void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt,
  57.183 +		      ...)
  57.184 +{
  57.185 +	va_list ap;
  57.186 +
  57.187 +	va_start(ap, fmt);
  57.188 +	_dev_error(dev, err, fmt, ap);
  57.189 +	va_end(ap);
  57.190 +}
  57.191 +EXPORT_SYMBOL(xenbus_dev_error);
  57.192 +
  57.193 +
  57.194 +void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
  57.195 +		      ...)
  57.196 +{
  57.197 +	va_list ap;
  57.198 +
  57.199 +	va_start(ap, fmt);
  57.200 +	_dev_error(dev, err, fmt, ap);
  57.201 +	va_end(ap);
  57.202 +	
  57.203 +	xenbus_switch_state(dev, NULL, XenbusStateClosing);
  57.204 +}
  57.205 +EXPORT_SYMBOL(xenbus_dev_fatal);
  57.206 +
  57.207 +
  57.208 +int xenbus_grant_ring(struct xenbus_device *dev, unsigned long ring_mfn)
  57.209 +{
  57.210 +	int err = gnttab_grant_foreign_access(dev->otherend_id, ring_mfn, 0);
  57.211 +	if (err < 0)
  57.212 +		xenbus_dev_fatal(dev, err, "granting access to ring page");
  57.213 +	return err;
  57.214 +}
  57.215 +EXPORT_SYMBOL(xenbus_grant_ring);
  57.216 +
  57.217 +
  57.218 +int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port)
  57.219 +{
  57.220 +	evtchn_op_t op = {
  57.221 +		.cmd = EVTCHNOP_alloc_unbound,
  57.222 +		.u.alloc_unbound.dom = DOMID_SELF,
  57.223 +		.u.alloc_unbound.remote_dom = dev->otherend_id };
  57.224 +
  57.225 +	int err = HYPERVISOR_event_channel_op(&op);
  57.226 +	if (err)
  57.227 +		xenbus_dev_fatal(dev, err, "allocating event channel");
  57.228 +	else
  57.229 +		*port = op.u.alloc_unbound.port;
  57.230 +	return err;
  57.231 +}
  57.232 +EXPORT_SYMBOL(xenbus_alloc_evtchn);
  57.233 +
  57.234 +
  57.235 +XenbusState xenbus_read_driver_state(const char *path)
  57.236 +{
  57.237 +	XenbusState result;
  57.238 +
  57.239 +	int err = xenbus_gather(NULL, path, "state", "%d", &result, NULL);
  57.240 +	if (err)
  57.241 +		result = XenbusStateClosed;
  57.242 +
  57.243 +	return result;
  57.244 +}
  57.245 +EXPORT_SYMBOL(xenbus_read_driver_state);
  57.246 +
  57.247 +
  57.248 +/*
  57.249 + * Local variables:
  57.250 + *  c-file-style: "linux"
  57.251 + *  indent-tabs-mode: t
  57.252 + *  c-indent-level: 8
  57.253 + *  c-basic-offset: 8
  57.254 + *  tab-width: 8
  57.255 + * End:
  57.256 + */
    58.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c	Fri Nov 18 23:06:09 2005 -0600
    58.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c	Fri Nov 18 23:16:29 2005 -0600
    58.3 @@ -36,7 +36,7 @@
    58.4  #include <asm-xen/xenbus.h>
    58.5  #include "xenbus_comms.h"
    58.6  
    58.7 -static int xenbus_irq      = 0;
    58.8 +static int xenbus_irq;
    58.9  
   58.10  extern void xenbus_probe(void *); 
   58.11  extern int xenstored_ready; 
   58.12 @@ -51,7 +51,7 @@ static inline struct xenstore_domain_int
   58.13  
   58.14  static irqreturn_t wake_waiting(int irq, void *unused, struct pt_regs *regs)
   58.15  {
   58.16 -	if(unlikely(xenstored_ready == 0)) {
   58.17 +	if (unlikely(xenstored_ready == 0)) {
   58.18  		xenstored_ready = 1; 
   58.19  		schedule_work(&probe_work); 
   58.20  	} 
   58.21 @@ -189,9 +189,6 @@ int xb_init_comms(void)
   58.22  
   58.23  	xenbus_irq = err;
   58.24  
   58.25 -	/* FIXME zero out page -- domain builder should probably do this*/
   58.26 -	memset(mfn_to_virt(xen_start_info->store_mfn), 0, PAGE_SIZE);
   58.27 -
   58.28  	return 0;
   58.29  }
   58.30  
    59.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Fri Nov 18 23:06:09 2005 -0600
    59.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Fri Nov 18 23:16:29 2005 -0600
    59.3 @@ -3,6 +3,7 @@
    59.4   *
    59.5   * Copyright (C) 2005 Rusty Russell, IBM Corporation
    59.6   * Copyright (C) 2005 Mike Wray, Hewlett-Packard
    59.7 + * Copyright (C) 2005 XenSource Ltd
    59.8   * 
    59.9   * This file may be distributed separately from the Linux kernel, or
   59.10   * incorporated into other software packages, subject to the following license:
   59.11 @@ -25,7 +26,13 @@
   59.12   * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   59.13   * IN THE SOFTWARE.
   59.14   */
   59.15 -#define DEBUG
   59.16 +
   59.17 +#if 0
   59.18 +#define DPRINTK(fmt, args...) \
   59.19 +    printk("xenbus_probe (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
   59.20 +#else
   59.21 +#define DPRINTK(fmt, args...) ((void)0)
   59.22 +#endif
   59.23  
   59.24  #include <linux/kernel.h>
   59.25  #include <linux/err.h>
   59.26 @@ -85,6 +92,7 @@ struct xen_bus_type
   59.27  	struct device dev;
   59.28  };
   59.29  
   59.30 +
   59.31  /* device/<type>/<id> => <type>-<id> */
   59.32  static int frontend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
   59.33  {
   59.34 @@ -103,6 +111,62 @@ static int frontend_bus_id(char bus_id[B
   59.35  	return 0;
   59.36  }
   59.37  
   59.38 +
   59.39 +static int read_otherend_details(struct xenbus_device *xendev,
   59.40 +				 char *id_node, char *path_node)
   59.41 +{
   59.42 +	int err = xenbus_gather(NULL, xendev->nodename,
   59.43 +				id_node, "%i", &xendev->otherend_id,
   59.44 +				path_node, NULL, &xendev->otherend,
   59.45 +				NULL);
   59.46 +	if (err) {
   59.47 +		xenbus_dev_fatal(xendev, err,
   59.48 +				 "reading other end details from %s",
   59.49 +				 xendev->nodename);
   59.50 +		return err;
   59.51 +	}
   59.52 +	if (strlen(xendev->otherend) == 0 ||
   59.53 +	    !xenbus_exists(NULL, xendev->otherend, "")) {
   59.54 +		xenbus_dev_fatal(xendev, -ENOENT, "missing other end from %s",
   59.55 +				 xendev->nodename);
   59.56 +		kfree(xendev->otherend);
   59.57 +		xendev->otherend = NULL;
   59.58 +		return -ENOENT;
   59.59 +	}
   59.60 +
   59.61 +	return 0;
   59.62 +}
   59.63 +
   59.64 +
   59.65 +static int read_backend_details(struct xenbus_device *xendev)
   59.66 +{
   59.67 +	return read_otherend_details(xendev, "backend-id", "backend");
   59.68 +}
   59.69 +
   59.70 +
   59.71 +static int read_frontend_details(struct xenbus_device *xendev)
   59.72 +{
   59.73 +	return read_otherend_details(xendev, "frontend-id", "frontend");
   59.74 +}
   59.75 +
   59.76 +
   59.77 +static void free_otherend_details(struct xenbus_device *dev)
   59.78 +{
   59.79 +	kfree(dev->otherend);
   59.80 +	dev->otherend = NULL;
   59.81 +}
   59.82 +
   59.83 +
   59.84 +static void free_otherend_watch(struct xenbus_device *dev)
   59.85 +{
   59.86 +	if (dev->otherend_watch.node) {
   59.87 +		unregister_xenbus_watch(&dev->otherend_watch);
   59.88 +		kfree(dev->otherend_watch.node);
   59.89 +		dev->otherend_watch.node = NULL;
   59.90 +	}
   59.91 +}
   59.92 +
   59.93 +
   59.94  /* Bus type for frontend drivers. */
   59.95  static int xenbus_probe_frontend(const char *type, const char *name);
   59.96  static struct xen_bus_type xenbus_frontend = {
   59.97 @@ -165,6 +229,8 @@ static int xenbus_hotplug_backend(struct
   59.98  	int i = 0;
   59.99  	int length = 0;
  59.100  
  59.101 +	DPRINTK("");
  59.102 +
  59.103  	if (dev == NULL)
  59.104  		return -ENODEV;
  59.105  
  59.106 @@ -211,20 +277,88 @@ static struct xen_bus_type xenbus_backen
  59.107  	},
  59.108  };
  59.109  
  59.110 +
  59.111 +static void otherend_changed(struct xenbus_watch *watch,
  59.112 +			     const char **vec, unsigned int len)
  59.113 +{
  59.114 +	struct xenbus_device *dev =
  59.115 +		container_of(watch, struct xenbus_device, otherend_watch);
  59.116 +	struct xenbus_driver *drv = to_xenbus_driver(dev->dev.driver);
  59.117 +	XenbusState state;
  59.118 +
  59.119 +	/* Protect us against watches firing on old details when the otherend
  59.120 +	   details change, say immediately after a resume. */
  59.121 +	if (!dev->otherend ||
  59.122 +	    strncmp(dev->otherend, vec[XS_WATCH_PATH],
  59.123 +		    strlen(dev->otherend))) {
  59.124 +		DPRINTK("Ignoring watch at %s", vec[XS_WATCH_PATH]);
  59.125 +		return;
  59.126 +	}
  59.127 +
  59.128 +	state = xenbus_read_driver_state(dev->otherend);
  59.129 +
  59.130 +	DPRINTK("state is %d, %s, %s",
  59.131 +		state, dev->otherend_watch.node, vec[XS_WATCH_PATH]);
  59.132 +	if (drv->otherend_changed)
  59.133 +		drv->otherend_changed(dev, state);
  59.134 +}
  59.135 +
  59.136 +
  59.137 +static int talk_to_otherend(struct xenbus_device *dev)
  59.138 +{
  59.139 +	struct xenbus_driver *drv = to_xenbus_driver(dev->dev.driver);
  59.140 +	int err;
  59.141 +
  59.142 +	free_otherend_watch(dev);
  59.143 +	free_otherend_details(dev);
  59.144 +
  59.145 +	err = drv->read_otherend_details(dev);
  59.146 +	if (err)
  59.147 +		return err;
  59.148 +
  59.149 +	return xenbus_watch_path2(dev, dev->otherend, "state",
  59.150 +				  &dev->otherend_watch, otherend_changed);
  59.151 +}
  59.152 +
  59.153 +
  59.154  static int xenbus_dev_probe(struct device *_dev)
  59.155  {
  59.156  	struct xenbus_device *dev = to_xenbus_device(_dev);
  59.157  	struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
  59.158  	const struct xenbus_device_id *id;
  59.159 +	int err;
  59.160  
  59.161 -	if (!drv->probe)
  59.162 -		return -ENODEV;
  59.163 +	DPRINTK("");
  59.164 +
  59.165 +	err = talk_to_otherend(dev);
  59.166 +	if (err) {
  59.167 +		printk(KERN_WARNING
  59.168 +		       "xenbus_probe: talk_to_otherend on %s failed.\n",
  59.169 +		       dev->nodename);
  59.170 +		return err;
  59.171 +	}
  59.172 +
  59.173 +	if (!drv->probe) {
  59.174 +		err = -ENODEV;
  59.175 +		goto fail;
  59.176 +	}
  59.177  
  59.178  	id = match_device(drv->ids, dev);
  59.179 -	if (!id)
  59.180 -		return -ENODEV;
  59.181 +	if (!id) {
  59.182 +		err = -ENODEV;
  59.183 +		goto fail;
  59.184 +	}
  59.185  
  59.186 -	return drv->probe(dev, id);
  59.187 +	err = drv->probe(dev, id);
  59.188 +	if (err)
  59.189 +		goto fail;
  59.190 +
  59.191 +	return 0;
  59.192 +fail:
  59.193 +	xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename);
  59.194 +	xenbus_switch_state(dev, NULL, XenbusStateClosed);
  59.195 +	return -ENODEV;
  59.196 +	
  59.197  }
  59.198  
  59.199  static int xenbus_dev_remove(struct device *_dev)
  59.200 @@ -232,9 +366,16 @@ static int xenbus_dev_remove(struct devi
  59.201  	struct xenbus_device *dev = to_xenbus_device(_dev);
  59.202  	struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
  59.203  
  59.204 -	if (!drv->remove)
  59.205 -		return 0;
  59.206 -	return drv->remove(dev);
  59.207 +	DPRINTK("");
  59.208 +
  59.209 +	free_otherend_watch(dev);
  59.210 +	free_otherend_details(dev);
  59.211 +
  59.212 +	if (drv->remove)
  59.213 +		drv->remove(dev);
  59.214 +
  59.215 +	xenbus_switch_state(dev, NULL, XenbusStateClosed);
  59.216 +	return 0;
  59.217  }
  59.218  
  59.219  static int xenbus_register_driver_common(struct xenbus_driver *drv,
  59.220 @@ -254,16 +395,21 @@ static int xenbus_register_driver_common
  59.221  	return ret;
  59.222  }
  59.223  
  59.224 -int xenbus_register_driver(struct xenbus_driver *drv)
  59.225 +int xenbus_register_frontend(struct xenbus_driver *drv)
  59.226  {
  59.227 +	drv->read_otherend_details = read_backend_details;
  59.228 +
  59.229  	return xenbus_register_driver_common(drv, &xenbus_frontend);
  59.230  }
  59.231 -EXPORT_SYMBOL(xenbus_register_driver);
  59.232 +EXPORT_SYMBOL(xenbus_register_frontend);
  59.233  
  59.234  int xenbus_register_backend(struct xenbus_driver *drv)
  59.235  {
  59.236 +	drv->read_otherend_details = read_frontend_details;
  59.237 +
  59.238  	return xenbus_register_driver_common(drv, &xenbus_backend);
  59.239  }
  59.240 +EXPORT_SYMBOL(xenbus_register_backend);
  59.241  
  59.242  void xenbus_unregister_driver(struct xenbus_driver *drv)
  59.243  {
  59.244 @@ -305,6 +451,8 @@ static int cleanup_dev(struct device *de
  59.245  	struct xb_find_info *info = data;
  59.246  	int len = strlen(info->nodename);
  59.247  
  59.248 +	DPRINTK("%s", info->nodename);
  59.249 +
  59.250  	if (!strncmp(xendev->nodename, info->nodename, len)) {
  59.251  		info->dev = xendev;
  59.252  		get_device(dev);
  59.253 @@ -327,12 +475,15 @@ static void xenbus_cleanup_devices(const
  59.254  	} while (info.dev);
  59.255  }
  59.256  
  59.257 -static void xenbus_release_device(struct device *dev)
  59.258 +static void xenbus_dev_free(struct xenbus_device *xendev)
  59.259 +{
  59.260 +	kfree(xendev);
  59.261 +}
  59.262 +
  59.263 +static void xenbus_dev_release(struct device *dev)
  59.264  {
  59.265  	if (dev) {
  59.266 -		struct xenbus_device *xendev = to_xenbus_device(dev);
  59.267 -
  59.268 -		kfree(xendev);
  59.269 +		xenbus_dev_free(to_xenbus_device(dev));
  59.270  	}
  59.271  }
  59.272  
  59.273 @@ -369,13 +520,31 @@ static ssize_t xendev_show_devtype(struc
  59.274  }
  59.275  DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL);
  59.276  
  59.277 +
  59.278  static int xenbus_probe_node(struct xen_bus_type *bus,
  59.279  			     const char *type,
  59.280  			     const char *nodename)
  59.281  {
  59.282 +#define CHECK_FAIL				\
  59.283 +	do {					\
  59.284 +		if (err)			\
  59.285 +			goto fail;		\
  59.286 +	}					\
  59.287 +	while (0)				\
  59.288 +
  59.289 +
  59.290  	int err;
  59.291  	struct xenbus_device *xendev;
  59.292 -	unsigned int stringlen;
  59.293 +	size_t stringlen;
  59.294 +	char *tmpstring;
  59.295 +
  59.296 +	XenbusState state = xenbus_read_driver_state(nodename);
  59.297 +
  59.298 +	if (state != XenbusStateInitialising) {
  59.299 +		/* Device is not new, so ignore it.  This can happen if a
  59.300 +		   device is going away after switching to Closed.  */
  59.301 +		return 0;
  59.302 +	}
  59.303  
  59.304  	stringlen = strlen(nodename) + 1 + strlen(type) + 1;
  59.305  	xendev = kmalloc(sizeof(*xendev) + stringlen, GFP_KERNEL);
  59.306 @@ -384,31 +553,35 @@ static int xenbus_probe_node(struct xen_
  59.307  	memset(xendev, 0, sizeof(*xendev));
  59.308  
  59.309  	/* Copy the strings into the extra space. */
  59.310 -	xendev->nodename = (char *)(xendev + 1);
  59.311 -	strcpy(xendev->nodename, nodename);
  59.312 -	xendev->devicetype = xendev->nodename + strlen(xendev->nodename) + 1;
  59.313 -	strcpy(xendev->devicetype, type);
  59.314 +
  59.315 +	tmpstring = (char *)(xendev + 1);
  59.316 +	strcpy(tmpstring, nodename);
  59.317 +	xendev->nodename = tmpstring;
  59.318 +
  59.319 +	tmpstring += strlen(tmpstring) + 1;
  59.320 +	strcpy(tmpstring, type);
  59.321 +	xendev->devicetype = tmpstring;
  59.322  
  59.323  	xendev->dev.parent = &bus->dev;
  59.324  	xendev->dev.bus = &bus->bus;
  59.325 -	xendev->dev.release = xenbus_release_device;
  59.326 +	xendev->dev.release = xenbus_dev_release;
  59.327  
  59.328  	err = bus->get_bus_id(xendev->dev.bus_id, xendev->nodename);
  59.329 -	if (err) {
  59.330 -		kfree(xendev);
  59.331 -		return err;
  59.332 -	}
  59.333 +	CHECK_FAIL;
  59.334  
  59.335  	/* Register with generic device framework. */
  59.336  	err = device_register(&xendev->dev);
  59.337 -	if (err) {
  59.338 -		printk("XENBUS: Registering %s device %s: error %i\n",
  59.339 -		       bus->bus.name, xendev->dev.bus_id, err);
  59.340 -		kfree(xendev);
  59.341 -	} else {
  59.342 -		device_create_file(&xendev->dev, &dev_attr_nodename);
  59.343 -		device_create_file(&xendev->dev, &dev_attr_devtype);
  59.344 -	}
  59.345 +	CHECK_FAIL;
  59.346 +
  59.347 +	device_create_file(&xendev->dev, &dev_attr_nodename);
  59.348 +	device_create_file(&xendev->dev, &dev_attr_devtype);
  59.349 +
  59.350 +	return 0;
  59.351 +
  59.352 +#undef CHECK_FAIL
  59.353 +
  59.354 +fail:
  59.355 +	xenbus_dev_free(xendev);
  59.356  	return err;
  59.357  }
  59.358  
  59.359 @@ -422,6 +595,8 @@ static int xenbus_probe_frontend(const c
  59.360  	if (!nodename)
  59.361  		return -ENOMEM;
  59.362  	
  59.363 +	DPRINTK("%s", nodename);
  59.364 +
  59.365  	err = xenbus_probe_node(&xenbus_frontend, type, nodename);
  59.366  	kfree(nodename);
  59.367  	return err;
  59.368 @@ -439,6 +614,8 @@ static int xenbus_probe_backend_unit(con
  59.369  	if (!nodename)
  59.370  		return -ENOMEM;
  59.371  
  59.372 +	DPRINTK("%s\n", nodename);
  59.373 +
  59.374  	err = xenbus_probe_node(&xenbus_backend, type, nodename);
  59.375  	kfree(nodename);
  59.376  	return err;
  59.377 @@ -452,6 +629,8 @@ static int xenbus_probe_backend(const ch
  59.378  	char **dir;
  59.379  	unsigned int i, dir_n = 0;
  59.380  
  59.381 +	DPRINTK("");
  59.382 +
  59.383  	nodename = kasprintf("%s/%s/%s", xenbus_backend.root, type, domid);
  59.384  	if (!nodename)
  59.385  		return -ENOMEM;
  59.386 @@ -574,12 +753,16 @@ static void dev_changed(const char *node
  59.387  static void frontend_changed(struct xenbus_watch *watch,
  59.388  			     const char **vec, unsigned int len)
  59.389  {
  59.390 +	DPRINTK("");
  59.391 +
  59.392  	dev_changed(vec[XS_WATCH_PATH], &xenbus_frontend);
  59.393  }
  59.394  
  59.395  static void backend_changed(struct xenbus_watch *watch,
  59.396  			    const char **vec, unsigned int len)
  59.397  {
  59.398 +	DPRINTK("");
  59.399 +
  59.400  	dev_changed(vec[XS_WATCH_PATH], &xenbus_backend);
  59.401  }
  59.402  
  59.403 @@ -600,6 +783,8 @@ static int suspend_dev(struct device *de
  59.404  	struct xenbus_driver *drv;
  59.405  	struct xenbus_device *xdev;
  59.406  
  59.407 +	DPRINTK("");
  59.408 +
  59.409  	if (dev->driver == NULL)
  59.410  		return 0;
  59.411  	drv = to_xenbus_driver(dev->driver);
  59.412 @@ -607,33 +792,49 @@ static int suspend_dev(struct device *de
  59.413  	if (drv->suspend)
  59.414  		err = drv->suspend(xdev);
  59.415  	if (err)
  59.416 -		printk("xenbus: suspend %s failed: %i\n", dev->bus_id, err);
  59.417 +		printk(KERN_WARNING
  59.418 +		       "xenbus: suspend %s failed: %i\n", dev->bus_id, err);
  59.419  	return 0;
  59.420  }
  59.421  
  59.422  static int resume_dev(struct device *dev, void *data)
  59.423  {
  59.424 -	int err = 0;
  59.425 +	int err;
  59.426  	struct xenbus_driver *drv;
  59.427  	struct xenbus_device *xdev;
  59.428  
  59.429 +	DPRINTK("");
  59.430 +
  59.431  	if (dev->driver == NULL)
  59.432  		return 0;
  59.433  	drv = to_xenbus_driver(dev->driver);
  59.434  	xdev = container_of(dev, struct xenbus_device, dev);
  59.435 +
  59.436 +	err = talk_to_otherend(xdev);
  59.437 +	if (err) {
  59.438 +		printk(KERN_WARNING
  59.439 +		       "xenbus: resume (talk_to_otherend) %s failed: %i\n",
  59.440 +		       dev->bus_id, err);
  59.441 +		return err;
  59.442 +	}
  59.443 +
  59.444  	if (drv->resume)
  59.445  		err = drv->resume(xdev);
  59.446  	if (err)
  59.447 -		printk("xenbus: resume %s failed: %i\n", dev->bus_id, err);
  59.448 -	return 0;
  59.449 +		printk(KERN_WARNING
  59.450 +		       "xenbus: resume %s failed: %i\n", dev->bus_id, err);
  59.451 +	return err;
  59.452  }
  59.453  
  59.454  void xenbus_suspend(void)
  59.455  {
  59.456 +	DPRINTK("");
  59.457 +
  59.458  	bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
  59.459  	bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, suspend_dev);
  59.460  	xs_suspend();
  59.461  }
  59.462 +EXPORT_SYMBOL(xenbus_suspend);
  59.463  
  59.464  void xenbus_resume(void)
  59.465  {
  59.466 @@ -642,6 +843,7 @@ void xenbus_resume(void)
  59.467  	bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev);
  59.468  	bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, resume_dev);
  59.469  }
  59.470 +EXPORT_SYMBOL(xenbus_resume);
  59.471  
  59.472  
  59.473  /* A flag to determine if xenstored is 'ready' (i.e. has started) */
  59.474 @@ -652,7 +854,7 @@ int register_xenstore_notifier(struct no
  59.475  {
  59.476  	int ret = 0;
  59.477  
  59.478 -        if(xenstored_ready > 0) 
  59.479 +	if (xenstored_ready > 0) 
  59.480  		ret = nb->notifier_call(nb, 0, NULL);
  59.481  	else 
  59.482  		notifier_chain_register(&xenstore_chain, nb);
  59.483 @@ -682,9 +884,7 @@ void xenbus_probe(void *unused)
  59.484  	register_xenbus_watch(&be_watch);
  59.485  
  59.486  	/* Notify others that xenstore is up */
  59.487 -	notifier_call_chain(&xenstore_chain, 0, 0);
  59.488 -
  59.489 -	return;
  59.490 +	notifier_call_chain(&xenstore_chain, 0, NULL);
  59.491  }
  59.492  
  59.493  
  59.494 @@ -716,10 +916,10 @@ static int __init xenbus_probe_init(void
  59.495  {
  59.496  	int err = 0, dom0;
  59.497  
  59.498 -	printk("xenbus_probe_init\n");
  59.499 +	DPRINTK("");
  59.500  
  59.501  	if (xen_init() < 0) {
  59.502 -		printk("xen_init failed\n");
  59.503 +		DPRINTK("failed");
  59.504  		return -ENODEV;
  59.505  	}
  59.506  
  59.507 @@ -773,7 +973,8 @@ static int __init xenbus_probe_init(void
  59.508  	/* Initialize the interface to xenstore. */
  59.509  	err = xs_init(); 
  59.510  	if (err) {
  59.511 -		printk("XENBUS: Error initializing xenstore comms: %i\n", err);
  59.512 +		printk(KERN_WARNING
  59.513 +		       "XENBUS: Error initializing xenstore comms: %i\n", err);
  59.514  		return err; 
  59.515  	}
  59.516  
    60.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Fri Nov 18 23:06:09 2005 -0600
    60.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Fri Nov 18 23:16:29 2005 -0600
    60.3 @@ -199,6 +199,7 @@ static void *xs_talkv(struct xenbus_tran
    60.4  	int err;
    60.5  
    60.6  	msg.tx_id = (u32)(unsigned long)t;
    60.7 +	msg.req_id = 0;
    60.8  	msg.type = type;
    60.9  	msg.len = 0;
   60.10  	for (i = 0; i < num_vecs; i++)
   60.11 @@ -517,89 +518,6 @@ int xenbus_printf(struct xenbus_transact
   60.12  }
   60.13  EXPORT_SYMBOL(xenbus_printf);
   60.14  
   60.15 -/**
   60.16 - * Return the path to the error node for the given device, or NULL on failure.
   60.17 - * If the value returned is non-NULL, then it is the caller's to kfree.
   60.18 - */
   60.19 -static char *error_path(struct xenbus_device *dev)
   60.20 -{
   60.21 -	char *path_buffer = kmalloc(strlen("error/") + strlen(dev->nodename) +
   60.22 -				    1, GFP_KERNEL);
   60.23 -	if (path_buffer == NULL) {
   60.24 -		return NULL;
   60.25 -	}
   60.26 -
   60.27 -	strcpy(path_buffer, "error/");
   60.28 -	strcpy(path_buffer + strlen("error/"), dev->nodename);
   60.29 -
   60.30 -	return path_buffer;
   60.31 -}
   60.32 -
   60.33 -/* Report a (negative) errno into the store, with explanation. */
   60.34 -void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt, ...)
   60.35 -{
   60.36 -	va_list ap;
   60.37 -	int ret;
   60.38 -	unsigned int len;
   60.39 -	char *printf_buffer = NULL, *path_buffer = NULL;
   60.40 -
   60.41 -	printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL);
   60.42 -	if (printf_buffer == NULL)
   60.43 -		goto fail;
   60.44 -
   60.45 -	len = sprintf(printf_buffer, "%i ", -err);
   60.46 -	va_start(ap, fmt);
   60.47 -	ret = vsnprintf(printf_buffer+len, PRINTF_BUFFER_SIZE-len, fmt, ap);
   60.48 -	va_end(ap);
   60.49 -
   60.50 -	BUG_ON(len + ret > PRINTF_BUFFER_SIZE-1);
   60.51 -	dev->has_error = 1;
   60.52 -
   60.53 -	path_buffer = error_path(dev);
   60.54 -
   60.55 -	if (path_buffer == NULL) {
   60.56 -		printk("xenbus: failed to write error node for %s (%s)\n",
   60.57 -		       dev->nodename, printf_buffer);
   60.58 -		goto fail;
   60.59 -	}
   60.60 -
   60.61 -	if (xenbus_write(NULL, path_buffer, "error", printf_buffer) != 0) {
   60.62 -		printk("xenbus: failed to write error node for %s (%s)\n",
   60.63 -		       dev->nodename, printf_buffer);
   60.64 -		goto fail;
   60.65 -	}
   60.66 -
   60.67 -fail:
   60.68 -	if (printf_buffer)
   60.69 -		kfree(printf_buffer);
   60.70 -	if (path_buffer)
   60.71 -		kfree(path_buffer);
   60.72 -}
   60.73 -EXPORT_SYMBOL(xenbus_dev_error);
   60.74 -
   60.75 -/* Clear any error. */
   60.76 -void xenbus_dev_ok(struct xenbus_device *dev)
   60.77 -{
   60.78 -	if (dev->has_error) {
   60.79 -		char *path_buffer = error_path(dev);
   60.80 -
   60.81 -		if (path_buffer == NULL) {
   60.82 -			printk("xenbus: failed to clear error node for %s\n",
   60.83 -			       dev->nodename);
   60.84 -			return;
   60.85 -		}
   60.86 -
   60.87 -		if (xenbus_rm(NULL, path_buffer, "error") != 0)
   60.88 -			printk("xenbus: failed to clear error node for %s\n",
   60.89 -			       dev->nodename);
   60.90 -		else
   60.91 -			dev->has_error = 0;
   60.92 -
   60.93 -		kfree(path_buffer);
   60.94 -	}
   60.95 -}
   60.96 -EXPORT_SYMBOL(xenbus_dev_ok);
   60.97 -	
   60.98  /* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
   60.99  int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...)
  60.100  {
    61.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypervisor.h	Fri Nov 18 23:06:09 2005 -0600
    61.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypervisor.h	Fri Nov 18 23:16:29 2005 -0600
    61.3 @@ -39,15 +39,11 @@
    61.4  #include <asm/ptrace.h>
    61.5  #include <asm/page.h>
    61.6  #if defined(__i386__)
    61.7 -# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
    61.8  #  ifdef CONFIG_X86_PAE
    61.9  #   include <asm-generic/pgtable-nopud.h>
   61.10  #  else
   61.11  #   include <asm-generic/pgtable-nopmd.h>
   61.12  #  endif
   61.13 -# else
   61.14 -#  define pud_t pgd_t
   61.15 -# endif
   61.16  #endif
   61.17  
   61.18  extern shared_info_t *HYPERVISOR_shared_info;
   61.19 @@ -113,22 +109,6 @@ void xen_tlb_flush_mask(cpumask_t *mask)
   61.20  void xen_invlpg_mask(cpumask_t *mask, unsigned long ptr);
   61.21  #endif
   61.22  
   61.23 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
   61.24 -/* 
   61.25 -** XXX SMH: 2.4 doesn't have percpu.h (or support SMP guests) so just 
   61.26 -** include sufficient #defines to allow the below to build. 
   61.27 -*/
   61.28 -#define DEFINE_PER_CPU(type, name) \
   61.29 -    __typeof__(type) per_cpu__##name
   61.30 -
   61.31 -#define per_cpu(var, cpu)           (*((void)cpu, &per_cpu__##var))
   61.32 -#define __get_cpu_var(var)          per_cpu__##var
   61.33 -#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
   61.34 -
   61.35 -#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var)
   61.36 -#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var)
   61.37 -#endif /* linux < 2.6.0 */
   61.38 -
   61.39  /* Returns zero on success else negative errno. */
   61.40  int xen_create_contiguous_region(
   61.41      unsigned long vstart, unsigned int order, unsigned int address_bits);
    62.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/io.h	Fri Nov 18 23:06:09 2005 -0600
    62.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/io.h	Fri Nov 18 23:16:29 2005 -0600
    62.3 @@ -228,7 +228,7 @@ static inline void memcpy_toio(volatile 
    62.4   * used as the IO-area pointer (it can be iounmapped as well, so the
    62.5   * analogy with PCI is quite large):
    62.6   */
    62.7 -#define __ISA_IO_base ((char __iomem *)(PAGE_OFFSET))
    62.8 +#define __ISA_IO_base ((char __iomem *)(fix_to_virt(FIX_ISAMAP_BEGIN)))
    62.9  
   62.10  #define isa_readb(a) readb(__ISA_IO_base + (a))
   62.11  #define isa_readw(a) readw(__ISA_IO_base + (a))
    63.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/page.h	Fri Nov 18 23:06:09 2005 -0600
    63.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/page.h	Fri Nov 18 23:16:29 2005 -0600
    63.3 @@ -86,6 +86,11 @@ static inline unsigned long mfn_to_pfn(u
    63.4  	return pfn;
    63.5  }
    63.6  
    63.7 +static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
    63.8 +{
    63.9 +	phys_to_machine_mapping[pfn] = mfn;
   63.10 +}
   63.11 +
   63.12  /* Definitions for machine and pseudophysical addresses. */
   63.13  #ifdef CONFIG_X86_PAE
   63.14  typedef unsigned long long paddr_t;
    64.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h	Fri Nov 18 23:06:09 2005 -0600
    64.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h	Fri Nov 18 23:16:29 2005 -0600
    64.3 @@ -438,9 +438,8 @@ void make_pages_writable(void *va, unsig
    64.4  
    64.5  #define arbitrary_virt_to_machine(__va)					\
    64.6  ({									\
    64.7 -	pte_t *__pte = virt_to_ptep(__va);				\
    64.8 -	maddr_t __pa = (maddr_t)pte_mfn(*__pte) << PAGE_SHIFT;		\
    64.9 -	__pa | ((unsigned long)(__va) & (PAGE_SIZE-1));			\
   64.10 +	maddr_t m = (maddr_t)pte_mfn(*virt_to_ptep(__va)) << PAGE_SHIFT;\
   64.11 +	m | ((unsigned long)(__va) & (PAGE_SIZE-1));			\
   64.12  })
   64.13  
   64.14  #endif /* !__ASSEMBLY__ */
   64.15 @@ -450,11 +449,11 @@ void make_pages_writable(void *va, unsig
   64.16  #endif /* !CONFIG_DISCONTIGMEM */
   64.17  
   64.18  int direct_remap_pfn_range(struct vm_area_struct *vma,
   64.19 -                            unsigned long address, 
   64.20 -                            unsigned long mfn,
   64.21 -                            unsigned long size, 
   64.22 -                            pgprot_t prot,
   64.23 -                            domid_t  domid);
   64.24 +                           unsigned long address, 
   64.25 +                           unsigned long mfn,
   64.26 +                           unsigned long size, 
   64.27 +                           pgprot_t prot,
   64.28 +                           domid_t  domid);
   64.29  int direct_kernel_remap_pfn_range(unsigned long address, 
   64.30  				  unsigned long mfn,
   64.31  				  unsigned long size, 
   64.32 @@ -462,7 +461,7 @@ int direct_kernel_remap_pfn_range(unsign
   64.33  				  domid_t  domid);
   64.34  int create_lookup_pte_addr(struct mm_struct *mm,
   64.35                             unsigned long address,
   64.36 -                           unsigned long *ptep);
   64.37 +                           uint64_t *ptep);
   64.38  int touch_pte_range(struct mm_struct *mm,
   64.39                      unsigned long address,
   64.40                      unsigned long size);
    65.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/io.h	Fri Nov 18 23:06:09 2005 -0600
    65.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/io.h	Fri Nov 18 23:16:29 2005 -0600
    65.3 @@ -298,7 +298,7 @@ void memset_io(volatile void __iomem *a,
    65.4   * used as the IO-area pointer (it can be iounmapped as well, so the
    65.5   * analogy with PCI is quite large):
    65.6   */
    65.7 -#define __ISA_IO_base ((char __iomem *)(PAGE_OFFSET))
    65.8 +#define __ISA_IO_base ((char __iomem *)(fix_to_virt(FIX_ISAMAP_BEGIN)))
    65.9  
   65.10  #define isa_readb(a) readb(__ISA_IO_base + (a))
   65.11  #define isa_readw(a) readw(__ISA_IO_base + (a))
    66.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/page.h	Fri Nov 18 23:06:09 2005 -0600
    66.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/page.h	Fri Nov 18 23:16:29 2005 -0600
    66.3 @@ -88,6 +88,11 @@ static inline unsigned long mfn_to_pfn(u
    66.4  	return pfn;
    66.5  }
    66.6  
    66.7 +static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
    66.8 +{
    66.9 +	phys_to_machine_mapping[pfn] = mfn;
   66.10 +}
   66.11 +
   66.12  /* Definitions for machine and pseudophysical addresses. */
   66.13  typedef unsigned long paddr_t;
   66.14  typedef unsigned long maddr_t;
    67.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h	Fri Nov 18 23:06:09 2005 -0600
    67.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h	Fri Nov 18 23:16:29 2005 -0600
    67.3 @@ -29,9 +29,8 @@ extern void xen_init_pt(void);
    67.4  
    67.5  #define arbitrary_virt_to_machine(__va)					\
    67.6  ({									\
    67.7 -	pte_t *__pte = virt_to_ptep(__va);				\
    67.8 -	unsigned long __pa = (*(unsigned long *)__pte) & PAGE_MASK;	\
    67.9 -	__pa | ((unsigned long)(__va) & (PAGE_SIZE-1));			\
   67.10 +	maddr_t m = (maddr_t)pte_mfn(*virt_to_ptep(__va)) << PAGE_SHIFT;\
   67.11 +	m | ((unsigned long)(__va) & (PAGE_SIZE-1));			\
   67.12  })
   67.13  #endif
   67.14  
   67.15 @@ -541,7 +540,7 @@ int direct_kernel_remap_pfn_range(unsign
   67.16  
   67.17  int create_lookup_pte_addr(struct mm_struct *mm,
   67.18                             unsigned long address,
   67.19 -                           unsigned long *ptep);
   67.20 +                           uint64_t *ptep);
   67.21  
   67.22  int touch_pte_range(struct mm_struct *mm,
   67.23                      unsigned long address,
    68.1 --- a/linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h	Fri Nov 18 23:06:09 2005 -0600
    68.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h	Fri Nov 18 23:16:29 2005 -0600
    68.3 @@ -55,6 +55,11 @@ typedef struct privcmd_mmapbatch {
    68.4  	unsigned long *arr; /* array of mfns - top nibble set on err */
    68.5  } privcmd_mmapbatch_t; 
    68.6  
    68.7 +typedef struct privcmd_m2pmfns { 
    68.8 +	int num;    /* max number of mfns to return */
    68.9 +	unsigned long *arr; /* array of mfns */
   68.10 +} privcmd_m2pmfns_t; 
   68.11 +
   68.12  typedef struct privcmd_blkmsg
   68.13  {
   68.14  	unsigned long op;
   68.15 @@ -69,12 +74,11 @@ typedef struct privcmd_blkmsg
   68.16   */
   68.17  #define IOCTL_PRIVCMD_HYPERCALL					\
   68.18  	_IOC(_IOC_NONE, 'P', 0, sizeof(privcmd_hypercall_t))
   68.19 -
   68.20  #define IOCTL_PRIVCMD_MMAP					\
   68.21  	_IOC(_IOC_NONE, 'P', 2, sizeof(privcmd_mmap_t))
   68.22  #define IOCTL_PRIVCMD_MMAPBATCH					\
   68.23  	_IOC(_IOC_NONE, 'P', 3, sizeof(privcmd_mmapbatch_t))
   68.24 -#define IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN			\
   68.25 +#define IOCTL_PRIVCMD_GET_MACH2PHYS_MFNS			\
   68.26  	_IOC(_IOC_READ, 'P', 4, sizeof(unsigned long))
   68.27  
   68.28  #endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
    69.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/net_driver_util.h	Fri Nov 18 23:16:29 2005 -0600
    69.3 @@ -0,0 +1,56 @@
    69.4 +/*****************************************************************************
    69.5 + *
    69.6 + * Utility functions for Xen network devices.
    69.7 + *
    69.8 + * Copyright (c) 2005 XenSource Ltd.
    69.9 + * 
   69.10 + * This file may be distributed separately from the Linux kernel, or
   69.11 + * incorporated into other software packages, subject to the following
   69.12 + * license:
   69.13 + * 
   69.14 + * Permission is hereby granted, free of charge, to any person obtaining a
   69.15 + * copy of this source file (the "Software"), to deal in the Software without
   69.16 + * restriction, including without limitation the rights to use, copy, modify,
   69.17 + * merge, publish, distribute, sublicense, and/or sell copies of the Software,
   69.18 + * and to permit persons to whom the Software is furnished to do so, subject
   69.19 + * to the following conditions:
   69.20 + * 
   69.21 + * The above copyright notice and this permission notice shall be included in
   69.22 + * all copies or substantial portions of the Software.
   69.23 + * 
   69.24 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   69.25 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   69.26 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   69.27 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   69.28 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   69.29 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   69.30 + * DEALINGS IN THE SOFTWARE.
   69.31 + */
   69.32 +
   69.33 +#ifndef _ASM_XEN_NET_DRIVER_UTIL_H
   69.34 +#define _ASM_XEN_NET_DRIVER_UTIL_H
   69.35 +
   69.36 +
   69.37 +#include <asm-xen/xenbus.h>
   69.38 +
   69.39 +
   69.40 +/**
   69.41 + * Read the 'mac' node at the given device's node in the store, and parse that
   69.42 + * as colon-separated octets, placing result the given mac array.  mac must be
   69.43 + * a preallocated array of length ETH_ALEN (as declared in linux/if_ether.h).
   69.44 + * Return 0 on success, or -errno on error.
   69.45 + */
   69.46 +int xen_net_read_mac(struct xenbus_device *dev, u8 mac[]);
   69.47 +
   69.48 +
   69.49 +#endif /* _ASM_XEN_NET_DRIVER_UTIL_H */
   69.50 +
   69.51 +/*
   69.52 + * Local variables:
   69.53 + *  c-file-style: "linux"
   69.54 + *  indent-tabs-mode: t
   69.55 + *  c-indent-level: 8
   69.56 + *  c-basic-offset: 8
   69.57 + *  tab-width: 8
   69.58 + * End:
   69.59 + */
    70.1 --- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h	Fri Nov 18 23:06:09 2005 -0600
    70.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h	Fri Nov 18 23:16:29 2005 -0600
    70.3 @@ -35,10 +35,48 @@
    70.4  #include <asm/semaphore.h>
    70.5  #include <asm-xen/xen-public/io/xs_wire.h>
    70.6  
    70.7 +/* Register callback to watch this node. */
    70.8 +struct xenbus_watch
    70.9 +{
   70.10 +	struct list_head list;
   70.11 +
   70.12 +	/* Path being watched. */
   70.13 +	const char *node;
   70.14 +
   70.15 +	/* Callback (executed in a process context with no locks held). */
   70.16 +	void (*callback)(struct xenbus_watch *,
   70.17 +			 const char **vec, unsigned int len);
   70.18 +};
   70.19 +
   70.20 +
   70.21 +/* The state of either end of the Xenbus, i.e. the current communication
   70.22 +   status of initialisation across the bus.  States here imply nothing about
   70.23 +   the state of the connection between the driver and the kernel's device
   70.24 +   layers.  */
   70.25 +typedef enum
   70.26 +{
   70.27 +  XenbusStateUnknown      = 0,
   70.28 +  XenbusStateInitialising = 1,
   70.29 +  XenbusStateInitWait     = 2,  /* Finished early initialisation, but waiting
   70.30 +                                   for information from the peer or hotplug
   70.31 +				   scripts. */
   70.32 +  XenbusStateInitialised  = 3,  /* Initialised and waiting for a connection
   70.33 +				   from the peer. */
   70.34 +  XenbusStateConnected    = 4,
   70.35 +  XenbusStateClosing      = 5,  /* The device is being closed due to an error
   70.36 +				   or an unplug event. */
   70.37 +  XenbusStateClosed       = 6
   70.38 +
   70.39 +} XenbusState;
   70.40 +
   70.41 +
   70.42  /* A xenbus device. */
   70.43  struct xenbus_device {
   70.44 -	char *devicetype;
   70.45 -	char *nodename;
   70.46 +	const char *devicetype;
   70.47 +	const char *nodename;
   70.48 +	const char *otherend;
   70.49 +	int otherend_id;
   70.50 +	struct xenbus_watch otherend_watch;
   70.51  	struct device dev;
   70.52  	int has_error;
   70.53  	void *data;
   70.54 @@ -62,11 +100,14 @@ struct xenbus_driver {
   70.55  	const struct xenbus_device_id *ids;
   70.56  	int (*probe)(struct xenbus_device *dev,
   70.57  		     const struct xenbus_device_id *id);
   70.58 +	void (*otherend_changed)(struct xenbus_device *dev,
   70.59 +				 XenbusState backend_state);
   70.60  	int (*remove)(struct xenbus_device *dev);
   70.61  	int (*suspend)(struct xenbus_device *dev);
   70.62  	int (*resume)(struct xenbus_device *dev);
   70.63  	int (*hotplug)(struct xenbus_device *, char **, int, char *, int);
   70.64  	struct device_driver driver;
   70.65 +	int (*read_otherend_details)(struct xenbus_device *dev);
   70.66  };
   70.67  
   70.68  static inline struct xenbus_driver *to_xenbus_driver(struct device_driver *drv)
   70.69 @@ -74,7 +115,7 @@ static inline struct xenbus_driver *to_x
   70.70  	return container_of(drv, struct xenbus_driver, driver);
   70.71  }
   70.72  
   70.73 -int xenbus_register_driver(struct xenbus_driver *drv);
   70.74 +int xenbus_register_frontend(struct xenbus_driver *drv);
   70.75  int xenbus_register_backend(struct xenbus_driver *drv);
   70.76  void xenbus_unregister_driver(struct xenbus_driver *drv);
   70.77  
   70.78 @@ -108,25 +149,6 @@ int xenbus_printf(struct xenbus_transact
   70.79   * sprintf-style type string, and pointer. Returns 0 or errno.*/
   70.80  int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...);
   70.81  
   70.82 -/* Report a (negative) errno into the store, with explanation. */
   70.83 -void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt,...);
   70.84 -
   70.85 -/* Clear any error. */
   70.86 -void xenbus_dev_ok(struct xenbus_device *dev);
   70.87 -
   70.88 -/* Register callback to watch this node. */
   70.89 -struct xenbus_watch
   70.90 -{
   70.91 -	struct list_head list;
   70.92 -
   70.93 -	/* Path being watched. */
   70.94 -	char *node;
   70.95 -
   70.96 -	/* Callback (executed in a process context with no locks held). */
   70.97 -	void (*callback)(struct xenbus_watch *,
   70.98 -			 const char **vec, unsigned int len);
   70.99 -};
  70.100 -
  70.101  /* notifer routines for when the xenstore comes up */
  70.102  int register_xenstore_notifier(struct notifier_block *nb);
  70.103  void unregister_xenstore_notifier(struct notifier_block *nb);
  70.104 @@ -153,6 +175,89 @@ void xenbus_resume(void);
  70.105  
  70.106  #define XENBUS_EXIST_ERR(err) ((err) == -ENOENT || (err) == -ERANGE)
  70.107  
  70.108 +
  70.109 +/**
  70.110 + * Register a watch on the given path, using the given xenbus_watch structure
  70.111 + * for storage, and the given callback function as the callback.  Return 0 on
  70.112 + * success, or -errno on error.  On success, the given path will be saved as
  70.113 + * watch->node, and remains the caller's to free.  On error, watch->node will
  70.114 + * be NULL, the device will switch to XenbusStateClosing, and the error will
  70.115 + * be saved in the store.
  70.116 + */
  70.117 +int xenbus_watch_path(struct xenbus_device *dev, const char *path,
  70.118 +		      struct xenbus_watch *watch, 
  70.119 +		      void (*callback)(struct xenbus_watch *,
  70.120 +				       const char **, unsigned int));
  70.121 +
  70.122 +
  70.123 +/**
  70.124 + * Register a watch on the given path/path2, using the given xenbus_watch
  70.125 + * structure for storage, and the given callback function as the callback.
  70.126 + * Return 0 on success, or -errno on error.  On success, the watched path
  70.127 + * (path/path2) will be saved as watch->node, and becomes the caller's to
  70.128 + * kfree().  On error, watch->node will be NULL, so the caller has nothing to
  70.129 + * free, the device will switch to XenbusStateClosing, and the error will be
  70.130 + * saved in the store.
  70.131 + */
  70.132 +int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
  70.133 +		       const char *path2, struct xenbus_watch *watch, 
  70.134 +		       void (*callback)(struct xenbus_watch *,
  70.135 +					const char **, unsigned int));
  70.136 +
  70.137 +
  70.138 +/**
  70.139 + * Advertise in the store a change of the given driver to the given new_state.
  70.140 + * Perform the change inside the given transaction xbt.  xbt may be NULL, in
  70.141 + * which case this is performed inside its own transaction.  Return 0 on
  70.142 + * success, or -errno on error.  On error, the device will switch to
  70.143 + * XenbusStateClosing, and the error will be saved in the store.
  70.144 + */
  70.145 +int xenbus_switch_state(struct xenbus_device *dev,
  70.146 +			struct xenbus_transaction *xbt,
  70.147 +			XenbusState new_state);
  70.148 +
  70.149 +
  70.150 +/**
  70.151 + * Grant access to the given ring_mfn to the peer of the given device.  Return
  70.152 + * 0 on success, or -errno on error.  On error, the device will switch to
  70.153 + * XenbusStateClosing, and the error will be saved in the store.
  70.154 + */
  70.155 +int xenbus_grant_ring(struct xenbus_device *dev, unsigned long ring_mfn);
  70.156 +
  70.157 +
  70.158 +/**
  70.159 + * Allocate an event channel for the given xenbus_device, assigning the newly
  70.160 + * created local port to *port.  Return 0 on success, or -errno on error.  On
  70.161 + * error, the device will switch to XenbusStateClosing, and the error will be
  70.162 + * saved in the store.
  70.163 + */
  70.164 +int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port);
  70.165 +
  70.166 +
  70.167 +/**
  70.168 + * Return the state of the driver rooted at the given store path, or
  70.169 + * XenbusStateClosed if no state can be read.
  70.170 + */
  70.171 +XenbusState xenbus_read_driver_state(const char *path);
  70.172 +
  70.173 +
  70.174 +/***
  70.175 + * Report the given negative errno into the store, along with the given
  70.176 + * formatted message.
  70.177 + */
  70.178 +void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt,
  70.179 +		      ...);
  70.180 +
  70.181 +
  70.182 +/***
  70.183 + * Equivalent to xenbus_dev_error(dev, err, fmt, args), followed by
  70.184 + * xenbus_switch_state(dev, NULL, XenbusStateClosing) to schedule an orderly
  70.185 + * closedown of this driver and its peer.
  70.186 + */
  70.187 +void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
  70.188 +		      ...);
  70.189 +
  70.190 +
  70.191  #endif /* _ASM_XEN_XENBUS_H */
  70.192  
  70.193  /*
    71.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/xencons.h	Fri Nov 18 23:16:29 2005 -0600
    71.3 @@ -0,0 +1,7 @@
    71.4 +#ifndef __ASM_XENCONS_H__
    71.5 +#define __ASM_XENCONS_H__
    71.6 +
    71.7 +void xencons_force_flush(void);
    71.8 +void xencons_resume(void);
    71.9 +
   71.10 +#endif /* __ASM_XENCONS_H__ */
    72.1 --- a/tools/Makefile	Fri Nov 18 23:06:09 2005 -0600
    72.2 +++ b/tools/Makefile	Fri Nov 18 23:16:29 2005 -0600
    72.3 @@ -11,6 +11,7 @@ SUBDIRS += xcutils
    72.4  SUBDIRS += firmware
    72.5  SUBDIRS += security
    72.6  SUBDIRS += console
    72.7 +SUBDIRS += xenmon
    72.8  ifeq ($(VTPM_TOOLS),y)
    72.9  SUBDIRS += vtpm_manager
   72.10  SUBDIRS += vtpm
    73.1 --- a/tools/blktap/blkif.c	Fri Nov 18 23:06:09 2005 -0600
    73.2 +++ b/tools/blktap/blkif.c	Fri Nov 18 23:16:29 2005 -0600
    73.3 @@ -108,8 +108,7 @@ void free_blkif(blkif_t *blkif)
    73.4          }
    73.5          pblkif = &curs->hash_next;
    73.6      }
    73.7 -    if (blkif != NULL)
    73.8 -        free(blkif);
    73.9 +    free(blkif);
   73.10  }
   73.11  
   73.12  void blkif_register_request_hook(blkif_t *blkif, char *name, 
    74.1 --- a/tools/blktap/parallax/blockstore.c	Fri Nov 18 23:06:09 2005 -0600
    74.2 +++ b/tools/blktap/parallax/blockstore.c	Fri Nov 18 23:16:29 2005 -0600
    74.3 @@ -604,8 +604,7 @@ void *readblock_indiv(int server, uint64
    74.4      return block;
    74.5  
    74.6      err:
    74.7 -    if (qe->block)
    74.8 -        free(qe->block);
    74.9 +    free(qe->block);
   74.10      free((void *)qe);
   74.11      return NULL;
   74.12  }
   74.13 @@ -1072,7 +1071,7 @@ uint64_t allocblock_hint(void *block, ui
   74.14   *
   74.15   *   @return: pointer to new block, NULL on error
   74.16   */
   74.17 -void *newblock() {
   74.18 +void *newblock(void) {
   74.19      void *block = malloc(BLOCK_SIZE);
   74.20      if (block == NULL) {
   74.21          perror("newblock");
   74.22 @@ -1089,7 +1088,6 @@ void *newblock() {
   74.23   *   @block: block to be freed
   74.24   */
   74.25  void freeblock(void *block) {
   74.26 -    if (block != NULL)
   74.27          free(block);
   74.28  }
   74.29  
    75.1 --- a/tools/blktap/parallax/blockstored.c	Fri Nov 18 23:06:09 2005 -0600
    75.2 +++ b/tools/blktap/parallax/blockstored.c	Fri Nov 18 23:16:29 2005 -0600
    75.3 @@ -232,7 +232,7 @@ uint64_t allocblock(void *block) {
    75.4   *
    75.5   *   @return: pointer to new block, NULL on error
    75.6   */
    75.7 -void *newblock() {
    75.8 +void *newblock(void) {
    75.9      void *block = malloc(BLOCK_SIZE);
   75.10      if (block == NULL) {
   75.11          perror("newblock");
   75.12 @@ -249,7 +249,6 @@ void *newblock() {
   75.13   *   @block: block to be freed
   75.14   */
   75.15  void freeblock(void *block) {
   75.16 -    if (block != NULL)
   75.17          free(block);
   75.18  }
   75.19  
    76.1 --- a/tools/blktap/parallax/requests-async.c	Fri Nov 18 23:06:09 2005 -0600
    76.2 +++ b/tools/blktap/parallax/requests-async.c	Fri Nov 18 23:16:29 2005 -0600
    76.3 @@ -715,7 +715,7 @@ static void write_cb(struct io_ret r, vo
    76.4          r.u.i  = -1;
    76.5          /* free any saved node vals. */
    76.6          for (i=0; i<3; i++)
    76.7 -            if (req->radix[i] != 0) free(req->radix[i]);
    76.8 +            free(req->radix[i]);
    76.9          free(req);
   76.10          cb(r, req_param);
   76.11      }
    77.1 --- a/tools/blktap/xenbus.c	Fri Nov 18 23:06:09 2005 -0600
    77.2 +++ b/tools/blktap/xenbus.c	Fri Nov 18 23:16:29 2005 -0600
    77.3 @@ -339,10 +339,8 @@ static int backend_remove(struct xs_hand
    77.4      /* Free everything else. */
    77.5      if (be->blkif)
    77.6          free_blkif(be->blkif);
    77.7 -    if (be->frontpath)
    77.8 -        free(be->frontpath);
    77.9 -    if (be->backpath)
   77.10 -        free(be->backpath);
   77.11 +    free(be->frontpath);
   77.12 +    free(be->backpath);
   77.13      free(be);
   77.14      return 0;
   77.15  }
   77.16 @@ -406,8 +404,7 @@ static void frontend_changed(struct xs_h
   77.17      return;
   77.18  
   77.19   fail:
   77.20 -    if (fepath)
   77.21 -        free(fepath);
   77.22 +    free(fepath);
   77.23  }
   77.24  
   77.25  
   77.26 @@ -460,9 +457,7 @@ static void backend_changed(struct xs_ha
   77.27      }
   77.28  
   77.29   fail:
   77.30 -    if (path)
   77.31 -        free(path);
   77.32 -
   77.33 +    free(path);
   77.34  }
   77.35  
   77.36  static void blkback_probe(struct xs_handle *h, struct xenbus_watch *w, 
   77.37 @@ -537,12 +532,10 @@ static void blkback_probe(struct xs_hand
   77.38  	return;
   77.39  
   77.40   free_be:
   77.41 -	if ((be) && (be->backend_watch.node))
   77.42 +	if (be && (be->backend_watch.node))
   77.43              unregister_xenbus_watch(h, &be->backend_watch);
   77.44 -	if (frontend)
   77.45 -            free(frontend);
   77.46 -        if (bepath)
   77.47 -            free(bepath);
   77.48 +        free(frontend);
   77.49 +        free(bepath);
   77.50  	free(be);
   77.51  	return;
   77.52  }
    78.1 --- a/tools/check/check_hotplug	Fri Nov 18 23:06:09 2005 -0600
    78.2 +++ b/tools/check/check_hotplug	Fri Nov 18 23:16:29 2005 -0600
    78.3 @@ -7,7 +7,7 @@ function error {
    78.4     exit 1
    78.5  }
    78.6  
    78.7 -if [ -x /sbin/udev ] && [ ! -z `udev -V` ] && [ `udev -V` -ge 059 ]; then
    78.8 +if [ -x /sbin/udev ] && [ ! -z `/sbin/udev -V` ] && [ `/sbin/udev -V` -ge 059 ]; then
    78.9    exit 0
   78.10  fi
   78.11  
    79.1 --- a/tools/console/daemon/io.c	Fri Nov 18 23:06:09 2005 -0600
    79.2 +++ b/tools/console/daemon/io.c	Fri Nov 18 23:16:29 2005 -0600
    79.3 @@ -114,7 +114,7 @@ static void buffer_append(struct domain 
    79.4  			buffer->data, buffer->max_capacity);
    79.5  		buffer->data = realloc(buffer->data,
    79.6  				       buffer->max_capacity);
    79.7 -		buffer->capacity = buffer->max_capacity;
    79.8 +		buffer->size = buffer->capacity = buffer->max_capacity;
    79.9  	}
   79.10  }
   79.11  
   79.12 @@ -344,8 +344,7 @@ static struct domain *create_domain(int 
   79.13  
   79.14  	return dom;
   79.15   out:
   79.16 -	if (dom->conspath)
   79.17 -		free(dom->conspath);
   79.18 +	free(dom->conspath);
   79.19  	free(dom);
   79.20  	return NULL;
   79.21  }
   79.22 @@ -380,20 +379,16 @@ static void cleanup_domain(struct domain
   79.23  	if (!buffer_empty(&d->buffer))
   79.24  		return;
   79.25  
   79.26 -	if (d->buffer.data) {
   79.27 -		free(d->buffer.data);
   79.28 -		d->buffer.data = NULL;
   79.29 -	}
   79.30 -
   79.31  	if (d->tty_fd != -1) {
   79.32  		close(d->tty_fd);
   79.33  		d->tty_fd = -1;
   79.34  	}
   79.35  
   79.36 -	if (d->conspath) {
   79.37 -		free(d->conspath);
   79.38 -		d->conspath = NULL;
   79.39 -	}
   79.40 +	free(d->buffer.data);
   79.41 +	d->buffer.data = NULL;
   79.42 +
   79.43 +	free(d->conspath);
   79.44 +	d->conspath = NULL;
   79.45  
   79.46  	remove_domain(d);
   79.47  }
    80.1 --- a/tools/examples/Makefile	Fri Nov 18 23:06:09 2005 -0600
    80.2 +++ b/tools/examples/Makefile	Fri Nov 18 23:16:29 2005 -0600
    80.3 @@ -41,7 +41,7 @@ DE = $(shell readlink -f $(DESTDIR))
    80.4  ifeq ($(findstring $(DI),$(DE)),$(DI))
    80.5  HOTPLUGS=install-hotplug install-udev
    80.6  else
    80.7 -ifeq ($(shell [ -x /sbin/udev ] && [ ! -z `udev -V` ] && [ `/sbin/udev -V` -ge 059 ] && echo 1),1)
    80.8 +ifeq ($(shell [ -x /sbin/udev ] && [ ! -z `/sbin/udev -V` ] && [ `/sbin/udev -V` -ge 059 ] && echo 1),1)
    80.9  HOTPLUGS=install-udev
   80.10  else
   80.11  HOTPLUGS=install-hotplug
    81.1 --- a/tools/examples/block	Fri Nov 18 23:06:09 2005 -0600
    81.2 +++ b/tools/examples/block	Fri Nov 18 23:16:29 2005 -0600
    81.3 @@ -3,6 +3,12 @@
    81.4  dir=$(dirname "$0")
    81.5  . "$dir/block-common.sh"
    81.6  
    81.7 +case "$command" in
    81.8 +    online | offline)
    81.9 +        exit 0
   81.10 +        ;;
   81.11 +esac
   81.12 +
   81.13  expand_dev() {
   81.14    local dev
   81.15    case $1 in
   81.16 @@ -16,10 +22,10 @@ expand_dev() {
   81.17    echo -n $dev
   81.18  }
   81.19  
   81.20 -t=$(xenstore_read "$XENBUS_PATH"/type || true)
   81.21 +t=$(xenstore_read_default "$XENBUS_PATH"/type "MISSING")
   81.22  
   81.23  case "$command" in 
   81.24 -  bind)
   81.25 +  add)
   81.26      p=$(xenstore_read "$XENBUS_PATH"/params)
   81.27      case $t in 
   81.28        phy)
   81.29 @@ -38,32 +44,25 @@ case "$command" in
   81.30  	done
   81.31  	exit 1
   81.32  	;;
   81.33 -
   81.34 -      *)
   81.35 -        [ -x /etc/xen/scripts/block-"$t" ] && \
   81.36 -	    /etc/xen/scripts/block-"$t" bind $p
   81.37 -	;;
   81.38      esac
   81.39      ;;
   81.40  
   81.41 -  unbind)
   81.42 -    node=$(xenstore_read "$XENBUS_PATH"/node)
   81.43 +  remove)
   81.44      case $t in 
   81.45        phy)
   81.46  	exit 0
   81.47  	;;
   81.48  
   81.49        file)
   81.50 +        node=$(xenstore_read "$XENBUS_PATH"/node)
   81.51  	losetup -d $node
   81.52  	exit 0
   81.53  	;;
   81.54 -
   81.55 -      *)
   81.56 -        [ -x /etc/xen/scripts/block-"$t" ] && \
   81.57 -	    /etc/xen/scripts/block-"$t" unbind $node
   81.58 -	;;
   81.59 -
   81.60      esac
   81.61      ;;
   81.62  
   81.63  esac
   81.64 +
   81.65 +# If we've reached here, $t is neither phy nor file, so fire a helper script.
   81.66 +[ -x /etc/xen/scripts/block-"$t" ] && \
   81.67 +  /etc/xen/scripts/block-"$t" "$command" $node
    82.1 --- a/tools/examples/block-common.sh	Fri Nov 18 23:06:09 2005 -0600
    82.2 +++ b/tools/examples/block-common.sh	Fri Nov 18 23:16:29 2005 -0600
    82.3 @@ -19,9 +19,12 @@
    82.4  dir=$(dirname "$0")
    82.5  . "$dir/xen-hotplug-common.sh"
    82.6  
    82.7 -command="$1"
    82.8 +findCommand "$@"
    82.9  
   82.10 -if [ "$command" != "bind" ] && [ "$command" != "unbind" ]
   82.11 +if [ "$command" != "online" ]  &&
   82.12 +   [ "$command" != "offline" ] &&
   82.13 +   [ "$command" != "add" ]     &&
   82.14 +   [ "$command" != "remove" ]
   82.15  then
   82.16    log err "Invalid command: $command"
   82.17    exit 1
    83.1 --- a/tools/examples/network-bridge	Fri Nov 18 23:06:09 2005 -0600
    83.2 +++ b/tools/examples/network-bridge	Fri Nov 18 23:16:29 2005 -0600
    83.3 @@ -16,29 +16,38 @@
    83.4  #
    83.5  # Usage:
    83.6  #
    83.7 -# network (start|stop|status) {VAR=VAL}*
    83.8 +# network-bridge (start|stop|status) {VAR=VAL}*
    83.9  #
   83.10  # Vars:
   83.11  #
   83.12 -# vifnum     Virtual device number to use (default 0). Numbers >=1
   83.13 +# vifnum     Virtual device number to use (default 0). Numbers >=8
   83.14  #            require the netback driver to have nloopbacks set to a
   83.15 -#            higher value than its default of 1.
   83.16 +#            higher value than its default of 8.
   83.17  # bridge     The bridge to use (default xenbr${vifnum}).
   83.18  # netdev     The interface to add to the bridge (default eth${vifnum}).
   83.19  # antispoof  Whether to use iptables to prevent spoofing (default no).
   83.20  #
   83.21 +# Internal Vars:
   83.22 +# pdev="p${netdev}"
   83.23 +# vdev="veth${vifnum}"
   83.24 +# vif0="vif0.${vifnum}"
   83.25 +#
   83.26  # start:
   83.27 -# Creates the bridge and enslaves netdev to it.
   83.28 -# Copies the IP addresses from netdev to the bridge.
   83.29 -# Deletes the routes to netdev and adds them on bridge.
   83.30 +# Creates the bridge
   83.31 +# Copies the IP and MAC addresses from netdev to vdev
   83.32 +# Renames netdev to be pdev 
   83.33 +# Renames vdev to be netdev 
   83.34 +# Enslaves pdev, vdev to bridge
   83.35  #
   83.36  # stop:
   83.37 -# Removes netdev from the bridge.
   83.38 -# Deletes the routes to bridge and adds them to netdev.
   83.39 +# Removes netdev from the bridge
   83.40 +# Transfers addresses, routes from netdev to pdev
   83.41 +# Renames netdev to vdev
   83.42 +# Renames pdev to netdev 
   83.43 +# Deletes bridge
   83.44  #
   83.45  # status:
   83.46 -# Print ifconfig for netdev and bridge.
   83.47 -# Print routes.
   83.48 +# Print addresses, interfaces, routes
   83.49  #
   83.50  #============================================================================
   83.51  
   83.52 @@ -97,7 +106,7 @@ s/inet/ip addr add/
   83.53  s@\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+/[0-9]\+\)@\1@
   83.54  s/${src}/dev ${dst}/
   83.55  " | sh -e
   83.56 -    # Remove automatic routes on destionation device
   83.57 +    # Remove automatic routes on destination device
   83.58      ip route list | sed -ne "
   83.59  /dev ${dst}\( \|$\)/ {
   83.60    s/^/ip route del /
   83.61 @@ -105,17 +114,6 @@ s/${src}/dev ${dst}/
   83.62  }" | sh -e
   83.63  }
   83.64  
   83.65 -# Usage: del_addrs src
   83.66 -del_addrs () {
   83.67 -    local src=$1
   83.68 -    ip addr show dev ${src} | egrep '^ *inet ' | sed -e "
   83.69 -s/inet/ip addr del/
   83.70 -s@\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\)/[0-9]\+@\1@
   83.71 -s/${src}/dev ${src}/
   83.72 -" | sh -e
   83.73 -    ip link set dev ${dst} up
   83.74 -}
   83.75 -
   83.76  # Usage: transfer_routes src dst
   83.77  # Get all IP routes to device $src, delete them, and
   83.78  # add the same routes to device $dst.
   83.79 @@ -140,6 +138,23 @@ transfer_routes () {
   83.80  }" | sh -e
   83.81  }
   83.82  
   83.83 +
   83.84 +##
   83.85 +# link_exists interface
   83.86 +#
   83.87 +# Returns 0 if the interface named exists (whether up or down), 1 otherwise.
   83.88 +#
   83.89 +link_exists()
   83.90 +{
   83.91 +    if ip link show "$1" >&/dev/null
   83.92 +    then
   83.93 +        return 0
   83.94 +    else
   83.95 +        return 1
   83.96 +    fi
   83.97 +}
   83.98 +
   83.99 +
  83.100  # Usage: create_bridge bridge
  83.101  create_bridge () {
  83.102      local bridge=$1
  83.103 @@ -195,8 +210,12 @@ op_start () {
  83.104  	return
  83.105      fi
  83.106  
  83.107 -    if ! ip link show 2>/dev/null | grep -q "^[0-9]*: ${vdev}"; then
  83.108 -        echo "
  83.109 +    if ! link_exists "$vdev"; then
  83.110 +        if link_exists "$pdev"; then
  83.111 +            # The device is already up.
  83.112 +            return
  83.113 +        else
  83.114 +            echo "
  83.115  Link $vdev is missing.
  83.116  This may be because you have reached the limit of the number of interfaces
  83.117  that the loopback driver supports.  If the loopback driver is a module, you
  83.118 @@ -204,12 +223,13 @@ may raise this limit by passing it as a 
  83.119  driver is compiled statically into the kernel, then you may set the parameter
  83.120  using loopback.nloopbacks=<N> on the domain 0 kernel command line.
  83.121  " >&2
  83.122 -        exit 1
  83.123 +            exit 1
  83.124 +        fi
  83.125      fi
  83.126  
  83.127      create_bridge ${bridge}
  83.128  
  83.129 -    if ip link show ${vdev} 2>/dev/null >/dev/null; then
  83.130 +    if link_exists "$vdev"; then
  83.131  	mac=`ip link show ${netdev} | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'`
  83.132  	preiftransfer ${netdev}
  83.133  	transfer_addrs ${netdev} ${vdev}
  83.134 @@ -262,11 +282,11 @@ op_stop () {
  83.135      if [ "${bridge}" == "null" ]; then
  83.136  	return
  83.137      fi
  83.138 -    if ! ip link show ${bridge} >/dev/null 2>&1; then
  83.139 +    if ! link_exists "$bridge"; then
  83.140  	return
  83.141      fi
  83.142  
  83.143 -    if ip link show ${pdev} 2>/dev/null >/dev/null; then
  83.144 +    if link_exists "$pdev"; then
  83.145  	ip link set dev ${vif0} down
  83.146  	mac=`ip link show ${netdev} | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'`
  83.147  	transfer_addrs ${netdev} ${pdev}
    84.1 --- a/tools/examples/vif-bridge	Fri Nov 18 23:06:09 2005 -0600
    84.2 +++ b/tools/examples/vif-bridge	Fri Nov 18 23:16:29 2005 -0600
    84.3 @@ -9,7 +9,7 @@
    84.4  # places, then this script is the default.
    84.5  #
    84.6  # Usage:
    84.7 -# vif-bridge (up|down)
    84.8 +# vif-bridge (add|remove|online|offline)
    84.9  #
   84.10  # Environment vars:
   84.11  # vif         vif interface name (required).
   84.12 @@ -47,7 +47,7 @@ then
   84.13  fi
   84.14  
   84.15  case "$command" in
   84.16 -    up)
   84.17 +    online)
   84.18          if brctl show "$bridge" | grep "$vif" >&/dev/null
   84.19          then
   84.20            log debug "$vif already attached to $bridge"
   84.21 @@ -58,9 +58,9 @@ case "$command" in
   84.22            fatal "brctl addif $bridge $vif failed"
   84.23  
   84.24          ifconfig "$vif" up || fatal "ifconfig $vif up failed"
   84.25 -        success
   84.26          ;;
   84.27 -    down)
   84.28 +
   84.29 +    offline)
   84.30          # vifs are auto-removed from bridge.
   84.31          ifconfig "$vif" down || fatal "ifconfig $vif down failed"
   84.32          ;;
   84.33 @@ -69,3 +69,4 @@ esac
   84.34  handle_iptable
   84.35  
   84.36  log debug "Successful vif-bridge operation for $vif, bridge $bridge."
   84.37 +success
    85.1 --- a/tools/examples/vif-common.sh	Fri Nov 18 23:06:09 2005 -0600
    85.2 +++ b/tools/examples/vif-common.sh	Fri Nov 18 23:16:29 2005 -0600
    85.3 @@ -22,12 +22,21 @@ dir=$(dirname "$0")
    85.4  
    85.5  findCommand "$@"
    85.6  
    85.7 -if [ "$command" != "up" ] && [ "$command" != "down" ]
    85.8 +if [ "$command" != "online" ]  &&
    85.9 +   [ "$command" != "offline" ] &&
   85.10 +   [ "$command" != "add" ]     &&
   85.11 +   [ "$command" != "remove" ]
   85.12  then
   85.13    log err "Invalid command: $command"
   85.14    exit 1
   85.15  fi
   85.16  
   85.17 +case "$command" in
   85.18 +    add | remove)
   85.19 +        exit 0
   85.20 +        ;;
   85.21 +esac
   85.22 +
   85.23  
   85.24  # Parameters may be read from the environment, the command line arguments, and
   85.25  # the store, with overriding in that order.  The environment is given by the
   85.26 @@ -46,14 +55,17 @@ vif="${vif:?}"
   85.27  
   85.28  function frob_iptable()
   85.29  {
   85.30 -  if [ "$command" == "up" ]
   85.31 +  if [ "$command" == "online" ]
   85.32    then
   85.33      local c="-A"
   85.34    else
   85.35      local c="-D"
   85.36    fi
   85.37  
   85.38 -  iptables "$c" FORWARD -m physdev --physdev-in "$vif" "$@" -j ACCEPT
   85.39 +  iptables "$c" FORWARD -m physdev --physdev-in "$vif" "$@" -j ACCEPT ||
   85.40 +    log err \
   85.41 +     "iptables $c FORWARD -m physdev --physdev-in $vif $@ -j ACCEPT failed.
   85.42 +If you are using iptables, this may affect networking for guest domains."
   85.43  }
   85.44  
   85.45  
   85.46 @@ -66,6 +78,15 @@ function frob_iptable()
   85.47  #
   85.48  function handle_iptable()
   85.49  {
   85.50 +  # Check for a working iptables installation.  Checking for the iptables
   85.51 +  # binary is not sufficient, because the user may not have the appropriate
   85.52 +  # modules installed.  If iptables is not working, then there's no need to do
   85.53 +  # anything with it, so we can just return.
   85.54 +  if ! iptables -L >&/dev/null
   85.55 +  then
   85.56 +    return
   85.57 +  fi
   85.58 +
   85.59    if [ "$ip" != "" ]
   85.60    then
   85.61        local addr
    86.1 --- a/tools/examples/vif-nat	Fri Nov 18 23:06:09 2005 -0600
    86.2 +++ b/tools/examples/vif-nat	Fri Nov 18 23:16:29 2005 -0600
    86.3 @@ -9,7 +9,7 @@
    86.4  # places, then vif-bridge is the default.
    86.5  #
    86.6  # Usage:
    86.7 -# vif-nat (up|down)
    86.8 +# vif-nat (add|remove|online|offline)
    86.9  #
   86.10  # Environment vars:
   86.11  # vif         vif interface name (required).
   86.12 @@ -40,12 +40,12 @@ netmask=$netmask.$(( $intmask & 0x000000
   86.13  main_ip=$(ip addr show eth0 | sed -e '/inet /!d;s/^.*inet \([^\s*]\)\s.*$/\1/')
   86.14  
   86.15  case "$command" in
   86.16 -    up)
   86.17 +    online)
   86.18          ifconfig ${vif} ${vif_ip} netmask ${netmask} up
   86.19          echo 1 >/proc/sys/net/ipv4/conf/${vif}/proxy_arp
   86.20          ipcmd='a'
   86.21          ;;
   86.22 -    down)
   86.23 +    offline)
   86.24          ifconfig ${vif} down
   86.25          ipcmd='d'
   86.26          ;;
   86.27 @@ -53,6 +53,6 @@ esac
   86.28  
   86.29  ip r ${ipcmd} ${ip} dev ${vif} src ${main_ip}
   86.30  
   86.31 -handle_iptable()
   86.32 +handle_iptable
   86.33  
   86.34  success
    87.1 --- a/tools/examples/vif-route	Fri Nov 18 23:06:09 2005 -0600
    87.2 +++ b/tools/examples/vif-route	Fri Nov 18 23:16:29 2005 -0600
    87.3 @@ -9,7 +9,7 @@
    87.4  # places, then vif-bridge is the default.
    87.5  #
    87.6  # Usage:
    87.7 -# vif-route (up|down)
    87.8 +# vif-route (add|remove|online|offline)
    87.9  #
   87.10  # Environment vars:
   87.11  # vif         vif interface name (required).
   87.12 @@ -26,12 +26,12 @@ dir=$(dirname "$0")
   87.13  main_ip=$(ip addr show eth0 | sed -e '/inet /!d;s/^.*inet \([^\s*]\)\s.*$/\1/')
   87.14  
   87.15  case "$command" in
   87.16 -    up)
   87.17 +    online)
   87.18          ifconfig ${vif} ${main_ip} netmask 255.255.255.255 up
   87.19          echo 1 >/proc/sys/net/ipv4/conf/${vif}/proxy_arp
   87.20          ipcmd='a'
   87.21          ;;
   87.22 -    down)
   87.23 +    offline)
   87.24          ifdown ${vif}
   87.25          ipcmd='d'
   87.26          ;;
   87.27 @@ -45,6 +45,6 @@ if [ "${ip}" ] ; then
   87.28      done 
   87.29  fi
   87.30  
   87.31 -handle_iptable()
   87.32 +handle_iptable
   87.33  
   87.34  success
    88.1 --- a/tools/examples/xen-backend.agent	Fri Nov 18 23:06:09 2005 -0600
    88.2 +++ b/tools/examples/xen-backend.agent	Fri Nov 18 23:16:29 2005 -0600
    88.3 @@ -2,35 +2,25 @@
    88.4  
    88.5  PATH=/etc/xen/scripts:$PATH
    88.6  
    88.7 +case "$XENBUS_TYPE" in
    88.8 +  vbd)
    88.9 +    /etc/xen/scripts/block "$ACTION"
   88.10 +    ;;
   88.11 +  vif)
   88.12 +    [ -n "$script" ] && $script "$ACTION"
   88.13 +    ;;
   88.14 +esac
   88.15 +
   88.16  case "$ACTION" in
   88.17    add)
   88.18 -    case "$XENBUS_TYPE" in
   88.19 -      vbd)
   88.20 -	/etc/xen/scripts/block bind
   88.21 -        ;;
   88.22 -    esac
   88.23      ;;
   88.24    remove)
   88.25 -    case "$XENBUS_TYPE" in
   88.26 -      vbd)
   88.27 -	/etc/xen/scripts/block unbind
   88.28 -        ;;
   88.29 -      vif)
   88.30 -        [ -n "$script" ] && $script down
   88.31 -        ;;
   88.32 -    esac
   88.33      # remove device backend store entries
   88.34 -    xenstore-rm -t "$XENBUS_PATH"
   88.35 -    xenstore-rm -t "error/$XENBUS_PATH"
   88.36 +    xenstore-rm -t "$XENBUS_PATH"       || true
   88.37 +    xenstore-rm -t "error/$XENBUS_PATH" || true
   88.38      ;;
   88.39    online)
   88.40 -    case "$XENBUS_TYPE" in
   88.41 -      vif)
   88.42 -        [ -n "$script" ] && $script up
   88.43 -        ;;
   88.44 -    esac
   88.45      ;;
   88.46    offline)
   88.47      ;;
   88.48  esac
   88.49 -
    89.1 --- a/tools/examples/xen-backend.rules	Fri Nov 18 23:06:09 2005 -0600
    89.2 +++ b/tools/examples/xen-backend.rules	Fri Nov 18 23:16:29 2005 -0600
    89.3 @@ -1,4 +1,5 @@
    89.4 -SUBSYSTEM=="xen-backend", KERNEL=="vbd*", ACTION=="add", RUN+="/etc/xen/scripts/block bind"
    89.5 -SUBSYSTEM=="xen-backend", KERNEL=="vbd*", ACTION=="remove", RUN+="/etc/xen/scripts/block unbind"
    89.6 -SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="online", RUN+="$env{script} up"
    89.7 +SUBSYSTEM=="xen-backend", KERNEL=="vbd*", RUN+="/etc/xen/scripts/block $env{ACTION}"
    89.8 +SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="online", RUN+="$env{script} online"
    89.9 +SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="offline", RUN+="$env{script} offline"
   89.10  SUBSYSTEM=="xen-backend", ACTION=="remove", RUN+="/usr/bin/xenstore-rm -t $env{XENBUS_PATH}"
   89.11 +SUBSYSTEM=="xen-backend", ACTION=="remove", RUN+="/usr/bin/xenstore-rm -t error/$env{XENBUS_PATH}"
    90.1 --- a/tools/examples/xmexample.vmx	Fri Nov 18 23:06:09 2005 -0600
    90.2 +++ b/tools/examples/xmexample.vmx	Fri Nov 18 23:16:29 2005 -0600
    90.3 @@ -35,7 +35,11 @@ vcpus=1
    90.4  
    90.5  # Optionally define mac and/or bridge for the network interfaces.
    90.6  # Random MACs are assigned if not given.
    90.7 -#vif = [ 'mac=aa:00:00:00:00:11, bridge=xenbr0' ]
    90.8 +# nics default is 1
    90.9 +#vif = [ 'type=ioemu, mac=aa:00:00:00:00:11, bridge=xenbr0' ]
   90.10 +nics=1 
   90.11 +# type=ioemu specify the NIC is an ioemu device not netfront
   90.12 +vif = [ 'type=ioemu, bridge=xenbr0' ]
   90.13  
   90.14  #----------------------------------------------------------------------------
   90.15  # Define the disk devices you want the domain to have access to, and
   90.16 @@ -117,6 +121,11 @@ vncviewer=1
   90.17  #nographic=0
   90.18  
   90.19  
   90.20 +#-----------------------------------------------------------------------------
   90.21 +#   serial port re-direct to pty deivce, /dev/pts/n 
   90.22 +#   then xm console or minicom can connect
   90.23 +#serial='pty'
   90.24 +
   90.25  #----------------------------------------------------------------------------
   90.26  # enable ne2000, default = 0(use pcnet)
   90.27  ne2000=0
    91.1 --- a/tools/ioemu/hw/magic-load.c	Fri Nov 18 23:06:09 2005 -0600
    91.2 +++ b/tools/ioemu/hw/magic-load.c	Fri Nov 18 23:16:29 2005 -0600
    91.3 @@ -196,10 +196,8 @@ static void load_symbols(struct elfhdr *
    91.4  	goto error_freesyms;
    91.5  
    91.6      /* Commit */
    91.7 -    if (disas_symtab)
    91.8 -	qemu_free(disas_symtab); /* XXX Merge with old symbols? */
    91.9 -    if (disas_strtab)
   91.10 -	qemu_free(disas_strtab);
   91.11 +    qemu_free(disas_symtab); /* XXX Merge with old symbols? */
   91.12 +    qemu_free(disas_strtab);
   91.13      disas_symtab = syms;
   91.14      disas_num_syms = nsyms;
   91.15      disas_strtab = str;
    92.1 --- a/tools/ioemu/target-i386-dm/Makefile	Fri Nov 18 23:06:09 2005 -0600
    92.2 +++ b/tools/ioemu/target-i386-dm/Makefile	Fri Nov 18 23:16:29 2005 -0600
    92.3 @@ -7,7 +7,7 @@ INSTALL_DIR := $(DESTDIR)/usr/$(LIBDIR)/
    92.4  TARGET_PATH=$(SRC_PATH)/target-$(TARGET_ARCH)
    92.5  VPATH=$(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw:$(SRC_PATH)/audio
    92.6  DEFINES=-I. -I$(TARGET_PATH) -I$(SRC_PATH)
    92.7 -DEFINES+= -I$(XEN_ROOT)/tools/libxc
    92.8 +DEFINES+= -I$(XEN_ROOT)/tools/libxc -I$(XEN_ROOT)/tools/xenstore
    92.9  ifdef CONFIG_USER_ONLY
   92.10  VPATH+=:$(SRC_PATH)/linux-user
   92.11  DEFINES+=-I$(SRC_PATH)/linux-user -I$(SRC_PATH)/linux-user/$(TARGET_ARCH)
   92.12 @@ -188,7 +188,7 @@ endif
   92.13  #########################################################
   92.14  
   92.15  DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
   92.16 -LIBS+=-lm -L../../libxc -lxenctrl -lxenguest
   92.17 +LIBS+=-lm -L../../libxc -lxenctrl -lxenguest -L../../xenstore -lxenstore
   92.18  ifndef CONFIG_USER_ONLY
   92.19  LIBS+=-lz
   92.20  endif
   92.21 @@ -376,9 +376,9 @@ mixeng.o: mixeng.c mixeng.h mixeng_templ
   92.22  
   92.23  clean:
   92.24  	rm -rf *.o  *.a *~ $(PROGS) gen-op.h opc.h op.h nwfpe slirp
   92.25 +	rm -rf config.mak config.h
   92.26  
   92.27 -distclean:
   92.28 -	rm -rf *.o  *.a *~ $(PROGS) gen-op.h opc.h op.h nwfpe slirp
   92.29 +distclean: clean
   92.30  
   92.31  install: all 
   92.32  	if [ ! -d $(INSTALL_DIR) ];then mkdir -p $(INSTALL_DIR);fi
    93.1 --- a/tools/ioemu/target-i386-dm/helper2.c	Fri Nov 18 23:06:09 2005 -0600
    93.2 +++ b/tools/ioemu/target-i386-dm/helper2.c	Fri Nov 18 23:16:29 2005 -0600
    93.3 @@ -416,6 +416,7 @@ int main_loop(void)
    93.4  	FD_ZERO(&wakeup_rfds);
    93.5  	FD_SET(evtchn_fd, &wakeup_rfds);
    93.6  	highest_fds = evtchn_fd;
    93.7 +	env->send_event = 0;
    93.8  	while (1) {
    93.9                  if (vm_running) {
   93.10                      if (shutdown_requested) {
   93.11 @@ -431,7 +432,6 @@ int main_loop(void)
   93.12  		tv.tv_sec = 0;
   93.13  		tv.tv_usec = 100000;
   93.14  
   93.15 -		env->send_event = 0;
   93.16  		retval = select(highest_fds+1, &wakeup_rfds, NULL, NULL, &tv);
   93.17  		if (retval == -1) {
   93.18  			perror("select");
   93.19 @@ -447,12 +447,13 @@ int main_loop(void)
   93.20  #define ULONGLONG_MAX   ULONG_MAX
   93.21  #endif
   93.22  
   93.23 -		main_loop_wait(0);
   93.24          tun_receive_handler(&rfds);
   93.25          if ( FD_ISSET(evtchn_fd, &rfds) ) {
   93.26              cpu_handle_ioreq(env);
   93.27          }
   93.28 +		main_loop_wait(0);
   93.29  		if (env->send_event) {
   93.30 +		    env->send_event = 0;
   93.31  			struct ioctl_evtchn_notify notify;
   93.32  			notify.port = ioreq_local_port;
   93.33  			(void)ioctl(evtchn_fd, IOCTL_EVTCHN_NOTIFY, &notify);
    94.1 --- a/tools/ioemu/target-i386-dm/qemu-ifup	Fri Nov 18 23:06:09 2005 -0600
    94.2 +++ b/tools/ioemu/target-i386-dm/qemu-ifup	Fri Nov 18 23:16:29 2005 -0600
    94.3 @@ -7,4 +7,4 @@ echo 'config qemu network with xen bridg
    94.4  echo $*
    94.5  
    94.6  ifconfig $1 0.0.0.0 up
    94.7 -brctl addif xenbr0 $1
    94.8 +brctl addif $2 $1
    95.1 --- a/tools/ioemu/vl.c	Fri Nov 18 23:06:09 2005 -0600
    95.2 +++ b/tools/ioemu/vl.c	Fri Nov 18 23:16:29 2005 -0600
    95.3 @@ -76,6 +76,7 @@
    95.4  #endif /* CONFIG_SDL */
    95.5  
    95.6  #include "xenctrl.h"
    95.7 +#include "xs.h"
    95.8  #include "exec-all.h"
    95.9  
   95.10  //#define DO_TB_FLUSH
   95.11 @@ -123,6 +124,7 @@ int domid = -1;
   95.12  static char network_script[1024];
   95.13  int pit_min_timer_count = 0;
   95.14  int nb_nics;
   95.15 +char bridge[16];
   95.16  NetDriverState nd_table[MAX_NICS];
   95.17  QEMUTimer *gui_timer;
   95.18  QEMUTimer *polling_timer;
   95.19 @@ -135,7 +137,7 @@ int adlib_enabled = 1;
   95.20  int gus_enabled = 1;
   95.21  int pci_enabled = 1;
   95.22  int prep_enabled = 0;
   95.23 -int rtc_utc = 1;
   95.24 +int rtc_utc = 0;
   95.25  int cirrus_vga_enabled = 1;
   95.26  int vga_accelerate = 1;
   95.27  int graphic_width = 800;
   95.28 @@ -1171,6 +1173,48 @@ CharDriverState *qemu_chr_open_stdio(voi
   95.29      return chr;
   95.30  }
   95.31  
   95.32 +int store_console_dev(int domid, char *pts)
   95.33 +{
   95.34 +    int xc_handle;
   95.35 +    unsigned int len = 0;
   95.36 +    struct xs_handle *xs;
   95.37 +    char *path;
   95.38 +
   95.39 +    xs = xs_daemon_open();
   95.40 +    if (xs == NULL) {
   95.41 +        fprintf(logfile, "Could not contact XenStore\n");
   95.42 +        return -1;
   95.43 +    }
   95.44 +
   95.45 +    xc_handle = xc_interface_open();
   95.46 +    if (xc_handle == -1) {
   95.47 +        fprintf(logfile, "xc_interface_open() error\n");
   95.48 +        return -1;
   95.49 +    }
   95.50 +    
   95.51 +    path = xs_get_domain_path(xs, domid);
   95.52 +    if (path == NULL) {
   95.53 +        fprintf(logfile, "xs_get_domain_path() error\n");
   95.54 +        return -1;
   95.55 +    }
   95.56 +    path = realloc(path, strlen(path) + strlen("/console/tty") + 1);
   95.57 +    if (path == NULL) {
   95.58 +        fprintf(logfile, "realloc error\n");
   95.59 +        return -1;
   95.60 +    }
   95.61 +    strcat(path, "/console/tty");
   95.62 +    if (!xs_write(xs, NULL, path, pts, strlen(pts))) {
   95.63 +        fprintf(logfile, "xs_write for console fail");
   95.64 +        return -1;
   95.65 +    }
   95.66 +    
   95.67 +    free(path);
   95.68 +    xs_daemon_close(xs);
   95.69 +    close(xc_handle);
   95.70 +
   95.71 +    return 0;
   95.72 +}
   95.73 +
   95.74  #if defined(__linux__)
   95.75  CharDriverState *qemu_chr_open_pty(void)
   95.76  {
   95.77 @@ -1182,6 +1226,7 @@ CharDriverState *qemu_chr_open_pty(void)
   95.78          return NULL;
   95.79      }
   95.80      fprintf(stderr, "char device redirected to %s\n", slave_name);
   95.81 +    store_console_dev(domid, slave_name);
   95.82      return qemu_chr_open_fd(master_fd, master_fd);
   95.83  }
   95.84  #else
   95.85 @@ -1542,7 +1587,7 @@ static void tun_add_read_packet(NetDrive
   95.86  static int net_tun_init(NetDriverState *nd)
   95.87  {
   95.88      int pid, status;
   95.89 -    char *args[3];
   95.90 +    char *args[4];
   95.91      char **parg;
   95.92      extern int highest_fds;
   95.93  
   95.94 @@ -1558,6 +1603,7 @@ static int net_tun_init(NetDriverState *
   95.95              parg = args;
   95.96              *parg++ = network_script;
   95.97              *parg++ = nd->ifname;
   95.98 +            *parg++ = bridge;
   95.99              *parg++ = NULL;
  95.100              execv(network_script, args);
  95.101              exit(1);
  95.102 @@ -2163,6 +2209,7 @@ void help(void)
  95.103             "Network options:\n"
  95.104             "-nics n         simulate 'n' network cards [default=1]\n"
  95.105             "-macaddr addr   set the mac address of the first interface\n"
  95.106 +           "-bridge  br     set the bridge interface for nic\n"
  95.107             "-n script       set tap/tun network init script [default=%s]\n"
  95.108             "-tun-fd fd      use this fd as already opened tap/tun interface\n"
  95.109  #ifdef CONFIG_SLIRP
  95.110 @@ -2253,6 +2300,7 @@ enum {
  95.111  
  95.112      QEMU_OPTION_nics,
  95.113      QEMU_OPTION_macaddr,
  95.114 +    QEMU_OPTION_bridge,
  95.115      QEMU_OPTION_n,
  95.116      QEMU_OPTION_tun_fd,
  95.117      QEMU_OPTION_user_net,
  95.118 @@ -2323,6 +2371,7 @@ const QEMUOption qemu_options[] = {
  95.119  
  95.120      { "nics", HAS_ARG, QEMU_OPTION_nics},
  95.121      { "macaddr", HAS_ARG, QEMU_OPTION_macaddr},
  95.122 +    { "bridge", HAS_ARG, QEMU_OPTION_bridge},
  95.123      { "n", HAS_ARG, QEMU_OPTION_n },
  95.124      { "tun-fd", HAS_ARG, QEMU_OPTION_tun_fd },
  95.125  #ifdef CONFIG_SLIRP
  95.126 @@ -2701,7 +2750,9 @@ int main(int argc, char **argv)
  95.127                  break;
  95.128              case QEMU_OPTION_nographic:
  95.129                  pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
  95.130 -                pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "stdio");
  95.131 +                if(!strcmp(serial_devices[0], "vc"))
  95.132 +                    pstrcpy(serial_devices[0], sizeof(serial_devices[0]),
  95.133 +                            "stdio");
  95.134                  nographic = 1;
  95.135                  break;
  95.136  #ifdef CONFIG_VNC
  95.137 @@ -2779,6 +2830,9 @@ int main(int argc, char **argv)
  95.138                      exit(1);
  95.139                  }
  95.140                  break;
  95.141 +            case QEMU_OPTION_bridge:
  95.142 +                pstrcpy(bridge, sizeof(bridge), optarg);
  95.143 +                break;
  95.144              case QEMU_OPTION_macaddr:
  95.145                  {
  95.146                      const char *p;
    96.1 --- a/tools/ioemu/vnc.c	Fri Nov 18 23:06:09 2005 -0600
    96.2 +++ b/tools/ioemu/vnc.c	Fri Nov 18 23:16:29 2005 -0600
    96.3 @@ -187,8 +187,7 @@ static void mouse_find_bounding_box_of_d
    96.4  
    96.5  static void start_mouse_calibration() {
    96.6  	int size = screen->height*screen->paddedWidthInBytes;
    96.7 -	if(mouse_magic->calibration)
    96.8 -		free(mouse_magic->calibration);
    96.9 +	free(mouse_magic->calibration);
   96.10  	mouse_magic->calibration = malloc(size);
   96.11  	memcpy(mouse_magic->calibration, screen->frameBuffer, size);
   96.12  	calibration_step=0;
   96.13 @@ -198,8 +197,7 @@ static void start_mouse_calibration() {
   96.14  }
   96.15  
   96.16  static void stop_mouse_calibration() {
   96.17 -	if(mouse_magic->calibration)
   96.18 -		free(mouse_magic->calibration);
   96.19 +	free(mouse_magic->calibration);
   96.20  	mouse_magic->calibration = 0;
   96.21  }
   96.22  
    97.1 --- a/tools/libxc/Makefile	Fri Nov 18 23:06:09 2005 -0600
    97.2 +++ b/tools/libxc/Makefile	Fri Nov 18 23:16:29 2005 -0600
    97.3 @@ -102,6 +102,7 @@ install: build
    97.4  	$(INSTALL_DATA) libxenguest.a $(DESTDIR)/usr/$(LIBDIR)
    97.5  	ln -sf libxenguest.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)/libxenguest.so.$(MAJOR)
    97.6  	ln -sf libxenguest.so.$(MAJOR) $(DESTDIR)/usr/$(LIBDIR)/libxenguest.so
    97.7 +	$(INSTALL_DATA) xenguest.h $(DESTDIR)/usr/include
    97.8  
    97.9  .PHONY: TAGS clean rpm install all
   97.10  
    98.1 --- a/tools/libxc/xc_ia64_stubs.c	Fri Nov 18 23:06:09 2005 -0600
    98.2 +++ b/tools/libxc/xc_ia64_stubs.c	Fri Nov 18 23:16:29 2005 -0600
    98.3 @@ -77,7 +77,7 @@ int xc_ia64_copy_to_domain_pages(int xc_
    98.4  {
    98.5      // N.B. gva should be page aligned
    98.6      
    98.7 -    unsigned long *page_array=NULL;
    98.8 +    unsigned long *page_array = NULL;
    98.9      int i;
   98.10  
   98.11      if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL ){
   98.12 @@ -99,8 +99,7 @@ int xc_ia64_copy_to_domain_pages(int xc_
   98.13      return 0;
   98.14      
   98.15  error_out:
   98.16 -    if (page_array)
   98.17 -        free(page_array);
   98.18 +    free(page_array);
   98.19      return -1;
   98.20  }
   98.21  
   98.22 @@ -657,8 +656,7 @@ int xc_vmx_build(int xc_handle,
   98.23          goto error_out;
   98.24      }
   98.25  
   98.26 -    if ( image != NULL )
   98.27 -        free(image);
   98.28 +    free(image);
   98.29  
   98.30      ctxt->flags = VGCF_VMX_GUEST;
   98.31      ctxt->regs.cr_iip = 0x80000000ffffffb0UL;
   98.32 @@ -675,9 +673,7 @@ int xc_vmx_build(int xc_handle,
   98.33      return rc;
   98.34  
   98.35   error_out:
   98.36 -    if ( image != NULL )
   98.37 -        free(image);
   98.38 -
   98.39 +    free(image);
   98.40      return -1;
   98.41  }
   98.42  
    99.1 --- a/tools/libxc/xc_linux_build.c	Fri Nov 18 23:06:09 2005 -0600
    99.2 +++ b/tools/libxc/xc_linux_build.c	Fri Nov 18 23:16:29 2005 -0600
    99.3 @@ -351,7 +351,7 @@ static int setup_guest(int xc_handle,
    99.4          xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, page_array[0]);
    99.5      memset(start_info, 0, sizeof(*start_info));
    99.6      rc = xc_version(xc_handle, XENVER_version, NULL);
    99.7 -    sprintf(start_info->magic, "xen-%i.%i", rc >> 16, rc & (0xFFFF));
    99.8 +    sprintf(start_info->magic, "xen-%i.%i-ia64", rc >> 16, rc & (0xFFFF));
    99.9      start_info->flags        = flags;
   99.10      start_info->store_mfn    = nr_pages - 2;
   99.11      start_info->store_evtchn = store_evtchn;
   99.12 @@ -619,14 +619,18 @@ static int setup_guest(int xc_handle,
   99.13  
   99.14      *store_mfn = page_array[(vstoreinfo_start-dsi.v_start) >> PAGE_SHIFT];
   99.15      *console_mfn = page_array[(vconsole_start-dsi.v_start) >> PAGE_SHIFT];
   99.16 -
   99.17 +    if ( xc_clear_domain_page(xc_handle, dom, *store_mfn) ||
   99.18 +         xc_clear_domain_page(xc_handle, dom, *console_mfn) )
   99.19 +        goto error_out;
   99.20  
   99.21      start_info = xc_map_foreign_range(
   99.22          xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
   99.23          page_array[(vstartinfo_start-dsi.v_start)>>PAGE_SHIFT]);
   99.24      memset(start_info, 0, sizeof(*start_info));
   99.25      rc = xc_version(xc_handle, XENVER_version, NULL);
   99.26 -    sprintf(start_info->magic, "xen-%i.%i", rc >> 16, rc & (0xFFFF));
   99.27 +    sprintf(start_info->magic, "xen-%i.%i-x86_%d%s",
   99.28 +            rc >> 16, rc & (0xFFFF), (unsigned int)sizeof(long)*8,
   99.29 +            dsi.pae_kernel ? "p" : "");
   99.30      start_info->nr_pages     = nr_pages;
   99.31      start_info->shared_info  = shared_info_frame << PAGE_SHIFT;
   99.32      start_info->flags        = flags;
   99.33 @@ -670,10 +674,8 @@ static int setup_guest(int xc_handle,
   99.34      return 0;
   99.35  
   99.36   error_out:
   99.37 -    if ( mmu != NULL )
   99.38 -        free(mmu);
   99.39 -    if ( page_array != NULL )
   99.40 -        free(page_array);
   99.41 +    free(mmu);
   99.42 +    free(page_array);
   99.43      return -1;
   99.44  }
   99.45  #endif
   99.46 @@ -768,8 +770,7 @@ int xc_linux_build(int xc_handle,
   99.47          close(initrd_fd);
   99.48      if ( initrd_gfd )
   99.49          gzclose(initrd_gfd);
   99.50 -    if ( image != NULL )
   99.51 -        free(image);
   99.52 +    free(image);
   99.53  
   99.54  #ifdef __ia64__
   99.55      /* based on new_thread in xen/arch/ia64/domain.c */
   99.56 @@ -858,9 +859,7 @@ int xc_linux_build(int xc_handle,
   99.57          gzclose(initrd_gfd);
   99.58      else if ( initrd_fd >= 0 )
   99.59          close(initrd_fd);
   99.60 -    if ( image != NULL )
   99.61 -        free(image);
   99.62 -
   99.63 +    free(image);
   99.64      return -1;
   99.65  }
   99.66  
   100.1 --- a/tools/libxc/xc_linux_restore.c	Fri Nov 18 23:06:09 2005 -0600
   100.2 +++ b/tools/libxc/xc_linux_restore.c	Fri Nov 18 23:16:29 2005 -0600
   100.3 @@ -12,16 +12,14 @@
   100.4  #include "xg_private.h"
   100.5  #include "xg_save_restore.h"
   100.6  
   100.7 -
   100.8 -
   100.9  /* max mfn of the whole machine */
  100.10 -static uint32_t max_mfn; 
  100.11 +static unsigned long max_mfn; 
  100.12  
  100.13  /* virtual starting address of the hypervisor */
  100.14 -static uint32_t hvirt_start; 
  100.15 +static unsigned long hvirt_start; 
  100.16  
  100.17  /* #levels of page tables used by the currrent guest */
  100.18 -static uint32_t pt_levels; 
  100.19 +static unsigned int pt_levels; 
  100.20  
  100.21  /* total number of pages used by the current guest */
  100.22  static unsigned long max_pfn;
  100.23 @@ -52,7 +50,6 @@ read_exact(int fd, void *buf, size_t cou
  100.24      return (r == count) ? 1 : 0; 
  100.25  }
  100.26  
  100.27 -
  100.28  /*
  100.29  ** In the state file (or during transfer), all page-table pages are 
  100.30  ** converted into a 'canonical' form where references to actual mfns 
  100.31 @@ -62,23 +59,11 @@ read_exact(int fd, void *buf, size_t cou
  100.32  */
  100.33  int uncanonicalize_pagetable(unsigned long type, void *page) 
  100.34  { 
  100.35 -    int i, pte_last, xen_start, xen_end; 
  100.36 +    int i, pte_last; 
  100.37      unsigned long pfn; 
  100.38      uint64_t pte; 
  100.39  
  100.40 -    /* 
  100.41 -    ** We need to determine which entries in this page table hold
  100.42 -    ** reserved hypervisor mappings. This depends on the current
  100.43 -    ** page table type as well as the number of paging levels. 
  100.44 -    */
  100.45 -    xen_start = xen_end = pte_last = PAGE_SIZE / ((pt_levels == 2)? 4 : 8); 
  100.46 -    
  100.47 -    if (pt_levels == 2 && type == L2TAB)
  100.48 -        xen_start = (hvirt_start >> L2_PAGETABLE_SHIFT); 
  100.49 -
  100.50 -    if (pt_levels == 3 && type == L3TAB) 
  100.51 -        xen_start = L3_PAGETABLE_ENTRIES_PAE; 
  100.52 -
  100.53 +    pte_last = PAGE_SIZE / ((pt_levels == 2)? 4 : 8); 
  100.54  
  100.55      /* Now iterate through the page table, uncanonicalizing each PTE */
  100.56      for(i = 0; i < pte_last; i++) { 
  100.57 @@ -87,13 +72,10 @@ int uncanonicalize_pagetable(unsigned lo
  100.58              pte = ((uint32_t *)page)[i]; 
  100.59          else 
  100.60              pte = ((uint64_t *)page)[i]; 
  100.61 -        
  100.62 -        if(i >= xen_start && i < xen_end) 
  100.63 -            pte = 0; 
  100.64 -        
  100.65 +
  100.66          if(pte & _PAGE_PRESENT) { 
  100.67 -            
  100.68 -            pfn = pte >> PAGE_SHIFT; 
  100.69 +
  100.70 +            pfn = (pte >> PAGE_SHIFT) & 0xffffffff;
  100.71              
  100.72              if(pfn >= max_pfn) { 
  100.73                  ERR("Frame number in type %lu page table is out of range: "
  100.74 @@ -103,17 +85,16 @@ int uncanonicalize_pagetable(unsigned lo
  100.75              } 
  100.76              
  100.77              
  100.78 -            if(type == L1TAB) 
  100.79 -                pte &= (PAGE_SIZE - 1) & ~(_PAGE_GLOBAL | _PAGE_PAT);
  100.80 -            else 
  100.81 -                pte &= (PAGE_SIZE - 1) & ~(_PAGE_GLOBAL | _PAGE_PSE);
  100.82 -            
  100.83 -            pte |= p2m[pfn] << PAGE_SHIFT;
  100.84 -            
  100.85 +            pte &= 0xffffff0000000fffULL;
  100.86 +            pte |= (uint64_t)p2m[pfn] << PAGE_SHIFT;
  100.87 +
  100.88              if(pt_levels == 2) 
  100.89                  ((uint32_t *)page)[i] = (uint32_t)pte; 
  100.90              else 
  100.91                  ((uint64_t *)page)[i] = (uint64_t)pte; 
  100.92 +
  100.93 +        
  100.94 +
  100.95          }
  100.96      }
  100.97      
  100.98 @@ -145,6 +126,9 @@ int xc_linux_restore(int xc_handle, int 
  100.99      /* A table of MFNs to map in the current region */
 100.100      unsigned long *region_mfn = NULL;
 100.101  
 100.102 +    /* Types of the pfns in the current region */
 100.103 +    unsigned long region_pfn_type[MAX_BATCH_SIZE];
 100.104 +
 100.105      /* A temporary mapping, and a copy, of one frame of guest memory. */
 100.106      unsigned long *page = NULL;
 100.107  
 100.108 @@ -162,7 +146,7 @@ int xc_linux_restore(int xc_handle, int 
 100.109      unsigned long buf[PAGE_SIZE/sizeof(unsigned long)];
 100.110  
 100.111      struct mmuext_op pin[MAX_PIN_BATCH];
 100.112 -    unsigned int nr_pins = 0;
 100.113 +    unsigned int nr_pins; 
 100.114  
 100.115  
 100.116      max_pfn = nr_pfns; 
 100.117 @@ -235,11 +219,13 @@ int xc_linux_restore(int xc_handle, int 
 100.118      
 100.119      if(xc_domain_memory_increase_reservation(
 100.120             xc_handle, dom, max_pfn, 0, 0, NULL) != 0) { 
 100.121 -        ERR("Failed to increase reservation by %lx KB\n", max_pfn); 
 100.122 +        ERR("Failed to increase reservation by %lx KB\n", PFN_TO_KB(max_pfn));
 100.123          errno = ENOMEM;
 100.124          goto out;
 100.125      }
 100.126  
 100.127 +    DPRINTF("Increased domain reservation by %lx KB\n", PFN_TO_KB(max_pfn)); 
 100.128 +
 100.129      /* Build the pfn-to-mfn table. We choose MFN ordering returned by Xen. */
 100.130      if (xc_get_pfn_list(xc_handle, dom, p2m, max_pfn) != max_pfn) {
 100.131          ERR("Did not read correct number of frame numbers for new dom");
 100.132 @@ -251,6 +237,7 @@ int xc_linux_restore(int xc_handle, int 
 100.133          goto out;
 100.134      }
 100.135  
 100.136 +
 100.137      DPRINTF("Reloading memory pages:   0%%\n");
 100.138  
 100.139      /*
 100.140 @@ -263,7 +250,6 @@ int xc_linux_restore(int xc_handle, int 
 100.141      while (1) { 
 100.142  
 100.143          int j;
 100.144 -        unsigned long region_pfn_type[MAX_BATCH_SIZE];
 100.145  
 100.146          this_pc = (n * 100) / max_pfn;
 100.147          if ( (this_pc - prev_pc) >= 5 )
 100.148 @@ -324,7 +310,7 @@ int xc_linux_restore(int xc_handle, int 
 100.149              if (pagetype == XTAB) 
 100.150                  /* a bogus/unmapped page: skip it */
 100.151                  continue;
 100.152 -            
 100.153 +
 100.154              if (pfn > max_pfn) {
 100.155                  ERR("pfn out of range");
 100.156                  goto out;
 100.157 @@ -350,10 +336,20 @@ int xc_linux_restore(int xc_handle, int 
 100.158                  ** A page table page - need to 'uncanonicalize' it, i.e. 
 100.159                  ** replace all the references to pfns with the corresponding 
 100.160                  ** mfns for the new domain. 
 100.161 -                */ 
 100.162 -                if(!uncanonicalize_pagetable(pagetype, page))
 100.163 -                    goto out; 
 100.164 +                ** 
 100.165 +                ** On PAE we need to ensure that PGDs are in MFNs < 4G, and 
 100.166 +                ** so we may need to update the p2m after the main loop. 
 100.167 +                ** Hence we defer canonicalization of L1s until then. 
 100.168 +                */
 100.169 +                if(pt_levels != 3 || pagetype != L1TAB) { 
 100.170  
 100.171 +                    if(!uncanonicalize_pagetable(pagetype, page)) {
 100.172 +                        ERR("failed uncanonicalize pt!\n"); 
 100.173 +                        goto out; 
 100.174 +                    }
 100.175 +
 100.176 +                } 
 100.177 +                    
 100.178              } else if(pagetype != NOTAB) { 
 100.179  
 100.180                  ERR("Bogus page type %lx page table is out of range: "
 100.181 @@ -363,7 +359,6 @@ int xc_linux_restore(int xc_handle, int 
 100.182              } 
 100.183  
 100.184  
 100.185 -
 100.186              if (verify) {
 100.187  
 100.188                  int res = memcmp(buf, (region_base + i*PAGE_SIZE), PAGE_SIZE);
 100.189 @@ -388,9 +383,9 @@ int xc_linux_restore(int xc_handle, int 
 100.190              }
 100.191  
 100.192              if (xc_add_mmu_update(xc_handle, mmu, 
 100.193 -                                  (mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE,
 100.194 -                                  pfn)) {
 100.195 -                ERR("machpys mfn=%ld pfn=%ld", mfn, pfn);
 100.196 +                                  (((unsigned long long)mfn) << PAGE_SHIFT) 
 100.197 +                                  | MMU_MACHPHYS_UPDATE, pfn)) {
 100.198 +                ERR("failed machpys update mfn=%lx pfn=%lx", mfn, pfn);
 100.199                  goto out;
 100.200              }
 100.201          } /* end of 'batch' for loop */
 100.202 @@ -401,14 +396,39 @@ int xc_linux_restore(int xc_handle, int 
 100.203  
 100.204      DPRINTF("Received all pages\n");
 100.205  
 100.206 -    if (pt_levels == 3) {
 100.207 +    if(pt_levels == 3) { 
 100.208  
 100.209 -        /* Get all PGDs below 4GB. */
 100.210 +        /* 
 100.211 +        ** XXX SMH on PAE we need to ensure PGDs are in MFNs < 4G. This 
 100.212 +        ** is a little awkward and involves (a) finding all such PGDs and
 100.213 +        ** replacing them with 'lowmem' versions; (b) upating the p2m[] 
 100.214 +        ** with the new info; and (c) canonicalizing all the L1s using the
 100.215 +        ** (potentially updated) p2m[]. 
 100.216 +        ** 
 100.217 +        ** This is relatively slow (and currently involves two passes through
 100.218 +        ** the pfn_type[] array), but at least seems to be correct. May wish
 100.219 +        ** to consider more complex approaches to optimize this later. 
 100.220 +        */
 100.221 +
 100.222 +        int j, k; 
 100.223 +
 100.224 +        /* First pass: find all L3TABs current in > 4G mfns and get new mfns */
 100.225          for (i = 0; i < max_pfn; i++) {
 100.226              
 100.227              if (((pfn_type[i] & LTABTYPE_MASK)==L3TAB) && (p2m[i]>0xfffffUL)) {
 100.228  
 100.229                  unsigned long new_mfn; 
 100.230 +                uint64_t l3ptes[4]; 
 100.231 +                uint64_t *l3tab; 
 100.232 +
 100.233 +                l3tab = (uint64_t *)
 100.234 +                    xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, 
 100.235 +                                         PROT_READ, p2m[i]); 
 100.236 +
 100.237 +                for(j = 0; j < 4; j++) 
 100.238 +                    l3ptes[j] = l3tab[j]; 
 100.239 +                
 100.240 +                munmap(l3tab, PAGE_SIZE); 
 100.241  
 100.242                  if (!(new_mfn=xc_make_page_below_4G(xc_handle, dom, p2m[i]))) {
 100.243                      ERR("Couldn't get a page below 4GB :-(");
 100.244 @@ -416,15 +436,58 @@ int xc_linux_restore(int xc_handle, int 
 100.245                  }
 100.246                  
 100.247                  p2m[i] = new_mfn;
 100.248 -                if (xc_add_mmu_update(
 100.249 -                        xc_handle, mmu, 
 100.250 -                        (new_mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, i)) {
 100.251 +                if (xc_add_mmu_update(xc_handle, mmu, 
 100.252 +                                      (((unsigned long long)new_mfn) 
 100.253 +                                       << PAGE_SHIFT) | 
 100.254 +                                      MMU_MACHPHYS_UPDATE, i)) {
 100.255                      ERR("Couldn't m2p on PAE root pgdir");
 100.256                      goto out;
 100.257                  }
 100.258 +                
 100.259 +                l3tab = (uint64_t *)
 100.260 +                    xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, 
 100.261 +                                         PROT_READ | PROT_WRITE, p2m[i]); 
 100.262 +                
 100.263 +                for(j = 0; j < 4; j++) 
 100.264 +                    l3tab[j] = l3ptes[j]; 
 100.265 +                
 100.266 +                munmap(l3tab, PAGE_SIZE); 
 100.267 +                
 100.268              }
 100.269          }
 100.270 -        
 100.271 +
 100.272 +        /* Second pass: find all L1TABs and uncanonicalize them */
 100.273 +        j = 0; 
 100.274 +
 100.275 +        for(i = 0; i < max_pfn; i++) { 
 100.276 +            
 100.277 +            if (((pfn_type[i] & LTABTYPE_MASK)==L1TAB)) { 
 100.278 +                region_mfn[j] = p2m[i]; 
 100.279 +                j++; 
 100.280 +            }
 100.281 +
 100.282 +            if(i == (max_pfn-1) || j == MAX_BATCH_SIZE) { 
 100.283 +
 100.284 +                if (!(region_base = xc_map_foreign_batch(
 100.285 +                          xc_handle, dom, PROT_READ | PROT_WRITE, 
 100.286 +                          region_mfn, j))) {  
 100.287 +                    ERR("map batch failed");
 100.288 +                    goto out;
 100.289 +                }
 100.290 +
 100.291 +                for(k = 0; k < j; k++) {
 100.292 +                    if(!uncanonicalize_pagetable(L1TAB, 
 100.293 +                                                 region_base + k*PAGE_SIZE)) {
 100.294 +                        ERR("failed uncanonicalize pt!\n"); 
 100.295 +                        goto out; 
 100.296 +                    } 
 100.297 +                }
 100.298 +                
 100.299 +                munmap(region_base, j*PAGE_SIZE); 
 100.300 +                j = 0; 
 100.301 +            }
 100.302 +        }
 100.303 +
 100.304      }
 100.305  
 100.306  
 100.307 @@ -433,15 +496,25 @@ int xc_linux_restore(int xc_handle, int 
 100.308          goto out;
 100.309      } 
 100.310  
 100.311 +
 100.312      /*
 100.313       * Pin page tables. Do this after writing to them as otherwise Xen
 100.314       * will barf when doing the type-checking.
 100.315       */
 100.316 +    nr_pins = 0; 
 100.317      for (i = 0; i < max_pfn; i++) {
 100.318  
 100.319 +        if (i == (max_pfn-1) || nr_pins == MAX_PIN_BATCH) {
 100.320 +            if (xc_mmuext_op(xc_handle, pin, nr_pins, dom) < 0) { 
 100.321 +                ERR("Failed to pin batch of %d page tables", nr_pins); 
 100.322 +                goto out;
 100.323 +            } 
 100.324 +            nr_pins = 0;
 100.325 +        }
 100.326 +
 100.327          if ( (pfn_type[i] & LPINTAB) == 0 )
 100.328              continue;
 100.329 -        
 100.330 +
 100.331          switch(pfn_type[i]) { 
 100.332  
 100.333          case (L1TAB|LPINTAB): 
 100.334 @@ -465,23 +538,8 @@ int xc_linux_restore(int xc_handle, int 
 100.335          }
 100.336  
 100.337          pin[nr_pins].arg1.mfn = p2m[i];
 100.338 -        
 100.339 -        if (++nr_pins == MAX_PIN_BATCH) {
 100.340 -            if (xc_mmuext_op(xc_handle, pin, nr_pins, dom) < 0) { 
 100.341 -                ERR("Failed to pin batch of %d page tables", nr_pins); 
 100.342 -                goto out;
 100.343 -            } 
 100.344 -            DPRINTF("successfully pinned batch of %d page tables", nr_pins); 
 100.345 -            nr_pins = 0;
 100.346 -        }
 100.347 -    }
 100.348 -    
 100.349 -    if (nr_pins != 0) { 
 100.350 -        if((rc = xc_mmuext_op(xc_handle, pin, nr_pins, dom)) < 0) { 
 100.351 -            ERR("Failed (2) to pin batch of %d page tables", nr_pins); 
 100.352 -            DPRINTF("rc is %d\n", rc); 
 100.353 -            goto out;
 100.354 -        }
 100.355 +        nr_pins++; 
 100.356 +
 100.357      }
 100.358  
 100.359      DPRINTF("\b\b\b\b100%%\n");
 100.360 @@ -581,23 +639,20 @@ int xc_linux_restore(int xc_handle, int 
 100.361      pfn = ctxt.ctrlreg[3] >> PAGE_SHIFT;
 100.362  
 100.363      if (pfn >= max_pfn) {
 100.364 -        DPRINTF("PT base is bad: pfn=%lu max_pfn=%lu type=%08lx\n",
 100.365 -                pfn, max_pfn, pfn_type[pfn]); 
 100.366 -        ERR("PT base is bad.");
 100.367 +        ERR("PT base is bad: pfn=%lu max_pfn=%lu type=%08lx",
 100.368 +            pfn, max_pfn, pfn_type[pfn]); 
 100.369          goto out;
 100.370      }
 100.371  
 100.372      if ((pt_levels == 2) && ((pfn_type[pfn]&LTABTYPE_MASK) != L2TAB)) { 
 100.373 -        DPRINTF("PT base is bad. pfn=%lu nr=%lu type=%08lx %08lx\n",
 100.374 -                pfn, max_pfn, pfn_type[pfn], (unsigned long)L2TAB);
 100.375 -        ERR("PT base is bad.");
 100.376 +        ERR("PT base is bad. pfn=%lu nr=%lu type=%08lx %08lx",
 100.377 +            pfn, max_pfn, pfn_type[pfn], (unsigned long)L2TAB);
 100.378          goto out;
 100.379      }
 100.380  
 100.381      if ((pt_levels == 3) && ((pfn_type[pfn]&LTABTYPE_MASK) != L3TAB)) { 
 100.382 -        DPRINTF("PT base is bad. pfn=%lu nr=%lu type=%08lx %08lx\n",
 100.383 -                pfn, max_pfn, pfn_type[pfn], (unsigned long)L3TAB);
 100.384 -        ERR("PT base is bad.");
 100.385 +        ERR("PT base is bad. pfn=%lu nr=%lu type=%08lx %08lx",
 100.386 +            pfn, max_pfn, pfn_type[pfn], (unsigned long)L3TAB);
 100.387          goto out;
 100.388      }
 100.389      
   101.1 --- a/tools/libxc/xc_linux_save.c	Fri Nov 18 23:06:09 2005 -0600
   101.2 +++ b/tools/libxc/xc_linux_save.c	Fri Nov 18 23:16:29 2005 -0600
   101.3 @@ -27,13 +27,13 @@
   101.4  
   101.5  
   101.6  /* max mfn of the whole machine */
   101.7 -static uint32_t max_mfn; 
   101.8 +static unsigned long max_mfn; 
   101.9  
  101.10  /* virtual starting address of the hypervisor */
  101.11 -static uint32_t hvirt_start; 
  101.12 +static unsigned long hvirt_start; 
  101.13  
  101.14  /* #levels of page tables used by the currrent guest */
  101.15 -static uint32_t pt_levels; 
  101.16 +static unsigned int pt_levels; 
  101.17  
  101.18  /* total number of pages used by the current guest */
  101.19  static unsigned long max_pfn;
  101.20 @@ -73,7 +73,7 @@ static unsigned long *live_m2p = NULL;
  101.21  */
  101.22  
  101.23  #define BITS_PER_LONG (sizeof(unsigned long) * 8) 
  101.24 -#define BITMAP_SIZE   ((max_pfn + BITS_PER_LONG - 1) / BITS_PER_LONG)
  101.25 +#define BITMAP_SIZE   ((max_pfn + BITS_PER_LONG - 1) / 8)
  101.26  
  101.27  #define BITMAP_ENTRY(_nr,_bmap) \
  101.28     ((unsigned long *)(_bmap))[(_nr)/BITS_PER_LONG]
  101.29 @@ -500,6 +500,70 @@ void canonicalize_pagetable(unsigned lon
  101.30  
  101.31  
  101.32  
  101.33 +static unsigned long *xc_map_m2p(int xc_handle, 
  101.34 +                                 unsigned long max_mfn, 
  101.35 +                                 int prot) 
  101.36 +{ 
  101.37 +    privcmd_m2pmfns_t m2p_mfns; 
  101.38 +    privcmd_mmap_t ioctlx; 
  101.39 +    privcmd_mmap_entry_t *entries; 
  101.40 +    unsigned long m2p_chunks, m2p_size; 
  101.41 +    unsigned long *m2p; 
  101.42 +    int i, rc; 
  101.43 +
  101.44 +    m2p_size   = M2P_SIZE(max_mfn); 
  101.45 +    m2p_chunks = M2P_CHUNKS(max_mfn); 
  101.46 +
  101.47 +
  101.48 +    m2p_mfns.num = m2p_chunks; 
  101.49 +
  101.50 +    if(!(m2p_mfns.arr = malloc(m2p_chunks * sizeof(unsigned long)))) { 
  101.51 +        ERR("failed to allocate space for m2p mfns!\n"); 
  101.52 +        return NULL; 
  101.53 +    } 
  101.54 +
  101.55 +    if (ioctl(xc_handle, IOCTL_PRIVCMD_GET_MACH2PHYS_MFNS, &m2p_mfns) < 0) {
  101.56 +        ERR("xc_get_m2p_mfns:"); 
  101.57 +        return NULL;
  101.58 +    }
  101.59 +
  101.60 +    if((m2p = mmap(NULL, m2p_size, prot, 
  101.61 +                   MAP_SHARED, xc_handle, 0)) == MAP_FAILED) {
  101.62 +        ERR("failed to mmap m2p"); 
  101.63 +        return NULL; 
  101.64 +    } 
  101.65 +    
  101.66 +
  101.67 +    if(!(entries = malloc(m2p_chunks * sizeof(privcmd_mmap_entry_t)))) { 
  101.68 +        ERR("failed to allocate space for mmap entries!\n"); 
  101.69 +        return NULL; 
  101.70 +    } 
  101.71 +
  101.72 +
  101.73 +    ioctlx.num   = m2p_chunks;
  101.74 +    ioctlx.dom   = DOMID_XEN; 
  101.75 +    ioctlx.entry = entries; 
  101.76 +    
  101.77 +    for(i=0; i < m2p_chunks; i++) { 
  101.78 +        
  101.79 +        entries[i].va = (unsigned long)(((void *)m2p) + (i * M2P_CHUNK_SIZE)); 
  101.80 +        entries[i].mfn = m2p_mfns.arr[i]; 
  101.81 +        entries[i].npages = M2P_CHUNK_SIZE >> PAGE_SHIFT;
  101.82 +
  101.83 +    }
  101.84 +
  101.85 +    if((rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx)) < 0) {
  101.86 +        ERR("ioctl_mmap failed (rc = %d)", rc); 
  101.87 +        return NULL; 
  101.88 +    }
  101.89 +        
  101.90 +    free(m2p_mfns.arr); 
  101.91 +    free(entries); 
  101.92 +
  101.93 +    return m2p; 
  101.94 +}
  101.95 +
  101.96 +
  101.97  
  101.98  int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, 
  101.99                    uint32_t max_factor, uint32_t flags)
 101.100 @@ -531,16 +595,12 @@ int xc_linux_save(int xc_handle, int io_
 101.101      /* A copy of the pfn-to-mfn table frame list. */
 101.102      unsigned long *p2m_frame_list = NULL;
 101.103  
 101.104 -    unsigned long m2p_start_mfn;
 101.105 -    
 101.106      /* Live mapping of shared info structure */
 101.107      shared_info_t *live_shinfo = NULL;
 101.108  
 101.109      /* base of the region in which domain memory is mapped */
 101.110      unsigned char *region_base = NULL;
 101.111  
 101.112 -
 101.113 -    
 101.114      /* power of 2 order of max_pfn */
 101.115      int order_nr; 
 101.116  
 101.117 @@ -564,9 +624,6 @@ int xc_linux_save(int xc_handle, int io_
 101.118      
 101.119      initialize_mbit_rate(); 
 101.120  
 101.121 -    DPRINTF("xc_linux_save start DOM%u live=%s\n", dom, live ? 
 101.122 -            "true" : "false"); 
 101.123 -
 101.124      if(!get_platform_info(xc_handle, dom, 
 101.125                            &max_mfn, &hvirt_start, &pt_levels)) {
 101.126          ERR("Unable to get platform info."); 
 101.127 @@ -647,11 +704,13 @@ int xc_linux_save(int xc_handle, int io_
 101.128      }
 101.129  
 101.130      /* Setup the mfn_to_pfn table mapping */
 101.131 -    m2p_start_mfn = xc_get_m2p_start_mfn(xc_handle);
 101.132 -    live_m2p      = xc_map_foreign_range(xc_handle, DOMID_XEN, M2P_SIZE, 
 101.133 -                                         PROT_READ, m2p_start_mfn);
 101.134 +    if(!(live_m2p = xc_map_m2p(xc_handle, max_mfn, PROT_READ))) { 
 101.135 +        ERR("Failed to map live M2P table"); 
 101.136 +        goto out; 
 101.137 +    } 
 101.138 +
 101.139      
 101.140 -    /* Get a local copy fo the live_P2M_frame_list */
 101.141 +    /* Get a local copy of the live_P2M_frame_list */
 101.142      if(!(p2m_frame_list = malloc(P2M_FL_SIZE))) { 
 101.143          ERR("Couldn't allocate p2m_frame_list array");
 101.144          goto out;
 101.145 @@ -662,12 +721,19 @@ int xc_linux_save(int xc_handle, int io_
 101.146      for (i = 0; i < max_pfn; i += ulpp) {
 101.147          if (!translate_mfn_to_pfn(&p2m_frame_list[i/ulpp])) { 
 101.148              ERR("Frame# in pfn-to-mfn frame list is not in pseudophys");
 101.149 +            ERR("entry %d: p2m_frame_list[%ld] is 0x%lx", i, i/ulpp, 
 101.150 +                p2m_frame_list[i/ulpp]); 
 101.151              goto out;
 101.152          }
 101.153      }
 101.154  
 101.155      /* Domain is still running at this point */
 101.156  
 101.157 +    if (live && (pt_levels != 2)) {
 101.158 +        ERR("Live migration supported only for 32-bit non-pae");
 101.159 +        goto out;
 101.160 +    }
 101.161 +
 101.162      if (live) {
 101.163  
 101.164          if (xc_shadow_control(xc_handle, dom, 
 101.165 @@ -693,11 +759,8 @@ int xc_linux_save(int xc_handle, int io_
 101.166          
 101.167      }
 101.168  
 101.169 -#if 0
 101.170 -    sent_last_iter = 0xFFFFFFFF; /* Pretend we sent a /lot/ last time */
 101.171 -#else
 101.172 -    sent_last_iter = 1 << 20; 
 101.173 -#endif
 101.174 +    /* pretend we sent all the pages last iteration */
 101.175 +    sent_last_iter = max_pfn; 
 101.176  
 101.177  
 101.178      /* calculate the power of 2 order of max_pfn, e.g.
 101.179 @@ -705,9 +768,6 @@ int xc_linux_save(int xc_handle, int io_
 101.180      for (i = max_pfn-1, order_nr = 0; i ; i >>= 1, order_nr++)
 101.181          continue;
 101.182  
 101.183 -#undef BITMAP_SIZE
 101.184 -#define BITMAP_SIZE ((1<<20)/8) 
 101.185 -
 101.186      /* Setup to_send / to_fix and to_skip bitmaps */
 101.187      to_send = malloc(BITMAP_SIZE); 
 101.188      to_fix  = calloc(1, BITMAP_SIZE); 
 101.189 @@ -922,10 +982,8 @@ int xc_linux_save(int xc_handle, int io_
 101.190  
 101.191  
 101.192                  /* write out pages in batch */
 101.193 -                if (pagetype == XTAB) {
 101.194 -                    DPRINTF("SKIP BOGUS page %i mfn %08lx\n", j, pfn_type[j]);
 101.195 +                if (pagetype == XTAB)
 101.196                      continue;
 101.197 -                }
 101.198  
 101.199                  pagetype &= LTABTYPE_MASK; 
 101.200                  
 101.201 @@ -950,11 +1008,11 @@ int xc_linux_save(int xc_handle, int io_
 101.202              } /* end of the write out for this batch */
 101.203              
 101.204              sent_this_iter += batch;
 101.205 -            
 101.206 +
 101.207 +            munmap(region_base, batch*PAGE_SIZE);
 101.208 +        
 101.209          } /* end of this while loop for this iteration */
 101.210          
 101.211 -        munmap(region_base, batch*PAGE_SIZE);
 101.212 -        
 101.213        skip: 
 101.214          
 101.215          total_sent += sent_this_iter;
 101.216 @@ -1027,13 +1085,9 @@ int xc_linux_save(int xc_handle, int io_
 101.217  
 101.218      DPRINTF("All memory is saved\n");
 101.219  
 101.220 -    /* Success! */
 101.221 -    rc = 0;
 101.222 -    
 101.223 -    /* ^^^^^^ XXX SMH: hmm.. not sure that's really success! */
 101.224 -    
 101.225      /* Zero terminate */
 101.226 -    if (!write_exact(io_fd, &rc, sizeof(int))) { 
 101.227 +    i = 0; 
 101.228 +    if (!write_exact(io_fd, &i, sizeof(int))) { 
 101.229          ERR("Error when writing to state file (6)");
 101.230          goto out;
 101.231      }
 101.232 @@ -1043,17 +1097,17 @@ int xc_linux_save(int xc_handle, int io_
 101.233          unsigned int i,j;
 101.234          unsigned long pfntab[1024]; 
 101.235  
 101.236 -        for ( i = 0, j = 0; i < max_pfn; i++ ) {
 101.237 -            if ( ! is_mapped(live_p2m[i]) )
 101.238 +        for (i = 0, j = 0; i < max_pfn; i++) {
 101.239 +            if (!is_mapped(live_p2m[i]))
 101.240                  j++;
 101.241          }
 101.242 -
 101.243 +        
 101.244          if(!write_exact(io_fd, &j, sizeof(unsigned int))) { 
 101.245              ERR("Error when writing to state file (6a)");
 101.246              goto out;
 101.247          }	
 101.248          
 101.249 -        for ( i = 0, j = 0; i < max_pfn; ) {
 101.250 +        for (i = 0, j = 0; i < max_pfn; ) {
 101.251  
 101.252              if (!is_mapped(live_p2m[i]))
 101.253                  pfntab[j++] = i;
 101.254 @@ -1097,7 +1151,10 @@ int xc_linux_save(int xc_handle, int io_
 101.255          ERR("Error when writing to state file (1)");
 101.256          goto out;
 101.257      }
 101.258 -    
 101.259 +
 101.260 +    /* Success! */
 101.261 +    rc = 0;
 101.262 +
 101.263   out:
 101.264  
 101.265      if (live_shinfo)
 101.266 @@ -1110,7 +1167,7 @@ int xc_linux_save(int xc_handle, int io_
 101.267          munmap(live_p2m, P2M_SIZE); 
 101.268  
 101.269      if(live_m2p) 
 101.270 -        munmap(live_m2p, M2P_SIZE); 
 101.271 +        munmap(live_m2p, M2P_SIZE(max_mfn)); 
 101.272  
 101.273      free(pfn_type);
 101.274      free(pfn_batch);
   102.1 --- a/tools/libxc/xc_private.c	Fri Nov 18 23:06:09 2005 -0600
   102.2 +++ b/tools/libxc/xc_private.c	Fri Nov 18 23:16:29 2005 -0600
   102.3 @@ -260,18 +260,6 @@ long long xc_domain_get_cpu_usage( int x
   102.4  }
   102.5  
   102.6  
   102.7 -unsigned long xc_get_m2p_start_mfn ( int xc_handle )
   102.8 -{
   102.9 -    unsigned long mfn;
  102.10 -
  102.11 -    if ( ioctl( xc_handle, IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN, &mfn ) < 0 )
  102.12 -    {
  102.13 -        perror("xc_get_m2p_start_mfn:");
  102.14 -        return 0;
  102.15 -    }
  102.16 -    return mfn;
  102.17 -}
  102.18 -
  102.19  int xc_get_pfn_list(int xc_handle,
  102.20                      uint32_t domid, 
  102.21                      unsigned long *pfn_buf, 
  102.22 @@ -336,6 +324,19 @@ int xc_copy_to_domain_page(int xc_handle
  102.23      return 0;
  102.24  }
  102.25  
  102.26 +int xc_clear_domain_page(int xc_handle,
  102.27 +                         uint32_t domid,
  102.28 +                         unsigned long dst_pfn)
  102.29 +{
  102.30 +    void *vaddr = xc_map_foreign_range(
  102.31 +        xc_handle, domid, PAGE_SIZE, PROT_WRITE, dst_pfn);
  102.32 +    if ( vaddr == NULL )
  102.33 +        return -1;
  102.34 +    memset(vaddr, 0, PAGE_SIZE);
  102.35 +    munmap(vaddr, PAGE_SIZE);
  102.36 +    return 0;
  102.37 +}
  102.38 +
  102.39  unsigned long xc_get_filesz(int fd)
  102.40  {
  102.41      uint16_t sig;
  102.42 @@ -389,11 +390,21 @@ int xc_version(int xc_handle, int cmd, v
  102.43  
  102.44      switch ( cmd )
  102.45      {
  102.46 -    case XENVER_extraversion: argsize = sizeof(xen_extraversion_t); break;
  102.47 -    case XENVER_compile_info: argsize = sizeof(xen_compile_info_t); break;
  102.48 -    case XENVER_capabilities: argsize = sizeof(xen_capabilities_info_t); break;
  102.49 -    case XENVER_changeset:    argsize = sizeof(xen_changeset_info_t); break;
  102.50 -    case XENVER_parameters:   argsize = sizeof(xen_parameters_info_t); break;
  102.51 +    case XENVER_extraversion:
  102.52 +        argsize = sizeof(xen_extraversion_t);
  102.53 +        break;
  102.54 +    case XENVER_compile_info:
  102.55 +        argsize = sizeof(xen_compile_info_t);
  102.56 +        break;
  102.57 +    case XENVER_capabilities:
  102.58 +        argsize = sizeof(xen_capabilities_info_t);
  102.59 +        break;
  102.60 +    case XENVER_changeset:
  102.61 +        argsize = sizeof(xen_changeset_info_t);
  102.62 +        break;
  102.63 +    case XENVER_platform_parameters:
  102.64 +        argsize = sizeof(xen_platform_parameters_t);
  102.65 +        break;
  102.66      }
  102.67  
  102.68      if ( (argsize != 0) && (mlock(arg, argsize) != 0) )
   103.1 --- a/tools/libxc/xc_vmx_build.c	Fri Nov 18 23:06:09 2005 -0600
   103.2 +++ b/tools/libxc/xc_vmx_build.c	Fri Nov 18 23:16:29 2005 -0600
   103.3 @@ -495,6 +495,9 @@ static int setup_guest(int xc_handle,
   103.4      }
   103.5  
   103.6      *store_mfn = page_array[(v_end-2) >> PAGE_SHIFT];
   103.7 +    if ( xc_clear_domain_page(xc_handle, dom, *store_mfn) )
   103.8 +        goto error_out;
   103.9 +
  103.10      shared_page_frame = (v_end - PAGE_SIZE) >> PAGE_SHIFT;
  103.11  
  103.12      if ((e820_page = xc_map_foreign_range(
  103.13 @@ -627,7 +630,7 @@ int xc_vmx_build(int xc_handle,
  103.14  
  103.15      if ( mlock(&st_ctxt, sizeof(st_ctxt) ) )
  103.16      {
  103.17 -        PERROR("xc_vmx_build: ctxt mlock failed");
  103.18 +        PERROR("%s: ctxt mlock failed", __func__);
  103.19          return 1;
  103.20      }
  103.21  
  103.22 @@ -708,7 +711,6 @@ int xc_vmx_build(int xc_handle,
  103.23  
  103.24   error_out:
  103.25      free(image);
  103.26 -
  103.27      return -1;
  103.28  }
  103.29  
   104.1 --- a/tools/libxc/xenctrl.h	Fri Nov 18 23:06:09 2005 -0600
   104.2 +++ b/tools/libxc/xenctrl.h	Fri Nov 18 23:16:29 2005 -0600
   104.3 @@ -424,6 +424,9 @@ int xc_ia64_get_pfn_list(int xc_handle, 
   104.4  int xc_copy_to_domain_page(int xc_handle, uint32_t domid,
   104.5  			   unsigned long dst_pfn, void *src_page);
   104.6  
   104.7 +int xc_clear_domain_page(int xc_handle, uint32_t domid,
   104.8 +                         unsigned long dst_pfn);
   104.9 +
  104.10  int xc_ia64_copy_to_domain_pages(int xc_handle, uint32_t domid,
  104.11          void* src_page, unsigned long dst_pfn, int nr_pages);
  104.12  
   105.1 --- a/tools/libxc/xg_private.h	Fri Nov 18 23:06:09 2005 -0600
   105.2 +++ b/tools/libxc/xg_private.h	Fri Nov 18 23:16:29 2005 -0600
   105.3 @@ -153,8 +153,6 @@ typedef struct mfn_mapper {
   105.4      
   105.5  } mfn_mapper_t;
   105.6  
   105.7 -unsigned long xc_get_m2p_start_mfn (int xc_handle);
   105.8 -
   105.9  int xc_copy_to_domain_page(int xc_handle, uint32_t domid,
  105.10                              unsigned long dst_pfn, void *src_page);
  105.11  
   106.1 --- a/tools/libxc/xg_save_restore.h	Fri Nov 18 23:06:09 2005 -0600
   106.2 +++ b/tools/libxc/xg_save_restore.h	Fri Nov 18 23:16:29 2005 -0600
   106.3 @@ -4,6 +4,8 @@
   106.4  ** Defintions and utilities for save / restore. 
   106.5  */
   106.6  
   106.7 +#include "xc_private.h"
   106.8 +
   106.9  #define DEBUG    1
  106.10  #define PROGRESS 0
  106.11  
  106.12 @@ -55,26 +57,25 @@ while (0)
  106.13  ** Returns 1 on success, 0 on failure. 
  106.14  */
  106.15  static int get_platform_info(int xc_handle, uint32_t dom, 
  106.16 -                             /* OUT */ uint32_t *max_mfn,  
  106.17 -                             /* OUT */ uint32_t *hvirt_start, 
  106.18 -                             /* OUT */ uint32_t *pt_levels)
  106.19 +                             /* OUT */ unsigned long *max_mfn,  
  106.20 +                             /* OUT */ unsigned long *hvirt_start, 
  106.21 +                             /* OUT */ unsigned int *pt_levels)
  106.22      
  106.23  { 
  106.24      xen_capabilities_info_t xen_caps = "";
  106.25 -    xen_parameters_info_t xen_parms;
  106.26 -    xc_physinfo_t physinfo;
  106.27 +    xen_platform_parameters_t xen_params;
  106.28      
  106.29 -    if (xc_physinfo(xc_handle, &physinfo) != 0) 
  106.30 -        return 0;
  106.31 -    
  106.32 -    if (xc_version(xc_handle, XENVER_parameters, &xen_parms) != 0)
  106.33 +
  106.34 +    if (xc_version(xc_handle, XENVER_platform_parameters, &xen_params) != 0)
  106.35          return 0;
  106.36      
  106.37      if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0)
  106.38          return 0;
  106.39  
  106.40 -    *max_mfn =     physinfo.total_pages;
  106.41 -    *hvirt_start = xen_parms.virt_start;
  106.42 +    if (xc_memory_op(xc_handle, XENMEM_maximum_ram_page, max_mfn) != 0)
  106.43 +        return 0; 
  106.44 +    
  106.45 +    *hvirt_start = xen_params.virt_start;
  106.46  
  106.47      if (strstr(xen_caps, "xen-3.0-x86_64"))
  106.48          *pt_levels = 4;
  106.49 @@ -95,13 +96,22 @@ static int get_platform_info(int xc_hand
  106.50  ** entry tell us whether or not the the PFN is currently mapped.
  106.51  */
  106.52  
  106.53 -#define PFN_TO_KB(_pfn) ((_pfn) * PAGE_SIZE / 1024)
  106.54 +#define PFN_TO_KB(_pfn) ((_pfn) << (PAGE_SHIFT - 10))
  106.55  #define ROUNDUP(_x,_w) (((unsigned long)(_x)+(1UL<<(_w))-1) & ~((1UL<<(_w))-1))
  106.56  
  106.57 -/* Size in bytes of the M2P and P2M (both rounded up to nearest PAGE_SIZE) */
  106.58 -#define M2P_SIZE ROUNDUP((max_mfn * sizeof(unsigned long)), PAGE_SHIFT) 
  106.59 -#define P2M_SIZE ROUNDUP((max_pfn * sizeof(unsigned long)), PAGE_SHIFT) 
  106.60  
  106.61 +/* 
  106.62 +** The M2P is made up of some number of 'chunks' of at least 2MB in size. 
  106.63 +** The below definitions and utility function(s) deal with mapping the M2P 
  106.64 +** regarldess of the underlying machine memory size or architecture. 
  106.65 +*/
  106.66 +#define M2P_SHIFT       L2_PAGETABLE_SHIFT_PAE 
  106.67 +#define M2P_CHUNK_SIZE  (1 << M2P_SHIFT) 
  106.68 +#define M2P_SIZE(_m)    ROUNDUP(((_m) * sizeof(unsigned long)), M2P_SHIFT) 
  106.69 +#define M2P_CHUNKS(_m)  (M2P_SIZE((_m)) >> M2P_SHIFT)
  106.70 +
  106.71 +/* Size in bytes of the P2M (rounded up to the nearest PAGE_SIZE bytes) */
  106.72 +#define P2M_SIZE        ROUNDUP((max_pfn * sizeof(unsigned long)), PAGE_SHIFT) 
  106.73  
  106.74  /* Number of unsigned longs in a page */
  106.75  #define ulpp            (PAGE_SIZE/sizeof(unsigned long))
   107.1 --- a/tools/pygrub/setup.py	Fri Nov 18 23:06:09 2005 -0600
   107.2 +++ b/tools/pygrub/setup.py	Fri Nov 18 23:16:29 2005 -0600
   107.3 @@ -34,6 +34,8 @@ if os.path.exists("/usr/include/reiserfs
   107.4      fsys_mods.append(reiser)
   107.5      fsys_pkgs.append("grub.fsys.reiser")
   107.6  
   107.7 +pkgs = ['grub', 'grub.fsys']
   107.8 +pkgs.extend(fsys_pkgs)
   107.9  setup(name='pygrub',
  107.10        version='0.3',
  107.11        description='Boot loader that looks a lot like grub for Xen',
  107.12 @@ -42,8 +44,7 @@ setup(name='pygrub',
  107.13        license='GPL',
  107.14        package_dir={'grub': 'src'},
  107.15        scripts = ["src/pygrub"],
  107.16 -      packages=['grub',
  107.17 -                'grub.fsys'].extend(fsys_pkgs),
  107.18 +      packages=pkgs,
  107.19        ext_modules = fsys_mods
  107.20        )
  107.21                 
   108.1 --- a/tools/pygrub/src/pygrub	Fri Nov 18 23:06:09 2005 -0600
   108.2 +++ b/tools/pygrub/src/pygrub	Fri Nov 18 23:16:29 2005 -0600
   108.3 @@ -89,8 +89,8 @@ def get_active_offset(file):
   108.4      buf = os.read(fd, 512)
   108.5      for poff in (446, 462, 478, 494): # partition offsets
   108.6          # active partition has 0x80 as the first byte
   108.7 -        if struct.unpack("<c", buf[p:p+1]) == ('\x80',):
   108.8 -            return struct.unpack("<", buf[p+8:p+12])[0] * SECTOR_SIZE
   108.9 +        if struct.unpack("<c", buf[poff:poff+1]) == ('\x80',):
  108.10 +            return struct.unpack("<L", buf[poff+8:poff+12])[0] * SECTOR_SIZE
  108.11      return -1
  108.12  
  108.13  def get_config(fn):
  108.14 @@ -113,11 +113,13 @@ def get_config(fn):
  108.15              break
  108.16  
  108.17      if fs is not None:
  108.18 -        if fs.file_exist("/boot/grub/menu.lst"):
  108.19 -            grubfile = "/boot/grub/menu.lst"
  108.20 -        elif fs.file_exist("/boot/grub/grub.conf"):
  108.21 -            grubfile = "/boot/grub/grub.conf"
  108.22 -        else:
  108.23 +        grubfile = None
  108.24 +        for f in ("/boot/grub/menu.lst", "/boot/grub/grub.conf",
  108.25 +                  "/grub/menu.lst", "/grub/grub.conf"):
  108.26 +            if fs.file_exist(f):
  108.27 +                grubfile = f
  108.28 +                break
  108.29 +        if grubfile is None:
  108.30              raise RuntimeError, "we couldn't find /boot/grub{menu.lst,grub.conf} " + \
  108.31                                  "in the image provided. halt!"
  108.32          f = fs.open_file(grubfile)
  108.33 @@ -169,7 +171,7 @@ def main(cf = None):
  108.34  #        if c == ord('q'):
  108.35  #            selected = -1
  108.36  #            break
  108.37 -        elif c == ord('c'):
  108.38 +        if c == ord('c'):
  108.39              # FIXME: needs to go to command line mode
  108.40              continue
  108.41          elif c == ord('a'):
  108.42 @@ -261,7 +263,7 @@ if __name__ == "__main__":
  108.43  
  108.44      offset = 0
  108.45      if is_disk_image(file):
  108.46 -        offset = get_active_offset(fn)
  108.47 +        offset = get_active_offset(file)
  108.48          if offset == -1:
  108.49              raise RuntimeError, "Unable to find active partition on disk"
  108.50  
   109.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Fri Nov 18 23:06:09 2005 -0600
   109.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Fri Nov 18 23:16:29 2005 -0600
   109.3 @@ -49,19 +49,16 @@ static PyObject *pyxc_domain_dumpcore(Py
   109.4  
   109.5      if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is", kwd_list,
   109.6                                        &dom, &corefile) )
   109.7 -        goto exit;
   109.8 +        return NULL;
   109.9  
  109.10      if ( (corefile == NULL) || (corefile[0] == '\0') )
  109.11 -        goto exit;
  109.12 +        return NULL;
  109.13  
  109.14      if ( xc_domain_dumpcore(xc->xc_handle, dom, corefile) != 0 )
  109.15          return PyErr_SetFromErrno(xc_error);
  109.16      
  109.17      Py_INCREF(zero);
  109.18      return zero;
  109.19 -
  109.20 - exit:
  109.21 -    return NULL;
  109.22  }
  109.23  
  109.24  static PyObject *pyxc_handle(PyObject *self)
  109.25 @@ -95,12 +92,7 @@ static PyObject *pyxc_domain_create(PyOb
  109.26      {
  109.27          if ( !PyList_Check(pyhandle) || 
  109.28               (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) )
  109.29 -        {
  109.30 -        out_exception:
  109.31 -            errno = EINVAL;
  109.32 -            PyErr_SetFromErrno(xc_error);
  109.33 -            return NULL;
  109.34 -        }
  109.35 +            goto out_exception;
  109.36  
  109.37          for ( i = 0; i < sizeof(xen_domain_handle_t); i++ )
  109.38          {
  109.39 @@ -115,6 +107,11 @@ static PyObject *pyxc_domain_create(PyOb
  109.40          return PyErr_SetFromErrno(xc_error);
  109.41  
  109.42      return PyInt_FromLong(dom);
  109.43 +
  109.44 +out_exception:
  109.45 +    errno = EINVAL;
  109.46 +    PyErr_SetFromErrno(xc_error);
  109.47 +    return NULL;
  109.48  }
  109.49  
  109.50  static PyObject *pyxc_domain_max_vcpus(PyObject *self,
  109.51 @@ -270,10 +267,7 @@ static PyObject *pyxc_domain_sethandle(P
  109.52      if ( !PyList_Check(pyhandle) || 
  109.53           (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) )
  109.54      {
  109.55 -    out_exception:
  109.56 -        errno = EINVAL;
  109.57 -        PyErr_SetFromErrno(xc_error);
  109.58 -        return NULL;
  109.59 +        goto out_exception;
  109.60      }
  109.61  
  109.62      for ( i = 0; i < sizeof(xen_domain_handle_t); i++ )
  109.63 @@ -289,8 +283,14 @@ static PyObject *pyxc_domain_sethandle(P
  109.64      
  109.65      Py_INCREF(zero);
  109.66      return zero;
  109.67 +
  109.68 +out_exception:
  109.69 +    errno = EINVAL;
  109.70 +    PyErr_SetFromErrno(xc_error);
  109.71 +    return NULL;
  109.72  }
  109.73  
  109.74 +
  109.75  static PyObject *pyxc_domain_getinfo(PyObject *self,
  109.76                                       PyObject *args,
  109.77                                       PyObject *kwds)
  109.78 @@ -721,7 +721,7 @@ static PyObject *pyxc_xeninfo(PyObject *
  109.79      xen_compile_info_t xen_cc;
  109.80      xen_changeset_info_t xen_chgset;
  109.81      xen_capabilities_info_t xen_caps;
  109.82 -    xen_parameters_info_t xen_parms;
  109.83 +    xen_platform_parameters_t p_parms;
  109.84      long xen_version;
  109.85      char str[128];
  109.86  
  109.87 @@ -739,17 +739,17 @@ static PyObject *pyxc_xeninfo(PyObject *
  109.88      if ( xc_version(xc->xc_handle, XENVER_capabilities, &xen_caps) != 0 )
  109.89          return PyErr_SetFromErrno(xc_error);
  109.90  
  109.91 -    if ( xc_version(xc->xc_handle, XENVER_parameters, &xen_parms) != 0 )
  109.92 +    if ( xc_version(xc->xc_handle, XENVER_platform_parameters, &p_parms) != 0 )
  109.93          return PyErr_SetFromErrno(xc_error);
  109.94  
  109.95 -    sprintf(str,"virt_start=0x%lx",xen_parms.virt_start);
  109.96 +    sprintf(str, "virt_start=0x%lx", p_parms.virt_start);
  109.97  
  109.98      return Py_BuildValue("{s:i,s:i,s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:s}",
  109.99                           "xen_major", xen_version >> 16,
 109.100                           "xen_minor", (xen_version & 0xffff),
 109.101                           "xen_extra", xen_extra,
 109.102                           "xen_caps",  xen_caps,
 109.103 -                         "xen_params", str,
 109.104 +                         "platform_params", str,
 109.105                           "xen_changeset", xen_chgset,
 109.106                           "cc_compiler", xen_cc.compiler,
 109.107                           "cc_compile_by", xen_cc.compile_by,
   110.1 --- a/tools/python/xen/lowlevel/xs/xs.c	Fri Nov 18 23:06:09 2005 -0600
   110.2 +++ b/tools/python/xen/lowlevel/xs/xs.c	Fri Nov 18 23:16:29 2005 -0600
   110.3 @@ -16,11 +16,12 @@
   110.4   *
   110.5   * Copyright (C) 2005 Mike Wray Hewlett-Packard
   110.6   * Copyright (C) 2005 Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
   110.7 - *
   110.8 + * Copyright (C) 2005 XenSource Ltd.
   110.9   */
  110.10  
  110.11  #include <Python.h>
  110.12  
  110.13 +#include <stdbool.h>
  110.14  #include <stdio.h>
  110.15  #include <stdlib.h>
  110.16  #include <unistd.h>
  110.17 @@ -70,6 +71,17 @@ static inline PyObject *pyvalue_str(char
  110.18              : PyErr_SetFromErrno(PyExc_RuntimeError));
  110.19  }
  110.20  
  110.21 +static void remove_watch(XsHandle *xsh, PyObject *token);
  110.22 +
  110.23 +static PyObject *none(bool result);
  110.24 +
  110.25 +static int parse_transaction_path(PyObject *self, PyObject *args,
  110.26 +                                  PyObject *kwds,
  110.27 +                                  struct xs_handle **xh,
  110.28 +                                  struct xs_transaction_handle **th,
  110.29 +                                  char **path);
  110.30 +
  110.31 +
  110.32  #define xspy_read_doc "\n"			\
  110.33  	"Read data from a path.\n"		\
  110.34  	" path [string]: xenstore path\n"	\
  110.35 @@ -81,44 +93,30 @@ static inline PyObject *pyvalue_str(char
  110.36  
  110.37  static PyObject *xspy_read(PyObject *self, PyObject *args, PyObject *kwds)
  110.38  {
  110.39 -    static char *kwd_spec[] = { "transaction", "path", NULL };
  110.40 -    static char *arg_spec = "ss";
  110.41 -    char *path = NULL;
  110.42 -
  110.43 -    struct xs_handle *xh = xshandle(self);
  110.44 -    char *xsval = NULL;
  110.45 -    unsigned int xsval_n = 0;
  110.46 -    PyObject *val = NULL;
  110.47 -
  110.48 +    struct xs_handle *xh;
  110.49      struct xs_transaction_handle *th;
  110.50 -    char *thstr;
  110.51 +    char *path;
  110.52  
  110.53 -    if (!xh)
  110.54 -        goto exit;
  110.55 -    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
  110.56 -                                     &thstr, &path))
  110.57 -        goto exit;
  110.58 +    char *xsval;
  110.59 +    unsigned int xsval_n;
  110.60  
  110.61 -    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
  110.62 +    if (!parse_transaction_path(self, args, kwds, &xh, &th, &path))
  110.63 +        return NULL;
  110.64  
  110.65      Py_BEGIN_ALLOW_THREADS
  110.66      xsval = xs_read(xh, th, path, &xsval_n);
  110.67      Py_END_ALLOW_THREADS
  110.68 -    if (!xsval) {
  110.69 -        if (errno == ENOENT) {
  110.70 -            Py_INCREF(Py_None);
  110.71 -            val = Py_None;
  110.72 -        } else
  110.73 -            PyErr_SetFromErrno(PyExc_RuntimeError);
  110.74 -        goto exit;
  110.75 +    if (xsval) {
  110.76 +        PyObject *val = PyString_FromStringAndSize(xsval, xsval_n);
  110.77 +        free(xsval);
  110.78 +        return val;
  110.79      }
  110.80 -    val = PyString_FromStringAndSize(xsval, xsval_n);
  110.81 - exit:
  110.82 -    if (xsval)
  110.83 -        free(xsval);
  110.84 -    return val;
  110.85 +    else {
  110.86 +        return none(errno == ENOENT);
  110.87 +    }
  110.88  }
  110.89  
  110.90 +
  110.91  #define xspy_write_doc "\n"					\
  110.92  	"Write data to a path.\n"				\
  110.93  	" path   [string] : xenstore path to write to\n."	\
  110.94 @@ -137,33 +135,27 @@ static PyObject *xspy_write(PyObject *se
  110.95      int data_n = 0;
  110.96  
  110.97      struct xs_handle *xh = xshandle(self);
  110.98 -    PyObject *val = NULL;
  110.99 -    int xsval = 0;
 110.100 +    bool result;
 110.101  
 110.102      struct xs_transaction_handle *th;
 110.103      char *thstr;
 110.104  
 110.105      if (!xh)
 110.106 -        goto exit;
 110.107 +        return NULL;
 110.108      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
 110.109                                       &thstr, &path, &data, &data_n))
 110.110 -        goto exit;
 110.111 +        return NULL;
 110.112  
 110.113      th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
 110.114  
 110.115      Py_BEGIN_ALLOW_THREADS
 110.116 -    xsval = xs_write(xh, th, path, data, data_n);
 110.117 +    result = xs_write(xh, th, path, data, data_n);
 110.118      Py_END_ALLOW_THREADS
 110.119 -    if (!xsval) {
 110.120 -        PyErr_SetFromErrno(PyExc_RuntimeError);
 110.121 -        goto exit;
 110.122 -    }
 110.123 -    Py_INCREF(Py_None);
 110.124 -    val = Py_None;
 110.125 - exit:
 110.126 -    return val;
 110.127 +
 110.128 +    return none(result);
 110.129  }
 110.130  
 110.131 +
 110.132  #define xspy_ls_doc "\n"					\
 110.133  	"List a directory.\n"					\
 110.134  	" path [string]: path to list.\n"			\
 110.135 @@ -175,47 +167,34 @@ static PyObject *xspy_write(PyObject *se
 110.136  
 110.137  static PyObject *xspy_ls(PyObject *self, PyObject *args, PyObject *kwds)
 110.138  {
 110.139 -    static char *kwd_spec[] = { "transaction", "path", NULL };
 110.140 -    static char *arg_spec = "ss";
 110.141 -    char *path = NULL;
 110.142 -
 110.143 -    struct xs_handle *xh = xshandle(self);
 110.144 -    PyObject *val = NULL;
 110.145 -    char **xsval = NULL;
 110.146 -    unsigned int xsval_n = 0;
 110.147 -    int i;
 110.148 -
 110.149 +    struct xs_handle *xh;
 110.150      struct xs_transaction_handle *th;
 110.151 -    char *thstr;
 110.152 +    char *path;
 110.153  
 110.154 -    if (!xh)
 110.155 -        goto exit;
 110.156 -    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
 110.157 -                                     &thstr, &path))
 110.158 -        goto exit;
 110.159 +    char **xsval;
 110.160 +    int xsval_n;
 110.161  
 110.162 -
 110.163 -    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
 110.164 +    if (!parse_transaction_path(self, args, kwds, &xh, &th, &path))
 110.165 +        return NULL;
 110.166  
 110.167      Py_BEGIN_ALLOW_THREADS
 110.168      xsval = xs_directory(xh, th, path, &xsval_n);
 110.169      Py_END_ALLOW_THREADS
 110.170 -    if (!xsval) {
 110.171 -        if (errno == ENOENT) {
 110.172 -            Py_INCREF(Py_None);
 110.173 -            val = Py_None;
 110.174 -        } else
 110.175 -            PyErr_SetFromErrno(PyExc_RuntimeError);
 110.176 -	goto exit;
 110.177 +
 110.178 +    if (xsval) {
 110.179 +        int i;
 110.180 +        PyObject *val = PyList_New(xsval_n);
 110.181 +        for (i = 0; i < xsval_n; i++)
 110.182 +            PyList_SetItem(val, i, PyString_FromString(xsval[i]));
 110.183 +        free(xsval);
 110.184 +        return val;
 110.185      }
 110.186 -    val = PyList_New(xsval_n);
 110.187 -    for (i = 0; i < xsval_n; i++)
 110.188 -        PyList_SetItem(val, i, PyString_FromString(xsval[i]));
 110.189 -    free(xsval);
 110.190 - exit:
 110.191 -    return val;
 110.192 +    else {
 110.193 +        return none(errno == ENOENT);
 110.194 +    }
 110.195  }
 110.196  
 110.197 +
 110.198  #define xspy_mkdir_doc "\n"					\
 110.199  	"Make a directory.\n"					\
 110.200  	" path [string]: path to directory to create.\n"	\
 110.201 @@ -226,38 +205,23 @@ static PyObject *xspy_ls(PyObject *self,
 110.202  
 110.203  static PyObject *xspy_mkdir(PyObject *self, PyObject *args, PyObject *kwds)
 110.204  {
 110.205 -    static char *kwd_spec[] = { "transaction", "path", NULL };
 110.206 -    static char *arg_spec = "ss";
 110.207 -    char *path = NULL;
 110.208 -
 110.209 -    struct xs_handle *xh = xshandle(self);
 110.210 -    PyObject *val = NULL;
 110.211 -    int xsval = 0;
 110.212 -
 110.213 +    struct xs_handle *xh;
 110.214      struct xs_transaction_handle *th;
 110.215 -    char *thstr;
 110.216 +    char *path;
 110.217  
 110.218 -    if (!xh)
 110.219 -        goto exit;
 110.220 -    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
 110.221 -                                     &thstr, &path))
 110.222 -        goto exit;
 110.223 +    bool result;
 110.224  
 110.225 -    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
 110.226 +    if (!parse_transaction_path(self, args, kwds, &xh, &th, &path))
 110.227 +        return NULL;
 110.228  
 110.229      Py_BEGIN_ALLOW_THREADS
 110.230 -    xsval = xs_mkdir(xh, th, path);
 110.231 +    result = xs_mkdir(xh, th, path);
 110.232      Py_END_ALLOW_THREADS
 110.233 -    if (!xsval) {
 110.234 -        PyErr_SetFromErrno(PyExc_RuntimeError);
 110.235 -        goto exit;
 110.236 -    }
 110.237 -    Py_INCREF(Py_None);
 110.238 -    val = Py_None;
 110.239 - exit:
 110.240 -    return val;
 110.241 +
 110.242 +    return none(result);
 110.243  }
 110.244  
 110.245 +
 110.246  #define xspy_rm_doc "\n"			\
 110.247  	"Remove a path.\n"			\
 110.248  	" path [string] : path to remove\n"	\
 110.249 @@ -268,38 +232,23 @@ static PyObject *xspy_mkdir(PyObject *se
 110.250  
 110.251  static PyObject *xspy_rm(PyObject *self, PyObject *args, PyObject *kwds)
 110.252  {
 110.253 -    static char *kwd_spec[] = { "transaction", "path", NULL };
 110.254 -    static char *arg_spec = "ss";
 110.255 -    char *path = NULL;
 110.256 -
 110.257 -    struct xs_handle *xh = xshandle(self);
 110.258 -    PyObject *val = NULL;
 110.259 -    int xsval = 0;
 110.260 -
 110.261 +    struct xs_handle *xh;
 110.262      struct xs_transaction_handle *th;
 110.263 -    char *thstr;
 110.264 +    char *path;
 110.265  
 110.266 -    if (!xh)
 110.267 -        goto exit;
 110.268 -    if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
 110.269 -                                     &thstr, &path))
 110.270 -        goto exit;
 110.271 +    bool result;
 110.272  
 110.273 -    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
 110.274 +    if (!parse_transaction_path(self, args, kwds, &xh, &th, &path))
 110.275 +        return NULL;
 110.276  
 110.277      Py_BEGIN_ALLOW_THREADS
 110.278 -    xsval = xs_rm(xh, th, path);
 110.279 +    result = xs_rm(xh, th, path);
 110.280      Py_END_ALLOW_THREADS
 110.281 -    if (!xsval && errno != ENOENT) {
 110.282 -        PyErr_SetFromErrno(PyExc_RuntimeError);
 110.283 -        goto exit;
 110.284 -    }
 110.285 -    Py_INCREF(Py_None);
 110.286 -    val = Py_None;
 110.287 - exit:
 110.288 -    return val;
 110.289 +
 110.290 +    return none(result || errno == ENOENT);
 110.291  }
 110.292  
 110.293 +
 110.294  #define xspy_get_permissions_doc "\n"		\
 110.295  	"Get the permissions for a path\n"	\
 110.296  	" path [string]: xenstore path.\n"	\
 110.297 @@ -316,7 +265,6 @@ static PyObject *xspy_get_permissions(Py
 110.298      char *path = NULL;
 110.299  
 110.300      struct xs_handle *xh = xshandle(self);
 110.301 -    PyObject *val = NULL;
 110.302      struct xs_permissions *perms;
 110.303      unsigned int perms_n = 0;
 110.304      int i;
 110.305 @@ -325,30 +273,34 @@ static PyObject *xspy_get_permissions(Py
 110.306      char *thstr;
 110.307  
 110.308      if (!xh)
 110.309 -        goto exit;
 110.310 +        return NULL;
 110.311      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
 110.312                                       &thstr, &path))
 110.313 -        goto exit;
 110.314 +        return NULL;
 110.315  
 110.316      th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
 110.317  
 110.318      Py_BEGIN_ALLOW_THREADS
 110.319      perms = xs_get_permissions(xh, th, path, &perms_n);
 110.320      Py_END_ALLOW_THREADS
 110.321 -    if (!perms) {
 110.322 -        PyErr_SetFromErrno(PyExc_RuntimeError);
 110.323 -        goto exit;
 110.324 +
 110.325 +    if (perms) {
 110.326 +        PyObject *val = PyList_New(perms_n);
 110.327 +        for (i = 0; i < perms_n; i++, perms++) {
 110.328 +            PyObject *p = Py_BuildValue("{s:i,s:i,s:i}",
 110.329 +                                        "dom",  perms->id,
 110.330 +                                        "read", perms->perms & XS_PERM_READ,
 110.331 +                                        "write",perms->perms & XS_PERM_WRITE);
 110.332 +            PyList_SetItem(val, i, p);
 110.333 +        }
 110.334 +
 110.335 +        free(perms);
 110.336 +        return val;
 110.337      }
 110.338 -    val = PyList_New(perms_n);
 110.339 -    for (i = 0; i < perms_n; i++, perms++) {
 110.340 -        PyObject *p = Py_BuildValue("{s:i,s:i,s:i}",
 110.341 -                                    "dom",   perms->id,
 110.342 -                                    "read",  (perms->perms & XS_PERM_READ),
 110.343 -                                    "write",  (perms->perms & XS_PERM_WRITE));
 110.344 -        PyList_SetItem(val, i, p);
 110.345 +    else {
 110.346 +        PyErr_SetFromErrno(PyExc_RuntimeError);
 110.347 +        return NULL;
 110.348      }
 110.349 - exit:
 110.350 -    return val;
 110.351  }
 110.352  
 110.353  #define xspy_set_permissions_doc "\n"		\
 110.354 @@ -371,7 +323,7 @@ static PyObject *xspy_set_permissions(Py
 110.355      static char *perm_spec = "i|iiii";
 110.356  
 110.357      struct xs_handle *xh = xshandle(self);
 110.358 -    int i, xsval;
 110.359 +    int i, result;
 110.360      struct xs_permissions *xsperms = NULL;
 110.361      int xsperms_n = 0;
 110.362      PyObject *tuple0 = NULL;
 110.363 @@ -417,9 +369,9 @@ static PyObject *xspy_set_permissions(Py
 110.364              xsperms[i].perms |= XS_PERM_WRITE;
 110.365      }
 110.366      Py_BEGIN_ALLOW_THREADS
 110.367 -    xsval = xs_set_permissions(xh, th, path, xsperms, xsperms_n);
 110.368 +    result = xs_set_permissions(xh, th, path, xsperms, xsperms_n);
 110.369      Py_END_ALLOW_THREADS
 110.370 -    if (!xsval) {
 110.371 +    if (!result) {
 110.372          PyErr_SetFromErrno(PyExc_RuntimeError);
 110.373          goto exit;
 110.374      }
 110.375 @@ -427,8 +379,7 @@ static PyObject *xspy_set_permissions(Py
 110.376      val = Py_None;
 110.377   exit:
 110.378      Py_XDECREF(tuple0);
 110.379 -    if (xsperms)
 110.380 -        free(xsperms);
 110.381 +    free(xsperms);
 110.382      return val;
 110.383  }
 110.384  
 110.385 @@ -455,39 +406,40 @@ static PyObject *xspy_watch(PyObject *se
 110.386  
 110.387      XsHandle *xsh = (XsHandle *)self;
 110.388      struct xs_handle *xh = xshandle(self);
 110.389 -    PyObject *val = NULL;
 110.390 -    int xsval = 0;
 110.391 +    int result = 0;
 110.392  
 110.393      if (!xh)
 110.394 -        goto exit;
 110.395 +        return NULL;
 110.396      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, 
 110.397                                       &path, &token))
 110.398 -        goto exit;
 110.399 -    Py_INCREF(token);
 110.400 -    sprintf(token_str, "%li", (unsigned long)token);
 110.401 -    Py_BEGIN_ALLOW_THREADS
 110.402 -    xsval = xs_watch(xh, path, token_str);
 110.403 -    Py_END_ALLOW_THREADS
 110.404 -    if (!xsval) {
 110.405 -        PyErr_SetFromErrno(PyExc_RuntimeError);
 110.406 -        Py_DECREF(token);
 110.407 -        goto exit;
 110.408 -    }
 110.409 +        return NULL;
 110.410 +
 110.411 +    /* Note that we have to store the watch token in the xs->watches list
 110.412 +       before registering the watch with xs_watch, otherwise this function
 110.413 +       races with xs_read_watch.
 110.414 +    */
 110.415  
 110.416      for (i = 0; i < PyList_Size(xsh->watches); i++) {
 110.417          if (PyList_GetItem(xsh->watches, i) == Py_None) {
 110.418 -            PyList_SetItem(xsh->watches, i, token);
 110.419 +            PySequence_SetItem(xsh->watches, i, token);
 110.420              break;
 110.421          }
 110.422      }
 110.423      if (i == PyList_Size(xsh->watches))
 110.424          PyList_Append(xsh->watches, token);
 110.425 -    Py_INCREF(Py_None);
 110.426 -    val = Py_None;
 110.427 - exit:
 110.428 -    return val;
 110.429 +
 110.430 +    sprintf(token_str, "%li", (unsigned long)token);
 110.431 +    Py_BEGIN_ALLOW_THREADS
 110.432 +    result = xs_watch(xh, path, token_str);
 110.433 +    Py_END_ALLOW_THREADS
 110.434 +
 110.435 +    if (!result)
 110.436 +        remove_watch(xsh, token);
 110.437 +
 110.438 +    return none(result);
 110.439  }
 110.440  
 110.441 +
 110.442  #define xspy_read_watch_doc "\n"				\
 110.443  	"Read a watch notification.\n"				\
 110.444  	"\n"							\
 110.445 @@ -510,9 +462,10 @@ static PyObject *xspy_read_watch(PyObjec
 110.446      unsigned int num;
 110.447  
 110.448      if (!xh)
 110.449 -        goto exit;
 110.450 +        return NULL;
 110.451      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec))
 110.452 -        goto exit;
 110.453 +        return NULL;
 110.454 +
 110.455  again:
 110.456      Py_BEGIN_ALLOW_THREADS
 110.457      xsval = xs_read_watch(xh, &num);
 110.458 @@ -541,8 +494,7 @@ again:
 110.459      /* Create tuple (path, token). */
 110.460      val = Py_BuildValue("(sO)", xsval[XS_WATCH_PATH], token);
 110.461   exit:
 110.462 -    if (xsval)
 110.463 -        free(xsval);
 110.464 +    free(xsval);
 110.465      return val;
 110.466  }
 110.467  
 110.468 @@ -562,37 +514,25 @@ static PyObject *xspy_unwatch(PyObject *
 110.469      char *path = NULL;
 110.470      PyObject *token;
 110.471      char token_str[MAX_STRLEN(unsigned long) + 1];
 110.472 -    int i;
 110.473  
 110.474      XsHandle *xsh = (XsHandle *)self;
 110.475      struct xs_handle *xh = xshandle(self);
 110.476 -    PyObject *val = NULL;
 110.477 -    int xsval = 0;
 110.478 +    int result = 0;
 110.479  
 110.480      if (!xh)
 110.481 -        goto exit;
 110.482 +        return NULL;
 110.483      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path,
 110.484                                       &token))
 110.485 -        goto exit;
 110.486 +        return NULL;
 110.487 +
 110.488      sprintf(token_str, "%li", (unsigned long)token);
 110.489      Py_BEGIN_ALLOW_THREADS
 110.490 -    xsval = xs_unwatch(xh, path, token_str);
 110.491 +    result = xs_unwatch(xh, path, token_str);
 110.492      Py_END_ALLOW_THREADS
 110.493 -    if (!xsval)
 110.494 -        PyErr_SetFromErrno(PyExc_RuntimeError);
 110.495 -    else {
 110.496 -        Py_INCREF(Py_None);
 110.497 -        val = Py_None;
 110.498 -    }
 110.499 -    for (i = 0; i < PyList_Size(xsh->watches); i++) {
 110.500 -        if (token == PyList_GetItem(xsh->watches, i)) {
 110.501 -            Py_INCREF(Py_None);
 110.502 -            PyList_SetItem(xsh->watches, i, Py_None);
 110.503 -            break;
 110.504 -        }
 110.505 -    }
 110.506 - exit:
 110.507 -    return val;
 110.508 +
 110.509 +    remove_watch(xsh, token);
 110.510 +
 110.511 +    return none(result);
 110.512  }
 110.513  
 110.514  #define xspy_transaction_start_doc "\n"				\
 110.515 @@ -610,26 +550,25 @@ static PyObject *xspy_transaction_start(
 110.516      char *path = NULL;
 110.517  
 110.518      struct xs_handle *xh = xshandle(self);
 110.519 -    PyObject *val = NULL;
 110.520      struct xs_transaction_handle *th;
 110.521      char thstr[20];
 110.522  
 110.523      if (!xh)
 110.524 -        goto exit;
 110.525 +        return NULL;
 110.526      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
 110.527 -        goto exit;
 110.528 +        return NULL;
 110.529 +
 110.530      Py_BEGIN_ALLOW_THREADS
 110.531      th = xs_transaction_start(xh);
 110.532      Py_END_ALLOW_THREADS
 110.533 +
 110.534      if (th == NULL) {
 110.535          PyErr_SetFromErrno(PyExc_RuntimeError);
 110.536 -        goto exit;
 110.537 +        return NULL;
 110.538      }
 110.539  
 110.540      sprintf(thstr, "%lX", (unsigned long)th);
 110.541 -    val = PyString_FromString(thstr);
 110.542 - exit:
 110.543 -    return val;
 110.544 +    return PyString_FromString(thstr);
 110.545  }
 110.546  
 110.547  #define xspy_transaction_end_doc "\n"					\
 110.548 @@ -649,38 +588,38 @@ static PyObject *xspy_transaction_end(Py
 110.549      int abort = 0;
 110.550  
 110.551      struct xs_handle *xh = xshandle(self);
 110.552 -    PyObject *val = NULL;
 110.553 -    int xsval = 0;
 110.554 +    bool result;
 110.555  
 110.556      struct xs_transaction_handle *th;
 110.557      char *thstr;
 110.558  
 110.559      if (!xh)
 110.560 -        goto exit;
 110.561 +        return NULL;
 110.562      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
 110.563                                       &thstr, &abort))
 110.564 -        goto exit;
 110.565 +        return NULL;
 110.566  
 110.567      th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
 110.568  
 110.569      Py_BEGIN_ALLOW_THREADS
 110.570 -    xsval = xs_transaction_end(xh, th, abort);
 110.571 +    result = xs_transaction_end(xh, th, abort);
 110.572      Py_END_ALLOW_THREADS
 110.573 -    if (!xsval) {
 110.574 -	if (errno == EAGAIN) {
 110.575 -	    Py_INCREF(Py_False);
 110.576 -	    val = Py_False;
 110.577 -	    goto exit;
 110.578 -	}
 110.579 +
 110.580 +    if (result) {
 110.581 +        Py_INCREF(Py_True);
 110.582 +        return Py_True;
 110.583 +    }
 110.584 +    else if (errno == EAGAIN) {
 110.585 +        Py_INCREF(Py_False);
 110.586 +        return Py_False;
 110.587 +    }
 110.588 +    else {
 110.589          PyErr_SetFromErrno(PyExc_RuntimeError);
 110.590 -        goto exit;
 110.591 +        return NULL;
 110.592      }
 110.593 -    Py_INCREF(Py_True);
 110.594 -    val = Py_True;
 110.595 - exit:
 110.596 -    return val;
 110.597  }
 110.598  
 110.599 +
 110.600  #define xspy_introduce_domain_doc "\n"					\
 110.601  	"Tell xenstore about a domain so it can talk to it.\n"		\
 110.602  	" dom  [int]   : domain id\n"					\
 110.603 @@ -701,27 +640,22 @@ static PyObject *xspy_introduce_domain(P
 110.604      unsigned int port = 0;
 110.605  
 110.606      struct xs_handle *xh = xshandle(self);
 110.607 -    PyObject *val = NULL;
 110.608 -    int xsval = 0;
 110.609 +    bool result = 0;
 110.610  
 110.611      if (!xh)
 110.612 -        goto exit;
 110.613 +        return NULL;
 110.614      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
 110.615                                       &dom, &page, &port))
 110.616 -        goto exit;
 110.617 +        return NULL;
 110.618 +
 110.619      Py_BEGIN_ALLOW_THREADS
 110.620 -    xsval = xs_introduce_domain(xh, dom, page, port);
 110.621 +    result = xs_introduce_domain(xh, dom, page, port);
 110.622      Py_END_ALLOW_THREADS
 110.623 -    if (!xsval) {
 110.624 -        PyErr_SetFromErrno(PyExc_RuntimeError);
 110.625 -        goto exit;
 110.626 -    }
 110.627 -    Py_INCREF(Py_None);
 110.628 -    val = Py_None;
 110.629 - exit:
 110.630 -    return val;
 110.631 +
 110.632 +    return none(result);
 110.633  }
 110.634  
 110.635 +
 110.636  #define xspy_release_domain_doc "\n"					\
 110.637  	"Tell xenstore to release its channel to a domain.\n"		\
 110.638  	"Unless this is done the domain will not be released.\n"	\
 110.639 @@ -735,31 +669,26 @@ static PyObject *xspy_release_domain(PyO
 110.640                                       PyObject *kwds)
 110.641  {
 110.642      static char *kwd_spec[] = { "dom", NULL };
 110.643 -    static char *arg_spec = "i|";
 110.644 +    static char *arg_spec = "i";
 110.645      domid_t dom;
 110.646  
 110.647      struct xs_handle *xh = xshandle(self);
 110.648 -    PyObject *val = NULL;
 110.649 -    int xsval = 0;
 110.650 +    bool result = 0;
 110.651  
 110.652      if (!xh)
 110.653 -        goto exit;
 110.654 +        return NULL;
 110.655      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
 110.656                                       &dom))
 110.657 -        goto exit;
 110.658 +        return NULL;
 110.659 +
 110.660      Py_BEGIN_ALLOW_THREADS
 110.661 -    xsval = xs_release_domain(xh, dom);
 110.662 +    result = xs_release_domain(xh, dom);
 110.663      Py_END_ALLOW_THREADS
 110.664 -    if (!xsval) {
 110.665 -        PyErr_SetFromErrno(PyExc_RuntimeError);
 110.666 -        goto exit;
 110.667 -    }
 110.668 -    Py_INCREF(Py_None);
 110.669 -    val = Py_None;
 110.670 - exit:
 110.671 -    return val;
 110.672 +
 110.673 +    return none(result);
 110.674  }
 110.675  
 110.676 +
 110.677  #define xspy_close_doc "\n"			\
 110.678  	"Close the connection to xenstore.\n"	\
 110.679  	"\n"					\
 110.680 @@ -775,25 +704,25 @@ static PyObject *xspy_close(PyObject *se
 110.681  
 110.682      XsHandle *xsh = (XsHandle *)self;
 110.683      struct xs_handle *xh = xshandle(self);
 110.684 -    PyObject *val = NULL;
 110.685  
 110.686      if (!xh)
 110.687 -        goto exit;
 110.688 +        return NULL;
 110.689      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec))
 110.690 -        goto exit;
 110.691 +        return NULL;
 110.692 +
 110.693      for (i = 0; i < PyList_Size(xsh->watches); i++) {
 110.694          /* TODO: xs_unwatch watches */
 110.695 -        Py_INCREF(Py_None);
 110.696 -        PyList_SetItem(xsh->watches, i, Py_None);
 110.697 +        PySequence_SetItem(xsh->watches, i, Py_None);
 110.698      }
 110.699 +
 110.700      xs_daemon_close(xh);
 110.701      xsh->xh = NULL;
 110.702 +
 110.703      Py_INCREF(Py_None);
 110.704