[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
# HG changeset patch # User Isaku Yamahata <yamahata@xxxxxxxxxxxxx> # Date 1239685498 -32400 # Node ID 8c806c66a597d62f3a4497c2736e069fdcff37aa # Parent 19919f01f2c56262bb28f4ec8edaf99a75c70f84 # Parent 120d3c67951bac0f4c31b0b828500ee6ac23b0b4 merge with xen-unstable.hg --- .hgtags | 1 Config.mk | 4 Makefile | 6 tools/hotplug/Linux/network-nat | 6 tools/libxc/xc_domain_restore.c | 2 tools/misc/sbdf2devicepath | 82 ++++ tools/misc/sxp-pretty | 8 tools/misc/xen-bugtool | 3 tools/misc/xen-python-path | 31 - tools/misc/xend | 8 tools/misc/xm | 3 tools/misc/xsview | 2 tools/pygrub/Makefile | 10 tools/pygrub/src/pygrub | 2 tools/python/Makefile | 9 tools/python/scripts/test_hvm_create.py | 1 tools/python/scripts/test_vm_create.py | 1 tools/python/scripts/xapi.py | 1 tools/python/xen/util/auxbin.py | 6 tools/python/xen/xend/XendConfig.py | 6 tools/python/xen/xend/XendDomainInfo.py | 206 ++++++---- tools/python/xen/xend/server/pciif.py | 22 - tools/python/xen/xm/create.dtd | 2 tools/python/xen/xm/main.py | 26 - tools/python/xen/xm/xenapi_create.py | 4 tools/security/Makefile | 10 tools/security/python/xensec_tools/acm_getlabel | 4 tools/security/xensec_gen.py | 4 tools/sv/index.psp | 1 tools/vnet/scripts/vn | 3 tools/xenpmd/Makefile | 3 xen/Makefile | 2 xen/arch/x86/acpi/cpu_idle.c | 4 xen/arch/x86/cpu/mcheck/mce.c | 61 +- xen/arch/x86/cpu/mcheck/mce.h | 5 xen/arch/x86/cpu/mcheck/mce_intel.c | 490 +++++++++++------------- xen/arch/x86/cpu/mcheck/mctelem.c | 114 ++++- xen/arch/x86/cpu/mcheck/mctelem.h | 4 xen/arch/x86/hvm/emulate.c | 3 xen/arch/x86/hvm/hvm.c | 30 - xen/arch/x86/hvm/svm/svm.c | 11 xen/arch/x86/hvm/vmx/vmx.c | 11 xen/common/domctl.c | 35 + xen/drivers/cpufreq/cpufreq_ondemand.c | 3 xen/include/asm-x86/domain.h | 1 xen/include/xen/domain.h | 3 xen/include/xen/hypercall.h | 1 47 files changed, 722 insertions(+), 533 deletions(-) diff -r 19919f01f2c5 -r 8c806c66a597 .hgtags --- a/.hgtags Tue Apr 07 11:32:24 2009 +0900 +++ b/.hgtags Tue Apr 14 14:04:58 2009 +0900 @@ -33,3 +33,4 @@ bc372510f1794ee41a8b0501cc84f8a65d05e094 bc372510f1794ee41a8b0501cc84f8a65d05e094 3.3.0-rc6 daf1193bcd11345d566a4747fe1f12c90b44452c 3.3.0-rc7 1e99ba54035623731bc7318a8357aa6a118c5da1 3.3.0-branched +d611d9ac6d0271b53eb1d4e5d0c4ef20b269eea8 3.4.0-rc1 diff -r 19919f01f2c5 -r 8c806c66a597 Config.mk --- a/Config.mk Tue Apr 07 11:32:24 2009 +0900 +++ b/Config.mk Tue Apr 14 14:04:58 2009 +0900 @@ -1,7 +1,7 @@ # -*- mode: Makefile; -*- -# A debug build of Xen and tools? TEMPORARILY ENABLED -debug ?= y +# A debug build of Xen and tools? +debug ?= n XEN_COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/ \ -e s/i86pc/x86_32/ -e s/amd64/x86_64/) diff -r 19919f01f2c5 -r 8c806c66a597 Makefile --- a/Makefile Tue Apr 07 11:32:24 2009 +0900 +++ b/Makefile Tue Apr 14 14:04:58 2009 +0900 @@ -188,11 +188,7 @@ help: @echo ' clean-tboot - clean the tboot module if it exists' @echo @echo 'Environment:' - @echo ' XEN_PYTHON_NATIVE_INSTALL=y' - @echo ' - native python install or dist' - @echo ' install into prefix/lib/python<VERSION>' - @echo ' instead of <PREFIX>/lib/python' - @echo ' true if set to non-empty value, false otherwise' + @echo ' [ this documentation is sadly not complete ]' # Use this target with extreme care! .PHONY: uninstall diff -r 19919f01f2c5 -r 8c806c66a597 tools/hotplug/Linux/network-nat --- a/tools/hotplug/Linux/network-nat Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/hotplug/Linux/network-nat Tue Apr 14 14:04:58 2009 +0900 @@ -48,12 +48,16 @@ then fi fi +domain_name=`cat /etc/resolv.conf | grep -v "#" | grep -E 'search|domain' -i | tail -n 1 | awk '{ print $2 }'` +nameserver=`cat /etc/resolv.conf | grep -v "#" | grep "nameserver" -i -m 1 | awk '{ print $2 }'` function dhcp_start() { if ! grep -q "subnet 10.0.0.0" "$dhcpd_conf_file" then - echo >>"$dhcpd_conf_file" "subnet 10.0.0.0 netmask 255.255.0.0 {}" + echo >>"$dhcpd_conf_file" "subnet 10.0.0.0 netmask 255.255.0.0 {\ + option domain-name \"$domain_name\";\ + option domain-name-servers $nameserver; }" fi "$dhcpd_init_file" restart diff -r 19919f01f2c5 -r 8c806c66a597 tools/libxc/xc_domain_restore.c --- a/tools/libxc/xc_domain_restore.c Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/libxc/xc_domain_restore.c Tue Apr 14 14:04:58 2009 +0900 @@ -1197,7 +1197,7 @@ int xc_domain_restore(int xc_handle, int * we need to adjust the live_p2m assignment appropriately */ if ( guest_width > sizeof (xen_pfn_t) ) for ( i = p2m_size - 1; i >= 0; i-- ) - ((uint64_t *)live_p2m)[i] = p2m[i]; + ((int64_t *)live_p2m)[i] = (long)p2m[i]; else if ( guest_width < sizeof (xen_pfn_t) ) for ( i = 0; i < p2m_size; i++ ) ((uint32_t *)live_p2m)[i] = p2m[i]; diff -r 19919f01f2c5 -r 8c806c66a597 tools/misc/sbdf2devicepath --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/misc/sbdf2devicepath Tue Apr 14 14:04:58 2009 +0900 @@ -0,0 +1,82 @@ +#!/usr/bin/env python +# -*- mode: python; -*- +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (c) 2009, NEC Corporation. +#============================================================================ +# This script converts SBDF into device path. +# 'SBDF' format is "[SEG#:]BUS#:DEV#.FUNC#" +# ex) 0000:0a:1f.3 +# Device path format is "HID[:UID]-DEV#.FUNC#[-DEV#.FUNC#[...]]" +# ex) PNP0A08:0-2.0-0.0 +#============================================================================= + +import sys +import os + +# add fallback path for non-native python path installs if needed +sys.path.append('/usr/lib/python') +sys.path.append('/usr/lib64/python') +from xen.util.pci import * + +SYSFS_ACPI_DEVS_PATH = '/firmware/acpi/namespace/ACPI/_SB' + +def find_hid_uid(dom, b, d, f): + obj_list = os.listdir(sb_path) + for obj in obj_list: + obj_path = sb_path + '/' + obj.strip() + '/' + if os.path.exists(obj_path + 'seg') and \ + os.path.exists(obj_path + 'bbn'): + seg = open(obj_path + 'seg').read() + bbn = open(obj_path + 'bbn').read() + if int(seg) == dom and int(bbn) == b: + hid = open(obj_path + 'hid').read() + if os.path.exists(obj_path + 'uid') is False: + path_str = hid.strip() + else: + uid = open(obj_path + 'uid').read() + path_str = hid.strip() + ':' + uid.strip() + return path_str + return None + +def make_device_path(dom, b, d, f): + dev = PciDevice(dom, b, d, f) + parent = dev.find_parent() + if parent is None: + path_str = find_hid_uid(dom, b, d, f) + path_str = path_str + '-' + hex(d).replace('0x', '') + '.' + \ + hex(f).replace('0x', '') + return path_str + (pdom, pb, pd, pf) = parent + path_str = make_device_path(pdom, pb, pd, pf) + path_str = path_str + '-' + hex(d).replace('0x', '') + '.' + \ + hex(f).replace('0x', '') + return path_str + +# main +if len(sys.argv) <> 2: + print 'Usage: sbdf2devicepath SBDF\n' +else: + sb_path = find_sysfs_mnt() + SYSFS_ACPI_DEVS_PATH + if os.path.exists(sb_path): + path = os.environ['PATH'] + os.environ['PATH'] = path + ':/sbin' + ':/user/sbin' + sbdf = sys.argv[1] + (dom, b, d, f) = parse_pci_name(sbdf) + path_str = make_device_path(dom, b, d, f) + print path_str + else: + print sb_path + ' not found.\n' + print 'This command is only for linux 2.6.18.8 xen kernel.\n' diff -r 19919f01f2c5 -r 8c806c66a597 tools/misc/sxp-pretty --- a/tools/misc/sxp-pretty Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/misc/sxp-pretty Tue Apr 14 14:04:58 2009 +0900 @@ -23,14 +23,6 @@ import pprint import pprint import sys -result = commands.getstatusoutput(os.path.join(os.path.dirname(sys.argv[0]), - 'xen-python-path')) -if result[0] != 0: - print >>sys.stderr, result[1] - sys.exit(1) - -sys.path.append(result[1]) - import xen.xend.sxp as sxp def main(): diff -r 19919f01f2c5 -r 8c806c66a597 tools/misc/xen-bugtool --- a/tools/misc/xen-bugtool Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/misc/xen-bugtool Tue Apr 14 14:04:58 2009 +0900 @@ -6,9 +6,6 @@ import sys -sys.path.append('/usr/lib/python') -sys.path.append('/usr/lib64/python') - from xen.util import bugtool diff -r 19919f01f2c5 -r 8c806c66a597 tools/misc/xen-python-path --- a/tools/misc/xen-python-path Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/misc/xen-python-path Tue Apr 14 14:04:58 2009 +0900 @@ -17,31 +17,8 @@ # Copyright (C) 2007 XenSource Inc. #============================================================================ +# Nowadays we install xen in the standard python site-packages +# directories. This script is still provided for the benefit of old +# out-of-xen-tree callers. It is deprecated and will be removed. -# Use the auxbin module in Xend to determine the correct Python path. We -# take the first installed instance of auxbin that we find, and then run it -# to determine the correct path, appending that to sys.path. - -AUXBIN = 'xen/util/auxbin.py' - -import os -import os.path -import sys - -usr = os.path.dirname(os.path.dirname(sys.argv[0])) -list = [ os.path.join(usr,'lib64') ] -list += [ os.path.join(usr,'lib') ] -list += ['/usr/lib64', '/usr/lib'] - -for l in list: - for p in ['python%s' % sys.version[:3], 'python']: - for k in ['', 'site-packages/']: - d = os.path.join(l, p, k) - if os.path.exists(os.path.join(d, AUXBIN)): - sys.path.append(d) - import xen.util.auxbin - print os.path.join(xen.util.auxbin.libpath(), p) - sys.exit(0) - -print >>sys.stderr, "Cannot find Xen Python modules." -sys.exit(1) +print '/dev/enoent/xen/python-path' diff -r 19919f01f2c5 -r 8c806c66a597 tools/misc/xend --- a/tools/misc/xend Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/misc/xend Tue Apr 14 14:04:58 2009 +0900 @@ -32,14 +32,6 @@ import signal import signal import time import commands - -xpp = os.path.join(os.path.dirname(sys.argv[0]), 'xen-python-path') -if os.path.exists(xpp): - result = commands.getstatusoutput(xpp) - if result[0] != 0: - print >>sys.stderr, result[1] - sys.exit(1) - sys.path.append(result[1]) from xen.xend.server import SrvDaemon diff -r 19919f01f2c5 -r 8c806c66a597 tools/misc/xm --- a/tools/misc/xm Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/misc/xm Tue Apr 14 14:04:58 2009 +0900 @@ -2,9 +2,6 @@ # -*- mode: python; -*- import sys -# add fallback path for non-native python path installs if needed -sys.path.append('/usr/lib/python') -sys.path.append('/usr/lib64/python') from xen.xm import main main.main(sys.argv) diff -r 19919f01f2c5 -r 8c806c66a597 tools/misc/xsview --- a/tools/misc/xsview Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/misc/xsview Tue Apr 14 14:04:58 2009 +0900 @@ -2,8 +2,6 @@ import sys -sys.path.append('/usr/lib/python') -sys.path.append('/usr/lib64/python') from xen.xsview import main main.main(sys.argv) diff -r 19919f01f2c5 -r 8c806c66a597 tools/pygrub/Makefile --- a/tools/pygrub/Makefile Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/pygrub/Makefile Tue Apr 14 14:04:58 2009 +0900 @@ -9,16 +9,10 @@ build: CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py build .PHONY: install -ifndef XEN_PYTHON_NATIVE_INSTALL -install: LIBPATH=$(shell PYTHONPATH=../python/xen/util python -c "import auxbin; print auxbin.libpath()") install: all - CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --home="$(DESTDIR)$(PREFIX)" --prefix="" --install-lib="$(DESTDIR)$(LIBDIR)/python" + CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install \ + --prefix="$(PREFIX)" --root="$(DESTDIR)" --force $(INSTALL_DIR) $(DESTDIR)/var/run/xend/boot -else -install: all - CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)" - $(INSTALL_DIR) $(DESTDIR)/var/run/xend/boot -endif .PHONY: clean clean: diff -r 19919f01f2c5 -r 8c806c66a597 tools/pygrub/src/pygrub --- a/tools/pygrub/src/pygrub Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/pygrub/src/pygrub Tue Apr 14 14:04:58 2009 +0900 @@ -20,8 +20,6 @@ import platform import curses, _curses, curses.wrapper, curses.textpad, curses.ascii import getopt - -sys.path = [ '/usr/lib/python', '/usr/lib64/python' ] + sys.path import fsimage import grub.GrubConf diff -r 19919f01f2c5 -r 8c806c66a597 tools/python/Makefile --- a/tools/python/Makefile Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/python/Makefile Tue Apr 14 14:04:58 2009 +0900 @@ -54,14 +54,9 @@ refresh-po: $(POTFILE) $(MSGFMT) -c -o $@ $< .PHONY: install -ifndef XEN_PYTHON_NATIVE_INSTALL -install: LIBPATH=$(shell PYTHONPATH=xen/util python -c "import auxbin; print auxbin.libpath()") install: install-messages install-dtd - CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --home="$(DESTDIR)$(PREFIX)" --prefix="" --force --install-lib="$(DESTDIR)$(LIBDIR)/python" -else -install: install-messages install-dtd - CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)" --force -endif + CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install \ + --prefix="$(PREFIX)" --root="$(DESTDIR)" --force install-dtd: all $(INSTALL_DIR) $(DESTDIR)$(DOCDIR) diff -r 19919f01f2c5 -r 8c806c66a597 tools/python/scripts/test_hvm_create.py --- a/tools/python/scripts/test_hvm_create.py Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/python/scripts/test_hvm_create.py Tue Apr 14 14:04:58 2009 +0900 @@ -74,7 +74,6 @@ console_cfg = { import sys import time -sys.path.append('/usr/lib/python') from xapi import connect, execute diff -r 19919f01f2c5 -r 8c806c66a597 tools/python/scripts/test_vm_create.py --- a/tools/python/scripts/test_vm_create.py Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/python/scripts/test_vm_create.py Tue Apr 14 14:04:58 2009 +0900 @@ -93,7 +93,6 @@ console_cfg = { import sys import time -sys.path.append('/usr/lib/python') from xapi import connect, execute diff -r 19919f01f2c5 -r 8c806c66a597 tools/python/scripts/xapi.py --- a/tools/python/scripts/xapi.py Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/python/scripts/xapi.py Tue Apr 14 14:04:58 2009 +0900 @@ -20,7 +20,6 @@ import time import time import re import os -sys.path.append('/usr/lib/python') from xen.util.xmlrpclib2 import ServerProxy from optparse import * diff -r 19919f01f2c5 -r 8c806c66a597 tools/python/xen/util/auxbin.py --- a/tools/python/xen/util/auxbin.py Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/python/xen/util/auxbin.py Tue Apr 14 14:04:58 2009 +0900 @@ -35,7 +35,11 @@ def execute(exe, args = None): a = [ exepath ] if args: a.extend(args) - os.execv(exepath, a) + try: + os.execv(exepath, a) + except OSError, exn: + print exepath, ": ", exn + sys.exit(1) def pathTo(exe): diff -r 19919f01f2c5 -r 8c806c66a597 tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/python/xen/xend/XendConfig.py Tue Apr 14 14:04:58 2009 +0900 @@ -1617,10 +1617,10 @@ class XendConfig(dict): # extendend like this: # # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1], [func, 2], - # [vslt, 0]], + # [vslot, 0]], # [state, 'Initialising']]] # - # 'vslt' shows the virtual hotplug slot number which the PCI device + # 'vslot' shows the virtual hotplug slot number which the PCI device # is inserted in. This is only effective for HVM domains. # # state 'Initialising' indicates that the device is being attached, @@ -1628,7 +1628,7 @@ class XendConfig(dict): # # The Dict looks like this: # - # { devs: [{domain: 0, bus: 0, slot: 1, func: 2, vslt: 0}], + # { devs: [{domain: 0, bus: 0, slot: 1, func: 2, vslot: 0}], # states: ['Initialising'] } dev_config = {} diff -r 19919f01f2c5 -r 8c806c66a597 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/python/xen/xend/XendDomainInfo.py Tue Apr 14 14:04:58 2009 +0900 @@ -596,7 +596,7 @@ class XendDomainInfo: #update the vslot info count = 0; for x in pci_devs: - x['vslt'] = slot_list[count] + x['vslot'] = slot_list[count] count += 1 @@ -619,9 +619,9 @@ class XendDomainInfo: pci_conf = self.info['devices'][dev_uuid][1] pci_devs = pci_conf['devs'] for x in pci_devs: - if (int(x['vslt'], 16) == int(new_dev['vslt'], 16) and - int(x['vslt'], 16) != AUTO_PHP_SLOT): - raise VmError("vslot %s already have a device." % (new_dev['vslt'])) + if (int(x['vslot'], 16) == int(new_dev['vslot'], 16) and + int(x['vslot'], 16) != AUTO_PHP_SLOT): + raise VmError("vslot %s already have a device." % (new_dev['vslot'])) if (int(x['domain'], 16) == int(new_dev['domain'], 16) and int(x['bus'], 16) == int(new_dev['bus'], 16) and @@ -634,7 +634,7 @@ class XendDomainInfo: new_dev['bus'], new_dev['slot'], new_dev['func']) - bdf = xc.test_assign_device(self.domid, pci_str) + bdf = xc.test_assign_device(0, pci_str) if bdf != 0: if bdf == -1: raise VmError("failed to assign device: maybe the platform" @@ -685,31 +685,39 @@ class XendDomainInfo: # co-assignment devices hasn't been assigned, or has been assigned to # domN. coassignment_list = pci_device.find_coassigned_devices() - assigned_pci_device_str_list = get_assigned_pci_devices(self.domid) + assigned_pci_device_str_list = self._get_assigned_pci_devices() for pci_str in coassignment_list: (domain, bus, dev, func) = parse_pci_name(pci_str) dev_str = '0x%x,0x%x,0x%x,0x%x' % (domain, bus, dev, func) - if xc.test_assign_device(self.domid, dev_str) == 0: + if xc.test_assign_device(0, dev_str) == 0: continue if not pci_str in assigned_pci_device_str_list: - raise VmError(('pci: failed to pci-attach %s to dom%d" + \ + raise VmError(("pci: failed to pci-attach %s to domain %s" + \ " because one of its co-assignment device %s has been" + \ - " assigned to other domain.' \ - )% (pci_device.name, self.domid, pci_str)) - - opts = '' - if 'opts' in new_dev and len(new_dev['opts']) > 0: - config_opts = new_dev['opts'] - config_opts = map(lambda (x, y): x+'='+y, config_opts) - opts = ',' + reduce(lambda x, y: x+','+y, config_opts) - - bdf_str = "%s:%s:%s.%s%s@%s" % (new_dev['domain'], + " assigned to other domain." \ + )% (pci_device.name, self.info['name_label'], pci_str)) + + if self.domid is not None: + opts = '' + if 'opts' in new_dev and len(new_dev['opts']) > 0: + config_opts = new_dev['opts'] + config_opts = map(lambda (x, y): x+'='+y, config_opts) + opts = ',' + reduce(lambda x, y: x+','+y, config_opts) + + bdf_str = "%s:%s:%s.%s%s@%s" % (new_dev['domain'], new_dev['bus'], new_dev['slot'], new_dev['func'], opts, - new_dev['vslt']) - self.image.signalDeviceModel('pci-ins', 'pci-inserted', bdf_str) + new_dev['vslot']) + self.image.signalDeviceModel('pci-ins', 'pci-inserted', bdf_str) + + vslot = xstransact.Read("/local/domain/0/device-model/%i/parameter" + % self.getDomid()) + else: + vslot = new_dev['vslot'] + + return vslot def device_create(self, dev_config): @@ -788,72 +796,101 @@ class XendDomainInfo: if self.info.is_hvm(): if pci_state == 'Initialising': # HVM PCI device attachment - self.hvm_pci_device_create(dev_config) - # Update vslt - vslt = xstransact.Read("/local/domain/0/device-model/%i/parameter" - % self.getDomid()) - dev['vslt'] = vslt + vslot = self.hvm_pci_device_create(dev_config) + # Update vslot + dev['vslot'] = vslot for n in sxp.children(pci_dev): - if(n[0] == 'vslt'): - n[1] = vslt + if(n[0] == 'vslot'): + n[1] = vslot else: # HVM PCI device detachment existing_dev_uuid = sxp.child_value(existing_dev_info, 'uuid') existing_pci_conf = self.info['devices'][existing_dev_uuid][1] existing_pci_devs = existing_pci_conf['devs'] - vslt = AUTO_PHP_SLOT_STR + vslot = AUTO_PHP_SLOT_STR for x in existing_pci_devs: if ( int(x['domain'], 16) == int(dev['domain'], 16) and int(x['bus'], 16) == int(dev['bus'], 16) and int(x['slot'], 16) == int(dev['slot'], 16) and int(x['func'], 16) == int(dev['func'], 16) ): - vslt = x['vslt'] + vslot = x['vslot'] break - if vslt == AUTO_PHP_SLOT_STR: + if vslot == AUTO_PHP_SLOT_STR: raise VmError("Device %04x:%02x:%02x.%01x is not connected" % (int(dev['domain'],16), int(dev['bus'],16), int(dev['slot'],16), int(dev['func'],16))) - self.hvm_destroyPCIDevice(int(vslt, 16)) - # Update vslt - dev['vslt'] = vslt + self.hvm_destroyPCIDevice(int(vslot, 16)) + # Update vslot + dev['vslot'] = vslot for n in sxp.children(pci_dev): - if(n[0] == 'vslt'): - n[1] = vslt + if(n[0] == 'vslot'): + n[1] = vslot # If pci platform does not exist, create and exit. if existing_dev_info is None: self.device_create(dev_sxp) return True - # use DevController.reconfigureDevice to change device config - dev_control = self.getDeviceController(dev_class) - dev_uuid = dev_control.reconfigureDevice(devid, dev_config) - if not self.info.is_hvm(): - # in PV case, wait until backend state becomes connected. - dev_control.waitForDevice_reconfigure(devid) - num_devs = dev_control.cleanupDevice(devid) - - # update XendConfig with new device info - if dev_uuid: - new_dev_sxp = dev_control.configuration(devid) + if self.domid is not None: + # use DevController.reconfigureDevice to change device config + dev_control = self.getDeviceController(dev_class) + dev_uuid = dev_control.reconfigureDevice(devid, dev_config) + if not self.info.is_hvm(): + # in PV case, wait until backend state becomes connected. + dev_control.waitForDevice_reconfigure(devid) + num_devs = dev_control.cleanupDevice(devid) + + # update XendConfig with new device info + if dev_uuid: + new_dev_sxp = dev_control.configuration(devid) + self.info.device_update(dev_uuid, new_dev_sxp) + + # If there is no device left, destroy pci and remove config. + if num_devs == 0: + if self.info.is_hvm(): + self.destroyDevice('pci', devid, True) + del self.info['devices'][dev_uuid] + platform = self.info['platform'] + orig_dev_num = len(platform['pci']) + # TODO: can use this to keep some info to ask high level + # management tools to hot insert a new passthrough dev + # after migration + if orig_dev_num != 0: + #platform['pci'] = ["%dDEVs" % orig_dev_num] + platform['pci'] = [] + else: + self.destroyDevice('pci', devid) + del self.info['devices'][dev_uuid] + else: + new_dev_sxp = ['pci'] + for cur_dev in sxp.children(existing_dev_info, 'dev'): + if pci_state == 'Closing': + if int(dev['domain'], 16) == int(sxp.child_value(cur_dev, 'domain'), 16) and \ + int(dev['bus'], 16) == int(sxp.child_value(cur_dev, 'bus'), 16) and \ + int(dev['slot'], 16) == int(sxp.child_value(cur_dev, 'slot'), 16) and \ + int(dev['func'], 16) == int(sxp.child_value(cur_dev, 'func'), 16): + continue + new_dev_sxp.append(cur_dev) + + if pci_state == 'Initialising': + for new_dev in sxp.children(dev_sxp, 'dev'): + new_dev_sxp.append(new_dev) + + dev_uuid = sxp.child_value(existing_dev_info, 'uuid') self.info.device_update(dev_uuid, new_dev_sxp) - # If there is no device left, destroy pci and remove config. - if num_devs == 0: - if self.info.is_hvm(): - self.destroyDevice('pci', devid, True) + # If there is only 'vscsi' in new_dev_sxp, remove the config. + if len(sxp.children(new_dev_sxp, 'dev')) == 0: del self.info['devices'][dev_uuid] - platform = self.info['platform'] - orig_dev_num = len(platform['pci']) - # TODO: can use this to keep some info to ask high level - # management tools to hot insert a new passthrough dev - # after migration - if orig_dev_num != 0: - #platform['pci'] = ["%dDEVs" % orig_dev_num] - platform['pci'] = [] - else: - self.destroyDevice('pci', devid) - del self.info['devices'][dev_uuid] + if self.info.is_hvm(): + platform = self.info['platform'] + orig_dev_num = len(platform['pci']) + # TODO: can use this to keep some info to ask high level + # management tools to hot insert a new passthrough dev + # after migration + if orig_dev_num != 0: + #platform['pci'] = ["%dDEVs" % orig_dev_num] + platform['pci'] = [] xen.xend.XendDomain.instance().managed_config_save(self) @@ -1046,7 +1083,7 @@ class XendDomainInfo: #find the pass-through device with the virtual slot devnum = 0 for x in pci_conf['devs']: - if int(x['vslt'], 16) == vslot: + if int(x['vslot'], 16) == vslot: break devnum += 1 @@ -1054,7 +1091,7 @@ class XendDomainInfo: raise VmError("Device @ vslot 0x%x doesn't exist." % (vslot)) if vslot == AUTO_PHP_SLOT: - raise VmError("Device @ vslot 0x%x do not support hotplug." % (vslot)) + raise VmError("Device @ vslot 0x%x doesn't support hotplug." % (vslot)) # Check the co-assignment. # To pci-detach a device D from domN, we should ensure: for each DD in the @@ -1072,19 +1109,20 @@ class XendDomainInfo: "parse it's resources - "+str(e)) coassignment_list = pci_device.find_coassigned_devices() coassignment_list.remove(pci_device.name) - assigned_pci_device_str_list = get_assigned_pci_devices(self.domid) + assigned_pci_device_str_list = self._get_assigned_pci_devices() for pci_str in coassignment_list: if pci_str in assigned_pci_device_str_list: - raise VmError(('pci: failed to pci-detach %s from dom%d" + \ + raise VmError(("pci: failed to pci-detach %s from domain %s" + \ " because one of its co-assignment device %s is still " + \ - " assigned to the domain.' \ - )% (pci_device.name, self.domid, pci_str)) + " assigned to the domain." \ + )% (pci_device.name, self.info['name_label'], pci_str)) bdf_str = "%s:%s:%s.%s" % (x['domain'], x['bus'], x['slot'], x['func']) log.info("hvm_destroyPCIDevice:%s:%s!", x, bdf_str) - self.image.signalDeviceModel('pci-rem', 'pci-removed', bdf_str) + if self.domid is not None: + self.image.signalDeviceModel('pci-rem', 'pci-removed', bdf_str) return 0 @@ -1234,6 +1272,26 @@ class XendDomainInfo: return dev_info return None + def _get_assigned_pci_devices(self, devid = 0): + if self.domid is not None: + return get_assigned_pci_devices(self.domid) + + dev_str_list = [] + dev_info = self._getDeviceInfo_pci(devid) + if dev_info is None: + return dev_str_list + dev_uuid = sxp.child_value(dev_info, 'uuid') + pci_conf = self.info['devices'][dev_uuid][1] + pci_devs = pci_conf['devs'] + for pci_dev in pci_devs: + domain = int(pci_dev['domain'], 16) + bus = int(pci_dev['bus'], 16) + slot = int(pci_dev['slot'], 16) + func = int(pci_dev['func'], 16) + dev_str = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func) + dev_str_list = dev_str_list + [dev_str] + return dev_str_list + def setMemoryTarget(self, target): """Set the memory target of this domain. @param target: In MiB. @@ -1634,7 +1692,13 @@ class XendDomainInfo: if changed: # Update the domain section of the store, as this contains some # parameters derived from the VM configuration. - self._storeDomDetails() + self.refresh_shutdown_lock.acquire() + try: + state = self._stateGet() + if state not in (DOM_STATE_SHUTDOWN, DOM_STATE_HALTED,): + self._storeDomDetails() + finally: + self.refresh_shutdown_lock.release() return 1 @@ -2333,7 +2397,7 @@ class XendDomainInfo: pci = map(lambda x: x[0:4], pci) # strip options pci_str = str(pci) if hvm and pci_str: - bdf = xc.test_assign_device(self.domid, pci_str) + bdf = xc.test_assign_device(0, pci_str) if bdf != 0: if bdf == -1: raise VmError("failed to assign device: maybe the platform" @@ -3660,7 +3724,7 @@ class XendDomainInfo: ['bus', '0x%02x' % ppci.get_bus()], ['slot', '0x%02x' % ppci.get_slot()], ['func', '0x%1x' % ppci.get_func()], - ['vslt', '0x%02x' % xenapi_pci.get('hotplug_slot')], + ['vslot', '0x%02x' % xenapi_pci.get('hotplug_slot')], ['opts', dpci_opts], ['uuid', dpci_uuid] ], diff -r 19919f01f2c5 -r 8c806c66a597 tools/python/xen/xend/server/pciif.py --- a/tools/python/xen/xend/server/pciif.py Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/python/xen/xend/server/pciif.py Tue Apr 14 14:04:58 2009 +0900 @@ -71,6 +71,10 @@ class PciController(DevController): pcidevid = 0 vslots = "" for pci_config in config.get('devs', []): + vslot = pci_config.get('vslot') + if vslot is not None: + vslots = vslots + vslot + ";" + domain = parse_hex(pci_config.get('domain', 0)) bus = parse_hex(pci_config.get('bus', 0)) slot = parse_hex(pci_config.get('slot', 0)) @@ -82,10 +86,6 @@ class PciController(DevController): opts = map(lambda (x, y): x+'='+y, opts) opts = reduce(lambda x, y: x+','+y, opts) back['opts-%i' % pcidevid] = opts - - vslt = pci_config.get('vslt') - if vslt is not None: - vslots = vslots + vslt + ";" back['dev-%i' % pcidevid] = "%04x:%02x:%02x.%01x" % \ (domain, bus, slot, func) @@ -170,9 +170,9 @@ class PciController(DevController): # Update vslots if back.get('vslots') is not None: vslots = old_vslots - for vslt in back['vslots'].split(';'): - if vslt != '': - vslots = vslots.replace(vslt + ';', '', 1) + for vslot in back['vslots'].split(';'): + if vslot != '': + vslots = vslots.replace(vslot + ';', '', 1) if vslots == '': self.removeBackend(devid, 'vslots') else: @@ -219,9 +219,9 @@ class PciController(DevController): #append vslot info if vslots is not None: try: - dev_dict['vslt'] = slot_list[i] + dev_dict['vslot'] = slot_list[i] except IndexError: - dev_dict['vslt'] = AUTO_PHP_SLOT_STR + dev_dict['vslot'] = AUTO_PHP_SLOT_STR pci_devs.append(dev_dict) @@ -454,7 +454,7 @@ class PciController(DevController): for (domain, bus, slot, func) in pci_dev_list: self.setupOneDevice(domain, bus, slot, func) wPath = '/local/domain/0/backend/pci/%u/0/aerState' % (self.getDomid()) - self.aerStatePath = xswatch(wPath, self._handleAerStateWatch) + self.aerStateWatch = xswatch(wPath, self._handleAerStateWatch) log.debug('pci: register aer watch %s', wPath) return @@ -590,7 +590,7 @@ class PciController(DevController): def destroyDevice(self, devid, force): DevController.destroyDevice(self, devid, True) log.debug('pci: unregister aer watch') - self.unwatchAerState + self.unwatchAerState() def unwatchAerState(self): """Remove the watch on the domain's aerState node, if any.""" diff -r 19919f01f2c5 -r 8c806c66a597 tools/python/xen/xm/create.dtd --- a/tools/python/xen/xm/create.dtd Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/python/xen/xm/create.dtd Tue Apr 14 14:04:58 2009 +0900 @@ -89,7 +89,7 @@ slot CDATA #REQUIRED func CDATA #REQUIRED opts_str CDATA #IMPLIED - vslt CDATA #IMPLIED> + vslot CDATA #IMPLIED> <!ELEMENT vscsi EMPTY> <!ATTLIST vscsi p-dev CDATA #REQUIRED diff -r 19919f01f2c5 -r 8c806c66a597 tools/python/xen/xm/main.py --- a/tools/python/xen/xm/main.py Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/python/xen/xm/main.py Tue Apr 14 14:04:58 2009 +0900 @@ -2155,7 +2155,7 @@ def xm_pci_list(args): "bus": "0x%02x" % int(ppci_record["bus"]), "slot": "0x%02x" % int(ppci_record["slot"]), "func": "0x%01x" % int(ppci_record["func"]), - "vslt": "0x%02x" % \ + "vslot": "0x%02x" % \ int(server.xenapi.DPCI.get_hotplug_slot(dpci_ref)) } devs.append(dev) @@ -2166,10 +2166,10 @@ def xm_pci_list(args): if len(devs) == 0: return - has_vslt = devs[0].has_key('vslt') - if has_vslt: + has_vslot = devs[0].has_key('vslot') + if has_vslot: hdr_str = 'VSlt domain bus slot func' - fmt_str = "%(vslt)-3s %(domain)-3s %(bus)-3s %(slot)-3s %(func)-3s " + fmt_str = "%(vslot)-3s %(domain)-3s %(bus)-3s %(slot)-3s %(func)-3s " else: hdr_str = 'domain bus slot func' fmt_str = "%(domain)-3s %(bus)-3s %(slot)-3s %(func)-3s " @@ -2441,16 +2441,16 @@ def parse_pci_configuration(args, state, dom = args[0] pci_dev_str = args[1] if len(args) == 3: - vslt = args[2] - else: - vslt = AUTO_PHP_SLOT_STR + vslot = args[2] + else: + vslot = AUTO_PHP_SLOT_STR pci=['pci'] pci_match = re.match(r"((?P<domain>[0-9a-fA-F]{1,4})[:,])?" + \ r"(?P<bus>[0-9a-fA-F]{1,2})[:,]" + \ r"(?P<slot>[0-9a-fA-F]{1,2})[.,]" + \ r"(?P<func>[0-7])$", pci_dev_str) if pci_match == None: - raise OptionError("Invalid argument: %s %s" % (pci_dev_str,vslt)) + raise OptionError("Invalid argument: %s %s" % (pci_dev_str, vslot)) pci_dev_info = pci_match.groupdict('0') try: @@ -2458,13 +2458,13 @@ def parse_pci_configuration(args, state, ['bus', '0x'+ pci_dev_info['bus']], ['slot', '0x'+ pci_dev_info['slot']], ['func', '0x'+ pci_dev_info['func']], - ['vslt', '0x%x' % int(vslt, 16)]] + ['vslot', '0x%x' % int(vslot, 16)]] if len(opts) > 0: pci_bdf.append(['opts', opts]) pci.append(pci_bdf) except: - raise OptionError("Invalid argument: %s %s" % (pci_dev_str,vslt)) + raise OptionError("Invalid argument: %s %s" % (pci_dev_str, vslot)) pci.append(['state', state]) return (dom, pci) @@ -2494,7 +2494,7 @@ def xm_pci_attach(args): bus = int(sxp.child_value(pci_dev, 'bus'), 16) slot = int(sxp.child_value(pci_dev, 'slot'), 16) func = int(sxp.child_value(pci_dev, 'func'), 16) - vslt = int(sxp.child_value(pci_dev, 'vslt'), 16) + vslot = int(sxp.child_value(pci_dev, 'vslot'), 16) name = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func) target_ref = None @@ -2508,7 +2508,7 @@ def xm_pci_attach(args): dpci_record = { "VM": get_single_vm(dom), "PPCI": target_ref, - "hotplug_slot": vslt, + "hotplug_slot": vslot, "options": dict(config_pci_opts) } server.xenapi.DPCI.create(dpci_record) @@ -2667,7 +2667,7 @@ def xm_pci_detach(args): bus = int(sxp.child_value(pci_dev, 'bus'), 16) slot = int(sxp.child_value(pci_dev, 'slot'), 16) func = int(sxp.child_value(pci_dev, 'func'), 16) - vslt = int(sxp.child_value(pci_dev, 'vslt'), 16) + vslot = int(sxp.child_value(pci_dev, 'vslot'), 16) name = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func) target_ref = None diff -r 19919f01f2c5 -r 8c806c66a597 tools/python/xen/xm/xenapi_create.py --- a/tools/python/xen/xm/xenapi_create.py Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/python/xen/xm/xenapi_create.py Tue Apr 14 14:04:58 2009 +0900 @@ -937,8 +937,8 @@ class sxp2xml: = get_child_by_name(dev_sxp, "slot", "0") pci.attributes["func"] \ = get_child_by_name(dev_sxp, "func", "0") - pci.attributes["vslt"] \ - = get_child_by_name(dev_sxp, "vslt", "0") + pci.attributes["vslot"] \ + = get_child_by_name(dev_sxp, "vslot", "0") for opt in get_child_by_name(dev_sxp, "opts", ""): if len(opt) > 0: pci_opt = document.createElement("pci_opt") diff -r 19919f01f2c5 -r 8c806c66a597 tools/security/Makefile --- a/tools/security/Makefile Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/security/Makefile Tue Apr 14 14:04:58 2009 +0900 @@ -40,9 +40,6 @@ all: build all: build .PHONY: install -ifndef XEN_PYTHON_NATIVE_INSTALL -install: LIBPATH=$(shell PYTHONPATH=../python/xen/util python -c "import auxbin; print auxbin.libpath()") -endif install: all $(ACM_CONFIG_FILE) $(INSTALL_DIR) $(DESTDIR)$(SBINDIR) $(INSTALL_PROG) $(ACM_INST_TOOLS) $(DESTDIR)$(SBINDIR) @@ -63,11 +60,8 @@ install: all $(ACM_CONFIG_FILE) $(INSTALL_DATA) $(ACM_INST_HTML) $(DESTDIR)$(ACM_SECGEN_HTMLDIR) $(INSTALL_DIR) $(DESTDIR)$(ACM_SECGEN_CGIDIR) $(INSTALL_PROG) $(ACM_INST_CGI) $(DESTDIR)$(ACM_SECGEN_CGIDIR) -ifndef XEN_PYTHON_NATIVE_INSTALL - python python/setup.py install --install-lib="$(DESTDIR)$(LIBPATH)/python" -else - python python/setup.py install --root="$(DESTDIR)" -endif + python python/setup.py install \ + --prefix="$(PREFIX)" --root="$(DESTDIR)" --force else .PHONY: all all: diff -r 19919f01f2c5 -r 8c806c66a597 tools/security/python/xensec_tools/acm_getlabel --- a/tools/security/python/xensec_tools/acm_getlabel Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/security/python/xensec_tools/acm_getlabel Tue Apr 14 14:04:58 2009 +0900 @@ -3,10 +3,6 @@ import sys import sys import traceback import getopt - -# add fallback path for non-native python path installs if needed -sys.path.insert(-1, '/usr/lib/python') -sys.path.insert(-1, '/usr/lib64/python') from xen.util.security import ACMError, err, get_ssid diff -r 19919f01f2c5 -r 8c806c66a597 tools/security/xensec_gen.py --- a/tools/security/xensec_gen.py Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/security/xensec_gen.py Tue Apr 14 14:04:58 2009 +0900 @@ -17,10 +17,6 @@ import sys -# Add fallback path for non-native python path installs if needed -sys.path.append( '/usr/lib/python' ) -sys.path.append( '/usr/lib64/python' ) - from xen.xensec_gen import main main.main( ) diff -r 19919f01f2c5 -r 8c806c66a597 tools/sv/index.psp --- a/tools/sv/index.psp Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/sv/index.psp Tue Apr 14 14:04:58 2009 +0900 @@ -1,6 +1,5 @@ <% import sys -sys.path.append( "/usr/lib/python" ) debug = True and False diff -r 19919f01f2c5 -r 8c806c66a597 tools/vnet/scripts/vn --- a/tools/vnet/scripts/vn Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/vnet/scripts/vn Tue Apr 14 14:04:58 2009 +0900 @@ -26,9 +26,6 @@ import socket import socket import sys from getopt import getopt, GetoptError - -sys.path.append('/usr/lib/python') -sys.path.append('/usr/lib64/python') from xen.xend import sxp from xen.xend.PrettyPrint import prettyprint diff -r 19919f01f2c5 -r 8c806c66a597 tools/xenpmd/Makefile --- a/tools/xenpmd/Makefile Tue Apr 07 11:32:24 2009 +0900 +++ b/tools/xenpmd/Makefile Tue Apr 14 14:04:58 2009 +0900 @@ -19,4 +19,7 @@ clean: clean: $(RM) -f $(BIN) $(DEPS) +%: %.c Makefile + $(CC) $(CFLAGS) $< $(LDFLAGS) -o $@ + -include $(DEPS) diff -r 19919f01f2c5 -r 8c806c66a597 xen/Makefile --- a/xen/Makefile Tue Apr 07 11:32:24 2009 +0900 +++ b/xen/Makefile Tue Apr 14 14:04:58 2009 +0900 @@ -2,7 +2,7 @@ # All other places this is stored (eg. compile.h) should be autogenerated. export XEN_VERSION = 3 export XEN_SUBVERSION = 4 -export XEN_EXTRAVERSION ?= -unstable$(XEN_VENDORVERSION) +export XEN_EXTRAVERSION ?= .0-rc2-pre$(XEN_VENDORVERSION) export XEN_FULLVERSION = $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION) -include xen-version diff -r 19919f01f2c5 -r 8c806c66a597 xen/arch/x86/acpi/cpu_idle.c --- a/xen/arch/x86/acpi/cpu_idle.c Tue Apr 07 11:32:24 2009 +0900 +++ b/xen/arch/x86/acpi/cpu_idle.c Tue Apr 14 14:04:58 2009 +0900 @@ -48,7 +48,7 @@ #include <public/platform.h> #include <public/sysctl.h> -#define DEBUG_PM_CX +/*#define DEBUG_PM_CX*/ static void (*lapic_timer_off)(void); static void (*lapic_timer_on)(void); @@ -780,7 +780,7 @@ long set_cx_pminfo(uint32_t cpu, struct /* FIXME: C-state dependency is not supported by far */ - print_acpi_power(cpu_id, acpi_power); + /*print_acpi_power(cpu_id, acpi_power);*/ if ( cpu_id == 0 && pm_idle_save == NULL ) { diff -r 19919f01f2c5 -r 8c806c66a597 xen/arch/x86/cpu/mcheck/mce.c --- a/xen/arch/x86/cpu/mcheck/mce.c Tue Apr 07 11:32:24 2009 +0900 +++ b/xen/arch/x86/cpu/mcheck/mce.c Tue Apr 14 14:04:58 2009 +0900 @@ -23,6 +23,7 @@ #include "mce.h" int mce_disabled = 0; +int is_mc_panic = 0; unsigned int nr_mce_banks; EXPORT_SYMBOL_GPL(nr_mce_banks); /* non-fatal.o */ @@ -33,18 +34,15 @@ static void mcinfo_clear(struct mc_info #define SEG_PL(segsel) ((segsel) & 0x3) #define _MC_MSRINJ_F_REQ_HWCR_WREN (1 << 16) -#if 1 /* XXFM switch to 0 for putback */ - -#define x86_mcerr(str, err) _x86_mcerr(str, err) - -static int _x86_mcerr(const char *msg, int err) -{ - printk("x86_mcerr: %s, returning %d\n", - msg != NULL ? msg : "", err); - return err; +#if 0 +static int x86_mcerr(const char *msg, int err) +{ + gdprintk(XENLOG_WARNING, "x86_mcerr: %s, returning %d\n", + msg != NULL ? msg : "", err); + return err; } #else -#define x86_mcerr(str,err) +#define x86_mcerr(msg, err) (err) #endif cpu_banks_t mca_allbanks; @@ -127,6 +125,7 @@ mctelem_cookie_t mcheck_mca_logout(enum switch (who) { case MCA_MCE_HANDLER: + case MCA_MCE_SCAN: mcg.mc_flags = MC_FLAG_MCE; which = MC_URGENT; break; @@ -222,8 +221,9 @@ mctelem_cookie_t mcheck_mca_logout(enum cbret = mc_callback_bank_extended(mci, i, status); } - /* Clear status */ - mca_wrmsrl(MSR_IA32_MC0_STATUS + 4 * i, 0x0ULL); + if (who != MCA_MCE_SCAN) + /* Clear status */ + mca_wrmsrl(MSR_IA32_MC0_STATUS + 4 * i, 0x0ULL); wmb(); } @@ -472,6 +472,21 @@ cmn_handler_done: } } +void mcheck_mca_clearbanks(cpu_banks_t bankmask) +{ + int i; + uint64_t status; + + for (i = 0; i < 32 && i < nr_mce_banks; i++) { + if (!test_bit(i, bankmask)) + continue; + mca_rdmsrl(MSR_IA32_MC0_STATUS + i * 4, status); + if (!(status & MCi_STATUS_VAL)) + continue; + mca_wrmsrl(MSR_IA32_MC0_STATUS + 4 * i, 0x0ULL); + } +} + static int amd_mcheck_init(struct cpuinfo_x86 *ci) { int rc = 0; @@ -1064,6 +1079,9 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u struct xen_mc_msrinject *mc_msrinject; struct xen_mc_mceinject *mc_mceinject; + if (!IS_PRIV(v->domain) ) + return x86_mcerr(NULL, -EPERM); + if ( copy_from_guest(op, u_xen_mc, 1) ) return x86_mcerr("do_mca: failed copyin of xen_mc_t", -EFAULT); @@ -1074,10 +1092,6 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u case XEN_MC_fetch: mc_fetch.nat = &op->u.mc_fetch; cmdflags = mc_fetch.nat->flags; - - /* This hypercall is for Dom0 only */ - if (!IS_PRIV(v->domain) ) - return x86_mcerr(NULL, -EPERM); switch (cmdflags & (XEN_MC_NONURGENT | XEN_MC_URGENT)) { case XEN_MC_NONURGENT: @@ -1134,9 +1148,6 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u return x86_mcerr("do_mca notify unsupported", -EINVAL); case XEN_MC_physcpuinfo: - if ( !IS_PRIV(v->domain) ) - return x86_mcerr("do_mca cpuinfo", -EPERM); - mc_physcpuinfo.nat = &op->u.mc_physcpuinfo; nlcpu = num_online_cpus(); @@ -1173,9 +1184,6 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u break; case XEN_MC_msrinject: - if ( !IS_PRIV(v->domain) ) - return x86_mcerr("do_mca inject", -EPERM); - if (nr_mce_banks == 0) return x86_mcerr("do_mca inject", -ENODEV); @@ -1203,9 +1211,6 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u break; case XEN_MC_mceinject: - if ( !IS_PRIV(v->domain) ) - return x86_mcerr("do_mca #MC", -EPERM); - if (nr_mce_banks == 0) return x86_mcerr("do_mca #MC", -ENODEV); @@ -1220,9 +1225,8 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u add_taint(TAINT_ERROR_INJECT); - on_selected_cpus(cpumask_of_cpu(target), - x86_mc_mceinject, mc_mceinject, 1, 1); - + on_selected_cpus(cpumask_of_cpu(target), x86_mc_mceinject, + mc_mceinject, 1, 1); break; default: @@ -1246,6 +1250,7 @@ void set_poll_bankmask(struct cpuinfo_x8 } void mc_panic(char *s) { + is_mc_panic = 1; console_start_sync(); printk("Fatal machine check: %s\n", s); printk("\n" diff -r 19919f01f2c5 -r 8c806c66a597 xen/arch/x86/cpu/mcheck/mce.h --- a/xen/arch/x86/cpu/mcheck/mce.h Tue Apr 07 11:32:24 2009 +0900 +++ b/xen/arch/x86/cpu/mcheck/mce.h Tue Apr 14 14:04:58 2009 +0900 @@ -70,7 +70,8 @@ enum mca_source { MCA_MCE_HANDLER, MCA_POLLER, MCA_CMCI_HANDLER, - MCA_RESET + MCA_RESET, + MCA_MCE_SCAN }; enum mca_extinfo { @@ -92,6 +93,8 @@ DECLARE_PER_CPU(cpu_banks_t, poll_bankma DECLARE_PER_CPU(cpu_banks_t, poll_bankmask); DECLARE_PER_CPU(cpu_banks_t, no_cmci_banks); extern int cmci_support; +extern int is_mc_panic; +extern void mcheck_mca_clearbanks(cpu_banks_t); extern mctelem_cookie_t mcheck_mca_logout(enum mca_source, cpu_banks_t, struct mca_summary *); diff -r 19919f01f2c5 -r 8c806c66a597 xen/arch/x86/cpu/mcheck/mce_intel.c --- a/xen/arch/x86/cpu/mcheck/mce_intel.c Tue Apr 07 11:32:24 2009 +0900 +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c Tue Apr 14 14:04:58 2009 +0900 @@ -18,6 +18,29 @@ static int nr_intel_ext_msrs = 0; static int nr_intel_ext_msrs = 0; static int firstbank; +/* Below are for MCE handling */ +struct mce_softirq_barrier { + atomic_t val; + atomic_t ingen; + atomic_t outgen; +}; + +static struct mce_softirq_barrier mce_inside_bar, mce_severity_bar; +static struct mce_softirq_barrier mce_trap_bar; + +/* + * mce_logout_lock should only be used in the trap handler, + * while MCIP has not been cleared yet in the global status + * register. Other use is not safe, since an MCE trap can + * happen at any moment, which would cause lock recursion. + */ +static DEFINE_SPINLOCK(mce_logout_lock); + +static atomic_t severity_cpu = ATOMIC_INIT(-1); + +static void mce_barrier_enter(struct mce_softirq_barrier *); +static void mce_barrier_exit(struct mce_softirq_barrier *); + #ifdef CONFIG_X86_MCE_THERMAL static void unexpected_thermal_interrupt(struct cpu_user_regs *regs) { @@ -123,7 +146,7 @@ static inline void intel_get_extended_ms if ( ext->mc_msrs < ARRAY_SIZE(ext->mc_msr) && msr < MSR_IA32_MCG_EAX + nr_intel_ext_msrs ) { ext->mc_msr[ext->mc_msrs].reg = msr; - rdmsrl(msr, ext->mc_msr[ext->mc_msrs].value); + mca_rdmsrl(msr, ext->mc_msr[ext->mc_msrs].value); ++ext->mc_msrs; } } @@ -169,45 +192,6 @@ intel_get_extended_msrs(struct mc_info * return MCA_EXTINFO_GLOBAL; } -/* Below are for MCE handling */ - -/* Log worst error severity and offending CPU., - * Pick this CPU for further processing in softirq */ -static int severity_cpu = -1; -static int worst = 0; - -/* Lock of entry@second round scanning in MCE# handler */ -static cpumask_t scanned_cpus; -/* Lock for entry@Critical Section in MCE# handler */ -static bool_t mce_enter_lock = 0; -/* Record how many CPUs impacted in this MCE# */ -static cpumask_t impact_map; - -/* Lock of softirq rendezvous entering point */ -static cpumask_t mced_cpus; -/*Lock of softirq rendezvous leaving point */ -static cpumask_t finished_cpus; -/* Lock for picking one processing CPU */ -static bool_t mce_process_lock = 0; - -/* Spinlock for vMCE# MSR virtualization data */ -static DEFINE_SPINLOCK(mce_locks); - -/* Local buffer for holding MCE# data temporarily, sharing between mce - * handler and softirq handler. Those data will be finally committed - * for DOM0 Log and coped to per_dom related data for guest vMCE# - * MSR virtualization. - * Note: When local buffer is still in processing in softirq, another - * MCA comes, simply panic. - */ - -struct mc_local_t -{ - bool_t in_use; - mctelem_cookie_t mctc[NR_CPUS]; -}; -static struct mc_local_t mc_local; - /* This node list records errors impacting a domain. when one * MCE# happens, one error bank impacts a domain. This error node * will be inserted to the tail of the per_dom data for vMCE# MSR @@ -252,18 +236,22 @@ static int fill_vmsr_data(int cpu, struc } entry = alloc_bank_entry(); + if (entry == NULL) + return -1; entry->mci_status = mc_bank->mc_status; entry->mci_addr = mc_bank->mc_addr; entry->mci_misc = mc_bank->mc_misc; entry->cpu = cpu; entry->bank = mc_bank->mc_bank; + spin_lock(&d->arch.vmca_msrs.lock); /* New error Node, insert to the tail of the per_dom data */ list_add_tail(&entry->list, &d->arch.vmca_msrs.impact_header); /* Fill MSR global status */ d->arch.vmca_msrs.mcg_status = gstatus; /* New node impact the domain, need another vMCE# injection*/ d->arch.vmca_msrs.nr_injection++; + spin_unlock(&d->arch.vmca_msrs.lock); printk(KERN_DEBUG "MCE: Found error @[CPU%d BANK%d " "status %"PRIx64" addr %"PRIx64" domid %d]\n ", @@ -273,100 +261,83 @@ static int fill_vmsr_data(int cpu, struc return 0; } -static int mce_actions(void) { - int32_t cpu, ret; +/* + * Called from mctelem_process_deferred. Return 1 if the telemetry + * should be committed for dom0 consumption, 0 if it should be + * dismissed. + */ +static int mce_action(unsigned int cpu, mctelem_cookie_t mctc) +{ struct mc_info *local_mi; struct mcinfo_common *mic = NULL; struct mcinfo_global *mc_global; struct mcinfo_bank *mc_bank; - /* Spinlock is used for exclusive read/write of vMSR virtualization - * (per_dom vMCE# data) - */ - spin_lock(&mce_locks); - - /* - * If softirq is filling this buffer while another MCE# comes, - * simply panic - */ - test_and_set_bool(mc_local.in_use); - - for_each_cpu_mask(cpu, impact_map) { - if (mc_local.mctc[cpu] == NULL) { - printk(KERN_ERR "MCE: get reserved entry failed\n "); - ret = -1; - goto end; - } - local_mi = (struct mc_info*)mctelem_dataptr(mc_local.mctc[cpu]); - x86_mcinfo_lookup(mic, local_mi, MC_TYPE_GLOBAL); - if (mic == NULL) { - printk(KERN_ERR "MCE: get local buffer entry failed\n "); - ret = -1; - goto end; - } - - mc_global = (struct mcinfo_global *)mic; - - /* Processing bank information */ - x86_mcinfo_lookup(mic, local_mi, MC_TYPE_BANK); - - for ( ; mic && mic->size; mic = x86_mcinfo_next(mic) ) { - if (mic->type != MC_TYPE_BANK) { - continue; - } - mc_bank = (struct mcinfo_bank*)mic; - /* Fill vMCE# injection and vMCE# MSR virtualization related data */ - if (fill_vmsr_data(cpu, mc_bank, mc_global->mc_gstatus) == -1) { - ret = -1; - goto end; - } - - /* TODO: Add recovery actions here, such as page-offline, etc */ - } - } /* end of impact_map loop */ - - ret = 0; - -end: - - for_each_cpu_mask(cpu, impact_map) { - /* This reserved entry is processed, commit it */ - if (mc_local.mctc[cpu] != NULL) { - mctelem_commit(mc_local.mctc[cpu]); - printk(KERN_DEBUG "MCE: Commit one URGENT ENTRY\n"); - } - } - - test_and_clear_bool(mc_local.in_use); - spin_unlock(&mce_locks); - return ret; + local_mi = (struct mc_info*)mctelem_dataptr(mctc); + x86_mcinfo_lookup(mic, local_mi, MC_TYPE_GLOBAL); + if (mic == NULL) { + printk(KERN_ERR "MCE: get local buffer entry failed\n "); + return 0; + } + + mc_global = (struct mcinfo_global *)mic; + + /* Processing bank information */ + x86_mcinfo_lookup(mic, local_mi, MC_TYPE_BANK); + + for ( ; mic && mic->size; mic = x86_mcinfo_next(mic) ) { + if (mic->type != MC_TYPE_BANK) { + continue; + } + mc_bank = (struct mcinfo_bank*)mic; + /* Fill vMCE# injection and vMCE# MSR virtualization related data */ + if (fill_vmsr_data(cpu, mc_bank, mc_global->mc_gstatus) == -1) + break; + + /* TODO: Add recovery actions here, such as page-offline, etc */ + } + + return 1; } /* Softirq Handler for this MCE# processing */ static void mce_softirq(void) { int cpu = smp_processor_id(); + unsigned int workcpu; cpumask_t affinity; - /* Wait until all cpus entered softirq */ - while ( cpus_weight(mced_cpus) != num_online_cpus() ) { - cpu_relax(); - } - /* Not Found worst error on severity_cpu, it's weird */ - if (severity_cpu == -1) { - printk(KERN_WARNING "MCE: not found severity_cpu!\n"); - mc_panic("MCE: not found severity_cpu!"); - return; - } + printk(KERN_DEBUG "CPU%d enter softirq\n", cpu); + + mce_barrier_enter(&mce_inside_bar); + + /* + * Everybody is here. Now let's see who gets to do the + * recovery work. Right now we just see if there's a CPU + * that did not have any problems, and pick that one. + * + * First, just set a default value: the last CPU who reaches this + * will overwrite the value and become the default. + */ + + atomic_set(&severity_cpu, cpu); + + mce_barrier_enter(&mce_severity_bar); + if (!mctelem_has_deferred(cpu)) + atomic_set(&severity_cpu, cpu); + mce_barrier_exit(&mce_severity_bar); + /* We choose severity_cpu for further processing */ - if (severity_cpu == cpu) { + if (atomic_read(&severity_cpu) == cpu) { + + printk(KERN_DEBUG "CPU%d handling errors\n", cpu); /* Step1: Fill DOM0 LOG buffer, vMCE injection buffer and * vMCE MSRs virtualization buffer */ - if (mce_actions()) - mc_panic("MCE recovery actions or Filling vMCE MSRS " - "virtualization data failed!\n"); + for_each_online_cpu(workcpu) { + mctelem_process_deferred(workcpu, mce_action); + } /* Step2: Send Log to DOM0 through vIRQ */ if (dom0 && guest_enabled_event(dom0->vcpu[0], VIRQ_MCA)) { @@ -387,26 +358,9 @@ static void mce_softirq(void) vcpu_set_affinity(dom0->vcpu[0], &affinity); vcpu_kick(dom0->vcpu[0]); } - - /* Clean Data */ - test_and_clear_bool(mce_process_lock); - cpus_clear(impact_map); - cpus_clear(scanned_cpus); - worst = 0; - cpus_clear(mced_cpus); - memset(&mc_local, 0x0, sizeof(mc_local)); - } - - cpu_set(cpu, finished_cpus); - wmb(); - /* Leave until all cpus finished recovery actions in softirq */ - while ( cpus_weight(finished_cpus) != num_online_cpus() ) { - cpu_relax(); - } - - cpus_clear(finished_cpus); - severity_cpu = -1; - printk(KERN_DEBUG "CPU%d exit softirq \n", cpu); + } + + mce_barrier_exit(&mce_inside_bar); } /* Machine Check owner judge algorithm: @@ -424,127 +378,157 @@ static void mce_softirq(void) * Round2: Do all MCE processing logic as normal. */ -/* Simple Scan. Panic when found non-recovery errors. Doing this for - * avoiding LOG missing +static void mce_panic_check(void) +{ + if (is_mc_panic) { + local_irq_enable(); + for ( ; ; ) + halt(); + } +} + +/* + * Initialize a barrier. Just set it to 0. */ -static void severity_scan(void) -{ - uint64_t status; - int32_t i; - - /* TODO: For PCC = 0, we need to have further judge. If it is can't be - * recovered, we need to RESET for avoiding DOM0 LOG missing - */ - for ( i = 0; i < nr_mce_banks; i++) { - mca_rdmsrl(MSR_IA32_MC0_STATUS + 4 * i , status); - if ( !(status & MCi_STATUS_VAL) ) - continue; - /* MCE handler only handles UC error */ - if ( !(status & MCi_STATUS_UC) ) - continue; - if ( !(status & MCi_STATUS_EN) ) - continue; - /* - * If this was an injected error, keep going, since the - * interposed value will be lost at reboot. - */ - if (status & MCi_STATUS_PCC && intpose_lookup(smp_processor_id(), - MSR_IA32_MC0_STATUS + 4 * i, NULL) == NULL) - mc_panic("pcc = 1, cpu unable to continue\n"); - } - - /* TODO: Further judgement for later CPUs here, maybe need MCACOD assistence */ - /* EIPV and RIPV is not a reliable way to judge the error severity */ - -} - +static void mce_barrier_init(struct mce_softirq_barrier *bar) +{ + atomic_set(&bar->val, 0); + atomic_set(&bar->ingen, 0); + atomic_set(&bar->outgen, 0); +} + +#if 0 +/* + * This function will need to be used when offlining a CPU in the + * recovery actions. + * + * Decrement a barrier only. Needed for cases where the CPU + * in question can't do it itself (e.g. it is being offlined). + */ +static void mce_barrier_dec(struct mce_softirq_barrier *bar) +{ + atomic_inc(&bar->outgen); + wmb(); + atomic_dec(&bar->val); +} +#endif + +static void mce_spin_lock(spinlock_t *lk) +{ + while (!spin_trylock(lk)) { + cpu_relax(); + mce_panic_check(); + } +} + +static void mce_spin_unlock(spinlock_t *lk) +{ + spin_unlock(lk); +} + +/* + * Increment the generation number and the value. The generation number + * is incremented when entering a barrier. This way, it can be checked + * on exit if a CPU is trying to re-enter the barrier. This can happen + * if the first CPU to make it out immediately exits or re-enters, while + * another CPU that is still in the loop becomes otherwise occupied + * (e.g. it needs to service an interrupt, etc), missing the value + * it's waiting for. + * + * These barrier functions should always be paired, so that the + * counter value will reach 0 again after all CPUs have exited. + */ +static void mce_barrier_enter(struct mce_softirq_barrier *bar) +{ + int gen; + + atomic_inc(&bar->ingen); + gen = atomic_read(&bar->outgen); + mb(); + atomic_inc(&bar->val); + while ( atomic_read(&bar->val) != num_online_cpus() && + atomic_read(&bar->outgen) == gen) { + mb(); + mce_panic_check(); + } +} + +static void mce_barrier_exit(struct mce_softirq_barrier *bar) +{ + int gen; + + atomic_inc(&bar->outgen); + gen = atomic_read(&bar->ingen); + mb(); + atomic_dec(&bar->val); + while ( atomic_read(&bar->val) != 0 && + atomic_read(&bar->ingen) == gen ) { + mb(); + mce_panic_check(); + } +} + +static void mce_barrier(struct mce_softirq_barrier *bar) +{ + mce_barrier_enter(bar); + mce_barrier_exit(bar); +} static void intel_machine_check(struct cpu_user_regs * regs, long error_code) { - unsigned int cpu = smp_processor_id(); - int32_t severity = 0; uint64_t gstatus; mctelem_cookie_t mctc = NULL; struct mca_summary bs; - /* First round scanning */ - severity_scan(); - cpu_set(cpu, scanned_cpus); - while (cpus_weight(scanned_cpus) < num_online_cpus()) - cpu_relax(); - - wmb(); - /* All CPUs Finished first round scanning */ - if (mc_local.in_use != 0) { - mc_panic("MCE: Local buffer is being processed, can't handle new MCE!\n"); - return; - } - - /* Enter Critical Section */ - while (test_and_set_bool(mce_enter_lock)) { - udelay (1); - } - - mctc = mcheck_mca_logout(MCA_MCE_HANDLER, mca_allbanks, &bs); - /* local data point to the reserved entry, let softirq to - * process the local data */ - if (!bs.errcnt) { + mce_spin_lock(&mce_logout_lock); + + mctc = mcheck_mca_logout(MCA_MCE_SCAN, mca_allbanks, &bs); + + if (bs.errcnt) { + /* + * Uncorrected errors must be dealth with in softirq context. + */ + if (bs.uc || bs.pcc) { + add_taint(TAINT_MACHINE_CHECK); + if (mctc != NULL) + mctelem_defer(mctc); + /* + * For PCC=1, context is lost, so reboot now without clearing + * the banks, and deal with the telemetry after reboot + * (the MSRs are sticky) + */ + if (bs.pcc) + mc_panic("State lost due to machine check exception.\n"); + } else { + if (mctc != NULL) + mctelem_commit(mctc); + } + mcheck_mca_clearbanks(mca_allbanks); + } else { if (mctc != NULL) mctelem_dismiss(mctc); - mc_local.mctc[cpu] = NULL; - cpu_set(cpu, mced_cpus); - test_and_clear_bool(mce_enter_lock); - raise_softirq(MACHINE_CHECK_SOFTIRQ); - return; - } - else if ( mctc != NULL) { - mc_local.mctc[cpu] = mctc; - } - - if (bs.uc || bs.pcc) - add_taint(TAINT_MACHINE_CHECK); - - if (bs.pcc) { - printk(KERN_WARNING "PCC=1 should have caused reset\n"); - severity = 3; - } - else if (bs.uc) { - severity = 2; - } - else { - printk(KERN_WARNING "We should skip Correctable Error\n"); - severity = 1; - } - /* This is the offending cpu! */ - cpu_set(cpu, impact_map); - - if ( severity > worst) { - worst = severity; - severity_cpu = cpu; - } - cpu_set(cpu, mced_cpus); - test_and_clear_bool(mce_enter_lock); - wmb(); - - /* Wait for all cpus Leave Critical */ - while (cpus_weight(mced_cpus) < num_online_cpus()) - cpu_relax(); - /* Print MCE error */ - x86_mcinfo_dump(mctelem_dataptr(mctc)); - - /* Pick one CPU to clear MCIP */ - if (!test_and_set_bool(mce_process_lock)) { + } + + mce_spin_unlock(&mce_logout_lock); + + /* + * Wait until everybody has processed the trap. + */ + mce_barrier(&mce_trap_bar); + + /* + * Clear MCIP if it wasn't already. There is a small + * chance that more than 1 CPU will end up doing this, + * but that's OK. + */ + if (bs.errcnt) { mca_rdmsrl(MSR_IA32_MCG_STATUS, gstatus); - mca_wrmsrl(MSR_IA32_MCG_STATUS, gstatus & ~MCG_STATUS_MCIP); - - if (worst >= 3) { - printk(KERN_WARNING "worst=3 should have caused RESET\n"); - mc_panic("worst=3 should have caused RESET"); - } - else { - printk(KERN_DEBUG "MCE: trying to recover\n"); - } - } + if ((gstatus & MCG_STATUS_MCIP) != 0) + mca_wrmsrl(MSR_IA32_MCG_STATUS, gstatus & ~MCG_STATUS_MCIP); + /* Print MCE error */ + x86_mcinfo_dump(mctelem_dataptr(mctc)); + } + raise_softirq(MACHINE_CHECK_SOFTIRQ); } @@ -778,6 +762,11 @@ static void mce_init(void) clear_in_cr4(X86_CR4_MCE); + mce_barrier_init(&mce_inside_bar); + mce_barrier_init(&mce_severity_bar); + mce_barrier_init(&mce_trap_bar); + spin_lock_init(&mce_logout_lock); + /* log the machine checks left over from the previous reset. * This also clears all registers*/ @@ -840,6 +829,7 @@ void intel_mce_init_msr(struct domain *d memset(d->arch.vmca_msrs.mci_ctl, ~0, sizeof(d->arch.vmca_msrs.mci_ctl)); INIT_LIST_HEAD(&d->arch.vmca_msrs.impact_header); + spin_lock_init(&d->arch.vmca_msrs.lock); } int intel_mce_wrmsr(u32 msr, u64 value) @@ -849,7 +839,7 @@ int intel_mce_wrmsr(u32 msr, u64 value) unsigned int bank; int ret = 1; - spin_lock(&mce_locks); + spin_lock(&d->arch.vmca_msrs.lock); switch(msr) { case MSR_IA32_MCG_CTL: @@ -924,7 +914,7 @@ int intel_mce_wrmsr(u32 msr, u64 value) ret = 0; break; } - spin_unlock(&mce_locks); + spin_unlock(&d->arch.vmca_msrs.lock); return ret; } @@ -936,7 +926,7 @@ int intel_mce_rdmsr(u32 msr, u32 *lo, u3 struct bank_entry *entry = NULL; *lo = *hi = 0x0; - spin_lock(&mce_locks); + spin_lock(&d->arch.vmca_msrs.lock); switch(msr) { case MSR_IA32_MCG_STATUS: @@ -1022,7 +1012,7 @@ int intel_mce_rdmsr(u32 msr, u32 *lo, u3 ret = 0; break; } - spin_unlock(&mce_locks); + spin_unlock(&d->arch.vmca_msrs.lock); return ret; } diff -r 19919f01f2c5 -r 8c806c66a597 xen/arch/x86/cpu/mcheck/mctelem.c --- a/xen/arch/x86/cpu/mcheck/mctelem.c Tue Apr 07 11:32:24 2009 +0900 +++ b/xen/arch/x86/cpu/mcheck/mctelem.c Tue Apr 14 14:04:58 2009 +0900 @@ -109,6 +109,14 @@ static struct mc_telem_ctl { * Telemetry array */ struct mctelem_ent *mctc_elems; + /* + * Per-CPU processing lists, used for deferred (softirq) + * processing of telemetry. mctc_cpu is indexed by the + * CPU that the telemetry belongs to. mctc_cpu_processing + * is indexed by the CPU that is processing the telemetry. + */ + struct mctelem_ent *mctc_cpu[NR_CPUS]; + struct mctelem_ent *mctc_cpu_processing[NR_CPUS]; } mctctl; /* Lock protecting all processing lists */ @@ -123,6 +131,82 @@ static void *cmpxchgptr(void *ptr, void return (void *)cmpxchg(ulp, a, b); } +static void mctelem_xchg_head(struct mctelem_ent **headp, + struct mctelem_ent **old, + struct mctelem_ent *new) +{ + for (;;) { + *old = *headp; + wmb(); + if (cmpxchgptr(headp, *old, new) == *old) + break; + } +} + + +void mctelem_defer(mctelem_cookie_t cookie) +{ + struct mctelem_ent *tep = COOKIE2MCTE(cookie); + + mctelem_xchg_head(&mctctl.mctc_cpu[smp_processor_id()], + &tep->mcte_next, tep); +} + +void mctelem_process_deferred(unsigned int cpu, + int (*fn)(unsigned int, mctelem_cookie_t)) +{ + struct mctelem_ent *tep; + struct mctelem_ent *head, *prev; + int ret; + + /* + * First, unhook the list of telemetry structures, and + * hook it up to the processing list head for this CPU. + */ + mctelem_xchg_head(&mctctl.mctc_cpu[cpu], + &mctctl.mctc_cpu_processing[smp_processor_id()], NULL); + + head = mctctl.mctc_cpu_processing[smp_processor_id()]; + + /* + * Then, fix up the list to include prev pointers, to make + * things a little easier, as the list must be traversed in + * chronological order, which is backward from the order they + * are in. + */ + for (tep = head, prev = NULL; tep != NULL; tep = tep->mcte_next) { + tep->mcte_prev = prev; + prev = tep; + } + + /* + * Now walk the list of telemetry structures, handling each + * one of them. Unhooking the structure here does not need to + * be atomic, as this list is only accessed from a softirq + * context; the MCE handler does not touch it. + */ + for (tep = prev; tep != NULL; tep = prev) { + prev = tep->mcte_prev; + tep->mcte_next = tep->mcte_prev = NULL; + + ret = fn(cpu, MCTE2COOKIE(tep)); + if (prev != NULL) + prev->mcte_next = NULL; + tep->mcte_prev = tep->mcte_next = NULL; + if (ret != 0) + mctelem_commit(MCTE2COOKIE(tep)); + else + mctelem_dismiss(MCTE2COOKIE(tep)); + } +} + +int mctelem_has_deferred(unsigned int cpu) +{ + if (mctctl.mctc_cpu[cpu] != NULL) + return 1; + return 0; +} + /* Free an entry to its native free list; the entry must not be linked on * any list. */ @@ -130,21 +214,12 @@ static void mctelem_free(struct mctelem_ { mctelem_class_t target = MCTE_HOME(tep) == MCTE_F_HOME_URGENT ? MC_URGENT : MC_NONURGENT; - struct mctelem_ent **freelp; - struct mctelem_ent *oldhead; BUG_ON(tep->mcte_refcnt != 0); BUG_ON(MCTE_STATE(tep) != MCTE_F_STATE_FREE); tep->mcte_prev = NULL; - freelp = &mctctl.mctc_free[target]; - for (;;) { - oldhead = *freelp; - tep->mcte_next = oldhead; - wmb(); - if (cmpxchgptr(freelp, oldhead, tep) == oldhead) - break; - } + mctelem_xchg_head(&mctctl.mctc_free[target], &tep->mcte_next, tep); } /* Increment the reference count of an entry that is not linked on to @@ -308,22 +383,13 @@ void mctelem_commit(mctelem_cookie_t coo void mctelem_commit(mctelem_cookie_t cookie) { struct mctelem_ent *tep = COOKIE2MCTE(cookie); - struct mctelem_ent **commlp; - struct mctelem_ent *oldhead; mctelem_class_t target = MCTE_CLASS(tep) == MCTE_F_CLASS_URGENT ? MC_URGENT : MC_NONURGENT; BUG_ON(tep->mcte_next != NULL || tep->mcte_prev != NULL); MCTE_TRANSITION_STATE(tep, UNCOMMITTED, COMMITTED); - commlp = &mctctl.mctc_committed[target]; - for (;;) { - oldhead = *commlp; - tep->mcte_prev = oldhead; - wmb(); - if (cmpxchgptr(commlp, oldhead, tep) == oldhead) - break; - } + mctelem_xchg_head(&mctctl.mctc_committed[target], &tep->mcte_prev, tep); } /* Move telemetry from committed list to processing list, reversing the @@ -358,13 +424,7 @@ static void mctelem_append_processing(mc * the list we unlink in a well-known location so it can be * picked up in panic code should we panic between this unlink * and the append to the processing list. */ - for (;;) { - dangling[target] = *commlp; - wmb(); - if (cmpxchgptr(commlp, dangling[target], NULL) == - dangling[target]) - break; - } + mctelem_xchg_head(commlp, &dangling[target], NULL); if (dangling[target] == NULL) return; diff -r 19919f01f2c5 -r 8c806c66a597 xen/arch/x86/cpu/mcheck/mctelem.h --- a/xen/arch/x86/cpu/mcheck/mctelem.h Tue Apr 07 11:32:24 2009 +0900 +++ b/xen/arch/x86/cpu/mcheck/mctelem.h Tue Apr 14 14:04:58 2009 +0900 @@ -67,5 +67,9 @@ extern mctelem_cookie_t mctelem_consume_ extern mctelem_cookie_t mctelem_consume_oldest_begin(mctelem_class_t); extern void mctelem_consume_oldest_end(mctelem_cookie_t); extern void mctelem_ack(mctelem_class_t, mctelem_cookie_t); +extern void mctelem_defer(mctelem_cookie_t); +extern void mctelem_process_deferred(unsigned int, + int (*)(unsigned int, mctelem_cookie_t)); +int mctelem_has_deferred(unsigned int); #endif diff -r 19919f01f2c5 -r 8c806c66a597 xen/arch/x86/hvm/emulate.c --- a/xen/arch/x86/hvm/emulate.c Tue Apr 07 11:32:24 2009 +0900 +++ b/xen/arch/x86/hvm/emulate.c Tue Apr 14 14:04:58 2009 +0900 @@ -18,6 +18,7 @@ #include <asm/event.h> #include <asm/hvm/emulate.h> #include <asm/hvm/hvm.h> +#include <asm/hvm/trace.h> #include <asm/hvm/support.h> #define HVMTRACE_IO_ASSIST_WRITE 0x200 @@ -749,6 +750,7 @@ static int hvmemul_read_cr( case 3: case 4: *val = current->arch.hvm_vcpu.guest_cr[reg]; + HVMTRACE_LONG_2D(CR_READ, reg, TRC_PAR_LONG(*val)); return X86EMUL_OKAY; default: break; @@ -762,6 +764,7 @@ static int hvmemul_write_cr( unsigned long val, struct x86_emulate_ctxt *ctxt) { + HVMTRACE_LONG_2D(CR_WRITE, reg, TRC_PAR_LONG(val)); switch ( reg ) { case 0: diff -r 19919f01f2c5 -r 8c806c66a597 xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Tue Apr 07 11:32:24 2009 +0900 +++ b/xen/arch/x86/hvm/hvm.c Tue Apr 14 14:04:58 2009 +0900 @@ -2377,6 +2377,9 @@ static int hvmop_flush_tlb_all(void) struct domain *d = current->domain; struct vcpu *v; + if ( !is_hvm_domain(d) ) + return -EINVAL; + /* Avoid deadlock if more than one vcpu tries this at the same time. */ if ( !spin_trylock(&d->hypercall_deadlock_mutex) ) return -EAGAIN; @@ -2413,6 +2416,7 @@ long do_hvm_op(unsigned long op, XEN_GUE long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg) { + struct domain *curr_d = current->domain; long rc = 0; switch ( op ) @@ -2477,8 +2481,9 @@ long do_hvm_op(unsigned long op, XEN_GUE rc = -EINVAL; break; case HVM_PARAM_IDENT_PT: + /* Not reflexive, as we must domain_pause(). */ rc = -EPERM; - if ( !IS_PRIV(current->domain) ) + if ( curr_d == d ) break; rc = -EINVAL; @@ -2488,30 +2493,33 @@ long do_hvm_op(unsigned long op, XEN_GUE rc = 0; if ( !paging_mode_hap(d) ) break; - - domain_pause(d); /* * Update GUEST_CR3 in each VMCS to point at identity map. * All foreign updates to guest state must synchronise on * the domctl_lock. */ - spin_lock(&domctl_lock); + rc = -EAGAIN; + if ( !domctl_lock_acquire() ) + break; + + rc = 0; + domain_pause(d); d->arch.hvm_domain.params[a.index] = a.value; for_each_vcpu ( d, v ) paging_update_cr3(v); - spin_unlock(&domctl_lock); - domain_unpause(d); + + domctl_lock_release(); break; case HVM_PARAM_DM_DOMAIN: - /* Privileged domains only, as we must domain_pause(d). */ + /* Not reflexive, as we must domain_pause(). */ rc = -EPERM; - if ( !IS_PRIV_FOR(current->domain, d) ) + if ( curr_d == d ) break; if ( a.value == DOMID_SELF ) - a.value = current->domain->domain_id; + a.value = curr_d->domain_id; rc = 0; domain_pause(d); /* safe to change per-vcpu xen_port */ @@ -2536,9 +2544,9 @@ long do_hvm_op(unsigned long op, XEN_GUE domain_unpause(d); break; case HVM_PARAM_ACPI_S_STATE: - /* Privileged domains only, as we must domain_pause(d). */ + /* Not reflexive, as we must domain_pause(). */ rc = -EPERM; - if ( !IS_PRIV_FOR(current->domain, d) ) + if ( curr_d == d ) break; rc = 0; diff -r 19919f01f2c5 -r 8c806c66a597 xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Tue Apr 07 11:32:24 2009 +0900 +++ b/xen/arch/x86/hvm/svm/svm.c Tue Apr 14 14:04:58 2009 +0900 @@ -1217,9 +1217,14 @@ asmlinkage void svm_vmexit_handler(struc exit_reason = vmcb->exitcode; - HVMTRACE_ND(VMEXIT64, 1/*cycles*/, 3, exit_reason, - (uint32_t)regs->eip, (uint32_t)((uint64_t)regs->eip >> 32), - 0, 0, 0); + if ( hvm_long_mode_enabled(v) ) + HVMTRACE_ND(VMEXIT64, 1/*cycles*/, 3, exit_reason, + (uint32_t)regs->eip, (uint32_t)((uint64_t)regs->eip >> 32), + 0, 0, 0); + else + HVMTRACE_ND(VMEXIT, 1/*cycles*/, 2, exit_reason, + (uint32_t)regs->eip, + 0, 0, 0, 0); if ( unlikely(exit_reason == VMEXIT_INVALID) ) { diff -r 19919f01f2c5 -r 8c806c66a597 xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Tue Apr 07 11:32:24 2009 +0900 +++ b/xen/arch/x86/hvm/vmx/vmx.c Tue Apr 14 14:04:58 2009 +0900 @@ -2241,9 +2241,14 @@ asmlinkage void vmx_vmexit_handler(struc exit_reason = __vmread(VM_EXIT_REASON); - HVMTRACE_ND(VMEXIT64, 1/*cycles*/, 3, exit_reason, - (uint32_t)regs->eip, (uint32_t)((uint64_t)regs->eip >> 32), - 0, 0, 0); + if ( hvm_long_mode_enabled(v) ) + HVMTRACE_ND(VMEXIT64, 1/*cycles*/, 3, exit_reason, + (uint32_t)regs->eip, (uint32_t)((uint64_t)regs->eip >> 32), + 0, 0, 0); + else + HVMTRACE_ND(VMEXIT, 1/*cycles*/, 2, exit_reason, + (uint32_t)regs->eip, + 0, 0, 0, 0); perfc_incra(vmexits, exit_reason); diff -r 19919f01f2c5 -r 8c806c66a597 xen/common/domctl.c --- a/xen/common/domctl.c Tue Apr 07 11:32:24 2009 +0900 +++ b/xen/common/domctl.c Tue Apr 14 14:04:58 2009 +0900 @@ -25,7 +25,7 @@ #include <public/domctl.h> #include <xsm/xsm.h> -DEFINE_SPINLOCK(domctl_lock); +static DEFINE_SPINLOCK(domctl_lock); extern long arch_do_domctl( struct xen_domctl *op, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl); @@ -188,6 +188,33 @@ static unsigned int default_vcpu0_locati return cpu; } +bool_t domctl_lock_acquire(void) +{ + /* + * Caller may try to pause its own VCPUs. We must prevent deadlock + * against other non-domctl routines which try to do the same. + */ + if ( !spin_trylock(¤t->domain->hypercall_deadlock_mutex) ) + return 0; + + /* + * Trylock here is paranoia if we have multiple privileged domains. Then + * we could have one domain trying to pause another which is spinning + * on domctl_lock -- results in deadlock. + */ + if ( spin_trylock(&domctl_lock) ) + return 1; + + spin_unlock(¤t->domain->hypercall_deadlock_mutex); + return 0; +} + +void domctl_lock_release(void) +{ + spin_unlock(&domctl_lock); + spin_unlock(¤t->domain->hypercall_deadlock_mutex); +} + long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) { long ret = 0; @@ -202,7 +229,9 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc if ( op->interface_version != XEN_DOMCTL_INTERFACE_VERSION ) return -EACCES; - spin_lock(&domctl_lock); + if ( !domctl_lock_acquire() ) + return hypercall_create_continuation( + __HYPERVISOR_domctl, "h", u_domctl); switch ( op->cmd ) { @@ -866,7 +895,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc break; } - spin_unlock(&domctl_lock); + domctl_lock_release(); return ret; } diff -r 19919f01f2c5 -r 8c806c66a597 xen/drivers/cpufreq/cpufreq_ondemand.c --- a/xen/drivers/cpufreq/cpufreq_ondemand.c Tue Apr 07 11:32:24 2009 +0900 +++ b/xen/drivers/cpufreq/cpufreq_ondemand.c Tue Apr 14 14:04:58 2009 +0900 @@ -178,7 +178,8 @@ static void do_dbs_timer(void *dbs) dbs_check_cpu(dbs_info); - set_timer(&dbs_timer[dbs_info->cpu], NOW()+dbs_tuners_ins.sampling_rate); + set_timer(&dbs_timer[dbs_info->cpu], + align_timer(NOW() , dbs_tuners_ins.sampling_rate)); } static void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) diff -r 19919f01f2c5 -r 8c806c66a597 xen/include/asm-x86/domain.h --- a/xen/include/asm-x86/domain.h Tue Apr 07 11:32:24 2009 +0900 +++ b/xen/include/asm-x86/domain.h Tue Apr 14 14:04:58 2009 +0900 @@ -226,6 +226,7 @@ struct domain_mca_msrs uint64_t mci_ctl[MAX_NR_BANKS]; uint16_t nr_injection; struct list_head impact_header; + spinlock_t lock; }; struct arch_domain diff -r 19919f01f2c5 -r 8c806c66a597 xen/include/xen/domain.h --- a/xen/include/xen/domain.h Tue Apr 07 11:32:24 2009 +0900 +++ b/xen/include/xen/domain.h Tue Apr 14 14:04:58 2009 +0900 @@ -58,6 +58,9 @@ void arch_dump_domain_info(struct domain void arch_vcpu_reset(struct vcpu *v); +bool_t domctl_lock_acquire(void); +void domctl_lock_release(void); + extern unsigned int xen_processor_pmbits; #endif /* __XEN_DOMAIN_H__ */ diff -r 19919f01f2c5 -r 8c806c66a597 xen/include/xen/hypercall.h --- a/xen/include/xen/hypercall.h Tue Apr 07 11:32:24 2009 +0900 +++ b/xen/include/xen/hypercall.h Tue Apr 14 14:04:58 2009 +0900 @@ -30,7 +30,6 @@ do_sched_op( int cmd, XEN_GUEST_HANDLE(void) arg); -extern spinlock_t domctl_lock; extern long do_domctl( XEN_GUEST_HANDLE(xen_domctl_t) u_domctl); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |