WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] Merge

# HG changeset patch
# User Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
# Date 1175071448 0
# Node ID 81fec499a9831370e40aa39a18b5f906b7c67ff0
# Parent  bc2811bf7771698852aa96e6c4c6b19f02cb9d05
# Parent  a138ae831515e2ef86922210b362c36589675a9c
Merge
---
 Config.mk                                              |   14 -
 linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S    |   16 -
 linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c |    2 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c   |   18 -
 tools/Rules.mk                                         |    6 
 tools/examples/xend-config.sxp                         |   14 -
 tools/ioemu/Makefile.target                            |    4 
 tools/ioemu/vnc.c                                      |   13 
 tools/python/xen/util/xmlrpcclient.py                  |  122 +++++++++
 tools/python/xen/util/xmlrpclib2.py                    |   70 -----
 tools/python/xen/xend/XendAPI.py                       |   45 +--
 tools/python/xen/xend/XendClient.py                    |    2 
 tools/python/xen/xend/XendConfig.py                    |   11 
 tools/python/xen/xend/XendDomain.py                    |   20 +
 tools/python/xen/xend/XendDomainInfo.py                |    5 
 tools/python/xen/xend/XendLogging.py                   |    1 
 tools/python/xen/xend/XendMonitor.py                   |   16 -
 tools/python/xen/xend/XendOptions.py                   |    8 
 tools/python/xen/xend/server/SSLXMLRPCServer.py        |  103 +++++++
 tools/python/xen/xend/server/SrvServer.py              |  100 +++++--
 tools/python/xen/xend/server/XMLRPCServer.py           |   51 +++
 tools/python/xen/xm/XenAPI.py                          |   13 
 tools/python/xen/xm/create.py                          |    2 
 tools/python/xen/xm/main.py                            |    2 
 xen/acm/acm_policy.c                                   |   24 +
 xen/arch/ia64/asm-offsets.c                            |    9 
 xen/arch/ia64/linux-xen/irq_ia64.c                     |    2 
 xen/arch/ia64/linux-xen/mca.c                          |   10 
 xen/arch/ia64/linux-xen/smp.c                          |    2 
 xen/arch/ia64/vmx/pal_emul.c                           |    2 
 xen/arch/ia64/vmx/vmx_process.c                        |    2 
 xen/arch/ia64/vmx/vmx_virt.c                           |   78 ++---
 xen/arch/ia64/xen/dom0_ops.c                           |    4 
 xen/arch/ia64/xen/domain.c                             |    8 
 xen/arch/ia64/xen/faults.c                             |    2 
 xen/arch/ia64/xen/hypercall.c                          |    4 
 xen/arch/ia64/xen/hyperprivop.S                        |   13 
 xen/arch/ia64/xen/mm.c                                 |   26 -
 xen/arch/ia64/xen/privop.c                             |   30 +-
 xen/arch/ia64/xen/privop_stat.c                        |   86 +++---
 xen/arch/ia64/xen/tlb_track.c                          |   42 +--
 xen/arch/ia64/xen/vcpu.c                               |   10 
 xen/arch/ia64/xen/vhpt.c                               |   30 +-
 xen/arch/powerpc/backtrace.c                           |   15 -
 xen/arch/powerpc/mm.c                                  |    2 
 xen/arch/x86/Rules.mk                                  |    4 
 xen/arch/x86/apic.c                                    |    2 
 xen/arch/x86/extable.c                                 |    2 
 xen/arch/x86/hvm/io.c                                  |   28 +-
 xen/arch/x86/hvm/svm/intr.c                            |  124 ++++-----
 xen/arch/x86/hvm/svm/svm.c                             |   24 -
 xen/arch/x86/hvm/svm/vmcb.c                            |    1 
 xen/arch/x86/hvm/vmx/intr.c                            |   35 --
 xen/arch/x86/irq.c                                     |    2 
 xen/arch/x86/mm.c                                      |   34 +-
 xen/arch/x86/mm/shadow/common.c                        |   40 +--
 xen/arch/x86/mm/shadow/multi.c                         |   56 ++--
 xen/arch/x86/smp.c                                     |    6 
 xen/arch/x86/time.c                                    |   22 -
 xen/arch/x86/traps.c                                   |   26 +
 xen/arch/x86/x86_32/asm-offsets.c                      |   14 -
 xen/arch/x86/x86_32/domain_page.c                      |    6 
 xen/arch/x86/x86_32/entry.S                            |    4 
 xen/arch/x86/x86_32/seg_fixup.c                        |    2 
 xen/arch/x86/x86_64/asm-offsets.c                      |   26 -
 xen/arch/x86/x86_64/compat/entry.S                     |    2 
 xen/arch/x86/x86_64/entry.S                            |    4 
 xen/arch/x86/x86_emulate.c                             |   12 
 xen/common/domain.c                                    |    4 
 xen/common/multicall.c                                 |    5 
 xen/common/page_alloc.c                                |    2 
 xen/common/perfc.c                                     |  223 ++++++++---------
 xen/common/schedule.c                                  |   13 
 xen/drivers/char/console.c                             |   10 
 xen/include/asm-ia64/bug.h                             |    1 
 xen/include/asm-ia64/linux-xen/asm/asmmacro.h          |    4 
 xen/include/asm-ia64/linux-xen/asm/iosapic.h           |    7 
 xen/include/asm-ia64/perfc_defn.h                      |  214 ++++++++--------
 xen/include/asm-ia64/privop_stat.h                     |   25 -
 xen/include/asm-ia64/tlb_track.h                       |    4 
 xen/include/asm-powerpc/bug.h                          |    1 
 xen/include/asm-powerpc/debugger.h                     |    4 
 xen/include/asm-x86/bug.h                              |    6 
 xen/include/asm-x86/hvm/svm/vmcb.h                     |    1 
 xen/include/asm-x86/multicall.h                        |  104 ++++---
 xen/include/asm-x86/perfc_defn.h                       |  126 ++++-----
 xen/include/asm-x86/x86_32/asm_defns.h                 |   12 
 xen/include/asm-x86/x86_32/bug.h                       |    6 
 xen/include/asm-x86/x86_64/asm_defns.h                 |   19 -
 xen/include/asm-x86/x86_64/bug.h                       |    6 
 xen/include/public/foreign/Makefile                    |    4 
 xen/include/xen/lib.h                                  |    4 
 xen/include/xen/perfc.h                                |  120 +++------
 xen/include/xen/perfc_defn.h                           |   15 -
 94 files changed, 1382 insertions(+), 1093 deletions(-)

diff -r bc2811bf7771 -r 81fec499a983 Config.mk
--- a/Config.mk Wed Mar 28 08:40:42 2007 +0000
+++ b/Config.mk Wed Mar 28 08:44:08 2007 +0000
@@ -31,16 +31,26 @@ EXTRA_LIB += $(EXTRA_PREFIX)/$(LIBDIR)
 EXTRA_LIB += $(EXTRA_PREFIX)/$(LIBDIR)
 endif
 
