ia64/xen-unstable

changeset 18421:d0a544d8a3f3

merge with xen-unstable.hg
author Isaku Yamahata <yamahata@valinux.co.jp>
date Mon Sep 01 16:59:43 2008 +0900 (2008-09-01)
parents 48db4eee7d58 05c7efee10a1
children 4ddd63b4be9b
files
line diff
     2.1 --- a/docs/misc/vtpm.txt	Mon Aug 25 19:04:37 2008 +0900
     2.2 +++ b/docs/misc/vtpm.txt	Mon Sep 01 16:59:43 2008 +0900
     2.3 @@ -92,8 +92,8 @@ the actual instance number that is assig
     2.4  can be different. This is the case if for example that particular
     2.5  instance is already used by another virtual machine. The association
     2.6  of which TPM instance number is used by which virtual machine is
     2.7 -kept in the file /etc/xen/vtpm.db. Associations are maintained by
     2.8 -domain name and instance number.
     2.9 +kept in the file /var/vtpm/vtpm.db. Associations are maintained by
    2.10 +a xend-internal vTPM UUID and vTPM instance number.
    2.11  
    2.12  Note: If you do not want TPM functionality for your user domain simply
    2.13  leave out the 'vtpm' line in the configuration file.
     3.1 --- a/docs/src/user.tex	Mon Aug 25 19:04:37 2008 +0900
     3.2 +++ b/docs/src/user.tex	Mon Sep 01 16:59:43 2008 +0900
     3.3 @@ -22,7 +22,7 @@
     3.4  \vfill
     3.5  \begin{tabular}{l}
     3.6  {\Huge \bf Users' Manual} \\[4mm]
     3.7 -{\huge Xen v3.0} \\[80mm]
     3.8 +{\huge Xen v3.3} \\[80mm]
     3.9  \end{tabular}
    3.10  \end{center}
    3.11  
    3.12 @@ -42,9 +42,7 @@ welcome.}
    3.13  
    3.14  \vspace*{\fill}
    3.15  
    3.16 -Xen is Copyright \copyright  2002-2005, University of Cambridge, UK, XenSource
    3.17 -Inc., IBM Corp., Hewlett-Packard Co., Intel Corp., AMD Inc., and others.  All
    3.18 -rights reserved.
    3.19 +Xen is Copyright \copyright  2002-2008, Citrix Systems, Inc., University of Cambridge, UK, XenSource Inc., IBM Corp., Hewlett-Packard Co., Intel Corp., AMD Inc., and others.  All rights reserved.
    3.20  
    3.21  Xen is an open-source project.  Most portions of Xen are licensed for copying
    3.22  under the terms of the GNU General Public License, version 2.  Other portions
    3.23 @@ -116,16 +114,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    3.24  
    3.25  
    3.26  Xen is an open-source \emph{para-virtualizing} virtual machine monitor
    3.27 -(VMM), or ``hypervisor'', for the x86 processor architecture. Xen can
    3.28 -securely execute multiple virtual machines on a single physical system
    3.29 -with close-to-native performance.  Xen facilitates enterprise-grade
    3.30 -functionality, including:
    3.31 +(VMM), or ``hypervisor'', for a variety of processor architectures including x86. Xen can securely execute multiple virtual machines on a single physical system with near native performance.  Xen facilitates enterprise-grade functionality, including:
    3.32  
    3.33  \begin{itemize}
    3.34  \item Virtual machines with performance close to native hardware.
    3.35  \item Live migration of running virtual machines between physical hosts.
    3.36  \item Up to 32\footnote{IA64 supports up to 64 virtual CPUs per guest virtual machine} virtual CPUs per guest virtual machine, with VCPU hotplug.
    3.37 -\item x86/32, x86/32 with PAE, x86/64, IA64 and Power platform support.
    3.38 +\item x86/32 with PAE, x86/64, and IA64 platform support.
    3.39  \item Intel and AMD Virtualization Technology for unmodified guest operating systems (including Microsoft Windows).
    3.40  \item Excellent hardware support (supports almost all Linux device
    3.41    drivers). 
    3.42 @@ -182,22 +177,20 @@ unmodified guests running natively on th
    3.43  
    3.44  Paravirtualized Xen support is available for increasingly many
    3.45  operating systems: currently, mature Linux support is available and
    3.46 -included in the standard distribution.  Other OS ports---including
    3.47 -NetBSD, FreeBSD and Solaris x86 v10---are nearing completion. 
    3.48 +included in the standard distribution.  Other OS ports, including
    3.49 +NetBSD, FreeBSD and Solaris are also complete. 
    3.50  
    3.51  
    3.52  \section{Hardware Support}
    3.53  
    3.54 -Xen currently runs on the x86 architecture, requiring a ``P6'' or
    3.55 -newer processor (e.g.\ Pentium Pro, Celeron, Pentium~II, Pentium~III,
    3.56 -Pentium~IV, Xeon, AMD~Athlon, AMD~Duron). Multiprocessor machines are
    3.57 -supported, and there is support for HyperThreading (SMT).  In 
    3.58 -addition, ports to IA64 and Power architectures are supported.
    3.59 -
    3.60 -The default 32-bit Xen supports for Intel's Physical Addressing Extensions (PAE), which enable x86/32 machines to address up to 64 GB of physical memory.
    3.61 -It also supports non-PAE 32-bit Xen up to 4GB of memory. 
    3.62 -Xen also supports x86/64 platforms such as Intel EM64T and AMD Opteron
    3.63 -which can currently address up to 1TB of physical memory.
    3.64 +Xen currently runs on the IA64 and x86 architectures. Multiprocessor
    3.65 +machines are supported, and there is support for HyperThreading (SMT).
    3.66 +
    3.67 +The default 32-bit Xen requires processor support for Physical
    3.68 +Addressing Extensions (PAE), which enables the hypervisor to address
    3.69 +up to 16GB of physical memory. Xen also supports x86/64 platforms
    3.70 +such as Intel EM64T and AMD Opteron which can currently address up to
    3.71 +1TB of physical memory.
    3.72  
    3.73  Xen offloads most of the hardware support issues to the guest OS
    3.74  running in the \emph{Domain~0} management virtual machine. Xen itself
    3.75 @@ -253,8 +246,8 @@ with pointers to papers and technical re
    3.76  Xen has grown into a fully-fledged project in its own right, enabling us
    3.77  to investigate interesting research issues regarding the best techniques
    3.78  for virtualizing resources such as the CPU, memory, disk and network.
    3.79 -Project contributors now include XenSource, Intel, IBM, HP, AMD, Novell,
    3.80 -RedHat.
    3.81 +Project contributors now include Citrix, Intel, IBM, HP, AMD, Novell,
    3.82 +RedHat, Sun, Fujitsu, and Samsung.
    3.83  
    3.84  Xen was first described in a paper presented at SOSP in
    3.85  2003\footnote{\tt
    3.86 @@ -265,25 +258,20 @@ sites.
    3.87  
    3.88  \section{What's New}
    3.89  
    3.90 -Xen 3.0.0 offers:
    3.91 +Xen 3.3.0 offers:
    3.92  
    3.93  \begin{itemize}
    3.94 -\item Support for up to 32-way SMP guest operating systems
    3.95 -\item Intel (Physical Addressing Extensions) PAE to support 32-bit
    3.96 -  servers with more than 4GB physical memory
    3.97 -\item x86/64 support (Intel EM64T, AMD Opteron)
    3.98 -\item Intel VT-x support to enable the running of unmodified guest
    3.99 -operating systems (Windows XP/2003, Legacy Linux)
   3.100 -\item Enhanced control tools
   3.101 -\item Improved ACPI support
   3.102 -\item AGP/DRM graphics
   3.103 +\item IO Emulation (stub domains) for HVM IO performance and scailability
   3.104 +\item Replacement of Intel VT vmxassist by new 16b emulation code
   3.105 +\item Improved VT-d device pass-through e.g. for graphics devices
   3.106 +\item Enhanced C and P state power management
   3.107 +\item Exploitation of multi-queue support on modern NICs
   3.108 +\item Removal of domain lock for improved PV guest scalability
   3.109 +\item 2MB page support for HVM and PV guests
   3.110 +\item CPU Portability
   3.111  \end{itemize}
   3.112  
   3.113 -
   3.114 -Xen 3.0 features greatly enhanced hardware support, configuration
   3.115 -flexibility, usability and a larger complement of supported operating
   3.116 -systems.  This latest release takes Xen a step closer to being the 
   3.117 -definitive open source solution for virtualization.
   3.118 +Xen 3.3 delivers the capabilities needed by enterprise customers and gives computing industry leaders a solid, secure platform to build upon for their virtualization solutions. This latest release establishes Xen as the definitive open source solution for virtualization.
   3.119  
   3.120  
   3.121  
   3.122 @@ -295,7 +283,7 @@ definitive open source solution for virt
   3.123  The Xen distribution includes three main components: Xen itself, ports
   3.124  of Linux and NetBSD to run on Xen, and the userspace tools required to
   3.125  manage a Xen-based system. This chapter describes how to install the
   3.126 -Xen~3.0 distribution from source. Alternatively, there may be pre-built
   3.127 +Xen~3.3 distribution from source. Alternatively, there may be pre-built
   3.128  packages available as part of your operating system distribution.
   3.129  
   3.130  
   3.131 @@ -4029,9 +4017,8 @@ files: \path{Config.mk} and \path{Makefi
   3.132  
   3.133  The former allows the overall build target architecture to be 
   3.134  specified. You will typically not need to modify this unless 
   3.135 -you are cross-compiling or if you wish to build a non-PAE  
   3.136 -Xen system. Additional configuration options are documented 
   3.137 -in the \path{Config.mk} file. 
   3.138 +you are cross-compiling. Additional configuration options are
   3.139 +documented in the \path{Config.mk} file. 
   3.140  
   3.141  The top-level \path{Makefile} is chiefly used to customize the set of
   3.142  kernels built. Look for the line: 
     4.1 --- a/docs/xen-api/xenapi-datamodel-graph.dot	Mon Aug 25 19:04:37 2008 +0900
     4.2 +++ b/docs/xen-api/xenapi-datamodel-graph.dot	Mon Sep 01 16:59:43 2008 +0900
     4.3 @@ -14,7 +14,7 @@ fontname="Verdana";
     4.4  
     4.5  node [ shape=box ]; session VM host network VIF PIF SR VDI VBD PBD user XSPolicy ACMPolicy;
     4.6  node [shape=ellipse]; PIF_metrics VIF_metrics VM_metrics VBD_metrics PBD_metrics VM_guest_metrics host_metrics;
     4.7 -node [shape=box]; DPCI PPCI host_cpu console
     4.8 +node [shape=box]; DPCI PPCI host_cpu console VTPM
     4.9  session -> host [ arrowhead="none" ]
    4.10  session -> user [ arrowhead="none" ]
    4.11  VM -> VM_metrics [ arrowhead="none" ]
     5.1 --- a/extras/mini-os/include/posix/dirent.h	Mon Aug 25 19:04:37 2008 +0900
     5.2 +++ b/extras/mini-os/include/posix/dirent.h	Mon Sep 01 16:59:43 2008 +0900
     5.3 @@ -1,7 +1,7 @@
     5.4  #ifndef _POSIX_DIRENT_H
     5.5  #define _POSIX_DIRENT_H
     5.6  
     5.7 -#include <sys/types.h>
     5.8 +#include <stdint.h>
     5.9  
    5.10  struct dirent {
    5.11          char *d_name;
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/extras/mini-os/include/posix/err.h	Mon Sep 01 16:59:43 2008 +0900
     6.3 @@ -0,0 +1,15 @@
     6.4 +#ifndef _POSIX_ERR_H
     6.5 +#define _POSIX_ERR_H
     6.6 +
     6.7 +#include <stdarg.h>
     6.8 +
     6.9 +void err(int eval, const char *fmt, ...);
    6.10 +void errx(int eval, const char *fmt, ...);
    6.11 +void warn(const char *fmt, ...);
    6.12 +void warnx(const char *fmt, ...);
    6.13 +void verr(int eval, const char *fmt, va_list args);
    6.14 +void verrx(int eval, const char *fmt, va_list args);
    6.15 +void vwarn(const char *fmt, va_list args);
    6.16 +void vwarnx(const char *fmt, va_list args);
    6.17 +
    6.18 +#endif /* _POSIX_ERR_H */
     7.1 --- a/extras/mini-os/include/posix/pthread.h	Mon Aug 25 19:04:37 2008 +0900
     7.2 +++ b/extras/mini-os/include/posix/pthread.h	Mon Sep 01 16:59:43 2008 +0900
     7.3 @@ -31,8 +31,15 @@ static inline int pthread_key_delete(pth
     7.4  
     7.5  
     7.6  
     7.7 +typedef struct {} pthread_mutexattr_t;
     7.8 +static inline int pthread_mutexattr_init(pthread_mutexattr_t *mattr) { return 0; }
     7.9 +#define PTHREAD_MUTEX_NORMAL 0
    7.10 +#define PTHREAD_MUTEX_RECURSIVE 1
    7.11 +static inline int pthread_mutexattr_settype(pthread_mutexattr_t *mattr, int kind) { return 0; }
    7.12 +static inline int pthread_mutexattr_destroy(pthread_mutexattr_t *mattr) { return 0; }
    7.13  typedef struct {} pthread_mutex_t;
    7.14  #define PTHREAD_MUTEX_INITIALIZER {}
    7.15 +static inline int pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *mattr) { return 0; }
    7.16  static inline int pthread_mutex_lock(pthread_mutex_t *mutex) { return 0; }
    7.17  static inline int pthread_mutex_unlock(pthread_mutex_t *mutex) { return 0; }
    7.18  
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/extras/mini-os/include/posix/syslog.h	Mon Sep 01 16:59:43 2008 +0900
     8.3 @@ -0,0 +1,37 @@
     8.4 +#ifndef _POSIX_SYSLOG_H
     8.5 +#define _POSIX_SYSLOG_H
     8.6 +
     8.7 +#include <stdarg.h>
     8.8 +
     8.9 +#define LOG_PID 0
    8.10 +#define LOG_CONS 0
    8.11 +#define LOG_NDELAY 0
    8.12 +#define LOG_ODELAY 0
    8.13 +#define LOG_NOWAIT 0
    8.14 +
    8.15 +#define LOG_KERN 0
    8.16 +#define LOG_USER 0
    8.17 +#define LOG_MAIL 0
    8.18 +#define LOG_NEWS 0
    8.19 +#define LOG_UUCP 0
    8.20 +#define LOG_DAEMON 0
    8.21 +#define LOG_AUTH 0
    8.22 +#define LOG_CRON 0
    8.23 +#define LOG_LPR 0
    8.24 +
    8.25 +/* TODO: support */
    8.26 +#define LOG_EMERG 0
    8.27 +#define LOG_ALERT 1
    8.28 +#define LOG_CRIT 2
    8.29 +#define LOG_ERR 3
    8.30 +#define LOG_WARNING 4
    8.31 +#define LOG_NOTICE 5
    8.32 +#define LOG_INFO 6
    8.33 +#define LOG_DEBUG 7
    8.34 +
    8.35 +void openlog(const char *ident, int option, int facility);
    8.36 +void syslog(int priority, const char *format, ...);
    8.37 +void closelog(void);
    8.38 +void vsyslog(int priority, const char *format, va_list ap);
    8.39 +
    8.40 +#endif /* _POSIX_SYSLOG_H */
     9.1 --- a/extras/mini-os/include/xenbus.h	Mon Aug 25 19:04:37 2008 +0900
     9.2 +++ b/extras/mini-os/include/xenbus.h	Mon Sep 01 16:59:43 2008 +0900
     9.3 @@ -83,12 +83,13 @@ char *xenbus_transaction_end(xenbus_tran
     9.4  			     int *retry);
     9.5  
     9.6  /* Read path and parse it as an integer.  Returns -1 on error. */
     9.7 -int xenbus_read_integer(char *path);
     9.8 +int xenbus_read_integer(const char *path);
     9.9  
    9.10  /* Contraction of snprintf and xenbus_write(path/node). */
    9.11  char* xenbus_printf(xenbus_transaction_t xbt,
    9.12 -                                  char* node, char* path,
    9.13 -                                  char* fmt, ...);
    9.14 +                                  const char* node, const char* path,
    9.15 +                                  const char* fmt, ...)
    9.16 +                   __attribute__((__format__(printf, 4, 5)));
    9.17  
    9.18  /* Reset the XenBus system. */
    9.19  void fini_xenbus(void);
    10.1 --- a/extras/mini-os/lib/sys.c	Mon Aug 25 19:04:37 2008 +0900
    10.2 +++ b/extras/mini-os/lib/sys.c	Mon Sep 01 16:59:43 2008 +0900
    10.3 @@ -1007,6 +1007,96 @@ LWIP_STUB(ssize_t, sendto, (int s, void 
    10.4  LWIP_STUB(int, getsockname, (int s, struct sockaddr *name, socklen_t *namelen), (s, name, namelen))
    10.5  #endif
    10.6  
    10.7 +static char *syslog_ident;
    10.8 +void openlog(const char *ident, int option, int facility)
    10.9 +{
   10.10 +    if (syslog_ident)
   10.11 +        free(syslog_ident);
   10.12 +    syslog_ident = strdup(ident);
   10.13 +}
   10.14 +
   10.15 +void vsyslog(int priority, const char *format, va_list ap)
   10.16 +{
   10.17 +    printk("%s: ", syslog_ident);
   10.18 +    print(0, format, ap);
   10.19 +}
   10.20 +
   10.21 +void syslog(int priority, const char *format, ...)
   10.22 +{
   10.23 +    va_list ap;
   10.24 +    va_start(ap, format);
   10.25 +    vsyslog(priority, format, ap);
   10.26 +    va_end(ap);
   10.27 +}
   10.28 +
   10.29 +void closelog(void)
   10.30 +{
   10.31 +    free(syslog_ident);
   10.32 +    syslog_ident = NULL;
   10.33 +}
   10.34 +
   10.35 +void vwarn(const char *format, va_list ap)
   10.36 +{
   10.37 +    int the_errno = errno;
   10.38 +    printk("stubdom: ");
   10.39 +    if (format) {
   10.40 +        print(0, format, ap);
   10.41 +        printk(", ");
   10.42 +    }
   10.43 +    printk("%s", strerror(the_errno));
   10.44 +}
   10.45 +
   10.46 +void warn(const char *format, ...)
   10.47 +{
   10.48 +    va_list ap;
   10.49 +    va_start(ap, format);
   10.50 +    vwarn(format, ap);
   10.51 +    va_end(ap);
   10.52 +}
   10.53 +
   10.54 +void verr(int eval, const char *format, va_list ap)
   10.55 +{
   10.56 +    vwarn(format, ap);
   10.57 +    exit(eval);
   10.58 +}
   10.59 +
   10.60 +void err(int eval, const char *format, ...)
   10.61 +{
   10.62 +    va_list ap;
   10.63 +    va_start(ap, format);
   10.64 +    verr(eval, format, ap);
   10.65 +    va_end(ap);
   10.66 +}
   10.67 +
   10.68 +void vwarnx(const char *format, va_list ap)
   10.69 +{
   10.70 +    printk("stubdom: ");
   10.71 +    if (format)
   10.72 +        print(0, format, ap);
   10.73 +}
   10.74 +
   10.75 +void warnx(const char *format, ...)
   10.76 +{
   10.77 +    va_list ap;
   10.78 +    va_start(ap, format);
   10.79 +    vwarnx(format, ap);
   10.80 +    va_end(ap);
   10.81 +}
   10.82 +
   10.83 +void verrx(int eval, const char *format, va_list ap)
   10.84 +{
   10.85 +    vwarnx(format, ap);
   10.86 +    exit(eval);
   10.87 +}
   10.88 +
   10.89 +void errx(int eval, const char *format, ...)
   10.90 +{
   10.91 +    va_list ap;
   10.92 +    va_start(ap, format);
   10.93 +    verrx(eval, format, ap);
   10.94 +    va_end(ap);
   10.95 +}
   10.96 +
   10.97  int nanosleep(const struct timespec *req, struct timespec *rem)
   10.98  {
   10.99      s_time_t start = NOW();
  10.100 @@ -1115,34 +1205,47 @@ void *mmap(void *start, size_t length, i
  10.101      } else ASSERT(0);
  10.102  }
  10.103  
  10.104 +#define UNMAP_BATCH ((STACK_SIZE / 2) / sizeof(multicall_entry_t))
  10.105  int munmap(void *start, size_t length)
  10.106  {
  10.107 -    int i, n = length / PAGE_SIZE;
  10.108 -    multicall_entry_t call[n];
  10.109 -    unsigned char (*data)[PAGE_SIZE] = start;
  10.110 -    int ret;
  10.111 +    int total = length / PAGE_SIZE;
  10.112      ASSERT(!((unsigned long)start & ~PAGE_MASK));
  10.113 -    ASSERT(!(length & ~PAGE_MASK));
  10.114 +    while (total) {
  10.115 +        int n = UNMAP_BATCH;
  10.116 +        if (n > total)
  10.117 +            n = total;
  10.118 +        {
  10.119 +            int i;
  10.120 +            multicall_entry_t call[n];
  10.121 +            unsigned char (*data)[PAGE_SIZE] = start;
  10.122 +            int ret;
  10.123  
  10.124 -    for (i = 0; i < n; i++) {
  10.125 -	call[i].op = __HYPERVISOR_update_va_mapping;
  10.126 -	call[i].args[0] = (unsigned long) &data[i];
  10.127 -	call[i].args[1] = 0;
  10.128 -	call[i].args[2] = 0;
  10.129 -	call[i].args[3] = UVMF_INVLPG;
  10.130 -    }
  10.131 +            for (i = 0; i < n; i++) {
  10.132 +                int arg = 0;
  10.133 +                call[i].op = __HYPERVISOR_update_va_mapping;
  10.134 +                call[i].args[arg++] = (unsigned long) &data[i];
  10.135 +                call[i].args[arg++] = 0;
  10.136 +#ifdef __i386__
  10.137 +                call[i].args[arg++] = 0;
  10.138 +#endif
  10.139 +                call[i].args[arg++] = UVMF_INVLPG;
  10.140 +            }
  10.141  
  10.142 -    ret = HYPERVISOR_multicall(call, n);
  10.143 -    if (ret) {
  10.144 -	errno = -ret;
  10.145 -	return -1;
  10.146 -    }
  10.147 +            ret = HYPERVISOR_multicall(call, n);
  10.148 +            if (ret) {
  10.149 +                errno = -ret;
  10.150 +                return -1;
  10.151 +            }
  10.152  
  10.153 -    for (i = 0; i < n; i++) {
  10.154 -	if (call[i].result) {
  10.155 -	    errno = call[i].result;
  10.156 -	    return -1;
  10.157 -	}
  10.158 +            for (i = 0; i < n; i++) {
  10.159 +                if (call[i].result) {
  10.160 +                    errno = call[i].result;
  10.161 +                    return -1;
  10.162 +                }
  10.163 +            }
  10.164 +        }
  10.165 +        start = (char *)start + n * PAGE_SIZE;
  10.166 +        total -= n;
  10.167      }
  10.168      return 0;
  10.169  }
    11.1 --- a/extras/mini-os/main.c	Mon Aug 25 19:04:37 2008 +0900
    11.2 +++ b/extras/mini-os/main.c	Mon Sep 01 16:59:43 2008 +0900
    11.3 @@ -42,7 +42,7 @@ void _fini(void)
    11.4  extern char __app_bss_start, __app_bss_end;
    11.5  static void call_main(void *p)
    11.6  {
    11.7 -    char *c;
    11.8 +    char *c, quote;
    11.9  #ifdef CONFIG_QEMU
   11.10      char *domargs, *msg;
   11.11  #endif
   11.12 @@ -101,32 +101,53 @@ static void call_main(void *p)
   11.13  
   11.14      argc = 1;
   11.15  
   11.16 -#define PARSE_ARGS(ARGS,START,END) \
   11.17 +#define PARSE_ARGS(ARGS,START,QUOTE,END) \
   11.18      c = ARGS; \
   11.19 +    quote = 0; \
   11.20      while (*c) { \
   11.21  	if (*c != ' ') { \
   11.22  	    START; \
   11.23 -	    while (*c && *c != ' ') \
   11.24 +	    while (*c) { \
   11.25 +		if (quote) { \
   11.26 +		    if (*c == quote) { \
   11.27 +			quote = 0; \
   11.28 +			QUOTE; \
   11.29 +			continue; \
   11.30 +		    } \
   11.31 +		} else if (*c == ' ') \
   11.32 +		    break; \
   11.33 +		if (*c == '"' || *c == '\'') { \
   11.34 +		    quote = *c; \
   11.35 +		    QUOTE; \
   11.36 +		    continue; \
   11.37 +		} \
   11.38  		c++; \
   11.39 +	    } \
   11.40  	} else { \
   11.41              END; \
   11.42  	    while (*c == ' ') \
   11.43  		c++; \
   11.44  	} \
   11.45 +    } \
   11.46 +    if (quote) {\
   11.47 +	printk("Warning: unterminated quotation %c\n", quote); \
   11.48 +	quote = 0; \
   11.49      }
   11.50 +#define PARSE_ARGS_COUNT(ARGS) PARSE_ARGS(ARGS, argc++, c++, )
   11.51 +#define PARSE_ARGS_STORE(ARGS) PARSE_ARGS(ARGS, argv[argc++] = c, memmove(c, c + 1, strlen(c + 1) + 1), *c++ = 0)
   11.52  
   11.53 -    PARSE_ARGS((char*)start_info.cmd_line, argc++, );
   11.54 +    PARSE_ARGS_COUNT((char*)start_info.cmd_line);
   11.55  #ifdef CONFIG_QEMU
   11.56 -    PARSE_ARGS(domargs, argc++, );
   11.57 +    PARSE_ARGS_COUNT(domargs);
   11.58  #endif
   11.59  
   11.60      argv = alloca((argc + 1) * sizeof(char *));
   11.61      argv[0] = "main";
   11.62      argc = 1;
   11.63  
   11.64 -    PARSE_ARGS((char*)start_info.cmd_line, argv[argc++] = c, *c++ = 0)
   11.65 +    PARSE_ARGS_STORE((char*)start_info.cmd_line)
   11.66  #ifdef CONFIG_QEMU
   11.67 -    PARSE_ARGS(domargs, argv[argc++] = c, *c++ = 0)
   11.68 +    PARSE_ARGS_STORE(domargs)
   11.69  #endif
   11.70  
   11.71      argv[argc] = NULL;
    12.1 --- a/extras/mini-os/xenbus/xenbus.c	Mon Aug 25 19:04:37 2008 +0900
    12.2 +++ b/extras/mini-os/xenbus/xenbus.c	Mon Sep 01 16:59:43 2008 +0900
    12.3 @@ -633,7 +633,7 @@ xenbus_transaction_end(xenbus_transactio
    12.4      return NULL;
    12.5  }
    12.6  
    12.7 -int xenbus_read_integer(char *path)
    12.8 +int xenbus_read_integer(const char *path)
    12.9  {
   12.10      char *res, *buf;
   12.11      int t;
   12.12 @@ -650,8 +650,8 @@ int xenbus_read_integer(char *path)
   12.13  }
   12.14  
   12.15  char* xenbus_printf(xenbus_transaction_t xbt,
   12.16 -                                  char* node, char* path,
   12.17 -                                  char* fmt, ...)
   12.18 +                                  const char* node, const char* path,
   12.19 +                                  const char* fmt, ...)
   12.20  {
   12.21  #define BUFFER_SIZE 256
   12.22      char fullpath[BUFFER_SIZE];
    13.1 --- a/stubdom/Makefile	Mon Aug 25 19:04:37 2008 +0900
    13.2 +++ b/stubdom/Makefile	Mon Sep 01 16:59:43 2008 +0900
    13.3 @@ -9,7 +9,7 @@ include $(XEN_ROOT)/Config.mk
    13.4  
    13.5  override CONFIG_QEMU=ioemu
    13.6  
    13.7 -IOEMU_OPTIONS=--disable-sdl --disable-opengl --disable-gfx-check --disable-vnc-tls --disable-brlapi --disable-kqemu
    13.8 +IOEMU_OPTIONS=--disable-sdl --disable-opengl --disable-vnc-tls --disable-brlapi --disable-kqemu
    13.9  ZLIB_URL?=http://www.zlib.net
   13.10  ZLIB_VERSION=1.2.3
   13.11  LIBPCI_URL?=http://www.kernel.org/pub/software/utils/pciutils
   13.12 @@ -53,7 +53,7 @@ TARGET_CFLAGS += $(call cc-option,$(CC),
   13.13  TARGET_CFLAGS += $(call cc-option,$(CC),-fno-stack-protector-all,)
   13.14  
   13.15  # Do not use host headers and libs
   13.16 -GCC_INSTALL = $(shell gcc -print-search-dirs | sed -n -e 's/install: \(.*\)/\1/p')
   13.17 +GCC_INSTALL = $(shell LANG=C gcc -print-search-dirs | sed -n -e 's/install: \(.*\)/\1/p')
   13.18  TARGET_CPPFLAGS += -U __linux__ -U __FreeBSD__ -U __sun__
   13.19  TARGET_CPPFLAGS += -nostdinc
   13.20  TARGET_CPPFLAGS += -isystem $(CURDIR)/$(MINI_OS)/include/posix
    14.1 --- a/tools/Makefile	Mon Aug 25 19:04:37 2008 +0900
    14.2 +++ b/tools/Makefile	Mon Sep 01 16:59:43 2008 +0900
    14.3 @@ -59,8 +59,7 @@ clean distclean: subdirs-clean
    14.4  ifneq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH))
    14.5  IOEMU_CONFIGURE_CROSS ?= --cpu=$(XEN_TARGET_ARCH) \
    14.6  			 --cross-prefix=$(CROSS_COMPILE) \
    14.7 -			 --interp-prefix=$(CROSS_SYS_ROOT) \
    14.8 -			 --install=$(CURDIR)/cross-install
    14.9 +			 --interp-prefix=$(CROSS_SYS_ROOT)
   14.10  endif
   14.11  
   14.12  ioemu/config-host.mak:
    15.1 --- a/tools/Rules.mk	Mon Aug 25 19:04:37 2008 +0900
    15.2 +++ b/tools/Rules.mk	Mon Sep 01 16:59:43 2008 +0900
    15.3 @@ -5,6 +5,9 @@ all:
    15.4  
    15.5  include $(XEN_ROOT)/Config.mk
    15.6  
    15.7 +export _INSTALL := $(INSTALL)
    15.8 +INSTALL = $(XEN_ROOT)/tools/cross-install
    15.9 +
   15.10  XEN_INCLUDE        = $(XEN_ROOT)/tools/include
   15.11  XEN_XC             = $(XEN_ROOT)/tools/python/xen/lowlevel/xc
   15.12  XEN_LIBXC          = $(XEN_ROOT)/tools/libxc
    16.1 --- a/tools/cross-install	Mon Aug 25 19:04:37 2008 +0900
    16.2 +++ b/tools/cross-install	Mon Sep 01 16:59:43 2008 +0900
    16.3 @@ -5,4 +5,4 @@ if [ -n "$CROSS_BIN_PATH" ]; then
    16.4      PATH="$CROSS_BIN_PATH:$PATH"
    16.5  fi
    16.6  
    16.7 -exec install "$@"
    16.8 +exec $_INSTALL "$@"
    17.1 --- a/tools/examples/xmexample.pv-grub	Mon Aug 25 19:04:37 2008 +0900
    17.2 +++ b/tools/examples/xmexample.pv-grub	Mon Sep 01 16:59:43 2008 +0900
    17.3 @@ -25,7 +25,7 @@ extra = "(hd0,0)/boot/grub/menu.lst"
    17.4  # WARNING: Creating a domain with insufficient memory may cause out of
    17.5  #          memory errors. The domain needs enough memory to boot kernel
    17.6  #          and modules. Allocating less than 32MBs is not recommended.
    17.7 -memory = 64
    17.8 +memory = 128
    17.9  
   17.10  # A name for your domain. All domains must have different names.
   17.11  name = "ExampleDomain"
   17.12 @@ -119,32 +119,6 @@ disk = [ 'phy:hda1,hda1,w' ]
   17.13  #vtpm = [ 'instance=1,backend=0' ]
   17.14  
   17.15  #----------------------------------------------------------------------------
   17.16 -# Set the kernel command line for the new domain.
   17.17 -# You only need to define the IP parameters and hostname if the domain's
   17.18 -# IP config doesn't, e.g. in ifcfg-eth0 or via DHCP.
   17.19 -# You can use 'extra' to set the runlevel and custom environment
   17.20 -# variables used by custom rc scripts (e.g. VMID=, usr= ).
   17.21 -
   17.22 -# Set if you want dhcp to allocate the IP address.
   17.23 -#dhcp="dhcp"
   17.24 -# Set netmask.
   17.25 -#netmask=
   17.26 -# Set default gateway.
   17.27 -#gateway=
   17.28 -# Set the hostname.
   17.29 -#hostname= "vm%d" % vmid
   17.30 -
   17.31 -# Set root device.
   17.32 -root = "/dev/hda1 ro"
   17.33 -
   17.34 -# Root device for nfs.
   17.35 -#root = "/dev/nfs"
   17.36 -# The nfs server.
   17.37 -#nfs_server = '192.0.2.1'  
   17.38 -# Root directory on the nfs server.
   17.39 -#nfs_root   = '/full/path/to/root/directory'
   17.40 -
   17.41 -#----------------------------------------------------------------------------
   17.42  # Configure the behaviour when a domain exits.  There are three 'reasons'
   17.43  # for a domain to stop: poweroff, reboot, and crash.  For each of these you
   17.44  # may specify:
    18.1 --- a/tools/firmware/hvmloader/32bitbios_support.c	Mon Aug 25 19:04:37 2008 +0900
    18.2 +++ b/tools/firmware/hvmloader/32bitbios_support.c	Mon Sep 01 16:59:43 2008 +0900
    18.3 @@ -76,7 +76,7 @@ static void relocate_32bitbios(char *elf
    18.4       */
    18.5      reloc_size = reloc_off;
    18.6      printf("%d bytes of ROMBIOS high-memory extensions:\n", reloc_size);
    18.7 -    highbiosarea = (char *)(long)e820_malloc(reloc_size);
    18.8 +    highbiosarea = (char *)(long)e820_malloc(reloc_size, 0);
    18.9      BUG_ON(highbiosarea == NULL);
   18.10      printf("  Relocating to 0x%x-0x%x ... ",
   18.11             (uint32_t)&highbiosarea[0],
    19.1 --- a/tools/firmware/hvmloader/acpi/Makefile	Mon Aug 25 19:04:37 2008 +0900
    19.2 +++ b/tools/firmware/hvmloader/acpi/Makefile	Mon Sep 01 16:59:43 2008 +0900
    19.3 @@ -22,8 +22,8 @@ C_SRC = build.c dsdt.c static_tables.c
    19.4  H_SRC = $(wildcard *.h)
    19.5  OBJS  = $(patsubst %.c,%.o,$(C_SRC))
    19.6  
    19.7 -IASL_VER = acpica-unix-20060707
    19.8 -IASL_URL = http://developer.intel.com/technology/iapc/acpi/downloads/$(IASL_VER).tar.gz
    19.9 +IASL_VER = acpica-unix-20080729
   19.10 +IASL_URL = http://acpica.org/download/$(IASL_VER).tar.gz
   19.11  
   19.12  CFLAGS += -I. -I.. $(CFLAGS_include)
   19.13  
   19.14 @@ -48,7 +48,7 @@ iasl:
   19.15  	@echo "ACPI ASL compiler(iasl) is needed"
   19.16  	@echo "Download Intel ACPI CA"
   19.17  	@echo "If wget failed, please download and compile manually from"
   19.18 -	@echo "http://developer.intel.com/technology/iapc/acpi/downloads.htm"
   19.19 +	@echo "http://acpica.org/downloads/"
   19.20  	@echo 
   19.21  	wget $(IASL_URL)
   19.22  	tar xzf $(IASL_VER).tar.gz
    20.1 --- a/tools/firmware/hvmloader/acpi/build.c	Mon Aug 25 19:04:37 2008 +0900
    20.2 +++ b/tools/firmware/hvmloader/acpi/build.c	Mon Sep 01 16:59:43 2008 +0900
    20.3 @@ -233,7 +233,7 @@ static int construct_secondary_tables(ui
    20.4          tcpa->header.oem_revision = ACPI_OEM_REVISION;
    20.5          tcpa->header.creator_id   = ACPI_CREATOR_ID;
    20.6          tcpa->header.creator_revision = ACPI_CREATOR_REVISION;
    20.7 -        tcpa->lasa = e820_malloc(ACPI_2_0_TCPA_LAML_SIZE);
    20.8 +        tcpa->lasa = e820_malloc(ACPI_2_0_TCPA_LAML_SIZE, 0);
    20.9          if ( tcpa->lasa )
   20.10          {
   20.11              tcpa->laml = ACPI_2_0_TCPA_LAML_SIZE;
   20.12 @@ -363,7 +363,7 @@ void acpi_build_tables(void)
   20.13      memset(buf, 0, high_sz);
   20.14  
   20.15      /* Allocate data area and set up ACPI tables there. */
   20.16 -    buf = (uint8_t *)e820_malloc(high_sz);
   20.17 +    buf = (uint8_t *)e820_malloc(high_sz, 0);
   20.18      __acpi_build_tables(buf, &low_sz, &high_sz);
   20.19  
   20.20      printf(" - Lo data: %08lx-%08lx\n"
    21.1 --- a/tools/firmware/hvmloader/hvmloader.c	Mon Aug 25 19:04:37 2008 +0900
    21.2 +++ b/tools/firmware/hvmloader/hvmloader.c	Mon Sep 01 16:59:43 2008 +0900
    21.3 @@ -243,6 +243,13 @@ static void pci_setup(void)
    21.4              bars[i].bar_sz  = bar_sz;
    21.5  
    21.6              nr_bars++;
    21.7 +
    21.8 +            /* Skip the upper-half of the address for a 64-bit BAR. */
    21.9 +            if ( (bar_data & (PCI_BASE_ADDRESS_SPACE |
   21.10 +                              PCI_BASE_ADDRESS_MEM_TYPE_MASK)) == 
   21.11 +                 (PCI_BASE_ADDRESS_SPACE_MEMORY | 
   21.12 +                  PCI_BASE_ADDRESS_MEM_TYPE_64) )
   21.13 +                bar++;
   21.14          }
   21.15  
   21.16          /* Map the interrupt. */
   21.17 @@ -430,12 +437,14 @@ static void cmos_write_memory_size(void)
   21.18      cmos_outb(0x35, (uint8_t)( alt_mem >> 8));
   21.19  }
   21.20  
   21.21 -static void init_xen_platform_io_base(void)
   21.22 +static uint16_t init_xen_platform_io_base(void)
   21.23  {
   21.24      struct bios_info *bios_info = (struct bios_info *)ACPI_PHYSICAL_ADDRESS;
   21.25      uint32_t devfn, bar_data;
   21.26      uint16_t vendor_id, device_id;
   21.27  
   21.28 +    bios_info->xen_pfiob = 0;
   21.29 +
   21.30      for ( devfn = 0; devfn < 128; devfn++ )
   21.31      {
   21.32          vendor_id = pci_readw(devfn, PCI_VENDOR_ID);
   21.33 @@ -445,12 +454,16 @@ static void init_xen_platform_io_base(vo
   21.34          bar_data = pci_readl(devfn, PCI_BASE_ADDRESS_0);
   21.35          bios_info->xen_pfiob = bar_data & PCI_BASE_ADDRESS_IO_MASK;
   21.36      }
   21.37 +
   21.38 +    return bios_info->xen_pfiob;
   21.39  }
   21.40  
   21.41  int main(void)
   21.42  {
   21.43      int vgabios_sz = 0, etherboot_sz = 0, rombios_sz, smbios_sz;
   21.44      int extboot_sz = 0;
   21.45 +    uint32_t vga_ram = 0;
   21.46 +    uint16_t xen_pfiob;
   21.47  
   21.48      printf("HVM Loader\n");
   21.49  
   21.50 @@ -497,6 +510,12 @@ int main(void)
   21.51          break;
   21.52      }
   21.53  
   21.54 +    if ( virtual_vga != VGA_none )
   21.55 +    {
   21.56 +        vga_ram = e820_malloc(8 << 20, 4096);
   21.57 +        printf("VGA RAM at %08x\n", vga_ram);
   21.58 +    }
   21.59 +
   21.60      etherboot_sz = scan_etherboot_nic((void*)ETHERBOOT_PHYSICAL_ADDRESS);
   21.61  
   21.62      if ( must_load_extboot() )
   21.63 @@ -537,7 +556,9 @@ int main(void)
   21.64                 ROMBIOS_PHYSICAL_ADDRESS,
   21.65                 ROMBIOS_PHYSICAL_ADDRESS + rombios_sz - 1);
   21.66  
   21.67 -    init_xen_platform_io_base();
   21.68 +    xen_pfiob = init_xen_platform_io_base();
   21.69 +    if ( xen_pfiob && vga_ram )
   21.70 +        outl(xen_pfiob + 4, vga_ram);
   21.71  
   21.72      printf("Invoking ROMBIOS ...\n");
   21.73      return 0;
    22.1 --- a/tools/firmware/hvmloader/util.c	Mon Aug 25 19:04:37 2008 +0900
    22.2 +++ b/tools/firmware/hvmloader/util.c	Mon Sep 01 16:59:43 2008 +0900
    22.3 @@ -325,35 +325,34 @@ static void e820_collapse(void)
    22.4      }
    22.5  }
    22.6  
    22.7 -uint32_t e820_malloc(uint32_t size)
    22.8 +uint32_t e820_malloc(uint32_t size, uint32_t align)
    22.9  {
   22.10      uint32_t addr;
   22.11      int i;
   22.12      struct e820entry *ent = (struct e820entry *)HVM_E820;
   22.13  
   22.14 -    /* Align allocation request to a reasonable boundary (1kB). */
   22.15 -    size = (size + 1023) & ~1023;
   22.16 +    /* Align to at leats one kilobyte. */
   22.17 +    if ( align < 1024 )
   22.18 +        align = 1024;
   22.19  
   22.20      for ( i = *HVM_E820_NR - 1; i >= 0; i-- )
   22.21      {
   22.22 -        addr = ent[i].addr;
   22.23 +        addr = (ent[i].addr + ent[i].size - size) & ~(align-1);
   22.24          if ( (ent[i].type != E820_RAM) || /* not ram? */
   22.25 -             (ent[i].size < size) ||      /* too small? */
   22.26 -             (addr != ent[i].addr) ||     /* starts above 4gb? */
   22.27 +             (addr < ent[i].addr) ||      /* too small or starts above 4gb? */
   22.28               ((addr + size) < addr) )     /* ends above 4gb? */
   22.29              continue;
   22.30  
   22.31 -        if ( ent[i].size != size )
   22.32 +        if ( addr != ent[i].addr )
   22.33          {
   22.34              memmove(&ent[i+1], &ent[i], (*HVM_E820_NR-i) * sizeof(*ent));
   22.35              (*HVM_E820_NR)++;
   22.36 -            ent[i].size -= size;
   22.37 -            addr += ent[i].size;
   22.38 +            ent[i].size = addr - ent[i].addr;
   22.39 +            ent[i+1].addr = addr;
   22.40 +            ent[i+1].size -= ent[i].size;
   22.41              i++;
   22.42          }
   22.43  
   22.44 -        ent[i].addr = addr;
   22.45 -        ent[i].size = size;
   22.46          ent[i].type = E820_RESERVED;
   22.47  
   22.48          e820_collapse();
    23.1 --- a/tools/firmware/hvmloader/util.h	Mon Aug 25 19:04:37 2008 +0900
    23.2 +++ b/tools/firmware/hvmloader/util.h	Mon Sep 01 16:59:43 2008 +0900
    23.3 @@ -132,7 +132,7 @@ int printf(const char *fmt, ...) __attri
    23.4  int vprintf(const char *fmt, va_list ap);
    23.5  
    23.6  /* Reserve a RAM region in the e820 table. */
    23.7 -uint32_t e820_malloc(uint32_t size);
    23.8 +uint32_t e820_malloc(uint32_t size, uint32_t align);
    23.9  
   23.10  /* Prepare the 32bit BIOS */
   23.11  void highbios_setup(void);
    24.1 --- a/tools/ioemu/hw/cirrus_vga.c	Mon Aug 25 19:04:37 2008 +0900
    24.2 +++ b/tools/ioemu/hw/cirrus_vga.c	Mon Sep 01 16:59:43 2008 +0900
    24.3 @@ -2543,34 +2543,28 @@ static CPUWriteMemoryFunc *cirrus_linear
    24.4      cirrus_linear_bitblt_writel,
    24.5  };
    24.6  
    24.7 -static void *set_vram_mapping(unsigned long begin, unsigned long end)
    24.8 +static void set_vram_mapping(CirrusVGAState *s, unsigned long begin, unsigned long end)
    24.9  {
   24.10 -    xen_pfn_t *extent_start = NULL;
   24.11 -    unsigned long nr_extents;
   24.12 -    void *vram_pointer = NULL;
   24.13 -    int i;
   24.14 -
   24.15 -    /* align begin and end address */
   24.16 -    begin = begin & TARGET_PAGE_MASK;
   24.17 -    end = begin + VGA_RAM_SIZE;
   24.18 -    end = (end + TARGET_PAGE_SIZE -1 ) & TARGET_PAGE_MASK;
   24.19 -    nr_extents = (end - begin) >> TARGET_PAGE_BITS;
   24.20 -
   24.21 -    extent_start = malloc(sizeof(xen_pfn_t) * nr_extents);
   24.22 -    if (extent_start == NULL) {
   24.23 -        fprintf(stderr, "Failed malloc on set_vram_mapping\n");
   24.24 -        return NULL;
   24.25 -    }
   24.26 -
   24.27 -    memset(extent_start, 0, sizeof(xen_pfn_t) * nr_extents);
   24.28 -
   24.29 -    for (i = 0; i < nr_extents; i++)
   24.30 -        extent_start[i] = (begin + i * TARGET_PAGE_SIZE) >> TARGET_PAGE_BITS;
   24.31 -
   24.32 -    if (set_mm_mapping(xc_handle, domid, nr_extents, 0, extent_start) < 0) {
   24.33 -        fprintf(logfile, "Failed set_mm_mapping\n");
   24.34 -        free(extent_start);
   24.35 -        return NULL;
   24.36 +    unsigned long i;
   24.37 +    struct xen_add_to_physmap xatp;
   24.38 +    int rc;
   24.39 +
   24.40 +    if (end > begin + VGA_RAM_SIZE)
   24.41 +        end = begin + VGA_RAM_SIZE;
   24.42 +
   24.43 +    fprintf(logfile,"mapping vram to %lx - %lx\n", begin, end);
   24.44 +
   24.45 +    xatp.domid = domid;
   24.46 +    xatp.space = XENMAPSPACE_mfn;
   24.47 +
   24.48 +    for (i = 0; i < (end - begin) >> TARGET_PAGE_BITS; i++) {
   24.49 +        xatp.idx = s->vram_mfns[i];
   24.50 +        xatp.gpfn = (begin >> TARGET_PAGE_BITS) + i;
   24.51 +        rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp);
   24.52 +        if (rc) {
   24.53 +            fprintf(stderr, "add_to_physmap MFN %"PRI_xen_pfn" to PFN %"PRI_xen_pfn" failed: %d\n", xatp.idx, xatp.gpfn, rc);
   24.54 +            return;
   24.55 +        }
   24.56      }
   24.57  
   24.58      (void)xc_domain_pin_memory_cacheattr(
   24.59 @@ -2578,61 +2572,42 @@ static void *set_vram_mapping(unsigned l
   24.60          begin >> TARGET_PAGE_BITS,
   24.61          end >> TARGET_PAGE_BITS,
   24.62          XEN_DOMCTL_MEM_CACHEATTR_WB);
   24.63 -
   24.64 -    vram_pointer = xc_map_foreign_pages(xc_handle, domid,
   24.65 -                                        PROT_READ|PROT_WRITE,
   24.66 -                                        extent_start, nr_extents);
   24.67 -    if (vram_pointer == NULL) {
   24.68 -        fprintf(logfile, "xc_map_foreign_batch vgaram returned error %d\n",
   24.69 -                errno);
   24.70 -        free(extent_start);
   24.71 -        return NULL;
   24.72 -    }
   24.73 -
   24.74 -    memset(vram_pointer, 0, nr_extents * TARGET_PAGE_SIZE);
   24.75 -
   24.76 -#ifdef CONFIG_STUBDOM
   24.77 -    xenfb_pv_display_start(vram_pointer);
   24.78 -#endif
   24.79 -
   24.80 -    free(extent_start);
   24.81 -
   24.82 -    return vram_pointer;
   24.83  }
   24.84  
   24.85 -static int unset_vram_mapping(unsigned long begin, unsigned long end, 
   24.86 -                              void *mapping)
   24.87 +static void unset_vram_mapping(CirrusVGAState *s, unsigned long begin, unsigned long end)
   24.88  {
   24.89 -    xen_pfn_t *extent_start = NULL;
   24.90 -    unsigned long nr_extents;
   24.91 -    int i;
   24.92 -
   24.93 -    /* align begin and end address */
   24.94 -
   24.95 -    end = begin + VGA_RAM_SIZE;
   24.96 -    begin = begin & TARGET_PAGE_MASK;
   24.97 -    end = (end + TARGET_PAGE_SIZE -1 ) & TARGET_PAGE_MASK;
   24.98 -    nr_extents = (end - begin) >> TARGET_PAGE_BITS;
   24.99 -
  24.100 -    extent_start = malloc(sizeof(xen_pfn_t) * nr_extents);
  24.101 -
  24.102 -    if (extent_start == NULL) {
  24.103 -        fprintf(stderr, "Failed malloc on set_mm_mapping\n");
  24.104 -        return -1;
  24.105 +    if (s->stolen_vram_addr) {
  24.106 +        /* We can put it there for xend to save it efficiently */
  24.107 +        set_vram_mapping(s, s->stolen_vram_addr, s->stolen_vram_addr + VGA_RAM_SIZE);
  24.108 +    } else {
  24.109 +        /* Old image, we have to unmap them completely */
  24.110 +        struct xen_remove_from_physmap xrfp;
  24.111 +        unsigned long i;
  24.112 +        int rc;
  24.113 +
  24.114 +        if (end > begin + VGA_RAM_SIZE)
  24.115 +            end = begin + VGA_RAM_SIZE;
  24.116 +
  24.117 +        fprintf(logfile,"unmapping vram from %lx - %lx\n", begin, end);
  24.118 +
  24.119 +        xrfp.domid = domid;
  24.120 +
  24.121 +        for (i = 0; i < (end - begin) >> TARGET_PAGE_BITS; i++) {
  24.122 +            xrfp.gpfn = (begin >> TARGET_PAGE_BITS) + i;
  24.123 +            rc = xc_memory_op(xc_handle, XENMEM_remove_from_physmap, &xrfp);
  24.124 +            if (rc) {
  24.125 +                fprintf(stderr, "remove_from_physmap PFN %"PRI_xen_pfn" failed: %d\n", xrfp.gpfn, rc);
  24.126 +                return;
  24.127 +            }
  24.128 +        }
  24.129      }
  24.130 -
  24.131 -    /* Drop our own references to the vram pages */
  24.132 -    munmap(mapping, nr_extents * TARGET_PAGE_SIZE);
  24.133 -
  24.134 -    /* Now drop the guest's mappings */
  24.135 -    memset(extent_start, 0, sizeof(xen_pfn_t) * nr_extents);
  24.136 -    for (i = 0; i < nr_extents; i++)
  24.137 -        extent_start[i] = (begin + (i * TARGET_PAGE_SIZE)) >> TARGET_PAGE_BITS;
  24.138 -    unset_mm_mapping(xc_handle, domid, nr_extents, 0, extent_start);
  24.139 -
  24.140 -    free(extent_start);
  24.141 -
  24.142 -    return 0;
  24.143 +}
  24.144 +
  24.145 +void cirrus_restart_acc(CirrusVGAState *s)
  24.146 +{
  24.147 +    set_vram_mapping(s, s->lfb_addr, s->lfb_end);
  24.148 +    s->map_addr = s->lfb_addr;
  24.149 +    s->map_end = s->lfb_end;
  24.150  }
  24.151  
  24.152  /* Compute the memory access functions */
  24.153 @@ -2654,17 +2629,7 @@ static void cirrus_update_memory_access(
  24.154  	mode = s->gr[0x05] & 0x7;
  24.155  	if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
  24.156              if (s->lfb_addr && s->lfb_end && !s->map_addr) {
  24.157 -                void *vram_pointer, *old_vram;
  24.158 -
  24.159 -                vram_pointer = set_vram_mapping(s->lfb_addr,
  24.160 -                                                s->lfb_end);
  24.161 -                if (!vram_pointer)
  24.162 -                    fprintf(stderr, "NULL vram_pointer\n");
  24.163 -                else {
  24.164 -                    old_vram = vga_update_vram((VGAState *)s, vram_pointer,
  24.165 -                                               VGA_RAM_SIZE);
  24.166 -                    qemu_free(old_vram);
  24.167 -                }
  24.168 +                set_vram_mapping(s, s->lfb_addr, s->lfb_end);
  24.169                  s->map_addr = s->lfb_addr;
  24.170                  s->map_end = s->lfb_end;
  24.171              }
  24.172 @@ -2674,14 +2639,7 @@ static void cirrus_update_memory_access(
  24.173          } else {
  24.174          generic_io:
  24.175              if (s->lfb_addr && s->lfb_end && s->map_addr) {
  24.176 -                void *old_vram;
  24.177 -
  24.178 -                old_vram = vga_update_vram((VGAState *)s, NULL, VGA_RAM_SIZE);
  24.179 -
  24.180 -                unset_vram_mapping(s->lfb_addr,
  24.181 -                                   s->lfb_end, 
  24.182 -                                   old_vram);
  24.183 -
  24.184 +                unset_vram_mapping(s, s->map_addr, s->map_end);
  24.185                  s->map_addr = s->map_end = 0;
  24.186              }
  24.187              s->cirrus_linear_write[0] = cirrus_linear_writeb;
  24.188 @@ -3040,36 +2998,6 @@ static CPUWriteMemoryFunc *cirrus_mmio_w
  24.189      cirrus_mmio_writel,
  24.190  };
  24.191  
  24.192 -void cirrus_stop_acc(CirrusVGAState *s)
  24.193 -{
  24.194 -    if (s->map_addr){
  24.195 -        int error;
  24.196 -        s->map_addr = 0;
  24.197 -        error = unset_vram_mapping(s->lfb_addr,
  24.198 -                s->lfb_end, s->vram_ptr);
  24.199 -        fprintf(stderr, "cirrus_stop_acc:unset_vram_mapping.\n");
  24.200 -    }
  24.201 -}
  24.202 -
  24.203 -void cirrus_restart_acc(CirrusVGAState *s)
  24.204 -{
  24.205 -    if (s->lfb_addr && s->lfb_end) {
  24.206 -        void *vram_pointer, *old_vram;
  24.207 -        fprintf(stderr, "cirrus_vga_load:re-enable vga acc.lfb_addr=0x%lx, lfb_end=0x%lx.\n",
  24.208 -                s->lfb_addr, s->lfb_end);
  24.209 -        vram_pointer = set_vram_mapping(s->lfb_addr ,s->lfb_end);
  24.210 -        if (!vram_pointer){
  24.211 -            fprintf(stderr, "cirrus_vga_load:NULL vram_pointer\n");
  24.212 -        } else {
  24.213 -            old_vram = vga_update_vram((VGAState *)s, vram_pointer,
  24.214 -                    VGA_RAM_SIZE);
  24.215 -            qemu_free(old_vram);
  24.216 -            s->map_addr = s->lfb_addr;
  24.217 -            s->map_end = s->lfb_end;
  24.218 -        }
  24.219 -    }
  24.220 -}
  24.221 -
  24.222  /* load/save state */
  24.223  
  24.224  static void cirrus_vga_save(QEMUFile *f, void *opaque)
  24.225 @@ -3118,7 +3046,10 @@ static void cirrus_vga_save(QEMUFile *f,
  24.226      qemu_put_8s(f, &vga_acc);
  24.227      qemu_put_be64s(f, (uint64_t*)&s->lfb_addr);
  24.228      qemu_put_be64s(f, (uint64_t*)&s->lfb_end);
  24.229 -    qemu_put_buffer(f, s->vram_ptr, VGA_RAM_SIZE); 
  24.230 +    qemu_put_be64s(f, &s->stolen_vram_addr);
  24.231 +    if (!s->stolen_vram_addr && !vga_acc)
  24.232 +        /* Old guest: VRAM is not mapped, we have to save it ourselves */
  24.233 +        qemu_put_buffer(f, s->vram_ptr, VGA_RAM_SIZE);
  24.234  }
  24.235  
  24.236  static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id)
  24.237 @@ -3127,7 +3058,7 @@ static int cirrus_vga_load(QEMUFile *f, 
  24.238      uint8_t vga_acc = 0;
  24.239      int ret;
  24.240  
  24.241 -    if (version_id > 2)
  24.242 +    if (version_id > 3)
  24.243          return -EINVAL;
  24.244  
  24.245      if (s->pci_dev && version_id >= 2) {
  24.246 @@ -3173,9 +3104,20 @@ static int cirrus_vga_load(QEMUFile *f, 
  24.247      qemu_get_8s(f, &vga_acc);
  24.248      qemu_get_be64s(f, (uint64_t*)&s->lfb_addr);
  24.249      qemu_get_be64s(f, (uint64_t*)&s->lfb_end);
  24.250 -    qemu_get_buffer(f, s->vram_ptr, VGA_RAM_SIZE); 
  24.251 -    if (vga_acc){
  24.252 -        cirrus_restart_acc(s);
  24.253 +    if (version_id >= 3) {
  24.254 +        qemu_get_be64s(f, &s->stolen_vram_addr);
  24.255 +        if (!s->stolen_vram_addr && !vga_acc) {
  24.256 +            /* Old guest, VRAM is not mapped, we have to restore it ourselves */
  24.257 +            qemu_get_buffer(f, s->vram_ptr, VGA_RAM_SIZE);
  24.258 +            xen_vga_populate_vram(s->lfb_addr);
  24.259 +        } else
  24.260 +            xen_vga_vram_map(vga_acc ? s->lfb_addr : s->stolen_vram_addr, 0);
  24.261 +    } else {
  24.262 +        /* Old image, we have to populate and restore VRAM ourselves */
  24.263 +        xen_vga_populate_vram(s->lfb_addr);
  24.264 +        qemu_get_buffer(f, s->vram_ptr, VGA_RAM_SIZE); 
  24.265 +        if (vga_acc)
  24.266 +            cirrus_restart_acc(s);
  24.267      }
  24.268  
  24.269      /* force refresh */
  24.270 @@ -3297,7 +3239,7 @@ static void cirrus_init_common(CirrusVGA
  24.271      s->cursor_invalidate = cirrus_cursor_invalidate;
  24.272      s->cursor_draw_line = cirrus_cursor_draw_line;
  24.273  
  24.274 -    register_savevm("cirrus_vga", 0, 2, cirrus_vga_save, cirrus_vga_load, s);
  24.275 +    register_savevm("cirrus_vga", 0, 3, cirrus_vga_save, cirrus_vga_load, s);
  24.276  }
  24.277  
  24.278  /***************************************
    25.1 --- a/tools/ioemu/hw/ide.c	Mon Aug 25 19:04:37 2008 +0900
    25.2 +++ b/tools/ioemu/hw/ide.c	Mon Sep 01 16:59:43 2008 +0900
    25.3 @@ -1108,14 +1108,14 @@ static void ide_flush_cb(void *opaque, i
    25.4  	return;
    25.5      }
    25.6      else
    25.7 -        s->status = READY_STAT;
    25.8 +        s->status = READY_STAT | SEEK_STAT;
    25.9      ide_set_irq(s);
   25.10  }
   25.11  
   25.12  static void ide_atapi_cmd_ok(IDEState *s)
   25.13  {
   25.14      s->error = 0;
   25.15 -    s->status = READY_STAT;
   25.16 +    s->status = READY_STAT | SEEK_STAT;
   25.17      s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
   25.18      ide_set_irq(s);
   25.19  }
   25.20 @@ -1229,7 +1229,7 @@ static void ide_atapi_cmd_reply_end(IDES
   25.21      if (s->packet_transfer_size <= 0) {
   25.22          /* end of transfer */
   25.23          ide_transfer_stop(s);
   25.24 -        s->status = READY_STAT;
   25.25 +        s->status = READY_STAT | SEEK_STAT;
   25.26          s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
   25.27          ide_set_irq(s);
   25.28  #ifdef DEBUG_IDE_ATAPI
   25.29 @@ -1307,10 +1307,10 @@ static void ide_atapi_cmd_reply(IDEState
   25.30      s->io_buffer_index = 0;
   25.31  
   25.32      if (s->atapi_dma) {
   25.33 -    	s->status = READY_STAT | DRQ_STAT;
   25.34 +    	s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
   25.35  	ide_dma_start(s, ide_atapi_cmd_read_dma_cb);
   25.36      } else {
   25.37 -    	s->status = READY_STAT;
   25.38 +    	s->status = READY_STAT | SEEK_STAT;
   25.39      	ide_atapi_cmd_reply_end(s);
   25.40      }
   25.41  }
   25.42 @@ -1325,7 +1325,7 @@ static void ide_atapi_cmd_read_pio(IDESt
   25.43      s->io_buffer_index = sector_size;
   25.44      s->cd_sector_size = sector_size;
   25.45  
   25.46 -    s->status = READY_STAT;
   25.47 +    s->status = READY_STAT | SEEK_STAT;
   25.48      ide_atapi_cmd_reply_end(s);
   25.49  }
   25.50  
   25.51 @@ -1368,7 +1368,7 @@ static void ide_atapi_cmd_read_dma_cb(vo
   25.52      }
   25.53  
   25.54      if (s->packet_transfer_size <= 0) {
   25.55 -        s->status = READY_STAT;
   25.56 +        s->status = READY_STAT | SEEK_STAT;
   25.57          s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
   25.58          ide_set_irq(s);
   25.59      eot:
   25.60 @@ -1418,7 +1418,7 @@ static void ide_atapi_cmd_read_dma(IDESt
   25.61      s->cd_sector_size = sector_size;
   25.62  
   25.63      /* XXX: check if BUSY_STAT should be set */
   25.64 -    s->status = READY_STAT | DRQ_STAT | BUSY_STAT;
   25.65 +    s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
   25.66      ide_dma_start(s, ide_atapi_cmd_read_dma_cb);
   25.67  }
   25.68  
   25.69 @@ -1886,7 +1886,7 @@ static void ide_ioport_write(void *opaqu
   25.70                  ide_abort_command(s);
   25.71              } else {
   25.72                  s->mult_sectors = s->nsector;
   25.73 -                s->status = READY_STAT;
   25.74 +                s->status = READY_STAT | SEEK_STAT;
   25.75              }
   25.76              ide_set_irq(s);
   25.77              break;
   25.78 @@ -1896,7 +1896,7 @@ static void ide_ioport_write(void *opaqu
   25.79          case WIN_VERIFY_ONCE:
   25.80              /* do sector number check ? */
   25.81  	    ide_cmd_lba48_transform(s, lba48);
   25.82 -            s->status = READY_STAT;
   25.83 +            s->status = READY_STAT | SEEK_STAT;
   25.84              ide_set_irq(s);
   25.85              break;
   25.86  	case WIN_READ_EXT:
   25.87 @@ -1965,12 +1965,12 @@ static void ide_ioport_write(void *opaqu
   25.88          case WIN_READ_NATIVE_MAX:
   25.89  	    ide_cmd_lba48_transform(s, lba48);
   25.90              ide_set_sector(s, s->nb_sectors - 1);
   25.91 -            s->status = READY_STAT;
   25.92 +            s->status = READY_STAT | SEEK_STAT;
   25.93              ide_set_irq(s);
   25.94              break;
   25.95          case WIN_CHECKPOWERMODE1:
   25.96              s->nsector = 0xff; /* device active or idle */
   25.97 -            s->status = READY_STAT;
   25.98 +            s->status = READY_STAT | SEEK_STAT;
   25.99              ide_set_irq(s);
  25.100              break;
  25.101          case WIN_SETFEATURES:
  25.102 @@ -2070,7 +2070,7 @@ static void ide_ioport_write(void *opaqu
  25.103              /* overlapping commands not supported */
  25.104              if (s->feature & 0x02)
  25.105                  goto abort_cmd;
  25.106 -            s->status = READY_STAT;
  25.107 +            s->status = READY_STAT | SEEK_STAT;
  25.108              s->atapi_dma = s->feature & 1;
  25.109              s->nsector = 1;
  25.110              ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE, 
  25.111 @@ -2289,7 +2289,7 @@ static void ide_reset(IDEState *s)
  25.112      s->mult_sectors = MAX_MULT_SECTORS;
  25.113      s->cur_drive = s;
  25.114      s->select = 0xa0;
  25.115 -    s->status = READY_STAT;
  25.116 +    s->status = READY_STAT | SEEK_STAT;
  25.117      ide_set_signature(s);
  25.118      /* init the transfer handler so that 0xffff is returned on data
  25.119         accesses */
    26.1 --- a/tools/ioemu/hw/pass-through.c	Mon Aug 25 19:04:37 2008 +0900
    26.2 +++ b/tools/ioemu/hw/pass-through.c	Mon Sep 01 16:59:43 2008 +0900
    26.3 @@ -2340,11 +2340,6 @@ static int pt_bar_reg_write(struct pt_de
    26.4                  return -1;
    26.5          }
    26.6  
    26.7 -        /* always keep the emulate register value to 0,
    26.8 -         * because hvmloader does not support high MMIO for now.
    26.9 -         */
   26.10 -        cfg_entry->data = 0;
   26.11 -
   26.12          /* never mapping the 'empty' upper region,
   26.13           * because we'll do it enough for the lower region.
   26.14           */
    27.1 --- a/tools/ioemu/hw/vga.c	Mon Aug 25 19:04:37 2008 +0900
    27.2 +++ b/tools/ioemu/hw/vga.c	Mon Sep 01 16:59:43 2008 +0900
    27.3 @@ -23,6 +23,7 @@
    27.4   */
    27.5  #include "vl.h"
    27.6  #include "vga_int.h"
    27.7 +#include <sys/mman.h>
    27.8  
    27.9  //#define DEBUG_VGA
   27.10  //#define DEBUG_VGA_MEM
   27.11 @@ -1776,7 +1777,10 @@ static void vga_save(QEMUFile *f, void *
   27.12  #endif
   27.13      vram_size = s->vram_size;
   27.14      qemu_put_be32s(f, &vram_size); 
   27.15 -    qemu_put_buffer(f, s->vram_ptr, s->vram_size); 
   27.16 +    qemu_put_be64s(f, &s->stolen_vram_addr);
   27.17 +    if (!s->stolen_vram_addr)
   27.18 +        /* Old guest: VRAM is not mapped, we have to save it ourselves */
   27.19 +        qemu_put_buffer(f, s->vram_ptr, VGA_RAM_SIZE);
   27.20  }
   27.21  
   27.22  static int vga_load(QEMUFile *f, void *opaque, int version_id)
   27.23 @@ -1788,7 +1792,7 @@ static int vga_load(QEMUFile *f, void *o
   27.24      int i;
   27.25  #endif
   27.26  
   27.27 -    if (version_id > 3)
   27.28 +    if (version_id > 4)
   27.29          return -EINVAL;
   27.30  
   27.31      if (s->pci_dev && version_id >= 2) {
   27.32 @@ -1839,7 +1843,14 @@ static int vga_load(QEMUFile *f, void *o
   27.33  	qemu_get_be32s(f, &vram_size);
   27.34  	if (vram_size != s->vram_size)
   27.35  	    return -EINVAL;
   27.36 -	qemu_get_buffer(f, s->vram_ptr, s->vram_size); 
   27.37 +        if (version_id >= 4) {
   27.38 +            qemu_get_be64s(f, &s->stolen_vram_addr);
   27.39 +            if (s->stolen_vram_addr)
   27.40 +                xen_vga_vram_map(s->stolen_vram_addr, 0);
   27.41 +        }
   27.42 +        /* Old guest, VRAM is not mapped, we have to restore it ourselves */
   27.43 +        if (!s->stolen_vram_addr)
   27.44 +            qemu_get_buffer(f, s->vram_ptr, s->vram_size); 
   27.45      }
   27.46  
   27.47      /* force refresh */
   27.48 @@ -1994,6 +2005,100 @@ void vga_bios_init(VGAState *s)
   27.49      /* TODO: add vbe support if enabled */
   27.50  }
   27.51  
   27.52 +
   27.53 +static VGAState *xen_vga_state;
   27.54 +
   27.55 +/* When loading old images we have to populate the video ram ourselves */
   27.56 +void xen_vga_populate_vram(uint64_t vram_addr)
   27.57 +{
   27.58 +    unsigned long nr_pfn;
   27.59 +    struct xen_remove_from_physmap xrfp;
   27.60 +    xen_pfn_t *pfn_list;
   27.61 +    int i;
   27.62 +    int rc;
   27.63 +
   27.64 +    fprintf(logfile, "populating video RAM at %lx\n", vram_addr);
   27.65 +
   27.66 +    nr_pfn = VGA_RAM_SIZE >> TARGET_PAGE_BITS;
   27.67 +
   27.68 +    pfn_list = malloc(sizeof(*pfn_list) * nr_pfn);
   27.69 +
   27.70 +    for (i = 0; i < nr_pfn; i++)
   27.71 +        pfn_list[i] = (vram_addr >> TARGET_PAGE_BITS) + i;
   27.72 +
   27.73 +    if (xc_domain_memory_populate_physmap(xc_handle, domid, nr_pfn, 0, 0, pfn_list)) {
   27.74 +        fprintf(stderr, "Failed to populate video ram\n");
   27.75 +        exit(1);
   27.76 +    }
   27.77 +    free(pfn_list);
   27.78 +
   27.79 +    xen_vga_vram_map(vram_addr, 0);
   27.80 +
   27.81 +    /* Unmap them from the guest for now. */
   27.82 +    xrfp.domid = domid;
   27.83 +    for (i = 0; i < nr_pfn; i++) {
   27.84 +        xrfp.gpfn = (vram_addr >> TARGET_PAGE_BITS) + i;
   27.85 +        rc = xc_memory_op(xc_handle, XENMEM_remove_from_physmap, &xrfp);
   27.86 +        if (rc) {
   27.87 +            fprintf(stderr, "remove_from_physmap PFN %"PRI_xen_pfn" failed: %d\n", xrfp.gpfn, rc);
   27.88 +            break;
   27.89 +        }
   27.90 +    }
   27.91 +}
   27.92 +
   27.93 +/* Called once video memory has been allocated in the GPFN space */
   27.94 +void xen_vga_vram_map(uint64_t vram_addr, int copy)
   27.95 +{
   27.96 +    unsigned long nr_pfn;
   27.97 +    xen_pfn_t *pfn_list;
   27.98 +    int i;
   27.99 +    void *vram;
  27.100 +
  27.101 +    fprintf(logfile, "mapping video RAM from %lx\n", vram_addr);
  27.102 +
  27.103 +    nr_pfn = VGA_RAM_SIZE >> TARGET_PAGE_BITS;
  27.104 +
  27.105 +    pfn_list = malloc(sizeof(*pfn_list) * nr_pfn);
  27.106 +
  27.107 +    for (i = 0; i < nr_pfn; i++)
  27.108 +        pfn_list[i] = (vram_addr >> TARGET_PAGE_BITS) + i;
  27.109 +
  27.110 +    vram = xc_map_foreign_pages(xc_handle, domid,
  27.111 +                                        PROT_READ|PROT_WRITE,
  27.112 +                                        pfn_list, nr_pfn);
  27.113 +
  27.114 +    if (!vram) {
  27.115 +        fprintf(stderr, "Failed to map vram\n");
  27.116 +        exit(1);
  27.117 +    }
  27.118 +
  27.119 +    if (xc_domain_memory_translate_gpfn_list(xc_handle, domid, nr_pfn,
  27.120 +                pfn_list, pfn_list)) {
  27.121 +        fprintf(stderr, "Failed translation in xen_vga_vram_addr\n");
  27.122 +        exit(1);
  27.123 +    }
  27.124 +
  27.125 +    if (copy)
  27.126 +        memcpy(vram, xen_vga_state->vram_ptr, VGA_RAM_SIZE);
  27.127 +    qemu_free(xen_vga_state->vram_ptr);
  27.128 +    xen_vga_state->vram_ptr = vram;
  27.129 +    xen_vga_state->vram_mfns = pfn_list;
  27.130 +#ifdef CONFIG_STUBDOM
  27.131 +    xenfb_pv_display_start(vram);
  27.132 +#endif
  27.133 +}
  27.134 +
  27.135 +/* Called at boot time when the BIOS has allocated video RAM */
  27.136 +void xen_vga_stolen_vram_addr(uint64_t stolen_vram_addr)
  27.137 +{
  27.138 +    fprintf(logfile, "stolen video RAM at %lx\n", stolen_vram_addr);
  27.139 +
  27.140 +    xen_vga_state->stolen_vram_addr = stolen_vram_addr;
  27.141 +
  27.142 +    /* And copy from the initialization value */
  27.143 +    xen_vga_vram_map(stolen_vram_addr, 1);
  27.144 +}
  27.145 +
  27.146  /* when used on xen environment, the vga_ram_base is not used */
  27.147  void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base, 
  27.148                       unsigned long vga_ram_offset, int vga_ram_size)
  27.149 @@ -2025,13 +2130,9 @@ void vga_common_init(VGAState *s, Displa
  27.150  
  27.151      vga_reset(s);
  27.152  
  27.153 -    /* Video RAM must be page-aligned for PVFB memory sharing */
  27.154 -    s->vram_ptr = s->vram_alloc = qemu_memalign(TARGET_PAGE_SIZE, vga_ram_size);
  27.155 -
  27.156 -#ifdef CONFIG_STUBDOM
  27.157 -    if (!cirrus_vga_enabled)
  27.158 -        xenfb_pv_display_start(s->vram_ptr);
  27.159 -#endif
  27.160 +    s->vram_ptr = qemu_malloc(vga_ram_size);
  27.161 +    s->vram_mfns = NULL;
  27.162 +    xen_vga_state = s;
  27.163  
  27.164      s->vram_offset = vga_ram_offset;
  27.165      s->vram_size = vga_ram_size;
  27.166 @@ -2051,7 +2152,7 @@ static void vga_init(VGAState *s)
  27.167  {
  27.168      int vga_io_memory;
  27.169  
  27.170 -    register_savevm("vga", 0, 3, vga_save, vga_load, s);
  27.171 +    register_savevm("vga", 0, 4, vga_save, vga_load, s);
  27.172  
  27.173      register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s);
  27.174  
  27.175 @@ -2163,33 +2264,6 @@ int pci_vga_init(PCIBus *bus, DisplaySta
  27.176      return 0;
  27.177  }
  27.178  
  27.179 -void *vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size)
  27.180 -{
  27.181 -    uint8_t *old_pointer;
  27.182 -
  27.183 -    if (s->vram_size != vga_ram_size) {
  27.184 -        fprintf(stderr, "No support to change vga_ram_size\n");
  27.185 -        return NULL;
  27.186 -    }
  27.187 -
  27.188 -    if (!vga_ram_base) {
  27.189 -        vga_ram_base = qemu_memalign(TARGET_PAGE_SIZE, vga_ram_size + TARGET_PAGE_SIZE + 1);
  27.190 -        if (!vga_ram_base) {
  27.191 -            fprintf(stderr, "reallocate error\n");
  27.192 -            return NULL;
  27.193 -        }
  27.194 -    }
  27.195 -
  27.196 -    /* XXX lock needed? */
  27.197 -    old_pointer = s->vram_alloc;
  27.198 -    s->vram_alloc = vga_ram_base;
  27.199 -    vga_ram_base = (uint8_t *)((long)(vga_ram_base + 15) & ~15L);
  27.200 -    memcpy(vga_ram_base, s->vram_ptr, vga_ram_size);
  27.201 -    s->vram_ptr = vga_ram_base;
  27.202 -
  27.203 -    return old_pointer;
  27.204 -}
  27.205 -
  27.206  /********************************************************/
  27.207  /* vga screen dump */
  27.208  
    28.1 --- a/tools/ioemu/hw/vga_int.h	Mon Aug 25 19:04:37 2008 +0900
    28.2 +++ b/tools/ioemu/hw/vga_int.h	Mon Sep 01 16:59:43 2008 +0900
    28.3 @@ -80,9 +80,9 @@
    28.4  #define VGA_MAX_HEIGHT 2048
    28.5  
    28.6  #define VGA_STATE_COMMON                                                \
    28.7 -    uint8_t *vram_alloc;                                                \
    28.8      uint8_t *vram_ptr;                                                  \
    28.9 -    uint8_t *vram_shadow;                                               \
   28.10 +    xen_pfn_t *vram_mfns;                                               \
   28.11 +    uint64_t stolen_vram_addr; /* Address of stolen RAM */              \
   28.12      unsigned long vram_offset;                                          \
   28.13      unsigned int vram_size;                                             \
   28.14      unsigned long bios_offset;                                          \
    29.1 --- a/tools/ioemu/hw/xen_platform.c	Mon Aug 25 19:04:37 2008 +0900
    29.2 +++ b/tools/ioemu/hw/xen_platform.c	Mon Sep 01 16:59:43 2008 +0900
    29.3 @@ -34,6 +34,7 @@ typedef struct PCIXenPlatformState
    29.4  {
    29.5    PCIDevice  pci_dev;
    29.6    uint8_t    platform_flags;
    29.7 +  uint64_t   vga_stolen_ram;
    29.8  } PCIXenPlatformState;
    29.9  
   29.10  static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr)
   29.11 @@ -69,11 +70,46 @@ static void xen_platform_ioport_writeb(v
   29.12  }
   29.13  
   29.14  
   29.15 +static uint32_t xen_platform_ioport_readl(void *opaque, uint32_t addr)
   29.16 +{
   29.17 +    PCIXenPlatformState *d = opaque;
   29.18 +
   29.19 +    addr  &= 0xff;
   29.20 +
   29.21 +    switch (addr) {
   29.22 +    case 4: /* VGA stolen memory address */
   29.23 +        return d->vga_stolen_ram;
   29.24 +    default:
   29.25 +        return ~0u;
   29.26 +    }
   29.27 +}
   29.28 +
   29.29 +static void xen_platform_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
   29.30 +{
   29.31 +    PCIXenPlatformState *d = opaque;
   29.32 +
   29.33 +    addr &= 0xff;
   29.34 +    val  &= 0xffffffff;
   29.35 +
   29.36 +    switch (addr) {
   29.37 +    case 4: /* VGA stolen memory address */
   29.38 +        d->vga_stolen_ram = val;
   29.39 +        xen_vga_stolen_vram_addr(val);
   29.40 +        break;
   29.41 +    default:
   29.42 +        break;
   29.43 +    }
   29.44 +}
   29.45 +
   29.46 +
   29.47 +
   29.48  static void platform_ioport_map(PCIDevice *pci_dev, int region_num, uint32_t addr, uint32_t size, int type)
   29.49  {
   29.50      PCIXenPlatformState *d = (PCIXenPlatformState *)pci_dev;
   29.51      register_ioport_write(addr, size, 1, xen_platform_ioport_writeb, d);
   29.52 +    register_ioport_write(addr, size, 4, xen_platform_ioport_writel, d);
   29.53      register_ioport_read(addr, size, 1, xen_platform_ioport_readb, d);
   29.54 +    register_ioport_read(addr, size, 4, xen_platform_ioport_readl, d);
   29.55  }
   29.56  
   29.57  static uint32_t platform_mmio_read(void *opaque, target_phys_addr_t addr)
   29.58 @@ -155,6 +191,7 @@ void xen_pci_save(QEMUFile *f, void *opa
   29.59  
   29.60      pci_device_save(&d->pci_dev, f);
   29.61      qemu_put_8s(f, &d->platform_flags);
   29.62 +    qemu_put_be64s(f, &d->vga_stolen_ram);
   29.63  }
   29.64  
   29.65  int xen_pci_load(QEMUFile *f, void *opaque, int version_id)
   29.66 @@ -173,6 +210,7 @@ int xen_pci_load(QEMUFile *f, void *opaq
   29.67          uint8_t flags;
   29.68          qemu_get_8s(f, &flags);
   29.69          xen_platform_ioport_writeb(d, 0, flags);
   29.70 +        qemu_get_be64s(f, &d->vga_stolen_ram);
   29.71      }
   29.72  
   29.73      return 0;
    30.1 --- a/tools/ioemu/vl.c	Mon Aug 25 19:04:37 2008 +0900
    30.2 +++ b/tools/ioemu/vl.c	Mon Sep 01 16:59:43 2008 +0900
    30.3 @@ -7023,38 +7023,6 @@ static BOOL WINAPI qemu_ctrl_handler(DWO
    30.4  
    30.5  #include <xg_private.h>
    30.6  
    30.7 -/* FIXME Flush the shadow page */
    30.8 -int unset_mm_mapping(int xc_handle, uint32_t domid,
    30.9 -                     unsigned long nr_pages, unsigned int address_bits,
   30.10 -                     xen_pfn_t *extent_start)
   30.11 -{
   30.12 -    int err = 0;
   30.13 -
   30.14 -    err = xc_domain_memory_decrease_reservation(xc_handle, domid,
   30.15 -                                                nr_pages, 0, extent_start);
   30.16 -    if (err)
   30.17 -        fprintf(stderr, "Failed to decrease physmap\n");
   30.18 -
   30.19 -    return err;
   30.20 -}
   30.21 -
   30.22 -int set_mm_mapping(int xc_handle, uint32_t domid,
   30.23 -                   unsigned long nr_pages, unsigned int address_bits,
   30.24 -                   xen_pfn_t *extent_start)
   30.25 -{
   30.26 -    int err = 0;
   30.27 -
   30.28 -    err = xc_domain_memory_populate_physmap(
   30.29 -        xc_handle, domid, nr_pages, 0,
   30.30 -        XENMEMF_address_bits(address_bits), extent_start);
   30.31 -    if (err) {
   30.32 -        fprintf(stderr, "Failed to populate physmap\n");
   30.33 -        return -1;
   30.34 -    }
   30.35 -
   30.36 -    return 0;
   30.37 -}
   30.38 -
   30.39  
   30.40  int main(int argc, char **argv)
   30.41  {
    31.1 --- a/tools/ioemu/vl.h	Mon Aug 25 19:04:37 2008 +0900
    31.2 +++ b/tools/ioemu/vl.h	Mon Sep 01 16:59:43 2008 +0900
    31.3 @@ -1560,6 +1560,9 @@ void timeoffset_get(void);
    31.4  /* xen_platform.c */
    31.5  #ifndef QEMU_TOOL
    31.6  void pci_xen_platform_init(PCIBus *bus);
    31.7 +void xen_vga_stolen_vram_addr(uint64_t vram_addr);
    31.8 +void xen_vga_populate_vram(uint64_t vram_addr);
    31.9 +void xen_vga_vram_map(uint64_t vram_addr, int copy);
   31.10  #endif
   31.11  
   31.12  /* pci_emulation.c */
    32.1 --- a/tools/libxc/xc_dom_boot.c	Mon Aug 25 19:04:37 2008 +0900
    32.2 +++ b/tools/libxc/xc_dom_boot.c	Mon Sep 01 16:59:43 2008 +0900
    32.3 @@ -187,7 +187,7 @@ void *xc_dom_boot_domU_map(struct xc_dom
    32.4  int xc_dom_boot_image(struct xc_dom_image *dom)
    32.5  {
    32.6      DECLARE_DOMCTL;
    32.7 -    void *ctxt;
    32.8 +    vcpu_guest_context_any_t ctxt;
    32.9      int rc;
   32.10  
   32.11      xc_dom_printf("%s: called\n", __FUNCTION__);
   32.12 @@ -245,12 +245,11 @@ int xc_dom_boot_image(struct xc_dom_imag
   32.13          return rc;
   32.14  
   32.15      /* let the vm run */
   32.16 -    ctxt = xc_dom_malloc(dom, PAGE_SIZE * 2 /* FIXME */ );
   32.17 -    memset(ctxt, 0, PAGE_SIZE * 2);
   32.18 -    if ( (rc = dom->arch_hooks->vcpu(dom, ctxt)) != 0 )
   32.19 +    memset(&ctxt, 0, sizeof(ctxt));
   32.20 +    if ( (rc = dom->arch_hooks->vcpu(dom, &ctxt)) != 0 )
   32.21          return rc;
   32.22      xc_dom_unmap_all(dom);
   32.23 -    rc = launch_vm(dom->guest_xc, dom->guest_domid, ctxt);
   32.24 +    rc = launch_vm(dom->guest_xc, dom->guest_domid, &ctxt);
   32.25  
   32.26      return rc;
   32.27  }
    33.1 --- a/tools/libxc/xc_domain.c	Mon Aug 25 19:04:37 2008 +0900
    33.2 +++ b/tools/libxc/xc_domain.c	Mon Sep 01 16:59:43 2008 +0900
    33.3 @@ -537,6 +537,33 @@ int xc_domain_memory_populate_physmap(in
    33.4      return err;
    33.5  }
    33.6  
    33.7 +int xc_domain_memory_translate_gpfn_list(int xc_handle,
    33.8 +                                         uint32_t domid,
    33.9 +                                         unsigned long nr_gpfns,
   33.10 +                                         xen_pfn_t *gpfn_list,
   33.11 +                                         xen_pfn_t *mfn_list)
   33.12 +{
   33.13 +    int err;
   33.14 +    struct xen_translate_gpfn_list translate_gpfn_list = {
   33.15 +        .domid    = domid,
   33.16 +        .nr_gpfns = nr_gpfns,
   33.17 +    };
   33.18 +    set_xen_guest_handle(translate_gpfn_list.gpfn_list, gpfn_list);
   33.19 +    set_xen_guest_handle(translate_gpfn_list.mfn_list, mfn_list);
   33.20 +
   33.21 +    err = xc_memory_op(xc_handle, XENMEM_translate_gpfn_list, &translate_gpfn_list);
   33.22 +
   33.23 +    if ( err != 0 )
   33.24 +    {
   33.25 +        DPRINTF("Failed translation for dom %d (%ld PFNs)\n",
   33.26 +                domid, nr_gpfns);
   33.27 +        errno = -err;
   33.28 +        err = -1;
   33.29 +    }
   33.30 +
   33.31 +    return err;
   33.32 +}
   33.33 +
   33.34  int xc_domain_max_vcpus(int xc_handle, uint32_t domid, unsigned int max)
   33.35  {
   33.36      DECLARE_DOMCTL;
    34.1 --- a/tools/libxc/xc_domain_save.c	Mon Aug 25 19:04:37 2008 +0900
    34.2 +++ b/tools/libxc/xc_domain_save.c	Mon Sep 01 16:59:43 2008 +0900
    34.3 @@ -1111,12 +1111,6 @@ int xc_domain_save(int xc_handle, int io
    34.4                         (test_bit(n, to_fix)  && last_iter)) )
    34.5                      continue;
    34.6  
    34.7 -                /* Skip PFNs that aren't really there */
    34.8 -                if ( hvm && ((n >= 0xa0 && n < 0xc0) /* VGA hole */
    34.9 -                             || (n >= (HVM_BELOW_4G_MMIO_START >> PAGE_SHIFT) 
   34.10 -                                 && n < (1ULL<<32) >> PAGE_SHIFT)) /* MMIO */ )
   34.11 -                    continue;
   34.12 -
   34.13                  /*
   34.14                  ** we get here if:
   34.15                  **  1. page is marked to_send & hasn't already been re-dirtied
    35.1 --- a/tools/libxc/xc_minios.c	Mon Aug 25 19:04:37 2008 +0900
    35.2 +++ b/tools/libxc/xc_minios.c	Mon Sep 01 16:59:43 2008 +0900
    35.3 @@ -64,7 +64,6 @@ void *xc_map_foreign_range(int xc_handle
    35.4                             unsigned long mfn)
    35.5  {
    35.6      unsigned long pt_prot = 0;
    35.7 -    printf("xc_map_foreign_range(%lx, %d)\n", mfn, size);
    35.8  #ifdef __ia64__
    35.9      /* TODO */
   35.10  #else
   35.11 @@ -81,9 +80,10 @@ void *xc_map_foreign_ranges(int xc_handl
   35.12                              size_t size, int prot, size_t chunksize,
   35.13                              privcmd_mmap_entry_t entries[], int nentries)
   35.14  {
   35.15 -    unsigned long mfns[size / PAGE_SIZE];
   35.16 +    unsigned long *mfns;
   35.17      int i, j, n;
   35.18      unsigned long pt_prot = 0;
   35.19 +    void *ret;
   35.20  #ifdef __ia64__
   35.21      /* TODO */
   35.22  #else
   35.23 @@ -93,12 +93,16 @@ void *xc_map_foreign_ranges(int xc_handl
   35.24  	pt_prot = L1_PROT;
   35.25  #endif
   35.26  
   35.27 +    mfns = malloc((size / PAGE_SIZE) * sizeof(*mfns));
   35.28 +
   35.29      n = 0;
   35.30      for (i = 0; i < nentries; i++)
   35.31          for (j = 0; j < chunksize / PAGE_SIZE; j++)
   35.32              mfns[n++] = entries[i].mfn + j;
   35.33  
   35.34 -    return map_frames_ex(mfns, n, 1, 0, 1, dom, 0, pt_prot);
   35.35 +    ret = map_frames_ex(mfns, n, 1, 0, 1, dom, 0, pt_prot);
   35.36 +    free(mfns);
   35.37 +    return ret;
   35.38  }
   35.39  
   35.40  
    36.1 --- a/tools/libxc/xenctrl.h	Mon Aug 25 19:04:37 2008 +0900
    36.2 +++ b/tools/libxc/xenctrl.h	Mon Sep 01 16:59:43 2008 +0900
    36.3 @@ -628,6 +628,12 @@ int xc_domain_memory_populate_physmap(in
    36.4                                        unsigned int mem_flags,
    36.5                                        xen_pfn_t *extent_start);
    36.6  
    36.7 +int xc_domain_memory_translate_gpfn_list(int xc_handle,
    36.8 +                                         uint32_t domid,
    36.9 +                                         unsigned long nr_gpfns,
   36.10 +                                         xen_pfn_t *gpfn_list,
   36.11 +                                         xen_pfn_t *mfn_list);
   36.12 +
   36.13  int xc_domain_ioport_permission(int xc_handle,
   36.14                                  uint32_t domid,
   36.15                                  uint32_t first_port,
    37.1 --- a/tools/pygrub/src/pygrub	Mon Aug 25 19:04:37 2008 +0900
    37.2 +++ b/tools/pygrub/src/pygrub	Mon Sep 01 16:59:43 2008 +0900
    37.3 @@ -124,7 +124,7 @@ def get_fs_offset(file):
    37.4  class GrubLineEditor(curses.textpad.Textbox):
    37.5      def __init__(self, screen, startx, starty, line = ""):
    37.6          screen.addstr(startx, starty, "> ")
    37.7 -        screen.refresh()
    37.8 +        screen.noutrefresh()
    37.9          win = curses.newwin(1, 74, startx, starty + 2)
   37.10          curses.textpad.Textbox.__init__(self, win)
   37.11          
   37.12 @@ -137,7 +137,7 @@ class GrubLineEditor(curses.textpad.Text
   37.13          """Show the text.  One of our advantages over standard textboxes
   37.14          is that we can handle lines longer than the window."""
   37.15  
   37.16 -        self.win.clear()
   37.17 +        self.win.erase()
   37.18          p = self.pos
   37.19          off = 0
   37.20          while p > 70:
   37.21 @@ -188,6 +188,7 @@ class GrubLineEditor(curses.textpad.Text
   37.22          return 1
   37.23  
   37.24      def edit(self):
   37.25 +        curses.doupdate()
   37.26          r = curses.textpad.Textbox.edit(self)
   37.27          if self.cancelled:
   37.28              return None
   37.29 @@ -217,16 +218,15 @@ class Grub:
   37.30              curses.def_prog_mode()
   37.31          
   37.32          curses.reset_prog_mode()
   37.33 -        self.screen.clear()
   37.34 -        self.screen.refresh()
   37.35 +        self.screen.erase()
   37.36  
   37.37          # create basic grub screen with a box of entries and a textbox
   37.38          self.screen.addstr(1, 4, "pyGRUB  version %s" %(PYGRUB_VER,))
   37.39          self.entry_win.box()
   37.40 -        self.screen.refresh()
   37.41 +        self.screen.noutrefresh()
   37.42  
   37.43      def fill_entry_list(self):
   37.44 -        self.entry_win.clear()
   37.45 +        self.entry_win.erase()
   37.46          self.entry_win.box()
   37.47  
   37.48          maxy = self.entry_win.getmaxyx()[0]-3 # maxy - 2 for the frame + index
   37.49 @@ -244,7 +244,7 @@ class Grub:
   37.50              self.entry_win.addstr(y + 1 - self.start_image, 2, i.title.ljust(70))
   37.51              if y == self.selected_image:
   37.52                  self.entry_win.attroff(curses.A_REVERSE)
   37.53 -        self.entry_win.refresh()
   37.54 +        self.entry_win.noutrefresh()
   37.55  
   37.56      def edit_entry(self, origimg):
   37.57          def draw():
   37.58 @@ -259,13 +259,13 @@ class Grub:
   37.59              self.text_win.addch(0, 14, curses.ACS_DARROW)
   37.60              (y, x) = self.text_win.getmaxyx()
   37.61              self.text_win.move(y - 1, x - 1)
   37.62 -            self.text_win.refresh()
   37.63 +            self.text_win.noutrefresh()
   37.64  
   37.65          curline = 1
   37.66          img = copy.deepcopy(origimg)
   37.67          while 1:
   37.68              draw()
   37.69 -            self.entry_win.clear()
   37.70 +            self.entry_win.erase()
   37.71              self.entry_win.box()
   37.72              for idx in range(1, len(img.lines)):
   37.73                  # current line should be highlighted
   37.74 @@ -280,7 +280,8 @@ class Grub:
   37.75                  self.entry_win.addstr(idx, 2, l)
   37.76                  if idx == curline:
   37.77                      self.entry_win.attroff(curses.A_REVERSE)
   37.78 -            self.entry_win.refresh()
   37.79 +            self.entry_win.noutrefresh()
   37.80 +            curses.doupdate()
   37.81  
   37.82              c = self.screen.getch()
   37.83              if c in (ord('q'), 27): # 27 == esc
   37.84 @@ -318,10 +319,10 @@ class Grub:
   37.85              origimg.reset(img.lines)
   37.86  
   37.87      def edit_line(self, line):
   37.88 -        self.screen.clear()
   37.89 +        self.screen.erase()
   37.90          self.screen.addstr(1, 2, "[ Minimal BASH-like line editing is supported.  ")
   37.91          self.screen.addstr(2, 2, "  ESC at any time cancels.  ENTER at any time accepts your changes. ]")
   37.92 -        self.screen.refresh()
   37.93 +        self.screen.noutrefresh()
   37.94  
   37.95          t = GrubLineEditor(self.screen, 5, 2, line)
   37.96          enable_cursor(True)
   37.97 @@ -331,10 +332,10 @@ class Grub:
   37.98          return None
   37.99  
  37.100      def command_line_mode(self):
  37.101 -        self.screen.clear()
  37.102 +        self.screen.erase()
  37.103          self.screen.addstr(1, 2, "[ Minimal BASH-like line editing is supported.  ESC at any time ")
  37.104          self.screen.addstr(2, 2, "  exits.  Typing 'boot' will boot with your entered commands. ] ")
  37.105 -        self.screen.refresh()
  37.106 +        self.screen.noutrefresh()
  37.107  
  37.108          y = 5
  37.109          lines = []
  37.110 @@ -420,7 +421,7 @@ class Grub:
  37.111              self.text_win.addch(0, 14, curses.ACS_DARROW)
  37.112              (y, x) = self.text_win.getmaxyx()
  37.113              self.text_win.move(y - 1, x - 1)
  37.114 -            self.text_win.refresh()
  37.115 +            self.text_win.noutrefresh()
  37.116  
  37.117          # now loop until we hit the timeout or get a go from the user
  37.118          mytime = 0
  37.119 @@ -433,6 +434,7 @@ class Grub:
  37.120              else:
  37.121                  self.screen.addstr(20, 5, " " * 80)
  37.122              self.fill_entry_list()
  37.123 +            curses.doupdate()
  37.124  
  37.125              c = self.screen.getch()
  37.126              if c == -1:
    38.1 --- a/tools/python/xen/util/pci.py	Mon Aug 25 19:04:37 2008 +0900
    38.2 +++ b/tools/python/xen/util/pci.py	Mon Sep 01 16:59:43 2008 +0900
    38.3 @@ -40,6 +40,7 @@ DEV_TYPE_PCIe_BRIDGE    = 1
    38.4  DEV_TYPE_PCI_BRIDGE     = 2
    38.5  DEV_TYPE_PCI            = 3    
    38.6  
    38.7 +PCI_VENDOR_ID = 0x0
    38.8  PCI_STATUS = 0x6
    38.9  PCI_CLASS_DEVICE = 0x0a
   38.10  PCI_CLASS_BRIDGE_PCI = 0x0604
   38.11 @@ -69,6 +70,11 @@ PCI_PM_CTRL_NO_SOFT_RESET = 0x0004
   38.12  PCI_PM_CTRL_STATE_MASK = 0x0003
   38.13  PCI_D3hot = 3
   38.14  
   38.15 +VENDOR_INTEL  = 0x8086
   38.16 +PCI_CAP_ID_VENDOR_SPECIFIC_CAP = 0x09
   38.17 +PCI_CLASS_ID_USB = 0x0c03
   38.18 +PCI_USB_FLRCTRL = 0x4
   38.19 +
   38.20  PCI_CAP_ID_AF = 0x13
   38.21  PCI_AF_CAPs   = 0x3
   38.22  PCI_AF_CAPs_TP_FLR = 0x3
   38.23 @@ -487,7 +493,7 @@ class PciDevice:
   38.24      def do_Dstate_transition(self):
   38.25          pos = self.find_cap_offset(PCI_CAP_ID_PM)
   38.26          if pos == 0:
   38.27 -            return 
   38.28 +            return False
   38.29          
   38.30          (pci_list, cfg_list) = save_pci_conf_space([self.name])
   38.31          
   38.32 @@ -504,6 +510,31 @@ class PciDevice:
   38.33          time.sleep(0.010)
   38.34  
   38.35          restore_pci_conf_space((pci_list, cfg_list))
   38.36 +        return True
   38.37 +
   38.38 +    def do_vendor_specific_FLR_method(self):
   38.39 +        pos = self.find_cap_offset(PCI_CAP_ID_VENDOR_SPECIFIC_CAP)
   38.40 +        if pos == 0:
   38.41 +            return
   38.42 +
   38.43 +        vendor_id = self.pci_conf_read16(PCI_VENDOR_ID)
   38.44 +        if vendor_id != VENDOR_INTEL:
   38.45 +            return
   38.46 +
   38.47 +        class_id = self.pci_conf_read16(PCI_CLASS_DEVICE)
   38.48 +        if class_id != PCI_CLASS_ID_USB:
   38.49 +            return
   38.50 +
   38.51 +        (pci_list, cfg_list) = save_pci_conf_space([self.name])
   38.52 +
   38.53 +        self.pci_conf_write8(pos + PCI_USB_FLRCTRL, 1)
   38.54 +        time.sleep(0.010)
   38.55 +
   38.56 +        restore_pci_conf_space((pci_list, cfg_list))
   38.57 +
   38.58 +    def do_FLR_for_integrated_device(self):
   38.59 +        if not self.do_Dstate_transition():
   38.60 +            self.do_vendor_specific_FLR_method()
   38.61  
   38.62      def find_all_the_multi_functions(self):
   38.63          sysfs_mnt = find_sysfs_mnt()
   38.64 @@ -676,7 +707,7 @@ class PciDevice:
   38.65                  restore_pci_conf_space((pci_list, cfg_list))
   38.66              else:
   38.67                  if self.bus == 0:
   38.68 -                    self.do_Dstate_transition()
   38.69 +                    self.do_FLR_for_integrated_device()
   38.70                  else:
   38.71                      funcs = self.find_all_the_multi_functions()
   38.72                      self.devs_check_driver(funcs)
   38.73 @@ -697,7 +728,7 @@ class PciDevice:
   38.74                  restore_pci_conf_space((pci_list, cfg_list))
   38.75              else:
   38.76                  if self.bus == 0:
   38.77 -                    self.do_Dstate_transition()
   38.78 +                    self.do_FLR_for_integrated_device()
   38.79                  else:
   38.80                      devs = self.find_coassigned_devices(False)
   38.81                      # Remove the element 0 which is a bridge
    39.1 --- a/tools/python/xen/xend/XendConfig.py	Mon Aug 25 19:04:37 2008 +0900
    39.2 +++ b/tools/python/xen/xend/XendConfig.py	Mon Sep 01 16:59:43 2008 +0900
    39.3 @@ -1538,9 +1538,9 @@ class XendConfig(dict):
    39.4                      pci_dev_info[opt] = val
    39.5                  except TypeError:
    39.6                      pass
    39.7 -                # append uuid for each pci device.
    39.8 -                dpci_uuid = pci_dev_info.get('uuid', uuid.createString())
    39.9 -                pci_dev_info['uuid'] = dpci_uuid
   39.10 +            # append uuid for each pci device.
   39.11 +            dpci_uuid = pci_dev_info.get('uuid', uuid.createString())
   39.12 +            pci_dev_info['uuid'] = dpci_uuid
   39.13              pci_devs.append(pci_dev_info)
   39.14          dev_config['devs'] = pci_devs 
   39.15  
    40.1 --- a/tools/python/xen/xend/XendDomain.py	Mon Aug 25 19:04:37 2008 +0900
    40.2 +++ b/tools/python/xen/xend/XendDomain.py	Mon Sep 01 16:59:43 2008 +0900
    40.3 @@ -419,6 +419,8 @@ class XendDomain:
    40.4                  except VmError:
    40.5                      log.exception("Unable to recreate domain")
    40.6                      try:
    40.7 +                        xc.domain_pause(domid)
    40.8 +                        do_FLR(domid)
    40.9                          xc.domain_destroy(domid)
   40.10                      except:
   40.11                          log.exception("Hard destruction of domain failed: %d" %
   40.12 @@ -1255,6 +1257,8 @@ class XendDomain:
   40.13              val = dominfo.destroy()
   40.14          else:
   40.15              try:
   40.16 +                xc.domain_pause(int(domid))
   40.17 +                do_FLR(int(domid))
   40.18                  val = xc.domain_destroy(int(domid))
   40.19              except ValueError:
   40.20                  raise XendInvalidDomain(domid)
    41.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Mon Aug 25 19:04:37 2008 +0900
    41.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Mon Sep 01 16:59:43 2008 +0900
    41.3 @@ -287,6 +287,28 @@ def dom_get(dom):
    41.4          log.trace("domain_getinfo(%d) failed, ignoring: %s", dom, str(err))
    41.5      return None
    41.6  
    41.7 +def do_FLR(domid):
    41.8 +    from xen.xend.server.pciif import parse_pci_name, PciDevice
    41.9 +    path = '/local/domain/0/backend/pci/%u/0/' % domid
   41.10 +    num_devs = xstransact.Read(path + 'num_devs');
   41.11 +    if num_devs is None or num_devs == "":
   41.12 +        return;
   41.13 +
   41.14 +    num_devs = int(xstransact.Read(path + 'num_devs'));
   41.15 +
   41.16 +    dev_str_list = []
   41.17 +    for i in range(num_devs):
   41.18 +        dev_str = xstransact.Read(path + 'dev-%i' % i)
   41.19 +        dev_str_list = dev_str_list + [dev_str]
   41.20 +
   41.21 +    for dev_str in dev_str_list:
   41.22 +        (dom, b, d, f) = parse_pci_name(dev_str)
   41.23 +        try:
   41.24 +            dev = PciDevice(dom, b, d, f)
   41.25 +        except Exception, e:
   41.26 +            raise VmError("pci: failed to locate device and "+
   41.27 +                    "parse it's resources - "+str(e))
   41.28 +        dev.do_FLR()
   41.29  
   41.30  class XendDomainInfo:
   41.31      """An object represents a domain.
   41.32 @@ -2386,44 +2408,34 @@ class XendDomainInfo:
   41.33          if self.domid is None:
   41.34              return
   41.35  
   41.36 +        from xen.xend import XendDomain
   41.37          log.debug("XendDomainInfo.destroy: domid=%s", str(self.domid))
   41.38  
   41.39          paths = self._prepare_phantom_paths()
   41.40  
   41.41          self._cleanupVm()
   41.42          if self.dompath is not None:
   41.43 -            self.destroyDomain()
   41.44 +            try:
   41.45 +                xc.domain_destroy_hook(self.domid)
   41.46 +                xc.domain_pause(self.domid)
   41.47 +                do_FLR(self.domid)
   41.48 +                xc.domain_destroy(self.domid)
   41.49 +                for state in DOM_STATES_OLD:
   41.50 +                    self.info[state] = 0
   41.51 +                self._stateSet(DOM_STATE_HALTED)
   41.52 +            except:
   41.53 +                log.exception("XendDomainInfo.destroy: domain destruction failed.")
   41.54 +
   41.55 +            XendDomain.instance().remove_domain(self)
   41.56 +            self.cleanupDomain()
   41.57  
   41.58          self._cleanup_phantom_devs(paths)
   41.59  
   41.60          if "transient" in self.info["other_config"] \
   41.61             and bool(self.info["other_config"]["transient"]):
   41.62 -            from xen.xend import XendDomain
   41.63              XendDomain.instance().domain_delete_by_dominfo(self)
   41.64  
   41.65  
   41.66 -    def destroyDomain(self):
   41.67 -        log.debug("XendDomainInfo.destroyDomain(%s)", str(self.domid))
   41.68 -
   41.69 -        paths = self._prepare_phantom_paths()
   41.70 -
   41.71 -        try:
   41.72 -            if self.domid is not None:
   41.73 -                xc.domain_destroy_hook(self.domid)
   41.74 -                xc.domain_destroy(self.domid)
   41.75 -                for state in DOM_STATES_OLD:
   41.76 -                    self.info[state] = 0
   41.77 -                self._stateSet(DOM_STATE_HALTED)
   41.78 -        except:
   41.79 -            log.exception("XendDomainInfo.destroy: xc.domain_destroy failed.")
   41.80 -
   41.81 -        from xen.xend import XendDomain
   41.82 -        XendDomain.instance().remove_domain(self)
   41.83 -
   41.84 -        self.cleanupDomain()
   41.85 -        self._cleanup_phantom_devs(paths)
   41.86 -
   41.87 -
   41.88      def resetDomain(self):
   41.89          log.debug("XendDomainInfo.resetDomain(%s)", str(self.domid))
   41.90  
    42.1 --- a/tools/python/xen/xend/image.py	Mon Aug 25 19:04:37 2008 +0900
    42.2 +++ b/tools/python/xen/xend/image.py	Mon Sep 01 16:59:43 2008 +0900
    42.3 @@ -637,8 +637,9 @@ class LinuxImageHandler(ImageHandler):
    42.4          log.debug("ramdisk        = %s", self.ramdisk)
    42.5          log.debug("vcpus          = %d", self.vm.getVCpuCount())
    42.6          log.debug("features       = %s", self.vm.getFeatures())
    42.7 +        log.debug("flags          = %d", self.flags)
    42.8          if arch.type == "ia64":
    42.9 -            log.debug("vhpt          = %d", self.flags)
   42.10 +            log.debug("vhpt          = %d", self.vhpt)
   42.11  
   42.12          return xc.linux_build(domid          = self.vm.getDomid(),
   42.13                                memsize        = mem_mb,
    43.1 --- a/tools/python/xen/xend/server/DevController.py	Mon Aug 25 19:04:37 2008 +0900
    43.2 +++ b/tools/python/xen/xend/server/DevController.py	Mon Sep 01 16:59:43 2008 +0900
    43.3 @@ -223,12 +223,6 @@ class DevController:
    43.4          raise VmError('%s devices may not be reconfigured' % self.deviceClass)
    43.5  
    43.6  
    43.7 -    def cleanupDeviceOnDomainDestroy(self, devid):
    43.8 -        """ Some devices may need special cleanup when the guest domain
    43.9 -            is destroyed.
   43.10 -        """
   43.11 -        return
   43.12 -
   43.13      def destroyDevice(self, devid, force):
   43.14          """Destroy the specified device.
   43.15  
   43.16 @@ -245,8 +239,6 @@ class DevController:
   43.17  
   43.18          dev = self.convertToDeviceNumber(devid)
   43.19  
   43.20 -        self.cleanupDeviceOnDomainDestroy(dev)
   43.21 -
   43.22          # Modify online status /before/ updating state (latter is watched by
   43.23          # drivers, so this ordering avoids a race).
   43.24          self.writeBackend(dev, 'online', "0")
    44.1 --- a/tools/python/xen/xend/server/pciif.py	Mon Aug 25 19:04:37 2008 +0900
    44.2 +++ b/tools/python/xen/xend/server/pciif.py	Mon Sep 01 16:59:43 2008 +0900
    44.3 @@ -383,10 +383,10 @@ class PciController(DevController):
    44.4              if (dev.dev_type == DEV_TYPE_PCIe_ENDPOINT) and not dev.pcie_flr:
    44.5                  if dev.bus == 0:
    44.6                      # We cope with this case by using the Dstate transition
    44.7 -                    # method for now.
    44.8 +                    # method or some vendor specific methods for now.
    44.9                      err_msg = 'pci: %s: it is on bus 0, but has no PCIe' +\
   44.10                          ' FLR Capability. Will try the Dstate transition'+\
   44.11 -                        ' method if available.'
   44.12 +                        ' method or some vendor specific methods if available.'
   44.13                      log.warn(err_msg % dev.name)
   44.14                  else:
   44.15                      funcs = dev.find_all_the_multi_functions()
   44.16 @@ -404,10 +404,11 @@ class PciController(DevController):
   44.17                  if dev.bus == 0 or arch.type == "ia64":
   44.18                      if not dev.pci_af_flr:
   44.19                          # We cope with this case by using the Dstate transition
   44.20 -                        # method for now.
   44.21 +                        # method or some vendor specific methods for now.
   44.22                          err_msg = 'pci: %s: it is on bus 0, but has no PCI' +\
   44.23                              ' Advanced Capabilities for FLR. Will try the'+\
   44.24 -                            ' Dstate transition method if available.'
   44.25 +                            ' Dstate transition method or some vendor' +\
   44.26 +                            ' specific methods if available.'
   44.27                          log.warn(err_msg % dev.name)
   44.28                  else:
   44.29                      # All devices behind the uppermost PCI/PCI-X bridge must be\
   44.30 @@ -543,22 +544,6 @@ class PciController(DevController):
   44.31  
   44.32          return new_num_devs
   44.33  
   44.34 -    def cleanupDeviceOnDomainDestroy(self, devid):
   44.35 -        num_devs = int(self.readBackend(devid, 'num_devs'))
   44.36 -        dev_str_list = []
   44.37 -        for i in range(num_devs):
   44.38 -            dev_str = self.readBackend(devid, 'dev-%i' % i)
   44.39 -            dev_str_list = dev_str_list + [dev_str]
   44.40 -
   44.41 -        for dev_str in dev_str_list:
   44.42 -            (dom, b, d, f) = parse_pci_name(dev_str)
   44.43 -            try:
   44.44 -                dev = PciDevice(dom, b, d, f)
   44.45 -            except Exception, e:
   44.46 -                raise VmError("pci: failed to locate device and "+
   44.47 -                        "parse it's resources - "+str(e))
   44.48 -            dev.do_FLR()
   44.49 -
   44.50      def waitForBackend(self,devid):
   44.51          return (0, "ok - no hotplug")
   44.52  
    45.1 --- a/tools/xenmon/Makefile	Mon Aug 25 19:04:37 2008 +0900
    45.2 +++ b/tools/xenmon/Makefile	Mon Sep 01 16:59:43 2008 +0900
    45.3 @@ -42,6 +42,6 @@ clean:
    45.4  
    45.5  
    45.6  %: %.c Makefile
    45.7 -	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
    45.8 +	$(CC) $(CFLAGS) $< $(LDFLAGS) -o $@
    45.9  xentrace_%: %.c Makefile
   45.10 -	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
   45.11 +	$(CC) $(CFLAGS) $< $(LDFLAGS) -o $@
    46.1 --- a/xen/Makefile	Mon Aug 25 19:04:37 2008 +0900
    46.2 +++ b/xen/Makefile	Mon Sep 01 16:59:43 2008 +0900
    46.3 @@ -1,8 +1,8 @@
    46.4  # This is the correct place to edit the build version.
    46.5  # All other places this is stored (eg. compile.h) should be autogenerated.
    46.6  export XEN_VERSION       = 3
    46.7 -export XEN_SUBVERSION    = 3
    46.8 -export XEN_EXTRAVERSION ?= .0-rc8-pre$(XEN_VENDORVERSION)
    46.9 +export XEN_SUBVERSION    = 4
   46.10 +export XEN_EXTRAVERSION ?= -unstable$(XEN_VENDORVERSION)
   46.11  export XEN_FULLVERSION   = $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION)
   46.12  -include xen-version
   46.13  
   46.14 @@ -87,7 +87,7 @@ include/xen/compile.h: include/xen/compi
   46.15  	    -e 's/@@whoami@@/$(XEN_WHOAMI)/g' \
   46.16  	    -e 's/@@domain@@/$(XEN_DOMAIN)/g' \
   46.17  	    -e 's/@@hostname@@/$(shell hostname)/g' \
   46.18 -	    -e 's!@@compiler@@!$(shell $(CC) $(CFLAGS) -v 2>&1 | grep -i "gcc.*version")!g' \
   46.19 +	    -e 's!@@compiler@@!$(shell $(CC) $(CFLAGS) -v 2>&1 | tail -1)!g' \
   46.20  	    -e 's/@@version@@/$(XEN_VERSION)/g' \
   46.21  	    -e 's/@@subversion@@/$(XEN_SUBVERSION)/g' \
   46.22  	    -e 's/@@extraversion@@/$(XEN_EXTRAVERSION)/g' \
    47.1 --- a/xen/arch/ia64/xen/mm.c	Mon Aug 25 19:04:37 2008 +0900
    47.2 +++ b/xen/arch/ia64/xen/mm.c	Mon Sep 01 16:59:43 2008 +0900
    47.3 @@ -2698,6 +2698,20 @@ void put_page_type(struct page_info *pag
    47.4  }
    47.5  
    47.6  
    47.7 +static int get_page_from_pagenr(unsigned long page_nr, struct domain *d)
    47.8 +{
    47.9 +    struct page_info *page = mfn_to_page(page_nr);
   47.10 +
   47.11 +    if ( unlikely(!mfn_valid(page_nr)) || unlikely(!get_page(page, d)) )
   47.12 +    {
   47.13 +        MEM_LOG("Could not get page ref for pfn %lx", page_nr);
   47.14 +        return 0;
   47.15 +    }
   47.16 +
   47.17 +    return 1;
   47.18 +}
   47.19 +
   47.20 +
   47.21  int get_page_type(struct page_info *page, u32 type)
   47.22  {
   47.23      u64 nx, x, y = page->u.inuse.type_info;
   47.24 @@ -2792,6 +2806,8 @@ int memory_is_conventional_ram(paddr_t p
   47.25  long
   47.26  arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
   47.27  {
   47.28 +    struct page_info *page = NULL;
   47.29 +
   47.30      switch (op) {
   47.31      case XENMEM_add_to_physmap:
   47.32      {
   47.33 @@ -2836,11 +2852,21 @@ arch_memory_op(int op, XEN_GUEST_HANDLE(
   47.34  
   47.35              spin_unlock(&d->grant_table->lock);
   47.36              break;
   47.37 +        case XENMAPSPACE_mfn:
   47.38 +        {
   47.39 +            if ( get_page_from_pagenr(xatp.idx, d) ) {
   47.40 +                mfn = xatp.idx;
   47.41 +                page = mfn_to_page(mfn);
   47.42 +            }
   47.43 +            break;
   47.44 +        }
   47.45          default:
   47.46              break;
   47.47          }
   47.48  
   47.49          if (mfn == 0) {
   47.50 +            if ( page )
   47.51 +                put_page(page);
   47.52              rcu_unlock_domain(d);
   47.53              return -EINVAL;
   47.54          }
   47.55 @@ -2872,12 +2898,54 @@ arch_memory_op(int op, XEN_GUEST_HANDLE(
   47.56  
   47.57      out:
   47.58          domain_unlock(d);
   47.59 -        
   47.60 +
   47.61 +        if ( page )
   47.62 +            put_page(page);
   47.63 +
   47.64          rcu_unlock_domain(d);
   47.65  
   47.66          break;
   47.67      }
   47.68  
   47.69 +    case XENMEM_remove_from_physmap:
   47.70 +    {
   47.71 +        struct xen_remove_from_physmap xrfp;
   47.72 +        unsigned long mfn;
   47.73 +        struct domain *d;
   47.74 +
   47.75 +        if ( copy_from_guest(&xrfp, arg, 1) )
   47.76 +            return -EFAULT;
   47.77 +
   47.78 +        if ( xrfp.domid == DOMID_SELF )
   47.79 +        {
   47.80 +            d = rcu_lock_current_domain();
   47.81 +        }
   47.82 +        else
   47.83 +        {
   47.84 +            if ( (d = rcu_lock_domain_by_id(xrfp.domid)) == NULL )
   47.85 +                return -ESRCH;
   47.86 +            if ( !IS_PRIV_FOR(current->domain, d) )
   47.87 +            {
   47.88 +                rcu_unlock_domain(d);
   47.89 +                return -EPERM;
   47.90 +            }
   47.91 +        }
   47.92 +
   47.93 +        domain_lock(d);
   47.94 +
   47.95 +        mfn = gmfn_to_mfn(d, xrfp.gpfn);
   47.96 +
   47.97 +        if ( mfn_valid(mfn) )
   47.98 +            guest_physmap_remove_page(d, xrfp.gpfn, mfn, 0);
   47.99 +
  47.100 +        domain_unlock(d);
  47.101 +
  47.102 +        rcu_unlock_domain(d);
  47.103 +
  47.104 +        break;
  47.105 +    }
  47.106 +
  47.107 +
  47.108      case XENMEM_machine_memory_map:
  47.109      {
  47.110          struct xen_memory_map memmap;
    48.1 --- a/xen/arch/x86/acpi/power.c	Mon Aug 25 19:04:37 2008 +0900
    48.2 +++ b/xen/arch/x86/acpi/power.c	Mon Sep 01 16:59:43 2008 +0900
    48.3 @@ -24,6 +24,7 @@
    48.4  #include <xen/sched.h>
    48.5  #include <xen/domain.h>
    48.6  #include <xen/console.h>
    48.7 +#include <xen/iommu.h>
    48.8  #include <public/platform.h>
    48.9  #include <asm/tboot.h>
   48.10  
   48.11 @@ -41,6 +42,8 @@ void do_suspend_lowlevel(void);
   48.12  
   48.13  static int device_power_down(void)
   48.14  {
   48.15 +    iommu_suspend();
   48.16 +
   48.17      console_suspend();
   48.18  
   48.19      time_suspend();
   48.20 @@ -65,6 +68,8 @@ static void device_power_up(void)
   48.21      time_resume();
   48.22  
   48.23      console_resume();
   48.24 +
   48.25 +    iommu_resume();
   48.26  }
   48.27  
   48.28  static void freeze_domains(void)
    49.1 --- a/xen/arch/x86/cpu/amd.c	Mon Aug 25 19:04:37 2008 +0900
    49.2 +++ b/xen/arch/x86/cpu/amd.c	Mon Sep 01 16:59:43 2008 +0900
    49.3 @@ -10,10 +10,144 @@
    49.4  #include <asm/hvm/support.h>
    49.5  
    49.6  #include "cpu.h"
    49.7 +#include "amd.h"
    49.8  
    49.9  int start_svm(struct cpuinfo_x86 *c);
   49.10  
   49.11  /*
   49.12 + * Pre-canned values for overriding the CPUID features 
   49.13 + * and extended features masks.
   49.14 + *
   49.15 + * Currently supported processors:
   49.16 + * 
   49.17 + * "fam_0f_rev_c"
   49.18 + * "fam_0f_rev_d"
   49.19 + * "fam_0f_rev_e"
   49.20 + * "fam_0f_rev_f"
   49.21 + * "fam_0f_rev_g"
   49.22 + * "fam_10_rev_b"
   49.23 + * "fam_10_rev_c"
   49.24 + * "fam_11_rev_b"
   49.25 + */
   49.26 +static char opt_famrev[14];
   49.27 +string_param("cpuid_mask_cpu", opt_famrev);
   49.28 +
   49.29 +/* Finer-grained CPUID feature control. */
   49.30 +static unsigned int opt_cpuid_mask_ecx, opt_cpuid_mask_edx;
   49.31 +integer_param("cpuid_mask_ecx", opt_cpuid_mask_ecx);
   49.32 +integer_param("cpuid_mask_edx", opt_cpuid_mask_edx);
   49.33 +static unsigned int opt_cpuid_mask_ext_ecx, opt_cpuid_mask_ext_edx;
   49.34 +integer_param("cpuid_mask_ecx", opt_cpuid_mask_ext_ecx);
   49.35 +integer_param("cpuid_mask_edx", opt_cpuid_mask_ext_edx);
   49.36 +
   49.37 +static inline void wrmsr_amd(unsigned int index, unsigned int lo, 
   49.38 +		unsigned int hi)
   49.39 +{
   49.40 +	asm volatile (
   49.41 +		"wrmsr"
   49.42 +		: /* No outputs */
   49.43 +		: "c" (index), "a" (lo), 
   49.44 +		"d" (hi), "D" (0x9c5a203a)
   49.45 +	);
   49.46 +}
   49.47 +
   49.48 +/*
   49.49 + * Mask the features and extended features returned by CPUID.  Parameters are
   49.50 + * set from the boot line via two methods:
   49.51 + *
   49.52 + *   1) Specific processor revision string
   49.53 + *   2) User-defined masks
   49.54 + *
   49.55 + * The processor revision string parameter has precedene.
   49.56 + */
   49.57 +static void __devinit set_cpuidmask(struct cpuinfo_x86 *c)
   49.58 +{
   49.59 +	static unsigned int feat_ecx, feat_edx;
   49.60 +	static unsigned int extfeat_ecx, extfeat_edx;
   49.61 +	static enum { not_parsed, no_mask, set_mask } status;
   49.62 +
   49.63 +	if (status == no_mask)
   49.64 +		return;
   49.65 +
   49.66 +	if (status == set_mask)
   49.67 +		goto setmask;
   49.68 +
   49.69 +	ASSERT((status == not_parsed) && (smp_processor_id() == 0));
   49.70 +	status = no_mask;
   49.71 +
   49.72 +	if (opt_cpuid_mask_ecx | opt_cpuid_mask_edx |
   49.73 +	    opt_cpuid_mask_ext_ecx | opt_cpuid_mask_ext_edx) {
   49.74 +		feat_ecx = opt_cpuid_mask_ecx ? : ~0U;
   49.75 +		feat_edx = opt_cpuid_mask_edx ? : ~0U;
   49.76 +		extfeat_ecx = opt_cpuid_mask_ext_ecx ? : ~0U;
   49.77 +		extfeat_edx = opt_cpuid_mask_ext_edx ? : ~0U;
   49.78 +	} else if (*opt_famrev == '\0') {
   49.79 +		return;
   49.80 +	} else if (!strcmp(opt_famrev, "fam_0f_rev_c")) {
   49.81 +		feat_ecx = AMD_FEATURES_K8_REV_C_ECX;
   49.82 +		feat_edx = AMD_FEATURES_K8_REV_C_EDX;
   49.83 +		extfeat_ecx = AMD_EXTFEATURES_K8_REV_C_ECX;
   49.84 +		extfeat_edx = AMD_EXTFEATURES_K8_REV_C_EDX;
   49.85 +	} else if (!strcmp(opt_famrev, "fam_0f_rev_d")) {
   49.86 +		feat_ecx = AMD_FEATURES_K8_REV_D_ECX;
   49.87 +		feat_edx = AMD_FEATURES_K8_REV_D_EDX;
   49.88 +		extfeat_ecx = AMD_EXTFEATURES_K8_REV_D_ECX;
   49.89 +		extfeat_edx = AMD_EXTFEATURES_K8_REV_D_EDX;
   49.90 +	} else if (!strcmp(opt_famrev, "fam_0f_rev_e")) {
   49.91 +		feat_ecx = AMD_FEATURES_K8_REV_E_ECX;
   49.92 +		feat_edx = AMD_FEATURES_K8_REV_E_EDX;
   49.93 +		extfeat_ecx = AMD_EXTFEATURES_K8_REV_E_ECX;
   49.94 +		extfeat_edx = AMD_EXTFEATURES_K8_REV_E_EDX;
   49.95 +	} else if (!strcmp(opt_famrev, "fam_0f_rev_f")) {
   49.96 +		feat_ecx = AMD_FEATURES_K8_REV_F_ECX;
   49.97 +		feat_edx = AMD_FEATURES_K8_REV_F_EDX;
   49.98 +		extfeat_ecx = AMD_EXTFEATURES_K8_REV_F_ECX;
   49.99 +		extfeat_edx = AMD_EXTFEATURES_K8_REV_F_EDX;
  49.100 +	} else if (!strcmp(opt_famrev, "fam_0f_rev_g")) {
  49.101 +		feat_ecx = AMD_FEATURES_K8_REV_G_ECX;
  49.102 +		feat_edx = AMD_FEATURES_K8_REV_G_EDX;
  49.103 +		extfeat_ecx = AMD_EXTFEATURES_K8_REV_G_ECX;
  49.104 +		extfeat_edx = AMD_EXTFEATURES_K8_REV_G_EDX;
  49.105 +	} else if (!strcmp(opt_famrev, "fam_10_rev_b")) {
  49.106 +		feat_ecx = AMD_FEATURES_FAM10h_REV_B_ECX;
  49.107 +		feat_edx = AMD_FEATURES_FAM10h_REV_B_EDX;
  49.108 +		extfeat_ecx = AMD_EXTFEATURES_FAM10h_REV_B_ECX;
  49.109 +		extfeat_edx = AMD_EXTFEATURES_FAM10h_REV_B_EDX;
  49.110 +	} else if (!strcmp(opt_famrev, "fam_10_rev_c")) {
  49.111 +		feat_ecx = AMD_FEATURES_FAM10h_REV_C_ECX;
  49.112 +		feat_edx = AMD_FEATURES_FAM10h_REV_C_EDX;
  49.113 +		extfeat_ecx = AMD_EXTFEATURES_FAM10h_REV_C_ECX;
  49.114 +		extfeat_edx = AMD_EXTFEATURES_FAM10h_REV_C_EDX;
  49.115 +	} else if (!strcmp(opt_famrev, "fam_11_rev_b")) {
  49.116 +		feat_ecx = AMD_FEATURES_FAM11h_REV_B_ECX;
  49.117 +		feat_edx = AMD_FEATURES_FAM11h_REV_B_EDX;
  49.118 +		extfeat_ecx = AMD_EXTFEATURES_FAM11h_REV_B_ECX;
  49.119 +		extfeat_edx = AMD_EXTFEATURES_FAM11h_REV_B_EDX;
  49.120 +	} else {
  49.121 +		printk("Invalid processor string: %s\n", opt_famrev);
  49.122 +		printk("CPUID will not be masked\n");
  49.123 +		return;
  49.124 +	}
  49.125 +
  49.126 +	status = set_mask;
  49.127 +	printk("Writing CPUID feature mask ECX:EDX -> %08Xh:%08Xh\n", 
  49.128 +	       feat_ecx, feat_edx);
  49.129 +	printk("Writing CPUID extended feature mask ECX:EDX -> %08Xh:%08Xh\n", 
  49.130 +	       extfeat_ecx, extfeat_edx);
  49.131 +
  49.132 + setmask:
  49.133 +	/* FIXME check if processor supports CPUID masking */
  49.134 +	/* AMD processors prior to family 10h required a 32-bit password */
  49.135 +	if (c->x86 >= 0x10) {
  49.136 +		wrmsr(MSR_K8_FEATURE_MASK, feat_edx, feat_ecx);
  49.137 +		wrmsr(MSR_K8_EXT_FEATURE_MASK, extfeat_edx, extfeat_ecx);
  49.138 +	} else if (c->x86 == 0x0f) {
  49.139 +		wrmsr_amd(MSR_K8_FEATURE_MASK, feat_edx, feat_ecx);
  49.140 +		wrmsr_amd(MSR_K8_EXT_FEATURE_MASK, extfeat_edx, extfeat_ecx);
  49.141 +	}
  49.142 +}
  49.143 +
  49.144 +/*
  49.145   * amd_flush_filter={on,off}. Forcibly Enable or disable the TLB flush
  49.146   * filter on AMD 64-bit processors.
  49.147   */
  49.148 @@ -115,7 +249,7 @@ static void check_disable_c1e(unsigned i
  49.149  		on_each_cpu(disable_c1e, NULL, 1, 1);
  49.150  }
  49.151  
  49.152 -static void __init init_amd(struct cpuinfo_x86 *c)
  49.153 +static void __devinit init_amd(struct cpuinfo_x86 *c)
  49.154  {
  49.155  	u32 l, h;
  49.156  	int mbytes = num_physpages >> (20-PAGE_SHIFT);
  49.157 @@ -368,6 +502,8 @@ static void __init init_amd(struct cpuin
  49.158  	if ((smp_processor_id() == 1) && c1_ramping_may_cause_clock_drift(c))
  49.159  		disable_c1_ramping();
  49.160  
  49.161 +	set_cpuidmask(c);
  49.162 +
  49.163  	start_svm(c);
  49.164  }
  49.165  
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/xen/arch/x86/cpu/amd.h	Mon Sep 01 16:59:43 2008 +0900
    50.3 @@ -0,0 +1,103 @@
    50.4 +/*
    50.5 + * amd.h - AMD processor specific definitions
    50.6 + */
    50.7 +
    50.8 +#ifndef __AMD_H__
    50.9 +#define __AMD_H__
   50.10 +
   50.11 +#include <asm/cpufeature.h>
   50.12 +
   50.13 +/* CPUID masked for use by AMD-V Extended Migration */
   50.14 +
   50.15 +#define X86_FEATURE_BITPOS(_feature_) ((_feature_) % 32)
   50.16 +#define __bit(_x_) (1U << X86_FEATURE_BITPOS(_x_))
   50.17 +
   50.18 +/* Family 0Fh, Revision C */
   50.19 +#define AMD_FEATURES_K8_REV_C_ECX  0
   50.20 +#define AMD_FEATURES_K8_REV_C_EDX (					\
   50.21 +	__bit(X86_FEATURE_FPU)      | __bit(X86_FEATURE_VME)   |	\
   50.22 +	__bit(X86_FEATURE_DE)       | __bit(X86_FEATURE_PSE)   |	\
   50.23 +	__bit(X86_FEATURE_TSC)      | __bit(X86_FEATURE_MSR)   |	\
   50.24 +	__bit(X86_FEATURE_PAE)      | __bit(X86_FEATURE_MCE)   |	\
   50.25 +	__bit(X86_FEATURE_CX8)      | __bit(X86_FEATURE_APIC)  |	\
   50.26 +	__bit(X86_FEATURE_SEP)      | __bit(X86_FEATURE_MTRR)  |	\
   50.27 +	__bit(X86_FEATURE_PGE)      | __bit(X86_FEATURE_MCA)   | 	\
   50.28 +	__bit(X86_FEATURE_CMOV)     | __bit(X86_FEATURE_PAT)   |	\
   50.29 +	__bit(X86_FEATURE_PSE36)    | __bit(X86_FEATURE_CLFLSH)|	\
   50.30 +	__bit(X86_FEATURE_MMX)      | __bit(X86_FEATURE_FXSR)  | 	\
   50.31 +	__bit(X86_FEATURE_XMM)      | __bit(X86_FEATURE_XMM2))
   50.32 +#define AMD_EXTFEATURES_K8_REV_C_ECX  0 
   50.33 +#define AMD_EXTFEATURES_K8_REV_C_EDX  (					\
   50.34 +	__bit(X86_FEATURE_FPU)      | __bit(X86_FEATURE_VME)   |	\
   50.35 +	__bit(X86_FEATURE_DE)       | __bit(X86_FEATURE_PSE)   |	\
   50.36 +	__bit(X86_FEATURE_TSC)      | __bit(X86_FEATURE_MSR)   |	\
   50.37 +	__bit(X86_FEATURE_PAE)      | __bit(X86_FEATURE_MCE)   |	\
   50.38 +	__bit(X86_FEATURE_CX8)      | __bit(X86_FEATURE_APIC)  |	\
   50.39 +	__bit(X86_FEATURE_SYSCALL)  | __bit(X86_FEATURE_MTRR)  |	\
   50.40 +	__bit(X86_FEATURE_PGE)      | __bit(X86_FEATURE_MCA)   |	\
   50.41 +	__bit(X86_FEATURE_CMOV)     | __bit(X86_FEATURE_PAT)   |	\
   50.42 +	__bit(X86_FEATURE_PSE36)    | __bit(X86_FEATURE_NX)    |	\
   50.43 +	__bit(X86_FEATURE_MMXEXT)   | __bit(X86_FEATURE_MMX)   |	\
   50.44 +	__bit(X86_FEATURE_FXSR)     | __bit(X86_FEATURE_LM)    |	\
   50.45 +	__bit(X86_FEATURE_3DNOWEXT) | __bit(X86_FEATURE_3DNOW))
   50.46 +
   50.47 +/* Family 0Fh, Revision D */
   50.48 +#define AMD_FEATURES_K8_REV_D_ECX         AMD_FEATURES_K8_REV_C_ECX
   50.49 +#define AMD_FEATURES_K8_REV_D_EDX         AMD_FEATURES_K8_REV_C_EDX
   50.50 +#define AMD_EXTFEATURES_K8_REV_D_ECX     (AMD_EXTFEATURES_K8_REV_C_ECX |\
   50.51 +	__bit(X86_FEATURE_LAHF_LM))
   50.52 +#define AMD_EXTFEATURES_K8_REV_D_EDX     (AMD_EXTFEATURES_K8_REV_C_EDX |\
   50.53 +	__bit(X86_FEATURE_FFXSR))
   50.54 +
   50.55 +/* Family 0Fh, Revision E */
   50.56 +#define AMD_FEATURES_K8_REV_E_ECX        (AMD_FEATURES_K8_REV_D_ECX |	\
   50.57 +	__bit(X86_FEATURE_XMM3))
   50.58 +#define AMD_FEATURES_K8_REV_E_EDX        (AMD_FEATURES_K8_REV_D_EDX | 	\
   50.59 +	__bit(X86_FEATURE_HT))
   50.60 +#define AMD_EXTFEATURES_K8_REV_E_ECX     (AMD_EXTFEATURES_K8_REV_D_ECX |\
   50.61 +	__bit(X86_FEATURE_CMP_LEGACY)) 
   50.62 +#define AMD_EXTFEATURES_K8_REV_E_EDX      AMD_EXTFEATURES_K8_REV_D_EDX
   50.63 +
   50.64 +/* Family 0Fh, Revision F */
   50.65 +#define AMD_FEATURES_K8_REV_F_ECX        (AMD_FEATURES_K8_REV_E_ECX | 	\
   50.66 +	__bit(X86_FEATURE_CX16))
   50.67 +#define AMD_FEATURES_K8_REV_F_EDX         AMD_FEATURES_K8_REV_E_EDX
   50.68 +#define AMD_EXTFEATURES_K8_REV_F_ECX     (AMD_EXTFEATURES_K8_REV_E_ECX |\
   50.69 +	__bit(X86_FEATURE_SVME) | __bit(X86_FEATURE_EXTAPICSPACE) |	\
   50.70 +	__bit(X86_FEATURE_ALTMOVCR))
   50.71 +#define AMD_EXTFEATURES_K8_REV_F_EDX     (AMD_EXTFEATURES_K8_REV_E_EDX |\
   50.72 +	__bit(X86_FEATURE_RDTSCP))
   50.73 +
   50.74 +/* Family 0Fh, Revision G */
   50.75 +#define AMD_FEATURES_K8_REV_G_ECX         AMD_FEATURES_K8_REV_F_ECX
   50.76 +#define AMD_FEATURES_K8_REV_G_EDX         AMD_FEATURES_K8_REV_F_EDX
   50.77 +#define AMD_EXTFEATURES_K8_REV_G_ECX     (AMD_EXTFEATURES_K8_REV_F_ECX |\
   50.78 +	__bit(X86_FEATURE_3DNOWPF))
   50.79 +#define AMD_EXTFEATURES_K8_REV_G_EDX      AMD_EXTFEATURES_K8_REV_F_EDX
   50.80 +
   50.81 +/* Family 10h, Revision B */
   50.82 +#define AMD_FEATURES_FAM10h_REV_B_ECX    (AMD_FEATURES_K8_REV_F_ECX | 	\
   50.83 +	__bit(X86_FEATURE_POPCNT) | __bit(X86_FEATURE_MWAIT))
   50.84 +#define AMD_FEATURES_FAM10h_REV_B_EDX     AMD_FEATURES_K8_REV_F_EDX
   50.85 +#define AMD_EXTFEATURES_FAM10h_REV_B_ECX (AMD_EXTFEATURES_K8_REV_F_ECX |\
   50.86 +	__bit(X86_FEATURE_ABM) | __bit(X86_FEATURE_SSE4A) | 		\
   50.87 +	__bit(X86_FEATURE_MISALIGNSSE) | __bit(X86_FEATURE_OSVW) | 	\
   50.88 +	__bit(X86_FEATURE_IBS))
   50.89 +#define AMD_EXTFEATURES_FAM10h_REV_B_EDX (AMD_EXTFEATURES_K8_REV_F_EDX |\
   50.90 +	__bit(X86_FEATURE_PAGE1GB))
   50.91 +
   50.92 +/* Family 10h, Revision C */
   50.93 +#define AMD_FEATURES_FAM10h_REV_C_ECX     AMD_FEATURES_FAM10h_REV_B_ECX
   50.94 +#define AMD_FEATURES_FAM10h_REV_C_EDX     AMD_FEATURES_FAM10h_REV_B_EDX
   50.95 +#define AMD_EXTFEATURES_FAM10h_REV_C_ECX (AMD_EXTFEATURES_FAM10h_REV_B_ECX |\
   50.96 +	__bit(X86_FEATURE_SKINIT) | __bit(X86_FEATURE_WDT))
   50.97 +#define AMD_EXTFEATURES_FAM10h_REV_C_EDX  AMD_EXTFEATURES_FAM10h_REV_B_EDX
   50.98 +
   50.99 +/* Family 11h, Revision B */
  50.100 +#define AMD_FEATURES_FAM11h_REV_B_ECX     AMD_FEATURES_K8_REV_G_ECX
  50.101 +#define AMD_FEATURES_FAM11h_REV_B_EDX     AMD_FEATURES_K8_REV_G_EDX
  50.102 +#define AMD_EXTFEATURES_FAM11h_REV_B_ECX (AMD_EXTFEATURES_K8_REV_G_ECX |\
  50.103 +	__bit(X86_FEATURE_SKINIT))
  50.104 +#define AMD_EXTFEATURES_FAM11h_REV_B_EDX  AMD_EXTFEATURES_K8_REV_G_EDX
  50.105 +
  50.106 +#endif /* __AMD_H__ */
    51.1 --- a/xen/arch/x86/hvm/emulate.c	Mon Aug 25 19:04:37 2008 +0900
    51.2 +++ b/xen/arch/x86/hvm/emulate.c	Mon Sep 01 16:59:43 2008 +0900
    51.3 @@ -571,11 +571,12 @@ static int hvmemul_rep_movs(
    51.4  {
    51.5      struct hvm_emulate_ctxt *hvmemul_ctxt =
    51.6          container_of(ctxt, struct hvm_emulate_ctxt, ctxt);
    51.7 -    unsigned long saddr, daddr;
    51.8 +    unsigned long saddr, daddr, bytes;
    51.9      paddr_t sgpa, dgpa;
   51.10      uint32_t pfec = PFEC_page_present;
   51.11      p2m_type_t p2mt;
   51.12 -    int rc;
   51.13 +    int rc, df = !!(ctxt->regs->eflags & X86_EFLAGS_DF);
   51.14 +    char *buf;
   51.15  
   51.16      rc = hvmemul_virtual_to_linear(
   51.17          src_seg, src_offset, bytes_per_rep, reps, hvm_access_read,
   51.18 @@ -606,15 +607,56 @@ static int hvmemul_rep_movs(
   51.19      (void)gfn_to_mfn_current(sgpa >> PAGE_SHIFT, &p2mt);
   51.20      if ( !p2m_is_ram(p2mt) )
   51.21          return hvmemul_do_mmio(
   51.22 -            sgpa, reps, bytes_per_rep, dgpa, IOREQ_READ,
   51.23 -            !!(ctxt->regs->eflags & X86_EFLAGS_DF), NULL);
   51.24 +            sgpa, reps, bytes_per_rep, dgpa, IOREQ_READ, df, NULL);
   51.25  
   51.26      (void)gfn_to_mfn_current(dgpa >> PAGE_SHIFT, &p2mt);
   51.27 -    if ( p2m_is_ram(p2mt) )
   51.28 +    if ( !p2m_is_ram(p2mt) )
   51.29 +        return hvmemul_do_mmio(
   51.30 +            dgpa, reps, bytes_per_rep, sgpa, IOREQ_WRITE, df, NULL);
   51.31 +
   51.32 +    /* RAM-to-RAM copy: emulate as equivalent of memmove(dgpa, sgpa, bytes). */
   51.33 +    bytes = *reps * bytes_per_rep;
   51.34 +
   51.35 +    /* Adjust source address for reverse copy. */
   51.36 +    if ( df )
   51.37 +        sgpa -= bytes - bytes_per_rep;
   51.38 +
   51.39 +    /*
   51.40 +     * Will first iteration copy fall within source range? If not then entire
   51.41 +     * copy does not corrupt itself. If so, then this is more complex than
   51.42 +     * can be emulated by a source-to-buffer-to-destination block copy.
   51.43 +     */
   51.44 +    if ( ((dgpa + bytes_per_rep) > sgpa) && (dgpa < (sgpa + bytes)) )
   51.45          return X86EMUL_UNHANDLEABLE;
   51.46 -    return hvmemul_do_mmio(
   51.47 -        dgpa, reps, bytes_per_rep, sgpa, IOREQ_WRITE,
   51.48 -        !!(ctxt->regs->eflags & X86_EFLAGS_DF), NULL);
   51.49 +
   51.50 +    /* Adjust destination address for reverse copy. */
   51.51 +    if ( df )
   51.52 +        dgpa -= bytes - bytes_per_rep;
   51.53 +
   51.54 +    /* Allocate temporary buffer. Fall back to slow emulation if this fails. */
   51.55 +    buf = xmalloc_bytes(bytes);
   51.56 +    if ( buf == NULL )
   51.57 +        return X86EMUL_UNHANDLEABLE;
   51.58 +
   51.59 +    /*
   51.60 +     * We do a modicum of checking here, just for paranoia's sake and to
   51.61 +     * definitely avoid copying an unitialised buffer into guest address space.
   51.62 +     */
   51.63 +    rc = hvm_copy_from_guest_phys(buf, sgpa, bytes);
   51.64 +    if ( rc == HVMCOPY_okay )
   51.65 +        rc = hvm_copy_to_guest_phys(dgpa, buf, bytes);
   51.66 +
   51.67 +    xfree(buf);
   51.68 +
   51.69 +    if ( rc != HVMCOPY_okay )
   51.70 +    {
   51.71 +        gdprintk(XENLOG_WARNING, "Failed memory-to-memory REP MOVS: sgpa=%"
   51.72 +                 PRIpaddr" dgpa=%"PRIpaddr" reps=%lu bytes_per_rep=%u\n",
   51.73 +                 sgpa, dgpa, *reps, bytes_per_rep);
   51.74 +        return X86EMUL_UNHANDLEABLE;
   51.75 +    }
   51.76 +
   51.77 +    return X86EMUL_OKAY;
   51.78  }
   51.79  
   51.80  static int hvmemul_read_segment(
    52.1 --- a/xen/arch/x86/irq.c	Mon Aug 25 19:04:37 2008 +0900
    52.2 +++ b/xen/arch/x86/irq.c	Mon Sep 01 16:59:43 2008 +0900
    52.3 @@ -63,7 +63,9 @@ asmlinkage void do_IRQ(struct cpu_user_r
    52.4  
    52.5      if ( likely(desc->status & IRQ_GUEST) )
    52.6      {
    52.7 +        irq_enter();
    52.8          __do_IRQ_guest(vector);
    52.9 +        irq_exit();
   52.10          spin_unlock(&desc->lock);
   52.11          return;
   52.12      }
    53.1 --- a/xen/arch/x86/microcode.c	Mon Aug 25 19:04:37 2008 +0900
    53.2 +++ b/xen/arch/x86/microcode.c	Mon Sep 01 16:59:43 2008 +0900
    53.3 @@ -124,7 +124,7 @@ static DEFINE_SPINLOCK(microcode_update_
    53.4  /* no concurrent ->write()s are allowed on /dev/cpu/microcode */
    53.5  static DEFINE_MUTEX(microcode_mutex);
    53.6  
    53.7 -static void __user *user_buffer;	/* user area microcode data buffer */
    53.8 +static const void __user *user_buffer;	/* user area microcode data buffer */
    53.9  static unsigned int user_buffer_size;	/* it's size */
   53.10  
   53.11  typedef enum mc_error_code {
   53.12 @@ -455,7 +455,7 @@ out:
   53.13  	return error;
   53.14  }
   53.15  
   53.16 -int microcode_update(XEN_GUEST_HANDLE(void) buf, unsigned long len)
   53.17 +int microcode_update(XEN_GUEST_HANDLE(const_void) buf, unsigned long len)
   53.18  {
   53.19  	int ret;
   53.20  
    54.1 --- a/xen/arch/x86/mm.c	Mon Aug 25 19:04:37 2008 +0900
    54.2 +++ b/xen/arch/x86/mm.c	Mon Sep 01 16:59:43 2008 +0900
    54.3 @@ -3339,6 +3339,7 @@ DEFINE_XEN_GUEST_HANDLE(e820entry_t);
    54.4  
    54.5  long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
    54.6  {
    54.7 +    struct page_info *page = NULL;
    54.8      switch ( op )
    54.9      {
   54.10      case XENMEM_add_to_physmap:
   54.11 @@ -3389,12 +3390,22 @@ long arch_memory_op(int op, XEN_GUEST_HA
   54.12  
   54.13              spin_unlock(&d->grant_table->lock);
   54.14              break;
   54.15 +        case XENMAPSPACE_mfn:
   54.16 +        {
   54.17 +            if ( get_page_from_pagenr(xatp.idx, d) ) {
   54.18 +                mfn = xatp.idx;
   54.19 +                page = mfn_to_page(mfn);
   54.20 +            }
   54.21 +            break;
   54.22 +        }
   54.23          default:
   54.24              break;
   54.25          }
   54.26  
   54.27          if ( !paging_mode_translate(d) || (mfn == 0) )
   54.28          {
   54.29 +            if ( page )
   54.30 +                put_page(page);
   54.31              rcu_unlock_domain(d);
   54.32              return -EINVAL;
   54.33          }
   54.34 @@ -3423,6 +3434,53 @@ long arch_memory_op(int op, XEN_GUEST_HA
   54.35  
   54.36          domain_unlock(d);
   54.37  
   54.38 +        if ( page )
   54.39 +            put_page(page);
   54.40 +
   54.41 +        rcu_unlock_domain(d);
   54.42 +
   54.43 +        break;
   54.44 +    }
   54.45 +
   54.46 +    case XENMEM_remove_from_physmap:
   54.47 +    {
   54.48 +        struct xen_remove_from_physmap xrfp;
   54.49 +        unsigned long mfn;
   54.50 +        struct domain *d;
   54.51 +
   54.52 +        if ( copy_from_guest(&xrfp, arg, 1) )
   54.53 +            return -EFAULT;
   54.54 +
   54.55 +        if ( xrfp.domid == DOMID_SELF )
   54.56 +        {
   54.57 +            d = rcu_lock_current_domain();
   54.58 +        }
   54.59 +        else
   54.60 +        {
   54.61 +            if ( (d = rcu_lock_domain_by_id(xrfp.domid)) == NULL )
   54.62 +                return -ESRCH;
   54.63 +            if ( !IS_PRIV_FOR(current->domain, d) )
   54.64 +            {
   54.65 +                rcu_unlock_domain(d);
   54.66 +                return -EPERM;
   54.67 +            }
   54.68 +        }
   54.69 +
   54.70 +        if ( xsm_remove_from_physmap(current->domain, d) )
   54.71 +        {
   54.72 +            rcu_unlock_domain(d);
   54.73 +            return -EPERM;
   54.74 +        }
   54.75 +
   54.76 +        domain_lock(d);
   54.77 +
   54.78 +        mfn = gmfn_to_mfn(d, xrfp.gpfn);
   54.79 +
   54.80 +        if ( mfn_valid(mfn) )
   54.81 +            guest_physmap_remove_page(d, xrfp.gpfn, mfn, 0);
   54.82 +
   54.83 +        domain_unlock(d);
   54.84 +
   54.85          rcu_unlock_domain(d);
   54.86  
   54.87          break;
    55.1 --- a/xen/arch/x86/platform_hypercall.c	Mon Aug 25 19:04:37 2008 +0900
    55.2 +++ b/xen/arch/x86/platform_hypercall.c	Mon Sep 01 16:59:43 2008 +0900
    55.3 @@ -147,8 +147,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
    55.4  
    55.5      case XENPF_microcode_update:
    55.6      {
    55.7 -        extern int microcode_update(XEN_GUEST_HANDLE(void), unsigned long len);
    55.8 -        XEN_GUEST_HANDLE(void) data;
    55.9 +        XEN_GUEST_HANDLE(const_void) data;
   55.10  
   55.11          ret = xsm_microcode();
   55.12          if ( ret )
    56.1 --- a/xen/arch/x86/time.c	Mon Aug 25 19:04:37 2008 +0900
    56.2 +++ b/xen/arch/x86/time.c	Mon Sep 01 16:59:43 2008 +0900
    56.3 @@ -840,12 +840,11 @@ struct cpu_calibration {
    56.4      u64 local_tsc_stamp;
    56.5      s_time_t stime_local_stamp;
    56.6      s_time_t stime_master_stamp;
    56.7 -    struct timer softirq_callback;
    56.8  };
    56.9  static DEFINE_PER_CPU(struct cpu_calibration, cpu_calibration);
   56.10  
   56.11  /* Softirq handler for per-CPU time calibration. */
   56.12 -static void local_time_calibration(void *unused)
   56.13 +static void local_time_calibration(void)
   56.14  {
   56.15      struct cpu_time *t = &this_cpu(cpu_time);
   56.16      struct cpu_calibration *c = &this_cpu(cpu_calibration);
   56.17 @@ -1004,13 +1003,12 @@ static void time_calibration_rendezvous(
   56.18      struct cpu_calibration *c = &this_cpu(cpu_calibration);
   56.19      struct calibration_rendezvous *r = _r;
   56.20  
   56.21 -    local_irq_disable();
   56.22 -
   56.23      if ( smp_processor_id() == 0 )
   56.24      {
   56.25          while ( atomic_read(&r->nr_cpus) != (total_cpus - 1) )
   56.26              cpu_relax();
   56.27          r->master_stime = read_platform_stime();
   56.28 +        mb(); /* write r->master_stime /then/ signal */
   56.29          atomic_inc(&r->nr_cpus);
   56.30      }
   56.31      else
   56.32 @@ -1018,16 +1016,14 @@ static void time_calibration_rendezvous(
   56.33          atomic_inc(&r->nr_cpus);
   56.34          while ( atomic_read(&r->nr_cpus) != total_cpus )
   56.35              cpu_relax();
   56.36 +        mb(); /* receive signal /then/ read r->master_stime */
   56.37      }
   56.38  
   56.39      rdtscll(c->local_tsc_stamp);
   56.40      c->stime_local_stamp = get_s_time();
   56.41      c->stime_master_stamp = r->master_stime;
   56.42  
   56.43 -    local_irq_enable();
   56.44 -
   56.45 -    /* Callback in softirq context as soon as possible. */
   56.46 -    set_timer(&c->softirq_callback, c->stime_local_stamp);
   56.47 +    raise_softirq(TIME_CALIBRATE_SOFTIRQ);
   56.48  }
   56.49  
   56.50  static void time_calibration(void *unused)
   56.51 @@ -1036,6 +1032,7 @@ static void time_calibration(void *unuse
   56.52          .nr_cpus = ATOMIC_INIT(0)
   56.53      };
   56.54  
   56.55 +    /* @wait=1 because we must wait for all cpus before freeing @r. */
   56.56      on_each_cpu(time_calibration_rendezvous, &r, 0, 1);
   56.57  }
   56.58  
   56.59 @@ -1053,9 +1050,6 @@ void init_percpu_time(void)
   56.60      t->stime_master_stamp = now;
   56.61      t->stime_local_stamp  = now;
   56.62  
   56.63 -    init_timer(&this_cpu(cpu_calibration).softirq_callback,
   56.64 -               local_time_calibration, NULL, smp_processor_id());
   56.65 -
   56.66      if ( smp_processor_id() == 0 )
   56.67      {
   56.68          init_timer(&calibration_timer, time_calibration, NULL, 0);
   56.69 @@ -1073,6 +1067,8 @@ int __init init_xen_time(void)
   56.70      if ( cpuid_edx(0x80000007) & (1u<<8) )
   56.71          tsc_invariant = 1;
   56.72  
   56.73 +    open_softirq(TIME_CALIBRATE_SOFTIRQ, local_time_calibration);
   56.74 +
   56.75      init_percpu_time();
   56.76  
   56.77      stime_platform_stamp = 0;
   56.78 @@ -1180,7 +1176,7 @@ int time_suspend(void)
   56.79      }
   56.80  
   56.81      /* Better to cancel calibration timer for accuracy. */
   56.82 -    kill_timer(&this_cpu(cpu_calibration).softirq_callback);
   56.83 +    clear_bit(TIME_CALIBRATE_SOFTIRQ, &softirq_pending(smp_processor_id()));
   56.84  
   56.85      return 0;
   56.86  }
    57.1 --- a/xen/arch/x86/x86_64/compat/mm.c	Mon Aug 25 19:04:37 2008 +0900
    57.2 +++ b/xen/arch/x86/x86_64/compat/mm.c	Mon Sep 01 16:59:43 2008 +0900
    57.3 @@ -69,6 +69,20 @@ int compat_arch_memory_op(int op, XEN_GU
    57.4          break;
    57.5      }
    57.6  
    57.7 +    case XENMEM_remove_from_physmap:
    57.8 +    {
    57.9 +        struct compat_remove_from_physmap cmp;
   57.10 +        struct xen_remove_from_physmap *nat = (void *)COMPAT_ARG_XLAT_VIRT_BASE;
   57.11 +
   57.12 +        if ( copy_from_guest(&cmp, arg, 1) )
   57.13 +            return -EFAULT;
   57.14 +
   57.15 +        XLAT_remove_from_physmap(nat, &cmp);
   57.16 +        rc = arch_memory_op(op, guest_handle_from_ptr(nat, void));
   57.17 +
   57.18 +        break;
   57.19 +    }
   57.20 +
   57.21      case XENMEM_set_memory_map:
   57.22      {
   57.23          struct compat_foreign_memory_map cmp;
    58.1 --- a/xen/common/softirq.c	Mon Aug 25 19:04:37 2008 +0900
    58.2 +++ b/xen/common/softirq.c	Mon Sep 01 16:59:43 2008 +0900
    58.3 @@ -49,6 +49,7 @@ asmlinkage void do_softirq(void)
    58.4  
    58.5  void open_softirq(int nr, softirq_handler handler)
    58.6  {
    58.7 +    ASSERT(nr < NR_SOFTIRQS);
    58.8      softirq_handlers[nr] = handler;
    58.9  }
   58.10  
    59.1 --- a/xen/common/timer.c	Mon Aug 25 19:04:37 2008 +0900
    59.2 +++ b/xen/common/timer.c	Mon Sep 01 16:59:43 2008 +0900
    59.3 @@ -30,6 +30,7 @@
    59.4  struct timers {
    59.5      spinlock_t     lock;
    59.6      struct timer **heap;
    59.7 +    struct timer  *list;
    59.8      struct timer  *running;
    59.9  } __cacheline_aligned;
   59.10  
   59.11 @@ -86,13 +87,11 @@ static void up_heap(struct timer **heap,
   59.12  
   59.13  
   59.14  /* Delete @t from @heap. Return TRUE if new top of heap. */
   59.15 -static int remove_entry(struct timer **heap, struct timer *t)
   59.16 +static int remove_from_heap(struct timer **heap, struct timer *t)
   59.17  {
   59.18      int sz = GET_HEAP_SIZE(heap);
   59.19      int pos = t->heap_offset;
   59.20  
   59.21 -    t->heap_offset = 0;
   59.22 -
   59.23      if ( unlikely(pos == sz) )
   59.24      {
   59.25          SET_HEAP_SIZE(heap, sz-1);
   59.26 @@ -115,7 +114,7 @@ static int remove_entry(struct timer **h
   59.27  
   59.28  
   59.29  /* Add new entry @t to @heap. Return TRUE if new top of heap. */
   59.30 -static int add_entry(struct timer ***pheap, struct timer *t)
   59.31 +static int add_to_heap(struct timer ***pheap, struct timer *t)
   59.32  {
   59.33      struct timer **heap = *pheap;
   59.34      int sz = GET_HEAP_SIZE(heap);
   59.35 @@ -126,8 +125,11 @@ static int add_entry(struct timer ***phe
   59.36          /* old_limit == (2^n)-1; new_limit == (2^(n+4))-1 */
   59.37          int old_limit = GET_HEAP_LIMIT(heap);
   59.38          int new_limit = ((old_limit + 1) << 4) - 1;
   59.39 +        if ( in_irq() )
   59.40 +            goto out;
   59.41          heap = xmalloc_array(struct timer *, new_limit + 1);
   59.42 -        BUG_ON(heap == NULL);
   59.43 +        if ( heap == NULL )
   59.44 +            goto out;
   59.45          memcpy(heap, *pheap, (old_limit + 1) * sizeof(*heap));
   59.46          SET_HEAP_LIMIT(heap, new_limit);
   59.47          if ( old_limit != 0 )
   59.48 @@ -139,26 +141,95 @@ static int add_entry(struct timer ***phe
   59.49      heap[sz] = t;
   59.50      t->heap_offset = sz;
   59.51      up_heap(heap, sz);
   59.52 + out:
   59.53      return (t->heap_offset == 1);
   59.54  }
   59.55  
   59.56  
   59.57  /****************************************************************************
   59.58 + * LINKED LIST OPERATIONS.
   59.59 + */
   59.60 +
   59.61 +static int remove_from_list(struct timer **pprev, struct timer *t)
   59.62 +{
   59.63 +    struct timer *curr, **_pprev = pprev;
   59.64 +
   59.65 +    while ( (curr = *_pprev) != t )
   59.66 +        _pprev = &curr->list_next;
   59.67 +
   59.68 +    *_pprev = t->list_next;
   59.69 +
   59.70 +    return (_pprev == pprev);
   59.71 +}
   59.72 +
   59.73 +static int add_to_list(struct timer **pprev, struct timer *t)
   59.74 +{
   59.75 +    struct timer *curr, **_pprev = pprev;
   59.76 +
   59.77 +    while ( ((curr = *_pprev) != NULL) && (curr->expires <= t->expires) )
   59.78 +        _pprev = &curr->list_next;
   59.79 +
   59.80 +    t->list_next = curr;
   59.81 +    *_pprev = t;
   59.82 +
   59.83 +    return (_pprev == pprev);
   59.84 +}
   59.85 +
   59.86 +
   59.87 +/****************************************************************************
   59.88   * TIMER OPERATIONS.
   59.89   */
   59.90  
   59.91 +static int remove_entry(struct timers *timers, struct timer *t)
   59.92 +{
   59.93 +    int rc;
   59.94 +
   59.95 +    switch ( t->status )
   59.96 +    {
   59.97 +    case TIMER_STATUS_in_heap:
   59.98 +        rc = remove_from_heap(timers->heap, t);
   59.99 +        break;
  59.100 +    case TIMER_STATUS_in_list:
  59.101 +        rc = remove_from_list(&timers->list, t);
  59.102 +        break;
  59.103 +    default:
  59.104 +        rc = 0;
  59.105 +        BUG();
  59.106 +    }
  59.107 +
  59.108 +    t->status = TIMER_STATUS_inactive;
  59.109 +    return rc;
  59.110 +}
  59.111 +
  59.112 +static int add_entry(struct timers *timers, struct timer *t)
  59.113 +{
  59.114 +    int rc;
  59.115 +
  59.116 +    ASSERT(t->status == TIMER_STATUS_inactive);
  59.117 +
  59.118 +    /* Try to add to heap. t->heap_offset indicates whether we succeed. */
  59.119 +    t->heap_offset = 0;
  59.120 +    t->status = TIMER_STATUS_in_heap;
  59.121 +    rc = add_to_heap(&timers->heap, t);
  59.122 +    if ( t->heap_offset != 0 )
  59.123 +        return rc;
  59.124 +
  59.125 +    /* Fall back to adding to the slower linked list. */
  59.126 +    t->status = TIMER_STATUS_in_list;
  59.127 +    return add_to_list(&timers->list, t);
  59.128 +}
  59.129 +
  59.130  static inline void __add_timer(struct timer *timer)
  59.131  {
  59.132      int cpu = timer->cpu;
  59.133 -    if ( add_entry(&per_cpu(timers, cpu).heap, timer) )
  59.134 +    if ( add_entry(&per_cpu(timers, cpu), timer) )
  59.135          cpu_raise_softirq(cpu, TIMER_SOFTIRQ);
  59.136  }
  59.137  
  59.138 -
  59.139  static inline void __stop_timer(struct timer *timer)
  59.140  {
  59.141      int cpu = timer->cpu;
  59.142 -    if ( remove_entry(per_cpu(timers, cpu).heap, timer) )
  59.143 +    if ( remove_entry(&per_cpu(timers, cpu), timer) )
  59.144          cpu_raise_softirq(cpu, TIMER_SOFTIRQ);
  59.145  }
  59.146  
  59.147 @@ -203,7 +274,7 @@ void set_timer(struct timer *timer, s_ti
  59.148  
  59.149      timer->expires = expires;
  59.150  
  59.151 -    if ( likely(!timer->killed) )
  59.152 +    if ( likely(timer->status != TIMER_STATUS_killed) )
  59.153          __add_timer(timer);
  59.154  
  59.155      timer_unlock_irqrestore(timer, flags);
  59.156 @@ -278,7 +349,7 @@ void kill_timer(struct timer *timer)
  59.157  
  59.158      if ( active_timer(timer) )
  59.159          __stop_timer(timer);
  59.160 -    timer->killed = 1;
  59.161 +    timer->status = TIMER_STATUS_killed;
  59.162  
  59.163      timer_unlock_irqrestore(timer, flags);
  59.164  
  59.165 @@ -290,43 +361,76 @@ void kill_timer(struct timer *timer)
  59.166  
  59.167  static void timer_softirq_action(void)
  59.168  {
  59.169 -    struct timer  *t, **heap;
  59.170 +    struct timer  *t, **heap, *next;
  59.171      struct timers *ts;
  59.172 -    s_time_t       now;
  59.173 +    s_time_t       now, deadline;
  59.174      void         (*fn)(void *);
  59.175      void          *data;
  59.176  
  59.177      ts = &this_cpu(timers);
  59.178  
  59.179      spin_lock_irq(&ts->lock);
  59.180 -    
  59.181 -    do {
  59.182 -        heap = ts->heap;
  59.183 -        now  = NOW();
  59.184  
  59.185 -        while ( (GET_HEAP_SIZE(heap) != 0) &&
  59.186 -                ((t = heap[1])->expires < (now + TIMER_SLOP)) )
  59.187 -        {
  59.188 -            remove_entry(heap, t);
  59.189 +    /* Try to move timers from overflow linked list to more efficient heap. */
  59.190 +    next = ts->list;
  59.191 +    ts->list = NULL;
  59.192 +    while ( unlikely((t = next) != NULL) )
  59.193 +    {
  59.194 +        next = t->list_next;
  59.195 +        t->status = TIMER_STATUS_inactive;
  59.196 +        add_entry(ts, t);
  59.197 +    }
  59.198 +    
  59.199 +    heap = ts->heap;
  59.200 +    now  = NOW();
  59.201 +
  59.202 +    while ( (GET_HEAP_SIZE(heap) != 0) &&
  59.203 +            ((t = heap[1])->expires < (now + TIMER_SLOP)) )
  59.204 +    {
  59.205 +        remove_entry(ts, t);
  59.206 +
  59.207 +        ts->running = t;
  59.208  
  59.209 -            ts->running = t;
  59.210 +        fn   = t->function;
  59.211 +        data = t->data;
  59.212  
  59.213 -            fn   = t->function;
  59.214 -            data = t->data;
  59.215 +        spin_unlock_irq(&ts->lock);
  59.216 +        (*fn)(data);
  59.217 +        spin_lock_irq(&ts->lock);
  59.218  
  59.219 -            spin_unlock_irq(&ts->lock);
  59.220 -            (*fn)(data);
  59.221 -            spin_lock_irq(&ts->lock);
  59.222 +        /* Heap may have grown while the lock was released. */
  59.223 +        heap = ts->heap;
  59.224 +    }
  59.225 +
  59.226 +    deadline = GET_HEAP_SIZE(heap) ? heap[1]->expires : 0;
  59.227  
  59.228 -            /* Heap may have grown while the lock was released. */
  59.229 -            heap = ts->heap;
  59.230 +    while ( unlikely((t = ts->list) != NULL) )
  59.231 +    {
  59.232 +        if ( t->expires >= (now + TIMER_SLOP) )
  59.233 +        {
  59.234 +            if ( (deadline == 0) || (deadline > t->expires) )
  59.235 +                deadline = t->expires;
  59.236 +            break;
  59.237          }
  59.238  
  59.239 -        ts->running = NULL;
  59.240 +        ts->list = t->list_next;
  59.241 +        t->status = TIMER_STATUS_inactive;
  59.242 +
  59.243 +        ts->running = t;
  59.244 +
  59.245 +        fn   = t->function;
  59.246 +        data = t->data;
  59.247  
  59.248 -        this_cpu(timer_deadline) = GET_HEAP_SIZE(heap) ? heap[1]->expires : 0;
  59.249 +        spin_unlock_irq(&ts->lock);
  59.250 +        (*fn)(data);
  59.251 +        spin_lock_irq(&ts->lock);
  59.252      }
  59.253 -    while ( !reprogram_timer(this_cpu(timer_deadline)) );
  59.254 +
  59.255 +    ts->running = NULL;
  59.256 +
  59.257 +    this_cpu(timer_deadline) = deadline;
  59.258 +    if ( !reprogram_timer(deadline) )
  59.259 +        raise_softirq(TIMER_SOFTIRQ);
  59.260  
  59.261      spin_unlock_irq(&ts->lock);
  59.262  }
  59.263 @@ -364,6 +468,9 @@ static void dump_timerq(unsigned char ke
  59.264              printk ("  %d : %p ex=0x%08X%08X %p\n",
  59.265                      j, t, (u32)(t->expires>>32), (u32)t->expires, t->data);
  59.266          }
  59.267 +        for ( t = ts->list, j = 0; t != NULL; t = t->list_next, j++ )
  59.268 +            printk (" L%d : %p ex=0x%08X%08X %p\n",
  59.269 +                    j, t, (u32)(t->expires>>32), (u32)t->expires, t->data);
  59.270          spin_unlock_irqrestore(&ts->lock, flags);
  59.271          printk("\n");
  59.272      }
    60.1 --- a/xen/common/xmalloc.c	Mon Aug 25 19:04:37 2008 +0900
    60.2 +++ b/xen/common/xmalloc.c	Mon Sep 01 16:59:43 2008 +0900
    60.3 @@ -136,15 +136,14 @@ static void maybe_split(struct xmalloc_h
    60.4  static void *xmalloc_new_page(size_t size)
    60.5  {
    60.6      struct xmalloc_hdr *hdr;
    60.7 -    unsigned long flags;
    60.8  
    60.9      hdr = alloc_xenheap_page();
   60.10      if ( hdr == NULL )
   60.11          return NULL;
   60.12  
   60.13 -    spin_lock_irqsave(&freelist_lock, flags);
   60.14 +    spin_lock(&freelist_lock);
   60.15      maybe_split(hdr, size, PAGE_SIZE);
   60.16 -    spin_unlock_irqrestore(&freelist_lock, flags);
   60.17 +    spin_unlock(&freelist_lock);
   60.18  
   60.19      return data_from_header(hdr);
   60.20  }
   60.21 @@ -175,7 +174,6 @@ static inline size_t align_up(size_t siz
   60.22  void *_xmalloc(size_t size, size_t align)
   60.23  {
   60.24      struct xmalloc_hdr *i;
   60.25 -    unsigned long flags;
   60.26  
   60.27      ASSERT(!in_irq());
   60.28  
   60.29 @@ -196,17 +194,17 @@ void *_xmalloc(size_t size, size_t align
   60.30          return xmalloc_whole_pages(size);
   60.31  
   60.32      /* Search free list. */
   60.33 -    spin_lock_irqsave(&freelist_lock, flags);
   60.34 +    spin_lock(&freelist_lock);
   60.35      list_for_each_entry( i, &freelist, freelist )
   60.36      {
   60.37          if ( i->size < size )
   60.38              continue;
   60.39          del_from_freelist(i);
   60.40          maybe_split(i, size, i->size);
   60.41 -        spin_unlock_irqrestore(&freelist_lock, flags);
   60.42 +        spin_unlock(&freelist_lock);
   60.43          return data_from_header(i);
   60.44      }
   60.45 -    spin_unlock_irqrestore(&freelist_lock, flags);
   60.46 +    spin_unlock(&freelist_lock);
   60.47  
   60.48      /* Alloc a new page and return from that. */
   60.49      return xmalloc_new_page(size);
   60.50 @@ -214,7 +212,6 @@ void *_xmalloc(size_t size, size_t align
   60.51  
   60.52  void xfree(void *p)
   60.53  {
   60.54 -    unsigned long flags;
   60.55      struct xmalloc_hdr *i, *tmp, *hdr;
   60.56  
   60.57      ASSERT(!in_irq());
   60.58 @@ -238,7 +235,7 @@ void xfree(void *p)
   60.59      }
   60.60  
   60.61      /* Merge with other free block, or put in list. */
   60.62 -    spin_lock_irqsave(&freelist_lock, flags);
   60.63 +    spin_lock(&freelist_lock);
   60.64      list_for_each_entry_safe( i, tmp, &freelist, freelist )
   60.65      {
   60.66          unsigned long _i   = (unsigned long)i;
   60.67 @@ -275,7 +272,7 @@ void xfree(void *p)
   60.68          add_to_freelist(hdr);
   60.69      }
   60.70  
   60.71 -    spin_unlock_irqrestore(&freelist_lock, flags);
   60.72 +    spin_unlock(&freelist_lock);
   60.73  }
   60.74  
   60.75  /*
    61.1 --- a/xen/drivers/passthrough/vtd/intremap.c	Mon Aug 25 19:04:37 2008 +0900
    61.2 +++ b/xen/drivers/passthrough/vtd/intremap.c	Mon Sep 01 16:59:43 2008 +0900
    61.3 @@ -43,7 +43,7 @@ u16 apicid_to_bdf(int apic_id)
    61.4      return 0;
    61.5  }
    61.6  
    61.7 -static void remap_entry_to_ioapic_rte(
    61.8 +static int remap_entry_to_ioapic_rte(
    61.9      struct iommu *iommu, struct IO_APIC_route_entry *old_rte)
   61.10  {
   61.11      struct iremap_entry *iremap_entry = NULL, *iremap_entries;
   61.12 @@ -56,15 +56,19 @@ static void remap_entry_to_ioapic_rte(
   61.13      {
   61.14          dprintk(XENLOG_ERR VTDPREFIX,
   61.15                  "remap_entry_to_ioapic_rte: ir_ctl is not ready\n");
   61.16 -        return;
   61.17 +        return -EFAULT;
   61.18      }
   61.19  
   61.20      remap_rte = (struct IO_APIC_route_remap_entry *) old_rte;
   61.21      index = (remap_rte->index_15 << 15) | remap_rte->index_0_14;
   61.22  
   61.23      if ( index > ir_ctrl->iremap_index )
   61.24 -        panic("%s: index (%d) is larger than remap table entry size (%d)!\n",
   61.25 -              __func__, index, ir_ctrl->iremap_index);
   61.26 +    {
   61.27 +        dprintk(XENLOG_ERR VTDPREFIX,
   61.28 +                "%s: index (%d) is larger than remap table entry size (%d)!\n",
   61.29 +                __func__, index, ir_ctrl->iremap_index);
   61.30 +        return -EFAULT;
   61.31 +    }
   61.32  
   61.33      spin_lock_irqsave(&ir_ctrl->iremap_lock, flags);
   61.34  
   61.35 @@ -82,9 +86,10 @@ static void remap_entry_to_ioapic_rte(
   61.36  
   61.37      unmap_vtd_domain_page(iremap_entries);
   61.38      spin_unlock_irqrestore(&ir_ctrl->iremap_lock, flags);
   61.39 +    return 0;
   61.40  }
   61.41  
   61.42 -static void ioapic_rte_to_remap_entry(struct iommu *iommu,
   61.43 +static int ioapic_rte_to_remap_entry(struct iommu *iommu,
   61.44      int apic_id, struct IO_APIC_route_entry *old_rte,
   61.45      unsigned int rte_upper, unsigned int value)
   61.46  {
   61.47 @@ -108,7 +113,14 @@ static void ioapic_rte_to_remap_entry(st
   61.48          index = (remap_rte->index_15 << 15) | remap_rte->index_0_14;
   61.49  
   61.50      if ( index > IREMAP_ENTRY_NR - 1 )
   61.51 -        panic("ioapic_rte_to_remap_entry: intremap index is more than 256!\n");
   61.52 +    {
   61.53 +        dprintk(XENLOG_ERR VTDPREFIX,
   61.54 +                "%s: intremap index (%d) is larger than"
   61.55 +                " the maximum index (%ld)!\n",
   61.56 +                __func__, index, IREMAP_ENTRY_NR - 1);
   61.57 +        spin_unlock_irqrestore(&ir_ctrl->iremap_lock, flags);
   61.58 +        return -EFAULT;
   61.59 +    }
   61.60  
   61.61      iremap_entries =
   61.62          (struct iremap_entry *)map_vtd_domain_page(ir_ctrl->iremap_maddr);
   61.63 @@ -159,7 +171,7 @@ static void ioapic_rte_to_remap_entry(st
   61.64  
   61.65      unmap_vtd_domain_page(iremap_entries);
   61.66      spin_unlock_irqrestore(&ir_ctrl->iremap_lock, flags);
   61.67 -    return;
   61.68 +    return 0;
   61.69  }
   61.70  
   61.71  unsigned int io_apic_read_remap_rte(
   61.72 @@ -189,23 +201,22 @@ unsigned int io_apic_read_remap_rte(
   61.73  
   61.74      remap_rte = (struct IO_APIC_route_remap_entry *) &old_rte;
   61.75  
   61.76 -    if ( remap_rte->mask || (remap_rte->format == 0) )
   61.77 +    if ( remap_rte->format == 0 )
   61.78      {
   61.79 -        *IO_APIC_BASE(apic) = reg;
   61.80 +        *IO_APIC_BASE(apic) = rte_upper ? (reg + 1) : reg;
   61.81          return *(IO_APIC_BASE(apic)+4);
   61.82      }
   61.83  
   61.84 -    remap_entry_to_ioapic_rte(iommu, &old_rte);
   61.85 -    if ( rte_upper )
   61.86 +    if ( remap_entry_to_ioapic_rte(iommu, &old_rte) )
   61.87      {
   61.88 -        *IO_APIC_BASE(apic) = reg + 1;
   61.89 -        return (*(((u32 *)&old_rte) + 1));
   61.90 +        *IO_APIC_BASE(apic) = rte_upper ? (reg + 1) : reg;
   61.91 +        return *(IO_APIC_BASE(apic)+4);
   61.92      }
   61.93 +
   61.94 +    if ( rte_upper )
   61.95 +        return (*(((u32 *)&old_rte) + 1));
   61.96      else
   61.97 -    {
   61.98 -        *IO_APIC_BASE(apic) = reg;
   61.99          return (*(((u32 *)&old_rte) + 0));
  61.100 -    }
  61.101  }
  61.102  
  61.103  void io_apic_write_remap_rte(
  61.104 @@ -243,8 +254,13 @@ void io_apic_write_remap_rte(
  61.105      *(IO_APIC_BASE(apic)+4) = *(((int *)&old_rte)+0);
  61.106      remap_rte->mask = saved_mask;
  61.107  
  61.108 -    ioapic_rte_to_remap_entry(iommu, mp_ioapics[apic].mpc_apicid,
  61.109 -                              &old_rte, rte_upper, value);
  61.110 +    if ( ioapic_rte_to_remap_entry(iommu, mp_ioapics[apic].mpc_apicid,
  61.111 +                                   &old_rte, rte_upper, value) )
  61.112 +    {
  61.113 +        *IO_APIC_BASE(apic) = rte_upper ? (reg + 1) : reg;
  61.114 +        *(IO_APIC_BASE(apic)+4) = value;
  61.115 +        return;
  61.116 +    }
  61.117  
  61.118      /* write new entry to ioapic */
  61.119      *IO_APIC_BASE(apic) = reg;
  61.120 @@ -253,7 +269,7 @@ void io_apic_write_remap_rte(
  61.121      *(IO_APIC_BASE(apic)+4) = *(((u32 *)&old_rte)+1);
  61.122  }
  61.123  
  61.124 -static void remap_entry_to_msi_msg(
  61.125 +static int remap_entry_to_msi_msg(
  61.126      struct iommu *iommu, struct msi_msg *msg)
  61.127  {
  61.128      struct iremap_entry *iremap_entry = NULL, *iremap_entries;
  61.129 @@ -266,7 +282,7 @@ static void remap_entry_to_msi_msg(
  61.130      {
  61.131          dprintk(XENLOG_ERR VTDPREFIX,
  61.132                  "remap_entry_to_msi_msg: ir_ctl == NULL");
  61.133 -        return;
  61.134 +        return -EFAULT;
  61.135      }
  61.136  
  61.137      remap_rte = (struct msi_msg_remap_entry *) msg;
  61.138 @@ -274,8 +290,12 @@ static void remap_entry_to_msi_msg(
  61.139               remap_rte->address_lo.index_0_14;
  61.140  
  61.141      if ( index > ir_ctrl->iremap_index )
  61.142 -        panic("%s: index (%d) is larger than remap table entry size (%d)\n",
  61.143 -              __func__, index, ir_ctrl->iremap_index);
  61.144 +    {
  61.145 +        dprintk(XENLOG_ERR VTDPREFIX,
  61.146 +                "%s: index (%d) is larger than remap table entry size (%d)\n",
  61.147 +                __func__, index, ir_ctrl->iremap_index);
  61.148 +        return -EFAULT;
  61.149 +    }
  61.150  
  61.151      spin_lock_irqsave(&ir_ctrl->iremap_lock, flags);
  61.152  
  61.153 @@ -304,9 +324,10 @@ static void remap_entry_to_msi_msg(
  61.154  
  61.155      unmap_vtd_domain_page(iremap_entries);
  61.156      spin_unlock_irqrestore(&ir_ctrl->iremap_lock, flags);
  61.157 +    return 0;
  61.158  }
  61.159  
  61.160 -static void msi_msg_to_remap_entry(
  61.161 +static int msi_msg_to_remap_entry(
  61.162      struct iommu *iommu, struct pci_dev *pdev, struct msi_msg *msg)
  61.163  {
  61.164      struct iremap_entry *iremap_entry = NULL, *iremap_entries;
  61.165 @@ -343,7 +364,15 @@ static void msi_msg_to_remap_entry(
  61.166          index = i;
  61.167  
  61.168      if ( index > IREMAP_ENTRY_NR - 1 )
  61.169 -        panic("msi_msg_to_remap_entry: intremap index is more than 256!\n");
  61.170 +    {
  61.171 +        dprintk(XENLOG_ERR VTDPREFIX,
  61.172 +                "%s: intremap index (%d) is larger than"
  61.173 +                " the maximum index (%ld)!\n",
  61.174 +                __func__, index, IREMAP_ENTRY_NR - 1);
  61.175 +        unmap_vtd_domain_page(iremap_entries);
  61.176 +        spin_unlock_irqrestore(&ir_ctrl->iremap_lock, flags);
  61.177 +        return -EFAULT;
  61.178 +    }
  61.179  
  61.180      iremap_entry = &iremap_entries[index];
  61.181      memcpy(&new_ire, iremap_entry, sizeof(struct iremap_entry));
  61.182 @@ -385,7 +414,7 @@ static void msi_msg_to_remap_entry(
  61.183  
  61.184      unmap_vtd_domain_page(iremap_entries);
  61.185      spin_unlock_irqrestore(&ir_ctrl->iremap_lock, flags);
  61.186 -    return;
  61.187 +    return 0;
  61.188  }
  61.189  
  61.190  void msi_msg_read_remap_rte(
    62.1 --- a/xen/drivers/passthrough/vtd/iommu.c	Mon Aug 25 19:04:37 2008 +0900
    62.2 +++ b/xen/drivers/passthrough/vtd/iommu.c	Mon Sep 01 16:59:43 2008 +0900
    62.3 @@ -624,15 +624,10 @@ static int iommu_set_root_entry(struct i
    62.4      unsigned long flags;
    62.5      s_time_t start_time;
    62.6  
    62.7 -    if ( iommu->root_maddr != 0 )
    62.8 -    {
    62.9 -        free_pgtable_maddr(iommu->root_maddr);
   62.10 -        iommu->root_maddr = 0;
   62.11 -    }
   62.12 -
   62.13      spin_lock_irqsave(&iommu->register_lock, flags);
   62.14  
   62.15 -    iommu->root_maddr = alloc_pgtable_maddr();
   62.16 +    if ( iommu->root_maddr == 0 )
   62.17 +        iommu->root_maddr = alloc_pgtable_maddr();
   62.18      if ( iommu->root_maddr == 0 )
   62.19      {
   62.20          spin_unlock_irqrestore(&iommu->register_lock, flags);
   62.21 @@ -1864,37 +1859,31 @@ static int intel_iommu_group_id(u8 bus, 
   62.22          return -1;
   62.23  }
   62.24  
   62.25 -u8 iommu_state[MAX_IOMMU_REGS * MAX_IOMMUS];
   62.26 +static u32 iommu_state[MAX_IOMMUS][MAX_IOMMU_REGS];
   62.27  int iommu_suspend(void)
   62.28  {
   62.29      struct acpi_drhd_unit *drhd;
   62.30      struct iommu *iommu;
   62.31 -    int i = 0;
   62.32 +    u32    i;
   62.33 +
   62.34 +    if ( !vtd_enabled )
   62.35 +        return 0;
   62.36  
   62.37      iommu_flush_all();
   62.38  
   62.39      for_each_drhd_unit ( drhd )
   62.40      {
   62.41          iommu = drhd->iommu;
   62.42 -        iommu_state[DMAR_RTADDR_REG * i] =
   62.43 -            (u64) dmar_readq(iommu->reg, DMAR_RTADDR_REG);
   62.44 -        iommu_state[DMAR_FECTL_REG * i] =
   62.45 +        i = iommu->index;
   62.46 +
   62.47 +        iommu_state[i][DMAR_FECTL_REG] =
   62.48              (u32) dmar_readl(iommu->reg, DMAR_FECTL_REG);
   62.49 -        iommu_state[DMAR_FEDATA_REG * i] =
   62.50 +        iommu_state[i][DMAR_FEDATA_REG] =
   62.51              (u32) dmar_readl(iommu->reg, DMAR_FEDATA_REG);
   62.52 -        iommu_state[DMAR_FEADDR_REG * i] =
   62.53 +        iommu_state[i][DMAR_FEADDR_REG] =
   62.54              (u32) dmar_readl(iommu->reg, DMAR_FEADDR_REG);
   62.55 -        iommu_state[DMAR_FEUADDR_REG * i] =
   62.56 +        iommu_state[i][DMAR_FEUADDR_REG] =
   62.57              (u32) dmar_readl(iommu->reg, DMAR_FEUADDR_REG);
   62.58 -        iommu_state[DMAR_PLMBASE_REG * i] =
   62.59 -            (u32) dmar_readl(iommu->reg, DMAR_PLMBASE_REG);
   62.60 -        iommu_state[DMAR_PLMLIMIT_REG * i] =
   62.61 -            (u32) dmar_readl(iommu->reg, DMAR_PLMLIMIT_REG);
   62.62 -        iommu_state[DMAR_PHMBASE_REG * i] =
   62.63 -            (u64) dmar_readq(iommu->reg, DMAR_PHMBASE_REG);
   62.64 -        iommu_state[DMAR_PHMLIMIT_REG * i] =
   62.65 -            (u64) dmar_readq(iommu->reg, DMAR_PHMLIMIT_REG);
   62.66 -        i++;
   62.67      }
   62.68  
   62.69      return 0;
   62.70 @@ -1904,37 +1893,34 @@ int iommu_resume(void)
   62.71  {
   62.72      struct acpi_drhd_unit *drhd;
   62.73      struct iommu *iommu;
   62.74 -    int i = 0;
   62.75 +    u32 i;
   62.76 +
   62.77 +    if ( !vtd_enabled )
   62.78 +        return 0;
   62.79  
   62.80      iommu_flush_all();
   62.81  
   62.82 -    init_vtd_hw();
   62.83 +    if ( init_vtd_hw() != 0  && force_iommu )
   62.84 +         panic("IOMMU setup failed, crash Xen for security purpose!\n");
   62.85 +
   62.86      for_each_drhd_unit ( drhd )
   62.87      {
   62.88          iommu = drhd->iommu;
   62.89 -        dmar_writeq( iommu->reg, DMAR_RTADDR_REG,
   62.90 -                     (u64) iommu_state[DMAR_RTADDR_REG * i]);
   62.91 +        i = iommu->index;
   62.92 +
   62.93          dmar_writel(iommu->reg, DMAR_FECTL_REG,
   62.94 -                    (u32) iommu_state[DMAR_FECTL_REG * i]);
   62.95 +                    (u32) iommu_state[i][DMAR_FECTL_REG]);
   62.96          dmar_writel(iommu->reg, DMAR_FEDATA_REG,
   62.97 -                    (u32) iommu_state[DMAR_FEDATA_REG * i]);
   62.98 +                    (u32) iommu_state[i][DMAR_FEDATA_REG]);
   62.99          dmar_writel(iommu->reg, DMAR_FEADDR_REG,
  62.100 -                    (u32) iommu_state[DMAR_FEADDR_REG * i]);
  62.101 +                    (u32) iommu_state[i][DMAR_FEADDR_REG]);
  62.102          dmar_writel(iommu->reg, DMAR_FEUADDR_REG,
  62.103 -                    (u32) iommu_state[DMAR_FEUADDR_REG * i]);
  62.104 -        dmar_writel(iommu->reg, DMAR_PLMBASE_REG,
  62.105 -                    (u32) iommu_state[DMAR_PLMBASE_REG * i]);
  62.106 -        dmar_writel(iommu->reg, DMAR_PLMLIMIT_REG,
  62.107 -                    (u32) iommu_state[DMAR_PLMLIMIT_REG * i]);
  62.108 -        dmar_writeq(iommu->reg, DMAR_PHMBASE_REG,
  62.109 -                    (u64) iommu_state[DMAR_PHMBASE_REG * i]);
  62.110 -        dmar_writeq(iommu->reg, DMAR_PHMLIMIT_REG,
  62.111 -                    (u64) iommu_state[DMAR_PHMLIMIT_REG * i]);
  62.112 +                    (u32) iommu_state[i][DMAR_FEUADDR_REG]);
  62.113  
  62.114          if ( iommu_enable_translation(iommu) )
  62.115              return -EIO;
  62.116 -        i++;
  62.117      }
  62.118 +
  62.119      return 0;
  62.120  }
  62.121  
    63.1 --- a/xen/include/asm-x86/io_apic.h	Mon Aug 25 19:04:37 2008 +0900
    63.2 +++ b/xen/include/asm-x86/io_apic.h	Mon Sep 01 16:59:43 2008 +0900
    63.3 @@ -125,7 +125,7 @@ extern int mpc_default_type;
    63.4  
    63.5  static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
    63.6  {
    63.7 -	if (vtd_enabled)
    63.8 +	if (iommu_enabled)
    63.9  		return io_apic_read_remap_rte(apic, reg);
   63.10  	*IO_APIC_BASE(apic) = reg;
   63.11  	return *(IO_APIC_BASE(apic)+4);
   63.12 @@ -152,6 +152,8 @@ extern int sis_apic_bug;
   63.13  #endif
   63.14  static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value)
   63.15  {
   63.16 +	if (iommu_enabled)
   63.17 +		return iommu_update_ire_from_apic(apic, reg, value);
   63.18  	if (sis_apic_bug)
   63.19  		*IO_APIC_BASE(apic) = reg;
   63.20  	*(IO_APIC_BASE(apic)+4) = value;
    64.1 --- a/xen/include/asm-x86/msr-index.h	Mon Aug 25 19:04:37 2008 +0900
    64.2 +++ b/xen/include/asm-x86/msr-index.h	Mon Sep 01 16:59:43 2008 +0900
    64.3 @@ -187,6 +187,9 @@
    64.4  #define MSR_K8_VM_CR			0xc0010114
    64.5  #define MSR_K8_VM_HSAVE_PA		0xc0010117
    64.6  
    64.7 +#define MSR_K8_FEATURE_MASK		0xc0011004
    64.8 +#define MSR_K8_EXT_FEATURE_MASK		0xc0011005
    64.9 +
   64.10  /* MSR_K8_VM_CR bits: */
   64.11  #define _K8_VMCR_SVME_DISABLE		4
   64.12  #define K8_VMCR_SVME_DISABLE		(1 << _K8_VMCR_SVME_DISABLE)
    65.1 --- a/xen/include/asm-x86/processor.h	Mon Aug 25 19:04:37 2008 +0900
    65.2 +++ b/xen/include/asm-x86/processor.h	Mon Sep 01 16:59:43 2008 +0900
    65.3 @@ -583,6 +583,8 @@ int rdmsr_hypervisor_regs(
    65.4  int wrmsr_hypervisor_regs(
    65.5      uint32_t idx, uint32_t eax, uint32_t edx);
    65.6  
    65.7 +int microcode_update(XEN_GUEST_HANDLE(const_void), unsigned long len);
    65.8 +
    65.9  #endif /* !__ASSEMBLY__ */
   65.10  
   65.11  #endif /* __ASM_X86_PROCESSOR_H */
    66.1 --- a/xen/include/asm-x86/softirq.h	Mon Aug 25 19:04:37 2008 +0900
    66.2 +++ b/xen/include/asm-x86/softirq.h	Mon Sep 01 16:59:43 2008 +0900
    66.3 @@ -1,8 +1,9 @@
    66.4  #ifndef __ASM_SOFTIRQ_H__
    66.5  #define __ASM_SOFTIRQ_H__
    66.6  
    66.7 -#define NMI_MCE_SOFTIRQ     (NR_COMMON_SOFTIRQS + 0)
    66.8 +#define NMI_MCE_SOFTIRQ        (NR_COMMON_SOFTIRQS + 0)
    66.9 +#define TIME_CALIBRATE_SOFTIRQ (NR_COMMON_SOFTIRQS + 1)
   66.10  
   66.11 -#define NR_ARCH_SOFTIRQS    1
   66.12 +#define NR_ARCH_SOFTIRQS       2
   66.13  
   66.14  #endif /* __ASM_SOFTIRQ_H__ */
    67.1 --- a/xen/include/public/memory.h	Mon Aug 25 19:04:37 2008 +0900
    67.2 +++ b/xen/include/public/memory.h	Mon Sep 01 16:59:43 2008 +0900
    67.3 @@ -204,6 +204,7 @@ struct xen_add_to_physmap {
    67.4      /* Source mapping space. */
    67.5  #define XENMAPSPACE_shared_info 0 /* shared info page */
    67.6  #define XENMAPSPACE_grant_table 1 /* grant table page */
    67.7 +#define XENMAPSPACE_mfn         2 /* usual MFN */
    67.8      unsigned int space;
    67.9  
   67.10      /* Index into source mapping space. */
   67.11 @@ -216,6 +217,22 @@ typedef struct xen_add_to_physmap xen_ad
   67.12  DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_t);
   67.13  
   67.14  /*
   67.15 + * Unmaps the page appearing at a particular GPFN from the specified guest's
   67.16 + * pseudophysical address space.
   67.17 + * arg == addr of xen_remove_from_physmap_t.
   67.18 + */
   67.19 +#define XENMEM_remove_from_physmap      15
   67.20 +struct xen_remove_from_physmap {
   67.21 +    /* Which domain to change the mapping for. */
   67.22 +    domid_t domid;
   67.23 +
   67.24 +    /* GPFN of the current mapping of the page. */
   67.25 +    xen_pfn_t     gpfn;
   67.26 +};
   67.27 +typedef struct xen_remove_from_physmap xen_remove_from_physmap_t;
   67.28 +DEFINE_XEN_GUEST_HANDLE(xen_remove_from_physmap_t);
   67.29 +
   67.30 +/*
   67.31   * Translates a list of domain-specific GPFNs into MFNs. Returns a -ve error
   67.32   * code on failure. This call only works for auto-translated guests.
   67.33   */
    68.1 --- a/xen/include/public/platform.h	Mon Aug 25 19:04:37 2008 +0900
    68.2 +++ b/xen/include/public/platform.h	Mon Sep 01 16:59:43 2008 +0900
    68.3 @@ -97,7 +97,7 @@ DEFINE_XEN_GUEST_HANDLE(xenpf_read_memty
    68.4  #define XENPF_microcode_update    35
    68.5  struct xenpf_microcode_update {
    68.6      /* IN variables. */
    68.7 -    XEN_GUEST_HANDLE(void) data;      /* Pointer to microcode data */
    68.8 +    XEN_GUEST_HANDLE(const_void) data;/* Pointer to microcode data */
    68.9      uint32_t length;                  /* Length of microcode data. */
   68.10  };
   68.11  typedef struct xenpf_microcode_update xenpf_microcode_update_t;
    69.1 --- a/xen/include/xen/compat.h	Mon Aug 25 19:04:37 2008 +0900
    69.2 +++ b/xen/include/xen/compat.h	Mon Sep 01 16:59:43 2008 +0900
    69.3 @@ -19,7 +19,9 @@
    69.4          type *_[0] __attribute__((__packed__)); \
    69.5      } __compat_handle_ ## name
    69.6  
    69.7 -#define DEFINE_COMPAT_HANDLE(name)   __DEFINE_COMPAT_HANDLE(name, name)
    69.8 +#define DEFINE_COMPAT_HANDLE(name) \
    69.9 +    __DEFINE_COMPAT_HANDLE(name, name); \
   69.10 +    __DEFINE_COMPAT_HANDLE(const_ ## name, const name)
   69.11  #define COMPAT_HANDLE(name)          __compat_handle_ ## name
   69.12  
   69.13  /* Is the compat handle a NULL reference? */
    70.1 --- a/xen/include/xen/iommu.h	Mon Aug 25 19:04:37 2008 +0900
    70.2 +++ b/xen/include/xen/iommu.h	Mon Sep 01 16:59:43 2008 +0900
    70.3 @@ -109,4 +109,8 @@ struct iommu_ops {
    70.4  
    70.5  void iommu_update_ire_from_apic(unsigned int apic, unsigned int reg, unsigned int value);
    70.6  void iommu_update_ire_from_msi(struct msi_desc *msi_desc, struct msi_msg *msg);
    70.7 +
    70.8 +int iommu_suspend(void);
    70.9 +int iommu_resume(void);
   70.10 +
   70.11  #endif /* _IOMMU_H_ */
    71.1 --- a/xen/include/xen/timer.h	Mon Aug 25 19:04:37 2008 +0900
    71.2 +++ b/xen/include/xen/timer.h	Mon Sep 01 16:59:43 2008 +0900
    71.3 @@ -14,16 +14,29 @@
    71.4  
    71.5  struct timer {
    71.6      /* System time expiry value (nanoseconds since boot). */
    71.7 -    s_time_t      expires;
    71.8 -    /* CPU on which this timer will be installed and executed. */
    71.9 -    unsigned int  cpu;
   71.10 +    s_time_t expires;
   71.11 +
   71.12 +    /* Position in active-timer data structure. */
   71.13 +    union {
   71.14 +        /* Timer-heap offset. */
   71.15 +        unsigned int heap_offset;
   71.16 +        /* Overflow linked list. */
   71.17 +        struct timer *list_next;
   71.18 +    };
   71.19 +
   71.20      /* On expiry, '(*function)(data)' will be executed in softirq context. */
   71.21 -    void        (*function)(void *);
   71.22 -    void         *data;
   71.23 -    /* Timer-heap offset. */
   71.24 -    unsigned int  heap_offset;
   71.25 -    /* Has this timer been killed (cannot be activated)? */
   71.26 -    int           killed;
   71.27 +    void (*function)(void *);
   71.28 +    void *data;
   71.29 +
   71.30 +    /* CPU on which this timer will be installed and executed. */
   71.31 +    uint16_t cpu;
   71.32 +
   71.33 +    /* Timer status. */
   71.34 +#define TIMER_STATUS_inactive 0 /* Not in use; can be activated.    */
   71.35 +#define TIMER_STATUS_killed   1 /* Not in use; canot be activated.  */
   71.36 +#define TIMER_STATUS_in_heap  2 /* In use; on timer heap.           */
   71.37 +#define TIMER_STATUS_in_list  3 /* In use; on overflow linked list. */
   71.38 +    uint8_t status;
   71.39  };
   71.40  
   71.41  /*
   71.42 @@ -37,7 +50,7 @@ struct timer {
   71.43   */
   71.44  static inline int active_timer(struct timer *timer)
   71.45  {
   71.46 -    return (timer->heap_offset != 0);
   71.47 +    return (timer->status >= TIMER_STATUS_in_heap);
   71.48  }
   71.49  
   71.50  /*
    72.1 --- a/xen/include/xlat.lst	Mon Aug 25 19:04:37 2008 +0900
    72.2 +++ b/xen/include/xlat.lst	Mon Sep 01 16:59:43 2008 +0900
    72.3 @@ -33,6 +33,7 @@
    72.4  !	kexec_image			kexec.h
    72.5  !	kexec_range			kexec.h
    72.6  !	add_to_physmap			memory.h
    72.7 +!	remove_from_physmap		memory.h
    72.8  !	foreign_memory_map		memory.h
    72.9  !	memory_exchange			memory.h
   72.10  !	memory_map			memory.h
    73.1 --- a/xen/include/xsm/xsm.h	Mon Aug 25 19:04:37 2008 +0900
    73.2 +++ b/xen/include/xsm/xsm.h	Mon Sep 01 16:59:43 2008 +0900
    73.3 @@ -136,6 +136,7 @@ struct xsm_operations {
    73.4      int (*mmu_machphys_update) (struct domain *d, unsigned long mfn);
    73.5      int (*update_va_mapping) (struct domain *d, l1_pgentry_t pte);
    73.6      int (*add_to_physmap) (struct domain *d1, struct domain *d2);
    73.7 +    int (*remove_from_physmap) (struct domain *d1, struct domain *d2);
    73.8  #endif
    73.9  };
   73.10  
   73.11 @@ -532,6 +533,11 @@ static inline int xsm_add_to_physmap(str
   73.12  {
   73.13      return xsm_call(add_to_physmap(d1, d2));
   73.14  }
   73.15 +
   73.16 +static inline int xsm_remove_from_physmap(struct domain *d1, struct domain *d2)
   73.17 +{
   73.18 +    return xsm_call(remove_from_physmap(d1, d2));
   73.19 +}
   73.20  #endif /* CONFIG_X86 */
   73.21  
   73.22  #endif /* __XSM_H */
    74.1 --- a/xen/xsm/dummy.c	Mon Aug 25 19:04:37 2008 +0900
    74.2 +++ b/xen/xsm/dummy.c	Mon Sep 01 16:59:43 2008 +0900
    74.3 @@ -385,6 +385,11 @@ static int dummy_add_to_physmap (struct 
    74.4  {
    74.5      return 0;
    74.6  }
    74.7 +
    74.8 +static int dummy_remove_from_physmap (struct domain *d1, struct domain *d2)
    74.9 +{
   74.10 +    return 0;
   74.11 +}
   74.12  #endif
   74.13  
   74.14  struct xsm_operations dummy_xsm_ops;
   74.15 @@ -484,5 +489,6 @@ void xsm_fixup_ops (struct xsm_operation
   74.16      set_to_dummy_if_null(ops, mmu_machphys_update);
   74.17      set_to_dummy_if_null(ops, update_va_mapping);
   74.18      set_to_dummy_if_null(ops, add_to_physmap);
   74.19 +    set_to_dummy_if_null(ops, remove_from_physmap);
   74.20  #endif
   74.21  }
    75.1 --- a/xen/xsm/flask/hooks.c	Mon Aug 25 19:04:37 2008 +0900
    75.2 +++ b/xen/xsm/flask/hooks.c	Mon Sep 01 16:59:43 2008 +0900
    75.3 @@ -1028,6 +1028,11 @@ static int flask_add_to_physmap(struct d
    75.4  {
    75.5      return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__PHYSMAP);
    75.6  }
    75.7 +
    75.8 +static int flask_remove_from_physmap(struct domain *d1, struct domain *d2)
    75.9 +{
   75.10 +    return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__PHYSMAP);
   75.11 +}
   75.12  #endif
   75.13  
   75.14  long do_flask_op(XEN_GUEST_HANDLE(xsm_op_t) u_flask_op);
   75.15 @@ -1115,6 +1120,7 @@ static struct xsm_operations flask_ops =
   75.16      .mmu_machphys_update = flask_mmu_machphys_update,
   75.17      .update_va_mapping = flask_update_va_mapping,
   75.18      .add_to_physmap = flask_add_to_physmap,
   75.19 +    .remove_from_physmap = flask_remove_from_physmap,
   75.20  #endif
   75.21  };
   75.22