aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIsaku Yamahata <yamahata@valinux.co.jp>2009-04-14 14:04:58 +0900
committerIsaku Yamahata <yamahata@valinux.co.jp>2009-04-14 14:04:58 +0900
commitf008a3fb0a9d2dd6fc6fc6da2c2eec4ea9d1a94a (patch)
tree93070d7a1688134e46ef02b3b585d99b1f8ebb64
parent58d538d2f6428d11f40d54feb005901d4deee08e (diff)
parent8687956ca3d330b9a77e2420e4a6b7125ad37e3b (diff)
downloadxen-f008a3fb0a9d2dd6fc6fc6da2c2eec4ea9d1a94a.tar.gz
xen-f008a3fb0a9d2dd6fc6fc6da2c2eec4ea9d1a94a.tar.bz2
xen-f008a3fb0a9d2dd6fc6fc6da2c2eec4ea9d1a94a.zip
merge with xen-unstable.hg
-rw-r--r--.hgtags1
-rw-r--r--Config.mk4
-rw-r--r--Makefile6
-rw-r--r--tools/hotplug/Linux/network-nat6
-rw-r--r--tools/libxc/xc_domain_restore.c2
-rw-r--r--tools/misc/sbdf2devicepath82
-rw-r--r--tools/misc/sxp-pretty8
-rw-r--r--tools/misc/xen-bugtool3
-rw-r--r--tools/misc/xen-python-path31
-rw-r--r--tools/misc/xend8
-rwxr-xr-xtools/misc/xm3
-rw-r--r--tools/misc/xsview2
-rw-r--r--tools/pygrub/Makefile10
-rw-r--r--tools/pygrub/src/pygrub2
-rw-r--r--tools/python/Makefile9
-rw-r--r--tools/python/scripts/test_hvm_create.py1
-rw-r--r--tools/python/scripts/test_vm_create.py1
-rw-r--r--tools/python/scripts/xapi.py1
-rw-r--r--tools/python/xen/util/auxbin.py6
-rw-r--r--tools/python/xen/xend/XendConfig.py6
-rw-r--r--tools/python/xen/xend/XendDomainInfo.py200
-rw-r--r--tools/python/xen/xend/server/pciif.py22
-rw-r--r--tools/python/xen/xm/create.dtd2
-rw-r--r--tools/python/xen/xm/main.py24
-rw-r--r--tools/python/xen/xm/xenapi_create.py4
-rw-r--r--tools/security/Makefile10
-rw-r--r--tools/security/python/xensec_tools/acm_getlabel4
-rw-r--r--tools/security/xensec_gen.py4
-rwxr-xr-xtools/sv/index.psp1
-rw-r--r--tools/vnet/scripts/vn3
-rw-r--r--tools/xenpmd/Makefile3
-rw-r--r--xen/Makefile2
-rw-r--r--xen/arch/x86/acpi/cpu_idle.c4
-rw-r--r--xen/arch/x86/cpu/mcheck/mce.c59
-rw-r--r--xen/arch/x86/cpu/mcheck/mce.h5
-rw-r--r--xen/arch/x86/cpu/mcheck/mce_intel.c446
-rw-r--r--xen/arch/x86/cpu/mcheck/mctelem.c114
-rw-r--r--xen/arch/x86/cpu/mcheck/mctelem.h4
-rw-r--r--xen/arch/x86/hvm/emulate.c3
-rw-r--r--xen/arch/x86/hvm/hvm.c30
-rw-r--r--xen/arch/x86/hvm/svm/svm.c11
-rw-r--r--xen/arch/x86/hvm/vmx/vmx.c11
-rw-r--r--xen/common/domctl.c35
-rw-r--r--xen/drivers/cpufreq/cpufreq_ondemand.c3
-rw-r--r--xen/include/asm-x86/domain.h1
-rw-r--r--xen/include/xen/domain.h3
-rw-r--r--xen/include/xen/hypercall.h1
47 files changed, 695 insertions, 506 deletions
diff --git a/.hgtags b/.hgtags
index 2cc3fba529..f8eaf2c121 100644
--- a/.hgtags
+++ b/.hgtags
@@ -33,3 +33,4 @@ b4dba6a0e97cb6dd080fa566468e3cc972c34d7a 3.3.0-rc5
bc372510f1794ee41a8b0501cc84f8a65d05e094 3.3.0-rc6
daf1193bcd11345d566a4747fe1f12c90b44452c 3.3.0-rc7
1e99ba54035623731bc7318a8357aa6a118c5da1 3.3.0-branched
+d611d9ac6d0271b53eb1d4e5d0c4ef20b269eea8 3.4.0-rc1
diff --git a/Config.mk b/Config.mk
index 2cdc7660e3..c1aa25ccd2 100644
--- a/Config.mk
+++ b/Config.mk
@@ -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 --git a/Makefile b/Makefile
index 131ab3d1a3..237c107ff0 100644
--- a/Makefile
+++ b/Makefile
@@ -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 --git a/tools/hotplug/Linux/network-nat b/tools/hotplug/Linux/network-nat
index d9c62c6160..aab793d93f 100644
--- a/tools/hotplug/Linux/network-nat
+++ b/tools/hotplug/Linux/network-nat
@@ -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 --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c
index 4f92ebb549..32782e1888 100644
--- a/tools/libxc/xc_domain_restore.c
+++ b/tools/libxc/xc_domain_restore.c
@@ -1197,7 +1197,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
* 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 --git a/tools/misc/sbdf2devicepath b/tools/misc/sbdf2devicepath
new file mode 100644
index 0000000000..690834adf5
--- /dev/null
+++ b/tools/misc/sbdf2devicepath
@@ -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 --git a/tools/misc/sxp-pretty b/tools/misc/sxp-pretty
index 4b8eaed335..dd642b088e 100644
--- a/tools/misc/sxp-pretty
+++ b/tools/misc/sxp-pretty
@@ -23,14 +23,6 @@ import os.path
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 --git a/tools/misc/xen-bugtool b/tools/misc/xen-bugtool
index cf41c8c957..a3742b4787 100644
--- a/tools/misc/xen-bugtool
+++ b/tools/misc/xen-bugtool
@@ -6,9 +6,6 @@
import sys
-sys.path.append('/usr/lib/python')
-sys.path.append('/usr/lib64/python')
-
from xen.util import bugtool
diff --git a/tools/misc/xen-python-path b/tools/misc/xen-python-path
index 57774a332b..073abaef53 100644
--- a/tools/misc/xen-python-path
+++ b/tools/misc/xen-python-path
@@ -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 --git a/tools/misc/xend b/tools/misc/xend
index 2cbdf6175c..4dd550bbed 100644
--- a/tools/misc/xend
+++ b/tools/misc/xend
@@ -33,14 +33,6 @@ 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
class CheckError(ValueError):
diff --git a/tools/misc/xm b/tools/misc/xm
index 80972ccef9..f4fd200346 100755
--- a/tools/misc/xm
+++ b/tools/misc/xm
@@ -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 --git a/tools/misc/xsview b/tools/misc/xsview
index c6726554b7..f926fe4fc6 100644
--- a/tools/misc/xsview
+++ b/tools/misc/xsview
@@ -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 --git a/tools/pygrub/Makefile b/tools/pygrub/Makefile
index 48e982c075..0791012e2a 100644
--- a/tools/pygrub/Makefile
+++ b/tools/pygrub/Makefile
@@ -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 --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub
index e43dcc2d9a..095db5e72c 100644
--- a/tools/pygrub/src/pygrub
+++ b/tools/pygrub/src/pygrub
@@ -21,8 +21,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
import grub.LiloConf
diff --git a/tools/python/Makefile b/tools/python/Makefile
index 249bf634e7..cbc3973d02 100644
--- a/tools/python/Makefile
+++ b/tools/python/Makefile
@@ -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 --git a/tools/python/scripts/test_hvm_create.py b/tools/python/scripts/test_hvm_create.py
index 35abfe0396..50203635da 100644
--- a/tools/python/scripts/test_hvm_create.py
+++ b/tools/python/scripts/test_hvm_create.py
@@ -74,7 +74,6 @@ console_cfg = {
import sys
import time
-sys.path.append('/usr/lib/python')
from xapi import connect, execute
diff --git a/tools/python/scripts/test_vm_create.py b/tools/python/scripts/test_vm_create.py
index 6575f153ea..9ac8a6eee2 100644
--- a/tools/python/scripts/test_vm_create.py
+++ b/tools/python/scripts/test_vm_create.py
@@ -93,7 +93,6 @@ console_cfg = {
import sys
import time
-sys.path.append('/usr/lib/python')
from xapi import connect, execute
diff --git a/tools/python/scripts/xapi.py b/tools/python/scripts/xapi.py
index 1a07795212..9530f4a151 100644
--- a/tools/python/scripts/xapi.py
+++ b/tools/python/scripts/xapi.py
@@ -20,7 +20,6 @@ import sys
import time
import re
import os
-sys.path.append('/usr/lib/python')
from xen.util.xmlrpclib2 import ServerProxy
from optparse import *
diff --git a/tools/python/xen/util/auxbin.py b/tools/python/xen/util/auxbin.py
index 75e38a838e..e1830001bb 100644
--- a/tools/python/xen/util/auxbin.py
+++ b/tools/python/xen/util/auxbin.py
@@ -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 --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py
index e195ab1060..591a22ddea 100644
--- a/tools/python/xen/xend/XendConfig.py
+++ b/tools/python/xen/xend/XendConfig.py
@@ -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 --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py
index 644831b87d..4244a542b8 100644
--- a/tools/python/xen/xend/XendDomainInfo.py
+++ b/tools/python/xen/xend/XendDomainInfo.py
@@ -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))
+ " assigned to other domain." \
+ )% (pci_device.name, self.info['name_label'], 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)
+ 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'],
+ 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)
+ 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)
+ # 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)
- 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)
+ # 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]
+ 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 --git a/tools/python/xen/xend/server/pciif.py b/tools/python/xen/xend/server/pciif.py
index 1b183884e3..1579262459 100644
--- a/tools/python/xen/xend/server/pciif.py
+++ b/tools/python/xen/xend/server/pciif.py
@@ -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))
@@ -83,10 +87,6 @@ class PciController(DevController):
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)
back['uuid-%i' % pcidevid] = pci_config.get('uuid', '')
@@ -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 --git a/tools/python/xen/xm/create.dtd b/tools/python/xen/xm/create.dtd
index d3010b6248..693d27e6ef 100644
--- a/tools/python/xen/xm/create.dtd
+++ b/tools/python/xen/xm/create.dtd
@@ -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 --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py
index b3cfecb448..a7b375dafa 100644
--- a/tools/python/xen/xm/main.py
+++ b/tools/python/xen/xm/main.py
@@ -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, opts = ''):
dom = args[0]
pci_dev_str = args[1]
if len(args) == 3:
- vslt = args[2]
+ vslot = args[2]
else:
- vslt = AUTO_PHP_SLOT_STR
+ 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, opts = ''):
['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 --git a/tools/python/xen/xm/xenapi_create.py b/tools/python/xen/xm/xenapi_create.py
index b66afaf414..0deced5063 100644
--- a/tools/python/xen/xm/xenapi_create.py
+++ b/tools/python/xen/xm/xenapi_create.py
@@ -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 --git a/tools/security/Makefile b/tools/security/Makefile
index 61062715a2..996e96599a 100644
--- a/tools/security/Makefile
+++ b/tools/security/Makefile
@@ -40,9 +40,6 @@ ifeq ($(ACM_SECURITY),y)
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 --git a/tools/security/python/xensec_tools/acm_getlabel b/tools/security/python/xensec_tools/acm_getlabel
index 63137a9993..8d5fe22461 100644
--- a/tools/security/python/xensec_tools/acm_getlabel
+++ b/tools/security/python/xensec_tools/acm_getlabel
@@ -4,10 +4,6 @@ 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
# getopt.gnu_getopt is better, but only exists in Python 2.3+. Use
diff --git a/tools/security/xensec_gen.py b/tools/security/xensec_gen.py
index 8f65b4cf1a..d531777660 100644
--- a/tools/security/xensec_gen.py
+++ b/tools/security/xensec_gen.py
@@ -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 --git a/tools/sv/index.psp b/tools/sv/index.psp
index 192aff84fa..829d468db4 100755
--- a/tools/sv/index.psp
+++ b/tools/sv/index.psp
@@ -1,6 +1,5 @@
<%
import sys
-sys.path.append( "/usr/lib/python" )
debug = True and False
diff --git a/tools/vnet/scripts/vn b/tools/vnet/scripts/vn
index 8e8e224d4b..4a4281f6f1 100644
--- a/tools/vnet/scripts/vn
+++ b/tools/vnet/scripts/vn
@@ -27,9 +27,6 @@ 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 --git a/tools/xenpmd/Makefile b/tools/xenpmd/Makefile
index 7e9353bfb0..10cb2fb211 100644
--- a/tools/xenpmd/Makefile
+++ b/tools/xenpmd/Makefile
@@ -19,4 +19,7 @@ install: all
clean:
$(RM) -f $(BIN) $(DEPS)
+%: %.c Makefile
+ $(CC) $(CFLAGS) $< $(LDFLAGS) -o $@
+
-include $(DEPS)
diff --git a/xen/Makefile b/xen/Makefile
index d16477a6a5..da3811dcb0 100644
--- a/xen/Makefile
+++ b/xen/Makefile
@@ -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 --git a/xen/arch/x86/acpi/cpu_idle.c b/xen/arch/x86/acpi/cpu_idle.c
index 40263873e8..a7ca18826e 100644
--- a/xen/arch/x86/acpi/cpu_idle.c
+++ b/xen/arch/x86/acpi/cpu_idle.c
@@ -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 xen_processor_power *power)
/* 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 --git a/xen/arch/x86/cpu/mcheck/mce.c b/xen/arch/x86/cpu/mcheck/mce.c
index a43f2f131a..49f3f84899 100644
--- a/xen/arch/x86/cpu/mcheck/mce.c
+++ b/xen/arch/x86/cpu/mcheck/mce.c
@@ -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)
+#if 0
+static int x86_mcerr(const char *msg, int err)
{
- printk("x86_mcerr: %s, returning %d\n",
- msg != NULL ? msg : "", err);
- return 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 mca_source who, cpu_banks_t bankmask,
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 mca_source who, cpu_banks_t bankmask,
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_xen_mc)
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);
@@ -1075,10 +1093,6 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u_xen_mc)
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:
which = MC_NONURGENT;
@@ -1134,9 +1148,6 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u_xen_mc)
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_xen_mc)
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_xen_mc)
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_xen_mc)
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_x86 *c)
}
void mc_panic(char *s)
{
+ is_mc_panic = 1;
console_start_sync();
printk("Fatal machine check: %s\n", s);
printk("\n"
diff --git a/xen/arch/x86/cpu/mcheck/mce.h b/xen/arch/x86/cpu/mcheck/mce.h
index 6b79e673e2..044d11a3e4 100644
--- a/xen/arch/x86/cpu/mcheck/mce.h
+++ b/xen/arch/x86/cpu/mcheck/mce.h
@@ -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 @@ void set_poll_bankmask(struct cpuinfo_x86 *c);
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 --git a/xen/arch/x86/cpu/mcheck/mce_intel.c b/xen/arch/x86/cpu/mcheck/mce_intel.c
index 67d0342d99..6bf8c87add 100644
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c
@@ -18,6 +18,29 @@ int cmci_support = 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_msr(struct mcinfo_extended *ext, u32 msr)
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 *mci, uint16_t bank, uint64_t status)
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, struct mcinfo_bank *mc_bank,
}
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, struct mcinfo_bank *mc_bank,
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;
+ 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;
+ }
- /* Processing bank information */
- x86_mcinfo_lookup(mic, local_mi, MC_TYPE_BANK);
+ mc_global = (struct mcinfo_global *)mic;
- 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;
- }
+ /* Processing bank information */
+ x86_mcinfo_lookup(mic, local_mi, MC_TYPE_BANK);
- /* TODO: Add recovery actions here, such as page-offline, etc */
+ for ( ; mic && mic->size; mic = x86_mcinfo_next(mic) ) {
+ if (mic->type != MC_TYPE_BANK) {
+ continue;
}
- } /* end of impact_map loop */
-
- ret = 0;
-
-end:
+ 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;
- 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");
- }
+ /* TODO: Add recovery actions here, such as page-offline, etc */
}
- test_and_clear_bool(mc_local.in_use);
- spin_unlock(&mce_locks);
- return ret;
+ 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)
+static void mce_barrier_init(struct mce_softirq_barrier *bar)
{
- uint64_t status;
- int32_t i;
+ atomic_set(&bar->val, 0);
+ atomic_set(&bar->ingen, 0);
+ atomic_set(&bar->outgen, 0);
+}
- /* 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");
- }
+#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
- /* 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_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();
+ mce_spin_lock(&mce_logout_lock);
- 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;
- }
+ mctc = mcheck_mca_logout(MCA_MCE_SCAN, mca_allbanks, &bs);
- /* 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) {
+ 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);
+ mce_spin_unlock(&mce_logout_lock);
- 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);
+ /*
+ * Wait until everybody has processed the trap.
+ */
+ mce_barrier(&mce_trap_bar);
- 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)) {
+ /*
+ * 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, u32 *hi)
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, u32 *hi)
ret = 0;
break;
}
- spin_unlock(&mce_locks);
+ spin_unlock(&d->arch.vmca_msrs.lock);
return ret;
}
diff --git a/xen/arch/x86/cpu/mcheck/mctelem.c b/xen/arch/x86/cpu/mcheck/mctelem.c
index 4111ddcbb7..d8dd482bc6 100644
--- a/xen/arch/x86/cpu/mcheck/mctelem.c
+++ b/xen/arch/x86/cpu/mcheck/mctelem.c
@@ -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 *old, void *new)
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_ent *tep)
{
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_dismiss(mctelem_cookie_t cookie)
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(mctelem_class_t which)
* 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 --git a/xen/arch/x86/cpu/mcheck/mctelem.h b/xen/arch/x86/cpu/mcheck/mctelem.h
index e3270f606c..fb381a10a0 100644
--- a/xen/arch/x86/cpu/mcheck/mctelem.h
+++ b/xen/arch/x86/cpu/mcheck/mctelem.h
@@ -67,5 +67,9 @@ extern void mctelem_dismiss(mctelem_cookie_t);
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 --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
index 6fbce84e90..2166e88a34 100644
--- a/xen/arch/x86/hvm/emulate.c
+++ b/xen/arch/x86/hvm/emulate.c
@@ -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 --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 9a6d6cd5a1..82b99ab761 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -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 @@ static int hvmop_flush_tlb_all(void)
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_GUEST_HANDLE(void) arg)
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;
@@ -2489,29 +2494,32 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
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_GUEST_HANDLE(void) arg)
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 --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index bd320fbe1f..a70f0ffd95 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1217,9 +1217,14 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
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 --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 3374ebb657..2d4c44bd63 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -2241,9 +2241,14 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
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 --git a/xen/common/domctl.c b/xen/common/domctl.c
index 23c2f4e529..4a8df90101 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -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_location(void)
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(&current->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(&current->domain->hypercall_deadlock_mutex);
+ return 0;
+}
+
+void domctl_lock_release(void)
+{
+ spin_unlock(&domctl_lock);
+ spin_unlock(&current->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_domctl_t) u_domctl)
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_domctl_t) u_domctl)
break;
}
- spin_unlock(&domctl_lock);
+ domctl_lock_release();
return ret;
}
diff --git a/xen/drivers/cpufreq/cpufreq_ondemand.c b/xen/drivers/cpufreq/cpufreq_ondemand.c
index b01312d9af..74dd74ea0e 100644
--- a/xen/drivers/cpufreq/cpufreq_ondemand.c
+++ b/xen/drivers/cpufreq/cpufreq_ondemand.c
@@ -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 --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 2bf5b1c823..8508a1d946 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -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 --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h
index 65df554421..282e5665d0 100644
--- a/xen/include/xen/domain.h
+++ b/xen/include/xen/domain.h
@@ -58,6 +58,9 @@ void arch_dump_domain_info(struct domain *d);
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 --git a/xen/include/xen/hypercall.h b/xen/include/xen/hypercall.h
index 99d2e0008a..43758b9de8 100644
--- a/xen/include/xen/hypercall.h
+++ b/xen/include/xen/hypercall.h
@@ -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);