ia64/xen-unstable

changeset 19538:8c806c66a597

merge with xen-unstable.hg
author Isaku Yamahata <yamahata@valinux.co.jp>
date Tue Apr 14 14:04:58 2009 +0900 (2009-04-14)
parents 19919f01f2c5 120d3c67951b
children 4063894c0c1f
files
line diff
     1.1 --- a/.hgtags	Tue Apr 07 11:32:24 2009 +0900
     1.2 +++ b/.hgtags	Tue Apr 14 14:04:58 2009 +0900
     1.3 @@ -33,3 +33,4 @@ b4dba6a0e97cb6dd080fa566468e3cc972c34d7a
     1.4  bc372510f1794ee41a8b0501cc84f8a65d05e094 3.3.0-rc6
     1.5  daf1193bcd11345d566a4747fe1f12c90b44452c 3.3.0-rc7
     1.6  1e99ba54035623731bc7318a8357aa6a118c5da1 3.3.0-branched
     1.7 +d611d9ac6d0271b53eb1d4e5d0c4ef20b269eea8 3.4.0-rc1
     2.1 --- a/Config.mk	Tue Apr 07 11:32:24 2009 +0900
     2.2 +++ b/Config.mk	Tue Apr 14 14:04:58 2009 +0900
     2.3 @@ -1,7 +1,7 @@
     2.4  # -*- mode: Makefile; -*-
     2.5  
     2.6 -# A debug build of Xen and tools? TEMPORARILY ENABLED
     2.7 -debug ?= y
     2.8 +# A debug build of Xen and tools?
     2.9 +debug ?= n
    2.10  
    2.11  XEN_COMPILE_ARCH    ?= $(shell uname -m | sed -e s/i.86/x86_32/ \
    2.12                           -e s/i86pc/x86_32/ -e s/amd64/x86_64/)
     3.1 --- a/Makefile	Tue Apr 07 11:32:24 2009 +0900
     3.2 +++ b/Makefile	Tue Apr 14 14:04:58 2009 +0900
     3.3 @@ -188,11 +188,7 @@ help:
     3.4  	@echo '  clean-tboot      - clean the tboot module if it exists'
     3.5  	@echo
     3.6  	@echo 'Environment:'
     3.7 -	@echo '  XEN_PYTHON_NATIVE_INSTALL=y'
     3.8 -	@echo '                   - native python install or dist'
     3.9 -	@echo '                     install into prefix/lib/python<VERSION>'
    3.10 -	@echo '                     instead of <PREFIX>/lib/python'
    3.11 -	@echo '                     true if set to non-empty value, false otherwise'
    3.12 +	@echo '  [ this documentation is sadly not complete ]'
    3.13  
    3.14  # Use this target with extreme care!
    3.15  .PHONY: uninstall
     4.1 --- a/tools/hotplug/Linux/network-nat	Tue Apr 07 11:32:24 2009 +0900
     4.2 +++ b/tools/hotplug/Linux/network-nat	Tue Apr 14 14:04:58 2009 +0900
     4.3 @@ -48,12 +48,16 @@ then
     4.4    fi
     4.5  fi
     4.6  
     4.7 +domain_name=`cat /etc/resolv.conf | grep -v "#" | grep -E 'search|domain' -i | tail -n 1 | awk '{ print $2 }'`
     4.8 +nameserver=`cat /etc/resolv.conf | grep -v "#" | grep "nameserver" -i -m 1 | awk '{ print $2 }'`
     4.9  
    4.10  function dhcp_start()
    4.11  {
    4.12    if ! grep -q "subnet 10.0.0.0" "$dhcpd_conf_file"
    4.13    then
    4.14 -    echo >>"$dhcpd_conf_file" "subnet 10.0.0.0 netmask 255.255.0.0 {}"
    4.15 +    echo >>"$dhcpd_conf_file" "subnet 10.0.0.0 netmask 255.255.0.0 {\
    4.16 + option domain-name \"$domain_name\";\
    4.17 + option domain-name-servers $nameserver; }"
    4.18    fi
    4.19  
    4.20    "$dhcpd_init_file" restart
     5.1 --- a/tools/libxc/xc_domain_restore.c	Tue Apr 07 11:32:24 2009 +0900
     5.2 +++ b/tools/libxc/xc_domain_restore.c	Tue Apr 14 14:04:58 2009 +0900
     5.3 @@ -1197,7 +1197,7 @@ int xc_domain_restore(int xc_handle, int
     5.4       * we need to adjust the live_p2m assignment appropriately */
     5.5      if ( guest_width > sizeof (xen_pfn_t) )
     5.6          for ( i = p2m_size - 1; i >= 0; i-- )
     5.7 -            ((uint64_t *)live_p2m)[i] = p2m[i];
     5.8 +            ((int64_t *)live_p2m)[i] = (long)p2m[i];
     5.9      else if ( guest_width < sizeof (xen_pfn_t) )
    5.10          for ( i = 0; i < p2m_size; i++ )   
    5.11              ((uint32_t *)live_p2m)[i] = p2m[i];
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/tools/misc/sbdf2devicepath	Tue Apr 14 14:04:58 2009 +0900
     6.3 @@ -0,0 +1,82 @@
     6.4 +#!/usr/bin/env python
     6.5 +#  -*- mode: python; -*-
     6.6 +#============================================================================
     6.7 +# This library is free software; you can redistribute it and/or
     6.8 +# modify it under the terms of version 2.1 of the GNU Lesser General Public
     6.9 +# License as published by the Free Software Foundation.
    6.10 +#
    6.11 +# This library is distributed in the hope that it will be useful,
    6.12 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.13 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    6.14 +# Lesser General Public License for more details.
    6.15 +#
    6.16 +# You should have received a copy of the GNU Lesser General Public
    6.17 +# License along with this library; if not, write to the Free Software
    6.18 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    6.19 +#============================================================================
    6.20 +# Copyright (c) 2009, NEC Corporation.
    6.21 +#============================================================================
    6.22 +# This script converts SBDF into device path.
    6.23 +#   'SBDF' format is "[SEG#:]BUS#:DEV#.FUNC#"
    6.24 +#       ex) 0000:0a:1f.3
    6.25 +#   Device path format is "HID[:UID]-DEV#.FUNC#[-DEV#.FUNC#[...]]"
    6.26 +#       ex) PNP0A08:0-2.0-0.0
    6.27 +#=============================================================================
    6.28 +
    6.29 +import sys
    6.30 +import os
    6.31 +
    6.32 +# add fallback path for non-native python path installs if needed
    6.33 +sys.path.append('/usr/lib/python')
    6.34 +sys.path.append('/usr/lib64/python')
    6.35 +from xen.util.pci import *
    6.36 +
    6.37 +SYSFS_ACPI_DEVS_PATH = '/firmware/acpi/namespace/ACPI/_SB'
    6.38 +
    6.39 +def find_hid_uid(dom, b, d, f):
    6.40 +    obj_list = os.listdir(sb_path)
    6.41 +    for obj in obj_list:
    6.42 +        obj_path = sb_path + '/' + obj.strip() + '/'
    6.43 +        if os.path.exists(obj_path + 'seg') and \
    6.44 +            os.path.exists(obj_path + 'bbn'):
    6.45 +            seg = open(obj_path + 'seg').read()
    6.46 +            bbn = open(obj_path + 'bbn').read()
    6.47 +            if int(seg) == dom and int(bbn) == b:
    6.48 +                hid = open(obj_path + 'hid').read()
    6.49 +                if os.path.exists(obj_path + 'uid') is False:
    6.50 +                    path_str = hid.strip()
    6.51 +                else:
    6.52 +                    uid = open(obj_path + 'uid').read()
    6.53 +                    path_str = hid.strip() + ':' + uid.strip()
    6.54 +                return path_str
    6.55 +    return None
    6.56 +
    6.57 +def make_device_path(dom, b, d, f):
    6.58 +    dev = PciDevice(dom, b, d, f)
    6.59 +    parent = dev.find_parent()
    6.60 +    if parent is None:
    6.61 +        path_str = find_hid_uid(dom, b, d, f)
    6.62 +        path_str = path_str + '-' + hex(d).replace('0x', '') + '.' + \
    6.63 +            hex(f).replace('0x', '')
    6.64 +        return path_str
    6.65 +    (pdom, pb, pd, pf) = parent
    6.66 +    path_str = make_device_path(pdom, pb, pd, pf)
    6.67 +    path_str = path_str + '-' + hex(d).replace('0x', '') + '.' + \
    6.68 +        hex(f).replace('0x', '')
    6.69 +    return path_str
    6.70 +
    6.71 +# main
    6.72 +if len(sys.argv) <> 2:
    6.73 +    print 'Usage: sbdf2devicepath SBDF\n'
    6.74 +else:
    6.75 +    sb_path = find_sysfs_mnt() + SYSFS_ACPI_DEVS_PATH
    6.76 +    if os.path.exists(sb_path):
    6.77 +        path = os.environ['PATH']
    6.78 +        os.environ['PATH'] = path + ':/sbin' + ':/user/sbin'
    6.79 +        sbdf = sys.argv[1]
    6.80 +        (dom, b, d, f) = parse_pci_name(sbdf)
    6.81 +        path_str = make_device_path(dom, b, d, f)
    6.82 +        print path_str
    6.83 +    else:
    6.84 +        print sb_path + ' not found.\n'
    6.85 +        print 'This command is only for linux 2.6.18.8 xen kernel.\n'
     7.1 --- a/tools/misc/sxp-pretty	Tue Apr 07 11:32:24 2009 +0900
     7.2 +++ b/tools/misc/sxp-pretty	Tue Apr 14 14:04:58 2009 +0900
     7.3 @@ -23,14 +23,6 @@ import os.path
     7.4  import pprint
     7.5  import sys
     7.6  
     7.7 -result = commands.getstatusoutput(os.path.join(os.path.dirname(sys.argv[0]),
     7.8 -                                               'xen-python-path'))
     7.9 -if result[0] != 0:
    7.10 -    print >>sys.stderr, result[1]
    7.11 -    sys.exit(1)
    7.12 -
    7.13 -sys.path.append(result[1])
    7.14 -
    7.15  import xen.xend.sxp as sxp
    7.16  
    7.17  def main():
     8.1 --- a/tools/misc/xen-bugtool	Tue Apr 07 11:32:24 2009 +0900
     8.2 +++ b/tools/misc/xen-bugtool	Tue Apr 14 14:04:58 2009 +0900
     8.3 @@ -6,9 +6,6 @@
     8.4  
     8.5  import sys
     8.6  
     8.7 -sys.path.append('/usr/lib/python')
     8.8 -sys.path.append('/usr/lib64/python')
     8.9 -
    8.10  from xen.util import bugtool
    8.11  
    8.12  
     9.1 --- a/tools/misc/xen-python-path	Tue Apr 07 11:32:24 2009 +0900
     9.2 +++ b/tools/misc/xen-python-path	Tue Apr 14 14:04:58 2009 +0900
     9.3 @@ -17,31 +17,8 @@
     9.4  # Copyright (C) 2007 XenSource Inc.
     9.5  #============================================================================
     9.6  
     9.7 -
     9.8 -# Use the auxbin module in Xend to determine the correct Python path.  We
     9.9 -# take the first installed instance of auxbin that we find, and then run it
    9.10 -# to determine the correct path, appending that to sys.path.
    9.11 -
    9.12 -AUXBIN = 'xen/util/auxbin.py'
    9.13 -
    9.14 -import os
    9.15 -import os.path
    9.16 -import sys
    9.17 +# Nowadays we install xen in the standard python site-packages
    9.18 +# directories.  This script is still provided for the benefit of old
    9.19 +# out-of-xen-tree callers.  It is deprecated and will be removed.
    9.20  
    9.21 -usr   = os.path.dirname(os.path.dirname(sys.argv[0]))
    9.22 -list  = [ os.path.join(usr,'lib64') ]
    9.23 -list += [ os.path.join(usr,'lib') ]
    9.24 -list += ['/usr/lib64', '/usr/lib']
    9.25 -
    9.26 -for l in list:
    9.27 -    for p in ['python%s' % sys.version[:3], 'python']:
    9.28 -        for k in ['', 'site-packages/']:
    9.29 -            d = os.path.join(l, p, k)
    9.30 -            if os.path.exists(os.path.join(d, AUXBIN)):
    9.31 -                sys.path.append(d)
    9.32 -                import xen.util.auxbin
    9.33 -                print os.path.join(xen.util.auxbin.libpath(), p)
    9.34 -                sys.exit(0)
    9.35 -
    9.36 -print >>sys.stderr, "Cannot find Xen Python modules."
    9.37 -sys.exit(1)
    9.38 +print '/dev/enoent/xen/python-path'
    10.1 --- a/tools/misc/xend	Tue Apr 07 11:32:24 2009 +0900
    10.2 +++ b/tools/misc/xend	Tue Apr 14 14:04:58 2009 +0900
    10.3 @@ -33,14 +33,6 @@ import signal
    10.4  import time
    10.5  import commands
    10.6  
    10.7 -xpp = os.path.join(os.path.dirname(sys.argv[0]), 'xen-python-path')
    10.8 -if os.path.exists(xpp):
    10.9 -    result = commands.getstatusoutput(xpp)
   10.10 -    if result[0] != 0:
   10.11 -        print >>sys.stderr, result[1]
   10.12 -        sys.exit(1)
   10.13 -    sys.path.append(result[1])
   10.14 -
   10.15  from xen.xend.server import SrvDaemon
   10.16  
   10.17  class CheckError(ValueError):
    11.1 --- a/tools/misc/xm	Tue Apr 07 11:32:24 2009 +0900
    11.2 +++ b/tools/misc/xm	Tue Apr 14 14:04:58 2009 +0900
    11.3 @@ -2,9 +2,6 @@
    11.4  #  -*- mode: python; -*-
    11.5  import sys
    11.6  
    11.7 -# add fallback path for non-native python path installs if needed
    11.8 -sys.path.append('/usr/lib/python')
    11.9 -sys.path.append('/usr/lib64/python')
   11.10  from xen.xm import main
   11.11  
   11.12  main.main(sys.argv)
    12.1 --- a/tools/misc/xsview	Tue Apr 07 11:32:24 2009 +0900
    12.2 +++ b/tools/misc/xsview	Tue Apr 14 14:04:58 2009 +0900
    12.3 @@ -2,8 +2,6 @@
    12.4  
    12.5  import sys
    12.6  
    12.7 -sys.path.append('/usr/lib/python')
    12.8 -sys.path.append('/usr/lib64/python')
    12.9  from xen.xsview import main
   12.10  
   12.11  main.main(sys.argv)
    13.1 --- a/tools/pygrub/Makefile	Tue Apr 07 11:32:24 2009 +0900
    13.2 +++ b/tools/pygrub/Makefile	Tue Apr 14 14:04:58 2009 +0900
    13.3 @@ -9,16 +9,10 @@ build:
    13.4  	CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py build
    13.5  
    13.6  .PHONY: install
    13.7 -ifndef XEN_PYTHON_NATIVE_INSTALL
    13.8 -install: LIBPATH=$(shell PYTHONPATH=../python/xen/util python -c "import auxbin; print auxbin.libpath()")
    13.9  install: all
   13.10 -	CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --home="$(DESTDIR)$(PREFIX)" --prefix="" --install-lib="$(DESTDIR)$(LIBDIR)/python"
   13.11 +	CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install \
   13.12 +		--prefix="$(PREFIX)" --root="$(DESTDIR)" --force
   13.13  	$(INSTALL_DIR) $(DESTDIR)/var/run/xend/boot
   13.14 -else
   13.15 -install: all
   13.16 -	CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)"
   13.17 -	$(INSTALL_DIR) $(DESTDIR)/var/run/xend/boot
   13.18 -endif
   13.19  
   13.20  .PHONY: clean
   13.21  clean:
    14.1 --- a/tools/pygrub/src/pygrub	Tue Apr 07 11:32:24 2009 +0900
    14.2 +++ b/tools/pygrub/src/pygrub	Tue Apr 14 14:04:58 2009 +0900
    14.3 @@ -21,8 +21,6 @@ import platform
    14.4  import curses, _curses, curses.wrapper, curses.textpad, curses.ascii
    14.5  import getopt
    14.6  
    14.7 -sys.path = [ '/usr/lib/python', '/usr/lib64/python' ] + sys.path
    14.8 -
    14.9  import fsimage
   14.10  import grub.GrubConf
   14.11  import grub.LiloConf
    15.1 --- a/tools/python/Makefile	Tue Apr 07 11:32:24 2009 +0900
    15.2 +++ b/tools/python/Makefile	Tue Apr 14 14:04:58 2009 +0900
    15.3 @@ -54,14 +54,9 @@ refresh-po: $(POTFILE)
    15.4  	$(MSGFMT) -c -o $@ $<
    15.5  
    15.6  .PHONY: install
    15.7 -ifndef XEN_PYTHON_NATIVE_INSTALL
    15.8 -install: LIBPATH=$(shell PYTHONPATH=xen/util python -c "import auxbin; print auxbin.libpath()")
    15.9  install: install-messages install-dtd
   15.10 -	CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --home="$(DESTDIR)$(PREFIX)" --prefix="" --force --install-lib="$(DESTDIR)$(LIBDIR)/python"
   15.11 -else
   15.12 -install: install-messages install-dtd
   15.13 -	CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)" --force
   15.14 -endif
   15.15 +	CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install \
   15.16 +		--prefix="$(PREFIX)" --root="$(DESTDIR)" --force
   15.17  
   15.18  install-dtd: all
   15.19  	$(INSTALL_DIR) $(DESTDIR)$(DOCDIR)
    16.1 --- a/tools/python/scripts/test_hvm_create.py	Tue Apr 07 11:32:24 2009 +0900
    16.2 +++ b/tools/python/scripts/test_hvm_create.py	Tue Apr 14 14:04:58 2009 +0900
    16.3 @@ -74,7 +74,6 @@ console_cfg = {
    16.4  
    16.5  import sys
    16.6  import time
    16.7 -sys.path.append('/usr/lib/python')
    16.8  
    16.9  from xapi import connect, execute
   16.10  
    17.1 --- a/tools/python/scripts/test_vm_create.py	Tue Apr 07 11:32:24 2009 +0900
    17.2 +++ b/tools/python/scripts/test_vm_create.py	Tue Apr 14 14:04:58 2009 +0900
    17.3 @@ -93,7 +93,6 @@ console_cfg = {
    17.4  
    17.5  import sys
    17.6  import time
    17.7 -sys.path.append('/usr/lib/python')
    17.8  
    17.9  from xapi import connect, execute
   17.10  
    18.1 --- a/tools/python/scripts/xapi.py	Tue Apr 07 11:32:24 2009 +0900
    18.2 +++ b/tools/python/scripts/xapi.py	Tue Apr 14 14:04:58 2009 +0900
    18.3 @@ -20,7 +20,6 @@ import sys
    18.4  import time
    18.5  import re
    18.6  import os
    18.7 -sys.path.append('/usr/lib/python')
    18.8  
    18.9  from xen.util.xmlrpclib2 import ServerProxy
   18.10  from optparse import *
    19.1 --- a/tools/python/xen/util/auxbin.py	Tue Apr 07 11:32:24 2009 +0900
    19.2 +++ b/tools/python/xen/util/auxbin.py	Tue Apr 14 14:04:58 2009 +0900
    19.3 @@ -35,7 +35,11 @@ def execute(exe, args = None):
    19.4      a = [ exepath ]
    19.5      if args:
    19.6          a.extend(args)
    19.7 -    os.execv(exepath, a)
    19.8 +    try:
    19.9 +        os.execv(exepath, a)
   19.10 +    except OSError, exn:
   19.11 +        print exepath, ": ", exn
   19.12 +        sys.exit(1)
   19.13  
   19.14  
   19.15  def pathTo(exe):
    20.1 --- a/tools/python/xen/xend/XendConfig.py	Tue Apr 07 11:32:24 2009 +0900
    20.2 +++ b/tools/python/xen/xend/XendConfig.py	Tue Apr 14 14:04:58 2009 +0900
    20.3 @@ -1617,10 +1617,10 @@ class XendConfig(dict):
    20.4          # extendend like this:
    20.5          #
    20.6          # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2],
    20.7 -        #                      [vslt, 0]],
    20.8 +        #                      [vslot, 0]],
    20.9          #                [state, 'Initialising']]]
   20.10          #
   20.11 -        # 'vslt' shows the virtual hotplug slot number which the PCI device
   20.12 +        # 'vslot' shows the virtual hotplug slot number which the PCI device
   20.13          # is inserted in. This is only effective for HVM domains.
   20.14          #
   20.15          # state 'Initialising' indicates that the device is being attached,
   20.16 @@ -1628,7 +1628,7 @@ class XendConfig(dict):
   20.17          #
   20.18          # The Dict looks like this:
   20.19          #
   20.20 -        # { devs: [{domain: 0, bus: 0, slot: 1, func: 2, vslt: 0}],
   20.21 +        # { devs: [{domain: 0, bus: 0, slot: 1, func: 2, vslot: 0}],
   20.22          #   states: ['Initialising'] }
   20.23  
   20.24          dev_config = {}
    21.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Tue Apr 07 11:32:24 2009 +0900
    21.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Tue Apr 14 14:04:58 2009 +0900
    21.3 @@ -596,7 +596,7 @@ class XendDomainInfo:
    21.4          #update the vslot info
    21.5          count = 0;
    21.6          for x in pci_devs:
    21.7 -            x['vslt'] = slot_list[count]
    21.8 +            x['vslot'] = slot_list[count]
    21.9              count += 1
   21.10  
   21.11  
   21.12 @@ -619,9 +619,9 @@ class XendDomainInfo:
   21.13              pci_conf = self.info['devices'][dev_uuid][1]
   21.14              pci_devs = pci_conf['devs']
   21.15              for x in pci_devs:
   21.16 -                if (int(x['vslt'], 16) == int(new_dev['vslt'], 16) and
   21.17 -                   int(x['vslt'], 16) != AUTO_PHP_SLOT):
   21.18 -                    raise VmError("vslot %s already have a device." % (new_dev['vslt']))
   21.19 +                if (int(x['vslot'], 16) == int(new_dev['vslot'], 16) and
   21.20 +                   int(x['vslot'], 16) != AUTO_PHP_SLOT):
   21.21 +                    raise VmError("vslot %s already have a device." % (new_dev['vslot']))
   21.22  
   21.23                  if (int(x['domain'], 16) == int(new_dev['domain'], 16) and
   21.24                     int(x['bus'], 16)    == int(new_dev['bus'], 16) and
   21.25 @@ -634,7 +634,7 @@ class XendDomainInfo:
   21.26                  new_dev['bus'],
   21.27                  new_dev['slot'],
   21.28                  new_dev['func'])
   21.29 -        bdf = xc.test_assign_device(self.domid, pci_str)
   21.30 +        bdf = xc.test_assign_device(0, pci_str)
   21.31          if bdf != 0:
   21.32              if bdf == -1:
   21.33                  raise VmError("failed to assign device: maybe the platform"
   21.34 @@ -685,31 +685,39 @@ class XendDomainInfo:
   21.35          # co-assignment devices hasn't been assigned, or has been assigned to
   21.36          # domN.
   21.37          coassignment_list = pci_device.find_coassigned_devices()
   21.38 -        assigned_pci_device_str_list = get_assigned_pci_devices(self.domid)
   21.39 +        assigned_pci_device_str_list = self._get_assigned_pci_devices()
   21.40          for pci_str in coassignment_list:
   21.41              (domain, bus, dev, func) = parse_pci_name(pci_str) 
   21.42              dev_str =  '0x%x,0x%x,0x%x,0x%x' % (domain, bus, dev, func)
   21.43 -            if xc.test_assign_device(self.domid, dev_str) == 0:
   21.44 +            if xc.test_assign_device(0, dev_str) == 0:
   21.45                  continue
   21.46              if not pci_str in assigned_pci_device_str_list:
   21.47 -                raise VmError(('pci: failed to pci-attach %s to dom%d" + \
   21.48 +                raise VmError(("pci: failed to pci-attach %s to domain %s" + \
   21.49                      " because one of its co-assignment device %s has been" + \
   21.50 -                    " assigned to other domain.' \
   21.51 -                    )% (pci_device.name, self.domid, pci_str))
   21.52 -
   21.53 -        opts = ''
   21.54 -        if 'opts' in new_dev and len(new_dev['opts']) > 0:
   21.55 -            config_opts = new_dev['opts']
   21.56 -            config_opts = map(lambda (x, y): x+'='+y, config_opts)
   21.57 -            opts = ',' + reduce(lambda x, y: x+','+y, config_opts)
   21.58 -
   21.59 -        bdf_str = "%s:%s:%s.%s%s@%s" % (new_dev['domain'],
   21.60 +                    " assigned to other domain." \
   21.61 +                    )% (pci_device.name, self.info['name_label'], pci_str))
   21.62 +
   21.63 +        if self.domid is not None:
   21.64 +            opts = ''
   21.65 +            if 'opts' in new_dev and len(new_dev['opts']) > 0:
   21.66 +                config_opts = new_dev['opts']
   21.67 +                config_opts = map(lambda (x, y): x+'='+y, config_opts)
   21.68 +                opts = ',' + reduce(lambda x, y: x+','+y, config_opts)
   21.69 +
   21.70 +            bdf_str = "%s:%s:%s.%s%s@%s" % (new_dev['domain'],
   21.71                  new_dev['bus'],
   21.72                  new_dev['slot'],
   21.73                  new_dev['func'],
   21.74                  opts,
   21.75 -                new_dev['vslt'])
   21.76 -        self.image.signalDeviceModel('pci-ins', 'pci-inserted', bdf_str)
   21.77 +                new_dev['vslot'])
   21.78 +            self.image.signalDeviceModel('pci-ins', 'pci-inserted', bdf_str)
   21.79 +
   21.80 +            vslot = xstransact.Read("/local/domain/0/device-model/%i/parameter"
   21.81 +                                    % self.getDomid())
   21.82 +        else:
   21.83 +            vslot = new_dev['vslot']
   21.84 +
   21.85 +        return vslot
   21.86  
   21.87  
   21.88      def device_create(self, dev_config):
   21.89 @@ -788,72 +796,101 @@ class XendDomainInfo:
   21.90          if self.info.is_hvm():
   21.91              if pci_state == 'Initialising':
   21.92                  # HVM PCI device attachment
   21.93 -                self.hvm_pci_device_create(dev_config)
   21.94 -                # Update vslt
   21.95 -                vslt = xstransact.Read("/local/domain/0/device-model/%i/parameter"
   21.96 -                                       % self.getDomid())
   21.97 -                dev['vslt'] = vslt
   21.98 +                vslot = self.hvm_pci_device_create(dev_config)
   21.99 +                # Update vslot
  21.100 +                dev['vslot'] = vslot
  21.101                  for n in sxp.children(pci_dev):
  21.102 -                    if(n[0] == 'vslt'):
  21.103 -                        n[1] = vslt
  21.104 +                    if(n[0] == 'vslot'):
  21.105 +                        n[1] = vslot
  21.106              else:
  21.107                  # HVM PCI device detachment
  21.108                  existing_dev_uuid = sxp.child_value(existing_dev_info, 'uuid')
  21.109                  existing_pci_conf = self.info['devices'][existing_dev_uuid][1]
  21.110                  existing_pci_devs = existing_pci_conf['devs']
  21.111 -                vslt = AUTO_PHP_SLOT_STR
  21.112 +                vslot = AUTO_PHP_SLOT_STR
  21.113                  for x in existing_pci_devs:
  21.114                      if ( int(x['domain'], 16) == int(dev['domain'], 16) and
  21.115                           int(x['bus'], 16) == int(dev['bus'], 16) and
  21.116                           int(x['slot'], 16) == int(dev['slot'], 16) and
  21.117                           int(x['func'], 16) == int(dev['func'], 16) ):
  21.118 -                        vslt = x['vslt']
  21.119 +                        vslot = x['vslot']
  21.120                          break
  21.121 -                if vslt == AUTO_PHP_SLOT_STR:
  21.122 +                if vslot == AUTO_PHP_SLOT_STR:
  21.123                      raise VmError("Device %04x:%02x:%02x.%01x is not connected"
  21.124                                    % (int(dev['domain'],16), int(dev['bus'],16),
  21.125                                       int(dev['slot'],16), int(dev['func'],16)))
  21.126 -                self.hvm_destroyPCIDevice(int(vslt, 16))
  21.127 -                # Update vslt
  21.128 -                dev['vslt'] = vslt
  21.129 +                self.hvm_destroyPCIDevice(int(vslot, 16))
  21.130 +                # Update vslot
  21.131 +                dev['vslot'] = vslot
  21.132                  for n in sxp.children(pci_dev):
  21.133 -                    if(n[0] == 'vslt'):
  21.134 -                        n[1] = vslt
  21.135 +                    if(n[0] == 'vslot'):
  21.136 +                        n[1] = vslot
  21.137  
  21.138          # If pci platform does not exist, create and exit.
  21.139          if existing_dev_info is None:
  21.140              self.device_create(dev_sxp)
  21.141              return True
  21.142  
  21.143 -        # use DevController.reconfigureDevice to change device config
  21.144 -        dev_control = self.getDeviceController(dev_class)
  21.145 -        dev_uuid = dev_control.reconfigureDevice(devid, dev_config)
  21.146 -        if not self.info.is_hvm():
  21.147 -            # in PV case, wait until backend state becomes connected.
  21.148 -            dev_control.waitForDevice_reconfigure(devid)
  21.149 -        num_devs = dev_control.cleanupDevice(devid)
  21.150 -
  21.151 -        # update XendConfig with new device info
  21.152 -        if dev_uuid:
  21.153 -            new_dev_sxp = dev_control.configuration(devid)
  21.154 +        if self.domid is not None:
  21.155 +            # use DevController.reconfigureDevice to change device config
  21.156 +            dev_control = self.getDeviceController(dev_class)
  21.157 +            dev_uuid = dev_control.reconfigureDevice(devid, dev_config)
  21.158 +            if not self.info.is_hvm():
  21.159 +                # in PV case, wait until backend state becomes connected.
  21.160 +                dev_control.waitForDevice_reconfigure(devid)
  21.161 +            num_devs = dev_control.cleanupDevice(devid)
  21.162 +
  21.163 +            # update XendConfig with new device info
  21.164 +            if dev_uuid:
  21.165 +                new_dev_sxp = dev_control.configuration(devid)
  21.166 +                self.info.device_update(dev_uuid, new_dev_sxp)
  21.167 +
  21.168 +            # If there is no device left, destroy pci and remove config.
  21.169 +            if num_devs == 0:
  21.170 +                if self.info.is_hvm():
  21.171 +                    self.destroyDevice('pci', devid, True)
  21.172 +                    del self.info['devices'][dev_uuid]
  21.173 +                    platform = self.info['platform']
  21.174 +                    orig_dev_num = len(platform['pci'])
  21.175 +                    # TODO: can use this to keep some info to ask high level
  21.176 +                    # management tools to hot insert a new passthrough dev
  21.177 +                    # after migration
  21.178 +                    if orig_dev_num != 0:
  21.179 +                        #platform['pci'] = ["%dDEVs" % orig_dev_num]
  21.180 +                        platform['pci'] = []
  21.181 +                else:
  21.182 +                    self.destroyDevice('pci', devid)
  21.183 +                    del self.info['devices'][dev_uuid]
  21.184 +        else:
  21.185 +            new_dev_sxp = ['pci']
  21.186 +            for cur_dev in sxp.children(existing_dev_info, 'dev'):
  21.187 +                if pci_state == 'Closing':
  21.188 +                    if int(dev['domain'], 16) == int(sxp.child_value(cur_dev, 'domain'), 16) and \
  21.189 +                       int(dev['bus'], 16) == int(sxp.child_value(cur_dev, 'bus'), 16) and \
  21.190 +                       int(dev['slot'], 16) == int(sxp.child_value(cur_dev, 'slot'), 16) and \
  21.191 +                       int(dev['func'], 16) == int(sxp.child_value(cur_dev, 'func'), 16):
  21.192 +                        continue
  21.193 +                new_dev_sxp.append(cur_dev)
  21.194 +
  21.195 +            if pci_state == 'Initialising':
  21.196 +                for new_dev in sxp.children(dev_sxp, 'dev'):
  21.197 +                    new_dev_sxp.append(new_dev)
  21.198 +
  21.199 +            dev_uuid = sxp.child_value(existing_dev_info, 'uuid')
  21.200              self.info.device_update(dev_uuid, new_dev_sxp)
  21.201  
  21.202 -        # If there is no device left, destroy pci and remove config.
  21.203 -        if num_devs == 0:
  21.204 -            if self.info.is_hvm():
  21.205 -                self.destroyDevice('pci', devid, True)
  21.206 +            # If there is only 'vscsi' in new_dev_sxp, remove the config.
  21.207 +            if len(sxp.children(new_dev_sxp, 'dev')) == 0:
  21.208                  del self.info['devices'][dev_uuid]
  21.209 -                platform = self.info['platform']
  21.210 -                orig_dev_num = len(platform['pci'])
  21.211 -                # TODO: can use this to keep some info to ask high level
  21.212 -                # management tools to hot insert a new passthrough dev
  21.213 -                # after migration
  21.214 -                if orig_dev_num != 0:
  21.215 -                    #platform['pci'] = ["%dDEVs" % orig_dev_num]
  21.216 -                    platform['pci'] = []
  21.217 -            else:
  21.218 -                self.destroyDevice('pci', devid)
  21.219 -                del self.info['devices'][dev_uuid]
  21.220 +                if self.info.is_hvm():
  21.221 +                    platform = self.info['platform']
  21.222 +                    orig_dev_num = len(platform['pci'])
  21.223 +                    # TODO: can use this to keep some info to ask high level
  21.224 +                    # management tools to hot insert a new passthrough dev
  21.225 +                    # after migration
  21.226 +                    if orig_dev_num != 0:
  21.227 +                        #platform['pci'] = ["%dDEVs" % orig_dev_num]
  21.228 +                        platform['pci'] = []
  21.229  
  21.230          xen.xend.XendDomain.instance().managed_config_save(self)
  21.231  
  21.232 @@ -1046,7 +1083,7 @@ class XendDomainInfo:
  21.233          #find the pass-through device with the virtual slot
  21.234          devnum = 0
  21.235          for x in pci_conf['devs']:
  21.236 -            if int(x['vslt'], 16) == vslot:
  21.237 +            if int(x['vslot'], 16) == vslot:
  21.238                  break
  21.239              devnum += 1
  21.240  
  21.241 @@ -1054,7 +1091,7 @@ class XendDomainInfo:
  21.242              raise VmError("Device @ vslot 0x%x doesn't exist." % (vslot))
  21.243  
  21.244          if vslot == AUTO_PHP_SLOT:
  21.245 -            raise VmError("Device @ vslot 0x%x do not support hotplug." % (vslot))
  21.246 +            raise VmError("Device @ vslot 0x%x doesn't support hotplug." % (vslot))
  21.247  
  21.248          # Check the co-assignment.
  21.249          # To pci-detach a device D from domN, we should ensure: for each DD in the
  21.250 @@ -1072,19 +1109,20 @@ class XendDomainInfo:
  21.251                      "parse it's resources - "+str(e))
  21.252          coassignment_list = pci_device.find_coassigned_devices()
  21.253          coassignment_list.remove(pci_device.name)
  21.254 -        assigned_pci_device_str_list = get_assigned_pci_devices(self.domid)
  21.255 +        assigned_pci_device_str_list = self._get_assigned_pci_devices()
  21.256          for pci_str in coassignment_list:
  21.257              if pci_str in assigned_pci_device_str_list:
  21.258 -                raise VmError(('pci: failed to pci-detach %s from dom%d" + \
  21.259 +                raise VmError(("pci: failed to pci-detach %s from domain %s" + \
  21.260                      " because one of its co-assignment device %s is still " + \
  21.261 -                    " assigned to the domain.' \
  21.262 -                    )% (pci_device.name, self.domid, pci_str))
  21.263 +                    " assigned to the domain." \
  21.264 +                    )% (pci_device.name, self.info['name_label'], pci_str))
  21.265  
  21.266  
  21.267          bdf_str = "%s:%s:%s.%s" % (x['domain'], x['bus'], x['slot'], x['func'])
  21.268          log.info("hvm_destroyPCIDevice:%s:%s!", x, bdf_str)
  21.269  
  21.270 -        self.image.signalDeviceModel('pci-rem', 'pci-removed', bdf_str)
  21.271 +        if self.domid is not None:
  21.272 +            self.image.signalDeviceModel('pci-rem', 'pci-removed', bdf_str)
  21.273  
  21.274          return 0
  21.275  
  21.276 @@ -1234,6 +1272,26 @@ class XendDomainInfo:
  21.277                  return dev_info
  21.278          return None
  21.279  
  21.280 +    def _get_assigned_pci_devices(self, devid = 0):
  21.281 +        if self.domid is not None:
  21.282 +            return get_assigned_pci_devices(self.domid)
  21.283 +
  21.284 +        dev_str_list = []
  21.285 +        dev_info = self._getDeviceInfo_pci(devid)
  21.286 +        if dev_info is None:
  21.287 +            return dev_str_list
  21.288 +        dev_uuid = sxp.child_value(dev_info, 'uuid')
  21.289 +        pci_conf = self.info['devices'][dev_uuid][1]
  21.290 +        pci_devs = pci_conf['devs']
  21.291 +        for pci_dev in pci_devs:
  21.292 +            domain = int(pci_dev['domain'], 16)
  21.293 +            bus = int(pci_dev['bus'], 16)
  21.294 +            slot = int(pci_dev['slot'], 16)
  21.295 +            func = int(pci_dev['func'], 16)
  21.296 +            dev_str = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func)
  21.297 +            dev_str_list = dev_str_list + [dev_str]
  21.298 +        return dev_str_list 
  21.299 +
  21.300      def setMemoryTarget(self, target):
  21.301          """Set the memory target of this domain.
  21.302          @param target: In MiB.
  21.303 @@ -1634,7 +1692,13 @@ class XendDomainInfo:
  21.304          if changed:
  21.305              # Update the domain section of the store, as this contains some
  21.306              # parameters derived from the VM configuration.
  21.307 -            self._storeDomDetails()
  21.308 +            self.refresh_shutdown_lock.acquire()
  21.309 +            try:
  21.310 +                state = self._stateGet()
  21.311 +                if state not in (DOM_STATE_SHUTDOWN, DOM_STATE_HALTED,):
  21.312 +                    self._storeDomDetails()
  21.313 +            finally:
  21.314 +                self.refresh_shutdown_lock.release()
  21.315  
  21.316          return 1
  21.317  
  21.318 @@ -2333,7 +2397,7 @@ class XendDomainInfo:
  21.319              pci = map(lambda x: x[0:4], pci)  # strip options 
  21.320              pci_str = str(pci)
  21.321          if hvm and pci_str:
  21.322 -            bdf = xc.test_assign_device(self.domid, pci_str)
  21.323 +            bdf = xc.test_assign_device(0, pci_str)
  21.324              if bdf != 0:
  21.325                  if bdf == -1:
  21.326                      raise VmError("failed to assign device: maybe the platform"
  21.327 @@ -3660,7 +3724,7 @@ class XendDomainInfo:
  21.328                      ['bus', '0x%02x' % ppci.get_bus()],
  21.329                      ['slot', '0x%02x' % ppci.get_slot()],
  21.330                      ['func', '0x%1x' % ppci.get_func()],
  21.331 -                    ['vslt', '0x%02x' % xenapi_pci.get('hotplug_slot')],
  21.332 +                    ['vslot', '0x%02x' % xenapi_pci.get('hotplug_slot')],
  21.333                      ['opts', dpci_opts],
  21.334                      ['uuid', dpci_uuid]
  21.335                  ],
    22.1 --- a/tools/python/xen/xend/server/pciif.py	Tue Apr 07 11:32:24 2009 +0900
    22.2 +++ b/tools/python/xen/xend/server/pciif.py	Tue Apr 14 14:04:58 2009 +0900
    22.3 @@ -71,6 +71,10 @@ class PciController(DevController):
    22.4          pcidevid = 0
    22.5          vslots = ""
    22.6          for pci_config in config.get('devs', []):
    22.7 +            vslot = pci_config.get('vslot')
    22.8 +            if vslot is not None:
    22.9 +                vslots = vslots + vslot + ";"
   22.10 +
   22.11              domain = parse_hex(pci_config.get('domain', 0))
   22.12              bus = parse_hex(pci_config.get('bus', 0))
   22.13              slot = parse_hex(pci_config.get('slot', 0))
   22.14 @@ -83,10 +87,6 @@ class PciController(DevController):
   22.15                  opts = reduce(lambda x, y: x+','+y, opts)
   22.16                  back['opts-%i' % pcidevid] = opts
   22.17  
   22.18 -            vslt = pci_config.get('vslt')
   22.19 -            if vslt is not None:
   22.20 -                vslots = vslots + vslt + ";"
   22.21 -
   22.22              back['dev-%i' % pcidevid] = "%04x:%02x:%02x.%01x" % \
   22.23                                          (domain, bus, slot, func)
   22.24              back['uuid-%i' % pcidevid] = pci_config.get('uuid', '')
   22.25 @@ -170,9 +170,9 @@ class PciController(DevController):
   22.26                  # Update vslots
   22.27                  if back.get('vslots') is not None:
   22.28                      vslots = old_vslots
   22.29 -                    for vslt in back['vslots'].split(';'):
   22.30 -                        if vslt != '':
   22.31 -                            vslots = vslots.replace(vslt + ';', '', 1)
   22.32 +                    for vslot in back['vslots'].split(';'):
   22.33 +                        if vslot != '':
   22.34 +                            vslots = vslots.replace(vslot + ';', '', 1)
   22.35                      if vslots == '':
   22.36                          self.removeBackend(devid, 'vslots')
   22.37                      else:
   22.38 @@ -219,9 +219,9 @@ class PciController(DevController):
   22.39                  #append vslot info
   22.40                  if vslots is not None:
   22.41                      try:
   22.42 -                        dev_dict['vslt'] = slot_list[i]
   22.43 +                        dev_dict['vslot'] = slot_list[i]
   22.44                      except IndexError:
   22.45 -                        dev_dict['vslt'] = AUTO_PHP_SLOT_STR
   22.46 +                        dev_dict['vslot'] = AUTO_PHP_SLOT_STR
   22.47  
   22.48                  pci_devs.append(dev_dict)
   22.49  
   22.50 @@ -454,7 +454,7 @@ class PciController(DevController):
   22.51          for (domain, bus, slot, func) in pci_dev_list:
   22.52              self.setupOneDevice(domain, bus, slot, func)
   22.53          wPath = '/local/domain/0/backend/pci/%u/0/aerState' % (self.getDomid())
   22.54 -        self.aerStatePath = xswatch(wPath, self._handleAerStateWatch)
   22.55 +        self.aerStateWatch = xswatch(wPath, self._handleAerStateWatch)
   22.56          log.debug('pci: register aer watch %s', wPath)
   22.57          return
   22.58  
   22.59 @@ -590,7 +590,7 @@ class PciController(DevController):
   22.60      def destroyDevice(self, devid, force):
   22.61          DevController.destroyDevice(self, devid, True)
   22.62          log.debug('pci: unregister aer watch')
   22.63 -        self.unwatchAerState
   22.64 +        self.unwatchAerState()
   22.65  
   22.66      def unwatchAerState(self):
   22.67          """Remove the watch on the domain's aerState node, if any."""
    23.1 --- a/tools/python/xen/xm/create.dtd	Tue Apr 07 11:32:24 2009 +0900
    23.2 +++ b/tools/python/xen/xm/create.dtd	Tue Apr 14 14:04:58 2009 +0900
    23.3 @@ -89,7 +89,7 @@
    23.4                   slot            CDATA #REQUIRED
    23.5                   func            CDATA #REQUIRED
    23.6                   opts_str        CDATA #IMPLIED
    23.7 -                 vslt            CDATA #IMPLIED>
    23.8 +                 vslot           CDATA #IMPLIED>
    23.9  
   23.10  <!ELEMENT vscsi  EMPTY>
   23.11  <!ATTLIST vscsi  p-dev           CDATA #REQUIRED
    24.1 --- a/tools/python/xen/xm/main.py	Tue Apr 07 11:32:24 2009 +0900
    24.2 +++ b/tools/python/xen/xm/main.py	Tue Apr 14 14:04:58 2009 +0900
    24.3 @@ -2155,7 +2155,7 @@ def xm_pci_list(args):
    24.4                  "bus":      "0x%02x" % int(ppci_record["bus"]),
    24.5                  "slot":     "0x%02x" % int(ppci_record["slot"]),
    24.6                  "func":     "0x%01x" % int(ppci_record["func"]),
    24.7 -                "vslt":     "0x%02x" % \
    24.8 +                "vslot":    "0x%02x" % \
    24.9                              int(server.xenapi.DPCI.get_hotplug_slot(dpci_ref))
   24.10              }
   24.11              devs.append(dev)
   24.12 @@ -2166,10 +2166,10 @@ def xm_pci_list(args):
   24.13      if len(devs) == 0:
   24.14          return
   24.15  
   24.16 -    has_vslt = devs[0].has_key('vslt')
   24.17 -    if has_vslt:
   24.18 +    has_vslot = devs[0].has_key('vslot')
   24.19 +    if has_vslot:
   24.20          hdr_str = 'VSlt domain   bus   slot   func'
   24.21 -        fmt_str =  "%(vslt)-3s    %(domain)-3s  %(bus)-3s   %(slot)-3s    %(func)-3s    "
   24.22 +        fmt_str =  "%(vslot)-3s    %(domain)-3s  %(bus)-3s   %(slot)-3s    %(func)-3s    "
   24.23      else:
   24.24          hdr_str = 'domain   bus   slot   func'
   24.25          fmt_str =  "%(domain)-3s  %(bus)-3s   %(slot)-3s    %(func)-3s    "
   24.26 @@ -2441,16 +2441,16 @@ def parse_pci_configuration(args, state,
   24.27      dom = args[0]
   24.28      pci_dev_str = args[1]
   24.29      if len(args) == 3:
   24.30 -        vslt = args[2]
   24.31 +        vslot = args[2]
   24.32      else:
   24.33 -        vslt = AUTO_PHP_SLOT_STR
   24.34 +        vslot = AUTO_PHP_SLOT_STR
   24.35      pci=['pci']
   24.36      pci_match = re.match(r"((?P<domain>[0-9a-fA-F]{1,4})[:,])?" + \
   24.37              r"(?P<bus>[0-9a-fA-F]{1,2})[:,]" + \
   24.38              r"(?P<slot>[0-9a-fA-F]{1,2})[.,]" + \
   24.39              r"(?P<func>[0-7])$", pci_dev_str)
   24.40      if pci_match == None:
   24.41 -        raise OptionError("Invalid argument: %s %s" % (pci_dev_str,vslt))
   24.42 +        raise OptionError("Invalid argument: %s %s" % (pci_dev_str, vslot))
   24.43      pci_dev_info = pci_match.groupdict('0')
   24.44  
   24.45      try:
   24.46 @@ -2458,13 +2458,13 @@ def parse_pci_configuration(args, state,
   24.47                  ['bus', '0x'+ pci_dev_info['bus']],
   24.48                  ['slot', '0x'+ pci_dev_info['slot']],
   24.49                  ['func', '0x'+ pci_dev_info['func']],
   24.50 -                ['vslt', '0x%x' % int(vslt, 16)]]
   24.51 +                ['vslot', '0x%x' % int(vslot, 16)]]
   24.52          if len(opts) > 0:
   24.53              pci_bdf.append(['opts', opts])
   24.54          pci.append(pci_bdf)
   24.55  
   24.56      except:
   24.57 -        raise OptionError("Invalid argument: %s %s" % (pci_dev_str,vslt))
   24.58 +        raise OptionError("Invalid argument: %s %s" % (pci_dev_str, vslot))
   24.59      pci.append(['state', state])
   24.60  
   24.61      return (dom, pci)
   24.62 @@ -2494,7 +2494,7 @@ def xm_pci_attach(args):
   24.63          bus = int(sxp.child_value(pci_dev, 'bus'), 16)
   24.64          slot = int(sxp.child_value(pci_dev, 'slot'), 16)
   24.65          func = int(sxp.child_value(pci_dev, 'func'), 16)
   24.66 -        vslt = int(sxp.child_value(pci_dev, 'vslt'), 16)
   24.67 +        vslot = int(sxp.child_value(pci_dev, 'vslot'), 16)
   24.68          name = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func)
   24.69  
   24.70          target_ref = None
   24.71 @@ -2508,7 +2508,7 @@ def xm_pci_attach(args):
   24.72          dpci_record = {
   24.73              "VM":           get_single_vm(dom),
   24.74              "PPCI":         target_ref,
   24.75 -            "hotplug_slot": vslt,
   24.76 +            "hotplug_slot": vslot,
   24.77              "options":      dict(config_pci_opts)
   24.78          }
   24.79          server.xenapi.DPCI.create(dpci_record)
   24.80 @@ -2667,7 +2667,7 @@ def xm_pci_detach(args):
   24.81          bus = int(sxp.child_value(pci_dev, 'bus'), 16)
   24.82          slot = int(sxp.child_value(pci_dev, 'slot'), 16)
   24.83          func = int(sxp.child_value(pci_dev, 'func'), 16)
   24.84 -        vslt = int(sxp.child_value(pci_dev, 'vslt'), 16)
   24.85 +        vslot = int(sxp.child_value(pci_dev, 'vslot'), 16)
   24.86          name = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func)
   24.87  
   24.88          target_ref = None
    25.1 --- a/tools/python/xen/xm/xenapi_create.py	Tue Apr 07 11:32:24 2009 +0900
    25.2 +++ b/tools/python/xen/xm/xenapi_create.py	Tue Apr 14 14:04:58 2009 +0900
    25.3 @@ -937,8 +937,8 @@ class sxp2xml:
    25.4                      = get_child_by_name(dev_sxp, "slot", "0")
    25.5                  pci.attributes["func"] \
    25.6                      = get_child_by_name(dev_sxp, "func", "0")
    25.7 -                pci.attributes["vslt"] \
    25.8 -                    = get_child_by_name(dev_sxp, "vslt", "0")
    25.9 +                pci.attributes["vslot"] \
   25.10 +                    = get_child_by_name(dev_sxp, "vslot", "0")
   25.11                  for opt in get_child_by_name(dev_sxp, "opts", ""):
   25.12                      if len(opt) > 0:
   25.13                          pci_opt = document.createElement("pci_opt")
    26.1 --- a/tools/security/Makefile	Tue Apr 07 11:32:24 2009 +0900
    26.2 +++ b/tools/security/Makefile	Tue Apr 14 14:04:58 2009 +0900
    26.3 @@ -40,9 +40,6 @@ ifeq ($(ACM_SECURITY),y)
    26.4  all: build
    26.5  
    26.6  .PHONY: install
    26.7 -ifndef XEN_PYTHON_NATIVE_INSTALL
    26.8 -install: LIBPATH=$(shell PYTHONPATH=../python/xen/util python -c "import auxbin; print auxbin.libpath()")
    26.9 -endif
   26.10  install: all $(ACM_CONFIG_FILE)
   26.11  	$(INSTALL_DIR) $(DESTDIR)$(SBINDIR)
   26.12  	$(INSTALL_PROG) $(ACM_INST_TOOLS) $(DESTDIR)$(SBINDIR)
   26.13 @@ -63,11 +60,8 @@ install: all $(ACM_CONFIG_FILE)
   26.14  	$(INSTALL_DATA) $(ACM_INST_HTML) $(DESTDIR)$(ACM_SECGEN_HTMLDIR)
   26.15  	$(INSTALL_DIR) $(DESTDIR)$(ACM_SECGEN_CGIDIR)
   26.16  	$(INSTALL_PROG) $(ACM_INST_CGI) $(DESTDIR)$(ACM_SECGEN_CGIDIR)
   26.17 -ifndef XEN_PYTHON_NATIVE_INSTALL
   26.18 -	python python/setup.py install --install-lib="$(DESTDIR)$(LIBPATH)/python"
   26.19 -else
   26.20 -	python python/setup.py install --root="$(DESTDIR)"
   26.21 -endif
   26.22 +	python python/setup.py install \
   26.23 +		--prefix="$(PREFIX)" --root="$(DESTDIR)" --force
   26.24  else
   26.25  .PHONY: all
   26.26  all:
    27.1 --- a/tools/security/python/xensec_tools/acm_getlabel	Tue Apr 07 11:32:24 2009 +0900
    27.2 +++ b/tools/security/python/xensec_tools/acm_getlabel	Tue Apr 14 14:04:58 2009 +0900
    27.3 @@ -4,10 +4,6 @@ import sys
    27.4  import traceback
    27.5  import getopt
    27.6  
    27.7 -# add fallback path for non-native python path installs if needed
    27.8 -sys.path.insert(-1, '/usr/lib/python')
    27.9 -sys.path.insert(-1, '/usr/lib64/python')
   27.10 -
   27.11  from xen.util.security import ACMError, err, get_ssid
   27.12  
   27.13  # getopt.gnu_getopt is better, but only exists in Python 2.3+.  Use
    28.1 --- a/tools/security/xensec_gen.py	Tue Apr 07 11:32:24 2009 +0900
    28.2 +++ b/tools/security/xensec_gen.py	Tue Apr 14 14:04:58 2009 +0900
    28.3 @@ -17,10 +17,6 @@
    28.4  
    28.5  import sys
    28.6  
    28.7 -# Add fallback path for non-native python path installs if needed
    28.8 -sys.path.append( '/usr/lib/python' )
    28.9 -sys.path.append( '/usr/lib64/python' )
   28.10 -
   28.11  from xen.xensec_gen import main
   28.12  
   28.13  main.main( )
    29.1 --- a/tools/sv/index.psp	Tue Apr 07 11:32:24 2009 +0900
    29.2 +++ b/tools/sv/index.psp	Tue Apr 14 14:04:58 2009 +0900
    29.3 @@ -1,6 +1,5 @@
    29.4  <%
    29.5  import sys
    29.6 -sys.path.append( "/usr/lib/python" )
    29.7  
    29.8  debug = True and False
    29.9  
    30.1 --- a/tools/vnet/scripts/vn	Tue Apr 07 11:32:24 2009 +0900
    30.2 +++ b/tools/vnet/scripts/vn	Tue Apr 14 14:04:58 2009 +0900
    30.3 @@ -27,9 +27,6 @@ import socket
    30.4  import sys
    30.5  from getopt import getopt, GetoptError
    30.6  
    30.7 -sys.path.append('/usr/lib/python')
    30.8 -sys.path.append('/usr/lib64/python')
    30.9 -
   30.10  from xen.xend import sxp
   30.11  from xen.xend.PrettyPrint import prettyprint
   30.12  
    31.1 --- a/tools/xenpmd/Makefile	Tue Apr 07 11:32:24 2009 +0900
    31.2 +++ b/tools/xenpmd/Makefile	Tue Apr 14 14:04:58 2009 +0900
    31.3 @@ -19,4 +19,7 @@ install: all
    31.4  clean:
    31.5  	$(RM) -f $(BIN) $(DEPS)
    31.6  
    31.7 +%: %.c Makefile
    31.8 +	$(CC) $(CFLAGS) $< $(LDFLAGS) -o $@
    31.9 +
   31.10  -include $(DEPS)
    32.1 --- a/xen/Makefile	Tue Apr 07 11:32:24 2009 +0900
    32.2 +++ b/xen/Makefile	Tue Apr 14 14:04:58 2009 +0900
    32.3 @@ -2,7 +2,7 @@
    32.4  # All other places this is stored (eg. compile.h) should be autogenerated.
    32.5  export XEN_VERSION       = 3
    32.6  export XEN_SUBVERSION    = 4
    32.7 -export XEN_EXTRAVERSION ?= -unstable$(XEN_VENDORVERSION)
    32.8 +export XEN_EXTRAVERSION ?= .0-rc2-pre$(XEN_VENDORVERSION)
    32.9  export XEN_FULLVERSION   = $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION)
   32.10  -include xen-version
   32.11  
    33.1 --- a/xen/arch/x86/acpi/cpu_idle.c	Tue Apr 07 11:32:24 2009 +0900
    33.2 +++ b/xen/arch/x86/acpi/cpu_idle.c	Tue Apr 14 14:04:58 2009 +0900
    33.3 @@ -48,7 +48,7 @@
    33.4  #include <public/platform.h>
    33.5  #include <public/sysctl.h>
    33.6  
    33.7 -#define DEBUG_PM_CX
    33.8 +/*#define DEBUG_PM_CX*/
    33.9  
   33.10  static void (*lapic_timer_off)(void);
   33.11  static void (*lapic_timer_on)(void);
   33.12 @@ -780,7 +780,7 @@ long set_cx_pminfo(uint32_t cpu, struct 
   33.13  
   33.14      /* FIXME: C-state dependency is not supported by far */
   33.15  
   33.16 -    print_acpi_power(cpu_id, acpi_power);
   33.17 +    /*print_acpi_power(cpu_id, acpi_power);*/
   33.18  
   33.19      if ( cpu_id == 0 && pm_idle_save == NULL )
   33.20      {
    34.1 --- a/xen/arch/x86/cpu/mcheck/mce.c	Tue Apr 07 11:32:24 2009 +0900
    34.2 +++ b/xen/arch/x86/cpu/mcheck/mce.c	Tue Apr 14 14:04:58 2009 +0900
    34.3 @@ -23,6 +23,7 @@
    34.4  #include "mce.h"
    34.5  
    34.6  int mce_disabled = 0;
    34.7 +int is_mc_panic = 0;
    34.8  unsigned int nr_mce_banks;
    34.9  
   34.10  EXPORT_SYMBOL_GPL(nr_mce_banks);	/* non-fatal.o */
   34.11 @@ -33,18 +34,15 @@ static void mcinfo_clear(struct mc_info 
   34.12  #define	SEG_PL(segsel)			((segsel) & 0x3)
   34.13  #define _MC_MSRINJ_F_REQ_HWCR_WREN	(1 << 16)
   34.14  
   34.15 -#if 1	/* XXFM switch to 0 for putback */
   34.16 -
   34.17 -#define	x86_mcerr(str, err) _x86_mcerr(str, err)
   34.18 -
   34.19 -static int _x86_mcerr(const char *msg, int err)
   34.20 +#if 0
   34.21 +static int x86_mcerr(const char *msg, int err)
   34.22  {
   34.23 -	printk("x86_mcerr: %s, returning %d\n",
   34.24 -	    msg != NULL ? msg : "", err);
   34.25 -	return err;
   34.26 +    gdprintk(XENLOG_WARNING, "x86_mcerr: %s, returning %d\n",
   34.27 +             msg != NULL ? msg : "", err);
   34.28 +    return err;
   34.29  }
   34.30  #else
   34.31 -#define x86_mcerr(str,err)
   34.32 +#define x86_mcerr(msg, err) (err)
   34.33  #endif
   34.34  
   34.35  cpu_banks_t mca_allbanks;
   34.36 @@ -127,6 +125,7 @@ mctelem_cookie_t mcheck_mca_logout(enum 
   34.37  
   34.38  	switch (who) {
   34.39  	case MCA_MCE_HANDLER:
   34.40 +	case MCA_MCE_SCAN:
   34.41  		mcg.mc_flags = MC_FLAG_MCE;
   34.42  		which = MC_URGENT;
   34.43  		break;
   34.44 @@ -222,8 +221,9 @@ mctelem_cookie_t mcheck_mca_logout(enum 
   34.45  			cbret = mc_callback_bank_extended(mci, i, status);
   34.46  		}
   34.47  
   34.48 -		/* Clear status */
   34.49 -		mca_wrmsrl(MSR_IA32_MC0_STATUS + 4 * i, 0x0ULL);
   34.50 +		if (who != MCA_MCE_SCAN)
   34.51 +			/* Clear status */
   34.52 +			mca_wrmsrl(MSR_IA32_MC0_STATUS + 4 * i, 0x0ULL);
   34.53  		wmb();
   34.54  	}
   34.55  
   34.56 @@ -472,6 +472,21 @@ cmn_handler_done:
   34.57  	}
   34.58  }
   34.59  
   34.60 +void mcheck_mca_clearbanks(cpu_banks_t bankmask)
   34.61 +{
   34.62 +	int i;
   34.63 +	uint64_t status;
   34.64 +
   34.65 +	for (i = 0; i < 32 && i < nr_mce_banks; i++) {
   34.66 +		if (!test_bit(i, bankmask))
   34.67 +			continue;
   34.68 +		mca_rdmsrl(MSR_IA32_MC0_STATUS + i * 4, status);
   34.69 +		if (!(status & MCi_STATUS_VAL))
   34.70 +			continue;
   34.71 +		mca_wrmsrl(MSR_IA32_MC0_STATUS + 4 * i, 0x0ULL);
   34.72 +	}
   34.73 +}
   34.74 +
   34.75  static int amd_mcheck_init(struct cpuinfo_x86 *ci)
   34.76  {
   34.77  	int rc = 0;
   34.78 @@ -1064,6 +1079,9 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u
   34.79  	struct xen_mc_msrinject *mc_msrinject;
   34.80  	struct xen_mc_mceinject *mc_mceinject;
   34.81  
   34.82 +	if (!IS_PRIV(v->domain) )
   34.83 +		return x86_mcerr(NULL, -EPERM);
   34.84 +
   34.85  	if ( copy_from_guest(op, u_xen_mc, 1) )
   34.86  		return x86_mcerr("do_mca: failed copyin of xen_mc_t", -EFAULT);
   34.87  
   34.88 @@ -1075,10 +1093,6 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u
   34.89  		mc_fetch.nat = &op->u.mc_fetch;
   34.90  		cmdflags = mc_fetch.nat->flags;
   34.91  
   34.92 -		/* This hypercall is for Dom0 only */
   34.93 -		if (!IS_PRIV(v->domain) )
   34.94 -			return x86_mcerr(NULL, -EPERM);
   34.95 -
   34.96  		switch (cmdflags & (XEN_MC_NONURGENT | XEN_MC_URGENT)) {
   34.97  		case XEN_MC_NONURGENT:
   34.98  			which = MC_NONURGENT;
   34.99 @@ -1134,9 +1148,6 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u
  34.100  		return x86_mcerr("do_mca notify unsupported", -EINVAL);
  34.101  
  34.102  	case XEN_MC_physcpuinfo:
  34.103 -		if ( !IS_PRIV(v->domain) )
  34.104 -			return x86_mcerr("do_mca cpuinfo", -EPERM);
  34.105 -
  34.106  		mc_physcpuinfo.nat = &op->u.mc_physcpuinfo;
  34.107  		nlcpu = num_online_cpus();
  34.108  
  34.109 @@ -1173,9 +1184,6 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u
  34.110  		break;
  34.111  
  34.112  	case XEN_MC_msrinject:
  34.113 -		if ( !IS_PRIV(v->domain) )
  34.114 -			return x86_mcerr("do_mca inject", -EPERM);
  34.115 -
  34.116  		if (nr_mce_banks == 0)
  34.117  			return x86_mcerr("do_mca inject", -ENODEV);
  34.118  
  34.119 @@ -1203,9 +1211,6 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u
  34.120  		break;
  34.121  
  34.122  	case XEN_MC_mceinject:
  34.123 -		if ( !IS_PRIV(v->domain) )
  34.124 -			return x86_mcerr("do_mca #MC", -EPERM);
  34.125 -
  34.126  		if (nr_mce_banks == 0)
  34.127  			return x86_mcerr("do_mca #MC", -ENODEV);
  34.128  
  34.129 @@ -1220,9 +1225,8 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u
  34.130  
  34.131  		add_taint(TAINT_ERROR_INJECT);
  34.132  
  34.133 -		on_selected_cpus(cpumask_of_cpu(target),
  34.134 -		    x86_mc_mceinject, mc_mceinject, 1, 1);
  34.135 -
  34.136 +		on_selected_cpus(cpumask_of_cpu(target), x86_mc_mceinject,
  34.137 +		    mc_mceinject, 1, 1);
  34.138  		break;
  34.139  
  34.140  	default:
  34.141 @@ -1246,6 +1250,7 @@ void set_poll_bankmask(struct cpuinfo_x8
  34.142  }
  34.143  void mc_panic(char *s)
  34.144  {
  34.145 +    is_mc_panic = 1;
  34.146      console_start_sync();
  34.147      printk("Fatal machine check: %s\n", s);
  34.148      printk("\n"
    35.1 --- a/xen/arch/x86/cpu/mcheck/mce.h	Tue Apr 07 11:32:24 2009 +0900
    35.2 +++ b/xen/arch/x86/cpu/mcheck/mce.h	Tue Apr 14 14:04:58 2009 +0900
    35.3 @@ -70,7 +70,8 @@ enum mca_source {
    35.4  	MCA_MCE_HANDLER,
    35.5  	MCA_POLLER,
    35.6  	MCA_CMCI_HANDLER,
    35.7 -	MCA_RESET
    35.8 +	MCA_RESET,
    35.9 +	MCA_MCE_SCAN
   35.10  };
   35.11  
   35.12  enum mca_extinfo {
   35.13 @@ -92,6 +93,8 @@ void set_poll_bankmask(struct cpuinfo_x8
   35.14  DECLARE_PER_CPU(cpu_banks_t, poll_bankmask);
   35.15  DECLARE_PER_CPU(cpu_banks_t, no_cmci_banks);
   35.16  extern int cmci_support;
   35.17 +extern int is_mc_panic;
   35.18 +extern void mcheck_mca_clearbanks(cpu_banks_t);
   35.19  
   35.20  extern mctelem_cookie_t mcheck_mca_logout(enum mca_source, cpu_banks_t,
   35.21      struct mca_summary *);
    36.1 --- a/xen/arch/x86/cpu/mcheck/mce_intel.c	Tue Apr 07 11:32:24 2009 +0900
    36.2 +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c	Tue Apr 14 14:04:58 2009 +0900
    36.3 @@ -18,6 +18,29 @@ int cmci_support = 0;
    36.4  static int nr_intel_ext_msrs = 0;
    36.5  static int firstbank;
    36.6  
    36.7 +/* Below are for MCE handling */
    36.8 +struct mce_softirq_barrier {
    36.9 +	atomic_t val;
   36.10 +	atomic_t ingen;
   36.11 +	atomic_t outgen;
   36.12 +};
   36.13 +
   36.14 +static struct mce_softirq_barrier mce_inside_bar, mce_severity_bar;
   36.15 +static struct mce_softirq_barrier mce_trap_bar;
   36.16 +
   36.17 +/*
   36.18 + * mce_logout_lock should only be used in the trap handler,
   36.19 + * while MCIP has not been cleared yet in the global status
   36.20 + * register. Other use is not safe, since an MCE trap can
   36.21 + * happen at any moment, which would cause lock recursion.
   36.22 + */
   36.23 +static DEFINE_SPINLOCK(mce_logout_lock);
   36.24 +
   36.25 +static atomic_t severity_cpu = ATOMIC_INIT(-1);
   36.26 +
   36.27 +static void mce_barrier_enter(struct mce_softirq_barrier *);
   36.28 +static void mce_barrier_exit(struct mce_softirq_barrier *);
   36.29 +
   36.30  #ifdef CONFIG_X86_MCE_THERMAL
   36.31  static void unexpected_thermal_interrupt(struct cpu_user_regs *regs)
   36.32  {
   36.33 @@ -123,7 +146,7 @@ static inline void intel_get_extended_ms
   36.34      if ( ext->mc_msrs < ARRAY_SIZE(ext->mc_msr)
   36.35           && msr < MSR_IA32_MCG_EAX + nr_intel_ext_msrs ) {
   36.36          ext->mc_msr[ext->mc_msrs].reg = msr;
   36.37 -        rdmsrl(msr, ext->mc_msr[ext->mc_msrs].value);
   36.38 +        mca_rdmsrl(msr, ext->mc_msr[ext->mc_msrs].value);
   36.39          ++ext->mc_msrs;
   36.40      }
   36.41  }
   36.42 @@ -169,45 +192,6 @@ intel_get_extended_msrs(struct mc_info *
   36.43      return MCA_EXTINFO_GLOBAL;
   36.44  }
   36.45  
   36.46 -/* Below are for MCE handling */
   36.47 -
   36.48 -/* Log worst error severity and offending CPU.,
   36.49 - * Pick this CPU for further processing in softirq */
   36.50 -static int severity_cpu = -1;
   36.51 -static int worst = 0;
   36.52 -
   36.53 -/* Lock of entry@second round scanning in MCE# handler */
   36.54 -static cpumask_t scanned_cpus;
   36.55 -/* Lock for entry@Critical Section in MCE# handler */
   36.56 -static bool_t mce_enter_lock = 0;
   36.57 -/* Record how many CPUs impacted in this MCE# */
   36.58 -static cpumask_t impact_map;
   36.59 -
   36.60 -/* Lock of softirq rendezvous entering point */
   36.61 -static cpumask_t mced_cpus;
   36.62 -/*Lock of softirq rendezvous leaving point */
   36.63 -static cpumask_t finished_cpus;
   36.64 -/* Lock for picking one processing CPU */
   36.65 -static bool_t mce_process_lock = 0;
   36.66 -
   36.67 -/* Spinlock for vMCE# MSR virtualization data */
   36.68 -static DEFINE_SPINLOCK(mce_locks);
   36.69 -
   36.70 -/* Local buffer for holding MCE# data temporarily, sharing between mce
   36.71 - * handler and softirq handler. Those data will be finally committed
   36.72 - * for DOM0 Log and coped to per_dom related data for guest vMCE#
   36.73 - * MSR virtualization.
   36.74 - * Note: When local buffer is still in processing in softirq, another
   36.75 - * MCA comes, simply panic.
   36.76 - */
   36.77 -
   36.78 -struct mc_local_t
   36.79 -{
   36.80 -    bool_t in_use;
   36.81 -    mctelem_cookie_t mctc[NR_CPUS];
   36.82 -};
   36.83 -static struct mc_local_t mc_local;
   36.84 -
   36.85  /* This node list records errors impacting a domain. when one
   36.86   * MCE# happens, one error bank impacts a domain. This error node
   36.87   * will be inserted to the tail of the per_dom data for vMCE# MSR
   36.88 @@ -252,18 +236,22 @@ static int fill_vmsr_data(int cpu, struc
   36.89          }
   36.90  
   36.91          entry = alloc_bank_entry();
   36.92 +        if (entry == NULL)
   36.93 +	    return -1;
   36.94          entry->mci_status = mc_bank->mc_status;
   36.95          entry->mci_addr = mc_bank->mc_addr;
   36.96          entry->mci_misc = mc_bank->mc_misc;
   36.97          entry->cpu = cpu;
   36.98          entry->bank = mc_bank->mc_bank;
   36.99  
  36.100 +	spin_lock(&d->arch.vmca_msrs.lock);
  36.101          /* New error Node, insert to the tail of the per_dom data */
  36.102          list_add_tail(&entry->list, &d->arch.vmca_msrs.impact_header);
  36.103          /* Fill MSR global status */
  36.104          d->arch.vmca_msrs.mcg_status = gstatus;
  36.105          /* New node impact the domain, need another vMCE# injection*/
  36.106          d->arch.vmca_msrs.nr_injection++;
  36.107 +	spin_unlock(&d->arch.vmca_msrs.lock);
  36.108  
  36.109          printk(KERN_DEBUG "MCE: Found error @[CPU%d BANK%d "
  36.110                  "status %"PRIx64" addr %"PRIx64" domid %d]\n ",
  36.111 @@ -273,100 +261,83 @@ static int fill_vmsr_data(int cpu, struc
  36.112      return 0;
  36.113  }
  36.114  
  36.115 -static int mce_actions(void) {
  36.116 -    int32_t cpu, ret;
  36.117 +/*
  36.118 + * Called from mctelem_process_deferred. Return 1 if the telemetry
  36.119 + * should be committed for dom0 consumption, 0 if it should be
  36.120 + * dismissed.
  36.121 + */
  36.122 +static int mce_action(unsigned int cpu, mctelem_cookie_t mctc)
  36.123 +{
  36.124      struct mc_info *local_mi;
  36.125      struct mcinfo_common *mic = NULL;
  36.126      struct mcinfo_global *mc_global;
  36.127      struct mcinfo_bank *mc_bank;
  36.128  
  36.129 -    /* Spinlock is used for exclusive read/write of vMSR virtualization
  36.130 -     * (per_dom vMCE# data)
  36.131 -     */
  36.132 -    spin_lock(&mce_locks);
  36.133 -
  36.134 -    /*
  36.135 -     * If softirq is filling this buffer while another MCE# comes,
  36.136 -     * simply panic
  36.137 -     */
  36.138 -    test_and_set_bool(mc_local.in_use);
  36.139 -
  36.140 -    for_each_cpu_mask(cpu, impact_map) {
  36.141 -        if (mc_local.mctc[cpu] == NULL) {
  36.142 -            printk(KERN_ERR "MCE: get reserved entry failed\n ");
  36.143 -            ret = -1;
  36.144 -            goto end;
  36.145 -        }
  36.146 -        local_mi = (struct mc_info*)mctelem_dataptr(mc_local.mctc[cpu]);
  36.147 -        x86_mcinfo_lookup(mic, local_mi, MC_TYPE_GLOBAL);
  36.148 -        if (mic == NULL) {
  36.149 -            printk(KERN_ERR "MCE: get local buffer entry failed\n ");
  36.150 -            ret = -1;
  36.151 -            goto end;
  36.152 -        }
  36.153 -
  36.154 -        mc_global = (struct mcinfo_global *)mic;
  36.155 -
  36.156 -        /* Processing bank information */
  36.157 -        x86_mcinfo_lookup(mic, local_mi, MC_TYPE_BANK);
  36.158 -
  36.159 -        for ( ; mic && mic->size; mic = x86_mcinfo_next(mic) ) {
  36.160 -            if (mic->type != MC_TYPE_BANK) {
  36.161 -                continue;
  36.162 -            }
  36.163 -            mc_bank = (struct mcinfo_bank*)mic;
  36.164 -            /* Fill vMCE# injection and vMCE# MSR virtualization related data */
  36.165 -            if (fill_vmsr_data(cpu, mc_bank, mc_global->mc_gstatus) == -1) {
  36.166 -                ret = -1;
  36.167 -                goto end;
  36.168 -            }
  36.169 -
  36.170 -            /* TODO: Add recovery actions here, such as page-offline, etc */
  36.171 -        }
  36.172 -    } /* end of impact_map loop */
  36.173 -
  36.174 -    ret = 0;
  36.175 -
  36.176 -end:
  36.177 -
  36.178 -    for_each_cpu_mask(cpu, impact_map) {
  36.179 -        /* This reserved entry is processed, commit it */
  36.180 -        if (mc_local.mctc[cpu] != NULL) {
  36.181 -            mctelem_commit(mc_local.mctc[cpu]);
  36.182 -            printk(KERN_DEBUG "MCE: Commit one URGENT ENTRY\n");
  36.183 -        }
  36.184 +    local_mi = (struct mc_info*)mctelem_dataptr(mctc);
  36.185 +    x86_mcinfo_lookup(mic, local_mi, MC_TYPE_GLOBAL);
  36.186 +    if (mic == NULL) {
  36.187 +        printk(KERN_ERR "MCE: get local buffer entry failed\n ");
  36.188 +        return 0;
  36.189      }
  36.190  
  36.191 -    test_and_clear_bool(mc_local.in_use);
  36.192 -    spin_unlock(&mce_locks);
  36.193 -    return ret;
  36.194 +    mc_global = (struct mcinfo_global *)mic;
  36.195 +
  36.196 +    /* Processing bank information */
  36.197 +    x86_mcinfo_lookup(mic, local_mi, MC_TYPE_BANK);
  36.198 +
  36.199 +    for ( ; mic && mic->size; mic = x86_mcinfo_next(mic) ) {
  36.200 +        if (mic->type != MC_TYPE_BANK) {
  36.201 +            continue;
  36.202 +        }
  36.203 +        mc_bank = (struct mcinfo_bank*)mic;
  36.204 +        /* Fill vMCE# injection and vMCE# MSR virtualization related data */
  36.205 +        if (fill_vmsr_data(cpu, mc_bank, mc_global->mc_gstatus) == -1)
  36.206 +             break;
  36.207 +
  36.208 +       /* TODO: Add recovery actions here, such as page-offline, etc */
  36.209 +    }
  36.210 +
  36.211 +    return 1;
  36.212  }
  36.213  
  36.214  /* Softirq Handler for this MCE# processing */
  36.215  static void mce_softirq(void)
  36.216  {
  36.217      int cpu = smp_processor_id();
  36.218 +    unsigned int workcpu;
  36.219      cpumask_t affinity;
  36.220  
  36.221 -    /* Wait until all cpus entered softirq */
  36.222 -    while ( cpus_weight(mced_cpus) != num_online_cpus() ) {
  36.223 -        cpu_relax();
  36.224 -    }
  36.225 -    /* Not Found worst error on severity_cpu, it's weird */
  36.226 -    if (severity_cpu == -1) {
  36.227 -        printk(KERN_WARNING "MCE: not found severity_cpu!\n");
  36.228 -        mc_panic("MCE: not found severity_cpu!");
  36.229 -        return;
  36.230 -    }
  36.231 +    printk(KERN_DEBUG "CPU%d enter softirq\n", cpu);
  36.232 +
  36.233 +    mce_barrier_enter(&mce_inside_bar);
  36.234 +
  36.235 +    /*
  36.236 +     * Everybody is here. Now let's see who gets to do the
  36.237 +     * recovery work. Right now we just see if there's a CPU
  36.238 +     * that did not have any problems, and pick that one.
  36.239 +     *
  36.240 +     * First, just set a default value: the last CPU who reaches this
  36.241 +     * will overwrite the value and become the default.
  36.242 +     */
  36.243 +
  36.244 +    atomic_set(&severity_cpu, cpu);
  36.245 +
  36.246 +    mce_barrier_enter(&mce_severity_bar);
  36.247 +    if (!mctelem_has_deferred(cpu))
  36.248 +        atomic_set(&severity_cpu, cpu);
  36.249 +    mce_barrier_exit(&mce_severity_bar);
  36.250 +
  36.251      /* We choose severity_cpu for further processing */
  36.252 -    if (severity_cpu == cpu) {
  36.253 +    if (atomic_read(&severity_cpu) == cpu) {
  36.254 +
  36.255 +        printk(KERN_DEBUG "CPU%d handling errors\n", cpu);
  36.256  
  36.257          /* Step1: Fill DOM0 LOG buffer, vMCE injection buffer and
  36.258           * vMCE MSRs virtualization buffer
  36.259           */
  36.260 -        if (mce_actions())
  36.261 -            mc_panic("MCE recovery actions or Filling vMCE MSRS "
  36.262 -                     "virtualization data failed!\n");
  36.263 +        for_each_online_cpu(workcpu) {
  36.264 +	    mctelem_process_deferred(workcpu, mce_action);
  36.265 +        }
  36.266  
  36.267          /* Step2: Send Log to DOM0 through vIRQ */
  36.268          if (dom0 && guest_enabled_event(dom0->vcpu[0], VIRQ_MCA)) {
  36.269 @@ -387,26 +358,9 @@ static void mce_softirq(void)
  36.270              vcpu_set_affinity(dom0->vcpu[0], &affinity);
  36.271              vcpu_kick(dom0->vcpu[0]);
  36.272          }
  36.273 -
  36.274 -        /* Clean Data */
  36.275 -        test_and_clear_bool(mce_process_lock);
  36.276 -        cpus_clear(impact_map);
  36.277 -        cpus_clear(scanned_cpus);
  36.278 -        worst = 0;
  36.279 -        cpus_clear(mced_cpus);
  36.280 -        memset(&mc_local, 0x0, sizeof(mc_local));
  36.281      }
  36.282  
  36.283 -    cpu_set(cpu, finished_cpus);
  36.284 -    wmb();
  36.285 -   /* Leave until all cpus finished recovery actions in softirq */
  36.286 -    while ( cpus_weight(finished_cpus) != num_online_cpus() ) {
  36.287 -        cpu_relax();
  36.288 -    }
  36.289 -
  36.290 -    cpus_clear(finished_cpus);
  36.291 -    severity_cpu = -1;
  36.292 -    printk(KERN_DEBUG "CPU%d exit softirq \n", cpu);
  36.293 +    mce_barrier_exit(&mce_inside_bar);
  36.294  }
  36.295  
  36.296  /* Machine Check owner judge algorithm:
  36.297 @@ -424,127 +378,157 @@ static void mce_softirq(void)
  36.298   * Round2: Do all MCE processing logic as normal.
  36.299   */
  36.300  
  36.301 -/* Simple Scan. Panic when found non-recovery errors. Doing this for
  36.302 - * avoiding LOG missing
  36.303 - */
  36.304 -static void severity_scan(void)
  36.305 +static void mce_panic_check(void)
  36.306  {
  36.307 -    uint64_t status;
  36.308 -    int32_t i;
  36.309 -
  36.310 -    /* TODO: For PCC = 0, we need to have further judge. If it is can't be
  36.311 -     * recovered, we need to RESET for avoiding DOM0 LOG missing
  36.312 -     */
  36.313 -    for ( i = 0; i < nr_mce_banks; i++) {
  36.314 -        mca_rdmsrl(MSR_IA32_MC0_STATUS + 4 * i , status);
  36.315 -        if ( !(status & MCi_STATUS_VAL) )
  36.316 -            continue;
  36.317 -        /* MCE handler only handles UC error */
  36.318 -        if ( !(status & MCi_STATUS_UC) )
  36.319 -            continue;
  36.320 -        if ( !(status & MCi_STATUS_EN) )
  36.321 -            continue;
  36.322 -        /*
  36.323 -         * If this was an injected error, keep going, since the
  36.324 -         * interposed value will be lost at reboot.
  36.325 -         */
  36.326 -        if (status & MCi_STATUS_PCC && intpose_lookup(smp_processor_id(),
  36.327 -          MSR_IA32_MC0_STATUS + 4 * i, NULL) == NULL)
  36.328 -            mc_panic("pcc = 1, cpu unable to continue\n");
  36.329 -    }
  36.330 -
  36.331 -    /* TODO: Further judgement for later CPUs here, maybe need MCACOD assistence */
  36.332 -    /* EIPV and RIPV is not a reliable way to judge the error severity */
  36.333 -
  36.334 +      if (is_mc_panic) {
  36.335 +              local_irq_enable();
  36.336 +              for ( ; ; )
  36.337 +                      halt();
  36.338 +      }
  36.339  }
  36.340  
  36.341 +/*
  36.342 + * Initialize a barrier. Just set it to 0.
  36.343 + */
  36.344 +static void mce_barrier_init(struct mce_softirq_barrier *bar)
  36.345 +{
  36.346 +      atomic_set(&bar->val, 0);
  36.347 +      atomic_set(&bar->ingen, 0);
  36.348 +      atomic_set(&bar->outgen, 0);
  36.349 +}
  36.350 +
  36.351 +#if 0
  36.352 +/*
  36.353 + * This function will need to be used when offlining a CPU in the
  36.354 + * recovery actions.
  36.355 + *
  36.356 + * Decrement a barrier only. Needed for cases where the CPU
  36.357 + * in question can't do it itself (e.g. it is being offlined).
  36.358 + */
  36.359 +static void mce_barrier_dec(struct mce_softirq_barrier *bar)
  36.360 +{
  36.361 +      atomic_inc(&bar->outgen);
  36.362 +      wmb();
  36.363 +      atomic_dec(&bar->val);
  36.364 +}
  36.365 +#endif
  36.366 +
  36.367 +static void mce_spin_lock(spinlock_t *lk)
  36.368 +{
  36.369 +      while (!spin_trylock(lk)) {
  36.370 +              cpu_relax();
  36.371 +              mce_panic_check();
  36.372 +      }
  36.373 +}
  36.374 +
  36.375 +static void mce_spin_unlock(spinlock_t *lk)
  36.376 +{
  36.377 +      spin_unlock(lk);
  36.378 +}
  36.379 +
  36.380 +/*
  36.381 + * Increment the generation number and the value. The generation number
  36.382 + * is incremented when entering a barrier. This way, it can be checked
  36.383 + * on exit if a CPU is trying to re-enter the barrier. This can happen
  36.384 + * if the first CPU to make it out immediately exits or re-enters, while
  36.385 + * another CPU that is still in the loop becomes otherwise occupied
  36.386 + * (e.g. it needs to service an interrupt, etc), missing the value
  36.387 + * it's waiting for.
  36.388 + *
  36.389 + * These barrier functions should always be paired, so that the
  36.390 + * counter value will reach 0 again after all CPUs have exited.
  36.391 + */
  36.392 +static void mce_barrier_enter(struct mce_softirq_barrier *bar)
  36.393 +{
  36.394 +      int gen;
  36.395 +
  36.396 +      atomic_inc(&bar->ingen);
  36.397 +      gen = atomic_read(&bar->outgen);
  36.398 +      mb();
  36.399 +      atomic_inc(&bar->val);
  36.400 +      while ( atomic_read(&bar->val) != num_online_cpus() &&
  36.401 +          atomic_read(&bar->outgen) == gen) {
  36.402 +              mb();
  36.403 +              mce_panic_check();
  36.404 +      }
  36.405 +}
  36.406 +
  36.407 +static void mce_barrier_exit(struct mce_softirq_barrier *bar)
  36.408 +{
  36.409 +      int gen;
  36.410 +
  36.411 +      atomic_inc(&bar->outgen);
  36.412 +      gen = atomic_read(&bar->ingen);
  36.413 +      mb();
  36.414 +      atomic_dec(&bar->val);
  36.415 +      while ( atomic_read(&bar->val) != 0 &&
  36.416 +          atomic_read(&bar->ingen) == gen ) {
  36.417 +              mb();
  36.418 +              mce_panic_check();
  36.419 +      }
  36.420 +}
  36.421 +
  36.422 +static void mce_barrier(struct mce_softirq_barrier *bar)
  36.423 +{
  36.424 +      mce_barrier_enter(bar);
  36.425 +      mce_barrier_exit(bar);
  36.426 +}
  36.427  
  36.428  static void intel_machine_check(struct cpu_user_regs * regs, long error_code)
  36.429  {
  36.430 -    unsigned int cpu = smp_processor_id();
  36.431 -    int32_t severity = 0;
  36.432      uint64_t gstatus;
  36.433      mctelem_cookie_t mctc = NULL;
  36.434      struct mca_summary bs;
  36.435  
  36.436 -    /* First round scanning */
  36.437 -    severity_scan();
  36.438 -    cpu_set(cpu, scanned_cpus);
  36.439 -    while (cpus_weight(scanned_cpus) < num_online_cpus())
  36.440 -        cpu_relax();
  36.441 +    mce_spin_lock(&mce_logout_lock);
  36.442  
  36.443 -    wmb();
  36.444 -    /* All CPUs Finished first round scanning */
  36.445 -    if (mc_local.in_use != 0) {
  36.446 -        mc_panic("MCE: Local buffer is being processed, can't handle new MCE!\n");
  36.447 -        return;
  36.448 -    }
  36.449 +    mctc = mcheck_mca_logout(MCA_MCE_SCAN, mca_allbanks, &bs);
  36.450  
  36.451 -    /* Enter Critical Section */
  36.452 -    while (test_and_set_bool(mce_enter_lock)) {
  36.453 -        udelay (1);
  36.454 -    }
  36.455 -
  36.456 -    mctc = mcheck_mca_logout(MCA_MCE_HANDLER, mca_allbanks, &bs);
  36.457 -     /* local data point to the reserved entry, let softirq to
  36.458 -      * process the local data */
  36.459 -    if (!bs.errcnt) {
  36.460 +    if (bs.errcnt) {
  36.461 +        /*
  36.462 +         * Uncorrected errors must be dealth with in softirq context.
  36.463 +         */
  36.464 +        if (bs.uc || bs.pcc) {
  36.465 +            add_taint(TAINT_MACHINE_CHECK);
  36.466 +            if (mctc != NULL)
  36.467 +                mctelem_defer(mctc);
  36.468 +            /*
  36.469 +             * For PCC=1, context is lost, so reboot now without clearing
  36.470 +             * the banks, and deal with the telemetry after reboot
  36.471 +             * (the MSRs are sticky)
  36.472 +             */
  36.473 +            if (bs.pcc)
  36.474 +                mc_panic("State lost due to machine check exception.\n");
  36.475 +        } else {
  36.476 +            if (mctc != NULL)
  36.477 +                mctelem_commit(mctc);
  36.478 +        }
  36.479 +        mcheck_mca_clearbanks(mca_allbanks);
  36.480 +    } else {
  36.481          if (mctc != NULL)
  36.482              mctelem_dismiss(mctc);
  36.483 -        mc_local.mctc[cpu] = NULL;
  36.484 -        cpu_set(cpu, mced_cpus);
  36.485 -        test_and_clear_bool(mce_enter_lock);
  36.486 -        raise_softirq(MACHINE_CHECK_SOFTIRQ);
  36.487 -        return;
  36.488 -    }
  36.489 -    else if ( mctc != NULL) {
  36.490 -        mc_local.mctc[cpu] = mctc;
  36.491      }
  36.492  
  36.493 -    if (bs.uc || bs.pcc)
  36.494 -        add_taint(TAINT_MACHINE_CHECK);
  36.495 +    mce_spin_unlock(&mce_logout_lock);
  36.496  
  36.497 -    if (bs.pcc) {
  36.498 -        printk(KERN_WARNING "PCC=1 should have caused reset\n");
  36.499 -        severity = 3;
  36.500 -    }
  36.501 -    else if (bs.uc) {
  36.502 -        severity = 2;
  36.503 -    }
  36.504 -    else {
  36.505 -        printk(KERN_WARNING "We should skip Correctable Error\n");
  36.506 -        severity = 1;
  36.507 -    }
  36.508 -    /* This is the offending cpu! */
  36.509 -    cpu_set(cpu, impact_map);
  36.510 +    /*
  36.511 +     * Wait until everybody has processed the trap.
  36.512 +     */
  36.513 +    mce_barrier(&mce_trap_bar);
  36.514  
  36.515 -    if ( severity > worst) {
  36.516 -        worst = severity;
  36.517 -        severity_cpu = cpu;
  36.518 +    /*
  36.519 +     * Clear MCIP if it wasn't already. There is a small
  36.520 +     * chance that more than 1 CPU will end up doing this,
  36.521 +     * but that's OK.
  36.522 +     */
  36.523 +    if (bs.errcnt) {
  36.524 +        mca_rdmsrl(MSR_IA32_MCG_STATUS, gstatus);
  36.525 +        if ((gstatus & MCG_STATUS_MCIP) != 0)
  36.526 +            mca_wrmsrl(MSR_IA32_MCG_STATUS, gstatus & ~MCG_STATUS_MCIP);
  36.527 +        /* Print MCE error */
  36.528 +        x86_mcinfo_dump(mctelem_dataptr(mctc));
  36.529      }
  36.530 -    cpu_set(cpu, mced_cpus);
  36.531 -    test_and_clear_bool(mce_enter_lock);
  36.532 -    wmb();
  36.533 -
  36.534 -    /* Wait for all cpus Leave Critical */
  36.535 -    while (cpus_weight(mced_cpus) < num_online_cpus())
  36.536 -        cpu_relax();
  36.537 -    /* Print MCE error */
  36.538 -    x86_mcinfo_dump(mctelem_dataptr(mctc));
  36.539  
  36.540 -    /* Pick one CPU to clear MCIP */
  36.541 -    if (!test_and_set_bool(mce_process_lock)) {
  36.542 -        mca_rdmsrl(MSR_IA32_MCG_STATUS, gstatus);
  36.543 -        mca_wrmsrl(MSR_IA32_MCG_STATUS, gstatus & ~MCG_STATUS_MCIP);
  36.544 -
  36.545 -        if (worst >= 3) {
  36.546 -            printk(KERN_WARNING "worst=3 should have caused RESET\n");
  36.547 -            mc_panic("worst=3 should have caused RESET");
  36.548 -        }
  36.549 -        else {
  36.550 -            printk(KERN_DEBUG "MCE: trying to recover\n");
  36.551 -        }
  36.552 -    }
  36.553      raise_softirq(MACHINE_CHECK_SOFTIRQ);
  36.554  }
  36.555  
  36.556 @@ -778,6 +762,11 @@ static void mce_init(void)
  36.557  
  36.558      clear_in_cr4(X86_CR4_MCE);
  36.559  
  36.560 +    mce_barrier_init(&mce_inside_bar);
  36.561 +    mce_barrier_init(&mce_severity_bar);
  36.562 +    mce_barrier_init(&mce_trap_bar);
  36.563 +    spin_lock_init(&mce_logout_lock);
  36.564 +
  36.565      /* log the machine checks left over from the previous reset.
  36.566       * This also clears all registers*/
  36.567  
  36.568 @@ -840,6 +829,7 @@ void intel_mce_init_msr(struct domain *d
  36.569      memset(d->arch.vmca_msrs.mci_ctl, ~0,
  36.570             sizeof(d->arch.vmca_msrs.mci_ctl));
  36.571      INIT_LIST_HEAD(&d->arch.vmca_msrs.impact_header);
  36.572 +    spin_lock_init(&d->arch.vmca_msrs.lock);
  36.573  }
  36.574  
  36.575  int intel_mce_wrmsr(u32 msr, u64 value)
  36.576 @@ -849,7 +839,7 @@ int intel_mce_wrmsr(u32 msr, u64 value)
  36.577      unsigned int bank;
  36.578      int ret = 1;
  36.579  
  36.580 -    spin_lock(&mce_locks);
  36.581 +    spin_lock(&d->arch.vmca_msrs.lock);
  36.582      switch(msr)
  36.583      {
  36.584      case MSR_IA32_MCG_CTL:
  36.585 @@ -924,7 +914,7 @@ int intel_mce_wrmsr(u32 msr, u64 value)
  36.586          ret = 0;
  36.587          break;
  36.588      }
  36.589 -    spin_unlock(&mce_locks);
  36.590 +    spin_unlock(&d->arch.vmca_msrs.lock);
  36.591      return ret;
  36.592  }
  36.593  
  36.594 @@ -936,7 +926,7 @@ int intel_mce_rdmsr(u32 msr, u32 *lo, u3
  36.595      struct bank_entry *entry = NULL;
  36.596  
  36.597      *lo = *hi = 0x0;
  36.598 -    spin_lock(&mce_locks);
  36.599 +    spin_lock(&d->arch.vmca_msrs.lock);
  36.600      switch(msr)
  36.601      {
  36.602      case MSR_IA32_MCG_STATUS:
  36.603 @@ -1022,7 +1012,7 @@ int intel_mce_rdmsr(u32 msr, u32 *lo, u3
  36.604          ret = 0;
  36.605          break;
  36.606      }
  36.607 -    spin_unlock(&mce_locks);
  36.608 +    spin_unlock(&d->arch.vmca_msrs.lock);
  36.609      return ret;
  36.610  }
  36.611  
    37.1 --- a/xen/arch/x86/cpu/mcheck/mctelem.c	Tue Apr 07 11:32:24 2009 +0900
    37.2 +++ b/xen/arch/x86/cpu/mcheck/mctelem.c	Tue Apr 14 14:04:58 2009 +0900
    37.3 @@ -109,6 +109,14 @@ static struct mc_telem_ctl {
    37.4  	 * Telemetry array
    37.5  	 */
    37.6  	struct mctelem_ent *mctc_elems;
    37.7 +	/*
    37.8 +	 * Per-CPU processing lists, used for deferred (softirq)
    37.9 +	 * processing of telemetry. mctc_cpu is indexed by the
   37.10 +	 * CPU that the telemetry belongs to. mctc_cpu_processing
   37.11 +	 * is indexed by the CPU that is processing the telemetry.
   37.12 +	 */
   37.13 +	struct mctelem_ent *mctc_cpu[NR_CPUS];
   37.14 +	struct mctelem_ent *mctc_cpu_processing[NR_CPUS];
   37.15  } mctctl;
   37.16  
   37.17  /* Lock protecting all processing lists */
   37.18 @@ -123,6 +131,82 @@ static void *cmpxchgptr(void *ptr, void 
   37.19  	return (void *)cmpxchg(ulp, a, b);
   37.20  }
   37.21  
   37.22 +static void mctelem_xchg_head(struct mctelem_ent **headp,
   37.23 +				struct mctelem_ent **old,
   37.24 +				struct mctelem_ent *new)
   37.25 +{
   37.26 +	for (;;) {
   37.27 +		*old = *headp;
   37.28 +		wmb();
   37.29 +		if (cmpxchgptr(headp, *old, new) == *old)
   37.30 +			break;
   37.31 +	}
   37.32 +}
   37.33 +
   37.34 +
   37.35 +void mctelem_defer(mctelem_cookie_t cookie)
   37.36 +{
   37.37 +	struct mctelem_ent *tep = COOKIE2MCTE(cookie);
   37.38 +
   37.39 +	mctelem_xchg_head(&mctctl.mctc_cpu[smp_processor_id()],
   37.40 +	    &tep->mcte_next, tep);
   37.41 +}
   37.42 +
   37.43 +void mctelem_process_deferred(unsigned int cpu,
   37.44 +			      int (*fn)(unsigned int, mctelem_cookie_t))
   37.45 +{
   37.46 +	struct mctelem_ent *tep;
   37.47 +	struct mctelem_ent *head, *prev;
   37.48 +	int ret;
   37.49 +
   37.50 +	/*
   37.51 +	 * First, unhook the list of telemetry structures, and	
   37.52 +	 * hook it up to the processing list head for this CPU.
   37.53 +	 */
   37.54 +	mctelem_xchg_head(&mctctl.mctc_cpu[cpu],
   37.55 +	    &mctctl.mctc_cpu_processing[smp_processor_id()], NULL);
   37.56 +
   37.57 +	head = mctctl.mctc_cpu_processing[smp_processor_id()];
   37.58 +
   37.59 +	/*
   37.60 +	 * Then, fix up the list to include prev pointers, to make
   37.61 +	 * things a little easier, as the list must be traversed in
   37.62 +	 * chronological order, which is backward from the order they
   37.63 +	 * are in.
   37.64 +	 */
   37.65 +	for (tep = head, prev = NULL; tep != NULL; tep = tep->mcte_next) {
   37.66 +		tep->mcte_prev = prev;
   37.67 +		prev = tep;
   37.68 +	}
   37.69 +
   37.70 +	/*
   37.71 +	 * Now walk the list of telemetry structures, handling each
   37.72 +	 * one of them. Unhooking the structure here does not need to
   37.73 +	 * be atomic, as this list is only accessed from a softirq
   37.74 +	 * context; the MCE handler does not touch it.
   37.75 +	 */
   37.76 +	for (tep = prev; tep != NULL; tep = prev) {
   37.77 +		prev = tep->mcte_prev;
   37.78 +		tep->mcte_next = tep->mcte_prev = NULL;
   37.79 +
   37.80 +		ret = fn(cpu, MCTE2COOKIE(tep));
   37.81 +		if (prev != NULL)
   37.82 +			prev->mcte_next = NULL;
   37.83 +		tep->mcte_prev = tep->mcte_next = NULL;
   37.84 +		if (ret != 0)
   37.85 +			mctelem_commit(MCTE2COOKIE(tep));
   37.86 +		else
   37.87 +			mctelem_dismiss(MCTE2COOKIE(tep));
   37.88 +	}
   37.89 +}
   37.90 +
   37.91 +int mctelem_has_deferred(unsigned int cpu)
   37.92 +{
   37.93 +	if (mctctl.mctc_cpu[cpu] != NULL)
   37.94 +		return 1;
   37.95 +	return 0;
   37.96 +}
   37.97 +
   37.98  /* Free an entry to its native free list; the entry must not be linked on
   37.99   * any list.
  37.100   */
  37.101 @@ -130,21 +214,12 @@ static void mctelem_free(struct mctelem_
  37.102  {
  37.103  	mctelem_class_t target = MCTE_HOME(tep) == MCTE_F_HOME_URGENT ?
  37.104  	    MC_URGENT : MC_NONURGENT;
  37.105 -	struct mctelem_ent **freelp;
  37.106 -	struct mctelem_ent *oldhead;
  37.107  
  37.108  	BUG_ON(tep->mcte_refcnt != 0);
  37.109  	BUG_ON(MCTE_STATE(tep) != MCTE_F_STATE_FREE);
  37.110  
  37.111  	tep->mcte_prev = NULL;
  37.112 -	freelp = &mctctl.mctc_free[target];
  37.113 -	for (;;) {
  37.114 -		oldhead = *freelp;
  37.115 -		tep->mcte_next = oldhead;
  37.116 -		wmb();
  37.117 -		if (cmpxchgptr(freelp, oldhead, tep) == oldhead)
  37.118 -			break;
  37.119 -	}
  37.120 +	mctelem_xchg_head(&mctctl.mctc_free[target], &tep->mcte_next, tep);
  37.121  }
  37.122  
  37.123  /* Increment the reference count of an entry that is not linked on to
  37.124 @@ -308,22 +383,13 @@ void mctelem_dismiss(mctelem_cookie_t co
  37.125  void mctelem_commit(mctelem_cookie_t cookie)
  37.126  {
  37.127  	struct mctelem_ent *tep = COOKIE2MCTE(cookie);
  37.128 -	struct mctelem_ent **commlp;
  37.129 -	struct mctelem_ent *oldhead;
  37.130  	mctelem_class_t target = MCTE_CLASS(tep) == MCTE_F_CLASS_URGENT ?
  37.131  	    MC_URGENT : MC_NONURGENT;
  37.132  
  37.133  	BUG_ON(tep->mcte_next != NULL || tep->mcte_prev != NULL);
  37.134  	MCTE_TRANSITION_STATE(tep, UNCOMMITTED, COMMITTED);
  37.135  
  37.136 -	commlp = &mctctl.mctc_committed[target];
  37.137 -	for (;;) {
  37.138 -		oldhead = *commlp;
  37.139 -		tep->mcte_prev = oldhead;
  37.140 -		wmb();
  37.141 -		if (cmpxchgptr(commlp, oldhead, tep) == oldhead)
  37.142 -			break;
  37.143 -	}
  37.144 +	mctelem_xchg_head(&mctctl.mctc_committed[target], &tep->mcte_prev, tep);
  37.145  }
  37.146  
  37.147  /* Move telemetry from committed list to processing list, reversing the
  37.148 @@ -358,13 +424,7 @@ static void mctelem_append_processing(mc
  37.149  	 * the list we unlink in a well-known location so it can be
  37.150  	 * picked up in panic code should we panic between this unlink
  37.151  	 * and the append to the processing list. */
  37.152 -	for (;;) {
  37.153 -		dangling[target] = *commlp;
  37.154 -		wmb();
  37.155 -		if (cmpxchgptr(commlp, dangling[target], NULL) ==
  37.156 -		    dangling[target])
  37.157 -			break;
  37.158 -	}
  37.159 +	mctelem_xchg_head(commlp, &dangling[target], NULL);
  37.160  
  37.161  	if (dangling[target] == NULL)
  37.162  		return;
    38.1 --- a/xen/arch/x86/cpu/mcheck/mctelem.h	Tue Apr 07 11:32:24 2009 +0900
    38.2 +++ b/xen/arch/x86/cpu/mcheck/mctelem.h	Tue Apr 14 14:04:58 2009 +0900
    38.3 @@ -67,5 +67,9 @@ extern void mctelem_dismiss(mctelem_cook
    38.4  extern mctelem_cookie_t mctelem_consume_oldest_begin(mctelem_class_t);
    38.5  extern void mctelem_consume_oldest_end(mctelem_cookie_t);
    38.6  extern void mctelem_ack(mctelem_class_t, mctelem_cookie_t);
    38.7 +extern void mctelem_defer(mctelem_cookie_t);
    38.8 +extern void mctelem_process_deferred(unsigned int,
    38.9 +    int (*)(unsigned int, mctelem_cookie_t));
   38.10 +int mctelem_has_deferred(unsigned int);
   38.11  
   38.12  #endif
    39.1 --- a/xen/arch/x86/hvm/emulate.c	Tue Apr 07 11:32:24 2009 +0900
    39.2 +++ b/xen/arch/x86/hvm/emulate.c	Tue Apr 14 14:04:58 2009 +0900
    39.3 @@ -18,6 +18,7 @@
    39.4  #include <asm/event.h>
    39.5  #include <asm/hvm/emulate.h>
    39.6  #include <asm/hvm/hvm.h>
    39.7 +#include <asm/hvm/trace.h>
    39.8  #include <asm/hvm/support.h>
    39.9  
   39.10  #define HVMTRACE_IO_ASSIST_WRITE 0x200
   39.11 @@ -749,6 +750,7 @@ static int hvmemul_read_cr(
   39.12      case 3:
   39.13      case 4:
   39.14          *val = current->arch.hvm_vcpu.guest_cr[reg];
   39.15 +        HVMTRACE_LONG_2D(CR_READ, reg, TRC_PAR_LONG(*val));
   39.16          return X86EMUL_OKAY;
   39.17      default:
   39.18          break;
   39.19 @@ -762,6 +764,7 @@ static int hvmemul_write_cr(
   39.20      unsigned long val,
   39.21      struct x86_emulate_ctxt *ctxt)
   39.22  {
   39.23 +    HVMTRACE_LONG_2D(CR_WRITE, reg, TRC_PAR_LONG(val));
   39.24      switch ( reg )
   39.25      {
   39.26      case 0:
    40.1 --- a/xen/arch/x86/hvm/hvm.c	Tue Apr 07 11:32:24 2009 +0900
    40.2 +++ b/xen/arch/x86/hvm/hvm.c	Tue Apr 14 14:04:58 2009 +0900
    40.3 @@ -2377,6 +2377,9 @@ static int hvmop_flush_tlb_all(void)
    40.4      struct domain *d = current->domain;
    40.5      struct vcpu *v;
    40.6  
    40.7 +    if ( !is_hvm_domain(d) )
    40.8 +        return -EINVAL;
    40.9 +
   40.10      /* Avoid deadlock if more than one vcpu tries this at the same time. */
   40.11      if ( !spin_trylock(&d->hypercall_deadlock_mutex) )
   40.12          return -EAGAIN;
   40.13 @@ -2413,6 +2416,7 @@ static int hvmop_flush_tlb_all(void)
   40.14  long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
   40.15  
   40.16  {
   40.17 +    struct domain *curr_d = current->domain;
   40.18      long rc = 0;
   40.19  
   40.20      switch ( op )
   40.21 @@ -2477,8 +2481,9 @@ long do_hvm_op(unsigned long op, XEN_GUE
   40.22                      rc = -EINVAL;
   40.23                  break;
   40.24              case HVM_PARAM_IDENT_PT:
   40.25 +                /* Not reflexive, as we must domain_pause(). */
   40.26                  rc = -EPERM;
   40.27 -                if ( !IS_PRIV(current->domain) )
   40.28 +                if ( curr_d == d )
   40.29                      break;
   40.30  
   40.31                  rc = -EINVAL;
   40.32 @@ -2489,29 +2494,32 @@ long do_hvm_op(unsigned long op, XEN_GUE
   40.33                  if ( !paging_mode_hap(d) )
   40.34                      break;
   40.35  
   40.36 -                domain_pause(d);
   40.37 -
   40.38                  /*
   40.39                   * Update GUEST_CR3 in each VMCS to point at identity map.
   40.40                   * All foreign updates to guest state must synchronise on
   40.41                   * the domctl_lock.
   40.42                   */
   40.43 -                spin_lock(&domctl_lock);
   40.44 +                rc = -EAGAIN;
   40.45 +                if ( !domctl_lock_acquire() )
   40.46 +                    break;
   40.47 +
   40.48 +                rc = 0;
   40.49 +                domain_pause(d);
   40.50                  d->arch.hvm_domain.params[a.index] = a.value;
   40.51                  for_each_vcpu ( d, v )
   40.52                      paging_update_cr3(v);
   40.53 -                spin_unlock(&domctl_lock);
   40.54 -
   40.55                  domain_unpause(d);
   40.56 +
   40.57 +                domctl_lock_release();
   40.58                  break;
   40.59              case HVM_PARAM_DM_DOMAIN:
   40.60 -                /* Privileged domains only, as we must domain_pause(d). */
   40.61 +                /* Not reflexive, as we must domain_pause(). */
   40.62                  rc = -EPERM;
   40.63 -                if ( !IS_PRIV_FOR(current->domain, d) )
   40.64 +                if ( curr_d == d )
   40.65                      break;
   40.66  
   40.67                  if ( a.value == DOMID_SELF )
   40.68 -                    a.value = current->domain->domain_id;
   40.69 +                    a.value = curr_d->domain_id;
   40.70  
   40.71                  rc = 0;
   40.72                  domain_pause(d); /* safe to change per-vcpu xen_port */
   40.73 @@ -2536,9 +2544,9 @@ long do_hvm_op(unsigned long op, XEN_GUE
   40.74                  domain_unpause(d);
   40.75                  break;
   40.76              case HVM_PARAM_ACPI_S_STATE:
   40.77 -                /* Privileged domains only, as we must domain_pause(d). */
   40.78 +                /* Not reflexive, as we must domain_pause(). */
   40.79                  rc = -EPERM;
   40.80 -                if ( !IS_PRIV_FOR(current->domain, d) )
   40.81 +                if ( curr_d == d )
   40.82                      break;
   40.83  
   40.84                  rc = 0;
    41.1 --- a/xen/arch/x86/hvm/svm/svm.c	Tue Apr 07 11:32:24 2009 +0900
    41.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Tue Apr 14 14:04:58 2009 +0900
    41.3 @@ -1217,9 +1217,14 @@ asmlinkage void svm_vmexit_handler(struc
    41.4  
    41.5      exit_reason = vmcb->exitcode;
    41.6  
    41.7 -    HVMTRACE_ND(VMEXIT64, 1/*cycles*/, 3, exit_reason,
    41.8 -                (uint32_t)regs->eip, (uint32_t)((uint64_t)regs->eip >> 32),
    41.9 -                0, 0, 0);
   41.10 +    if ( hvm_long_mode_enabled(v) )
   41.11 +        HVMTRACE_ND(VMEXIT64, 1/*cycles*/, 3, exit_reason,
   41.12 +                    (uint32_t)regs->eip, (uint32_t)((uint64_t)regs->eip >> 32),
   41.13 +                    0, 0, 0);
   41.14 +    else
   41.15 +        HVMTRACE_ND(VMEXIT, 1/*cycles*/, 2, exit_reason,
   41.16 +                    (uint32_t)regs->eip, 
   41.17 +                    0, 0, 0, 0);
   41.18  
   41.19      if ( unlikely(exit_reason == VMEXIT_INVALID) )
   41.20      {
    42.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Tue Apr 07 11:32:24 2009 +0900
    42.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Tue Apr 14 14:04:58 2009 +0900
    42.3 @@ -2241,9 +2241,14 @@ asmlinkage void vmx_vmexit_handler(struc
    42.4  
    42.5      exit_reason = __vmread(VM_EXIT_REASON);
    42.6  
    42.7 -    HVMTRACE_ND(VMEXIT64, 1/*cycles*/, 3, exit_reason,
    42.8 -                (uint32_t)regs->eip, (uint32_t)((uint64_t)regs->eip >> 32),
    42.9 -                0, 0, 0);
   42.10 +    if ( hvm_long_mode_enabled(v) )
   42.11 +        HVMTRACE_ND(VMEXIT64, 1/*cycles*/, 3, exit_reason,
   42.12 +                    (uint32_t)regs->eip, (uint32_t)((uint64_t)regs->eip >> 32),
   42.13 +                    0, 0, 0);
   42.14 +    else
   42.15 +        HVMTRACE_ND(VMEXIT, 1/*cycles*/, 2, exit_reason,
   42.16 +                    (uint32_t)regs->eip, 
   42.17 +                    0, 0, 0, 0);
   42.18  
   42.19      perfc_incra(vmexits, exit_reason);
   42.20  
    43.1 --- a/xen/common/domctl.c	Tue Apr 07 11:32:24 2009 +0900
    43.2 +++ b/xen/common/domctl.c	Tue Apr 14 14:04:58 2009 +0900
    43.3 @@ -25,7 +25,7 @@
    43.4  #include <public/domctl.h>
    43.5  #include <xsm/xsm.h>
    43.6  
    43.7 -DEFINE_SPINLOCK(domctl_lock);
    43.8 +static DEFINE_SPINLOCK(domctl_lock);
    43.9  
   43.10  extern long arch_do_domctl(
   43.11      struct xen_domctl *op, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl);
   43.12 @@ -188,6 +188,33 @@ static unsigned int default_vcpu0_locati
   43.13      return cpu;
   43.14  }
   43.15  
   43.16 +bool_t domctl_lock_acquire(void)
   43.17 +{
   43.18 +    /*
   43.19 +     * Caller may try to pause its own VCPUs. We must prevent deadlock
   43.20 +     * against other non-domctl routines which try to do the same.
   43.21 +     */
   43.22 +    if ( !spin_trylock(&current->domain->hypercall_deadlock_mutex) )
   43.23 +        return 0;
   43.24 +
   43.25 +    /*
   43.26 +     * Trylock here is paranoia if we have multiple privileged domains. Then
   43.27 +     * we could have one domain trying to pause another which is spinning
   43.28 +     * on domctl_lock -- results in deadlock.
   43.29 +     */
   43.30 +    if ( spin_trylock(&domctl_lock) )
   43.31 +        return 1;
   43.32 +
   43.33 +    spin_unlock(&current->domain->hypercall_deadlock_mutex);
   43.34 +    return 0;
   43.35 +}
   43.36 +
   43.37 +void domctl_lock_release(void)
   43.38 +{
   43.39 +    spin_unlock(&domctl_lock);
   43.40 +    spin_unlock(&current->domain->hypercall_deadlock_mutex);
   43.41 +}
   43.42 +
   43.43  long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
   43.44  {
   43.45      long ret = 0;
   43.46 @@ -202,7 +229,9 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   43.47      if ( op->interface_version != XEN_DOMCTL_INTERFACE_VERSION )
   43.48          return -EACCES;
   43.49  
   43.50 -    spin_lock(&domctl_lock);
   43.51 +    if ( !domctl_lock_acquire() )
   43.52 +        return hypercall_create_continuation(
   43.53 +            __HYPERVISOR_domctl, "h", u_domctl);
   43.54  
   43.55      switch ( op->cmd )
   43.56      {
   43.57 @@ -866,7 +895,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   43.58          break;
   43.59      }
   43.60  
   43.61 -    spin_unlock(&domctl_lock);
   43.62 +    domctl_lock_release();
   43.63  
   43.64      return ret;
   43.65  }
    44.1 --- a/xen/drivers/cpufreq/cpufreq_ondemand.c	Tue Apr 07 11:32:24 2009 +0900
    44.2 +++ b/xen/drivers/cpufreq/cpufreq_ondemand.c	Tue Apr 14 14:04:58 2009 +0900
    44.3 @@ -178,7 +178,8 @@ static void do_dbs_timer(void *dbs)
    44.4  
    44.5      dbs_check_cpu(dbs_info);
    44.6  
    44.7 -    set_timer(&dbs_timer[dbs_info->cpu], NOW()+dbs_tuners_ins.sampling_rate);
    44.8 +    set_timer(&dbs_timer[dbs_info->cpu],
    44.9 +            align_timer(NOW() , dbs_tuners_ins.sampling_rate));
   44.10  }
   44.11  
   44.12  static void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
    45.1 --- a/xen/include/asm-x86/domain.h	Tue Apr 07 11:32:24 2009 +0900
    45.2 +++ b/xen/include/asm-x86/domain.h	Tue Apr 14 14:04:58 2009 +0900
    45.3 @@ -226,6 +226,7 @@ struct domain_mca_msrs
    45.4      uint64_t mci_ctl[MAX_NR_BANKS];
    45.5      uint16_t nr_injection;
    45.6      struct list_head impact_header;
    45.7 +    spinlock_t lock;
    45.8  };
    45.9  
   45.10  struct arch_domain
    46.1 --- a/xen/include/xen/domain.h	Tue Apr 07 11:32:24 2009 +0900
    46.2 +++ b/xen/include/xen/domain.h	Tue Apr 14 14:04:58 2009 +0900
    46.3 @@ -58,6 +58,9 @@ void arch_dump_domain_info(struct domain
    46.4  
    46.5  void arch_vcpu_reset(struct vcpu *v);
    46.6  
    46.7 +bool_t domctl_lock_acquire(void);
    46.8 +void domctl_lock_release(void);
    46.9 +
   46.10  extern unsigned int xen_processor_pmbits;
   46.11  
   46.12  #endif /* __XEN_DOMAIN_H__ */
    47.1 --- a/xen/include/xen/hypercall.h	Tue Apr 07 11:32:24 2009 +0900
    47.2 +++ b/xen/include/xen/hypercall.h	Tue Apr 14 14:04:58 2009 +0900
    47.3 @@ -30,7 +30,6 @@ do_sched_op(
    47.4      int cmd,
    47.5      XEN_GUEST_HANDLE(void) arg);
    47.6  
    47.7 -extern spinlock_t domctl_lock;
    47.8  extern long
    47.9  do_domctl(
   47.10      XEN_GUEST_HANDLE(xen_domctl_t) u_domctl);