diff -r 501a70f3ae96 tools/examples/xend-config.sxp
--- a/tools/examples/xend-config.sxp	Thu Jul 28 12:34:45 2005
+++ b/tools/examples/xend-config.sxp	Fri Jul 29 11:55:38 2005
@@ -44,3 +44,11 @@
 # Setup script for enbd-backed block devices
 (block-enbd block-enbd)
 
+# Dom0 will balloon out when needed to free memory for domU.
+# dom0-min-mem is the lowest memory level (in MB) dom0 will get down to.
+# If dom0-min-mem=0, dom0 will never balloon out.
+(dom0-min-mem 0)
+
+# In SMP system, dom0 will use only CPUs in range [1,dom0-cpus]
+# If dom0-cpus = 0, dom0 will take all cpus available
+(dom0-cpus 0)
diff -r 501a70f3ae96 tools/python/xen/xend/XendRoot.py
--- a/tools/python/xen/xend/XendRoot.py	Thu Jul 28 12:34:45 2005
+++ b/tools/python/xen/xend/XendRoot.py	Fri Jul 29 11:55:38 2005
@@ -75,6 +75,10 @@
 
     """Default port xend serves consoles at. """
     console_port_base_default = '9600'
+
+    dom0_min_mem_default = '0'
+
+    dom0_cpus_default = '0'
 
     components = {}
 
@@ -329,6 +333,12 @@
     def get_vif_antispoof(self):
         return self.get_config_bool('vif-antispoof', 'yes')
 
+    def get_dom0_min_mem(self):
+        return self.get_config_int('dom0-min-mem', self.dom0_min_mem_default)
+
+    def get_dom0_cpus(self):
+        return self.get_config_int('dom0-cpus', self.dom0_cpus_default)
+
 def instance():
     """Get an instance of XendRoot.
     Use this instead of the constructor.
diff -r 501a70f3ae96 tools/python/xen/xend/server/SrvDaemon.py
--- a/tools/python/xen/xend/server/SrvDaemon.py	Thu Jul 28 12:34:45 2005
+++ b/tools/python/xen/xend/server/SrvDaemon.py	Fri Jul 29 11:55:38 2005
@@ -5,7 +5,6 @@
 ###########################################################
 
 import os
-import os.path
 import signal
 import sys
 import threading
@@ -16,6 +15,7 @@
 import StringIO
 import traceback
 import time
+import glob
 
 from xen.lowlevel import xu
 
@@ -25,6 +25,7 @@
 from xen.xend.XendError import XendError
 from xen.xend.server import SrvServer
 from xen.xend.XendLogging import log
+from xen.xend import XendRoot; xroot = XendRoot.instance()
 
 import channel
 import controller
@@ -327,6 +328,7 @@
         return self.cleanup(kill=True)
 
     def run(self):
+        _enforce_dom0_cpus()
         try:
             log.info("Xend Daemon started")
             self.createFactories()
@@ -363,6 +365,32 @@
         #sys.exit(rc)
         os._exit(rc)
 
+def _enforce_dom0_cpus():
+    dn = xroot.get_dom0_cpus()
+
+    for d in glob.glob("/sys/devices/system/cpu/cpu*"):
+        cpu = int(os.path.basename(d)[3:])
+        if (dn == 0) or (cpu < dn):
+            v = "1"
+        else:
+            v = "0"
+        try:
+            f = open("%s/online" %d, "r+")
+            c = f.read(1)
+            if (c != v):
+                if v == "0":
+                    log.info("dom0 is trying to give back cpu %d", cpu)
+                else:
+                    log.info("dom0 is trying to take cpu %d", cpu)
+                f.seek(0)
+                f.write(v)
+                f.close()
+                log.info("dom0 successfully enforced cpu %d", cpu)
+            else:
+                f.close()
+        except:
+            pass
+
 def instance():
     global inst
     try:
diff -r 501a70f3ae96 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py	Thu Jul 28 12:34:45 2005
+++ b/tools/python/xen/xm/create.py	Fri Jul 29 11:55:38 2005
@@ -1,4 +1,5 @@
 # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
+# Copyright (C) 2005 Nguyen Anh Quynh <aquynh@gmail.com>
 
 """Domain creation.
 """
@@ -7,10 +8,13 @@
 import sys
 import socket
 
+import xen.lowlevel.xc
+
 from xen.xend import sxp
 from xen.xend import PrettyPrint
 from xen.xend.XendClient import server, XendError
 from xen.xend.XendBootloader import bootloader
+from xen.xend import XendRoot; xroot = XendRoot.instance()
 from xen.util import blkif
 
 from xen.util import console_client
@@ -644,6 +648,36 @@
               % (dom, console_port))
     return (dom, console_port)
 
+def get_dom0_alloc():
+    """Return current allocation memory of dom0 (in MB). Return 0 on error"""
+    PROC_XEN_BALLOON = "/proc/xen/balloon"
+
+    f = open(PROC_XEN_BALLOON, "r")
+    line = f.readline()
+    for x in line.split():
+        for n in x:
+            if not n.isdigit():
+                break
+        else:
+            f.close()
+            return int(x)/1024
+    f.close()
+    return 0
+
+def balloon_out(dom0_min_mem, opts):
+    """Balloon out to get memory for domU, if necessarily"""
+    SLACK = 4
+
+    xc = xen.lowlevel.xc.new()
+    pinfo = xc.physinfo()
+    free_mem = pinfo['free_pages']/256
+    if free_mem < opts.vals.memory + SLACK:
+        need_mem = opts.vals.memory + SLACK - free_mem
+        cur_alloc = get_dom0_alloc()
+        if cur_alloc - need_mem >= dom0_min_mem:
+            server.xend_domain_mem_target_set(0, cur_alloc - need_mem)
+    del xc
+
 def main(argv):
     opts = gopts
     args = opts.parse(argv)
@@ -671,6 +705,10 @@
     if opts.vals.dryrun:
         PrettyPrint.prettyprint(config)
     else:
+        dom0_min_mem = xroot.get_dom0_min_mem()
+        if dom0_min_mem != 0:
+            balloon_out(dom0_min_mem, opts)
+
         (dom, console) = make_domain(opts, config)
         if opts.vals.console_autoconnect:
             path = "/var/lib/xend/console-%s" % console