-# cc-option
+# cc-option: Check if compiler supports first option, else fall back to second.
 # Usage: cflags-y += $(call cc-option,$(CC),-march=winchip-c6,-march=i586)
 cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \
               /dev/null 2>&1`"; then echo "$(2)"; else echo "$(3)"; fi ;)
 
-# cc-ver
+# cc-ver: Check compiler is at least specified version. Return boolean 'y'/'n'.
 # Usage: ifeq ($(call cc-ver,$(CC),0x030400),y)
 cc-ver = $(shell if [ $$((`$(1) -dumpversion | awk -F. \
            '{ printf "0x%02x%02x%02x", $$1, $$2, $$3}'`)) -ge $$(($(2))) ]; \
            then echo y; else echo n; fi ;)
+
+# cc-ver-check: Check compiler is at least specified version, else fail.
+# Usage: $(call cc-ver-check,CC,0x030400,"Require at least gcc-3.4")
+cc-ver-check = $(eval $(call cc-ver-check-closure,$(1),$(2),$(3)))
+define cc-ver-check-closure
+    ifeq ($$(call cc-ver,$$($(1)),$(2)),n)
+        override $(1) = echo "*** FATAL BUILD ERROR: "$(3) >&2; exit 1;
+        cc-option := n
+    endif
+endef
 
 ifneq ($(debug),y)
 CFLAGS += -DNDEBUG
diff -r bc2811bf7771 -r 81fec499a983 
linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S       Wed Mar 28 
08:40:42 2007 +0000
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S       Wed Mar 28 
08:44:08 2007 +0000
@@ -148,11 +148,11 @@ NMI_MASK = 0x80000000
        .endm
 
         /*
-         * Must be consistent with the definition in arch-x86_64.h:    
+         * Must be consistent with the definition in arch-x86/xen-x86_64.h:
          *     struct iret_context {
          *        u64 rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
          *     };
-         * #define VGCF_IN_SYSCALL (1<<8) 
+         * with rax, r11, and rcx being taken care of in the hypercall stub.
          */
        .macro HYPERVISOR_IRET flag
        testb $3,1*8(%rsp)
@@ -164,21 +164,15 @@ NMI_MASK = 0x80000000
        jnz   1f
 
        /* Direct iret to kernel space. Correct CS and SS. */
-       orb   $3,1*8(%rsp)
-       orb   $3,4*8(%rsp)
+       orl   $3,1*8(%rsp)
+       orl   $3,4*8(%rsp)
 1:     iretq
 
 2:     /* Slow iret via hypervisor. */
-       andl  $~NMI_MASK, 16(%rsp)
+       andl  $~NMI_MASK, 2*8(%rsp)
        pushq $\flag
        jmp  hypercall_page + (__HYPERVISOR_iret * 32)
        .endm
-
-        .macro SWITCH_TO_KERNEL ssoff,adjust=0
-       jc  1f
-       orb  $1,\ssoff-\adjust+4(%rsp)
-1:
-        .endm
 
 /*
  * A newly forked process directly context switches into this.
diff -r bc2811bf7771 -r 81fec499a983 
linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c    Wed Mar 28 
08:40:42 2007 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c    Wed Mar 28 
08:44:08 2007 +0000
@@ -123,7 +123,7 @@ static int take_machine_down(void *p_fas
 static int take_machine_down(void *p_fast_suspend)
 {
        int fast_suspend = *(int *)p_fast_suspend;
-       int suspend_cancelled, err, cpu;
+       int suspend_cancelled, err;
        extern void time_resume(void);
 
        if (fast_suspend) {
diff -r bc2811bf7771 -r 81fec499a983 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      Wed Mar 28 
08:40:42 2007 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      Wed Mar 28 
08:44:08 2007 +0000
@@ -236,7 +236,10 @@ static ssize_t xenbus_dev_write(struct f
                break;
 
        case XS_WATCH:
-       case XS_UNWATCH:
+       case XS_UNWATCH: {
+               static const char *XS_RESP = "OK";
+               struct xsd_sockmsg hdr;
+
                path = u->u.buffer + sizeof(u->u.msg);
                token = memchr(path, 0, u->u.msg.len);
                if (token == NULL) {
@@ -246,9 +249,6 @@ static ssize_t xenbus_dev_write(struct f
                token++;
 
                if (msg_type == XS_WATCH) {
-                       static const char * XS_WATCH_RESP = "OK";
-                       struct xsd_sockmsg hdr;
-
                        watch = kmalloc(sizeof(*watch), GFP_KERNEL);
                        watch->watch.node = kmalloc(strlen(path)+1,
                                                     GFP_KERNEL);
@@ -266,11 +266,6 @@ static ssize_t xenbus_dev_write(struct f
                        }
                        
                        list_add(&watch->list, &u->watches);
-
-                       hdr.type = XS_WATCH;
-                       hdr.len = strlen(XS_WATCH_RESP) + 1;
-                       queue_reply(u, (char *)&hdr, sizeof(hdr));
-                       queue_reply(u, (char *)XS_WATCH_RESP, hdr.len);
                } else {
                        list_for_each_entry_safe(watch, tmp_watch,
                                                  &u->watches, list) {
@@ -285,7 +280,12 @@ static ssize_t xenbus_dev_write(struct f
                        }
                }
 
+               hdr.type = msg_type;
+               hdr.len = strlen(XS_RESP) + 1;
+               queue_reply(u, (char *)&hdr, sizeof(hdr));
+               queue_reply(u, (char *)XS_RESP, hdr.len);
                break;
+       }
 
        default:
                rc = -EINVAL;
diff -r bc2811bf7771 -r 81fec499a983 tools/Rules.mk
--- a/tools/Rules.mk    Wed Mar 28 08:40:42 2007 +0000
+++ b/tools/Rules.mk    Wed Mar 28 08:44:08 2007 +0000
@@ -24,9 +24,9 @@ CFLAGS += $(CFLAGS-y)
 CFLAGS += $(CFLAGS-y)
 
 # Require GCC v3.4+ (to avoid issues with alignment constraints in Xen headers)
-ifeq ($(CONFIG_X86)$(call cc-ver,$(CC),0x030400),yn)
-$(error Xen tools require at least gcc-3.4)
-endif
+check-$(CONFIG_X86) = $(call cc-ver-check,CC,0x030400,\
+                        "Xen requires at least gcc-3.4")
+$(eval $(check-y))
 
 %.opic: %.c
        $(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $<
diff -r bc2811bf7771 -r 81fec499a983 tools/examples/xend-config.sxp
--- a/tools/examples/xend-config.sxp    Wed Mar 28 08:40:42 2007 +0000
+++ b/tools/examples/xend-config.sxp    Wed Mar 28 08:44:08 2007 +0000
@@ -46,6 +46,11 @@
 #   (xen-api-server ((9363 pam '^localhost$ example\\.com$')
 #                    (unix none)))
 #
+# Optionally, the TCP Xen-API server can use SSL by specifying the private
+# key and certificate location:
+#
+#                    (9367 pam '' /etc/xen/xen-api.key /etc/xen/xen-api.crt)
+#
 # Default:
 #   (xen-api-server ((unix)))
 
@@ -59,10 +64,17 @@
 
 #(xend-unix-path /var/lib/xend/xend-socket)
 
-# Address and port xend should use for the TCP XMLRPC interface, 
+
+# Address and port xend should use for the legacy TCP XMLRPC interface, 
 # if xen-tcp-xmlrpc-server is set.
 #(xen-tcp-xmlrpc-server-address 'localhost')
 #(xen-tcp-xmlrpc-server-port 8006)
+
+# SSL key and certificate to use for the legacy TCP XMLRPC interface.
+# Setting these will mean that this port serves only SSL connections as
+# opposed to plaintext ones.
+#(xend-tcp-xmlrpc-server-ssl-key-file  /etc/xen/xmlrpc.key)
+#(xend-tcp-xmlrpc-server-ssl-cert-file /etc/xen/xmlrpc.crt)
 
 
 # Port xend should use for the HTTP interface, if xend-http-server is set.
diff -r bc2811bf7771 -r 81fec499a983 tools/ioemu/Makefile.target
--- a/tools/ioemu/Makefile.target       Wed Mar 28 08:40:42 2007 +0000
+++ b/tools/ioemu/Makefile.target       Wed Mar 28 08:44:08 2007 +0000
@@ -193,6 +193,10 @@ LIBS+=-lsocket -lnsl -lresolv
 LIBS+=-lsocket -lnsl -lresolv
 endif
 
+ifeq ($(debug),y)
+CFLAGS += -DQEMU_VNC_MONITOR_EXPORT
+endif
+
 # profiling code
 ifdef TARGET_GPROF
 LDFLAGS+=-p
diff -r bc2811bf7771 -r 81fec499a983 tools/ioemu/vnc.c
--- a/tools/ioemu/vnc.c Wed Mar 28 08:40:42 2007 +0000
+++ b/tools/ioemu/vnc.c Wed Mar 28 08:44:08 2007 +0000
@@ -113,8 +113,10 @@ struct VncState
     int visible_w;
     int visible_h;
 
+#ifdef QEMU_VNC_MONITOR_EXPORT
     int ctl_keys;               /* Ctrl+Alt starts calibration */
     int shift_keys;             /* Shift / CapsLock keys */
+#endif
     int numlock;
 };
 
@@ -895,6 +897,7 @@ static void do_key_event(VncState *vs, i
            kbd_put_keycode(keycode & 0x7f);
        else
            kbd_put_keycode(keycode | 0x80);
+#ifdef QEMU_VNC_MONITOR_EXPORT
     } else if (down) {
        int qemu_keysym = 0;
 
@@ -922,8 +925,10 @@ static void do_key_event(VncState *vs, i
        }
        if (qemu_keysym != 0)
            kbd_put_keysym(qemu_keysym);
-    }
-
+#endif
+    }
+
+#ifdef QEMU_VNC_MONITOR_EXPORT
     if (down) {
        switch (sym) {
        case XK_Control_L:
@@ -976,6 +981,10 @@ static void do_key_event(VncState *vs, i
            break;
        }
     }
+#else
+    if (!down && sym == XK_Num_Lock)
+        vs->numlock = !vs->numlock;
+#endif
 }
 
 static void key_event(VncState *vs, int down, uint32_t sym)
diff -r bc2811bf7771 -r 81fec499a983 tools/python/xen/util/xmlrpcclient.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/util/xmlrpcclient.py     Wed Mar 28 08:44:08 2007 +0000
@@ -0,0 +1,122 @@
+#============================================================================
+# 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) 2006 Anthony Liguori <aliguori@xxxxxxxxxx>
+# Copyright (C) 2007 XenSource Inc.
+#============================================================================
+
+
+from httplib import FakeSocket, HTTPConnection, HTTP
+import socket
+import xmlrpclib
+from types import StringTypes
+
+
+try:
+    import SSHTransport
+    ssh_enabled = True
+except ImportError:
+    # SSHTransport is disabled on Python <2.4, because it uses the subprocess
+    # package.
+    ssh_enabled = False
+
+
+# A new ServerProxy that also supports httpu urls.  An http URL comes in the
+# form:
+#
+# httpu:///absolute/path/to/socket.sock
+#
+# It assumes that the RPC handler is /RPC2.  This probably needs to be improved
+
+class HTTPUnixConnection(HTTPConnection):
+    def connect(self):
+        self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+        self.sock.connect(self.host)
+
+class HTTPUnix(HTTP):
+    _connection_class = HTTPUnixConnection
+
+class UnixTransport(xmlrpclib.Transport):
+    def request(self, host, handler, request_body, verbose=0):
+        self.__handler = handler
+        return xmlrpclib.Transport.request(self, host, '/RPC2',
+                                           request_body, verbose)
+    def make_connection(self, host):
+        return HTTPUnix(self.__handler)
+
+
+# We need our own transport for HTTPS, because xmlrpclib.SafeTransport is
+# broken -- it does not handle ERROR_ZERO_RETURN properly.
+class HTTPSTransport(xmlrpclib.SafeTransport):
+    def _parse_response(self, file, sock):
+        p, u = self.getparser()
+        while 1:
+            try:
+                if sock:
+                    response = sock.recv(1024)
+                else:
+                    response = file.read(1024)
+            except socket.sslerror, exn:
+                if exn[0] == socket.SSL_ERROR_ZERO_RETURN:
+                    break
+                raise
+                
+            if not response:
+                break
+            if self.verbose:
+                print 'body:', repr(response)
+            p.feed(response)
+            
+        file.close()
+        p.close()
+        return u.close()
+
+
+# See xmlrpclib2.TCPXMLRPCServer._marshalled_dispatch.
+def conv_string(x):
+    if isinstance(x, StringTypes):
+        s = string.replace(x, "'", r"\047")
+        exec "s = '" + s + "'"
+        return s
+    else:
+        return x
+
+
+class ServerProxy(xmlrpclib.ServerProxy):
+    def __init__(self, uri, transport=None, encoding=None, verbose=0,
+                 allow_none=1):
+        if transport == None:
+            (protocol, rest) = uri.split(':', 1)
+            if protocol == 'httpu':
+                uri = 'http:' + rest
+                transport = UnixTransport()
+            elif protocol == 'https':
+                transport = HTTPSTransport()
+            elif protocol == 'ssh':
+                global ssh_enabled
+                if ssh_enabled:
+                    (transport, uri) = SSHTransport.getHTTPURI(uri)
+                else:
+                    raise ValueError(
+                        "SSH transport not supported on Python <2.4.")
+        xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
+                                       verbose, allow_none)
+
+    def __request(self, methodname, params):
+        response = xmlrpclib.ServerProxy.__request(self, methodname, params)
+
+        if isinstance(response, tuple):
+            return tuple([conv_string(x) for x in response])
+        else:
+            return conv_string(response)
diff -r bc2811bf7771 -r 81fec499a983 tools/python/xen/util/xmlrpclib2.py
--- a/tools/python/xen/util/xmlrpclib2.py       Wed Mar 28 08:40:42 2007 +0000
+++ b/tools/python/xen/util/xmlrpclib2.py       Wed Mar 28 08:44:08 2007 +0000
@@ -26,7 +26,6 @@ from types import *
 from types import *
     
 
-from httplib import HTTPConnection, HTTP
 from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
 import SocketServer
 import xmlrpclib, socket, os, stat
@@ -35,14 +34,6 @@ import mkdir
 
 from xen.web import connection
 from xen.xend.XendLogging import log
-
-try:
-    import SSHTransport
-    ssh_enabled = True
-except ImportError:
-    # SSHTransport is disabled on Python <2.4, because it uses the subprocess
-    # package.
-    ssh_enabled = False
 
 #
 # Convert all integers to strings as described in the Xen API
@@ -64,13 +55,6 @@ def stringify(value):
         return value
 
 
-# A new ServerProxy that also supports httpu urls.  An http URL comes in the
-# form:
-#
-# httpu:///absolute/path/to/socket.sock
-#
-# It assumes that the RPC handler is /RPC2.  This probably needs to be improved
-
 # We're forced to subclass the RequestHandler class so that we can work around
 # some bugs in Keep-Alive handling and also enabled it by default
 class XMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
@@ -105,60 +89,6 @@ class XMLRPCRequestHandler(SimpleXMLRPCR
         self.wfile.flush()
         if self.close_connection == 1:
             self.connection.shutdown(1)
-
-class HTTPUnixConnection(HTTPConnection):
-    def connect(self):
-        self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
-        self.sock.connect(self.host)
-
-class HTTPUnix(HTTP):
-    _connection_class = HTTPUnixConnection
-
-class UnixTransport(xmlrpclib.Transport):
-    def request(self, host, handler, request_body, verbose=0):
-        self.__handler = handler
-        return xmlrpclib.Transport.request(self, host, '/RPC2',
-                                           request_body, verbose)
-    def make_connection(self, host):
-        return HTTPUnix(self.__handler)
-
-
-# See _marshalled_dispatch below.
-def conv_string(x):
-    if isinstance(x, StringTypes):
-        s = string.replace(x, "'", r"\047")
-        exec "s = '" + s + "'"
-        return s
-    else:
-        return x
-
-
-class ServerProxy(xmlrpclib.ServerProxy):
-    def __init__(self, uri, transport=None, encoding=None, verbose=0,
-                 allow_none=1):
-        if transport == None:
-            (protocol, rest) = uri.split(':', 1)
-            if protocol == 'httpu':
-                uri = 'http:' + rest
-                transport = UnixTransport()
-            elif protocol == 'ssh':
-                global ssh_enabled
-                if ssh_enabled:
-                    (transport, uri) = SSHTransport.getHTTPURI(uri)
-                else:
-                    raise ValueError(
-                        "SSH transport not supported on Python <2.4.")
-        xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
-                                       verbose, allow_none)
-
-    def __request(self, methodname, params):
-        response = xmlrpclib.ServerProxy.__request(self, methodname, params)
-
-        if isinstance(response, tuple):
-            return tuple([conv_string(x) for x in response])
-        else:
-            return conv_string(response)
-
 
 # This is a base XML-RPC server for TCP.  It sets allow_reuse_address to
 # true, and has an improved marshaller that logs and serializes exceptions.
diff -r bc2811bf7771 -r 81fec499a983 tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py  Wed Mar 28 08:40:42 2007 +0000
+++ b/tools/python/xen/xend/XendAPI.py  Wed Mar 28 08:44:08 2007 +0000
@@ -982,10 +982,10 @@ class XendAPI(object):
     # Xen API: Class PIF
     # ----------------------------------------------------------------
 
-    PIF_attr_ro = ['metrics']
+    PIF_attr_ro = ['network',
+                   'host',
+                   'metrics']
     PIF_attr_rw = ['device',
-                   'network',
-                   'host',
                    'MAC',
                    'MTU',
                    'VLAN']
@@ -1647,14 +1647,15 @@ class XendAPI(object):
 
     def VM_send_sysrq(self, _, vm_ref, req):
         xeninfo = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        if xeninfo.state != XEN_API_VM_POWER_STATE_RUNNING:
+        if xeninfo.state == XEN_API_VM_POWER_STATE_RUNNING \
+               or xeninfo.state == XEN_API_VM_POWER_STATE_PAUSED:
+            xeninfo.send_sysrq(req)
+            return xen_api_success_void()
+        else:
             return xen_api_error(
                 ['VM_BAD_POWER_STATE', vm_ref,
                  XendDomain.POWER_STATE_NAMES[XEN_API_VM_POWER_STATE_RUNNING],
                  XendDomain.POWER_STATE_NAMES[xeninfo.state]])
-        xeninfo.send_sysrq(req)
-        return xen_api_success_void()
-
 
     def VM_send_trigger(self, _, vm_ref, trigger, vcpu):
         xendom = XendDomain.instance()
@@ -1689,6 +1690,9 @@ class XendAPI(object):
     VM_metrics_attr_rw = []
     VM_metrics_methods = []
 
+    def VIF_metrics_get_all(self, session):
+        return self.VIF_get_all(session)
+
     def _VM_metrics_get(self, _, ref):
         return XendVMMetrics.get_by_uuid(ref)
 
@@ -1699,11 +1703,11 @@ class XendAPI(object):
     # Xen API: Class VBD
     # ----------------------------------------------------------------
 
-    VBD_attr_ro = ['metrics',
+    VBD_attr_ro = ['VM',
+                   'VDI',
+                   'metrics',
                    'runtime_properties']
-    VBD_attr_rw = ['VM',
-                   'VDI',
-                   'device',
+    VBD_attr_rw = ['device',
                    'bootable',
                    'mode',
                    'type']
@@ -1852,7 +1856,10 @@ class XendAPI(object):
                            'io_write_kbs',
                            'last_updated']
     VBD_metrics_attr_rw = []
-    VBD_methods = []
+    VBD_metrics_methods = []
+
+    def VBD_metrics_get_all(self, session):
+        return self.VBD_get_all(session)
 
     def VBD_metrics_get_record(self, _, ref):
         vm = XendDomain.instance().get_vm_with_dev_uuid('vbd', ref)
@@ -1877,11 +1884,11 @@ class XendAPI(object):
     # Xen API: Class VIF
     # ----------------------------------------------------------------
 
-    VIF_attr_ro = ['metrics',
+    VIF_attr_ro = ['network',
+                   'VM',
+                   'metrics',
                    'runtime_properties']
     VIF_attr_rw = ['device',
-                   'network',
-                   'VM',
                    'MAC',
                    'MTU']
 
@@ -1945,10 +1952,10 @@ class XendAPI(object):
         return xen_api_success(vif_ref)
 
     def VIF_get_VM(self, session, vif_ref):
-        xendom = XendDomain.instance()        
-        vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)        
+        xendom = XendDomain.instance()
+        vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
         return xen_api_success(vm.get_uuid())
-    
+
     def VIF_get_MTU(self, session, vif_ref):
         return self._VIF_get(vif_ref, 'MTU')
     
@@ -1993,7 +2000,7 @@ class XendAPI(object):
                            'io_write_kbs',
                            'last_updated']
     VIF_metrics_attr_rw = []
-    VIF_methods = []
+    VIF_metrics_methods = []
 
     def VIF_metrics_get_record(self, _, ref):
         vm = XendDomain.instance().get_vm_with_dev_uuid('vif', ref)
diff -r bc2811bf7771 -r 81fec499a983 tools/python/xen/xend/XendClient.py
--- a/tools/python/xen/xend/XendClient.py       Wed Mar 28 08:40:42 2007 +0000
+++ b/tools/python/xen/xend/XendClient.py       Wed Mar 28 08:44:08 2007 +0000
@@ -17,7 +17,7 @@
 # Copyright (C) 2006 Anthony Liguori <aliguori@xxxxxxxxxx>
 #============================================================================
 
-from xen.util.xmlrpclib2 import ServerProxy
+from xen.util.xmlrpcclient import ServerProxy
 import os
 import sys
 
diff -r bc2811bf7771 -r 81fec499a983 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Wed Mar 28 08:40:42 2007 +0000
+++ b/tools/python/xen/xend/XendConfig.py       Wed Mar 28 08:44:08 2007 +0000
@@ -298,7 +298,7 @@ class XendConfig(dict):
             'actions_after_reboot': 'restart',
             'actions_after_crash': 'restart',
             'actions_after_suspend': '',
-            'is_template': False,
+            'is_a_template': False,
             'is_control_domain': False,
             'features': '',
             'PV_bootloader': '',
@@ -452,7 +452,10 @@ class XendConfig(dict):
         for key, typ in XENAPI_CFG_TYPES.items():
             val = sxp.child_value(sxp_cfg, key)
             if val is not None:
-                cfg[key] = typ(val)
+                try:
+                    cfg[key] = typ(val)
+                except (ValueError, TypeError), e:
+                    log.warn('Unable to convert type value for key: %s' % key)
 
         # Convert deprecated options to current equivalents.
         
@@ -845,6 +848,8 @@ class XendConfig(dict):
                     sxpr.append([name, s])
 
         for xenapi, legacy in XENAPI_CFG_TO_LEGACY_CFG.items():
+            if legacy in ('cpus'): # skip this
+                continue
             if self.has_key(xenapi) and self[xenapi] not in (None, []):
                 if type(self[xenapi]) == bool:
                     # convert booleans to ints before making an sxp item
@@ -858,7 +863,7 @@ class XendConfig(dict):
         sxpr.append(["memory", int(self["memory_dynamic_max"])/MiB])
 
         for legacy in LEGACY_UNSUPPORTED_BY_XENAPI_CFG:
-            if legacy in ('domid', 'uuid'): # skip these
+            if legacy in ('domid', 'uuid', 'cpus'): # skip these
                 continue
             if self.has_key(legacy) and self[legacy] not in (None, []):
                 sxpr.append([legacy, self[legacy]])
diff -r bc2811bf7771 -r 81fec499a983 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Wed Mar 28 08:40:42 2007 +0000
+++ b/tools/python/xen/xend/XendDomain.py       Wed Mar 28 08:44:08 2007 +0000
@@ -569,6 +569,26 @@ class XendDomain:
         finally:
             self.domains_lock.release()
 
+    def autostart_domains(self):
+        """ Autostart managed domains that are marked as such. """
+
+        need_starting = []
+        
+        self.domains_lock.acquire()
+        try:
+            for dom_uuid, dom in self.managed_domains.items():
+                if dom and dom.state == DOM_STATE_HALTED:
+                    on_xend_start = dom.info.get('on_xend_start', 'ignore')
+                    auto_power_on = dom.info.get('auto_power_on', False)
+                    should_start = (on_xend_start == 'start') or auto_power_on
+                    if should_start:
+                        need_starting.append(dom_uuid)
+        finally:
+            self.domains_lock.release()
+
+        for dom_uuid in need_starting:
+            self.domain_start(dom_uuid, False)
+
     def cleanup_domains(self):
         """Clean up domains that are marked as autostop.
         Should be called when Xend goes down. This is currently
diff -r bc2811bf7771 -r 81fec499a983 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Wed Mar 28 08:40:42 2007 +0000
+++ b/tools/python/xen/xend/XendDomainInfo.py   Wed Mar 28 08:44:08 2007 +0000
@@ -152,8 +152,9 @@ def recreate(info, priv):
     try:
         vmpath = xstransact.Read(dompath, "vm")
         if not vmpath:
-            log.warn('/local/domain/%d/vm is missing. recreate is '
-                     'confused, trying our best to recover' % domid)
+            if not priv:
+                log.warn('/local/domain/%d/vm is missing. recreate is '
+                         'confused, trying our best to recover' % domid)
             needs_reinitialising = True
             raise XendError('reinit')
         
diff -r bc2811bf7771 -r 81fec499a983 tools/python/xen/xend/XendLogging.py
--- a/tools/python/xen/xend/XendLogging.py      Wed Mar 28 08:40:42 2007 +0000
+++ b/tools/python/xen/xend/XendLogging.py      Wed Mar 28 08:44:08 2007 +0000
@@ -62,6 +62,7 @@ if 'TRACE' not in logging.__dict__:
     # Work around a bug in Python's inspect module: findsource is supposed to
     # raise IOError if it fails, with other functions in that module coping
     # with that, but some people are seeing IndexError raised from there.
+    # This is Python bug 1628987.  http://python.org/sf/1628987.
     if hasattr(inspect, 'findsource'):
         real_findsource = getattr(inspect, 'findsource')
         def findsource(*args, **kwargs):
diff -r bc2811bf7771 -r 81fec499a983 tools/python/xen/xend/XendMonitor.py
--- a/tools/python/xen/xend/XendMonitor.py      Wed Mar 28 08:40:42 2007 +0000
+++ b/tools/python/xen/xend/XendMonitor.py      Wed Mar 28 08:44:08 2007 +0000
@@ -24,8 +24,8 @@ import re
 """Monitoring thread to keep track of Xend statistics. """
 
 VBD_SYSFS_PATH = '/sys/devices/xen-backend/'
-VBD_WR_PATH = VBD_SYSFS_PATH + '%s/statistics/wr_req'
-VBD_RD_PATH = VBD_SYSFS_PATH + '%s/statistics/rd_req'
+VBD_WR_PATH = VBD_SYSFS_PATH + '%s/statistics/wr_sect'
+VBD_RD_PATH = VBD_SYSFS_PATH + '%s/statistics/rd_sect'
 VBD_DOMAIN_RE = r'vbd-(?P<domid>\d+)-(?P<devid>\d+)$'
 
 NET_PROCFS_PATH = '/proc/net/dev'
@@ -51,14 +51,9 @@ VIF_DOMAIN_RE = re.compile(r'vif(?P<domi
                            PROC_NET_DEV_RE)
 PIF_RE = re.compile(r'^\s*(?P<iface>peth\d+):\s*' + PROC_NET_DEV_RE)
 
-# The VBD transfer figures are in "requests" where we don't
-# really know how many bytes per requests. For now we make
-# up a number roughly could be.
-VBD_ROUGH_BYTES_PER_REQUEST = 1024 * 8 * 4
-
 # Interval to poll xc, sysfs and proc
 POLL_INTERVAL = 2.0
-
+SECTOR_SIZE = 512
 class XendMonitor(threading.Thread):
     """Monitors VCPU, VBD, VIF and PIF statistics for Xen API.
 
@@ -186,9 +181,8 @@ class XendMonitor(threading.Thread):
                 usage_at = time.time()
                 rd_stat = int(open(rd_stat_path).readline().strip())
                 wr_stat = int(open(wr_stat_path).readline().strip())
-                rd_stat *= VBD_ROUGH_BYTES_PER_REQUEST
-                wr_stat *= VBD_ROUGH_BYTES_PER_REQUEST
-                
+                rd_stat *= SECTOR_SIZE
+                wr_stat *= SECTOR_SIZE
                 if domid not in stats:
                     stats[domid] = {}
 
diff -r bc2811bf7771 -r 81fec499a983 tools/python/xen/xend/XendOptions.py
--- a/tools/python/xen/xend/XendOptions.py      Wed Mar 28 08:40:42 2007 +0000
+++ b/tools/python/xen/xend/XendOptions.py      Wed Mar 28 08:44:08 2007 +0000
@@ -165,7 +165,13 @@ class XendOptions:
 
     def get_xend_tcp_xmlrpc_server_address(self):
         return self.get_config_string("xend-tcp-xmlrpc-server-address",
-                                    
self.xend_tcp_xmlrpc_server_address_default)    
+                                      
self.xend_tcp_xmlrpc_server_address_default)
+
+    def get_xend_tcp_xmlrpc_server_ssl_key_file(self):
+        return self.get_config_string("xend-tcp-xmlrpc-server-ssl-key-file")
+
+    def get_xend_tcp_xmlrpc_server_ssl_cert_file(self):
+        return self.get_config_string("xend-tcp-xmlrpc-server-ssl-cert-file")
 
     def get_xend_unix_xmlrpc_server(self):
         return self.get_config_bool("xend-unix-xmlrpc-server",
diff -r bc2811bf7771 -r 81fec499a983 
tools/python/xen/xend/server/SSLXMLRPCServer.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/server/SSLXMLRPCServer.py   Wed Mar 28 08:44:08 
2007 +0000
@@ -0,0 +1,103 @@
+#============================================================================
+# 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) 2007 XenSource Inc.
+#============================================================================
+
+
+"""
+HTTPS wrapper for an XML-RPC server interface.  Requires PyOpenSSL (Debian
+package python-pyopenssl).
+"""
+
+import socket
+
+from OpenSSL import SSL
+
+from xen.util.xmlrpclib2 import XMLRPCRequestHandler, TCPXMLRPCServer
+
+
+class SSLXMLRPCRequestHandler(XMLRPCRequestHandler):
+    def setup(self):
+        self.connection = self.request
+        self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
+        self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
+
+#
+# Taken from pyOpenSSL-0.6 examples (public-domain)
+#
+
+class SSLWrapper:
+    """
+    """
+    def __init__(self, conn):
+        """
+        Connection is not yet a new-style class,
+        so I'm making a proxy instead of subclassing.
+        """
+        self.__dict__["conn"] = conn
+    def __getattr__(self, name):
+        return getattr(self.__dict__["conn"], name)
+    def __setattr__(self, name, value):
+        setattr(self.__dict__["conn"], name, value)
+
+    def close(self):
+        self.shutdown()
+        return self.__dict__["conn"].close()
+
+    def shutdown(self, how=1):
+        """
+        SimpleXMLRpcServer.doPOST calls shutdown(1),
+        and Connection.shutdown() doesn't take
+        an argument. So we just discard the argument.
+        """
+        # Block until the shutdown is complete
+        self.__dict__["conn"].shutdown()
+        self.__dict__["conn"].shutdown()
+
+    def accept(self):
+        """
+        This is the other part of the shutdown() workaround.
+        Since servers create new sockets, we have to infect
+        them with our magic. :)
+        """
+        c, a = self.__dict__["conn"].accept()
+        return (SSLWrapper(c), a)
+
+#
+# End of pyOpenSSL-0.6 example code.
+#
+
+class SSLXMLRPCServer(TCPXMLRPCServer):
+    def __init__(self, addr, allowed, xenapi, logRequests = 1,
+                 ssl_key_file = None, ssl_cert_file = None):
+
+        TCPXMLRPCServer.__init__(self, addr, allowed, xenapi,
+                                 SSLXMLRPCRequestHandler, logRequests)
+
+        if not ssl_key_file or not ssl_cert_file:
+            raise ValueError("SSLXMLRPCServer requires ssl_key_file "
+                             "and ssl_cert_file to be set.")
+
+        # make a SSL socket
+        ctx = SSL.Context(SSL.SSLv23_METHOD)
+        ctx.set_options(SSL.OP_NO_SSLv2)
+        ctx.use_privatekey_file (ssl_key_file)
+        ctx.use_certificate_file(ssl_cert_file)
+        self.socket = SSLWrapper(SSL.Connection(ctx,
+                                 socket.socket(self.address_family,
+                                               self.socket_type)))
+        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+        self.server_bind()
+        self.server_activate()
diff -r bc2811bf7771 -r 81fec499a983 tools/python/xen/xend/server/SrvServer.py
--- a/tools/python/xen/xend/server/SrvServer.py Wed Mar 28 08:40:42 2007 +0000
+++ b/tools/python/xen/xend/server/SrvServer.py Wed Mar 28 08:44:08 2007 +0000
@@ -52,6 +52,7 @@ from xen.xend import Vifctl
 from xen.xend import Vifctl
 from xen.xend.XendLogging import log
 from xen.xend.XendClient import XEN_API_SOCKET
+from xen.xend.XendDomain import instance as xenddomain
 from xen.web.SrvDir import SrvDir
 
 from SrvRoot import SrvRoot
@@ -72,7 +73,7 @@ class XendServers:
     def add(self, server):
         self.servers.append(server)
 
-    def cleanup(self, signum = 0, frame = None):
+    def cleanup(self, signum = 0, frame = None, reloading = False):
         log.debug("SrvServer.cleanup()")
         self.cleaningUp = True
         for server in self.servers:
@@ -80,12 +81,18 @@ class XendServers:
                 server.shutdown()
             except:
                 pass
+
+        # clean up domains for those that have on_xend_stop
+        if not reloading:
+            xenddomain().cleanup_domains()
+        
         self.running = False
+        
 
     def reloadConfig(self, signum = 0, frame = None):
         log.debug("SrvServer.reloadConfig()")
         self.reloadingConfig = True
-        self.cleanup(signum, frame)
+        self.cleanup(signum, frame, reloading = True)
 
     def start(self, status):
         # Running the network script will spawn another process, which takes
@@ -144,6 +151,12 @@ class XendServers:
                 status.close()
                 status = None
 
+            # Reaching this point means we can auto start domains
+            try:
+                xenddomain().autostart_domains()
+            except Exception, e:
+                log.exception("Failed while autostarting domains")
+
             # loop to keep main thread alive until it receives a SIGTERM
             self.running = True
             while self.running:
@@ -172,33 +185,49 @@ def _loadConfig(servers, root, reload):
     api_cfg = xoptions.get_xen_api_server()
     if api_cfg:
         try:
-            addrs = [(str(x[0]).split(':'),
-                      len(x) > 1 and x[1] or XendAPI.AUTH_PAM,
-                      len(x) > 2 and x[2] and map(re.compile, x[2].split(" "))
-                      or None)
-                     for x in api_cfg]
-            for addrport, auth, allowed in addrs:
-                if auth not in [XendAPI.AUTH_PAM, XendAPI.AUTH_NONE]:
-                    log.error('Xen-API server configuration %s is invalid, ' +
-                              'as %s is not a valid authentication type.',
-                              api_cfg, auth)
-                    break
-
-                if len(addrport) == 1:
-                    if addrport[0] == 'unix':
-                        servers.add(XMLRPCServer(auth, True,
-                                                 path = XEN_API_SOCKET,
-                                                 hosts_allowed = allowed))
-                    else:
-                        servers.add(
-                            XMLRPCServer(auth, True, True, '',
-                                         int(addrport[0]),
-                                         hosts_allowed = allowed))
-                else:
-                    addr, port = addrport
-                    servers.add(XMLRPCServer(auth, True, True, addr,
-                                             int(port),
-                                             hosts_allowed = allowed))
+            for server_cfg in api_cfg:
+                # Parse the xen-api-server config
+                
+                host = 'localhost'
+                port = 0
+                use_tcp = False
+                ssl_key_file = None
+                ssl_cert_file = None
+                auth_method = XendAPI.AUTH_NONE
+                hosts_allowed = None
+                
+                host_addr = server_cfg[0].split(':', 1)
+                if len(host_addr) == 1 and host_addr[0].lower() == 'unix':
+                    use_tcp = False
+                elif len(host_addr) == 1:
+                    use_tcp = True
+                    port = int(host_addr[0])
+                elif len(host_addr) == 2:
+                    use_tcp = True
+                    host = str(host_addr[0])
+                    port = int(host_addr[1])
+
+                if len(server_cfg) > 1:
+                    if server_cfg[1] in [XendAPI.AUTH_PAM, XendAPI.AUTH_NONE]:
+                        auth_method = server_cfg[1]
+
+                if len(server_cfg) > 2:
+                    hosts_allowed = server_cfg[2] or None
+                
+
+                if len(server_cfg) > 4:
+                    # SSL key and cert file
+                    ssl_key_file = server_cfg[3]
+                    ssl_cert_file = server_cfg[4]
+
+
+                servers.add(XMLRPCServer(auth_method, True, use_tcp = use_tcp,
+                                         ssl_key_file = ssl_key_file,
+                                         ssl_cert_file = ssl_cert_file,
+                                         host = host, port = port,
+                                         path = XEN_API_SOCKET,
+                                         hosts_allowed = hosts_allowed))
+
         except (ValueError, TypeError), exn:
             log.exception('Xen API Server init failed')
             log.error('Xen-API server configuration %s is invalid.', api_cfg)
@@ -206,8 +235,17 @@ def _loadConfig(servers, root, reload):
     if xoptions.get_xend_tcp_xmlrpc_server():
         addr = xoptions.get_xend_tcp_xmlrpc_server_address()
         port = xoptions.get_xend_tcp_xmlrpc_server_port()
-        servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False, use_tcp = True,
-                                 host = addr, port = port))
+        ssl_key_file = xoptions.get_xend_tcp_xmlrpc_server_ssl_key_file()
+        ssl_cert_file = xoptions.get_xend_tcp_xmlrpc_server_ssl_cert_file()
+
+        if ssl_key_file and ssl_cert_file:
+            servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False, use_tcp = True,
+                                     ssl_key_file = ssl_key_file,
+                                     ssl_cert_file = ssl_cert_file,
+                                     host = addr, port = port))
+        else:
+            servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False, use_tcp = True,
+                                     host = addr, port = port))
 
     if xoptions.get_xend_unix_xmlrpc_server():
         servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False))
diff -r bc2811bf7771 -r 81fec499a983 
tools/python/xen/xend/server/XMLRPCServer.py
--- a/tools/python/xen/xend/server/XMLRPCServer.py      Wed Mar 28 08:40:42 
2007 +0000
+++ b/tools/python/xen/xend/server/XMLRPCServer.py      Wed Mar 28 08:44:08 
2007 +0000
@@ -21,6 +21,11 @@ import types
 import types
 import xmlrpclib
 from xen.util.xmlrpclib2 import UnixXMLRPCServer, TCPXMLRPCServer
+try:
+    from SSLXMLRPCServer import SSLXMLRPCServer
+    ssl_enabled = True
+except ImportError:
+    ssl_enabled = False
 
 from xen.xend import XendAPI, XendDomain, XendDomainInfo, XendNode
 from xen.xend import XendLogging, XendDmesg
@@ -87,14 +92,20 @@ exclude = ['domain_create', 'domain_rest
 exclude = ['domain_create', 'domain_restore']
 
 class XMLRPCServer:
-    def __init__(self, auth, use_xenapi, use_tcp=False, host = "localhost",
-                 port = 8006, path = XML_RPC_SOCKET, hosts_allowed = None):
+    def __init__(self, auth, use_xenapi, use_tcp = False,
+                 ssl_key_file = None, ssl_cert_file = None,
+                 host = "localhost", port = 8006, path = XML_RPC_SOCKET,
+                 hosts_allowed = None):
+        
         self.use_tcp = use_tcp
         self.port = port
         self.host = host
         self.path = path
         self.hosts_allowed = hosts_allowed
         
+        self.ssl_key_file = ssl_key_file
+        self.ssl_cert_file = ssl_cert_file
+        
         self.ready = False        
         self.running = True
         self.auth = auth
@@ -107,14 +118,33 @@ class XMLRPCServer:
 
         try:
             if self.use_tcp:
-                log.info("Opening TCP XML-RPC server on %s%d%s",
+                using_ssl = self.ssl_key_file and self.ssl_cert_file
+
+                log.info("Opening %s XML-RPC server on %s%d%s",
+                         using_ssl and 'HTTPS' or 'TCP',
                          self.host and '%s:' % self.host or
                          'all interfaces, port ',
                          self.port, authmsg)
-                self.server = TCPXMLRPCServer((self.host, self.port),
-                                              self.hosts_allowed,
-                                              self.xenapi is not None,
-                                              logRequests = False)
+
+                if not ssl_enabled:
+                    raise ValueError("pyOpenSSL not installed. "
+                                     "Unable to start HTTPS XML-RPC server")
+
+                if using_ssl:
+                    self.server = SSLXMLRPCServer(
+                        (self.host, self.port),
+                        self.hosts_allowed,
+                        self.xenapi is not None,
+                        logRequests = False,
+                        ssl_key_file = self.ssl_key_file,
+                        ssl_cert_file = self.ssl_cert_file)
+                else:
+                    self.server = TCPXMLRPCServer(
+                        (self.host, self.port),
+                        self.hosts_allowed,
+                        self.xenapi is not None,
+                        logRequests = False)
+
             else:
                 log.info("Opening Unix domain socket XML-RPC server on %s%s",
                          self.path, authmsg)
@@ -126,7 +156,12 @@ class XMLRPCServer:
             ready = True
             running = False
             return
-
+        except Exception, e:
+            log.exception('Cannot start server: %s!', e)
+            ready = True
+            running = False
+            return
+        
         # Register Xen API Functions
         # -------------------------------------------------------------------
         # exportable functions are ones that do not begin with '_'
diff -r bc2811bf7771 -r 81fec499a983 tools/python/xen/xm/XenAPI.py
--- a/tools/python/xen/xm/XenAPI.py     Wed Mar 28 08:40:42 2007 +0000
+++ b/tools/python/xen/xm/XenAPI.py     Wed Mar 28 08:44:08 2007 +0000
@@ -12,7 +12,7 @@
 # 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) 2006 XenSource Inc.
+# Copyright (C) 2006-2007 XenSource Inc.
 #============================================================================
 #
 # Parts of this file are based upon xmlrpclib.py, the XML-RPC client
@@ -47,7 +47,7 @@ import gettext
 import gettext
 import xmlrpclib
 
-import xen.util.xmlrpclib2
+import xen.util.xmlrpcclient as xmlrpcclient
 
 
 translation = gettext.translation('xen-xm', fallback = True)
@@ -85,7 +85,7 @@ _RECONNECT_AND_RETRY = (lambda _ : ())
 _RECONNECT_AND_RETRY = (lambda _ : ())
 
 
-class Session(xen.util.xmlrpclib2.ServerProxy):
+class Session(xmlrpcclient.ServerProxy):
     """A server proxy and session manager for communicating with Xend using
     the Xen-API.
 
@@ -104,9 +104,8 @@ class Session(xen.util.xmlrpclib2.Server
 
     def __init__(self, uri, transport=None, encoding=None, verbose=0,
                  allow_none=1):
-        xen.util.xmlrpclib2.ServerProxy.__init__(self, uri, transport,
-                                                 encoding, verbose,
-                                                 allow_none)
+        xmlrpcclient.ServerProxy.__init__(self, uri, transport, encoding,
+                                          verbose, allow_none)
         self._session = None
         self.last_login_method = None
         self.last_login_params = None
@@ -153,7 +152,7 @@ class Session(xen.util.xmlrpclib2.Server
         elif name.startswith('login'):
             return lambda *params: self._login(name, params)
         else:
-            return xen.util.xmlrpclib2.ServerProxy.__getattr__(self, name)
+            return xmlrpcclient.ServerProxy.__getattr__(self, name)
 
 
 def _parse_result(result):
diff -r bc2811bf7771 -r 81fec499a983 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Wed Mar 28 08:40:42 2007 +0000
+++ b/tools/python/xen/xm/create.py     Wed Mar 28 08:44:08 2007 +0000
@@ -107,7 +107,7 @@ gopts.opt('skipdtd', short='s',
 gopts.opt('skipdtd', short='s',
           fn=set_true, default=0,
           use="Skip DTD checking - skips checks on XML before creating. "
-          " Experimental.  Can decreate create time." )
+          " Experimental.  Can decrease create time." )
 
 gopts.opt('paused', short='p',
           fn=set_true, default=0,
diff -r bc2811bf7771 -r 81fec499a983 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Wed Mar 28 08:40:42 2007 +0000
+++ b/tools/python/xen/xm/main.py       Wed Mar 28 08:44:08 2007 +0000
@@ -49,7 +49,7 @@ from xen.xend.XendConstants import *
 
 from xen.xm.opts import OptionError, Opts, wrap, set_true
 from xen.xm import console
-from xen.util.xmlrpclib2 import ServerProxy
+from xen.util.xmlrpcclient import ServerProxy
 
 import XenAPI
 
diff -r bc2811bf7771 -r 81fec499a983 xen/acm/acm_policy.c
--- a/xen/acm/acm_policy.c      Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/acm/acm_policy.c      Wed Mar 28 08:44:08 2007 +0000
@@ -62,6 +62,7 @@ do_acm_set_policy(void *buf, u32 buf_siz
 do_acm_set_policy(void *buf, u32 buf_size)
 {
     struct acm_policy_buffer *pol = (struct acm_policy_buffer *)buf;
+    uint32_t offset, length;
     /* some sanity checking */
     if ((be32_to_cpu(pol->magic) != ACM_MAGIC) ||
         (buf_size != be32_to_cpu(pol->len)) ||
@@ -92,22 +93,27 @@ do_acm_set_policy(void *buf, u32 buf_siz
     /* get bin_policy lock and rewrite policy (release old one) */
     write_lock(&acm_bin_pol_rwlock);
 
+    offset = be32_to_cpu(pol->policy_reference_offset);
+    length = be32_to_cpu(pol->primary_buffer_offset) - offset;
+
     /* set label reference name */
-    if (acm_set_policy_reference(buf + 
be32_to_cpu(pol->policy_reference_offset),
-                                 be32_to_cpu(pol->primary_buffer_offset) -
-                                 be32_to_cpu(pol->policy_reference_offset)))
+    if ( (offset + length) > buf_size ||
+         acm_set_policy_reference(buf + offset, length))
         goto error_lock_free;
 
     /* set primary policy data */
-    if (acm_primary_ops->set_binary_policy(buf + 
be32_to_cpu(pol->primary_buffer_offset),
-                                           
be32_to_cpu(pol->secondary_buffer_offset) -
-                                           
be32_to_cpu(pol->primary_buffer_offset)))
+    offset = be32_to_cpu(pol->primary_buffer_offset);
+    length = be32_to_cpu(pol->secondary_buffer_offset) - offset;
+
+    if ( (offset + length) > buf_size ||
+         acm_primary_ops->set_binary_policy(buf + offset, length))
         goto error_lock_free;
 
     /* set secondary policy data */
-    if (acm_secondary_ops->set_binary_policy(buf + 
be32_to_cpu(pol->secondary_buffer_offset),
-                                             be32_to_cpu(pol->len) - 
-                                             
be32_to_cpu(pol->secondary_buffer_offset)))
+    offset = be32_to_cpu(pol->secondary_buffer_offset);
+    length = be32_to_cpu(pol->len) - offset;
+    if ( (offset + length) > buf_size ||
+         acm_secondary_ops->set_binary_policy(buf + offset, length))
         goto error_lock_free;
 
     write_unlock(&acm_bin_pol_rwlock);
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/ia64/asm-offsets.c
--- a/xen/arch/ia64/asm-offsets.c       Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/ia64/asm-offsets.c       Wed Mar 28 08:44:08 2007 +0000
@@ -223,10 +223,11 @@ void foo(void)
 
 #ifdef PERF_COUNTERS
        BLANK();
-       DEFINE(RECOVER_TO_PAGE_FAULT_PERFC_OFS, offsetof (struct perfcounter, 
recover_to_page_fault));
-       DEFINE(RECOVER_TO_BREAK_FAULT_PERFC_OFS, offsetof (struct perfcounter, 
recover_to_break_fault));
-       DEFINE(FAST_HYPERPRIVOP_PERFC_OFS, offsetof (struct perfcounter, 
fast_hyperprivop));
-       DEFINE(FAST_REFLECT_PERFC_OFS, offsetof (struct perfcounter, 
fast_reflect));
+       DEFINE(IA64_PERFC_recover_to_page_fault, PERFC_recover_to_page_fault);
+       DEFINE(IA64_PERFC_recover_to_break_fault, PERFC_recover_to_break_fault);
+       DEFINE(IA64_PERFC_fast_vhpt_translate, PERFC_fast_vhpt_translate);
+       DEFINE(IA64_PERFC_fast_hyperprivop, PERFC_fast_hyperprivop);
+       DEFINE(IA64_PERFC_fast_reflect, PERFC_fast_reflect);
 #endif
 
        BLANK();
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/ia64/linux-xen/irq_ia64.c
--- a/xen/arch/ia64/linux-xen/irq_ia64.c        Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/ia64/linux-xen/irq_ia64.c        Wed Mar 28 08:44:08 2007 +0000
@@ -113,7 +113,7 @@ ia64_handle_irq (ia64_vector vector, str
        unsigned long saved_tpr;
 
 #ifdef XEN
-       perfc_incrc(irqs);
+       perfc_incr(irqs);
 #endif
 #if IRQ_DEBUG
 #ifdef XEN
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/ia64/linux-xen/mca.c
--- a/xen/arch/ia64/linux-xen/mca.c     Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/ia64/linux-xen/mca.c     Wed Mar 28 08:44:08 2007 +0000
@@ -396,16 +396,6 @@ ia64_log_queue(int sal_info_type, int vi
 #ifdef CONFIG_ACPI
 
 #ifdef XEN
-/**
- *     Copy from linux/include/asm-generic/bug.h
- */
-#define WARN_ON(condition) do { \
-       if (unlikely((condition)!=0)) { \
-               printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, 
__LINE__); \
-               dump_stack(); \
-       } \
-} while (0)
-
 /**
  *     Copy from linux/kernel/irq/manage.c
  *
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/ia64/linux-xen/smp.c
--- a/xen/arch/ia64/linux-xen/smp.c     Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/ia64/linux-xen/smp.c     Wed Mar 28 08:44:08 2007 +0000
@@ -148,7 +148,7 @@ handle_IPI (int irq, void *dev_id, struc
        unsigned long ops;
 
 #ifdef XEN
-       perfc_incrc(ipis);
+       perfc_incr(ipis);
 #endif
        mb();   /* Order interrupt and bit testing. */
        while ((ops = xchg(pending_ipis, 0)) != 0) {
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/ia64/vmx/pal_emul.c
--- a/xen/arch/ia64/vmx/pal_emul.c      Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/ia64/vmx/pal_emul.c      Wed Mar 28 08:44:08 2007 +0000
@@ -37,7 +37,7 @@ pal_emul(struct vcpu *vcpu)
        vcpu_get_gr_nat(vcpu, 30, &gr30); 
        vcpu_get_gr_nat(vcpu, 31, &gr31);
 
-       perfc_incrc(vmx_pal_emul);
+       perfc_incr(vmx_pal_emul);
        result = xen_pal_emulator(gr28, gr29, gr30, gr31);
 
        vcpu_set_gr(vcpu, 8, result.status, 0);
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/ia64/vmx/vmx_process.c
--- a/xen/arch/ia64/vmx/vmx_process.c   Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/ia64/vmx/vmx_process.c   Wed Mar 28 08:44:08 2007 +0000
@@ -151,7 +151,7 @@ vmx_ia64_handle_break (unsigned long ifa
     struct domain *d = current->domain;
     struct vcpu *v = current;
 
-    perfc_incrc(vmx_ia64_handle_break);
+    perfc_incr(vmx_ia64_handle_break);
 #ifdef CRASH_DEBUG
     if ((iim == 0 || iim == CDB_BREAK_NUM) && !user_mode(regs) &&
         IS_VMM_ADDRESS(regs->cr_iip)) {
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/ia64/vmx/vmx_virt.c
--- a/xen/arch/ia64/vmx/vmx_virt.c      Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/ia64/vmx/vmx_virt.c      Wed Mar 28 08:44:08 2007 +0000
@@ -1401,159 +1401,159 @@ if ( (cause == 0xff && opcode == 0x1e000
 
     switch(cause) {
     case EVENT_RSM:
-        perfc_incrc(vmx_rsm);
+        perfc_incr(vmx_rsm);
         status=vmx_emul_rsm(vcpu, inst);
         break;
     case EVENT_SSM:
-        perfc_incrc(vmx_ssm);
+        perfc_incr(vmx_ssm);
         status=vmx_emul_ssm(vcpu, inst);
         break;
     case EVENT_MOV_TO_PSR:
-        perfc_incrc(vmx_mov_to_psr);
+        perfc_incr(vmx_mov_to_psr);
         status=vmx_emul_mov_to_psr(vcpu, inst);
         break;
     case EVENT_MOV_FROM_PSR:
-        perfc_incrc(vmx_mov_from_psr);
+        perfc_incr(vmx_mov_from_psr);
         status=vmx_emul_mov_from_psr(vcpu, inst);
         break;
     case EVENT_MOV_FROM_CR:
-        perfc_incrc(vmx_mov_from_cr);
+        perfc_incr(vmx_mov_from_cr);
         status=vmx_emul_mov_from_cr(vcpu, inst);
         break;
     case EVENT_MOV_TO_CR:
-        perfc_incrc(vmx_mov_to_cr);
+        perfc_incr(vmx_mov_to_cr);
         status=vmx_emul_mov_to_cr(vcpu, inst);
         break;
     case EVENT_BSW_0:
-        perfc_incrc(vmx_bsw0);
+        perfc_incr(vmx_bsw0);
         status=vmx_emul_bsw0(vcpu, inst);
         break;
     case EVENT_BSW_1:
-        perfc_incrc(vmx_bsw1);
+        perfc_incr(vmx_bsw1);
         status=vmx_emul_bsw1(vcpu, inst);
         break;
     case EVENT_COVER:
-        perfc_incrc(vmx_cover);
+        perfc_incr(vmx_cover);
         status=vmx_emul_cover(vcpu, inst);
         break;
     case EVENT_RFI:
-        perfc_incrc(vmx_rfi);
+        perfc_incr(vmx_rfi);
         status=vmx_emul_rfi(vcpu, inst);
         break;
     case EVENT_ITR_D:
-        perfc_incrc(vmx_itr_d);
+        perfc_incr(vmx_itr_d);
         status=vmx_emul_itr_d(vcpu, inst);
         break;
     case EVENT_ITR_I:
-        perfc_incrc(vmx_itr_i);
+        perfc_incr(vmx_itr_i);
         status=vmx_emul_itr_i(vcpu, inst);
         break;
     case EVENT_PTR_D:
-        perfc_incrc(vmx_ptr_d);
+        perfc_incr(vmx_ptr_d);
         status=vmx_emul_ptr_d(vcpu, inst);
         break;
     case EVENT_PTR_I:
-        perfc_incrc(vmx_ptr_i);
+        perfc_incr(vmx_ptr_i);
         status=vmx_emul_ptr_i(vcpu, inst);
         break;
     case EVENT_ITC_D:
-        perfc_incrc(vmx_itc_d);
+        perfc_incr(vmx_itc_d);
         status=vmx_emul_itc_d(vcpu, inst);
         break;
     case EVENT_ITC_I:
-        perfc_incrc(vmx_itc_i);
+        perfc_incr(vmx_itc_i);
         status=vmx_emul_itc_i(vcpu, inst);
         break;
     case EVENT_PTC_L:
-        perfc_incrc(vmx_ptc_l);
+        perfc_incr(vmx_ptc_l);
         status=vmx_emul_ptc_l(vcpu, inst);
         break;
     case EVENT_PTC_G:
-        perfc_incrc(vmx_ptc_g);
+        perfc_incr(vmx_ptc_g);
         status=vmx_emul_ptc_g(vcpu, inst);
         break;
     case EVENT_PTC_GA:
-        perfc_incrc(vmx_ptc_ga);
+        perfc_incr(vmx_ptc_ga);
         status=vmx_emul_ptc_ga(vcpu, inst);
         break;
     case EVENT_PTC_E:
-        perfc_incrc(vmx_ptc_e);
+        perfc_incr(vmx_ptc_e);
         status=vmx_emul_ptc_e(vcpu, inst);
         break;
     case EVENT_MOV_TO_RR:
-        perfc_incrc(vmx_mov_to_rr);
+        perfc_incr(vmx_mov_to_rr);
         status=vmx_emul_mov_to_rr(vcpu, inst);
         break;
     case EVENT_MOV_FROM_RR:
-        perfc_incrc(vmx_mov_from_rr);
+        perfc_incr(vmx_mov_from_rr);
         status=vmx_emul_mov_from_rr(vcpu, inst);
         break;
     case EVENT_THASH:
-        perfc_incrc(vmx_thash);
+        perfc_incr(vmx_thash);
         status=vmx_emul_thash(vcpu, inst);
         break;
     case EVENT_TTAG:
-        perfc_incrc(vmx_ttag);
+        perfc_incr(vmx_ttag);
         status=vmx_emul_ttag(vcpu, inst);
         break;
     case EVENT_TPA:
-        perfc_incrc(vmx_tpa);
+        perfc_incr(vmx_tpa);
         status=vmx_emul_tpa(vcpu, inst);
         break;
     case EVENT_TAK:
-        perfc_incrc(vmx_tak);
+        perfc_incr(vmx_tak);
         status=vmx_emul_tak(vcpu, inst);
         break;
     case EVENT_MOV_TO_AR_IMM:
-        perfc_incrc(vmx_mov_to_ar_imm);
+        perfc_incr(vmx_mov_to_ar_imm);
         status=vmx_emul_mov_to_ar_imm(vcpu, inst);
         break;
     case EVENT_MOV_TO_AR:
-        perfc_incrc(vmx_mov_to_ar_reg);
+        perfc_incr(vmx_mov_to_ar_reg);
         status=vmx_emul_mov_to_ar_reg(vcpu, inst);
         break;
     case EVENT_MOV_FROM_AR:
-        perfc_incrc(vmx_mov_from_ar_reg);
+        perfc_incr(vmx_mov_from_ar_reg);
         status=vmx_emul_mov_from_ar_reg(vcpu, inst);
         break;
     case EVENT_MOV_TO_DBR:
-        perfc_incrc(vmx_mov_to_dbr);
+        perfc_incr(vmx_mov_to_dbr);
         status=vmx_emul_mov_to_dbr(vcpu, inst);
         break;
     case EVENT_MOV_TO_IBR:
-        perfc_incrc(vmx_mov_to_ibr);
+        perfc_incr(vmx_mov_to_ibr);
         status=vmx_emul_mov_to_ibr(vcpu, inst);
         break;
     case EVENT_MOV_TO_PMC:
-        perfc_incrc(vmx_mov_to_pmc);
+        perfc_incr(vmx_mov_to_pmc);
         status=vmx_emul_mov_to_pmc(vcpu, inst);
         break;
     case EVENT_MOV_TO_PMD:
-        perfc_incrc(vmx_mov_to_pmd);
+        perfc_incr(vmx_mov_to_pmd);
         status=vmx_emul_mov_to_pmd(vcpu, inst);
         break;
     case EVENT_MOV_TO_PKR:
-        perfc_incrc(vmx_mov_to_pkr);
+        perfc_incr(vmx_mov_to_pkr);
         status=vmx_emul_mov_to_pkr(vcpu, inst);
         break;
     case EVENT_MOV_FROM_DBR:
-        perfc_incrc(vmx_mov_from_dbr);
+        perfc_incr(vmx_mov_from_dbr);
         status=vmx_emul_mov_from_dbr(vcpu, inst);
         break;
     case EVENT_MOV_FROM_IBR:
-        perfc_incrc(vmx_mov_from_ibr);
+        perfc_incr(vmx_mov_from_ibr);
         status=vmx_emul_mov_from_ibr(vcpu, inst);
         break;
     case EVENT_MOV_FROM_PMC:
-        perfc_incrc(vmx_mov_from_pmc);
+        perfc_incr(vmx_mov_from_pmc);
         status=vmx_emul_mov_from_pmc(vcpu, inst);
         break;
     case EVENT_MOV_FROM_PKR:
-        perfc_incrc(vmx_mov_from_pkr);
+        perfc_incr(vmx_mov_from_pkr);
         status=vmx_emul_mov_from_pkr(vcpu, inst);
         break;
     case EVENT_MOV_FROM_CPUID:
-        perfc_incrc(vmx_mov_from_cpuid);
+        perfc_incr(vmx_mov_from_cpuid);
         status=vmx_emul_mov_from_cpuid(vcpu, inst);
         break;
     case EVENT_VMSW:
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/ia64/xen/dom0_ops.c
--- a/xen/arch/ia64/xen/dom0_ops.c      Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/ia64/xen/dom0_ops.c      Wed Mar 28 08:44:08 2007 +0000
@@ -372,7 +372,7 @@ do_dom0vp_op(unsigned long cmd,
         } else {
             ret = (ret & _PFN_MASK) >> PAGE_SHIFT;//XXX pte_pfn()
         }
-        perfc_incrc(dom0vp_phystomach);
+        perfc_incr(dom0vp_phystomach);
         break;
     case IA64_DOM0VP_machtophys:
         if (!mfn_valid(arg0)) {
@@ -380,7 +380,7 @@ do_dom0vp_op(unsigned long cmd,
             break;
         }
         ret = get_gpfn_from_mfn(arg0);
-        perfc_incrc(dom0vp_machtophys);
+        perfc_incr(dom0vp_machtophys);
         break;
     case IA64_DOM0VP_zap_physmap:
         ret = dom0vp_zap_physmap(d, arg0, (unsigned int)arg1);
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c        Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/ia64/xen/domain.c        Wed Mar 28 08:44:08 2007 +0000
@@ -131,11 +131,11 @@ static void flush_vtlb_for_context_switc
                if (vhpt_is_flushed || NEED_FLUSH(__get_cpu_var(tlbflush_time),
                                                  last_tlbflush_timestamp)) {
                        local_flush_tlb_all();
-                       perfc_incrc(tlbflush_clock_cswitch_purge);
+                       perfc_incr(tlbflush_clock_cswitch_purge);
                } else {
-                       perfc_incrc(tlbflush_clock_cswitch_skip);
-               }
-               perfc_incrc(flush_vtlb_for_context_switch);
+                       perfc_incr(tlbflush_clock_cswitch_skip);
+               }
+               perfc_incr(flush_vtlb_for_context_switch);
        }
 }
 
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/ia64/xen/faults.c
--- a/xen/arch/ia64/xen/faults.c        Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/ia64/xen/faults.c        Wed Mar 28 08:44:08 2007 +0000
@@ -187,7 +187,7 @@ static int handle_lazy_cover(struct vcpu
        if (!PSCB(v, interrupt_collection_enabled)) {
                PSCB(v, ifs) = regs->cr_ifs;
                regs->cr_ifs = 0;
-               perfc_incrc(lazy_cover);
+               perfc_incr(lazy_cover);
                return 1;       // retry same instruction with cr.ifs off
        }
        return 0;
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/ia64/xen/hypercall.c
--- a/xen/arch/ia64/xen/hypercall.c     Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/ia64/xen/hypercall.c     Wed Mar 28 08:44:08 2007 +0000
@@ -161,7 +161,7 @@ ia64_hypercall(struct pt_regs *regs)
                if (regs->r28 == PAL_HALT_LIGHT) {
                        if (vcpu_deliverable_interrupts(v) ||
                                event_pending(v)) {
-                               perfc_incrc(idle_when_pending);
+                               perfc_incr(idle_when_pending);
                                vcpu_pend_unspecified_interrupt(v);
 //printk("idle w/int#%d pending!\n",pi);
 //this shouldn't happen, but it apparently does quite a bit!  so don't
@@ -170,7 +170,7 @@ ia64_hypercall(struct pt_regs *regs)
 //as deliver_pending_interrupt is called on the way out and will deliver it
                        }
                        else {
-                               perfc_incrc(pal_halt_light);
+                               perfc_incr(pal_halt_light);
                                migrate_timer(&v->arch.hlt_timer,
                                              v->processor);
                                set_timer(&v->arch.hlt_timer,
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/ia64/xen/hyperprivop.S
--- a/xen/arch/ia64/xen/hyperprivop.S   Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/ia64/xen/hyperprivop.S   Wed Mar 28 08:44:08 2007 +0000
@@ -26,8 +26,7 @@
 # define FAST_HYPERPRIVOPS
 # ifdef PERF_COUNTERS
 #  define FAST_HYPERPRIVOP_CNT
-#  define FAST_HYPERPRIVOP_PERFC(N) \
-       (perfcounters + FAST_HYPERPRIVOP_PERFC_OFS + (4 * N))
+#  define FAST_HYPERPRIVOP_PERFC(N) PERFC(fast_hyperprivop + N)
 #  define FAST_REFLECT_CNT
 # endif
        
@@ -364,7 +363,7 @@ GLOBAL_ENTRY(fast_tick_reflect)
        mov rp=r29;;
        mov cr.itm=r26;;        // ensure next tick
 #ifdef FAST_REFLECT_CNT
-       movl r20=perfcounters+FAST_REFLECT_PERFC_OFS+((0x3000>>8)*4);;
+       movl r20=PERFC(fast_reflect + (0x3000>>8));;
        ld4 r21=[r20];;
        adds r21=1,r21;;
        st4 [r20]=r21;;
@@ -597,7 +596,7 @@ END(fast_break_reflect)
 //     r31 == pr
 ENTRY(fast_reflect)
 #ifdef FAST_REFLECT_CNT
-       movl r22=perfcounters+FAST_REFLECT_PERFC_OFS;
+       movl r22=PERFC(fast_reflect);
        shr r23=r20,8-2;;
        add r22=r22,r23;;
        ld4 r21=[r22];;
@@ -938,7 +937,7 @@ 1:  // check the guest VHPT
 (p7)   br.cond.spnt.few page_not_present;;
 
 #ifdef FAST_REFLECT_CNT
-       movl r21=perfcounter+FAST_VHPT_TRANSLATE_PERFC_OFS;;
+       movl r21=PERFC(fast_vhpt_translate);;
        ld4 r22=[r21];;
        adds r22=1,r22;;
        st4 [r21]=r22;;
@@ -968,7 +967,7 @@ END(fast_tlb_miss_reflect)
 // we get here if fast_insert fails (e.g. due to metaphysical lookup)
 ENTRY(recover_and_page_fault)
 #ifdef PERF_COUNTERS
-       movl r21=perfcounters + RECOVER_TO_PAGE_FAULT_PERFC_OFS;;
+       movl r21=PERFC(recover_to_page_fault);;
        ld4 r22=[r21];;
        adds r22=1,r22;;
        st4 [r21]=r22;;
@@ -1832,7 +1831,7 @@ END(hyper_ptc_ga)
 // recovery block for hyper_itc metaphysical memory lookup
 ENTRY(recover_and_dispatch_break_fault)
 #ifdef PERF_COUNTERS
-       movl r21=perfcounters + RECOVER_TO_BREAK_FAULT_PERFC_OFS;;
+       movl r21=PERFC(recover_to_break_fault);;
        ld4 r22=[r21];;
        adds r22=1,r22;;
        st4 [r21]=r22;;
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/ia64/xen/mm.c
--- a/xen/arch/ia64/xen/mm.c    Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/ia64/xen/mm.c    Wed Mar 28 08:44:08 2007 +0000
@@ -1139,7 +1139,7 @@ assign_domain_page_replace(struct domain
             domain_put_page(d, mpaddr, pte, old_pte, 1);
         }
     }
-    perfc_incrc(assign_domain_page_replace);
+    perfc_incr(assign_domain_page_replace);
 }
 
 // caller must get_page(new_page) before
@@ -1202,7 +1202,7 @@ assign_domain_page_cmpxchg_rel(struct do
     set_gpfn_from_mfn(old_mfn, INVALID_M2P_ENTRY);
 
     domain_page_flush_and_put(d, mpaddr, pte, old_pte, old_page);
-    perfc_incrc(assign_domain_pge_cmpxchg_rel);
+    perfc_incr(assign_domain_pge_cmpxchg_rel);
     return 0;
 }
 
@@ -1264,7 +1264,7 @@ zap_domain_page_one(struct domain *d, un
     //   guest_physmap_remove_page()
     //     zap_domain_page_one()
     domain_put_page(d, mpaddr, pte, old_pte, (page_get_owner(page) != NULL));
-    perfc_incrc(zap_dcomain_page_one);
+    perfc_incr(zap_dcomain_page_one);
 }
 
 unsigned long
@@ -1277,7 +1277,7 @@ dom0vp_zap_physmap(struct domain *d, uns
     }
 
     zap_domain_page_one(d, gpfn << PAGE_SHIFT, INVALID_MFN);
-    perfc_incrc(dom0vp_zap_physmap);
+    perfc_incr(dom0vp_zap_physmap);
     return 0;
 }
 
@@ -1331,7 +1331,7 @@ __dom0vp_add_physmap(struct domain* d, u
            get_gpfn_from_mfn(mfn) != INVALID_M2P_ENTRY);
     assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, flags);
     //don't update p2m table because this page belongs to rd, not d.
-    perfc_incrc(dom0vp_add_physmap);
+    perfc_incr(dom0vp_add_physmap);
 out1:
     put_domain(rd);
     return error;
@@ -1501,7 +1501,7 @@ create_grant_host_mapping(unsigned long 
 #endif
                                ((flags & GNTMAP_readonly) ?
                                 ASSIGN_readonly : ASSIGN_writable));
-    perfc_incrc(create_grant_host_mapping);
+    perfc_incr(create_grant_host_mapping);
     return GNTST_okay;
 }
 
@@ -1565,7 +1565,7 @@ destroy_grant_host_mapping(unsigned long
            get_gpfn_from_mfn(mfn) == gpfn);
     domain_page_flush_and_put(d, gpaddr, pte, old_pte, page);
 
-    perfc_incrc(destroy_grant_host_mapping);
+    perfc_incr(destroy_grant_host_mapping);
     return GNTST_okay;
 }
 
@@ -1629,7 +1629,7 @@ steal_page(struct domain *d, struct page
             free_domheap_page(new);
             return -1;
         }
-        perfc_incrc(steal_page_refcount);
+        perfc_incr(steal_page_refcount);
     }
 
     spin_lock(&d->page_alloc_lock);
@@ -1703,7 +1703,7 @@ steal_page(struct domain *d, struct page
     list_del(&page->list);
 
     spin_unlock(&d->page_alloc_lock);
-    perfc_incrc(steal_page);
+    perfc_incr(steal_page);
     return 0;
 }
 
@@ -1723,7 +1723,7 @@ guest_physmap_add_page(struct domain *d,
 
     //BUG_ON(mfn != ((lookup_domain_mpa(d, gpfn << PAGE_SHIFT) & _PFN_MASK) >> 
PAGE_SHIFT));
 
-    perfc_incrc(guest_physmap_add_page);
+    perfc_incr(guest_physmap_add_page);
 }
 
 void
@@ -1732,7 +1732,7 @@ guest_physmap_remove_page(struct domain 
 {
     BUG_ON(mfn == 0);//XXX
     zap_domain_page_one(d, gpfn << PAGE_SHIFT, mfn);
-    perfc_incrc(guest_physmap_remove_page);
+    perfc_incr(guest_physmap_remove_page);
 }
 
 static void
@@ -1812,7 +1812,7 @@ domain_page_flush_and_put(struct domain*
         break;
     }
 #endif
-    perfc_incrc(domain_page_flush_and_put);
+    perfc_incr(domain_page_flush_and_put);
 }
 
 int
@@ -2009,7 +2009,7 @@ int get_page_type(struct page_info *page
 
                 if ( unlikely(!cpus_empty(mask)) )
                 {
-                    perfc_incrc(need_flush_tlb_flush);
+                    perfc_incr(need_flush_tlb_flush);
                     flush_tlb_mask(mask);
                 }
 
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/ia64/xen/privop.c
--- a/xen/arch/ia64/xen/privop.c        Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/ia64/xen/privop.c        Wed Mar 28 08:44:08 2007 +0000
@@ -641,15 +641,15 @@ static IA64FAULT priv_handle_op(VCPU * v
                        if (inst.M29.x3 != 0)
                                break;
                        if (inst.M30.x4 == 8 && inst.M30.x2 == 2) {
-                               perfc_incrc(mov_to_ar_imm);
+                               perfc_incr(mov_to_ar_imm);
                                return priv_mov_to_ar_imm(vcpu, inst);
                        }
                        if (inst.M44.x4 == 6) {
-                               perfc_incrc(ssm);
+                               perfc_incr(ssm);
                                return priv_ssm(vcpu, inst);
                        }
                        if (inst.M44.x4 == 7) {
-                               perfc_incrc(rsm);
+                               perfc_incr(rsm);
                                return priv_rsm(vcpu, inst);
                        }
                        break;
@@ -658,9 +658,9 @@ static IA64FAULT priv_handle_op(VCPU * v
                x6 = inst.M29.x6;
                if (x6 == 0x2a) {
                        if (privify_en && inst.M29.r2 > 63 && inst.M29.ar3 < 8)
-                               perfc_incrc(mov_from_ar); // privified mov from 
kr
+                               perfc_incr(mov_from_ar); // privified mov from 
kr
                        else
-                               perfc_incrc(mov_to_ar_reg);
+                               perfc_incr(mov_to_ar_reg);
                        return priv_mov_to_ar_reg(vcpu, inst);
                }
                if (inst.M29.x3 != 0)
@@ -676,9 +676,9 @@ static IA64FAULT priv_handle_op(VCPU * v
                        }
                }
                if (privify_en && x6 == 52 && inst.M28.r3 > 63)
-                       perfc_incrc(fc);
+                       perfc_incr(fc);
                else if (privify_en && x6 == 16 && inst.M43.r3 > 63)
-                       perfc_incrc(cpuid);
+                       perfc_incr(cpuid);
                else
                        perfc_incra(misc_privop, x6);
                return (*pfunc) (vcpu, inst);
@@ -688,23 +688,23 @@ static IA64FAULT priv_handle_op(VCPU * v
                        break;
                if (inst.B8.x6 == 0x08) {
                        IA64FAULT fault;
-                       perfc_incrc(rfi);
+                       perfc_incr(rfi);
                        fault = priv_rfi(vcpu, inst);
                        if (fault == IA64_NO_FAULT)
                                fault = IA64_RFI_IN_PROGRESS;
                        return fault;
                }
                if (inst.B8.x6 == 0x0c) {
-                       perfc_incrc(bsw0);
+                       perfc_incr(bsw0);
                        return priv_bsw0(vcpu, inst);
                }
                if (inst.B8.x6 == 0x0d) {
-                       perfc_incrc(bsw1);
+                       perfc_incr(bsw1);
                        return priv_bsw1(vcpu, inst);
                }
                if (inst.B8.x6 == 0x0) {
                        // break instr for privified cover
-                       perfc_incrc(cover);
+                       perfc_incr(cover);
                        return priv_cover(vcpu, inst);
                }
                break;
@@ -713,7 +713,7 @@ static IA64FAULT priv_handle_op(VCPU * v
                        break;
 #if 0
                if (inst.I26.x6 == 0 && inst.I26.x3 == 0) {
-                       perfc_incrc(cover);
+                       perfc_incr(cover);
                        return priv_cover(vcpu, inst);
                }
 #endif
@@ -721,13 +721,13 @@ static IA64FAULT priv_handle_op(VCPU * v
                        break;  // I26.x3 == I27.x3
                if (inst.I26.x6 == 0x2a) {
                        if (privify_en && inst.I26.r2 > 63 && inst.I26.ar3 < 8)
-                               perfc_incrc(mov_from_ar);       // privified 
mov from kr
+                               perfc_incr(mov_from_ar);        // privified 
mov from kr
                        else
-                               perfc_incrc(mov_to_ar_reg);
+                               perfc_incr(mov_to_ar_reg);
                        return priv_mov_to_ar_reg(vcpu, inst);
                }
                if (inst.I27.x6 == 0x0a) {
-                       perfc_incrc(mov_to_ar_imm);
+                       perfc_incr(mov_to_ar_imm);
                        return priv_mov_to_ar_imm(vcpu, inst);
                }
                break;
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/ia64/xen/privop_stat.c
--- a/xen/arch/ia64/xen/privop_stat.c   Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/ia64/xen/privop_stat.c   Wed Mar 28 08:44:08 2007 +0000
@@ -10,48 +10,39 @@ struct privop_addr_count {
        unsigned long addr[PRIVOP_COUNT_NADDRS];
        unsigned int count[PRIVOP_COUNT_NADDRS];
        unsigned int overflow;
-       atomic_t *perfc_addr;
-       atomic_t *perfc_count;
-       atomic_t *perfc_overflow;
 };
 
-#undef  PERFCOUNTER
+struct privop_addr_info {
+       enum perfcounter perfc_addr;
+       enum perfcounter perfc_count;
+       enum perfcounter perfc_overflow;
+};
+
 #define PERFCOUNTER(var, name)
-
-#undef  PERFCOUNTER_CPU
-#define PERFCOUNTER_CPU(var, name)
-
-#undef  PERFCOUNTER_ARRAY
 #define PERFCOUNTER_ARRAY(var, name, size)
 
-#undef  PERFSTATUS
 #define PERFSTATUS(var, name)
-
-#undef  PERFSTATUS_CPU
-#define PERFSTATUS_CPU(var, name)
-
-#undef  PERFSTATUS_ARRAY
 #define PERFSTATUS_ARRAY(var, name, size)
 
-#undef PERFPRIVOPADDR
 #define PERFPRIVOPADDR(name)                        \
     {                                               \
-        { 0 }, { 0 }, 0,                            \
-        perfcounters.privop_addr_##name##_addr,     \
-        perfcounters.privop_addr_##name##_count,    \
-        perfcounters.privop_addr_##name##_overflow  \
+        PERFC_privop_addr_##name##_addr,            \
+        PERFC_privop_addr_##name##_count,           \
+        PERFC_privop_addr_##name##_overflow         \
     },
 
-static struct privop_addr_count privop_addr_counter[] = {
+static const struct privop_addr_info privop_addr_info[] = {
 #include <asm/perfc_defn.h>
 };
 
 #define PRIVOP_COUNT_NINSTS \
-        (sizeof(privop_addr_counter) / sizeof(privop_addr_counter[0]))
+        (sizeof(privop_addr_info) / sizeof(privop_addr_info[0]))
+
+static DEFINE_PER_CPU(struct privop_addr_count[PRIVOP_COUNT_NINSTS], 
privop_addr_counter);
 
 void privop_count_addr(unsigned long iip, enum privop_inst inst)
 {
-       struct privop_addr_count *v = &privop_addr_counter[inst];
+       struct privop_addr_count *v = this_cpu(privop_addr_counter) + inst;
        int i;
 
        if (inst >= PRIVOP_COUNT_NINSTS)
@@ -72,31 +63,44 @@ void privop_count_addr(unsigned long iip
 
 void gather_privop_addrs(void)
 {
-       int i, j;
-       atomic_t *v;
-       for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) {
-               /* Note: addresses are truncated!  */
-               v = privop_addr_counter[i].perfc_addr;
-               for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
-                       atomic_set(&v[j], privop_addr_counter[i].addr[j]);
+       unsigned int cpu;
 
-               v = privop_addr_counter[i].perfc_count;
-               for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
-                       atomic_set(&v[j], privop_addr_counter[i].count[j]);
+       for_each_cpu ( cpu ) {
+               perfc_t *perfcounters = per_cpu(perfcounters, cpu);
+               struct privop_addr_count *s = per_cpu(privop_addr_counter, cpu);
+               int i, j;
+
+               for (i = 0; i < PRIVOP_COUNT_NINSTS; i++, s++) {
+                       perfc_t *d;
+
+                       /* Note: addresses are truncated!  */
+                       d = perfcounters + privop_addr_info[i].perfc_addr;
+                       for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
+                               d[j] = s->addr[j];
+
+                       d = perfcounters + privop_addr_info[i].perfc_count;
+                       for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
+                               d[j] = s->count[j];
                
-               atomic_set(privop_addr_counter[i].perfc_overflow,
-                          privop_addr_counter[i].overflow);
+                       perfcounters[privop_addr_info[i].perfc_overflow] =
+                               s->overflow;
+               }
        }
 }
 
 void reset_privop_addrs(void)
 {
-       int i, j;
-       for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) {
-               struct privop_addr_count *v = &privop_addr_counter[i];
-               for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
-                       v->addr[j] = v->count[j] = 0;
-               v->overflow = 0;
+       unsigned int cpu;
+
+       for_each_cpu ( cpu ) {
+               struct privop_addr_count *v = per_cpu(privop_addr_counter, cpu);
+               int i, j;
+
+               for (i = 0; i < PRIVOP_COUNT_NINSTS; i++, v++) {
+                       for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
+                               v->addr[j] = v->count[j] = 0;
+                       v->overflow = 0;
+               }
        }
 }
 #endif
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/ia64/xen/tlb_track.c
--- a/xen/arch/ia64/xen/tlb_track.c     Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/ia64/xen/tlb_track.c     Wed Mar 28 08:44:08 2007 +0000
@@ -216,14 +216,14 @@ tlb_track_insert_or_dirty(struct tlb_tra
     TLB_TRACK_RET_T ret = TLB_TRACK_NOT_FOUND;
 
 #if 0 /* this is done at vcpu_tlb_track_insert_or_dirty() */
-    perfc_incrc(tlb_track_iod);
+    perfc_incr(tlb_track_iod);
     if (!pte_tlb_tracking(old_pte)) {
-        perfc_incrc(tlb_track_iod_not_tracked);
+        perfc_incr(tlb_track_iod_not_tracked);
         return TLB_TRACK_NOT_TRACKED;
     }
 #endif
     if (pte_tlb_inserted_many(old_pte)) {
-        perfc_incrc(tlb_track_iod_tracked_many);
+        perfc_incr(tlb_track_iod_tracked_many);
         return TLB_TRACK_MANY;
     }
 
@@ -260,7 +260,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
             if (entry->vaddr == vaddr && entry->rid == rid) {
                 // tlb_track_printd("TLB_TRACK_FOUND\n");
                 ret = TLB_TRACK_FOUND;
-                perfc_incrc(tlb_track_iod_found);
+                perfc_incr(tlb_track_iod_found);
 #ifdef CONFIG_TLB_TRACK_CNT
                 entry->cnt++;
                 if (entry->cnt > TLB_TRACK_CNT_FORCE_MANY) {
@@ -276,7 +276,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
                      */
                      // tlb_track_entry_printf(entry);
                      // tlb_track_printd("cnt = %ld\n", entry->cnt);
-                    perfc_incrc(tlb_track_iod_force_many);
+                    perfc_incr(tlb_track_iod_force_many);
                     goto force_many;
                 }
 #endif
@@ -294,14 +294,14 @@ tlb_track_insert_or_dirty(struct tlb_tra
                 if (pte_val(ret_pte) != pte_val(old_pte)) {
                     // tlb_track_printd("TLB_TRACK_AGAIN\n");
                     ret = TLB_TRACK_AGAIN;
-                    perfc_incrc(tlb_track_iod_again);
+                    perfc_incr(tlb_track_iod_again);
                 } else {
                     // tlb_track_printd("TLB_TRACK_MANY del entry 0x%p\n",
                     //                  entry);
                     ret = TLB_TRACK_MANY;
                     list_del(&entry->list);
                     // tlb_track_entry_printf(entry);
-                    perfc_incrc(tlb_track_iod_tracked_many_del);
+                    perfc_incr(tlb_track_iod_tracked_many_del);
                 }
                 goto out;
             }
@@ -314,7 +314,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
          */
         // tlb_track_printd("TLB_TRACK_AGAIN\n");
         ret = TLB_TRACK_AGAIN;
-        perfc_incrc(tlb_track_iod_again);
+        perfc_incr(tlb_track_iod_again);
         goto out;
     }
 
@@ -323,7 +323,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
         /* Other thread else removed the tlb_track_entry after we got old_pte
            before we got spin lock. */
         ret = TLB_TRACK_AGAIN;
-        perfc_incrc(tlb_track_iod_again);
+        perfc_incr(tlb_track_iod_again);
         goto out;
     }
     if (new_entry == NULL && bit_to_be_set == _PAGE_TLB_INSERTED) {
@@ -334,10 +334,10 @@ tlb_track_insert_or_dirty(struct tlb_tra
             /* entry can't be allocated.
                fall down into full flush mode. */
             bit_to_be_set |= _PAGE_TLB_INSERTED_MANY;
-            perfc_incrc(tlb_track_iod_new_failed);
+            perfc_incr(tlb_track_iod_new_failed);
         }
         // tlb_track_printd("new_entry 0x%p\n", new_entry);
-        perfc_incrc(tlb_track_iod_new_entry);
+        perfc_incr(tlb_track_iod_new_entry);
         goto again;
     }
 
@@ -348,7 +348,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
         if (tlb_track_pte_zapped(old_pte, ret_pte)) {
             // tlb_track_printd("zapped TLB_TRACK_AGAIN\n");
             ret = TLB_TRACK_AGAIN;
-            perfc_incrc(tlb_track_iod_again);
+            perfc_incr(tlb_track_iod_again);
             goto out;
         }
 
@@ -359,7 +359,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
             // tlb_track_printd("iserted TLB_TRACK_MANY\n");
             BUG_ON(!pte_tlb_inserted(ret_pte));
             ret = TLB_TRACK_MANY;
-            perfc_incrc(tlb_track_iod_new_many);
+            perfc_incr(tlb_track_iod_new_many);
             goto out;
         }
         BUG_ON(pte_tlb_inserted(ret_pte));
@@ -381,7 +381,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
 #ifdef CONFIG_TLB_TRACK_CNT
         entry->cnt = 0;
 #endif
-        perfc_incrc(tlb_track_iod_insert);
+        perfc_incr(tlb_track_iod_insert);
         // tlb_track_entry_printf(entry);
     } else {
         goto out;
@@ -392,7 +392,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
     cpu_set(v->processor, entry->pcpu_dirty_mask);
     BUG_ON(v->vcpu_id >= NR_CPUS);
     vcpu_set(v->vcpu_id, entry->vcpu_dirty_mask);
-    perfc_incrc(tlb_track_iod_dirtied);
+    perfc_incr(tlb_track_iod_dirtied);
 
  out:
     spin_unlock(&tlb_track->hash_lock);
@@ -432,19 +432,19 @@ tlb_track_search_and_remove(struct tlb_t
     struct list_head* head = tlb_track_hash_head(tlb_track, ptep);
     struct tlb_track_entry* entry;
 
-    perfc_incrc(tlb_track_sar);
+    perfc_incr(tlb_track_sar);
     if (!pte_tlb_tracking(old_pte)) {
-        perfc_incrc(tlb_track_sar_not_tracked);
+        perfc_incr(tlb_track_sar_not_tracked);
         return TLB_TRACK_NOT_TRACKED;
     }
     if (!pte_tlb_inserted(old_pte)) {
         BUG_ON(pte_tlb_inserted_many(old_pte));
-        perfc_incrc(tlb_track_sar_not_found);
+        perfc_incr(tlb_track_sar_not_found);
         return TLB_TRACK_NOT_FOUND;
     }
     if (pte_tlb_inserted_many(old_pte)) {
         BUG_ON(!pte_tlb_inserted(old_pte));
-        perfc_incrc(tlb_track_sar_many);
+        perfc_incr(tlb_track_sar_many);
         return TLB_TRACK_MANY;
     }
 
@@ -475,14 +475,14 @@ tlb_track_search_and_remove(struct tlb_t
                          pte_tlb_inserted(current_pte))) {
                 BUG_ON(pte_tlb_inserted_many(current_pte));
                 spin_unlock(&tlb_track->hash_lock);
-                perfc_incrc(tlb_track_sar_many);
+                perfc_incr(tlb_track_sar_many);
                 return TLB_TRACK_MANY;
             }
 
             list_del(&entry->list);
             spin_unlock(&tlb_track->hash_lock);
             *entryp = entry;
-            perfc_incrc(tlb_track_sar_found);
+            perfc_incr(tlb_track_sar_found);
             // tlb_track_entry_printf(entry);
 #ifdef CONFIG_TLB_TRACK_CNT
             // tlb_track_printd("cnt = %ld\n", entry->cnt);
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/ia64/xen/vcpu.c
--- a/xen/arch/ia64/xen/vcpu.c  Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/ia64/xen/vcpu.c  Wed Mar 28 08:44:08 2007 +0000
@@ -1616,7 +1616,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u6
                        *pteval = (address & _PAGE_PPN_MASK) |
                                __DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX;
                        *itir = PAGE_SHIFT << 2;
-                       perfc_incrc(phys_translate);
+                       perfc_incr(phys_translate);
                        return IA64_NO_FAULT;
                }
        } else if (!region && warn_region0_address) {
@@ -1637,7 +1637,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u6
                if (trp != NULL) {
                        *pteval = trp->pte.val;
                        *itir = trp->itir;
-                       perfc_incrc(tr_translate);
+                       perfc_incr(tr_translate);
                        return IA64_NO_FAULT;
                }
        }
@@ -1647,7 +1647,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u6
                if (trp != NULL) {
                        *pteval = trp->pte.val;
                        *itir = trp->itir;
-                       perfc_incrc(tr_translate);
+                       perfc_incr(tr_translate);
                        return IA64_NO_FAULT;
                }
        }
@@ -1660,7 +1660,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u6
            && vcpu_match_tr_entry_no_p(trp, address, rid)) {
                *pteval = pte.val;
                *itir = trp->itir;
-               perfc_incrc(dtlb_translate);
+               perfc_incr(dtlb_translate);
                return IA64_USE_TLB;
        }
 
@@ -1709,7 +1709,7 @@ out:
 out:
        *itir = rr & RR_PS_MASK;
        *pteval = pte.val;
-       perfc_incrc(vhpt_translate);
+       perfc_incr(vhpt_translate);
        return IA64_NO_FAULT;
 }
 
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/ia64/xen/vhpt.c
--- a/xen/arch/ia64/xen/vhpt.c  Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/ia64/xen/vhpt.c  Wed Mar 28 08:44:08 2007 +0000
@@ -48,14 +48,14 @@ local_vhpt_flush(void)
        /* this must be after flush */
        tlbflush_update_time(&__get_cpu_var(vhpt_tlbflush_timestamp),
                             flush_time);
-       perfc_incrc(local_vhpt_flush);
+       perfc_incr(local_vhpt_flush);
 }
 
 void
 vcpu_vhpt_flush(struct vcpu* v)
 {
        __vhpt_flush(vcpu_vhpt_maddr(v));
-       perfc_incrc(vcpu_vhpt_flush);
+       perfc_incr(vcpu_vhpt_flush);
 }
 
 static void
@@ -248,7 +248,7 @@ void vcpu_flush_vtlb_all(struct vcpu *v)
           not running on this processor.  There is currently no easy way to
           check this.  */
 
-       perfc_incrc(vcpu_flush_vtlb_all);
+       perfc_incr(vcpu_flush_vtlb_all);
 }
 
 static void __vcpu_flush_vtlb_all(void *vcpu)
@@ -280,7 +280,7 @@ void domain_flush_vtlb_all(struct domain
                                                 __vcpu_flush_vtlb_all,
                                                 v, 1, 1);
        }
-       perfc_incrc(domain_flush_vtlb_all);
+       perfc_incr(domain_flush_vtlb_all);
 }
 
 // Callers may need to call smp_mb() before/after calling this.
@@ -322,7 +322,7 @@ void vcpu_flush_tlb_vhpt_range (u64 vadr
                                     vadr, 1UL << log_range);
        ia64_ptcl(vadr, log_range << 2);
        ia64_srlz_i();
-       perfc_incrc(vcpu_flush_tlb_vhpt_range);
+       perfc_incr(vcpu_flush_tlb_vhpt_range);
 }
 
 void domain_flush_vtlb_range (struct domain *d, u64 vadr, u64 addr_range)
@@ -361,7 +361,7 @@ void domain_flush_vtlb_range (struct dom
 
        /* ptc.ga  */
        platform_global_tlb_purge(vadr, vadr + addr_range, PAGE_SHIFT);
-       perfc_incrc(domain_flush_vtlb_range);
+       perfc_incr(domain_flush_vtlb_range);
 }
 
 #ifdef CONFIG_XEN_IA64_TLB_TRACK
@@ -391,11 +391,11 @@ __domain_flush_vtlb_track_entry(struct d
         */
        vcpu_get_rr(current, VRN7 << VRN_SHIFT, &rr7_rid);
        if (likely(rr7_rid == entry->rid)) {
-               perfc_incrc(tlb_track_use_rr7);
+               perfc_incr(tlb_track_use_rr7);
        } else {
                swap_rr0 = 1;
                vaddr = (vaddr << 3) >> 3;// force vrn0
-               perfc_incrc(tlb_track_swap_rr0);
+               perfc_incr(tlb_track_swap_rr0);
        }
 
        // tlb_track_entry_printf(entry);
@@ -435,18 +435,18 @@ __domain_flush_vtlb_track_entry(struct d
        /* ptc.ga  */
        if (local_purge) {
                ia64_ptcl(vaddr, PAGE_SHIFT << 2);
-               perfc_incrc(domain_flush_vtlb_local);
+               perfc_incr(domain_flush_vtlb_local);
        } else {
                /* ptc.ga has release semantics. */
                platform_global_tlb_purge(vaddr, vaddr + PAGE_SIZE,
                                          PAGE_SHIFT);
-               perfc_incrc(domain_flush_vtlb_global);
+               perfc_incr(domain_flush_vtlb_global);
        }
 
        if (swap_rr0) {
                vcpu_set_rr(current, 0, old_rid);
        }
-       perfc_incrc(domain_flush_vtlb_track_entry);
+       perfc_incr(domain_flush_vtlb_track_entry);
 }
 
 void
@@ -512,7 +512,7 @@ void gather_vhpt_stats(void)
                for (i = 0; i < VHPT_NUM_ENTRIES; i++, v++)
                        if (!(v->ti_tag & INVALID_TI_TAG))
                                vhpt_valid++;
-               perfc_seta(vhpt_valid_entries, cpu, vhpt_valid);
-       }
-}
-#endif
+               per_cpu(perfcounters, cpu)[PERFC_vhpt_valid_entries] = 
vhpt_valid;
+       }
+}
+#endif
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/powerpc/backtrace.c
--- a/xen/arch/powerpc/backtrace.c      Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/powerpc/backtrace.c      Wed Mar 28 08:44:08 2007 +0000
@@ -205,21 +205,6 @@ void show_backtrace_regs(struct cpu_user
     console_end_sync();
 }
 
-void __warn(char *file, int line)
-{
-    ulong sp;
-    ulong lr;
-
-    console_start_sync();
-    printk("WARN at %s:%d\n", file, line);
-
-    sp = (ulong)__builtin_frame_address(0);
-    lr = (ulong)__builtin_return_address(0);
-    backtrace(sp, lr, lr);
-
-    console_end_sync();
-}
-
 void dump_execution_state(void)
 {
     struct cpu_user_regs *regs = guest_cpu_user_regs();
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/powerpc/mm.c
--- a/xen/arch/powerpc/mm.c     Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/powerpc/mm.c     Wed Mar 28 08:44:08 2007 +0000
@@ -261,7 +261,7 @@ int get_page_type(struct page_info *page
 
                 if ( unlikely(!cpus_empty(mask)) )
                 {
-                    perfc_incrc(need_flush_tlb_flush);
+                    perfc_incr(need_flush_tlb_flush);
                     flush_tlb_mask(mask);
                 }
 
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/Rules.mk
--- a/xen/arch/x86/Rules.mk     Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/Rules.mk     Wed Mar 28 08:44:08 2007 +0000
@@ -59,6 +59,4 @@ HDRS += $(wildcard $(BASEDIR)/include/as
 HDRS += $(wildcard $(BASEDIR)/include/asm-x86/hvm/vmx/*.h)
 
 # Require GCC v3.4+ (to avoid issues with alignment constraints in Xen headers)
-ifneq ($(call cc-ver,$(CC),0x030400),y)
-$(error Xen requires at least gcc-3.4)
-endif
+$(call cc-ver-check,CC,0x030400,"Xen requires at least gcc-3.4")
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/apic.c
--- a/xen/arch/x86/apic.c       Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/apic.c       Wed Mar 28 08:44:08 2007 +0000
@@ -1076,7 +1076,7 @@ fastcall void smp_apic_timer_interrupt(s
 fastcall void smp_apic_timer_interrupt(struct cpu_user_regs * regs)
 {
     ack_APIC_irq();
-    perfc_incrc(apic_timer);
+    perfc_incr(apic_timer);
     raise_softirq(TIMER_SOFTIRQ);
 }
 
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/extable.c
--- a/xen/arch/x86/extable.c    Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/extable.c    Wed Mar 28 08:44:08 2007 +0000
@@ -72,7 +72,7 @@ search_pre_exception_table(struct cpu_us
     if ( fixup )
     {
         dprintk(XENLOG_INFO, "Pre-exception: %p -> %p\n", _p(addr), _p(fixup));
-        perfc_incrc(exception_fixed);
+        perfc_incr(exception_fixed);
     }
     return fixup;
 }
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c     Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/hvm/io.c     Wed Mar 28 08:44:08 2007 +0000
@@ -292,7 +292,11 @@ static inline void set_eflags_CF(int siz
 static inline void set_eflags_CF(int size, unsigned long v1,
                                  unsigned long v2, struct cpu_user_regs *regs)
 {
-    unsigned long mask = (1 << (8 * size)) - 1;
+    unsigned long mask;
+    
+    ASSERT((size <= sizeof(mask)) && (size > 0));
+
+    mask = ~0UL >> (8 * (sizeof(mask) - size));
 
     if ((v1 & mask) > (v2 & mask))
         regs->eflags |= X86_EFLAGS_CF;
@@ -303,7 +307,13 @@ static inline void set_eflags_OF(int siz
 static inline void set_eflags_OF(int size, unsigned long v1,
                                  unsigned long v2, unsigned long v3, struct 
cpu_user_regs *regs)
 {
-    if ((v3 ^ v2) & (v3 ^ v1) & (1 << ((8 * size) - 1)))
+    unsigned long mask;
+
+    ASSERT((size <= sizeof(mask)) && (size > 0));
+
+    mask = ~0UL >> (8 * (sizeof(mask) - size));
+    
+    if ((v3 ^ v2) & (v3 ^ v1) & mask)
         regs->eflags |= X86_EFLAGS_OF;
 }
 
@@ -317,7 +327,11 @@ static inline void set_eflags_ZF(int siz
 static inline void set_eflags_ZF(int size, unsigned long v1,
                                  struct cpu_user_regs *regs)
 {
-    unsigned long mask = (1 << (8 * size)) - 1;
+    unsigned long mask;
+    
+    ASSERT((size <= sizeof(mask)) && (size > 0));
+
+    mask = ~0UL >> (8 * (sizeof(mask) - size));
 
     if ((v1 & mask) == 0)
         regs->eflags |= X86_EFLAGS_ZF;
@@ -326,7 +340,13 @@ static inline void set_eflags_SF(int siz
 static inline void set_eflags_SF(int size, unsigned long v1,
                                  struct cpu_user_regs *regs)
 {
-    if (v1 & (1 << ((8 * size) - 1)))
+    unsigned long mask;
+    
+    ASSERT((size <= sizeof(mask)) && (size > 0));
+
+    mask = ~0UL >> (8 * (sizeof(mask) - size));
+
+    if (v1 & mask)
         regs->eflags |= X86_EFLAGS_SF;
 }
 
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c       Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/hvm/svm/intr.c       Wed Mar 28 08:44:08 2007 +0000
@@ -64,87 +64,75 @@ asmlinkage void svm_intr_assist(void)
 {
     struct vcpu *v = current;
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-    struct periodic_time *pt;
     int intr_type = APIC_DM_EXTINT;
     int intr_vector = -1;
-    int re_injecting = 0;
 
-    /* Check if an Injection is active */
-    /* Previous Interrupt delivery caused this Intercept? */
+    /*
+     * Do not deliver a virtual interrupt (vintr) if an exception is pending.
+     * This is because the delivery of the exception can arbitrarily delay
+     * the injection of the vintr (for example, if the exception is handled
+     * via an interrupt gate, hence zeroing RFLAGS.IF). In the meantime the
+     * vTPR can be modified upwards and we can end up delivering the vintr
+     * when it is not in fact valid to do so (because we do not re-check the
+     * vTPR value). Moreover, the guest will be able to see the updated
+     * APIC/PIC state (as if the interrupt had been acknowledged) yet will not
+     * have actually received the interrupt. This could confuse the guest!
+     */
+    if ( vmcb->eventinj.fields.v )
+        return;
+
+    /*
+     * Previous Interrupt delivery caused this intercept?
+     * This will happen if the injection is latched by the processor (hence
+     * clearing vintr.fields.irq) but then subsequently a fault occurs (e.g.,
+     * due to lack of shadow mapping of guest IDT or guest-kernel stack).
+     * 
+     * NB. Exceptions that fault during delivery are lost. This needs to be
+     * fixed but we'll usually get away with it since faults are usually
+     * idempotent. But this isn't the case for e.g. software interrupts!
+     */
     if ( vmcb->exitintinfo.fields.v && (vmcb->exitintinfo.fields.type == 0) )
     {
-        v->arch.hvm_svm.saved_irq_vector = vmcb->exitintinfo.fields.vector;
+        intr_vector = vmcb->exitintinfo.fields.vector;
         vmcb->exitintinfo.bytes = 0;
-        re_injecting = 1;
+        HVMTRACE_1D(REINJ_VIRQ, v, intr_vector);
+        svm_inject_extint(v, intr_vector);
+        return;
     }
 
-    /* Previous interrupt still pending? */
+    /*
+     * Previous interrupt still pending? This occurs if we return from VMRUN
+     * very early in the entry-to-guest process. Usually this is because an
+     * external physical interrupt was pending when we executed VMRUN.
+     */
     if ( vmcb->vintr.fields.irq )
+        return;
+
+    /* Crank the handle on interrupt state and check for new interrrupts. */
+    pt_update_irq(v);
+    hvm_set_callback_irq_level();
+    if ( !cpu_has_pending_irq(v) )
+        return;
+
+    /*
+     * Create a 'fake' virtual interrupt on to intercept as soon as the
+     * guest _can_ take interrupts.  Do not obtain the next interrupt from
+     * the vlapic/pic if unable to inject.
+     */
+    if ( irq_masked(vmcb->rflags) || vmcb->interrupt_shadow )  
     {
-        intr_vector = vmcb->vintr.fields.vector;
-        vmcb->vintr.bytes = 0;
-        re_injecting = 1;
-    }
-    /* Pending IRQ saved at last VMExit? */
-    else if ( v->arch.hvm_svm.saved_irq_vector >= 0 )
-    {
-        intr_vector = v->arch.hvm_svm.saved_irq_vector;
-        v->arch.hvm_svm.saved_irq_vector = -1;
-        re_injecting = 1;
-    }
-    /* Now let's check for newer interrrupts  */
-    else
-    {
-        pt_update_irq(v);
-
-        hvm_set_callback_irq_level();
-
-        if ( cpu_has_pending_irq(v) )
-        {
-            /*
-             * Create a 'fake' virtual interrupt on to intercept as soon
-             * as the guest _can_ take interrupts.  Do not obtain the next
-             * interrupt from the vlapic/pic if unable to inject.
-             */
-            if ( irq_masked(vmcb->rflags) || vmcb->interrupt_shadow )  
-            {
-                vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR;
-                HVMTRACE_2D(INJ_VIRQ, v, 0x0, /*fake=*/ 1);
-                svm_inject_extint(v, 0x0); /* actual vector doesn't really 
matter */
-                return;
-            }
-            intr_vector = cpu_get_interrupt(v, &intr_type);
-        }
+        vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR;
+        HVMTRACE_2D(INJ_VIRQ, v, 0x0, /*fake=*/ 1);
+        svm_inject_extint(v, 0x0); /* actual vector doesn't matter */
+        return;
     }
 
-    /* have we got an interrupt to inject? */
-    if ( intr_vector < 0 )
-        return;
+    /* Okay, we can deliver the interrupt: grab it and update PIC state. */
+    intr_vector = cpu_get_interrupt(v, &intr_type);
+    BUG_ON(intr_vector < 0);
 
-    switch ( intr_type )
-    {
-    case APIC_DM_EXTINT:
-    case APIC_DM_FIXED:
-    case APIC_DM_LOWEST:
-        /* Re-injecting a PIT interruptt? */
-        if ( re_injecting && (pt = is_pt_irq(v, intr_vector, intr_type)) )
-            ++pt->pending_intr_nr;
-        /* let's inject this interrupt */
-        if (re_injecting)
-            HVMTRACE_1D(REINJ_VIRQ, v, intr_vector);
-        else
-            HVMTRACE_2D(INJ_VIRQ, v, intr_vector, /*fake=*/ 0);
-        svm_inject_extint(v, intr_vector);
-        break;
-    case APIC_DM_SMI:
-    case APIC_DM_NMI:
-    case APIC_DM_INIT:
-    case APIC_DM_STARTUP:
-    default:
-        printk("Unsupported interrupt type: %d\n", intr_type);
-        BUG();
-        break;
-    }
+    HVMTRACE_2D(INJ_VIRQ, v, intr_vector, /*fake=*/ 0);
+    svm_inject_extint(v, intr_vector);
 
     pt_intr_post(v, intr_vector, intr_type);
 }
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/hvm/svm/svm.c        Wed Mar 28 08:44:08 2007 +0000
@@ -64,8 +64,8 @@ extern int svm_dbg_on;
 extern int svm_dbg_on;
 void svm_dump_regs(const char *from, struct cpu_user_regs *regs);
 
-static int svm_do_vmmcall_reset_to_realmode(struct vcpu *v,
-                                            struct cpu_user_regs *regs);
+static int svm_reset_to_realmode(struct vcpu *v,
+                                 struct cpu_user_regs *regs);
 
 /* va of hardware host save area     */
 static void *hsa[NR_CPUS] __read_mostly;
@@ -749,19 +749,21 @@ static void svm_init_ap_context(
     struct vcpu_guest_context *ctxt, int vcpuid, int trampoline_vector)
 {
     struct vcpu *v;
+    struct vmcb_struct *vmcb;
     cpu_user_regs_t *regs;
     u16 cs_sel;
 
     /* We know this is safe because hvm_bringup_ap() does it */
     v = current->domain->vcpu[vcpuid];
+    vmcb = v->arch.hvm_svm.vmcb;
     regs = &v->arch.guest_context.user_regs;
 
     memset(ctxt, 0, sizeof(*ctxt));
 
     /*
      * We execute the trampoline code in real mode. The trampoline vector
-     * passed to us is page alligned and is the physicall frame number for
-     * the code. We will execute this code in real mode. 
+     * passed to us is page alligned and is the physical frame number for
+     * the code. We will execute this code in real mode.
      */
     cs_sel = trampoline_vector << 8;
     ctxt->user_regs.eip = 0x0;
@@ -771,11 +773,11 @@ static void svm_init_ap_context(
      * This is the launch of an AP; set state so that we begin executing
      * the trampoline code in real-mode.
      */
-    svm_do_vmmcall_reset_to_realmode(v, regs);  
+    svm_reset_to_realmode(v, regs);  
     /* Adjust the vmcb's hidden register state. */
-    v->arch.hvm_svm.vmcb->rip = 0;
-    v->arch.hvm_svm.vmcb->cs.sel = cs_sel;
-    v->arch.hvm_svm.vmcb->cs.base = (cs_sel << 4);
+    vmcb->rip = 0;
+    vmcb->cs.sel = cs_sel;
+    vmcb->cs.base = (cs_sel << 4);
 }
 
 static void svm_init_hypercall_page(struct domain *d, void *hypercall_page)
@@ -960,8 +962,6 @@ static int svm_vcpu_initialise(struct vc
     v->arch.schedule_tail    = arch_svm_do_resume;
     v->arch.ctxt_switch_from = svm_ctxt_switch_from;
     v->arch.ctxt_switch_to   = svm_ctxt_switch_to;
-
-    v->arch.hvm_svm.saved_irq_vector = -1;
 
     v->arch.hvm_svm.launch_core = -1;
 
@@ -2494,8 +2494,8 @@ void svm_handle_invlpg(const short invlp
  *
  * returns 0 on success, non-zero otherwise
  */
-static int svm_do_vmmcall_reset_to_realmode(struct vcpu *v, 
-                                            struct cpu_user_regs *regs)
+static int svm_reset_to_realmode(struct vcpu *v, 
+                                 struct cpu_user_regs *regs)
 {
     struct vmcb_struct *vmcb;
 
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c       Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/hvm/svm/vmcb.c       Wed Mar 28 08:44:08 2007 +0000
@@ -203,6 +203,7 @@ static int construct_vmcb(struct vcpu *v
         vmcb->g_pat = 0x0007040600070406ULL; /* guest PAT */
         vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_PG;
         vmcb->h_cr3 = pagetable_get_paddr(v->domain->arch.phys_table);
+        vmcb->cr4 = arch_svm->cpu_shadow_cr4 = 0;
     }
 
     return 0;
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/hvm/vmx/intr.c
--- a/xen/arch/x86/hvm/vmx/intr.c       Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/hvm/vmx/intr.c       Wed Mar 28 08:44:08 2007 +0000
@@ -89,7 +89,7 @@ asmlinkage void vmx_intr_assist(void)
 asmlinkage void vmx_intr_assist(void)
 {
     int intr_type = 0;
-    int highest_vector;
+    int intr_vector;
     unsigned long eflags;
     struct vcpu *v = current;
     unsigned int idtv_info_field;
@@ -106,8 +106,9 @@ asmlinkage void vmx_intr_assist(void)
 
     if ( unlikely(v->arch.hvm_vmx.vector_injected) )
     {
-        v->arch.hvm_vmx.vector_injected=0;
-        if (unlikely(has_ext_irq)) enable_irq_window(v);
+        v->arch.hvm_vmx.vector_injected = 0;
+        if ( unlikely(has_ext_irq) )
+            enable_irq_window(v);
         return;
     }
 
@@ -132,7 +133,6 @@ asmlinkage void vmx_intr_assist(void)
             enable_irq_window(v);
 
         HVM_DBG_LOG(DBG_LEVEL_1, "idtv_info_field=%x", idtv_info_field);
-
         return;
     }
 
@@ -154,30 +154,13 @@ asmlinkage void vmx_intr_assist(void)
         return;
     }
 
-    highest_vector = cpu_get_interrupt(v, &intr_type);
-    if ( highest_vector < 0 )
-        return;
+    intr_vector = cpu_get_interrupt(v, &intr_type);
+    BUG_ON(intr_vector < 0);
 
-    switch ( intr_type )
-    {
-    case APIC_DM_EXTINT:
-    case APIC_DM_FIXED:
-    case APIC_DM_LOWEST:
-        HVMTRACE_2D(INJ_VIRQ, v, highest_vector, /*fake=*/ 0);
-        vmx_inject_extint(v, highest_vector, VMX_DELIVER_NO_ERROR_CODE);
-        break;
+    HVMTRACE_2D(INJ_VIRQ, v, intr_vector, /*fake=*/ 0);
+    vmx_inject_extint(v, intr_vector, VMX_DELIVER_NO_ERROR_CODE);
 
-    case APIC_DM_SMI:
-    case APIC_DM_NMI:
-    case APIC_DM_INIT:
-    case APIC_DM_STARTUP:
-    default:
-        printk("Unsupported interrupt type\n");
-        BUG();
-        break;
-    }
-
-    pt_intr_post(v, highest_vector, intr_type);
+    pt_intr_post(v, intr_vector, intr_type);
 }
 
 /*
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c        Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/irq.c        Wed Mar 28 08:44:08 2007 +0000
@@ -56,7 +56,7 @@ asmlinkage void do_IRQ(struct cpu_user_r
     irq_desc_t       *desc = &irq_desc[vector];
     struct irqaction *action;
 
-    perfc_incrc(irqs);
+    perfc_incr(irqs);
 
     spin_lock(&desc->lock);
     desc->handler->ack(vector);
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/mm.c Wed Mar 28 08:44:08 2007 +0000
@@ -1726,7 +1726,7 @@ int get_page_type(struct page_info *page
                      (!shadow_mode_enabled(page_get_owner(page)) ||
                       ((nx & PGT_type_mask) == PGT_writable_page)) )
                 {
-                    perfc_incrc(need_flush_tlb_flush);
+                    perfc_incr(need_flush_tlb_flush);
                     flush_tlb_mask(mask);
                 }
 
@@ -1969,6 +1969,8 @@ int do_mmuext_op(
         if ( unlikely(!guest_handle_is_null(pdone)) )
             (void)copy_from_guest(&done, pdone, 1);
     }
+    else
+        perfc_incr(calls_to_mmuext_op);
 
     if ( unlikely(!guest_handle_okay(uops, count)) )
     {
@@ -2223,6 +2225,8 @@ int do_mmuext_op(
 
     UNLOCK_BIGLOCK(d);
 
+    perfc_add(num_mmuext_ops, i);
+
  out:
     /* Add incremental work we have done to the @done output parameter. */
     if ( unlikely(!guest_handle_is_null(pdone)) )
@@ -2257,6 +2261,8 @@ int do_mmu_update(
         if ( unlikely(!guest_handle_is_null(pdone)) )
             (void)copy_from_guest(&done, pdone, 1);
     }
+    else
+        perfc_incr(calls_to_mmu_update);
 
     if ( unlikely(!guest_handle_okay(ureqs, count)) )
     {
@@ -2272,9 +2278,6 @@ int do_mmu_update(
 
     domain_mmap_cache_init(&mapcache);
     domain_mmap_cache_init(&sh_mapcache);
-
-    perfc_incrc(calls_to_mmu_update);
-    perfc_addc(num_page_updates, count);
 
     LOCK_BIGLOCK(d);
 
@@ -2431,12 +2434,14 @@ int do_mmu_update(
         guest_handle_add_offset(ureqs, 1);
     }
 
+    process_deferred_ops();
+
+    UNLOCK_BIGLOCK(d);
+
     domain_mmap_cache_destroy(&mapcache);
     domain_mmap_cache_destroy(&sh_mapcache);
 
-    process_deferred_ops();
-
-    UNLOCK_BIGLOCK(d);
+    perfc_add(num_page_updates, i);
 
  out:
     /* Add incremental work we have done to the @done output parameter. */
@@ -2724,7 +2729,7 @@ int do_update_va_mapping(unsigned long v
     cpumask_t      pmask;
     int            rc  = 0;
 
-    perfc_incrc(calls_to_update_va);
+    perfc_incr(calls_to_update_va);
 
     if ( unlikely(!__addr_ok(va) && !paging_mode_external(d)) )
         return -EINVAL;
@@ -2739,6 +2744,10 @@ int do_update_va_mapping(unsigned long v
     if ( pl1e )
         guest_unmap_l1e(v, pl1e);
     pl1e = NULL;
+
+    process_deferred_ops();
+
+    UNLOCK_BIGLOCK(d);
 
     switch ( flags & UVMF_FLUSHTYPE_MASK )
     {
@@ -2785,10 +2794,6 @@ int do_update_va_mapping(unsigned long v
         break;
     }
 
-    process_deferred_ops();
-    
-    UNLOCK_BIGLOCK(d);
-
     return rc;
 }
 
@@ -2805,6 +2810,9 @@ int do_update_va_mapping_otherdomain(uns
         return -ESRCH;
 
     rc = do_update_va_mapping(va, val64, flags);
+
+    BUG_ON(this_cpu(percpu_mm_info).deferred_ops);
+    process_deferred_ops(); /* only to clear foreigndom */
 
     return rc;
 }
@@ -3378,7 +3386,7 @@ int ptwr_do_page_fault(struct vcpu *v, u
         goto bail;
 
     UNLOCK_BIGLOCK(d);
-    perfc_incrc(ptwr_emulations);
+    perfc_incr(ptwr_emulations);
     return EXCRET_fault_fixed;
 
  bail:
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c   Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/mm/shadow/common.c   Wed Mar 28 08:44:08 2007 +0000
@@ -276,7 +276,7 @@ hvm_emulate_write(enum x86_segment seg,
 
     /* How many emulations could we save if we unshadowed on stack writes? */
     if ( seg == x86_seg_ss )
-        perfc_incrc(shadow_fault_emulate_stack);
+        perfc_incr(shadow_fault_emulate_stack);
 
     rc = hvm_translate_linear_addr(
         seg, offset, bytes, hvm_access_write, sh_ctxt, &addr);
@@ -804,7 +804,7 @@ void shadow_prealloc(struct domain *d, u
     ASSERT(v != NULL); /* Shouldn't have enabled shadows if we've no vcpus  */
 
     /* Stage one: walk the list of pinned pages, unpinning them */
-    perfc_incrc(shadow_prealloc_1);
+    perfc_incr(shadow_prealloc_1);
     list_for_each_backwards_safe(l, t, &d->arch.paging.shadow.pinned_shadows)
     {
         sp = list_entry(l, struct shadow_page_info, list);
@@ -820,7 +820,7 @@ void shadow_prealloc(struct domain *d, u
     /* Stage two: all shadow pages are in use in hierarchies that are
      * loaded in cr3 on some vcpu.  Walk them, unhooking the non-Xen
      * mappings. */
-    perfc_incrc(shadow_prealloc_2);
+    perfc_incr(shadow_prealloc_2);
 
     for_each_vcpu(d, v2) 
         for ( i = 0 ; i < 4 ; i++ )
@@ -929,7 +929,7 @@ mfn_t shadow_alloc(struct domain *d,
     ASSERT(shadow_locked_by_me(d));
     ASSERT(order <= SHADOW_MAX_ORDER);
     ASSERT(shadow_type != SH_type_none);
-    perfc_incrc(shadow_alloc);
+    perfc_incr(shadow_alloc);
 
     /* Find smallest order which can satisfy the request. */
     for ( i = order; i <= SHADOW_MAX_ORDER; i++ )
@@ -967,7 +967,7 @@ mfn_t shadow_alloc(struct domain *d,
         tlbflush_filter(mask, sp[i].tlbflush_timestamp);
         if ( unlikely(!cpus_empty(mask)) )
         {
-            perfc_incrc(shadow_alloc_tlbflush);
+            perfc_incr(shadow_alloc_tlbflush);
             flush_tlb_mask(mask);
         }
         /* Now safe to clear the page for reuse */
@@ -997,7 +997,7 @@ void shadow_free(struct domain *d, mfn_t
     int i;
 
     ASSERT(shadow_locked_by_me(d));
-    perfc_incrc(shadow_free);
+    perfc_incr(shadow_free);
 
     shadow_type = sp->type;
     ASSERT(shadow_type != SH_type_none);
@@ -1406,7 +1406,7 @@ mfn_t shadow_hash_lookup(struct vcpu *v,
 
     sh_hash_audit(d);
 
-    perfc_incrc(shadow_hash_lookups);
+    perfc_incr(shadow_hash_lookups);
     key = sh_hash(n, t);
     sh_hash_audit_bucket(d, key);
 
@@ -1434,7 +1434,7 @@ mfn_t shadow_hash_lookup(struct vcpu *v,
             }
             else
             {
-                perfc_incrc(shadow_hash_lookup_head);
+                perfc_incr(shadow_hash_lookup_head);
             }
             return shadow_page_to_mfn(sp);
         }
@@ -1442,7 +1442,7 @@ mfn_t shadow_hash_lookup(struct vcpu *v,
         sp = sp->next_shadow;
     }
 
-    perfc_incrc(shadow_hash_lookup_miss);
+    perfc_incr(shadow_hash_lookup_miss);
     return _mfn(INVALID_MFN);
 }
 
@@ -1460,7 +1460,7 @@ void shadow_hash_insert(struct vcpu *v, 
 
     sh_hash_audit(d);
 
-    perfc_incrc(shadow_hash_inserts);
+    perfc_incr(shadow_hash_inserts);
     key = sh_hash(n, t);
     sh_hash_audit_bucket(d, key);
     
@@ -1486,7 +1486,7 @@ void shadow_hash_delete(struct vcpu *v, 
 
     sh_hash_audit(d);
 
-    perfc_incrc(shadow_hash_deletes);
+    perfc_incr(shadow_hash_deletes);
     key = sh_hash(n, t);
     sh_hash_audit_bucket(d, key);
     
@@ -1713,7 +1713,7 @@ int sh_remove_write_access(struct vcpu *
          || (pg->u.inuse.type_info & PGT_count_mask) == 0 )
         return 0;
 
-    perfc_incrc(shadow_writeable);
+    perfc_incr(shadow_writeable);
 
     /* If this isn't a "normal" writeable page, the domain is trying to 
      * put pagetables in special memory of some kind.  We can't allow that. */
@@ -1735,7 +1735,7 @@ int sh_remove_write_access(struct vcpu *
 
 #define GUESS(_a, _h) do {                                                \
             if ( v->arch.paging.mode->shadow.guess_wrmap(v, (_a), gmfn) ) \
-                perfc_incrc(shadow_writeable_h_ ## _h);                   \
+                perfc_incr(shadow_writeable_h_ ## _h);                   \
             if ( (pg->u.inuse.type_info & PGT_count_mask) == 0 )          \
                 return 1;                                                 \
         } while (0)
@@ -1808,7 +1808,7 @@ int sh_remove_write_access(struct vcpu *
             callbacks[shtype](v, last_smfn, gmfn);
 
         if ( (pg->u.inuse.type_info & PGT_count_mask) != old_count )
-            perfc_incrc(shadow_writeable_h_5);
+            perfc_incr(shadow_writeable_h_5);
     }
 
     if ( (pg->u.inuse.type_info & PGT_count_mask) == 0 )
@@ -1817,7 +1817,7 @@ int sh_remove_write_access(struct vcpu *
 #endif /* SHADOW_OPTIMIZATIONS & SHOPT_WRITABLE_HEURISTIC */
     
     /* Brute-force search of all the shadows, by walking the hash */
-    perfc_incrc(shadow_writeable_bf);
+    perfc_incr(shadow_writeable_bf);
     hash_foreach(v, callback_mask, callbacks, gmfn);
 
     /* If that didn't catch the mapping, something is very wrong */
@@ -1888,7 +1888,7 @@ int sh_remove_all_mappings(struct vcpu *
         | 1 << SH_type_fl1_64_shadow
         ;
 
-    perfc_incrc(shadow_mappings);
+    perfc_incr(shadow_mappings);
     if ( (page->count_info & PGC_count_mask) == 0 )
         return 0;
 
@@ -1903,7 +1903,7 @@ int sh_remove_all_mappings(struct vcpu *
      * Heuristics for finding the (probably) single mapping of this gmfn */
     
     /* Brute-force search of all the shadows, by walking the hash */
-    perfc_incrc(shadow_mappings_bf);
+    perfc_incr(shadow_mappings_bf);
     hash_foreach(v, callback_mask, callbacks, gmfn);
 
     /* If that didn't catch the mapping, something is very wrong */
@@ -1992,9 +1992,9 @@ static int sh_remove_shadow_via_pointer(
     
     sh_unmap_domain_page(vaddr);
     if ( rc )
-        perfc_incrc(shadow_up_pointer);
+        perfc_incr(shadow_up_pointer);
     else
-        perfc_incrc(shadow_unshadow_bf);
+        perfc_incr(shadow_unshadow_bf);
 
     return rc;
 }
@@ -2093,7 +2093,7 @@ void sh_remove_shadows(struct vcpu *v, m
     }
 
     /* Search for this shadow in all appropriate shadows */
-    perfc_incrc(shadow_unshadow);
+    perfc_incr(shadow_unshadow);
     sh_flags = pg->shadow_flags;
 
     /* Lower-level shadows need to be excised from upper-level shadows.
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c    Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/mm/shadow/multi.c    Wed Mar 28 08:44:08 2007 +0000
@@ -109,7 +109,7 @@ get_shadow_status(struct vcpu *v, mfn_t 
 /* Look for shadows in the hash table */
 {
     mfn_t smfn = shadow_hash_lookup(v, mfn_x(gmfn), shadow_type);
-    perfc_incrc(shadow_get_shadow_status);
+    perfc_incr(shadow_get_shadow_status);
     return smfn;
 }
 
@@ -209,7 +209,7 @@ guest_walk_tables(struct vcpu *v, unsign
 {
     ASSERT(!guest_op || shadow_locked_by_me(v->domain));
 
-    perfc_incrc(shadow_guest_walk);
+    perfc_incr(shadow_guest_walk);
     memset(gw, 0, sizeof(*gw));
     gw->va = va;
 
@@ -448,14 +448,14 @@ static u32 guest_set_ad_bits(struct vcpu
              == (_PAGE_DIRTY | _PAGE_ACCESSED) )
             return flags;  /* Guest already has A and D bits set */
         flags |= _PAGE_DIRTY | _PAGE_ACCESSED;
-        perfc_incrc(shadow_ad_update);
+        perfc_incr(shadow_ad_update);
     }
     else 
     {
         if ( flags & _PAGE_ACCESSED )
             return flags;  /* Guest already has A bit set */
         flags |= _PAGE_ACCESSED;
-        perfc_incrc(shadow_a_update);
+        perfc_incr(shadow_a_update);
     }
 
     /* Set the bit(s) */
@@ -863,7 +863,7 @@ shadow_write_entries(void *d, void *s, i
      * using map_domain_page() to get a writeable mapping if we need to. */
     if ( __copy_to_user(d, d, sizeof (unsigned long)) != 0 ) 
     {
-        perfc_incrc(shadow_linear_map_failed);
+        perfc_incr(shadow_linear_map_failed);
         map = sh_map_domain_page(mfn);
         ASSERT(map != NULL);
         dst = map + ((unsigned long)dst & (PAGE_SIZE - 1));
@@ -925,7 +925,7 @@ shadow_get_page_from_l1e(shadow_l1e_t sl
 
     if ( unlikely(!res) )
     {
-        perfc_incrc(shadow_get_page_fail);
+        perfc_incr(shadow_get_page_fail);
         SHADOW_PRINTK("failed: l1e=" SH_PRI_pte "\n");
     }
 
@@ -2198,7 +2198,7 @@ static int validate_gl4e(struct vcpu *v,
     mfn_t sl3mfn = _mfn(INVALID_MFN);
     int result = 0;
 
-    perfc_incrc(shadow_validate_gl4e_calls);
+    perfc_incr(shadow_validate_gl4e_calls);
 
     if ( guest_l4e_get_flags(*new_gl4e) & _PAGE_PRESENT )
     {
@@ -2250,7 +2250,7 @@ static int validate_gl3e(struct vcpu *v,
     mfn_t sl2mfn = _mfn(INVALID_MFN);
     int result = 0;
 
-    perfc_incrc(shadow_validate_gl3e_calls);
+    perfc_incr(shadow_validate_gl3e_calls);
 
     if ( guest_l3e_get_flags(*new_gl3e) & _PAGE_PRESENT )
     {
@@ -2277,7 +2277,7 @@ static int validate_gl2e(struct vcpu *v,
     mfn_t sl1mfn = _mfn(INVALID_MFN);
     int result = 0;
 
-    perfc_incrc(shadow_validate_gl2e_calls);
+    perfc_incr(shadow_validate_gl2e_calls);
 
     if ( guest_l2e_get_flags(*new_gl2e) & _PAGE_PRESENT )
     {
@@ -2363,7 +2363,7 @@ static int validate_gl1e(struct vcpu *v,
     mfn_t gmfn;
     int result = 0, mmio;
 
-    perfc_incrc(shadow_validate_gl1e_calls);
+    perfc_incr(shadow_validate_gl1e_calls);
 
     gfn = guest_l1e_get_gfn(*new_gl1e);
     gmfn = vcpu_gfn_to_mfn(v, gfn);
@@ -2523,7 +2523,7 @@ static inline void check_for_early_unsha
         u32 flags = mfn_to_page(gmfn)->shadow_flags;
         if ( !(flags & (SHF_L2_32|SHF_L2_PAE|SHF_L2H_PAE|SHF_L4_64)) )
         {
-            perfc_incrc(shadow_early_unshadow);
+            perfc_incr(shadow_early_unshadow);
             sh_remove_shadows(v, gmfn, 0, 0 /* Slow, can fail to unshadow */ );
         } 
     }
@@ -2642,7 +2642,7 @@ static int sh_page_fault(struct vcpu *v,
     SHADOW_PRINTK("d:v=%u:%u va=%#lx err=%u\n",
                    v->domain->domain_id, v->vcpu_id, va, regs->error_code);
 
-    perfc_incrc(shadow_fault);
+    perfc_incr(shadow_fault);
     //
     // XXX: Need to think about eventually mapping superpages directly in the
     //      shadow (when possible), as opposed to splintering them into a
@@ -2670,7 +2670,7 @@ static int sh_page_fault(struct vcpu *v,
                     ASSERT(regs->error_code & PFEC_page_present);
                     regs->error_code ^= (PFEC_reserved_bit|PFEC_page_present);
                     reset_early_unshadow(v);
-                    perfc_incrc(shadow_fault_fast_gnp);
+                    perfc_incr(shadow_fault_fast_gnp);
                     SHADOW_PRINTK("fast path not-present\n");
                     return 0;
                 }
@@ -2688,7 +2688,7 @@ static int sh_page_fault(struct vcpu *v,
                        << PAGE_SHIFT) 
                     | (va & ~PAGE_MASK);
             }
-            perfc_incrc(shadow_fault_fast_mmio);
+            perfc_incr(shadow_fault_fast_mmio);
             SHADOW_PRINTK("fast path mmio %#"PRIpaddr"\n", gpa);
             reset_early_unshadow(v);
             handle_mmio(gpa);
@@ -2699,7 +2699,7 @@ static int sh_page_fault(struct vcpu *v,
             /* This should be exceptionally rare: another vcpu has fixed
              * the tables between the fault and our reading the l1e. 
              * Retry and let the hardware give us the right fault next time. */
-            perfc_incrc(shadow_fault_fast_fail);
+            perfc_incr(shadow_fault_fast_fail);
             SHADOW_PRINTK("fast path false alarm!\n");            
             return EXCRET_fault_fixed;
         }
@@ -2746,7 +2746,7 @@ static int sh_page_fault(struct vcpu *v,
             goto mmio;
         }
 
-        perfc_incrc(shadow_fault_bail_not_present);
+        perfc_incr(shadow_fault_bail_not_present);
         goto not_a_shadow_fault;
     }
 
@@ -2761,7 +2761,7 @@ static int sh_page_fault(struct vcpu *v,
          !(accumulated_gflags & _PAGE_USER) )
     {
         /* illegal user-mode access to supervisor-only page */
-        perfc_incrc(shadow_fault_bail_user_supervisor);
+        perfc_incr(shadow_fault_bail_user_supervisor);
         goto not_a_shadow_fault;
     }
 
@@ -2772,7 +2772,7 @@ static int sh_page_fault(struct vcpu *v,
     {
         if ( unlikely(!(accumulated_gflags & _PAGE_RW)) )
         {
-            perfc_incrc(shadow_fault_bail_ro_mapping);
+            perfc_incr(shadow_fault_bail_ro_mapping);
             goto not_a_shadow_fault;
         }
     }
@@ -2787,7 +2787,7 @@ static int sh_page_fault(struct vcpu *v,
             if ( accumulated_gflags & _PAGE_NX_BIT )
             {
                 /* NX prevented this code fetch */
-                perfc_incrc(shadow_fault_bail_nx);
+                perfc_incr(shadow_fault_bail_nx);
                 goto not_a_shadow_fault;
             }
         }
@@ -2802,7 +2802,7 @@ static int sh_page_fault(struct vcpu *v,
 
     if ( !mmio && !mfn_valid(gmfn) )
     {
-        perfc_incrc(shadow_fault_bail_bad_gfn);
+        perfc_incr(shadow_fault_bail_bad_gfn);
         SHADOW_PRINTK("BAD gfn=%"SH_PRI_gfn" gmfn=%"PRI_mfn"\n", 
                       gfn_x(gfn), mfn_x(gmfn));
         goto not_a_shadow_fault;
@@ -2844,12 +2844,12 @@ static int sh_page_fault(struct vcpu *v,
     {
         if ( ft == ft_demand_write )
         {
-            perfc_incrc(shadow_fault_emulate_write);
+            perfc_incr(shadow_fault_emulate_write);
             goto emulate;
         }
         else if ( shadow_mode_trap_reads(d) && ft == ft_demand_read )
         {
-            perfc_incrc(shadow_fault_emulate_read);
+            perfc_incr(shadow_fault_emulate_read);
             goto emulate;
         }
     }
@@ -2860,7 +2860,7 @@ static int sh_page_fault(struct vcpu *v,
         goto mmio;
     }
 
-    perfc_incrc(shadow_fault_fixed);
+    perfc_incr(shadow_fault_fixed);
     d->arch.paging.shadow.fault_count++;
     reset_early_unshadow(v);
 
@@ -2920,7 +2920,7 @@ static int sh_page_fault(struct vcpu *v,
     {
         SHADOW_PRINTK("emulator failure, unshadowing mfn %#lx\n", 
                        mfn_x(gmfn));
-        perfc_incrc(shadow_fault_emulate_failed);
+        perfc_incr(shadow_fault_emulate_failed);
         /* If this is actually a page table, then we have a bug, and need 
          * to support more operations in the emulator.  More likely, 
          * though, this is a hint that this page should not be shadowed. */
@@ -2935,7 +2935,7 @@ static int sh_page_fault(struct vcpu *v,
  mmio:
     if ( !guest_mode(regs) )
         goto not_a_shadow_fault;
-    perfc_incrc(shadow_fault_mmio);
+    perfc_incr(shadow_fault_mmio);
     sh_audit_gw(v, &gw);
     unmap_walk(v, &gw);
     SHADOW_PRINTK("mmio %#"PRIpaddr"\n", gpa);
@@ -2964,7 +2964,7 @@ sh_invlpg(struct vcpu *v, unsigned long 
 {
     shadow_l2e_t sl2e;
     
-    perfc_incrc(shadow_invlpg);
+    perfc_incr(shadow_invlpg);
 
     /* First check that we can safely read the shadow l2e.  SMP/PAE linux can
      * run as high as 6% of invlpg calls where we haven't shadowed the l2 
@@ -2983,7 +2983,7 @@ sh_invlpg(struct vcpu *v, unsigned long 
                                       + shadow_l3_linear_offset(va)),
                               sizeof (sl3e)) != 0 )
         {
-            perfc_incrc(shadow_invlpg_fault);
+            perfc_incr(shadow_invlpg_fault);
             return 0;
         }
         if ( (!shadow_l3e_get_flags(sl3e) & _PAGE_PRESENT) )
@@ -3002,7 +3002,7 @@ sh_invlpg(struct vcpu *v, unsigned long 
                           sh_linear_l2_table(v) + shadow_l2_linear_offset(va),
                           sizeof (sl2e)) != 0 )
     {
-        perfc_incrc(shadow_invlpg_fault);
+        perfc_incr(shadow_invlpg_fault);
         return 0;
     }
 
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/smp.c
--- a/xen/arch/x86/smp.c        Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/smp.c        Wed Mar 28 08:44:08 2007 +0000
@@ -169,7 +169,7 @@ fastcall void smp_invalidate_interrupt(v
 fastcall void smp_invalidate_interrupt(void)
 {
     ack_APIC_irq();
-    perfc_incrc(ipis);
+    perfc_incr(ipis);
     irq_enter();
     if ( !__sync_lazy_execstate() )
     {
@@ -329,7 +329,7 @@ fastcall void smp_event_check_interrupt(
 fastcall void smp_event_check_interrupt(struct cpu_user_regs *regs)
 {
     ack_APIC_irq();
-    perfc_incrc(ipis);
+    perfc_incr(ipis);
 }
 
 fastcall void smp_call_function_interrupt(struct cpu_user_regs *regs)
@@ -338,7 +338,7 @@ fastcall void smp_call_function_interrup
     void *info = call_data->info;
 
     ack_APIC_irq();
-    perfc_incrc(ipis);
+    perfc_incr(ipis);
 
     if ( !cpu_isset(smp_processor_id(), call_data->selected) )
         return;
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/time.c
--- a/xen/arch/x86/time.c       Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/time.c       Wed Mar 28 08:44:08 2007 +0000
@@ -670,13 +670,19 @@ static inline void version_update_end(u3
     (*version)++;
 }
 
-static inline void __update_vcpu_system_time(struct vcpu *v)
+void update_vcpu_system_time(struct vcpu *v)
 {
     struct cpu_time       *t;
     struct vcpu_time_info *u;
 
+    if ( v->vcpu_info == NULL )
+        return;
+
     t = &this_cpu(cpu_time);
     u = &vcpu_info(v, time);
+
+    if ( u->tsc_timestamp == t->local_tsc_stamp )
+        return;
 
     version_update_begin(&u->version);
 
@@ -686,13 +692,6 @@ static inline void __update_vcpu_system_
     u->tsc_shift         = (s8)t->tsc_scale.shift;
 
     version_update_end(&u->version);
-}
-
-void update_vcpu_system_time(struct vcpu *v)
-{
-    if ( vcpu_info(v, time.tsc_timestamp) !=
-         this_cpu(cpu_time).local_tsc_stamp )
-        __update_vcpu_system_time(v);
 }
 
 void update_domain_wallclock_time(struct domain *d)
@@ -771,9 +770,10 @@ static void local_time_calibration(void 
     local_irq_enable();
 
 #if 0
-    printk("PRE%d: tsc=%lld stime=%lld master=%lld\n",
+    printk("PRE%d: tsc=%"PRIu64" stime=%"PRIu64" master=%"PRIu64"\n",
            smp_processor_id(), prev_tsc, prev_local_stime, prev_master_stime);
-    printk("CUR%d: tsc=%lld stime=%lld master=%lld -> %lld\n",
+    printk("CUR%d: tsc=%"PRIu64" stime=%"PRIu64" master=%"PRIu64
+           " -> %"PRId64"\n",
            smp_processor_id(), curr_tsc, curr_local_stime, curr_master_stime,
            curr_master_stime - curr_local_stime);
 #endif
@@ -854,6 +854,8 @@ static void local_time_calibration(void 
     t->local_tsc_stamp    = curr_tsc;
     t->stime_local_stamp  = curr_local_stime;
     t->stime_master_stamp = curr_master_stime;
+
+    update_vcpu_system_time(current);
 
  out:
     set_timer(&t->calibration_timer, NOW() + EPOCH);
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/traps.c      Wed Mar 28 08:44:08 2007 +0000
@@ -637,28 +637,34 @@ asmlinkage int do_invalid_op(struct cpu_
          memcmp(bug.ud2, "\xf\xb", sizeof(bug.ud2)) ||
          (bug.ret != 0xc2) )
         goto die;
+    eip += sizeof(bug);
 
     id = bug.id & 3;
-    if ( id == BUGFRAME_rsvd )
-        goto die;
 
     if ( id == BUGFRAME_dump )
     {
         show_execution_state(regs);
-        regs->eip += sizeof(bug);
+        regs->eip = (unsigned long)eip;
         return EXCRET_fault_fixed;
     }
 
-    /* BUG() or ASSERT(): decode the filename pointer and line number. */
-    ASSERT((id == BUGFRAME_bug) || (id == BUGFRAME_assert));
-    eip += sizeof(bug);
+    /* WARN, BUG or ASSERT: decode the filename pointer and line number. */
     if ( !is_kernel(eip) ||
          __copy_from_user(&bug_str, eip, sizeof(bug_str)) ||
          memcmp(bug_str.mov, BUG_MOV_STR, sizeof(bug_str.mov)) )
         goto die;
+    eip += sizeof(bug_str);
 
     filename = is_kernel(bug_str.str) ? (char *)bug_str.str : "<unknown>";
     lineno   = bug.id >> 2;
+
+    if ( id == BUGFRAME_warn )
+    {
+        printk("Xen WARN at %.50s:%d\n", filename, lineno);
+        show_execution_state(regs);
+        regs->eip = (unsigned long)eip;
+        return EXCRET_fault_fixed;
+    }
 
     if ( id == BUGFRAME_bug )
     {
@@ -668,13 +674,13 @@ asmlinkage int do_invalid_op(struct cpu_
         panic("Xen BUG at %.50s:%d\n", filename, lineno);
     }
 
-    /* ASSERT(): decode the predicate string pointer. */
+    /* ASSERT: decode the predicate string pointer. */
     ASSERT(id == BUGFRAME_assert);
-    eip += sizeof(bug_str);
     if ( !is_kernel(eip) ||
          __copy_from_user(&bug_str, eip, sizeof(bug_str)) ||
          memcmp(bug_str.mov, BUG_MOV_STR, sizeof(bug_str.mov)) )
         goto die;
+    eip += sizeof(bug_str);
 
     predicate = is_kernel(bug_str.str) ? (char *)bug_str.str : "<unknown>";
     printk("Assertion '%s' failed at %.50s:%d\n",
@@ -950,7 +956,7 @@ asmlinkage int do_page_fault(struct cpu_
 
     DEBUGGER_trap_entry(TRAP_page_fault, regs);
 
-    perfc_incrc(page_faults);
+    perfc_incr(page_faults);
 
     if ( unlikely((rc = fixup_page_fault(addr, regs)) != 0) )
         return rc;
@@ -962,7 +968,7 @@ asmlinkage int do_page_fault(struct cpu_
 
         if ( likely((fixup = search_exception_table(regs->eip)) != 0) )
         {
-            perfc_incrc(copy_user_faults);
+            perfc_incr(copy_user_faults);
             regs->eip = fixup;
             return 0;
         }
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/x86_32/asm-offsets.c
--- a/xen/arch/x86/x86_32/asm-offsets.c Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/x86_32/asm-offsets.c Wed Mar 28 08:44:08 2007 +0000
@@ -107,20 +107,10 @@ void __dummy__(void)
     BLANK();
 
 #if PERF_COUNTERS
-    OFFSET(PERFC_hypercalls, struct perfcounter, hypercalls);
-    OFFSET(PERFC_exceptions, struct perfcounter, exceptions);
+    DEFINE(PERFC_hypercalls, PERFC_hypercalls);
+    DEFINE(PERFC_exceptions, PERFC_exceptions);
     BLANK();
 #endif
-
-    OFFSET(MULTICALL_op, struct multicall_entry, op);
-    OFFSET(MULTICALL_arg0, struct multicall_entry, args[0]);
-    OFFSET(MULTICALL_arg1, struct multicall_entry, args[1]);
-    OFFSET(MULTICALL_arg2, struct multicall_entry, args[2]);
-    OFFSET(MULTICALL_arg3, struct multicall_entry, args[3]);
-    OFFSET(MULTICALL_arg4, struct multicall_entry, args[4]);
-    OFFSET(MULTICALL_arg5, struct multicall_entry, args[5]);
-    OFFSET(MULTICALL_result, struct multicall_entry, result);
-    BLANK();
 
     DEFINE(FIXMAP_apic_base, fix_to_virt(FIX_APIC_BASE));
     BLANK();
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/x86_32/domain_page.c
--- a/xen/arch/x86/x86_32/domain_page.c Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/x86_32/domain_page.c Wed Mar 28 08:44:08 2007 +0000
@@ -50,7 +50,7 @@ void *map_domain_page(unsigned long mfn)
 
     ASSERT(!in_irq());
 
-    perfc_incrc(map_domain_page_count);
+    perfc_incr(map_domain_page_count);
 
     v = mapcache_current_vcpu();
 
@@ -76,7 +76,7 @@ void *map_domain_page(unsigned long mfn)
         cache->shadow_epoch[vcpu] = cache->epoch;
         if ( NEED_FLUSH(this_cpu(tlbflush_time), cache->tlbflush_timestamp) )
         {
-            perfc_incrc(domain_page_tlb_flush);
+            perfc_incr(domain_page_tlb_flush);
             local_flush_tlb();
         }
     }
@@ -92,7 +92,7 @@ void *map_domain_page(unsigned long mfn)
         }
 
         /* /Second/, flush TLBs. */
-        perfc_incrc(domain_page_tlb_flush);
+        perfc_incr(domain_page_tlb_flush);
         local_flush_tlb();
         cache->shadow_epoch[vcpu] = ++cache->epoch;
         cache->tlbflush_timestamp = tlbflush_current_time();
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S       Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/x86_32/entry.S       Wed Mar 28 08:44:08 2007 +0000
@@ -173,7 +173,7 @@ ENTRY(hypercall)
         GET_CURRENT(%ebx)
         cmpl  $NR_hypercalls,%eax
         jae   bad_hypercall
-        PERFC_INCR(PERFC_hypercalls, %eax)
+        PERFC_INCR(PERFC_hypercalls, %eax, %ebx)
 #ifndef NDEBUG
         /* Create shadow parameters and corrupt those not used by this call. */
         pushl %eax
@@ -429,7 +429,7 @@ 1:      xorl  %eax,%eax
         movl  %esp,%edx
         pushl %edx                      # push the cpu_user_regs pointer
         GET_CURRENT(%ebx)
-        PERFC_INCR(PERFC_exceptions, %eax)
+        PERFC_INCR(PERFC_exceptions, %eax, %ebx)
         call  *exception_table(,%eax,4)
         addl  $4,%esp
         movl  UREGS_eflags(%esp),%eax
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/x86_32/seg_fixup.c
--- a/xen/arch/x86/x86_32/seg_fixup.c   Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/x86_32/seg_fixup.c   Wed Mar 28 08:44:08 2007 +0000
@@ -434,7 +434,7 @@ int gpf_emulate_4gb(struct cpu_user_regs
         goto fail;
 
     /* Success! */
-    perfc_incrc(seg_fixups);
+    perfc_incr(seg_fixups);
 
     /* If requested, give a callback on otherwise unused vector 15. */
     if ( VM_ASSIST(d->domain, VMASST_TYPE_4gb_segments_notify) )
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/x86_64/asm-offsets.c
--- a/xen/arch/x86/x86_64/asm-offsets.c Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/x86_64/asm-offsets.c Wed Mar 28 08:44:08 2007 +0000
@@ -121,30 +121,8 @@ void __dummy__(void)
     BLANK();
 
 #if PERF_COUNTERS
-    OFFSET(PERFC_hypercalls, struct perfcounter, hypercalls);
-    OFFSET(PERFC_exceptions, struct perfcounter, exceptions);
-    BLANK();
-#endif
-
-    OFFSET(MULTICALL_op, struct multicall_entry, op);
-    OFFSET(MULTICALL_arg0, struct multicall_entry, args[0]);
-    OFFSET(MULTICALL_arg1, struct multicall_entry, args[1]);
-    OFFSET(MULTICALL_arg2, struct multicall_entry, args[2]);
-    OFFSET(MULTICALL_arg3, struct multicall_entry, args[3]);
-    OFFSET(MULTICALL_arg4, struct multicall_entry, args[4]);
-    OFFSET(MULTICALL_arg5, struct multicall_entry, args[5]);
-    OFFSET(MULTICALL_result, struct multicall_entry, result);
-    BLANK();
-
-#ifdef CONFIG_COMPAT
-    OFFSET(COMPAT_MULTICALL_op, struct compat_multicall_entry, op);
-    OFFSET(COMPAT_MULTICALL_arg0, struct compat_multicall_entry, args[0]);
-    OFFSET(COMPAT_MULTICALL_arg1, struct compat_multicall_entry, args[1]);
-    OFFSET(COMPAT_MULTICALL_arg2, struct compat_multicall_entry, args[2]);
-    OFFSET(COMPAT_MULTICALL_arg3, struct compat_multicall_entry, args[3]);
-    OFFSET(COMPAT_MULTICALL_arg4, struct compat_multicall_entry, args[4]);
-    OFFSET(COMPAT_MULTICALL_arg5, struct compat_multicall_entry, args[5]);
-    OFFSET(COMPAT_MULTICALL_result, struct compat_multicall_entry, result);
+    DEFINE(PERFC_hypercalls, PERFC_hypercalls);
+    DEFINE(PERFC_exceptions, PERFC_exceptions);
     BLANK();
 #endif
 
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/x86_64/compat/entry.S
--- a/xen/arch/x86/x86_64/compat/entry.S        Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/x86_64/compat/entry.S        Wed Mar 28 08:44:08 2007 +0000
@@ -57,7 +57,7 @@ ENTRY(compat_hypercall)
         movl  UREGS_rbx(%rsp),%edi   /* Arg 1        */
 #endif
         leaq  compat_hypercall_table(%rip),%r10
-        PERFC_INCR(PERFC_hypercalls, %rax)
+        PERFC_INCR(PERFC_hypercalls, %rax, %rbx)
         callq *(%r10,%rax,8)
 #ifndef NDEBUG
         /* Deliberately corrupt parameter regs used by this hypercall. */
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S       Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/x86_64/entry.S       Wed Mar 28 08:44:08 2007 +0000
@@ -147,7 +147,7 @@ ENTRY(syscall_enter)
         pushq UREGS_rip+8(%rsp)
 #endif
         leaq  hypercall_table(%rip),%r10
-        PERFC_INCR(PERFC_hypercalls, %rax)
+        PERFC_INCR(PERFC_hypercalls, %rax, %rbx)
         callq *(%r10,%rax,8)
 #ifndef NDEBUG
         /* Deliberately corrupt parameter regs used by this hypercall. */
@@ -396,7 +396,7 @@ 1:      movq  %rsp,%rdi
         movl  UREGS_entry_vector(%rsp),%eax
         leaq  exception_table(%rip),%rdx
         GET_CURRENT(%rbx)
-        PERFC_INCR(PERFC_exceptions, %rax)
+        PERFC_INCR(PERFC_exceptions, %rax, %rbx)
         callq *(%rdx,%rax,8)
         testb $3,UREGS_cs(%rsp)
         jz    restore_all_xen
diff -r bc2811bf7771 -r 81fec499a983 xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c        Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/arch/x86/x86_emulate.c        Wed Mar 28 08:44:08 2007 +0000
@@ -1565,8 +1565,10 @@ x86_emulate(
             if ( ((op_bytes = dst.bytes) != 8) && mode_64bit() )
             {
                 dst.bytes = op_bytes = 8;
-                if ( (rc = ops->read(dst.mem.seg, dst.mem.off,
-                                     &dst.val, 8, ctxt)) != 0 )
+                if ( dst.type == OP_REG )
+                    dst.val = *dst.reg;
+                else if ( (rc = ops->read(dst.mem.seg, dst.mem.off,
+                                          &dst.val, 8, ctxt)) != 0 )
                     goto done;
             }
             src.val = _regs.eip;
@@ -1579,8 +1581,10 @@ x86_emulate(
             if ( mode_64bit() && (dst.bytes == 4) )
             {
                 dst.bytes = 8;
-                if ( (rc = ops->read(dst.mem.seg, dst.mem.off,
-                                     &dst.val, 8, ctxt)) != 0 )
+                if ( dst.type == OP_REG )
+                    dst.val = *dst.reg;
+                else if ( (rc = ops->read(dst.mem.seg, dst.mem.off,
+                                          &dst.val, 8, ctxt)) != 0 )
                     goto done;
             }
             if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(dst.bytes),
diff -r bc2811bf7771 -r 81fec499a983 xen/common/domain.c
--- a/xen/common/domain.c       Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/common/domain.c       Wed Mar 28 08:44:08 2007 +0000
@@ -96,14 +96,16 @@ struct vcpu *alloc_vcpu(
 
     v->domain = d;
     v->vcpu_id = vcpu_id;
-    v->vcpu_info = shared_info_addr(d, vcpu_info[vcpu_id]);
     spin_lock_init(&v->pause_lock);
 
     v->runstate.state = is_idle_vcpu(v) ? RUNSTATE_running : RUNSTATE_offline;
     v->runstate.state_entry_time = NOW();
 
     if ( !is_idle_domain(d) )
+    {
         set_bit(_VCPUF_down, &v->vcpu_flags);
+        v->vcpu_info = shared_info_addr(d, vcpu_info[vcpu_id]);
+    }
 
     if ( sched_init_vcpu(v, cpu_id) != 0 )
     {
diff -r bc2811bf7771 -r 81fec499a983 xen/common/multicall.c
--- a/xen/common/multicall.c    Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/common/multicall.c    Wed Mar 28 08:44:08 2007 +0000
@@ -10,6 +10,7 @@
 #include <xen/event.h>
 #include <xen/multicall.h>
 #include <xen/guest_access.h>
+#include <xen/perfc.h>
 #include <asm/current.h>
 #include <asm/hardirq.h>
 
@@ -69,14 +70,18 @@ do_multicall(
         guest_handle_add_offset(call_list, 1);
     }
 
+    perfc_incr(calls_to_multicall);
+    perfc_add(calls_from_multicall, nr_calls);
     mcs->flags = 0;
     return 0;
 
  fault:
+    perfc_incr(calls_to_multicall);
     mcs->flags = 0;
     return -EFAULT;
 
  preempted:
+    perfc_add(calls_from_multicall, i);
     mcs->flags = 0;
     return hypercall_create_continuation(
         __HYPERVISOR_multicall, "hi", call_list, nr_calls-i);
diff -r bc2811bf7771 -r 81fec499a983 xen/common/page_alloc.c
--- a/xen/common/page_alloc.c   Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/common/page_alloc.c   Wed Mar 28 08:44:08 2007 +0000
@@ -423,7 +423,7 @@ static struct page_info *alloc_heap_page
 
     if ( unlikely(!cpus_empty(mask)) )
     {
-        perfc_incrc(need_flush_tlb_flush);
+        perfc_incr(need_flush_tlb_flush);
         flush_tlb_mask(mask);
     }
 
diff -r bc2811bf7771 -r 81fec499a983 xen/common/perfc.c
--- a/xen/common/perfc.c        Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/common/perfc.c        Wed Mar 28 08:44:08 2007 +0000
@@ -10,81 +10,98 @@
 #include <public/sysctl.h>
 #include <asm/perfc.h>
 
-#undef  PERFCOUNTER
-#undef  PERFCOUNTER_CPU
-#undef  PERFCOUNTER_ARRAY
-#undef  PERFSTATUS
-#undef  PERFSTATUS_CPU
-#undef  PERFSTATUS_ARRAY
 #define PERFCOUNTER( var, name )              { name, TYPE_SINGLE, 0 },
-#define PERFCOUNTER_CPU( var, name )          { name, TYPE_CPU,    0 },
 #define PERFCOUNTER_ARRAY( var, name, size )  { name, TYPE_ARRAY,  size },
 #define PERFSTATUS( var, name )               { name, TYPE_S_SINGLE, 0 },
-#define PERFSTATUS_CPU( var, name )           { name, TYPE_S_CPU,    0 },
 #define PERFSTATUS_ARRAY( var, name, size )   { name, TYPE_S_ARRAY,  size },
-static struct {
-    char *name;
-    enum { TYPE_SINGLE, TYPE_CPU, TYPE_ARRAY,
-           TYPE_S_SINGLE, TYPE_S_CPU, TYPE_S_ARRAY
+static const struct {
+    const char *name;
+    enum { TYPE_SINGLE, TYPE_ARRAY,
+           TYPE_S_SINGLE, TYPE_S_ARRAY
     } type;
-    int nr_elements;
+    unsigned int nr_elements;
 } perfc_info[] = {
 #include <xen/perfc_defn.h>
 };
 
 #define NR_PERFCTRS (sizeof(perfc_info) / sizeof(perfc_info[0]))
 
-struct perfcounter perfcounters;
+DEFINE_PER_CPU(perfc_t[NUM_PERFCOUNTERS], perfcounters);
 
 void perfc_printall(unsigned char key)
 {
-    unsigned int i, j, sum;
+    unsigned int i, j;
     s_time_t now = NOW();
-    atomic_t *counters = (atomic_t *)&perfcounters;
 
     printk("Xen performance counters SHOW  (now = 0x%08X:%08X)\n",
            (u32)(now>>32), (u32)now);
 
-    for ( i = 0; i < NR_PERFCTRS; i++ ) 
-    {
+    for ( i = j = 0; i < NR_PERFCTRS; i++ )
+    {
+        unsigned int k, cpu;
+        unsigned long long sum = 0;
+
         printk("%-32s  ",  perfc_info[i].name);
         switch ( perfc_info[i].type )
         {
         case TYPE_SINGLE:
         case TYPE_S_SINGLE:
-            printk("TOTAL[%10d]", atomic_read(&counters[0]));
-            counters += 1;
-            break;
-        case TYPE_CPU:
-        case TYPE_S_CPU:
-            sum = 0;
-            for_each_online_cpu ( j )
-                sum += atomic_read(&counters[j]);
-            printk("TOTAL[%10u]", sum);
+            for_each_online_cpu ( cpu )
+                sum += per_cpu(perfcounters, cpu)[j];
+            printk("TOTAL[%12Lu]", sum);
+            if ( sum )
+            {
+                k = 0;
+                for_each_online_cpu ( cpu )
+                {
+                    if ( k > 0 && (k % 4) == 0 )
+                        printk("\n%46s", "");
+                    printk("  CPU%02u[%10"PRIperfc"u]", cpu, 
per_cpu(perfcounters, cpu)[j]);
+                    ++k;
+                }
+            }
+            ++j;
+            break;
+        case TYPE_ARRAY:
+        case TYPE_S_ARRAY:
+            for_each_online_cpu ( cpu )
+            {
+                perfc_t *counters = per_cpu(perfcounters, cpu) + j;
+
+                for ( k = 0; k < perfc_info[i].nr_elements; k++ )
+                    sum += counters[k];
+            }
+            printk("TOTAL[%12Lu]", sum);
             if (sum)
             {
-                for_each_online_cpu ( j )
-                    printk("  CPU%02d[%10d]", j, atomic_read(&counters[j]));
-            }
-            counters += NR_CPUS;
-            break;
-        case TYPE_ARRAY:
-        case TYPE_S_ARRAY:
-            for ( j = sum = 0; j < perfc_info[i].nr_elements; j++ )
-                sum += atomic_read(&counters[j]);
-            printk("TOTAL[%10u]", sum);
 #ifdef PERF_ARRAYS
-            if (sum)
-            {
-                for ( j = 0; j < perfc_info[i].nr_elements; j++ )
-                {
-                    if ( (j % 4) == 0 )
-                        printk("\n                 ");
-                    printk("  ARR%02d[%10d]", j, atomic_read(&counters[j]));
-                }
-            }
+                for ( k = 0; k < perfc_info[i].nr_elements; k++ )
+                {
+                    sum = 0;
+                    for_each_online_cpu ( cpu )
+                        sum += per_cpu(perfcounters, cpu)[j + k];
+                    if ( (k % 4) == 0 )
+                        printk("\n%16s", "");
+                    printk("  ARR%02u[%10Lu]", k, sum);
+                }
+#else
+                k = 0;
+                for_each_online_cpu ( cpu )
+                {
+                    perfc_t *counters = per_cpu(perfcounters, cpu) + j;
+                    unsigned int n;
+
+                    sum = 0;
+                    for ( n = 0; n < perfc_info[i].nr_elements; n++ )
+                        sum += counters[n];
+                    if ( k > 0 && (k % 4) == 0 )
+                        printk("\n%46s", "");
+                    printk("  CPU%02u[%10Lu]", cpu, sum);
+                    ++k;
+                }
 #endif
-            counters += j;
+            }
+            j += perfc_info[i].nr_elements;
             break;
         }
         printk("\n");
@@ -97,7 +114,6 @@ void perfc_reset(unsigned char key)
 {
     unsigned int i, j;
     s_time_t now = NOW();
-    atomic_t *counters = (atomic_t *)&perfcounters;
 
     if ( key != '\0' )
         printk("Xen performance counters RESET (now = 0x%08X:%08X)\n",
@@ -105,43 +121,39 @@ void perfc_reset(unsigned char key)
 
     /* leave STATUS counters alone -- don't reset */
 
-    for ( i = 0; i < NR_PERFCTRS; i++ ) 
-    {
-        switch ( perfc_info[i].type )
-        {
-        case TYPE_SINGLE:
-            atomic_set(&counters[0],0);
-        case TYPE_S_SINGLE:
-            counters += 1;
-            break;
-        case TYPE_CPU:
-            for ( j = 0; j < NR_CPUS; j++ )
-                atomic_set(&counters[j],0);
-        case TYPE_S_CPU:
-            counters += NR_CPUS;
-            break;
-        case TYPE_ARRAY:
-            for ( j = 0; j < perfc_info[i].nr_elements; j++ )
-                atomic_set(&counters[j],0);
-        case TYPE_S_ARRAY:
-            counters += perfc_info[i].nr_elements;
-            break;
-        }
-    }
-
-    arch_perfc_reset ();
+    for ( i = j = 0; i < NR_PERFCTRS; i++ )
+    {
+        unsigned int cpu;
+
+        switch ( perfc_info[i].type )
+        {
+        case TYPE_SINGLE:
+            for_each_cpu ( cpu )
+                per_cpu(perfcounters, cpu)[j] = 0;
+        case TYPE_S_SINGLE:
+            ++j;
+            break;
+        case TYPE_ARRAY:
+            for_each_cpu ( cpu )
+                memset(per_cpu(perfcounters, cpu) + j, 0,
+                       perfc_info[i].nr_elements * sizeof(perfc_t));
+        case TYPE_S_ARRAY:
+            j += perfc_info[i].nr_elements;
+            break;
+        }
+    }
+
+    arch_perfc_reset();
 }
 
 static xen_sysctl_perfc_desc_t perfc_d[NR_PERFCTRS];
 static xen_sysctl_perfc_val_t *perfc_vals;
-static int               perfc_nbr_vals;
+static unsigned int      perfc_nbr_vals;
 static int               perfc_init = 0;
 static int perfc_copy_info(XEN_GUEST_HANDLE_64(xen_sysctl_perfc_desc_t) desc,
                            XEN_GUEST_HANDLE_64(xen_sysctl_perfc_val_t) val)
 {
-    unsigned int i, j;
-    unsigned int v = 0;
-    atomic_t *counters = (atomic_t *)&perfcounters;
+    unsigned int i, j, v;
 
     /* We only copy the name and array-size information once. */
     if ( !perfc_init ) 
@@ -154,11 +166,7 @@ static int perfc_copy_info(XEN_GUEST_HAN
             {
             case TYPE_SINGLE:
             case TYPE_S_SINGLE:
-                perfc_d[i].nr_vals = 1;
-                break;
-            case TYPE_CPU:
-            case TYPE_S_CPU:
-                perfc_d[i].nr_vals = num_online_cpus();
+                perfc_d[i].nr_vals = num_possible_cpus();
                 break;
             case TYPE_ARRAY:
             case TYPE_S_ARRAY:
@@ -181,26 +189,31 @@ static int perfc_copy_info(XEN_GUEST_HAN
     arch_perfc_gather();
 
     /* We gather the counts together every time. */
-    for ( i = 0; i < NR_PERFCTRS; i++ )
-    {
-        switch ( perfc_info[i].type )
-        {
-        case TYPE_SINGLE:
-        case TYPE_S_SINGLE:
-            perfc_vals[v++] = atomic_read(&counters[0]);
-            counters += 1;
-            break;
-        case TYPE_CPU:
-        case TYPE_S_CPU:
-            for ( j = 0; j < perfc_d[i].nr_vals; j++ )
-                perfc_vals[v++] = atomic_read(&counters[j]);
-            counters += NR_CPUS;
-            break;
-        case TYPE_ARRAY:
-        case TYPE_S_ARRAY:
-            for ( j = 0; j < perfc_d[i].nr_vals; j++ )
-                perfc_vals[v++] = atomic_read(&counters[j]);
-            counters += perfc_info[i].nr_elements;
+    for ( i = j = v = 0; i < NR_PERFCTRS; i++ )
+    {
+        unsigned int cpu;
+
+        switch ( perfc_info[i].type )
+        {
+        case TYPE_SINGLE:
+        case TYPE_S_SINGLE:
+            for_each_cpu ( cpu )
+                perfc_vals[v++] = per_cpu(perfcounters, cpu)[j];
+            ++j;
+            break;
+        case TYPE_ARRAY:
+        case TYPE_S_ARRAY:
+            memset(perfc_vals + v, 0, perfc_d[i].nr_vals * 
sizeof(*perfc_vals));
+            for_each_cpu ( cpu )
+            {
+                perfc_t *counters = per_cpu(perfcounters, cpu) + j;
+                unsigned int k;
+
+                for ( k = 0; k < perfc_d[i].nr_vals; k++ )
+                    perfc_vals[v + k] += counters[k];
+            }
+            v += perfc_d[i].nr_vals;
+            j += perfc_info[i].nr_elements;
             break;
         }
     }
@@ -224,14 +237,12 @@ int perfc_control(xen_sysctl_perfc_op_t 
     switch ( pc->cmd )
     {
     case XEN_SYSCTL_PERFCOP_reset:
-        perfc_copy_info(pc->desc, pc->val);
+        rc = perfc_copy_info(pc->desc, pc->val);
         perfc_reset(0);
-        rc = 0;
         break;
 
     case XEN_SYSCTL_PERFCOP_query:
-        perfc_copy_info(pc->desc, pc->val);
-        rc = 0;
+        rc = perfc_copy_info(pc->desc, pc->val);
         break;
 
     default:
diff -r bc2811bf7771 -r 81fec499a983 xen/common/schedule.c
--- a/xen/common/schedule.c     Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/common/schedule.c     Wed Mar 28 08:44:08 2007 +0000
@@ -606,7 +606,7 @@ static void schedule(void)
     ASSERT(!in_irq());
     ASSERT(this_cpu(mc_state).flags == 0);
 
-    perfc_incrc(sched_run);
+    perfc_incr(sched_run);
 
     sd = &this_cpu(schedule_data);
 
@@ -654,16 +654,13 @@ static void schedule(void)
 
     spin_unlock_irq(&sd->schedule_lock);
 
-    perfc_incrc(sched_ctx);
+    perfc_incr(sched_ctx);
 
     stop_timer(&prev->periodic_timer);
 
     /* Ensure that the domain has an up-to-date time base. */
-    if ( !is_idle_vcpu(next) )
-    {
-        update_vcpu_system_time(next);
-        vcpu_periodic_timer_work(next);
-    }
+    update_vcpu_system_time(next);
+    vcpu_periodic_timer_work(next);
 
     TRACE_4D(TRC_SCHED_SWITCH,
              prev->domain->domain_id, prev->vcpu_id,
@@ -684,7 +681,7 @@ static void s_timer_fn(void *unused)
 static void s_timer_fn(void *unused)
 {
     raise_softirq(SCHEDULE_SOFTIRQ);
-    perfc_incrc(sched_irq);
+    perfc_incr(sched_irq);
 }
 
 /* Per-VCPU periodic timer function: sends a virtual timer interrupt. */
diff -r bc2811bf7771 -r 81fec499a983 xen/drivers/char/console.c
--- a/xen/drivers/char/console.c        Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/drivers/char/console.c        Wed Mar 28 08:44:08 2007 +0000
@@ -900,10 +900,16 @@ void __bug(char *file, int line)
 void __bug(char *file, int line)
 {
     console_start_sync();
-    printk("BUG at %s:%d\n", file, line);
+    printk("Xen BUG at %s:%d\n", file, line);
     dump_execution_state();
-    panic("BUG at %s:%d\n", file, line);
+    panic("Xen BUG at %s:%d\n", file, line);
     for ( ; ; ) ;
+}
+
+void __warn(char *file, int line)
+{
+    printk("Xen WARN at %s:%d\n", file, line);
+    dump_execution_state();
 }
 
 /*
diff -r bc2811bf7771 -r 81fec499a983 xen/include/asm-ia64/bug.h
--- a/xen/include/asm-ia64/bug.h        Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/include/asm-ia64/bug.h        Wed Mar 28 08:44:08 2007 +0000
@@ -2,5 +2,6 @@
 #define __IA64_BUG_H__
 
 #define BUG() __bug(__FILE__, __LINE__)
+#define WARN() __warn(__FILE__, __LINE__)
 
 #endif /* __IA64_BUG_H__ */
diff -r bc2811bf7771 -r 81fec499a983 
xen/include/asm-ia64/linux-xen/asm/asmmacro.h
--- a/xen/include/asm-ia64/linux-xen/asm/asmmacro.h     Wed Mar 28 08:40:42 
2007 +0000
+++ b/xen/include/asm-ia64/linux-xen/asm/asmmacro.h     Wed Mar 28 08:44:08 
2007 +0000
@@ -116,4 +116,8 @@ 2:{ .mib;                                           \
 # define dv_serialize_instruction
 #endif
 
+#ifdef PERF_COUNTERS
+#define PERFC(n) (THIS_CPU(perfcounters) + (IA64_PERFC_ ## n) * 4)
+#endif
+
 #endif /* _ASM_IA64_ASMMACRO_H */
diff -r bc2811bf7771 -r 81fec499a983 
xen/include/asm-ia64/linux-xen/asm/iosapic.h
--- a/xen/include/asm-ia64/linux-xen/asm/iosapic.h      Wed Mar 28 08:40:42 
2007 +0000
+++ b/xen/include/asm-ia64/linux-xen/asm/iosapic.h      Wed Mar 28 08:44:08 
2007 +0000
@@ -123,13 +123,6 @@ static inline void list_move(struct list
 
 #define move_irq(x)
 
-#define WARN_ON(condition) do { \
-       if (unlikely((condition)!=0)) { \
-               printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, 
__LINE__); \
-               dump_stack(); \
-       } \
-} while (0)
-
 #ifdef nop
 #undef nop
 #endif
diff -r bc2811bf7771 -r 81fec499a983 xen/include/asm-ia64/perfc_defn.h
--- a/xen/include/asm-ia64/perfc_defn.h Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/include/asm-ia64/perfc_defn.h Wed Mar 28 08:44:08 2007 +0000
@@ -1,34 +1,34 @@
 /* This file is legitimately included multiple times. */
 
-PERFCOUNTER_CPU(dtlb_translate,       "dtlb hit")
+PERFCOUNTER(dtlb_translate,       "dtlb hit")
 
-PERFCOUNTER_CPU(tr_translate,         "TR hit")
+PERFCOUNTER(tr_translate,         "TR hit")
 
-PERFCOUNTER_CPU(vhpt_translate,       "virtual vhpt translation")
-PERFCOUNTER_CPU(fast_vhpt_translate,  "virtual vhpt fast translation")
+PERFCOUNTER(vhpt_translate,       "virtual vhpt translation")
+PERFCOUNTER(fast_vhpt_translate,  "virtual vhpt fast translation")
 
 PERFCOUNTER(recover_to_page_fault,    "recoveries to page fault")
 PERFCOUNTER(recover_to_break_fault,   "recoveries to break fault")
 
-PERFCOUNTER_CPU(phys_translate,       "metaphysical translation")
+PERFCOUNTER(phys_translate,       "metaphysical translation")
 
-PERFCOUNTER_CPU(idle_when_pending,    "vcpu idle at event")
+PERFCOUNTER(idle_when_pending,    "vcpu idle at event")
 
-PERFCOUNTER_CPU(pal_halt_light,       "calls to pal_halt_light")
+PERFCOUNTER(pal_halt_light,       "calls to pal_halt_light")
 
-PERFCOUNTER_CPU(lazy_cover,           "lazy cover")
+PERFCOUNTER(lazy_cover,           "lazy cover")
 
-PERFCOUNTER_CPU(mov_to_ar_imm,        "privop mov_to_ar_imm")
-PERFCOUNTER_CPU(mov_to_ar_reg,        "privop mov_to_ar_reg")
-PERFCOUNTER_CPU(mov_from_ar,          "privop privified-mov_from_ar")
-PERFCOUNTER_CPU(ssm,                  "privop ssm")
-PERFCOUNTER_CPU(rsm,                  "privop rsm")
-PERFCOUNTER_CPU(rfi,                  "privop rfi")
-PERFCOUNTER_CPU(bsw0,                 "privop bsw0")
-PERFCOUNTER_CPU(bsw1,                 "privop bsw1")
-PERFCOUNTER_CPU(cover,                "privop cover")
-PERFCOUNTER_CPU(fc,                   "privop privified-fc")
-PERFCOUNTER_CPU(cpuid,                "privop privified-cpuid")
+PERFCOUNTER(mov_to_ar_imm,        "privop mov_to_ar_imm")
+PERFCOUNTER(mov_to_ar_reg,        "privop mov_to_ar_reg")
+PERFCOUNTER(mov_from_ar,          "privop privified-mov_from_ar")
+PERFCOUNTER(ssm,                  "privop ssm")
+PERFCOUNTER(rsm,                  "privop rsm")
+PERFCOUNTER(rfi,                  "privop rfi")
+PERFCOUNTER(bsw0,                 "privop bsw0")
+PERFCOUNTER(bsw1,                 "privop bsw1")
+PERFCOUNTER(cover,                "privop cover")
+PERFCOUNTER(fc,                   "privop privified-fc")
+PERFCOUNTER(cpuid,                "privop privified-cpuid")
 
 PERFCOUNTER_ARRAY(mov_to_cr,          "privop mov to cr", 128)
 PERFCOUNTER_ARRAY(mov_from_cr,        "privop mov from cr", 128)
@@ -36,45 +36,45 @@ PERFCOUNTER_ARRAY(misc_privop,        "p
 PERFCOUNTER_ARRAY(misc_privop,        "privop misc", 64)
 
 // privileged instructions to fall into vmx_entry
-PERFCOUNTER_CPU(vmx_rsm,              "vmx privop rsm")
-PERFCOUNTER_CPU(vmx_ssm,              "vmx privop ssm")
-PERFCOUNTER_CPU(vmx_mov_to_psr,       "vmx privop mov_to_psr")
-PERFCOUNTER_CPU(vmx_mov_from_psr,     "vmx privop mov_from_psr")
-PERFCOUNTER_CPU(vmx_mov_from_cr,      "vmx privop mov_from_cr")
-PERFCOUNTER_CPU(vmx_mov_to_cr,        "vmx privop mov_to_cr")
-PERFCOUNTER_CPU(vmx_bsw0,             "vmx privop bsw0")
-PERFCOUNTER_CPU(vmx_bsw1,             "vmx privop bsw1")
-PERFCOUNTER_CPU(vmx_cover,            "vmx privop cover")
-PERFCOUNTER_CPU(vmx_rfi,              "vmx privop rfi")
-PERFCOUNTER_CPU(vmx_itr_d,            "vmx privop itr_d")
-PERFCOUNTER_CPU(vmx_itr_i,            "vmx privop itr_i")
-PERFCOUNTER_CPU(vmx_ptr_d,            "vmx privop ptr_d")
-PERFCOUNTER_CPU(vmx_ptr_i,            "vmx privop ptr_i")
-PERFCOUNTER_CPU(vmx_itc_d,            "vmx privop itc_d")
-PERFCOUNTER_CPU(vmx_itc_i,            "vmx privop itc_i")
-PERFCOUNTER_CPU(vmx_ptc_l,            "vmx privop ptc_l")
-PERFCOUNTER_CPU(vmx_ptc_g,            "vmx privop ptc_g")
-PERFCOUNTER_CPU(vmx_ptc_ga,           "vmx privop ptc_ga")
-PERFCOUNTER_CPU(vmx_ptc_e,            "vmx privop ptc_e")
-PERFCOUNTER_CPU(vmx_mov_to_rr,        "vmx privop mov_to_rr")
-PERFCOUNTER_CPU(vmx_mov_from_rr,      "vmx privop mov_from_rr")
-PERFCOUNTER_CPU(vmx_thash,            "vmx privop thash")
-PERFCOUNTER_CPU(vmx_ttag,             "vmx privop ttag")
-PERFCOUNTER_CPU(vmx_tpa,              "vmx privop tpa")
-PERFCOUNTER_CPU(vmx_tak,              "vmx privop tak")
-PERFCOUNTER_CPU(vmx_mov_to_ar_imm,    "vmx privop mov_to_ar_imm")
-PERFCOUNTER_CPU(vmx_mov_to_ar_reg,    "vmx privop mov_to_ar_reg")
-PERFCOUNTER_CPU(vmx_mov_from_ar_reg,  "vmx privop mov_from_ar_reg")
-PERFCOUNTER_CPU(vmx_mov_to_dbr,       "vmx privop mov_to_dbr")
-PERFCOUNTER_CPU(vmx_mov_to_ibr,       "vmx privop mov_to_ibr")
-PERFCOUNTER_CPU(vmx_mov_to_pmc,       "vmx privop mov_to_pmc")
-PERFCOUNTER_CPU(vmx_mov_to_pmd,       "vmx privop mov_to_pmd")
-PERFCOUNTER_CPU(vmx_mov_to_pkr,       "vmx privop mov_to_pkr")
-PERFCOUNTER_CPU(vmx_mov_from_dbr,     "vmx privop mov_from_dbr")
-PERFCOUNTER_CPU(vmx_mov_from_ibr,     "vmx privop mov_from_ibr")
-PERFCOUNTER_CPU(vmx_mov_from_pmc,     "vmx privop mov_from_pmc")
-PERFCOUNTER_CPU(vmx_mov_from_pkr,     "vmx privop mov_from_pkr")
-PERFCOUNTER_CPU(vmx_mov_from_cpuid,   "vmx privop mov_from_cpuid")
+PERFCOUNTER(vmx_rsm,              "vmx privop rsm")
+PERFCOUNTER(vmx_ssm,              "vmx privop ssm")
+PERFCOUNTER(vmx_mov_to_psr,       "vmx privop mov_to_psr")
+PERFCOUNTER(vmx_mov_from_psr,     "vmx privop mov_from_psr")
+PERFCOUNTER(vmx_mov_from_cr,      "vmx privop mov_from_cr")
+PERFCOUNTER(vmx_mov_to_cr,        "vmx privop mov_to_cr")
+PERFCOUNTER(vmx_bsw0,             "vmx privop bsw0")
+PERFCOUNTER(vmx_bsw1,             "vmx privop bsw1")
+PERFCOUNTER(vmx_cover,            "vmx privop cover")
+PERFCOUNTER(vmx_rfi,              "vmx privop rfi")
+PERFCOUNTER(vmx_itr_d,            "vmx privop itr_d")
+PERFCOUNTER(vmx_itr_i,            "vmx privop itr_i")
+PERFCOUNTER(vmx_ptr_d,            "vmx privop ptr_d")
+PERFCOUNTER(vmx_ptr_i,            "vmx privop ptr_i")
+PERFCOUNTER(vmx_itc_d,            "vmx privop itc_d")
+PERFCOUNTER(vmx_itc_i,            "vmx privop itc_i")
+PERFCOUNTER(vmx_ptc_l,            "vmx privop ptc_l")
+PERFCOUNTER(vmx_ptc_g,            "vmx privop ptc_g")
+PERFCOUNTER(vmx_ptc_ga,           "vmx privop ptc_ga")
+PERFCOUNTER(vmx_ptc_e,            "vmx privop ptc_e")
+PERFCOUNTER(vmx_mov_to_rr,        "vmx privop mov_to_rr")
+PERFCOUNTER(vmx_mov_from_rr,      "vmx privop mov_from_rr")
+PERFCOUNTER(vmx_thash,            "vmx privop thash")
+PERFCOUNTER(vmx_ttag,             "vmx privop ttag")
+PERFCOUNTER(vmx_tpa,              "vmx privop tpa")
+PERFCOUNTER(vmx_tak,              "vmx privop tak")
+PERFCOUNTER(vmx_mov_to_ar_imm,    "vmx privop mov_to_ar_imm")
+PERFCOUNTER(vmx_mov_to_ar_reg,    "vmx privop mov_to_ar_reg")
+PERFCOUNTER(vmx_mov_from_ar_reg,  "vmx privop mov_from_ar_reg")
+PERFCOUNTER(vmx_mov_to_dbr,       "vmx privop mov_to_dbr")
+PERFCOUNTER(vmx_mov_to_ibr,       "vmx privop mov_to_ibr")
+PERFCOUNTER(vmx_mov_to_pmc,       "vmx privop mov_to_pmc")
+PERFCOUNTER(vmx_mov_to_pmd,       "vmx privop mov_to_pmd")
+PERFCOUNTER(vmx_mov_to_pkr,       "vmx privop mov_to_pkr")
+PERFCOUNTER(vmx_mov_from_dbr,     "vmx privop mov_from_dbr")
+PERFCOUNTER(vmx_mov_from_ibr,     "vmx privop mov_from_ibr")
+PERFCOUNTER(vmx_mov_from_pmc,     "vmx privop mov_from_pmc")
+PERFCOUNTER(vmx_mov_from_pkr,     "vmx privop mov_from_pkr")
+PERFCOUNTER(vmx_mov_from_cpuid,   "vmx privop mov_from_cpuid")
 
 
 PERFCOUNTER_ARRAY(slow_hyperprivop,   "slow hyperprivops", HYPERPRIVOP_MAX + 1)
@@ -84,12 +84,12 @@ PERFCOUNTER_ARRAY(fast_reflect,       "f
 PERFCOUNTER_ARRAY(fast_reflect,       "fast reflection", 0x80)
 
 PERFSTATUS(vhpt_nbr_entries,          "nbr of entries per VHPT")
-PERFSTATUS_CPU(vhpt_valid_entries,    "nbr of valid entries in VHPT")
+PERFSTATUS(vhpt_valid_entries,        "nbr of valid entries in VHPT")
 
 PERFCOUNTER_ARRAY(vmx_mmio_access,    "vmx_mmio_access", 8)
-PERFCOUNTER_CPU(vmx_pal_emul,         "vmx_pal_emul")
+PERFCOUNTER(vmx_pal_emul,         "vmx_pal_emul")
 PERFCOUNTER_ARRAY(vmx_switch_mm_mode, "vmx_switch_mm_mode", 8)
-PERFCOUNTER_CPU(vmx_ia64_handle_break,"vmx_ia64_handle_break")
+PERFCOUNTER(vmx_ia64_handle_break,"vmx_ia64_handle_break")
 PERFCOUNTER_ARRAY(vmx_inject_guest_interruption,
                                       "vmx_inject_guest_interruption", 0x80)
 PERFCOUNTER_ARRAY(fw_hypercall,       "fw_hypercall", 0x20)
@@ -106,69 +106,71 @@ PERFSTATUS(privop_addr_##name##_overflow
 
 PERFPRIVOPADDR(get_ifa)
 PERFPRIVOPADDR(thash)
+
+#undef PERFPRIVOPADDR
 #endif
 
 // vhpt.c
-PERFCOUNTER_CPU(local_vhpt_flush,               "local_vhpt_flush")
-PERFCOUNTER_CPU(vcpu_vhpt_flush,                "vcpu_vhpt_flush")
-PERFCOUNTER_CPU(vcpu_flush_vtlb_all,            "vcpu_flush_vtlb_all")
-PERFCOUNTER_CPU(domain_flush_vtlb_all,          "domain_flush_vtlb_all")
-PERFCOUNTER_CPU(vcpu_flush_tlb_vhpt_range,      "vcpu_flush_tlb_vhpt_range")
-PERFCOUNTER_CPU(domain_flush_vtlb_track_entry,  
"domain_flush_vtlb_track_entry")
-PERFCOUNTER_CPU(domain_flush_vtlb_local,        "domain_flush_vtlb_local")
-PERFCOUNTER_CPU(domain_flush_vtlb_global,       "domain_flush_vtlb_global")
-PERFCOUNTER_CPU(domain_flush_vtlb_range,        "domain_flush_vtlb_range")
+PERFCOUNTER(local_vhpt_flush,               "local_vhpt_flush")
+PERFCOUNTER(vcpu_vhpt_flush,                "vcpu_vhpt_flush")
+PERFCOUNTER(vcpu_flush_vtlb_all,            "vcpu_flush_vtlb_all")
+PERFCOUNTER(domain_flush_vtlb_all,          "domain_flush_vtlb_all")
+PERFCOUNTER(vcpu_flush_tlb_vhpt_range,      "vcpu_flush_tlb_vhpt_range")
+PERFCOUNTER(domain_flush_vtlb_track_entry,  "domain_flush_vtlb_track_entry")
+PERFCOUNTER(domain_flush_vtlb_local,        "domain_flush_vtlb_local")
+PERFCOUNTER(domain_flush_vtlb_global,       "domain_flush_vtlb_global")
+PERFCOUNTER(domain_flush_vtlb_range,        "domain_flush_vtlb_range")
 
 // domain.c
-PERFCOUNTER_CPU(flush_vtlb_for_context_switch,  
"flush_vtlb_for_context_switch")
+PERFCOUNTER(flush_vtlb_for_context_switch,  "flush_vtlb_for_context_switch")
 
 // mm.c
-PERFCOUNTER_CPU(assign_domain_page_replace,     "assign_domain_page_replace")
-PERFCOUNTER_CPU(assign_domain_pge_cmpxchg_rel,  
"assign_domain_pge_cmpxchg_rel")
-PERFCOUNTER_CPU(zap_dcomain_page_one,           "zap_dcomain_page_one")
-PERFCOUNTER_CPU(dom0vp_zap_physmap,             "dom0vp_zap_physmap")
-PERFCOUNTER_CPU(dom0vp_add_physmap,             "dom0vp_add_physmap")
-PERFCOUNTER_CPU(create_grant_host_mapping,      "create_grant_host_mapping")
-PERFCOUNTER_CPU(destroy_grant_host_mapping,     "destroy_grant_host_mapping")
-PERFCOUNTER_CPU(steal_page_refcount,            "steal_page_refcount")
-PERFCOUNTER_CPU(steal_page,                     "steal_page")
-PERFCOUNTER_CPU(guest_physmap_add_page,         "guest_physmap_add_page")
-PERFCOUNTER_CPU(guest_physmap_remove_page,      "guest_physmap_remove_page")
-PERFCOUNTER_CPU(domain_page_flush_and_put,      "domain_page_flush_and_put")
+PERFCOUNTER(assign_domain_page_replace,     "assign_domain_page_replace")
+PERFCOUNTER(assign_domain_pge_cmpxchg_rel,  "assign_domain_pge_cmpxchg_rel")
+PERFCOUNTER(zap_dcomain_page_one,           "zap_dcomain_page_one")
+PERFCOUNTER(dom0vp_zap_physmap,             "dom0vp_zap_physmap")
+PERFCOUNTER(dom0vp_add_physmap,             "dom0vp_add_physmap")
+PERFCOUNTER(create_grant_host_mapping,      "create_grant_host_mapping")
+PERFCOUNTER(destroy_grant_host_mapping,     "destroy_grant_host_mapping")
+PERFCOUNTER(steal_page_refcount,            "steal_page_refcount")
+PERFCOUNTER(steal_page,                     "steal_page")
+PERFCOUNTER(guest_physmap_add_page,         "guest_physmap_add_page")
+PERFCOUNTER(guest_physmap_remove_page,      "guest_physmap_remove_page")
+PERFCOUNTER(domain_page_flush_and_put,      "domain_page_flush_and_put")
 
 // dom0vp
-PERFCOUNTER_CPU(dom0vp_phystomach,              "dom0vp_phystomach")
-PERFCOUNTER_CPU(dom0vp_machtophys,              "dom0vp_machtophys")
+PERFCOUNTER(dom0vp_phystomach,              "dom0vp_phystomach")
+PERFCOUNTER(dom0vp_machtophys,              "dom0vp_machtophys")
 
 #ifdef CONFIG_XEN_IA64_TLB_TRACK
 // insert or dirty
-PERFCOUNTER_CPU(tlb_track_iod,                  "tlb_track_iod")
-PERFCOUNTER_CPU(tlb_track_iod_again,            "tlb_track_iod_again")
-PERFCOUNTER_CPU(tlb_track_iod_not_tracked,      "tlb_track_iod_not_tracked")
-PERFCOUNTER_CPU(tlb_track_iod_force_many,       "tlb_track_iod_force_many")
-PERFCOUNTER_CPU(tlb_track_iod_tracked_many,     "tlb_track_iod_tracked_many")
-PERFCOUNTER_CPU(tlb_track_iod_tracked_many_del, 
"tlb_track_iod_tracked_many_del")
-PERFCOUNTER_CPU(tlb_track_iod_found,            "tlb_track_iod_found")
-PERFCOUNTER_CPU(tlb_track_iod_new_entry,        "tlb_track_iod_new_entry")
-PERFCOUNTER_CPU(tlb_track_iod_new_failed,       "tlb_track_iod_new_failed")
-PERFCOUNTER_CPU(tlb_track_iod_new_many,         "tlb_track_iod_new_many")
-PERFCOUNTER_CPU(tlb_track_iod_insert,           "tlb_track_iod_insert")
-PERFCOUNTER_CPU(tlb_track_iod_dirtied,          "tlb_track_iod_dirtied")
+PERFCOUNTER(tlb_track_iod,                  "tlb_track_iod")
+PERFCOUNTER(tlb_track_iod_again,            "tlb_track_iod_again")
+PERFCOUNTER(tlb_track_iod_not_tracked,      "tlb_track_iod_not_tracked")
+PERFCOUNTER(tlb_track_iod_force_many,       "tlb_track_iod_force_many")
+PERFCOUNTER(tlb_track_iod_tracked_many,     "tlb_track_iod_tracked_many")
+PERFCOUNTER(tlb_track_iod_tracked_many_del, "tlb_track_iod_tracked_many_del")
+PERFCOUNTER(tlb_track_iod_found,            "tlb_track_iod_found")
+PERFCOUNTER(tlb_track_iod_new_entry,        "tlb_track_iod_new_entry")
+PERFCOUNTER(tlb_track_iod_new_failed,       "tlb_track_iod_new_failed")
+PERFCOUNTER(tlb_track_iod_new_many,         "tlb_track_iod_new_many")
+PERFCOUNTER(tlb_track_iod_insert,           "tlb_track_iod_insert")
+PERFCOUNTER(tlb_track_iod_dirtied,          "tlb_track_iod_dirtied")
 
 // search and remove
-PERFCOUNTER_CPU(tlb_track_sar,                  "tlb_track_sar")
-PERFCOUNTER_CPU(tlb_track_sar_not_tracked,      "tlb_track_sar_not_tracked")
-PERFCOUNTER_CPU(tlb_track_sar_not_found,        "tlb_track_sar_not_found")
-PERFCOUNTER_CPU(tlb_track_sar_found,            "tlb_track_sar_found")
-PERFCOUNTER_CPU(tlb_track_sar_many,             "tlb_track_sar_many")
+PERFCOUNTER(tlb_track_sar,                  "tlb_track_sar")
+PERFCOUNTER(tlb_track_sar_not_tracked,      "tlb_track_sar_not_tracked")
+PERFCOUNTER(tlb_track_sar_not_found,        "tlb_track_sar_not_found")
+PERFCOUNTER(tlb_track_sar_found,            "tlb_track_sar_found")
+PERFCOUNTER(tlb_track_sar_many,             "tlb_track_sar_many")
 
 // flush
-PERFCOUNTER_CPU(tlb_track_use_rr7,              "tlb_track_use_rr7")
-PERFCOUNTER_CPU(tlb_track_swap_rr0,             "tlb_track_swap_rr0")
+PERFCOUNTER(tlb_track_use_rr7,              "tlb_track_use_rr7")
+PERFCOUNTER(tlb_track_swap_rr0,             "tlb_track_swap_rr0")
 #endif
 
 // tlb flush clock
 #ifdef CONFIG_XEN_IA64_TLBFLUSH_CLOCK
-PERFCOUNTER_CPU(tlbflush_clock_cswitch_purge,  "tlbflush_clock_cswitch_purge")
-PERFCOUNTER_CPU(tlbflush_clock_cswitch_skip,   "tlbflush_clock_cswitch_skip")
+PERFCOUNTER(tlbflush_clock_cswitch_purge,  "tlbflush_clock_cswitch_purge")
+PERFCOUNTER(tlbflush_clock_cswitch_skip,   "tlbflush_clock_cswitch_skip")
 #endif
diff -r bc2811bf7771 -r 81fec499a983 xen/include/asm-ia64/privop_stat.h
--- a/xen/include/asm-ia64/privop_stat.h        Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/include/asm-ia64/privop_stat.h        Wed Mar 28 08:44:08 2007 +0000
@@ -1,5 +1,5 @@
-#ifndef _XEN_UA64_PRIVOP_STAT_H
-#define _XEN_UA64_PRIVOP_STAT_H
+#ifndef _XEN_IA64_PRIVOP_STAT_H
+#define _XEN_IA64_PRIVOP_STAT_H
 #include <asm/config.h>
 #include <xen/types.h>
 #include <public/xen.h>
@@ -9,30 +9,23 @@ extern void gather_privop_addrs(void);
 extern void gather_privop_addrs(void);
 extern void reset_privop_addrs(void);
 
-#undef  PERFCOUNTER
 #define PERFCOUNTER(var, name)
-
-#undef  PERFCOUNTER_CPU
-#define PERFCOUNTER_CPU(var, name)
-
-#undef  PERFCOUNTER_ARRAY
 #define PERFCOUNTER_ARRAY(var, name, size)
 
-#undef  PERFSTATUS
 #define PERFSTATUS(var, name)
-
-#undef  PERFSTATUS_CPU
-#define PERFSTATUS_CPU(var, name)
-
-#undef  PERFSTATUS_ARRAY
 #define PERFSTATUS_ARRAY(var, name, size)
 
-#undef  PERFPRIVOPADDR
 #define PERFPRIVOPADDR(name) privop_inst_##name,
 
 enum privop_inst {
 #include <asm/perfc_defn.h>
 };
+
+#undef PERFCOUNTER
+#undef PERFCOUNTER_ARRAY
+
+#undef PERFSTATUS
+#undef PERFSTATUS_ARRAY
 
 #undef PERFPRIVOPADDR
 
@@ -45,4 +38,4 @@ extern void privop_count_addr(unsigned l
 #define reset_privop_addrs() do {} while (0)
 #endif
 
-#endif /* _XEN_UA64_PRIVOP_STAT_H */
+#endif /* _XEN_IA64_PRIVOP_STAT_H */
diff -r bc2811bf7771 -r 81fec499a983 xen/include/asm-ia64/tlb_track.h
--- a/xen/include/asm-ia64/tlb_track.h  Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/include/asm-ia64/tlb_track.h  Wed Mar 28 08:44:08 2007 +0000
@@ -97,9 +97,9 @@ vcpu_tlb_track_insert_or_dirty(struct vc
 {
     /* optimization.
        non-tracking pte is most common. */
-    perfc_incrc(tlb_track_iod);
+    perfc_incr(tlb_track_iod);
     if (!pte_tlb_tracking(entry->used)) {
-        perfc_incrc(tlb_track_iod_not_tracked);
+        perfc_incr(tlb_track_iod_not_tracked);
         return;
     }
 
diff -r bc2811bf7771 -r 81fec499a983 xen/include/asm-powerpc/bug.h
--- a/xen/include/asm-powerpc/bug.h     Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/include/asm-powerpc/bug.h     Wed Mar 28 08:44:08 2007 +0000
@@ -2,5 +2,6 @@
 #define __POWERPC_BUG_H__
 
 #define BUG() __bug(__FILE__, __LINE__)
+#define WARN() __warn(__FILE__, __LINE__)
 
 #endif /* __POWERPC_BUG_H__ */
diff -r bc2811bf7771 -r 81fec499a983 xen/include/asm-powerpc/debugger.h
--- a/xen/include/asm-powerpc/debugger.h        Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/include/asm-powerpc/debugger.h        Wed Mar 28 08:44:08 2007 +0000
@@ -67,10 +67,6 @@ static inline void unimplemented(void)
 #endif
 }
 
-extern void __warn(char *file, int line);
-#define WARN() __warn(__FILE__, __LINE__)
-#define WARN_ON(_p) do { if (_p) WARN(); } while ( 0 )
-
 extern void __attn(void);
 #define ATTN() __attn();
 
diff -r bc2811bf7771 -r 81fec499a983 xen/include/asm-x86/bug.h
--- a/xen/include/asm-x86/bug.h Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/include/asm-x86/bug.h Wed Mar 28 08:44:08 2007 +0000
@@ -14,8 +14,8 @@ struct bug_frame {
 } __attribute__((packed));
 
 #define BUGFRAME_dump   0
-#define BUGFRAME_bug    1
-#define BUGFRAME_assert 2
-#define BUGFRAME_rsvd   3
+#define BUGFRAME_warn   1
+#define BUGFRAME_bug    2
+#define BUGFRAME_assert 3
 
 #endif /* __X86_BUG_H__ */
diff -r bc2811bf7771 -r 81fec499a983 xen/include/asm-x86/hvm/svm/vmcb.h
--- a/xen/include/asm-x86/hvm/svm/vmcb.h        Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/include/asm-x86/hvm/svm/vmcb.h        Wed Mar 28 08:44:08 2007 +0000
@@ -446,7 +446,6 @@ struct arch_svm_struct {
     u64                 vmcb_pa;
     u32                 *msrpm;
     u64                 vmexit_tsc; /* tsc read at #VMEXIT. for TSC_OFFSET */
-    int                 saved_irq_vector;
     int                 launch_core;
     
     unsigned long       flags;            /* VMCB flags */
diff -r bc2811bf7771 -r 81fec499a983 xen/include/asm-x86/multicall.h
--- a/xen/include/asm-x86/multicall.h   Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/include/asm-x86/multicall.h   Wed Mar 28 08:44:08 2007 +0000
@@ -6,84 +6,94 @@
 #define __ASM_X86_MULTICALL_H__
 
 #include <xen/errno.h>
-#include <asm/asm_defns.h>
 
 #ifdef __x86_64__
 
 #define do_multicall_call(_call)                             \
     do {                                                     \
         __asm__ __volatile__ (                               \
-            "    movq  "STR(MULTICALL_op)"(%0),%%rax; "      \
+            "    movq  %c1(%0),%%rax; "                      \
+            "    leaq  hypercall_table(%%rip),%%rdi; "       \
             "    cmpq  $("STR(NR_hypercalls)"),%%rax; "      \
             "    jae   2f; "                                 \
-            "    leaq  hypercall_table(%%rip),%%rdi; "       \
-            "    leaq  (%%rdi,%%rax,8),%%rax; "              \
-            "    movq  "STR(MULTICALL_arg0)"(%0),%%rdi; "    \
-            "    movq  "STR(MULTICALL_arg1)"(%0),%%rsi; "    \
-            "    movq  "STR(MULTICALL_arg2)"(%0),%%rdx; "    \
-            "    movq  "STR(MULTICALL_arg3)"(%0),%%rcx; "    \
-            "    movq  "STR(MULTICALL_arg4)"(%0),%%r8; "     \
-            "    callq *(%%rax); "                           \
-            "1:  movq  %%rax,"STR(MULTICALL_result)"(%0)\n"  \
+            "    movq  (%%rdi,%%rax,8),%%rax; "              \
+            "    movq  %c2+0*%c3(%0),%%rdi; "                \
+            "    movq  %c2+1*%c3(%0),%%rsi; "                \
+            "    movq  %c2+2*%c3(%0),%%rdx; "                \
+            "    movq  %c2+3*%c3(%0),%%rcx; "                \
+            "    movq  %c2+4*%c3(%0),%%r8; "                 \
+            "    callq *%%rax; "                             \
+            "1:  movq  %%rax,%c4(%0)\n"                      \
             ".section .fixup,\"ax\"\n"                       \
             "2:  movq  $-"STR(ENOSYS)",%%rax\n"              \
             "    jmp   1b\n"                                 \
             ".previous\n"                                    \
-            : : "b" (_call)                                  \
+            :                                                \
+            : "b" (_call),                                   \
+              "i" (offsetof(__typeof__(*_call), op)),        \
+              "i" (offsetof(__typeof__(*_call), args)),      \
+              "i" (sizeof(*(_call)->args)),                  \
+              "i" (offsetof(__typeof__(*_call), result))     \
               /* all the caller-saves registers */           \
             : "rax", "rcx", "rdx", "rsi", "rdi",             \
               "r8",  "r9",  "r10", "r11" );                  \
     } while ( 0 )
 
-#define compat_multicall_call(_call)                              \
-    do {                                                          \
-        __asm__ __volatile__ (                                    \
-            "    movl  "STR(COMPAT_MULTICALL_op)"(%0),%%eax; "    \
-            "    leaq  compat_hypercall_table(%%rip),%%rdi; "     \
-            "    cmpl  $("STR(NR_hypercalls)"),%%eax; "           \
-            "    jae   2f; "                                      \
-            "    movq  (%%rdi,%%rax,8),%%rax; "                   \
-            "    movl  "STR(COMPAT_MULTICALL_arg0)"(%0),%%edi; "  \
-            "    movl  "STR(COMPAT_MULTICALL_arg1)"(%0),%%esi; "  \
-            "    movl  "STR(COMPAT_MULTICALL_arg2)"(%0),%%edx; "  \
-            "    movl  "STR(COMPAT_MULTICALL_arg3)"(%0),%%ecx; "  \
-            "    movl  "STR(COMPAT_MULTICALL_arg4)"(%0),%%r8d; "  \
-            "    callq *%%rax; "                                  \
-            "1:  movl  %%eax,"STR(COMPAT_MULTICALL_result)"(%0)\n"\
-            ".section .fixup,\"ax\"\n"                            \
-            "2:  movl  $-"STR(ENOSYS)",%%eax\n"                   \
-            "    jmp   1b\n"                                      \
-            ".previous\n"                                         \
-            : : "b" (_call)                                       \
-              /* all the caller-saves registers */                \
-            : "rax", "rcx", "rdx", "rsi", "rdi",                  \
-              "r8",  "r9",  "r10", "r11" );                       \
-    } while ( 0 )
+#define compat_multicall_call(_call)                         \
+        __asm__ __volatile__ (                               \
+            "    movl  %c1(%0),%%eax; "                      \
+            "    leaq  compat_hypercall_table(%%rip),%%rdi; "\
+            "    cmpl  $("STR(NR_hypercalls)"),%%eax; "      \
+            "    jae   2f; "                                 \
+            "    movq  (%%rdi,%%rax,8),%%rax; "              \
+            "    movl  %c2+0*%c3(%0),%%edi; "                \
+            "    movl  %c2+1*%c3(%0),%%esi; "                \
+            "    movl  %c2+2*%c3(%0),%%edx; "                \
+            "    movl  %c2+3*%c3(%0),%%ecx; "                \
+            "    movl  %c2+4*%c3(%0),%%r8d; "                \
+            "    callq *%%rax; "                             \
+            "1:  movl  %%eax,%c4(%0)\n"                      \
+            ".section .fixup,\"ax\"\n"                       \
+            "2:  movl  $-"STR(ENOSYS)",%%eax\n"              \
+            "    jmp   1b\n"                                 \
+            ".previous\n"                                    \
+            :                                                \
+            : "b" (_call),                                   \
+              "i" (offsetof(__typeof__(*_call), op)),        \
+              "i" (offsetof(__typeof__(*_call), args)),      \
+              "i" (sizeof(*(_call)->args)),                  \
+              "i" (offsetof(__typeof__(*_call), result))     \
+              /* all the caller-saves registers */           \
+            : "rax", "rcx", "rdx", "rsi", "rdi",             \
+              "r8",  "r9",  "r10", "r11" )                   \
 
 #else
 
 #define do_multicall_call(_call)                             \
-    do {                                                     \
         __asm__ __volatile__ (                               \
-            "    pushl "STR(MULTICALL_arg4)"(%0); "          \
-            "    pushl "STR(MULTICALL_arg3)"(%0); "          \
-            "    pushl "STR(MULTICALL_arg2)"(%0); "          \
-            "    pushl "STR(MULTICALL_arg1)"(%0); "          \
-            "    pushl "STR(MULTICALL_arg0)"(%0); "          \
-            "    movl  "STR(MULTICALL_op)"(%0),%%eax; "      \
+            "    movl  %c1(%0),%%eax; "                      \
+            "    pushl %c2+4*%c3(%0); "                      \
+            "    pushl %c2+3*%c3(%0); "                      \
+            "    pushl %c2+2*%c3(%0); "                      \
+            "    pushl %c2+1*%c3(%0); "                      \
+            "    pushl %c2+0*%c3(%0); "                      \
             "    cmpl  $("STR(NR_hypercalls)"),%%eax; "      \
             "    jae   2f; "                                 \
             "    call  *hypercall_table(,%%eax,4); "         \
-            "1:  movl  %%eax,"STR(MULTICALL_result)"(%0); "  \
+            "1:  movl  %%eax,%c4(%0); "                      \
             "    addl  $20,%%esp\n"                          \
             ".section .fixup,\"ax\"\n"                       \
             "2:  movl  $-"STR(ENOSYS)",%%eax\n"              \
             "    jmp   1b\n"                                 \
             ".previous\n"                                    \
-            : : "b" (_call)                                  \
+            :                                                \
+            : "bSD" (_call),                                 \
+              "i" (offsetof(__typeof__(*_call), op)),        \
+              "i" (offsetof(__typeof__(*_call), args)),      \
+              "i" (sizeof(*(_call)->args)),                  \
+              "i" (offsetof(__typeof__(*_call), result))     \
               /* all the caller-saves registers */           \
-            : "eax", "ecx", "edx" );                         \
-    } while ( 0 )
+            : "eax", "ecx", "edx" )                          \
 
 #endif
 
diff -r bc2811bf7771 -r 81fec499a983 xen/include/asm-x86/perfc_defn.h
--- a/xen/include/asm-x86/perfc_defn.h  Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/include/asm-x86/perfc_defn.h  Wed Mar 28 08:44:08 2007 +0000
@@ -12,81 +12,83 @@ PERFCOUNTER_ARRAY(cause_vector,         
 #define SVM_PERF_EXIT_REASON_SIZE (1+136)
 PERFCOUNTER_ARRAY(svmexits,             "SVMexits", SVM_PERF_EXIT_REASON_SIZE)
 
-PERFCOUNTER_CPU(seg_fixups,             "segmentation fixups")
+PERFCOUNTER(seg_fixups,             "segmentation fixups")
 
-PERFCOUNTER_CPU(apic_timer,             "apic timer interrupts")
+PERFCOUNTER(apic_timer,             "apic timer interrupts")
 
-PERFCOUNTER_CPU(domain_page_tlb_flush,  "domain page tlb flushes")
+PERFCOUNTER(domain_page_tlb_flush,  "domain page tlb flushes")
 
-PERFCOUNTER_CPU(calls_to_mmu_update,    "calls_to_mmu_update")
-PERFCOUNTER_CPU(num_page_updates,       "num_page_updates")
-PERFCOUNTER_CPU(calls_to_update_va,     "calls_to_update_va_map")
-PERFCOUNTER_CPU(page_faults,            "page faults")
-PERFCOUNTER_CPU(copy_user_faults,       "copy_user faults")
+PERFCOUNTER(calls_to_mmuext_op,         "calls to mmuext_op")
+PERFCOUNTER(num_mmuext_ops,             "mmuext ops")
+PERFCOUNTER(calls_to_mmu_update,        "calls to mmu_update")
+PERFCOUNTER(num_page_updates,           "page updates")
+PERFCOUNTER(calls_to_update_va,         "calls to update_va_map")
+PERFCOUNTER(page_faults,            "page faults")
+PERFCOUNTER(copy_user_faults,       "copy_user faults")
 
-PERFCOUNTER_CPU(map_domain_page_count,  "map_domain_page count")
-PERFCOUNTER_CPU(ptwr_emulations,        "writable pt emulations")
+PERFCOUNTER(map_domain_page_count,  "map_domain_page count")
+PERFCOUNTER(ptwr_emulations,        "writable pt emulations")
 
-PERFCOUNTER_CPU(exception_fixed,        "pre-exception fixed")
+PERFCOUNTER(exception_fixed,        "pre-exception fixed")
 
 
 /* Shadow counters */
-PERFCOUNTER_CPU(shadow_alloc,          "calls to shadow_alloc")
-PERFCOUNTER_CPU(shadow_alloc_tlbflush, "shadow_alloc flushed TLBs")
+PERFCOUNTER(shadow_alloc,          "calls to shadow_alloc")
+PERFCOUNTER(shadow_alloc_tlbflush, "shadow_alloc flushed TLBs")
 
 /* STATUS counters do not reset when 'P' is hit */
 PERFSTATUS(shadow_alloc_count,         "number of shadow pages in use")
-PERFCOUNTER_CPU(shadow_free,           "calls to shadow_free")
-PERFCOUNTER_CPU(shadow_prealloc_1,     "shadow recycles old shadows")
-PERFCOUNTER_CPU(shadow_prealloc_2,     "shadow recycles in-use shadows")
-PERFCOUNTER_CPU(shadow_linear_map_failed, "shadow hit read-only linear map")
-PERFCOUNTER_CPU(shadow_a_update,       "shadow A bit update")
-PERFCOUNTER_CPU(shadow_ad_update,      "shadow A&D bit update")
-PERFCOUNTER_CPU(shadow_fault,          "calls to shadow_fault")
-PERFCOUNTER_CPU(shadow_fault_fast_gnp, "shadow_fault fast path n/p")
-PERFCOUNTER_CPU(shadow_fault_fast_mmio, "shadow_fault fast path mmio")
-PERFCOUNTER_CPU(shadow_fault_fast_fail, "shadow_fault fast path error")
-PERFCOUNTER_CPU(shadow_fault_bail_bad_gfn, "shadow_fault guest bad gfn")
-PERFCOUNTER_CPU(shadow_fault_bail_not_present, 
+PERFCOUNTER(shadow_free,           "calls to shadow_free")
+PERFCOUNTER(shadow_prealloc_1,     "shadow recycles old shadows")
+PERFCOUNTER(shadow_prealloc_2,     "shadow recycles in-use shadows")
+PERFCOUNTER(shadow_linear_map_failed, "shadow hit read-only linear map")
+PERFCOUNTER(shadow_a_update,       "shadow A bit update")
+PERFCOUNTER(shadow_ad_update,      "shadow A&D bit update")
+PERFCOUNTER(shadow_fault,          "calls to shadow_fault")
+PERFCOUNTER(shadow_fault_fast_gnp, "shadow_fault fast path n/p")
+PERFCOUNTER(shadow_fault_fast_mmio, "shadow_fault fast path mmio")
+PERFCOUNTER(shadow_fault_fast_fail, "shadow_fault fast path error")
+PERFCOUNTER(shadow_fault_bail_bad_gfn, "shadow_fault guest bad gfn")
+PERFCOUNTER(shadow_fault_bail_not_present, 
                                         "shadow_fault guest not-present")
-PERFCOUNTER_CPU(shadow_fault_bail_nx,  "shadow_fault guest NX fault")
-PERFCOUNTER_CPU(shadow_fault_bail_ro_mapping, "shadow_fault guest R/W fault")
-PERFCOUNTER_CPU(shadow_fault_bail_user_supervisor, 
+PERFCOUNTER(shadow_fault_bail_nx,  "shadow_fault guest NX fault")
+PERFCOUNTER(shadow_fault_bail_ro_mapping, "shadow_fault guest R/W fault")
+PERFCOUNTER(shadow_fault_bail_user_supervisor, 
                                         "shadow_fault guest U/S fault")
-PERFCOUNTER_CPU(shadow_fault_emulate_read, "shadow_fault emulates a read")
-PERFCOUNTER_CPU(shadow_fault_emulate_write, "shadow_fault emulates a write")
-PERFCOUNTER_CPU(shadow_fault_emulate_failed, "shadow_fault emulator fails")
-PERFCOUNTER_CPU(shadow_fault_emulate_stack, "shadow_fault emulate stack write")
-PERFCOUNTER_CPU(shadow_fault_mmio,     "shadow_fault handled as mmio")
-PERFCOUNTER_CPU(shadow_fault_fixed,    "shadow_fault fixed fault")
-PERFCOUNTER_CPU(shadow_ptwr_emulate,   "shadow causes ptwr to emulate")
-PERFCOUNTER_CPU(shadow_validate_gl1e_calls, "calls to shadow_validate_gl1e")
-PERFCOUNTER_CPU(shadow_validate_gl2e_calls, "calls to shadow_validate_gl2e")
-PERFCOUNTER_CPU(shadow_validate_gl3e_calls, "calls to shadow_validate_gl3e")
-PERFCOUNTER_CPU(shadow_validate_gl4e_calls, "calls to shadow_validate_gl4e")
-PERFCOUNTER_CPU(shadow_hash_lookups,   "calls to shadow_hash_lookup")
-PERFCOUNTER_CPU(shadow_hash_lookup_head, "shadow hash hit in bucket head")
-PERFCOUNTER_CPU(shadow_hash_lookup_miss, "shadow hash misses")
-PERFCOUNTER_CPU(shadow_get_shadow_status, "calls to get_shadow_status")
-PERFCOUNTER_CPU(shadow_hash_inserts,   "calls to shadow_hash_insert")
-PERFCOUNTER_CPU(shadow_hash_deletes,   "calls to shadow_hash_delete")
-PERFCOUNTER_CPU(shadow_writeable,      "shadow removes write access")
-PERFCOUNTER_CPU(shadow_writeable_h_1,  "shadow writeable: 32b w2k3")
-PERFCOUNTER_CPU(shadow_writeable_h_2,  "shadow writeable: 32pae w2k3")
-PERFCOUNTER_CPU(shadow_writeable_h_3,  "shadow writeable: 64b w2k3")
-PERFCOUNTER_CPU(shadow_writeable_h_4,  "shadow writeable: 32b linux low")
-PERFCOUNTER_CPU(shadow_writeable_h_5,  "shadow writeable: 32b linux high")
-PERFCOUNTER_CPU(shadow_writeable_bf,   "shadow writeable brute-force")
-PERFCOUNTER_CPU(shadow_mappings,       "shadow removes all mappings")
-PERFCOUNTER_CPU(shadow_mappings_bf,    "shadow rm-mappings brute-force")
-PERFCOUNTER_CPU(shadow_early_unshadow, "shadow unshadows for fork/exit")
-PERFCOUNTER_CPU(shadow_unshadow,       "shadow unshadows a page")
-PERFCOUNTER_CPU(shadow_up_pointer,     "shadow unshadow by up-pointer")
-PERFCOUNTER_CPU(shadow_unshadow_bf,    "shadow unshadow brute-force")
-PERFCOUNTER_CPU(shadow_get_page_fail,  "shadow_get_page_from_l1e failed")
-PERFCOUNTER_CPU(shadow_guest_walk,     "shadow walks guest tables")
-PERFCOUNTER_CPU(shadow_invlpg,         "shadow emulates invlpg")
-PERFCOUNTER_CPU(shadow_invlpg_fault,   "shadow invlpg faults")
+PERFCOUNTER(shadow_fault_emulate_read, "shadow_fault emulates a read")
+PERFCOUNTER(shadow_fault_emulate_write, "shadow_fault emulates a write")
+PERFCOUNTER(shadow_fault_emulate_failed, "shadow_fault emulator fails")
+PERFCOUNTER(shadow_fault_emulate_stack, "shadow_fault emulate stack write")
+PERFCOUNTER(shadow_fault_mmio,     "shadow_fault handled as mmio")
+PERFCOUNTER(shadow_fault_fixed,    "shadow_fault fixed fault")
+PERFCOUNTER(shadow_ptwr_emulate,   "shadow causes ptwr to emulate")
+PERFCOUNTER(shadow_validate_gl1e_calls, "calls to shadow_validate_gl1e")
+PERFCOUNTER(shadow_validate_gl2e_calls, "calls to shadow_validate_gl2e")
+PERFCOUNTER(shadow_validate_gl3e_calls, "calls to shadow_validate_gl3e")
+PERFCOUNTER(shadow_validate_gl4e_calls, "calls to shadow_validate_gl4e")
+PERFCOUNTER(shadow_hash_lookups,   "calls to shadow_hash_lookup")
+PERFCOUNTER(shadow_hash_lookup_head, "shadow hash hit in bucket head")
+PERFCOUNTER(shadow_hash_lookup_miss, "shadow hash misses")
+PERFCOUNTER(shadow_get_shadow_status, "calls to get_shadow_status")
+PERFCOUNTER(shadow_hash_inserts,   "calls to shadow_hash_insert")
+PERFCOUNTER(shadow_hash_deletes,   "calls to shadow_hash_delete")
+PERFCOUNTER(shadow_writeable,      "shadow removes write access")
+PERFCOUNTER(shadow_writeable_h_1,  "shadow writeable: 32b w2k3")
+PERFCOUNTER(shadow_writeable_h_2,  "shadow writeable: 32pae w2k3")
+PERFCOUNTER(shadow_writeable_h_3,  "shadow writeable: 64b w2k3")
+PERFCOUNTER(shadow_writeable_h_4,  "shadow writeable: 32b linux low")
+PERFCOUNTER(shadow_writeable_h_5,  "shadow writeable: 32b linux high")
+PERFCOUNTER(shadow_writeable_bf,   "shadow writeable brute-force")
+PERFCOUNTER(shadow_mappings,       "shadow removes all mappings")
+PERFCOUNTER(shadow_mappings_bf,    "shadow rm-mappings brute-force")
+PERFCOUNTER(shadow_early_unshadow, "shadow unshadows for fork/exit")
+PERFCOUNTER(shadow_unshadow,       "shadow unshadows a page")
+PERFCOUNTER(shadow_up_pointer,     "shadow unshadow by up-pointer")
+PERFCOUNTER(shadow_unshadow_bf,    "shadow unshadow brute-force")
+PERFCOUNTER(shadow_get_page_fail,  "shadow_get_page_from_l1e failed")
+PERFCOUNTER(shadow_guest_walk,     "shadow walks guest tables")
+PERFCOUNTER(shadow_invlpg,         "shadow emulates invlpg")
+PERFCOUNTER(shadow_invlpg_fault,   "shadow invlpg faults")
 
 
 /*#endif*/ /* __XEN_PERFC_DEFN_H__ */
diff -r bc2811bf7771 -r 81fec499a983 xen/include/asm-x86/x86_32/asm_defns.h
--- a/xen/include/asm-x86/x86_32/asm_defns.h    Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/include/asm-x86/x86_32/asm_defns.h    Wed Mar 28 08:44:08 2007 +0000
@@ -1,5 +1,7 @@
 #ifndef __X86_32_ASM_DEFNS_H__
 #define __X86_32_ASM_DEFNS_H__
+
+#include <asm/percpu.h>
 
 #ifndef NDEBUG
 /* Indicate special exception stack frame by inverting the frame pointer. */
@@ -47,10 +49,14 @@
         1:
 
 #ifdef PERF_COUNTERS
-#define PERFC_INCR(_name,_idx)                          \
-        lock incl perfcounters+_name(,_idx,4)
+#define PERFC_INCR(_name,_idx,_cur)                     \
+        pushl _cur;                                     \
+        movl VCPU_processor(_cur),_cur;                 \
+        shll $PERCPU_SHIFT,_cur;                        \
+        incl per_cpu__perfcounters+_name*4(_cur,_idx,4);\
+        popl _cur
 #else
-#define PERFC_INCR(_name,_idx)
+#define PERFC_INCR(_name,_idx,_cur)
 #endif
 
 #ifdef CONFIG_X86_SUPERVISOR_MODE_KERNEL
diff -r bc2811bf7771 -r 81fec499a983 xen/include/asm-x86/x86_32/bug.h
--- a/xen/include/asm-x86/x86_32/bug.h  Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/include/asm-x86/x86_32/bug.h  Wed Mar 28 08:44:08 2007 +0000
@@ -11,6 +11,12 @@ struct bug_frame_str {
     asm volatile (                                      \
         "ud2 ; ret $%c0"                                \
         : : "i" (BUGFRAME_dump) )
+
+#define WARN()                                          \
+    asm volatile (                                      \
+        "ud2 ; ret $%c0 ; .byte 0xbc ; .long %c1"       \
+        : : "i" (BUGFRAME_warn | (__LINE__<<2)),        \
+            "i" (__FILE__) )
 
 #define BUG()                                           \
     asm volatile (                                      \
diff -r bc2811bf7771 -r 81fec499a983 xen/include/asm-x86/x86_64/asm_defns.h
--- a/xen/include/asm-x86/x86_64/asm_defns.h    Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/include/asm-x86/x86_64/asm_defns.h    Wed Mar 28 08:44:08 2007 +0000
@@ -1,5 +1,7 @@
 #ifndef __X86_64_ASM_DEFNS_H__
 #define __X86_64_ASM_DEFNS_H__
+
+#include <asm/percpu.h>
 
 #ifndef NDEBUG
 /* Indicate special exception stack frame by inverting the frame pointer. */
@@ -47,13 +49,18 @@
         popq  %rdi;
 
 #ifdef PERF_COUNTERS
-#define PERFC_INCR(_name,_idx)                  \
-    pushq %rdx;                                 \
-    leaq perfcounters+_name(%rip),%rdx;         \
-    lock incl (%rdx,_idx,4);                    \
-    popq %rdx;
+#define PERFC_INCR(_name,_idx,_cur)             \
+        pushq _cur;                             \
+        movslq VCPU_processor(_cur),_cur;       \
+        pushq %rdx;                             \
+        leaq per_cpu__perfcounters(%rip),%rdx;  \
+        shlq $PERCPU_SHIFT,_cur;                \
+        addq %rdx,_cur;                         \
+        popq %rdx;                              \
+        incl _name*4(_cur,_idx,4);              \
+        popq _cur
 #else
-#define PERFC_INCR(_name,_idx)
+#define PERFC_INCR(_name,_idx,_cur)
 #endif
 
 /* Work around AMD erratum #88 */
diff -r bc2811bf7771 -r 81fec499a983 xen/include/asm-x86/x86_64/bug.h
--- a/xen/include/asm-x86/x86_64/bug.h  Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/include/asm-x86/x86_64/bug.h  Wed Mar 28 08:44:08 2007 +0000
@@ -11,6 +11,12 @@ struct bug_frame_str {
     asm volatile (                                      \
         "ud2 ; ret $%c0"                                \
         : : "i" (BUGFRAME_dump) )
+
+#define WARN()                                          \
+    asm volatile (                                      \
+        "ud2 ; ret $%c0 ; .byte 0x48,0xbc ; .quad %c1"  \
+        : : "i" (BUGFRAME_warn | (__LINE__<<2)),        \
+            "i" (__FILE__) )
 
 #define BUG()                                           \
     asm volatile (                                      \
diff -r bc2811bf7771 -r 81fec499a983 xen/include/public/foreign/Makefile
--- a/xen/include/public/foreign/Makefile       Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/include/public/foreign/Makefile       Wed Mar 28 08:44:08 2007 +0000
@@ -1,5 +1,5 @@ XEN_ROOT := ../../../..
-XEN_ROOT := ../../../..
-include $(XEN_ROOT)/tools/Rules.mk
+XEN_ROOT=../../../..
+include $(XEN_ROOT)/Config.mk
 
 architectures := x86_32 x86_64 ia64
 headers := $(patsubst %, %.h, $(architectures))
diff -r bc2811bf7771 -r 81fec499a983 xen/include/xen/lib.h
--- a/xen/include/xen/lib.h     Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/include/xen/lib.h     Wed Mar 28 08:44:08 2007 +0000
@@ -10,8 +10,10 @@
 #include <asm/bug.h>
 
 void __bug(char *file, int line) __attribute__((noreturn));
+void __warn(char *file, int line);
 
-#define BUG_ON(_p) do { if (_p) BUG(); } while ( 0 )
+#define BUG_ON(p)  do { if (p) BUG();  } while (0)
+#define WARN_ON(p) do { if (p) WARN(); } while (0)
 
 /* Force a compilation error if condition is true */
 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 * !!(condition)]))
diff -r bc2811bf7771 -r 81fec499a983 xen/include/xen/perfc.h
--- a/xen/include/xen/perfc.h   Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/include/xen/perfc.h   Wed Mar 28 08:44:08 2007 +0000
@@ -1,4 +1,3 @@
-
 #ifndef __XEN_PERFC_H__
 #define __XEN_PERFC_H__
 
@@ -6,102 +5,92 @@
 
 #include <xen/lib.h>
 #include <xen/smp.h>
-#include <asm/atomic.h>
+#include <xen/percpu.h>
 
-/* 
+/*
  * NOTE: new counters must be defined in perfc_defn.h
  * 
+ * Counter declarations:
  * PERFCOUNTER (counter, string)              define a new performance counter
- * PERFCOUNTER_CPU (counter, string, size)    define a counter per CPU
- * PERFCOUNTER_ARRY (counter, string, size)   define an array of counters
+ * PERFCOUNTER_ARRAY (counter, string, size)  define an array of counters
  * 
- * unlike "COUNTERS", "STATUS" variables DO NOT RESET
+ * Unlike counters, status variables do not reset:
  * PERFSTATUS (counter, string)               define a new performance stauts
- * PERFSTATUS_CPU (counter, string, size)     define a status var per CPU
- * PERFSTATUS_ARRY (counter, string, size)    define an array of status vars
+ * PERFSTATUS_ARRAY (counter, string, size)   define an array of status vars
  * 
  * unsigned long perfc_value  (counter)        get value of a counter  
- * unsigned long perfc_valuec (counter)        get value of a per CPU counter
  * unsigned long perfc_valuea (counter, index) get value of an array counter
  * unsigned long perfc_set  (counter, val)     set value of a counter  
- * unsigned long perfc_setc (counter, val)     set value of a per CPU counter
  * unsigned long perfc_seta (counter, index, val) set value of an array counter
  * void perfc_incr  (counter)                  increment a counter          
- * void perfc_incrc (counter, index)           increment a per CPU counter   
+ * void perfc_decr  (counter)                  decrement a status
  * void perfc_incra (counter, index)           increment an array counter   
  * void perfc_add   (counter, value)           add a value to a counter     
- * void perfc_addc  (counter, value)           add a value to a per CPU counter
  * void perfc_adda  (counter, index, value)    add a value to array counter 
  * void perfc_print (counter)                  print out the counter
  */
 
-#define PERFCOUNTER( var, name ) \
-  atomic_t var[1];
-#define PERFCOUNTER_CPU( var, name ) \
-  atomic_t var[NR_CPUS];
-#define PERFCOUNTER_ARRAY( var, name, size ) \
-  atomic_t var[size];
-#define PERFSTATUS( var, name ) \
-  atomic_t var[1];
-#define PERFSTATUS_CPU( var, name ) \
-  atomic_t var[NR_CPUS];
-#define PERFSTATUS_ARRAY( var, name, size ) \
-  atomic_t var[size];
+#define PERFCOUNTER( name, descr ) \
+  PERFC_##name,
+#define PERFCOUNTER_ARRAY( name, descr, size ) \
+  PERFC_##name,                                \
+  PERFC_LAST_##name = PERFC_ ## name + (size) - sizeof(char[2 * !!(size) - 1]),
 
-struct perfcounter {
+#define PERFSTATUS       PERFCOUNTER
+#define PERFSTATUS_ARRAY PERFCOUNTER_ARRAY
+
+enum perfcounter {
 #include <xen/perfc_defn.h>
+       NUM_PERFCOUNTERS
 };
 
-extern struct perfcounter perfcounters;
+#undef PERFCOUNTER
+#undef PERFCOUNTER_ARRAY
+#undef PERFSTATUS
+#undef PERFSTATUS_ARRAY
 
-#define perfc_value(x)    atomic_read(&perfcounters.x[0])
-#define perfc_valuec(x)   atomic_read(&perfcounters.x[smp_processor_id()])
+typedef unsigned perfc_t;
+#define PRIperfc ""
+
+DECLARE_PER_CPU(perfc_t[NUM_PERFCOUNTERS], perfcounters);
+
+#define perfc_value(x)    this_cpu(perfcounters)[PERFC_ ## x]
 #define perfc_valuea(x,y)                                               \
-    ( (y) < (sizeof(perfcounters.x) / sizeof(*perfcounters.x)) ?       \
-       atomic_read(&perfcounters.x[y]) : 0 )
-#define perfc_set(x,v)    atomic_set(&perfcounters.x[0], v)
-#define perfc_setc(x,v)   atomic_set(&perfcounters.x[smp_processor_id()], v)
+    ( (y) <= PERFC_LAST_ ## x - PERFC_ ## x ?                           \
+        this_cpu(perfcounters)[PERFC_ ## x + (y)] : 0 )
+#define perfc_set(x,v)    (this_cpu(perfcounters)[PERFC_ ## x] = (v))
 #define perfc_seta(x,y,v)                                               \
-    do {                                                                \
-        if ( (y) < (sizeof(perfcounters.x) / sizeof(*perfcounters.x)) ) \
-            atomic_set(&perfcounters.x[y], v);                          \
-    } while ( 0 )
-#define perfc_incr(x)     atomic_inc(&perfcounters.x[0])
-#define perfc_decr(x)     atomic_dec(&perfcounters.x[0])
-#define perfc_incrc(x)    atomic_inc(&perfcounters.x[smp_processor_id()])
-#define perfc_decrc(x)    atomic_dec(&perfcounters.x[smp_processor_id()])
+    ( (y) <= PERFC_LAST_ ## x - PERFC_ ## x ?                           \
+        this_cpu(perfcounters)[PERFC_ ## x + (y)] = (v) : (v) )
+#define perfc_incr(x)     (++this_cpu(perfcounters)[PERFC_ ## x])
+#define perfc_decr(x)     (--this_cpu(perfcounters)[PERFC_ ## x])
 #define perfc_incra(x,y)                                                \
-    do {                                                                \
-        if ( (y) < (sizeof(perfcounters.x) / sizeof(*perfcounters.x)) ) \
-            atomic_inc(&perfcounters.x[y]);                             \
-    } while ( 0 )
-#define perfc_add(x,y)    atomic_add((y), &perfcounters.x[0])
-#define perfc_addc(x,y)   atomic_add((y), &perfcounters.x[smp_processor_id()])
-#define perfc_adda(x,y,z)                                               \
-    do {                                                                \
-        if ( (y) < (sizeof(perfcounters.x) / sizeof(*perfcounters.x)) ) \
-            atomic_add((z), &perfcounters.x[y]);                        \
-    } while ( 0 )
+    ( (y) <= PERFC_LAST_ ## x - PERFC_ ## x ?                           \
+        ++this_cpu(perfcounters)[PERFC_ ## x + (y)] : 0 )
+#define perfc_add(x,v)    (this_cpu(perfcounters)[PERFC_ ## x] += (v))
+#define perfc_adda(x,y,v)                                               \
+    ( (y) <= PERFC_LAST_ ## x - PERFC_ ## x ?                           \
+        this_cpu(perfcounters)[PERFC_ ## x + (y)] = (v) : (v) )
 
 /*
  * Histogram: special treatment for 0 and 1 count. After that equally spaced 
  * with last bucket taking the rest.
  */
 #ifdef PERF_ARRAYS
-#define perfc_incr_histo(_x,_v,_n)                                          \
-    do {                                                                    \
-        if ( (_v) == 0 )                                                    \
-            perfc_incra(_x, 0);                                             \
-        else if ( (_v) == 1 )                                               \
-            perfc_incra(_x, 1);                                             \
-        else if ( (((_v)-2) / PERFC_ ## _n ## _BUCKET_SIZE) <               \
-                  (PERFC_MAX_ ## _n - 3) )                                  \
-            perfc_incra(_x, (((_v)-2) / PERFC_ ## _n ## _BUCKET_SIZE) + 2); \
-        else                                                                \
-            perfc_incra(_x, PERFC_MAX_ ## _n - 1);                          \
+#define perfc_incr_histo(x,v)                                           \
+    do {                                                                \
+        if ( (v) == 0 )                                                 \
+            perfc_incra(x, 0);                                          \
+        else if ( (v) == 1 )                                            \
+            perfc_incra(x, 1);                                          \
+        else if ( (((v) - 2) / PERFC_ ## x ## _BUCKET_SIZE) <           \
+                  (PERFC_LAST_ ## x - PERFC_ ## x - 2) )                \
+            perfc_incra(x, (((v) - 2) / PERFC_ ## x ## _BUCKET_SIZE) + 2); \
+        else                                                            \
+            perfc_incra(x, PERFC_LAST_ ## x - PERFC_ ## x);             \
     } while ( 0 )
 #else
-#define perfc_incr_histo(_x,_v,_n) ((void)0)
+#define perfc_incr_histo(x,v) ((void)0)
 #endif
 
 struct xen_sysctl_perfc_op;
@@ -110,19 +99,14 @@ int perfc_control(struct xen_sysctl_perf
 #else /* PERF_COUNTERS */
 
 #define perfc_value(x)    (0)
-#define perfc_valuec(x)   (0)
 #define perfc_valuea(x,y) (0)
 #define perfc_set(x,v)    ((void)0)
-#define perfc_setc(x,v)   ((void)0)
 #define perfc_seta(x,y,v) ((void)0)
 #define perfc_incr(x)     ((void)0)
 #define perfc_decr(x)     ((void)0)
-#define perfc_incrc(x)    ((void)0)
-#define perfc_decrc(x)    ((void)0)
 #define perfc_incra(x,y)  ((void)0)
 #define perfc_decra(x,y)  ((void)0)
 #define perfc_add(x,y)    ((void)0)
-#define perfc_addc(x,y)   ((void)0)
 #define perfc_adda(x,y,z) ((void)0)
 #define perfc_incr_histo(x,y,z) ((void)0)
 
diff -r bc2811bf7771 -r 81fec499a983 xen/include/xen/perfc_defn.h
--- a/xen/include/xen/perfc_defn.h      Wed Mar 28 08:40:42 2007 +0000
+++ b/xen/include/xen/perfc_defn.h      Wed Mar 28 08:44:08 2007 +0000
@@ -6,13 +6,16 @@
 
 PERFCOUNTER_ARRAY(hypercalls,           "hypercalls", NR_hypercalls)
 
-PERFCOUNTER_CPU(irqs,                   "#interrupts")
-PERFCOUNTER_CPU(ipis,                   "#IPIs")
+PERFCOUNTER(calls_to_multicall,         "calls to multicall")
+PERFCOUNTER(calls_from_multicall,       "calls from multicall")
 
-PERFCOUNTER_CPU(sched_irq,              "sched: timer")
-PERFCOUNTER_CPU(sched_run,              "sched: runs through scheduler")
-PERFCOUNTER_CPU(sched_ctx,              "sched: context switches")
+PERFCOUNTER(irqs,                   "#interrupts")
+PERFCOUNTER(ipis,                   "#IPIs")
 
-PERFCOUNTER_CPU(need_flush_tlb_flush,   "PG_need_flush tlb flushes")
+PERFCOUNTER(sched_irq,              "sched: timer")
+PERFCOUNTER(sched_run,              "sched: runs through scheduler")
+PERFCOUNTER(sched_ctx,              "sched: context switches")
+
+PERFCOUNTER(need_flush_tlb_flush,   "PG_need_flush tlb flushes")
 
 /*#endif*/ /* __XEN_PERFC_DEFN_H__ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>