ia64/xen-unstable

changeset 15705:04fb85a46dc5

merge with xen-unstable.hg
author Hollis Blanchard <hollisb@us.ibm.com>
date Thu Aug 02 09:54:18 2007 -0500 (2007-08-02)
parents 976db28bcc43 88bb0d305308
children 9f939ff527ee
files
line diff
     1.1 --- a/tools/blktap/drivers/blktapctrl.c	Thu Aug 02 09:50:55 2007 -0500
     1.2 +++ b/tools/blktap/drivers/blktapctrl.c	Thu Aug 02 09:54:18 2007 -0500
     1.3 @@ -42,6 +42,7 @@
     1.4  #include <errno.h>
     1.5  #include <sys/types.h>
     1.6  #include <linux/types.h>
     1.7 +#include <sys/wait.h>
     1.8  #include <signal.h>
     1.9  #include <fcntl.h>
    1.10  #include <sys/poll.h>
    1.11 @@ -472,11 +473,38 @@ static int read_msg(int fd, int msgtype,
    1.12  
    1.13  }
    1.14  
    1.15 +int launch_tapdisk(char *wrctldev, char *rdctldev)
    1.16 +{
    1.17 +	char *argv[] = { "tapdisk", wrctldev, rdctldev, NULL };
    1.18 +	pid_t child;
    1.19 +	
    1.20 +	if ((child = fork()) < 0)
    1.21 +		return -1;
    1.22 +
    1.23 +	if (!child) {
    1.24 +		int i;
    1.25 +		for (i = 0 ; i < sysconf(_SC_OPEN_MAX) ; i++)
    1.26 +			if (i != STDIN_FILENO &&
    1.27 +			    i != STDOUT_FILENO &&
    1.28 +			    i != STDERR_FILENO)
    1.29 +				close(i);
    1.30 +
    1.31 +		execvp("tapdisk", argv);
    1.32 +		_exit(1);
    1.33 +	} else {
    1.34 +		pid_t got;
    1.35 +		do {
    1.36 +			got = waitpid(child, NULL, 0);
    1.37 +		} while (got != child);
    1.38 +	}
    1.39 +	return 0;
    1.40 +}
    1.41 +
    1.42  int blktapctrl_new_blkif(blkif_t *blkif)
    1.43  {
    1.44  	blkif_info_t *blk;
    1.45  	int major, minor, fd_read, fd_write, type, new;
    1.46 -	char *rdctldev, *wrctldev, *cmd, *ptr;
    1.47 +	char *rdctldev, *wrctldev, *ptr;
    1.48  	image_t *image;
    1.49  	blkif_t *exist = NULL;
    1.50  	static uint16_t next_cookie = 0;
    1.51 @@ -504,12 +532,6 @@ int blktapctrl_new_blkif(blkif_t *blkif)
    1.52  				free(rdctldev);
    1.53  				return -1;
    1.54  			}
    1.55 -			if (asprintf(&cmd, "tapdisk %s %s", wrctldev, rdctldev) == -1) {
    1.56 -				free(rdctldev);
    1.57 -				free(wrctldev);
    1.58 -				return -1;
    1.59 -			}
    1.60 -
    1.61  			blkif->fds[READ] = open_ctrl_socket(rdctldev);
    1.62  			blkif->fds[WRITE] = open_ctrl_socket(wrctldev);
    1.63  			
    1.64 @@ -517,15 +539,14 @@ int blktapctrl_new_blkif(blkif_t *blkif)
    1.65  				goto fail;
    1.66  
    1.67  			/*launch the new process*/
    1.68 -			DPRINTF("Launching process, CMDLINE [%s]\n",cmd);
    1.69 -			if (system(cmd) == -1) {
    1.70 -				DPRINTF("Unable to fork, cmdline: [%s]\n",cmd);
    1.71 + 			DPRINTF("Launching process, CMDLINE [tapdisk %s %s]\n",wrctldev, rdctldev);
    1.72 + 			if (launch_tapdisk(wrctldev, rdctldev) == -1) {
    1.73 + 				DPRINTF("Unable to fork, cmdline: [tapdisk %s %s]\n",wrctldev, rdctldev);
    1.74  				return -1;
    1.75  			}
    1.76  
    1.77  			free(rdctldev);
    1.78  			free(wrctldev);
    1.79 -			free(cmd);
    1.80  		} else {
    1.81  			DPRINTF("Process exists!\n");
    1.82  			blkif->fds[READ] = exist->fds[READ];
    1.83 @@ -605,7 +626,6 @@ int open_ctrl_socket(char *devname)
    1.84  {
    1.85  	int ret;
    1.86  	int ipc_fd;
    1.87 -	char *cmd;
    1.88  	fd_set socks;
    1.89  	struct timeval timeout;
    1.90  
     2.1 --- a/tools/blktap/lib/blktaplib.h	Thu Aug 02 09:50:55 2007 -0500
     2.2 +++ b/tools/blktap/lib/blktaplib.h	Thu Aug 02 09:54:18 2007 -0500
     2.3 @@ -169,12 +169,14 @@ typedef struct image {
     2.4  	unsigned int info;
     2.5  } image_t;
     2.6  
     2.7 +/* 16-byte message header, immediately followed by message payload. */
     2.8  typedef struct msg_hdr {
     2.9 -	uint16_t    type;
    2.10 +	uint16_t   type;
    2.11  	uint16_t   len;
    2.12  	uint16_t   drivertype;
    2.13  	uint16_t   cookie;
    2.14  	uint8_t    readonly;
    2.15 +	uint8_t    pad[7];
    2.16  } msg_hdr_t;
    2.17  
    2.18  typedef struct msg_newdev {
     3.1 --- a/tools/firmware/hvmloader/smbios.c	Thu Aug 02 09:50:55 2007 -0500
     3.2 +++ b/tools/firmware/hvmloader/smbios.c	Thu Aug 02 09:54:18 2007 -0500
     3.3 @@ -169,7 +169,7 @@ hvm_write_smbios_tables(void)
     3.4      /* temporary variables used to build up Xen version string */
     3.5      char *p = NULL; /* points to next point of insertion */
     3.6      unsigned len = 0; /* length of string already composed */
     3.7 -    char *tmp = NULL; /* holds result of itoa() */
     3.8 +    char tmp[16]; /* holds result of itoa() */
     3.9      unsigned tmp_len; /* length of next string to add */
    3.10  
    3.11      hypercall_xen_version(XENVER_guest_handle, uuid);
     4.1 --- a/tools/libxc/ia64/Makefile	Thu Aug 02 09:50:55 2007 -0500
     4.2 +++ b/tools/libxc/ia64/Makefile	Thu Aug 02 09:54:18 2007 -0500
     4.3 @@ -5,6 +5,8 @@ GUEST_SRCS-y += ia64/xc_ia64_linux_save.
     4.4  GUEST_SRCS-y += ia64/xc_ia64_linux_restore.c
     4.5  
     4.6  GUEST_SRCS-y += ia64/xc_dom_ia64_util.c
     4.7 +GUEST_SRCS-y += ia64/dom_fw_acpi.c
     4.8 +
     4.9  DOMFW_SRCS_BASE := dom_fw_common.c dom_fw_domu.c dom_fw_asm.S
    4.10  DOMFW_SRCS := $(addprefix ia64/, $(DOMFW_SRCS_BASE))
    4.11  $(DOMFW_SRCS):
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/tools/libxc/ia64/dom_fw_acpi.c	Thu Aug 02 09:54:18 2007 -0500
     5.3 @@ -0,0 +1,13 @@
     5.4 +#include <inttypes.h>
     5.5 +#include <xen/acpi.h>
     5.6 +
     5.7 +uint8_t
     5.8 +generate_acpi_checksum(void *tbl, unsigned long len)
     5.9 +{
    5.10 +    uint8_t *ptr, sum = 0;
    5.11 +
    5.12 +    for ( ptr = tbl; len > 0 ; len--, ptr++ )
    5.13 +        sum += *ptr;
    5.14 +
    5.15 +    return 0 - sum;
    5.16 +}
     6.1 --- a/tools/python/xen/util/acmpolicy.py	Thu Aug 02 09:50:55 2007 -0500
     6.2 +++ b/tools/python/xen/util/acmpolicy.py	Thu Aug 02 09:54:18 2007 -0500
     6.3 @@ -818,12 +818,13 @@ class ACMPolicy(XSPolicy):
     6.4              if successful,the policy's flags will indicate that the
     6.5              policy is the one loaded into the hypervisor
     6.6          """
     6.7 -        (ret, output) = commands.getstatusoutput(
     6.8 +        if not self.isloaded():
     6.9 +            (ret, output) = commands.getstatusoutput(
    6.10                                     security.xensec_tool +
    6.11                                     " loadpolicy " +
    6.12                                     self.get_filename(".bin"))
    6.13 -        if ret != 0:
    6.14 -            return -xsconstants.XSERR_POLICY_LOAD_FAILED
    6.15 +            if ret != 0:
    6.16 +                return -xsconstants.XSERR_POLICY_LOAD_FAILED
    6.17          return xsconstants.XSERR_SUCCESS
    6.18  
    6.19      def isloaded(self):
     7.1 --- a/tools/xenstore/utils.c	Thu Aug 02 09:50:55 2007 -0500
     7.2 +++ b/tools/xenstore/utils.c	Thu Aug 02 09:54:18 2007 -0500
     7.3 @@ -8,20 +8,19 @@
     7.4  #include <fcntl.h>
     7.5  #include <sys/types.h>
     7.6  #include <signal.h>
     7.7 -
     7.8  #include "utils.h"
     7.9  
    7.10  void xprintf(const char *fmt, ...)
    7.11  {
    7.12 -	static FILE *out = NULL;
    7.13  	va_list args;
    7.14 -	if (!out)
    7.15 -		out = stderr;
    7.16 +
    7.17 +	if (!stderr)
    7.18 +		return; /* could trace()? */
    7.19  
    7.20  	va_start(args, fmt);
    7.21 -	vfprintf(out, fmt, args);
    7.22 +	vfprintf(stderr, fmt, args);
    7.23  	va_end(args);
    7.24 -	fflush(out);
    7.25 +	fflush(stderr);
    7.26  }
    7.27  
    7.28  void barf(const char *fmt, ...)
    7.29 @@ -61,72 +60,3 @@ void barf_perror(const char *fmt, ...)
    7.30  	}
    7.31  	exit(1);
    7.32  }
    7.33 -
    7.34 -void *_realloc_array(void *ptr, size_t size, size_t num)
    7.35 -{
    7.36 -	if (num >= SIZE_MAX/size)
    7.37 -		return NULL;
    7.38 -	return realloc_nofail(ptr, size * num);
    7.39 -}
    7.40 -
    7.41 -void *realloc_nofail(void *ptr, size_t size)
    7.42 -{
    7.43 -	ptr = realloc(ptr, size);
    7.44 -	if (ptr)
    7.45 -		return ptr;
    7.46 -	barf("realloc of %zu failed", size);
    7.47 -}
    7.48 -
    7.49 -void *malloc_nofail(size_t size)
    7.50 -{
    7.51 -	void *ptr = malloc(size);
    7.52 -	if (ptr)
    7.53 -		return ptr;
    7.54 -	barf("malloc of %zu failed", size);
    7.55 -}
    7.56 -
    7.57 -/* This version adds one byte (for nul term) */
    7.58 -void *grab_file(const char *filename, unsigned long *size)
    7.59 -{
    7.60 -	unsigned int max = 16384;
    7.61 -	int ret, fd;
    7.62 -	void *buffer;
    7.63 -
    7.64 -	if (streq(filename, "-"))
    7.65 -		fd = dup(STDIN_FILENO);
    7.66 -	else
    7.67 -		fd = open(filename, O_RDONLY, 0);
    7.68 -
    7.69 -	if (fd == -1)
    7.70 -		return NULL;
    7.71 -
    7.72 -	buffer = malloc(max+1);
    7.73 -	if (!buffer)
    7.74 -		goto error;
    7.75 -	*size = 0;
    7.76 -	while ((ret = read(fd, buffer + *size, max - *size)) > 0) {
    7.77 -		*size += ret;
    7.78 -		if (*size == max) {
    7.79 -			void *nbuffer;
    7.80 -			max *= 2;
    7.81 -			nbuffer = realloc(buffer, max + 1);
    7.82 -			if (!nbuffer)
    7.83 -				goto error;
    7.84 -			buffer = nbuffer;
    7.85 -		}
    7.86 -	}
    7.87 -	if (ret < 0)
    7.88 -		goto error;
    7.89 -	((char *)buffer)[*size] = '\0';
    7.90 -	close(fd);
    7.91 -	return buffer;
    7.92 -error:
    7.93 -	free(buffer);
    7.94 -	close(fd);
    7.95 -	return NULL;
    7.96 -}
    7.97 -
    7.98 -void release_file(void *data, unsigned long size __attribute__((unused)))
    7.99 -{
   7.100 -	free(data);
   7.101 -}
     8.1 --- a/tools/xenstore/utils.h	Thu Aug 02 09:50:55 2007 -0500
     8.2 +++ b/tools/xenstore/utils.h	Thu Aug 02 09:54:18 2007 -0500
     8.3 @@ -21,39 +21,12 @@ static inline bool strends(const char *a
     8.4  
     8.5  #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
     8.6  
     8.7 -#define ___stringify(x)	#x
     8.8 -#define __stringify(x)		___stringify(x)
     8.9 -
    8.10 -/* Convenient wrappers for malloc and realloc.  Use them. */
    8.11 -#define new(type) ((type *)malloc_nofail(sizeof(type)))
    8.12 -#define new_array(type, num) realloc_array((type *)0, (num))
    8.13 -#define realloc_array(ptr, num) ((__typeof__(ptr))_realloc_array((ptr), sizeof((*ptr)), (num)))
    8.14 -
    8.15 -void *malloc_nofail(size_t size);
    8.16 -void *realloc_nofail(void *ptr, size_t size);
    8.17 -void *_realloc_array(void *ptr, size_t size, size_t num);
    8.18 -
    8.19  void barf(const char *fmt, ...) __attribute__((noreturn));
    8.20  void barf_perror(const char *fmt, ...) __attribute__((noreturn));
    8.21  
    8.22 -/* This version adds one byte (for nul term) */
    8.23 -void *grab_file(const char *filename, unsigned long *size);
    8.24 -void release_file(void *data, unsigned long size);
    8.25 -
    8.26 -/* Signal handling: returns fd to listen on. */
    8.27 -int signal_to_fd(int signal);
    8.28 -void close_signal(int fd);
    8.29 -
    8.30  void xprintf(const char *fmt, ...);
    8.31  
    8.32  #define eprintf(_fmt, _args...) xprintf("[ERR] %s" _fmt, __FUNCTION__, ##_args)
    8.33 -#define iprintf(_fmt, _args...) xprintf("[INF] %s" _fmt, __FUNCTION__, ##_args)
    8.34 -
    8.35 -#ifdef DEBUG
    8.36 -#define dprintf(_fmt, _args...) xprintf("[DBG] %s" _fmt, __FUNCTION__, ##_args)
    8.37 -#else
    8.38 -#define dprintf(_fmt, _args...) ((void)0)
    8.39 -#endif
    8.40  
    8.41  /*
    8.42   * Mux errno values onto returned pointers.
     9.1 --- a/tools/xenstore/xenstored_core.c	Thu Aug 02 09:50:55 2007 -0500
     9.2 +++ b/tools/xenstore/xenstored_core.c	Thu Aug 02 09:54:18 2007 -0500
     9.3 @@ -1820,7 +1820,9 @@ int main(int argc, char *argv[])
     9.4  	if (pidfile)
     9.5  		write_pidfile(pidfile);
     9.6  
     9.7 -	talloc_enable_leak_report_full();
     9.8 +	/* Talloc leak reports go to stderr, which is closed if we fork. */
     9.9 +	if (!dofork)
    9.10 +		talloc_enable_leak_report_full();
    9.11  
    9.12  	/* Create sockets for them to listen to. */
    9.13  	sock = talloc(talloc_autofree_context(), int);
    9.14 @@ -1881,6 +1883,11 @@ int main(int argc, char *argv[])
    9.15  		close(STDIN_FILENO);
    9.16  		close(STDOUT_FILENO);
    9.17  		close(STDERR_FILENO);
    9.18 +
    9.19 +		/* Get ourselves a nice xenstored crash if these are used. */
    9.20 +		stdin = NULL;
    9.21 +		stdout = NULL;
    9.22 +		stderr = NULL;
    9.23  	}
    9.24  
    9.25  	signal(SIGHUP, trigger_reopen_log);
    10.1 --- a/tools/xenstore/xenstored_domain.c	Thu Aug 02 09:50:55 2007 -0500
    10.2 +++ b/tools/xenstore/xenstored_domain.c	Thu Aug 02 09:54:18 2007 -0500
    10.3 @@ -621,13 +621,8 @@ void domain_entry_fix(unsigned int domid
    10.4  	struct domain *d;
    10.5  
    10.6  	d = find_domain_by_domid(domid);
    10.7 -	if (d) {
    10.8 -		if ((d->nbentry += num) < 0) {
    10.9 -			eprintf("invalid domain entry number %d",
   10.10 -				d->nbentry);
   10.11 -			d->nbentry = 0;
   10.12 -		}
   10.13 -	}
   10.14 +	if (d && ((d->nbentry += num) < 0))
   10.15 +		d->nbentry = 0;
   10.16  }
   10.17  
   10.18  int domain_entry(struct connection *conn)
    11.1 --- a/tools/xenstore/xs_tdb_dump.c	Thu Aug 02 09:50:55 2007 -0500
    11.2 +++ b/tools/xenstore/xs_tdb_dump.c	Thu Aug 02 09:54:18 2007 -0500
    11.3 @@ -4,7 +4,7 @@
    11.4  #include <fcntl.h>
    11.5  #include <stdio.h>
    11.6  #include <stdarg.h>
    11.7 -
    11.8 +#include <string.h>
    11.9  #include "xs_lib.h"
   11.10  #include "tdb.h"
   11.11  #include "talloc.h"
    12.1 --- a/tools/xm-test/lib/XmTestLib/acm.py	Thu Aug 02 09:50:55 2007 -0500
    12.2 +++ b/tools/xm-test/lib/XmTestLib/acm.py	Thu Aug 02 09:54:18 2007 -0500
    12.3 @@ -67,6 +67,10 @@ def ACMLoadPolicy(policy='xm-test'):
    12.4      if main.serverType == main.SERVER_XEN_API:
    12.5          ACMLoadPolicy_XenAPI()
    12.6      else:
    12.7 +        cmd='xm dumppolicy | grep -E "^POLICY REFERENCE = ' + policy + '.$"'
    12.8 +        s, o = traceCommand(cmd)
    12.9 +        if o != "":
   12.10 +            return
   12.11          s, o = traceCommand("xm makepolicy %s" % (policy))
   12.12          if s != 0:
   12.13              FAIL("Need to be able to do 'xm makepolicy %s' but could not" %
    13.1 --- a/tools/xm-test/tests/security-acm/07_security-acm_pol_update.py	Thu Aug 02 09:50:55 2007 -0500
    13.2 +++ b/tools/xm-test/tests/security-acm/07_security-acm_pol_update.py	Thu Aug 02 09:54:18 2007 -0500
    13.3 @@ -12,11 +12,20 @@ from xen.xend import XendAPIConstants
    13.4  from xen.util import acmpolicy, security, xsconstants
    13.5  from xen.util.acmpolicy import ACMPolicy
    13.6  from xen.xend.XendDomain import DOM0_UUID
    13.7 +from XmTestLib.acm import *
    13.8  
    13.9  import commands
   13.10  import os
   13.11  import base64
   13.12  
   13.13 +if not isACMEnabled():
   13.14 +    SKIP("Not running this test since ACM not enabled.")
   13.15 +
   13.16 +try:
   13.17 +    session = xapi.connect()
   13.18 +except:
   13.19 +    SKIP("Skipping this test since xm is not using the Xen-API.")
   13.20 +
   13.21  xm_test = {}
   13.22  xm_test['policyname'] = "xm-test"
   13.23  xm_test['date'] = "Fri Sep 29 14:44:38 2006"
    14.1 --- a/tools/xm-test/tests/security-acm/09_security-acm_pol_update.py	Thu Aug 02 09:50:55 2007 -0500
    14.2 +++ b/tools/xm-test/tests/security-acm/09_security-acm_pol_update.py	Thu Aug 02 09:54:18 2007 -0500
    14.3 @@ -7,6 +7,7 @@
    14.4  
    14.5  from XmTestLib import xapi
    14.6  from XmTestLib.XenAPIDomain import XmTestAPIDomain
    14.7 +from XmTestLib.acm import *
    14.8  from XmTestLib import *
    14.9  from xen.xend import XendAPIConstants
   14.10  from xen.util import security, xsconstants
   14.11 @@ -16,6 +17,14 @@ import base64
   14.12  import struct
   14.13  import time
   14.14  
   14.15 +if not isACMEnabled():
   14.16 +    SKIP("Not running this test since ACM not enabled.")
   14.17 +
   14.18 +try:
   14.19 +    session = xapi.connect()
   14.20 +except:
   14.21 +    SKIP("Skipping this test since xm is not using the Xen-API.")
   14.22 +
   14.23  def typestoxml(types):
   14.24      res = ""
   14.25      for t in types:
    15.1 --- a/xen/arch/ia64/xen/dom_fw_common.c	Thu Aug 02 09:50:55 2007 -0500
    15.2 +++ b/xen/arch/ia64/xen/dom_fw_common.c	Thu Aug 02 09:54:18 2007 -0500
    15.3 @@ -207,17 +207,6 @@ print_md(efi_memory_desc_t *md)
    15.4  		printk("(%luKB)\n", size >> 10);
    15.5  }
    15.6  
    15.7 -uint8_t
    15.8 -generate_acpi_checksum(void *tbl, unsigned long len)
    15.9 -{
   15.10 -	uint8_t *ptr, sum = 0;
   15.11 -
   15.12 -	for (ptr = tbl; len > 0 ; len--, ptr++)
   15.13 -		sum += *ptr;
   15.14 -
   15.15 -	return 0 - sum;
   15.16 -}
   15.17 -
   15.18  struct fake_acpi_tables {
   15.19  	struct acpi20_table_rsdp rsdp;
   15.20  	struct xsdt_descriptor_rev2 xsdt;
    16.1 --- a/xen/arch/ia64/xen/dom_fw_dom0.c	Thu Aug 02 09:50:55 2007 -0500
    16.2 +++ b/xen/arch/ia64/xen/dom_fw_dom0.c	Thu Aug 02 09:54:18 2007 -0500
    16.3 @@ -103,6 +103,7 @@ acpi_update_madt_checksum(unsigned long 
    16.4  /* base is physical address of acpi table */
    16.5  static void __init touch_acpi_table(void)
    16.6  {
    16.7 +	int result;
    16.8  	lsapic_nbr = 0;
    16.9  
   16.10  	if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_update_lsapic, 0) < 0)
   16.11 @@ -111,6 +112,18 @@ static void __init touch_acpi_table(void
   16.12  				  acpi_patch_plat_int_src, 0) < 0)
   16.13  		printk("Error parsing MADT - no PLAT_INT_SRC entries\n");
   16.14  
   16.15 +	result = acpi_table_disable(ACPI_SRAT);
   16.16 +	if ( result == 0 )
   16.17 +		printk("Success Disabling SRAT\n");
   16.18 +	else if ( result != -ENOENT )
   16.19 +		printk("ERROR: Failed Disabling SRAT\n");
   16.20 +
   16.21 +	result = acpi_table_disable(ACPI_SLIT);
   16.22 +	if ( result == 0 )
   16.23 +		printk("Success Disabling SLIT\n");
   16.24 +	else if ( result != -ENOENT )
   16.25 +		printk("ERROR: Failed Disabling SLIT\n");
   16.26 +
   16.27  	acpi_table_parse(ACPI_APIC, acpi_update_madt_checksum);
   16.28  
   16.29  	return;
    17.1 --- a/xen/arch/x86/acpi/boot.c	Thu Aug 02 09:50:55 2007 -0500
    17.2 +++ b/xen/arch/x86/acpi/boot.c	Thu Aug 02 09:54:18 2007 -0500
    17.3 @@ -371,12 +371,19 @@ extern u32 pmtmr_ioport;
    17.4  
    17.5  #ifdef CONFIG_ACPI_SLEEP
    17.6  /* Get pm1x_cnt and pm1x_evt information for ACPI sleep */
    17.7 -static int __init
    17.8 +static void __init
    17.9  acpi_fadt_parse_sleep_info(struct fadt_descriptor_rev2 *fadt)
   17.10  {
   17.11 +	struct acpi_table_rsdp *rsdp;
   17.12 +	unsigned long rsdp_phys;
   17.13  	struct facs_descriptor_rev2 *facs = NULL;
   17.14  	uint64_t facs_pa;
   17.15  
   17.16 +	rsdp_phys = acpi_find_rsdp();
   17.17 +	if (!rsdp_phys || acpi_disabled)
   17.18 +		goto bad;
   17.19 +	rsdp = __va(rsdp_phys);
   17.20 +
   17.21  	if (fadt->revision >= FADT2_REVISION_ID) {
   17.22  		/* Sanity check on FADT Rev. 2 */
   17.23  		if ((fadt->xpm1a_cnt_blk.address_space_id !=
   17.24 @@ -432,8 +439,7 @@ acpi_fadt_parse_sleep_info(struct fadt_d
   17.25  			"FACS is shorter than ACPI spec allow: 0x%x",
   17.26  			facs->length);
   17.27  
   17.28 -	if ((acpi_rsdp_rev < 2) ||
   17.29 -	    (facs->length < 32)) {
   17.30 +	if ((rsdp->revision < 2) || (facs->length < 32)) {
   17.31  		acpi_sinfo.wakeup_vector = facs_pa + 
   17.32  			offsetof(struct facs_descriptor_rev2,
   17.33  				 firmware_waking_vector);
   17.34 @@ -451,10 +457,9 @@ acpi_fadt_parse_sleep_info(struct fadt_d
   17.35  		acpi_sinfo.pm1a_cnt, acpi_sinfo.pm1b_cnt,
   17.36  		acpi_sinfo.pm1a_evt, acpi_sinfo.pm1b_cnt,
   17.37  		acpi_sinfo.wakeup_vector, acpi_sinfo.vector_width);
   17.38 -	return 0;
   17.39 +	return;
   17.40  bad:
   17.41  	memset(&acpi_sinfo, 0, sizeof(acpi_sinfo));
   17.42 -	return 0;
   17.43  }
   17.44  #endif
   17.45  
    18.1 --- a/xen/arch/x86/domain_build.c	Thu Aug 02 09:50:55 2007 -0500
    18.2 +++ b/xen/arch/x86/domain_build.c	Thu Aug 02 09:54:18 2007 -0500
    18.3 @@ -316,6 +316,9 @@ int __init construct_dom0(
    18.4             parms.pae       ? ", PAE"  : "",
    18.5             elf_msb(&elf)   ? "msb"    : "lsb",
    18.6             elf.pstart, elf.pend);
    18.7 +    if ( parms.bsd_symtab )
    18.8 +        printk(" Dom0 symbol map 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
    18.9 +               elf.sstart, elf.send);
   18.10  
   18.11      if ( !compatible )
   18.12      {
   18.13 @@ -385,7 +388,7 @@ int __init construct_dom0(
   18.14      v_start          = parms.virt_base;
   18.15      vkern_start      = parms.virt_kstart;
   18.16      vkern_end        = parms.virt_kend;
   18.17 -    vinitrd_start    = round_pgup(vkern_end);
   18.18 +    vinitrd_start    = round_pgup(parms.virt_end);
   18.19      vinitrd_end      = vinitrd_start + initrd_len;
   18.20      vphysmap_start   = round_pgup(vinitrd_end);
   18.21      vphysmap_end     = vphysmap_start + (nr_pages * (!is_pv_32on64_domain(d) ?
   18.22 @@ -795,7 +798,7 @@ int __init construct_dom0(
   18.23  
   18.24      /* Copy the OS image and free temporary buffer. */
   18.25      elf.dest = (void*)vkern_start;
   18.26 -    elf_load_binary(&elf);
   18.27 +    elf_xen_dom_load_binary(&elf, &parms);
   18.28  
   18.29      if ( UNSET_ADDR != parms.virt_hypercall )
   18.30      {
    19.1 --- a/xen/arch/x86/hvm/instrlen.c	Thu Aug 02 09:50:55 2007 -0500
    19.2 +++ b/xen/arch/x86/hvm/instrlen.c	Thu Aug 02 09:54:18 2007 -0500
    19.3 @@ -9,14 +9,6 @@
    19.4   * x86_emulate.c.  Used for MMIO.
    19.5   */
    19.6  
    19.7 -/*
    19.8 - * TODO: The way in which we use hvm_instruction_length is very inefficient as
    19.9 - * it now stands. It will be worthwhile to return the actual instruction buffer
   19.10 - * along with the instruction length since one of the reasons we are getting
   19.11 - * the instruction length is to know how many instruction bytes we need to
   19.12 - * fetch.
   19.13 - */
   19.14 -
   19.15  #include <xen/config.h>
   19.16  #include <xen/sched.h>
   19.17  #include <xen/mm.h>
   19.18 @@ -194,31 +186,51 @@ static uint8_t twobyte_table[256] = {
   19.19  /* 
   19.20   * insn_fetch - fetch the next byte from instruction stream
   19.21   */
   19.22 -#define insn_fetch()                                                    \
   19.23 -({ uint8_t _x;                                                          \
   19.24 -   if ( length >= 15 )                                                  \
   19.25 -       return -1;                                                       \
   19.26 -   if ( inst_copy_from_guest(&_x, pc, 1) != 1 ) {                       \
   19.27 -       gdprintk(XENLOG_WARNING,                                         \
   19.28 -                "Cannot read from address %lx (eip %lx, mode %d)\n",    \
   19.29 -                pc, org_pc, address_bytes);                             \
   19.30 -       return -1;                                                       \
   19.31 -   }                                                                    \
   19.32 -   pc += 1;                                                             \
   19.33 -   length += 1;                                                         \
   19.34 -   _x;                                                                  \
   19.35 +#define insn_fetch()                                                      \
   19.36 +({ uint8_t _x;                                                            \
   19.37 +   if ( length >= 15 )                                                    \
   19.38 +       return -1;                                                         \
   19.39 +   if ( inst_copy_from_guest(&_x, pc, 1) != 1 ) {                         \
   19.40 +       unsigned long err;                                                 \
   19.41 +       struct segment_register cs;                                        \
   19.42 +       gdprintk(XENLOG_WARNING,                                           \
   19.43 +                "Cannot read from address %lx (eip %lx, mode %d)\n",      \
   19.44 +                pc, org_pc, address_bytes);                               \
   19.45 +       err = 0; /* Must be not-present: we don't enforce reserved bits */ \
   19.46 +       if ( hvm_nx_enabled(current) )                                     \
   19.47 +           err |= PFEC_insn_fetch;                                        \
   19.48 +       hvm_get_segment_register(current, x86_seg_cs, &cs);                \
   19.49 +       if ( cs.attr.fields.dpl != 0 )                                     \
   19.50 +           err |= PFEC_user_mode;                                         \
   19.51 +       hvm_inject_exception(TRAP_page_fault, err, pc);                    \
   19.52 +       return -1;                                                         \
   19.53 +   }                                                                      \
   19.54 +   if ( buf )                                                             \
   19.55 +       buf[length] = _x;                                                  \
   19.56 +   length += 1;                                                           \
   19.57 +   pc += 1;                                                               \
   19.58 +   _x;                                                                    \
   19.59  })
   19.60  
   19.61 +#define insn_skip(_n) do {                      \
   19.62 +    int _i;                                     \
   19.63 +    for ( _i = 0; _i < (_n); _i++) {            \
   19.64 +        (void) insn_fetch();                    \
   19.65 +    }                                           \
   19.66 +} while (0)
   19.67 +
   19.68  /**
   19.69 - * hvm_instruction_length - returns the current instructions length
   19.70 + * hvm_instruction_fetch - read the current instruction and return its length
   19.71   *
   19.72   * @org_pc: guest instruction pointer
   19.73 - * @mode: guest operating mode
   19.74 + * @address_bytes: guest address width
   19.75 + * @buf: (optional) buffer to load actual instruction bytes into
   19.76   *
   19.77 - * EXTERNAL this routine calculates the length of the current instruction
   19.78 - * pointed to by org_pc.  The guest state is _not_ changed by this routine.
   19.79 + * Doesn't increment the guest's instruction pointer, but may
   19.80 + * issue faults to the guest.  Returns -1 on failure.
   19.81   */
   19.82 -int hvm_instruction_length(unsigned long org_pc, int address_bytes)
   19.83 +int hvm_instruction_fetch(unsigned long org_pc, int address_bytes,
   19.84 +                          unsigned char *buf)
   19.85  {
   19.86      uint8_t b, d, twobyte = 0, rex_prefix = 0, modrm_reg = 0;
   19.87      unsigned int op_default, op_bytes, ad_default, ad_bytes, tmp;
   19.88 @@ -317,18 +329,13 @@ done_prefixes:
   19.89              {
   19.90              case 0:
   19.91                  if ( modrm_rm == 6 ) 
   19.92 -                {
   19.93 -                    length += 2;
   19.94 -                    pc += 2; /* skip disp16 */
   19.95 -                }
   19.96 +                    insn_skip(2); /* skip disp16 */
   19.97                  break;
   19.98              case 1:
   19.99 -                length += 1;
  19.100 -                pc += 1; /* skip disp8 */
  19.101 +                insn_skip(1); /* skip disp8 */
  19.102                  break;
  19.103              case 2:
  19.104 -                length += 2;
  19.105 -                pc += 2; /* skip disp16 */
  19.106 +                insn_skip(2); /* skip disp16 */
  19.107                  break;
  19.108              }
  19.109          }
  19.110 @@ -340,33 +347,19 @@ done_prefixes:
  19.111              case 0:
  19.112                  if ( (modrm_rm == 4) && 
  19.113                       ((insn_fetch() & 7) == 5) )
  19.114 -                {
  19.115 -                    length += 4;
  19.116 -                    pc += 4; /* skip disp32 specified by SIB.base */
  19.117 -                }
  19.118 +                    insn_skip(4); /* skip disp32 specified by SIB.base */
  19.119                  else if ( modrm_rm == 5 )
  19.120 -                {
  19.121 -                    length += 4;
  19.122 -                    pc += 4; /* skip disp32 */
  19.123 -                }
  19.124 +                    insn_skip(4); /* skip disp32 */
  19.125                  break;
  19.126              case 1:
  19.127                  if ( modrm_rm == 4 )
  19.128 -                {
  19.129 -                    length += 1;
  19.130 -                    pc += 1;
  19.131 -                }
  19.132 -                length += 1;
  19.133 -                pc += 1; /* skip disp8 */
  19.134 +                    insn_skip(1);
  19.135 +                insn_skip(1); /* skip disp8 */
  19.136                  break;
  19.137              case 2:
  19.138                  if ( modrm_rm == 4 )
  19.139 -                {
  19.140 -                    length += 1;
  19.141 -                    pc += 1;
  19.142 -                }
  19.143 -                length += 4;
  19.144 -                pc += 4; /* skip disp32 */
  19.145 +                    insn_skip(1);
  19.146 +                insn_skip(4); /* skip disp32 */
  19.147                  break;
  19.148              }
  19.149          }
  19.150 @@ -387,12 +380,10 @@ done_prefixes:
  19.151          tmp = (d & ByteOp) ? 1 : op_bytes;
  19.152          if ( tmp == 8 ) tmp = 4;
  19.153          /* NB. Immediates are sign-extended as necessary. */
  19.154 -        length += tmp;
  19.155 -        pc += tmp;
  19.156 +        insn_skip(tmp);
  19.157          break;
  19.158      case SrcImmByte:
  19.159 -        length += 1;
  19.160 -        pc += 1;
  19.161 +        insn_skip(1);
  19.162          break;
  19.163      }
  19.164  
  19.165 @@ -402,8 +393,7 @@ done_prefixes:
  19.166      switch ( b )
  19.167      {
  19.168      case 0xa0 ... 0xa3: /* mov */
  19.169 -        length += ad_bytes;
  19.170 -        pc += ad_bytes; /* skip src/dst displacement */
  19.171 +        insn_skip(ad_bytes); /* skip src/dst displacement */
  19.172          break;
  19.173      case 0xf6 ... 0xf7: /* Grp3 */
  19.174          switch ( modrm_reg )
  19.175 @@ -412,8 +402,7 @@ done_prefixes:
  19.176              /* Special case in Grp3: test has an immediate source operand. */
  19.177              tmp = (d & ByteOp) ? 1 : op_bytes;
  19.178              if ( tmp == 8 ) tmp = 4;
  19.179 -            length += tmp;
  19.180 -            pc += tmp;
  19.181 +            insn_skip(tmp);
  19.182              break;
  19.183          }
  19.184          break;
    20.1 --- a/xen/arch/x86/hvm/platform.c	Thu Aug 02 09:50:55 2007 -0500
    20.2 +++ b/xen/arch/x86/hvm/platform.c	Thu Aug 02 09:54:18 2007 -0500
    20.3 @@ -1041,17 +1041,13 @@ void handle_mmio(unsigned long gpa)
    20.4          /* real or vm86 modes */
    20.5          address_bytes = 2;
    20.6      inst_addr = hvm_get_segment_base(v, x86_seg_cs) + regs->eip;
    20.7 -    inst_len = hvm_instruction_length(inst_addr, address_bytes);
    20.8 +    memset(inst, 0, MAX_INST_LEN);
    20.9 +    inst_len = hvm_instruction_fetch(inst_addr, address_bytes, inst);
   20.10      if ( inst_len <= 0 )
   20.11      {
   20.12 -        printk("handle_mmio: failed to get instruction length\n");
   20.13 -        domain_crash_synchronous();
   20.14 -    }
   20.15 -
   20.16 -    memset(inst, 0, MAX_INST_LEN);
   20.17 -    if ( inst_copy_from_guest(inst, inst_addr, inst_len) != inst_len ) {
   20.18 -        printk("handle_mmio: failed to copy instruction\n");
   20.19 -        domain_crash_synchronous();
   20.20 +        gdprintk(XENLOG_DEBUG, "handle_mmio: failed to get instruction\n");
   20.21 +        /* hvm_instruction_fetch() will have injected a #PF; get out now */
   20.22 +        return;
   20.23      }
   20.24  
   20.25      if ( mmio_decode(address_bytes, inst, mmio_op, &ad_size,
    21.1 --- a/xen/arch/x86/hvm/svm/intr.c	Thu Aug 02 09:50:55 2007 -0500
    21.2 +++ b/xen/arch/x86/hvm/svm/intr.c	Thu Aug 02 09:54:18 2007 -0500
    21.3 @@ -58,7 +58,7 @@ static void svm_inject_nmi(struct vcpu *
    21.4  
    21.5      event.bytes = 0;
    21.6      event.fields.v = 1;
    21.7 -    event.fields.type = EVENTTYPE_NMI;
    21.8 +    event.fields.type = X86_EVENTTYPE_NMI;
    21.9      event.fields.vector = 2;
   21.10  
   21.11      ASSERT(vmcb->eventinj.fields.v == 0);
   21.12 @@ -72,13 +72,33 @@ static void svm_inject_extint(struct vcp
   21.13  
   21.14      event.bytes = 0;
   21.15      event.fields.v = 1;
   21.16 -    event.fields.type = EVENTTYPE_INTR;
   21.17 +    event.fields.type = X86_EVENTTYPE_EXT_INTR;
   21.18      event.fields.vector = vector;
   21.19  
   21.20      ASSERT(vmcb->eventinj.fields.v == 0);
   21.21      vmcb->eventinj = event;
   21.22  }
   21.23      
   21.24 +static void enable_intr_window(struct vcpu *v, enum hvm_intack intr_source)
   21.25 +{
   21.26 +    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
   21.27 +
   21.28 +    ASSERT(intr_source != hvm_intack_none);
   21.29 +
   21.30 +    /*
   21.31 +     * Create a dummy virtual interrupt to intercept as soon as the
   21.32 +     * guest can accept the real interrupt.
   21.33 +     *
   21.34 +     * TODO: Better NMI handling. We need a way to skip a MOV SS interrupt
   21.35 +     * shadow. This is hard to do without hardware support. We should also
   21.36 +     * track 'NMI blocking' from NMI injection until IRET. This can be done
   21.37 +     * quite easily in software by intercepting the unblocking IRET.
   21.38 +     */
   21.39 +    vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR;
   21.40 +    HVMTRACE_2D(INJ_VIRQ, v, 0x0, /*fake=*/ 1);
   21.41 +    svm_inject_dummy_vintr(v);
   21.42 +}
   21.43 +
   21.44  asmlinkage void svm_intr_assist(void) 
   21.45  {
   21.46      struct vcpu *v = current;
   21.47 @@ -86,21 +106,6 @@ asmlinkage void svm_intr_assist(void)
   21.48      enum hvm_intack intr_source;
   21.49      int intr_vector;
   21.50  
   21.51 -    /*
   21.52 -     * Previous event delivery caused this intercept?
   21.53 -     * This will happen if the injection is latched by the processor (hence
   21.54 -     * clearing vintr.fields.irq or eventinj.v) but then subsequently a fault
   21.55 -     * occurs (e.g., due to lack of shadow mapping of guest IDT or guest-kernel
   21.56 -     * stack).
   21.57 -     */
   21.58 -    if ( vmcb->exitintinfo.fields.v )
   21.59 -    {
   21.60 -        vmcb->eventinj = vmcb->exitintinfo;
   21.61 -        vmcb->exitintinfo.bytes = 0;
   21.62 -        HVMTRACE_1D(REINJ_VIRQ, v, intr_vector);
   21.63 -        return;
   21.64 -    }
   21.65 -
   21.66      /* Crank the handle on interrupt state. */
   21.67      pt_update_irq(v);
   21.68      hvm_set_callback_irq_level();
   21.69 @@ -111,32 +116,23 @@ asmlinkage void svm_intr_assist(void)
   21.70              return;
   21.71  
   21.72          /*
   21.73 -         * If the guest can't take an interrupt right now, create a 'fake'
   21.74 -         * virtual interrupt on to intercept as soon as the guest _can_ take
   21.75 -         * interrupts.  Do not obtain the next interrupt from the vlapic/pic
   21.76 -         * if unable to inject.
   21.77 -         *
   21.78 -         * Also do this if there is an injection already pending. This is
   21.79 -         * because the event delivery can arbitrarily delay the injection
   21.80 -         * of the vintr (for example, if the exception is handled via an
   21.81 -         * interrupt gate, hence zeroing RFLAGS.IF). In the meantime:
   21.82 -         * - the vTPR could be modified upwards, so we need to wait until the
   21.83 -         *   exception is delivered before we can safely decide that an
   21.84 -         *   interrupt is deliverable; and
   21.85 -         * - the guest might look at the APIC/PIC state, so we ought not to
   21.86 -         *   have cleared the interrupt out of the IRR.
   21.87 -         *
   21.88 -         * TODO: Better NMI handling. We need a way to skip a MOV SS interrupt
   21.89 -         * shadow. This is hard to do without hardware support. We should also
   21.90 -         * track 'NMI blocking' from NMI injection until IRET. This can be done
   21.91 -         * quite easily in software by intercepting the unblocking IRET.
   21.92 +         * Pending IRQs must be delayed if:
   21.93 +         * 1. An event is already pending. This is despite the fact that SVM
   21.94 +         *    provides a VINTR delivery method quite separate from the EVENTINJ
   21.95 +         *    mechanism. The event delivery can arbitrarily delay the injection
   21.96 +         *    of the vintr (for example, if the exception is handled via an
   21.97 +         *    interrupt gate, hence zeroing RFLAGS.IF). In the meantime:
   21.98 +         *    - the vTPR could be modified upwards, so we need to wait until
   21.99 +         *      the exception is delivered before we can safely decide that an
  21.100 +         *      interrupt is deliverable; and
  21.101 +         *    - the guest might look at the APIC/PIC state, so we ought not to
  21.102 +         *      have cleared the interrupt out of the IRR.
  21.103 +         * 2. The IRQ is masked.
  21.104           */
  21.105 -        if ( !hvm_interrupts_enabled(v, intr_source) ||
  21.106 -             vmcb->eventinj.fields.v )
  21.107 +        if ( unlikely(vmcb->eventinj.fields.v) ||
  21.108 +             !hvm_interrupts_enabled(v, intr_source) )
  21.109          {
  21.110 -            vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR;
  21.111 -            HVMTRACE_2D(INJ_VIRQ, v, 0x0, /*fake=*/ 1);
  21.112 -            svm_inject_dummy_vintr(v);
  21.113 +            enable_intr_window(v, intr_source);
  21.114              return;
  21.115          }
  21.116      } while ( !hvm_vcpu_ack_pending_irq(v, intr_source, &intr_vector) );
  21.117 @@ -151,6 +147,11 @@ asmlinkage void svm_intr_assist(void)
  21.118          svm_inject_extint(v, intr_vector);
  21.119          pt_intr_post(v, intr_vector, intr_source);
  21.120      }
  21.121 +
  21.122 +    /* Is there another IRQ to queue up behind this one? */
  21.123 +    intr_source = hvm_vcpu_has_pending_irq(v);
  21.124 +    if ( unlikely(intr_source != hvm_intack_none) )
  21.125 +        enable_intr_window(v, intr_source);
  21.126  }
  21.127  
  21.128  /*
    22.1 --- a/xen/arch/x86/hvm/svm/svm.c	Thu Aug 02 09:50:55 2007 -0500
    22.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Thu Aug 02 09:54:18 2007 -0500
    22.3 @@ -71,8 +71,8 @@ static void *root_vmcb[NR_CPUS] __read_m
    22.4  /* hardware assisted paging bits */
    22.5  extern int opt_hap_enabled;
    22.6  
    22.7 -static void svm_inject_exception(struct vcpu *v, int trap, 
    22.8 -                                        int ev, int error_code)
    22.9 +static void svm_inject_exception(
   22.10 +    struct vcpu *v, int trap, int ev, int error_code)
   22.11  {
   22.12      eventinj_t event;
   22.13      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
   22.14 @@ -84,13 +84,11 @@ static void svm_inject_exception(struct 
   22.15  
   22.16      event.bytes = 0;            
   22.17      event.fields.v = 1;
   22.18 -    event.fields.type = EVENTTYPE_EXCEPTION;
   22.19 +    event.fields.type = X86_EVENTTYPE_HW_EXCEPTION;
   22.20      event.fields.vector = trap;
   22.21      event.fields.ev = ev;
   22.22      event.fields.errorcode = error_code;
   22.23  
   22.24 -    ASSERT(vmcb->eventinj.fields.v == 0);
   22.25 -    
   22.26      vmcb->eventinj = event;
   22.27  }
   22.28  
   22.29 @@ -362,22 +360,15 @@ int svm_vmcb_save(struct vcpu *v, struct
   22.30      c->sysenter_esp = vmcb->sysenter_esp;
   22.31      c->sysenter_eip = vmcb->sysenter_eip;
   22.32  
   22.33 -    /* Save any event/interrupt that was being injected when we last exited. */
   22.34 -    if ( vmcb->exitintinfo.fields.v )
   22.35 +    c->pending_event = 0;
   22.36 +    c->error_code = 0;
   22.37 +    if ( vmcb->eventinj.fields.v &&
   22.38 +         hvm_event_needs_reinjection(vmcb->eventinj.fields.type,
   22.39 +                                     vmcb->eventinj.fields.vector) )
   22.40      {
   22.41 -        c->pending_event = vmcb->exitintinfo.bytes & 0xffffffff;
   22.42 -        c->error_code = vmcb->exitintinfo.fields.errorcode;
   22.43 -    }
   22.44 -    else if ( vmcb->eventinj.fields.v ) 
   22.45 -    {
   22.46 -        c->pending_event = vmcb->eventinj.bytes & 0xffffffff;
   22.47 +        c->pending_event = (uint32_t)vmcb->eventinj.bytes;
   22.48          c->error_code = vmcb->eventinj.fields.errorcode;
   22.49      }
   22.50 -    else 
   22.51 -    {
   22.52 -        c->pending_event = 0;
   22.53 -        c->error_code = 0;
   22.54 -    }
   22.55  
   22.56      return 1;
   22.57  }
   22.58 @@ -495,11 +486,11 @@ int svm_vmcb_restore(struct vcpu *v, str
   22.59      vmcb->sysenter_esp = c->sysenter_esp;
   22.60      vmcb->sysenter_eip = c->sysenter_eip;
   22.61  
   22.62 -    /* update VMCB for nested paging restore */
   22.63 -    if ( paging_mode_hap(v->domain) ) {
   22.64 +    if ( paging_mode_hap(v->domain) )
   22.65 +    {
   22.66          vmcb->cr0 = v->arch.hvm_svm.cpu_shadow_cr0;
   22.67 -        vmcb->cr4 = v->arch.hvm_svm.cpu_shadow_cr4 |
   22.68 -                    (HVM_CR4_HOST_MASK & ~X86_CR4_PAE);
   22.69 +        vmcb->cr4 = (v->arch.hvm_svm.cpu_shadow_cr4 |
   22.70 +                     (HVM_CR4_HOST_MASK & ~X86_CR4_PAE));
   22.71          vmcb->cr3 = c->cr3;
   22.72          vmcb->np_enable = 1;
   22.73          vmcb->g_pat = 0x0007040600070406ULL; /* guest PAT */
   22.74 @@ -514,26 +505,23 @@ int svm_vmcb_restore(struct vcpu *v, str
   22.75          gdprintk(XENLOG_INFO, "Re-injecting 0x%"PRIx32", 0x%"PRIx32"\n",
   22.76                   c->pending_event, c->error_code);
   22.77  
   22.78 -        /* VMX uses a different type for #OF and #BP; fold into "Exception"  */
   22.79 -        if ( c->pending_type == 6 ) 
   22.80 -            c->pending_type = 3;
   22.81 -        /* Sanity check */
   22.82 -        if ( c->pending_type == 1 || c->pending_type > 4 
   22.83 -             || c->pending_reserved != 0 )
   22.84 +        if ( (c->pending_type == 1) || (c->pending_type > 6) ||
   22.85 +             (c->pending_reserved != 0) )
   22.86          {
   22.87              gdprintk(XENLOG_ERR, "Invalid pending event 0x%"PRIx32"\n", 
   22.88                       c->pending_event);
   22.89              return -EINVAL;
   22.90          }
   22.91 -        /* Put this pending event in exitintinfo and svm_intr_assist()
   22.92 -         * will reinject it when we return to the guest. */
   22.93 -        vmcb->exitintinfo.bytes = c->pending_event;
   22.94 -        vmcb->exitintinfo.fields.errorcode = c->error_code;
   22.95 +
   22.96 +        if ( hvm_event_needs_reinjection(c->pending_type, c->pending_vector) )
   22.97 +        {
   22.98 +            vmcb->eventinj.bytes = c->pending_event;
   22.99 +            vmcb->eventinj.fields.errorcode = c->error_code;
  22.100 +        }
  22.101      }
  22.102  
  22.103      paging_update_paging_modes(v);
  22.104 -    /* signal paging update to ASID handler */
  22.105 -    svm_asid_g_update_paging (v);
  22.106 +    svm_asid_g_update_paging(v);
  22.107  
  22.108      return 0;
  22.109   
  22.110 @@ -965,10 +953,10 @@ static void svm_hvm_inject_exception(
  22.111      svm_inject_exception(v, trapnr, (errcode != -1), errcode);
  22.112  }
  22.113  
  22.114 -static int svm_event_injection_faulted(struct vcpu *v)
  22.115 +static int svm_event_pending(struct vcpu *v)
  22.116  {
  22.117      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
  22.118 -    return vmcb->exitintinfo.fields.v;
  22.119 +    return vmcb->eventinj.fields.v;
  22.120  }
  22.121  
  22.122  static struct hvm_function_table svm_function_table = {
  22.123 @@ -1000,7 +988,7 @@ static struct hvm_function_table svm_fun
  22.124      .inject_exception     = svm_hvm_inject_exception,
  22.125      .init_ap_context      = svm_init_ap_context,
  22.126      .init_hypercall_page  = svm_init_hypercall_page,
  22.127 -    .event_injection_faulted = svm_event_injection_faulted
  22.128 +    .event_pending        = svm_event_pending
  22.129  };
  22.130  
  22.131  static void svm_npt_detect(void)
  22.132 @@ -1668,6 +1656,17 @@ static int svm_set_cr0(unsigned long val
  22.133    
  22.134      HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR0 value = %lx", value);
  22.135  
  22.136 +    if ( (u32)value != value )
  22.137 +    {
  22.138 +        HVM_DBG_LOG(DBG_LEVEL_1,
  22.139 +                    "Guest attempts to set upper 32 bits in CR0: %lx",
  22.140 +                    value);
  22.141 +        svm_inject_exception(v, TRAP_gp_fault, 1, 0);
  22.142 +        return 0;
  22.143 +    }
  22.144 +
  22.145 +    value &= ~HVM_CR0_GUEST_RESERVED_BITS;
  22.146 +
  22.147      /* ET is reserved and should be always be 1. */
  22.148      value |= X86_CR0_ET;
  22.149  
  22.150 @@ -2420,6 +2419,7 @@ asmlinkage void svm_vmexit_handler(struc
  22.151      unsigned long eip;
  22.152      struct vcpu *v = current;
  22.153      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
  22.154 +    eventinj_t eventinj;
  22.155      int inst_len, rc;
  22.156  
  22.157      exit_reason = vmcb->exitcode;
  22.158 @@ -2435,6 +2435,13 @@ asmlinkage void svm_vmexit_handler(struc
  22.159      perfc_incra(svmexits, exit_reason);
  22.160      eip = vmcb->rip;
  22.161  
  22.162 +    /* Event delivery caused this intercept? Queue for redelivery. */
  22.163 +    eventinj = vmcb->exitintinfo;
  22.164 +    if ( unlikely(eventinj.fields.v) &&
  22.165 +         hvm_event_needs_reinjection(eventinj.fields.type,
  22.166 +                                     eventinj.fields.vector) )
  22.167 +        vmcb->eventinj = eventinj;
  22.168 +
  22.169      switch ( exit_reason )
  22.170      {
  22.171      case VMEXIT_INTR:
    23.1 --- a/xen/arch/x86/hvm/vmx/intr.c	Thu Aug 02 09:50:55 2007 -0500
    23.2 +++ b/xen/arch/x86/hvm/vmx/intr.c	Thu Aug 02 09:54:18 2007 -0500
    23.3 @@ -76,10 +76,9 @@ static void enable_intr_window(struct vc
    23.4      u32 *cpu_exec_control = &v->arch.hvm_vmx.exec_control;
    23.5      u32 ctl = CPU_BASED_VIRTUAL_INTR_PENDING;
    23.6  
    23.7 -    if ( unlikely(intr_source == hvm_intack_none) )
    23.8 -        return;
    23.9 +    ASSERT(intr_source != hvm_intack_none);
   23.10  
   23.11 -    if ( unlikely(intr_source == hvm_intack_nmi) && cpu_has_vmx_vnmi )
   23.12 +    if ( (intr_source == hvm_intack_nmi) && cpu_has_vmx_vnmi )
   23.13      {
   23.14          /*
   23.15           * We set MOV-SS blocking in lieu of STI blocking when delivering an
   23.16 @@ -131,68 +130,27 @@ asmlinkage void vmx_intr_assist(void)
   23.17      int intr_vector;
   23.18      enum hvm_intack intr_source;
   23.19      struct vcpu *v = current;
   23.20 -    unsigned int idtv_info_field;
   23.21 -    unsigned long inst_len;
   23.22 +    unsigned int intr_info;
   23.23  
   23.24 +    /* Crank the handle on interrupt state. */
   23.25      pt_update_irq(v);
   23.26 -
   23.27      hvm_set_callback_irq_level();
   23.28  
   23.29 -    update_tpr_threshold(vcpu_vlapic(v));
   23.30 -
   23.31      do {
   23.32          intr_source = hvm_vcpu_has_pending_irq(v);
   23.33 -
   23.34 -        if ( unlikely(v->arch.hvm_vmx.vector_injected) )
   23.35 -        {
   23.36 -            v->arch.hvm_vmx.vector_injected = 0;
   23.37 -            enable_intr_window(v, intr_source);
   23.38 -            return;
   23.39 -        }
   23.40 -
   23.41 -        /* This could be moved earlier in the VMX resume sequence. */
   23.42 -        idtv_info_field = __vmread(IDT_VECTORING_INFO_FIELD);
   23.43 -        if ( unlikely(idtv_info_field & INTR_INFO_VALID_MASK) )
   23.44 -        {
   23.45 -            /* See SDM 3B 25.7.1.1 and .2 for info about masking resvd bits. */
   23.46 -            __vmwrite(VM_ENTRY_INTR_INFO_FIELD,
   23.47 -                      idtv_info_field & ~INTR_INFO_RESVD_BITS_MASK);
   23.48 +        if ( likely(intr_source == hvm_intack_none) )
   23.49 +            goto out;
   23.50  
   23.51 -            /*
   23.52 -             * Safe: the length will only be interpreted for software
   23.53 -             * exceptions and interrupts. If we get here then delivery of some
   23.54 -             * event caused a fault, and this always results in defined
   23.55 -             * VM_EXIT_INSTRUCTION_LEN.
   23.56 -             */
   23.57 -            inst_len = __vmread(VM_EXIT_INSTRUCTION_LEN); /* Safe */
   23.58 -            __vmwrite(VM_ENTRY_INSTRUCTION_LEN, inst_len);
   23.59 -
   23.60 -            if ( unlikely(idtv_info_field & 0x800) ) /* valid error code */
   23.61 -                __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE,
   23.62 -                          __vmread(IDT_VECTORING_ERROR_CODE));
   23.63 -
   23.64 -            /*
   23.65 -             * Clear NMI-blocking interruptibility info if an NMI delivery
   23.66 -             * faulted. Re-delivery will re-set it (see SDM 3B 25.7.1.2).
   23.67 -             */
   23.68 -            if ( (idtv_info_field&INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI )
   23.69 -                __vmwrite(GUEST_INTERRUPTIBILITY_INFO,
   23.70 -                          __vmread(GUEST_INTERRUPTIBILITY_INFO) &
   23.71 -                          ~VMX_INTR_SHADOW_NMI);
   23.72 -
   23.73 -            enable_intr_window(v, intr_source);
   23.74 -
   23.75 -            HVM_DBG_LOG(DBG_LEVEL_1, "idtv_info_field=%x", idtv_info_field);
   23.76 -            return;
   23.77 -        }
   23.78 -
   23.79 -        if ( likely(intr_source == hvm_intack_none) )
   23.80 -            return;
   23.81 -
   23.82 -        if ( !hvm_interrupts_enabled(v, intr_source) )
   23.83 +        /*
   23.84 +         * An event is already pending or the pending interrupt is masked?
   23.85 +         * Then the pending interrupt must be delayed.
   23.86 +         */
   23.87 +        intr_info = __vmread(VM_ENTRY_INTR_INFO);
   23.88 +        if ( unlikely(intr_info & INTR_INFO_VALID_MASK) ||
   23.89 +             !hvm_interrupts_enabled(v, intr_source) )
   23.90          {
   23.91              enable_intr_window(v, intr_source);
   23.92 -            return;
   23.93 +            goto out;
   23.94          }
   23.95      } while ( !hvm_vcpu_ack_pending_irq(v, intr_source, &intr_vector) );
   23.96  
   23.97 @@ -206,6 +164,14 @@ asmlinkage void vmx_intr_assist(void)
   23.98          vmx_inject_extint(v, intr_vector);
   23.99          pt_intr_post(v, intr_vector, intr_source);
  23.100      }
  23.101 +
  23.102 +    /* Is there another IRQ to queue up behind this one? */
  23.103 +    intr_source = hvm_vcpu_has_pending_irq(v);
  23.104 +    if ( unlikely(intr_source != hvm_intack_none) )
  23.105 +        enable_intr_window(v, intr_source);
  23.106 +
  23.107 + out:
  23.108 +    update_tpr_threshold(vcpu_vlapic(v));
  23.109  }
  23.110  
  23.111  /*
    24.1 --- a/xen/arch/x86/hvm/vmx/vmcs.c	Thu Aug 02 09:50:55 2007 -0500
    24.2 +++ b/xen/arch/x86/hvm/vmx/vmcs.c	Thu Aug 02 09:54:18 2007 -0500
    24.3 @@ -240,9 +240,24 @@ int vmx_cpu_up(void)
    24.4  {
    24.5      u32 eax, edx;
    24.6      int cpu = smp_processor_id();
    24.7 +    u64 cr0, vmx_cr0_fixed0, vmx_cr0_fixed1;
    24.8  
    24.9      BUG_ON(!(read_cr4() & X86_CR4_VMXE));
   24.10  
   24.11 +    /* 
   24.12 +     * Ensure the current processor operating mode meets 
   24.13 +     * the requred CRO fixed bits in VMX operation. 
   24.14 +     */
   24.15 +    cr0 = read_cr0();
   24.16 +    rdmsrl(MSR_IA32_VMX_CR0_FIXED0, vmx_cr0_fixed0);
   24.17 +    rdmsrl(MSR_IA32_VMX_CR0_FIXED1, vmx_cr0_fixed1);
   24.18 +    if ( (~cr0 & vmx_cr0_fixed0) || (cr0 & ~vmx_cr0_fixed1) )
   24.19 +    {
   24.20 +        printk("CPU%d: some settings of host CR0 are " 
   24.21 +               "not allowed in VMX operation.\n", cpu);
   24.22 +        return 0;
   24.23 +    }
   24.24 +
   24.25      rdmsr(IA32_FEATURE_CONTROL_MSR, eax, edx);
   24.26  
   24.27      if ( eax & IA32_FEATURE_CONTROL_MSR_LOCK )
   24.28 @@ -418,7 +433,7 @@ static void construct_vmcs(struct vcpu *
   24.29      __vmwrite(VM_EXIT_MSR_LOAD_COUNT, 0);
   24.30      __vmwrite(VM_ENTRY_MSR_LOAD_COUNT, 0);
   24.31  
   24.32 -    __vmwrite(VM_ENTRY_INTR_INFO_FIELD, 0);
   24.33 +    __vmwrite(VM_ENTRY_INTR_INFO, 0);
   24.34  
   24.35      __vmwrite(CR0_GUEST_HOST_MASK, ~0UL);
   24.36      __vmwrite(CR4_GUEST_HOST_MASK, ~0UL);
    25.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Thu Aug 02 09:50:55 2007 -0500
    25.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Thu Aug 02 09:54:18 2007 -0500
    25.3 @@ -613,29 +613,14 @@ void vmx_vmcs_save(struct vcpu *v, struc
    25.4      c->sysenter_esp = __vmread(GUEST_SYSENTER_ESP);
    25.5      c->sysenter_eip = __vmread(GUEST_SYSENTER_EIP);
    25.6  
    25.7 -    /*
    25.8 -     * Save any event/interrupt that was being injected when we last
    25.9 -     * exited. IDT_VECTORING_INFO_FIELD has priority, as anything in
   25.10 -     * VM_ENTRY_INTR_INFO_FIELD is either a fault caused by the first
   25.11 -     * event, which will happen the next time, or an interrupt, which we
   25.12 -     * never inject when IDT_VECTORING_INFO_FIELD is valid.
   25.13 -     */
   25.14 -    if ( (ev = __vmread(IDT_VECTORING_INFO_FIELD)) & INTR_INFO_VALID_MASK )
   25.15 -    {
   25.16 -        c->pending_event = ev;
   25.17 -        c->error_code = __vmread(IDT_VECTORING_ERROR_CODE);
   25.18 -    }
   25.19 -    else if ( (ev = __vmread(VM_ENTRY_INTR_INFO_FIELD)) &
   25.20 -              INTR_INFO_VALID_MASK )
   25.21 +    c->pending_event = 0;
   25.22 +    c->error_code = 0;
   25.23 +    if ( ((ev = __vmread(VM_ENTRY_INTR_INFO)) & INTR_INFO_VALID_MASK) &&
   25.24 +         hvm_event_needs_reinjection((ev >> 8) & 7, ev & 0xff) )
   25.25      {
   25.26          c->pending_event = ev;
   25.27          c->error_code = __vmread(VM_ENTRY_EXCEPTION_ERROR_CODE);
   25.28      }
   25.29 -    else
   25.30 -    {
   25.31 -        c->pending_event = 0;
   25.32 -        c->error_code = 0;
   25.33 -    }
   25.34  
   25.35      vmx_vmcs_exit(v);
   25.36  }
   25.37 @@ -754,34 +739,9 @@ int vmx_vmcs_restore(struct vcpu *v, str
   25.38  
   25.39      if ( c->pending_valid )
   25.40      {
   25.41 -        vmx_vmcs_enter(v);
   25.42 -
   25.43          gdprintk(XENLOG_INFO, "Re-injecting 0x%"PRIx32", 0x%"PRIx32"\n",
   25.44                   c->pending_event, c->error_code);
   25.45  
   25.46 -        /* SVM uses type 3 ("Exception") for #OF and #BP; VMX uses type 6 */
   25.47 -        if ( (c->pending_type == 3) &&
   25.48 -             ((c->pending_vector == 3) || (c->pending_vector == 4)) )
   25.49 -            c->pending_type = 6;
   25.50 -
   25.51 -        /* For software exceptions, we need to tell the hardware the
   25.52 -         * instruction length as well (hmmm). */
   25.53 -        if ( c->pending_type > 4 )
   25.54 -        {
   25.55 -            int addrbytes, ilen;
   25.56 -            if ( (c->cs_arbytes & X86_SEG_AR_CS_LM_ACTIVE) &&
   25.57 -                 (c->msr_efer & EFER_LMA) )
   25.58 -                addrbytes = 8;
   25.59 -            else if ( c->cs_arbytes & X86_SEG_AR_DEF_OP_SIZE )
   25.60 -                addrbytes = 4;
   25.61 -            else
   25.62 -                addrbytes = 2;
   25.63 -
   25.64 -            ilen = hvm_instruction_length(c->rip, addrbytes);
   25.65 -            __vmwrite(VM_ENTRY_INSTRUCTION_LEN, ilen);
   25.66 -        }
   25.67 -
   25.68 -        /* Sanity check */
   25.69          if ( (c->pending_type == 1) || (c->pending_type > 6) ||
   25.70               (c->pending_reserved != 0) )
   25.71          {
   25.72 @@ -790,12 +750,13 @@ int vmx_vmcs_restore(struct vcpu *v, str
   25.73              return -EINVAL;
   25.74          }
   25.75  
   25.76 -        /* Re-inject the exception */
   25.77 -        __vmwrite(VM_ENTRY_INTR_INFO_FIELD, c->pending_event);
   25.78 -        __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, c->error_code);
   25.79 -        v->arch.hvm_vmx.vector_injected = 1;
   25.80 -
   25.81 -        vmx_vmcs_exit(v);
   25.82 +        if ( hvm_event_needs_reinjection(c->pending_type, c->pending_vector) )
   25.83 +        {
   25.84 +            vmx_vmcs_enter(v);
   25.85 +            __vmwrite(VM_ENTRY_INTR_INFO, c->pending_event);
   25.86 +            __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, c->error_code);
   25.87 +            vmx_vmcs_exit(v);
   25.88 +        }
   25.89      }
   25.90  
   25.91      return 0;
   25.92 @@ -1203,14 +1164,10 @@ static void vmx_update_vtpr(struct vcpu 
   25.93      /* VMX doesn't have a V_TPR field */
   25.94  }
   25.95  
   25.96 -static int vmx_event_injection_faulted(struct vcpu *v)
   25.97 +static int vmx_event_pending(struct vcpu *v)
   25.98  {
   25.99 -    unsigned int idtv_info_field;
  25.100 -
  25.101      ASSERT(v == current);
  25.102 -
  25.103 -    idtv_info_field = __vmread(IDT_VECTORING_INFO_FIELD);
  25.104 -    return (idtv_info_field & INTR_INFO_VALID_MASK);
  25.105 +    return (__vmread(VM_ENTRY_INTR_INFO) & INTR_INFO_VALID_MASK);
  25.106  }
  25.107  
  25.108  static void disable_intercept_for_msr(u32 msr)
  25.109 @@ -1261,7 +1218,7 @@ static struct hvm_function_table vmx_fun
  25.110      .inject_exception     = vmx_inject_exception,
  25.111      .init_ap_context      = vmx_init_ap_context,
  25.112      .init_hypercall_page  = vmx_init_hypercall_page,
  25.113 -    .event_injection_faulted = vmx_event_injection_faulted,
  25.114 +    .event_pending        = vmx_event_pending,
  25.115      .cpu_up               = vmx_cpu_up,
  25.116      .cpu_down             = vmx_cpu_down,
  25.117  };
  25.118 @@ -2200,6 +2157,17 @@ static int vmx_set_cr0(unsigned long val
  25.119  
  25.120      HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR0 value = %lx", value);
  25.121  
  25.122 +    if ( (u32)value != value )
  25.123 +    {
  25.124 +        HVM_DBG_LOG(DBG_LEVEL_1,
  25.125 +                    "Guest attempts to set upper 32 bits in CR0: %lx",
  25.126 +                    value);
  25.127 +        vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
  25.128 +        return 0;
  25.129 +    }
  25.130 +
  25.131 +    value &= ~HVM_CR0_GUEST_RESERVED_BITS;
  25.132 +
  25.133      /* ET is reserved and should be always be 1. */
  25.134      value |= X86_CR0_ET;
  25.135  
  25.136 @@ -2842,47 +2810,6 @@ static void vmx_do_extint(struct cpu_use
  25.137      }
  25.138  }
  25.139  
  25.140 -static void vmx_reflect_exception(struct vcpu *v)
  25.141 -{
  25.142 -    int error_code, intr_info, vector;
  25.143 -
  25.144 -    intr_info = __vmread(VM_EXIT_INTR_INFO);
  25.145 -    vector = intr_info & 0xff;
  25.146 -    if ( intr_info & INTR_INFO_DELIVER_CODE_MASK )
  25.147 -        error_code = __vmread(VM_EXIT_INTR_ERROR_CODE);
  25.148 -    else
  25.149 -        error_code = VMX_DELIVER_NO_ERROR_CODE;
  25.150 -
  25.151 -#ifndef NDEBUG
  25.152 -    {
  25.153 -        unsigned long rip;
  25.154 -
  25.155 -        rip = __vmread(GUEST_RIP);
  25.156 -        HVM_DBG_LOG(DBG_LEVEL_1, "rip = %lx, error_code = %x",
  25.157 -                    rip, error_code);
  25.158 -    }
  25.159 -#endif /* NDEBUG */
  25.160 -
  25.161 -    /*
  25.162 -     * According to Intel Virtualization Technology Specification for
  25.163 -     * the IA-32 Intel Architecture (C97063-002 April 2005), section
  25.164 -     * 2.8.3, SW_EXCEPTION should be used for #BP and #OV, and
  25.165 -     * HW_EXCEPTION used for everything else.  The main difference
  25.166 -     * appears to be that for SW_EXCEPTION, the EIP/RIP is incremented
  25.167 -     * by VM_ENTER_INSTRUCTION_LEN bytes, whereas for HW_EXCEPTION,
  25.168 -     * it is not.
  25.169 -     */
  25.170 -    if ( (intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_SW_EXCEPTION )
  25.171 -    {
  25.172 -        int ilen = __get_instruction_length(); /* Safe: software exception */
  25.173 -        vmx_inject_sw_exception(v, vector, ilen);
  25.174 -    }
  25.175 -    else
  25.176 -    {
  25.177 -        vmx_inject_hw_exception(v, vector, error_code);
  25.178 -    }
  25.179 -}
  25.180 -
  25.181  static void vmx_failed_vmentry(unsigned int exit_reason,
  25.182                                 struct cpu_user_regs *regs)
  25.183  {
  25.184 @@ -2919,7 +2846,7 @@ static void vmx_failed_vmentry(unsigned 
  25.185  
  25.186  asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
  25.187  {
  25.188 -    unsigned int exit_reason;
  25.189 +    unsigned int exit_reason, idtv_info;
  25.190      unsigned long exit_qualification, inst_len = 0;
  25.191      struct vcpu *v = current;
  25.192  
  25.193 @@ -2935,6 +2862,30 @@ asmlinkage void vmx_vmexit_handler(struc
  25.194      if ( unlikely(exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) )
  25.195          return vmx_failed_vmentry(exit_reason, regs);
  25.196  
  25.197 +    /* Event delivery caused this intercept? Queue for redelivery. */
  25.198 +    idtv_info = __vmread(IDT_VECTORING_INFO);
  25.199 +    if ( unlikely(idtv_info & INTR_INFO_VALID_MASK) )
  25.200 +    {
  25.201 +        if ( hvm_event_needs_reinjection((idtv_info>>8)&7, idtv_info&0xff) )
  25.202 +        {
  25.203 +            /* See SDM 3B 25.7.1.1 and .2 for info about masking resvd bits. */
  25.204 +            __vmwrite(VM_ENTRY_INTR_INFO,
  25.205 +                      idtv_info & ~INTR_INFO_RESVD_BITS_MASK);
  25.206 +            if ( idtv_info & INTR_INFO_DELIVER_CODE_MASK )
  25.207 +                __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE,
  25.208 +                          __vmread(IDT_VECTORING_ERROR_CODE));
  25.209 +        }
  25.210 +
  25.211 +        /*
  25.212 +         * Clear NMI-blocking interruptibility info if an NMI delivery faulted.
  25.213 +         * Re-delivery will re-set it (see SDM 3B 25.7.1.2).
  25.214 +         */
  25.215 +        if ( (idtv_info & INTR_INFO_INTR_TYPE_MASK) == (X86_EVENTTYPE_NMI<<8) )
  25.216 +            __vmwrite(GUEST_INTERRUPTIBILITY_INFO,
  25.217 +                      __vmread(GUEST_INTERRUPTIBILITY_INFO) &
  25.218 +                      ~VMX_INTR_SHADOW_NMI);
  25.219 +    }
  25.220 +
  25.221      switch ( exit_reason )
  25.222      {
  25.223      case EXIT_REASON_EXCEPTION_NMI:
  25.224 @@ -2957,7 +2908,7 @@ asmlinkage void vmx_vmexit_handler(struc
  25.225           * (NB. If we emulate this IRET for any reason, we should re-clear!)
  25.226           */
  25.227          if ( unlikely(intr_info & INTR_INFO_NMI_UNBLOCKED_BY_IRET) &&
  25.228 -             !(__vmread(IDT_VECTORING_INFO_FIELD) & INTR_INFO_VALID_MASK) &&
  25.229 +             !(__vmread(IDT_VECTORING_INFO) & INTR_INFO_VALID_MASK) &&
  25.230               (vector != TRAP_double_fault) )
  25.231              __vmwrite(GUEST_INTERRUPTIBILITY_INFO,
  25.232                      __vmread(GUEST_INTERRUPTIBILITY_INFO)|VMX_INTR_SHADOW_NMI);
  25.233 @@ -2995,14 +2946,12 @@ asmlinkage void vmx_vmexit_handler(struc
  25.234              vmx_inject_hw_exception(v, TRAP_page_fault, regs->error_code);
  25.235              break;
  25.236          case TRAP_nmi:
  25.237 -            if ( (intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI )
  25.238 -            {
  25.239 -                HVMTRACE_0D(NMI, v);
  25.240 -                vmx_store_cpu_guest_regs(v, regs, NULL);
  25.241 -                do_nmi(regs); /* Real NMI, vector 2: normal processing. */
  25.242 -            }
  25.243 -            else
  25.244 -                vmx_reflect_exception(v);
  25.245 +            if ( (intr_info & INTR_INFO_INTR_TYPE_MASK) !=
  25.246 +                 (X86_EVENTTYPE_NMI << 8) )
  25.247 +                goto exit_and_crash;
  25.248 +            HVMTRACE_0D(NMI, v);
  25.249 +            vmx_store_cpu_guest_regs(v, regs, NULL);
  25.250 +            do_nmi(regs); /* Real NMI, vector 2: normal processing. */
  25.251              break;
  25.252          case TRAP_machine_check:
  25.253              HVMTRACE_0D(MCE, v);
    26.1 --- a/xen/arch/x86/mm/shadow/multi.c	Thu Aug 02 09:50:55 2007 -0500
    26.2 +++ b/xen/arch/x86/mm/shadow/multi.c	Thu Aug 02 09:54:18 2007 -0500
    26.3 @@ -2905,7 +2905,7 @@ static int sh_page_fault(struct vcpu *v,
    26.4           * stack is currently considered to be a page table, so we should
    26.5           * unshadow the faulting page before exiting.
    26.6           */
    26.7 -        if ( unlikely(hvm_event_injection_faulted(v)) )
    26.8 +        if ( unlikely(hvm_event_pending(v)) )
    26.9          {
   26.10              gdprintk(XENLOG_DEBUG, "write to pagetable during event "
   26.11                       "injection: cr2=%#lx, mfn=%#lx\n", 
    27.1 --- a/xen/common/libelf/libelf-dominfo.c	Thu Aug 02 09:50:55 2007 -0500
    27.2 +++ b/xen/common/libelf/libelf-dominfo.c	Thu Aug 02 09:54:18 2007 -0500
    27.3 @@ -333,6 +333,99 @@ static int elf_xen_note_check(struct elf
    27.4      return 0;
    27.5  }
    27.6  
    27.7 +
    27.8 +static void elf_xen_loadsymtab(struct elf_binary *elf,
    27.9 +                               struct elf_dom_parms *parms)
   27.10 +{
   27.11 +    unsigned long maxva, len;
   27.12 +
   27.13 +    if ( !parms->bsd_symtab )
   27.14 +        return;
   27.15 +
   27.16 +    /* Calculate the required additional kernel space for the elf image */
   27.17 +
   27.18 +    /* The absolute base address of the elf image */
   27.19 +    maxva = elf_round_up(elf, parms->virt_kend);
   27.20 +    maxva += sizeof(long); /* Space to store the size of the elf image */
   27.21 +    /* Space for the elf and elf section headers */
   27.22 +    maxva += (elf_uval(elf, elf->ehdr, e_ehsize) +
   27.23 +              elf_shdr_count(elf) * elf_uval(elf, elf->ehdr, e_shentsize));
   27.24 +    maxva = elf_round_up(elf, maxva);
   27.25 +
   27.26 +    /* Space for the symbol and string tabs */
   27.27 +    len = (unsigned long)elf->send - (unsigned long)elf->sstart;
   27.28 +    maxva = elf_round_up(elf, maxva + len);
   27.29 +
   27.30 +    /* The address the kernel must expanded to */
   27.31 +    parms->virt_end = maxva;
   27.32 +}
   27.33 +
   27.34 +int elf_xen_dom_load_binary(struct elf_binary *elf,
   27.35 +                            struct elf_dom_parms *parms)
   27.36 +{
   27.37 +    elf_ehdr *sym_ehdr;
   27.38 +    unsigned long shdr, symtab_addr;
   27.39 +    unsigned long maxva, symbase;
   27.40 +    uint8_t i;
   27.41 +    char *p;
   27.42 +
   27.43 +    elf_load_binary(elf);
   27.44 +
   27.45 +    if ( !parms->bsd_symtab )
   27.46 +        return 0;
   27.47 +
   27.48 +#define elf_hdr_elm(_elf, _hdr, _elm, _val)     \
   27.49 +do {                                            \
   27.50 +    if ( elf_64bit(_elf) )                      \
   27.51 +        (_hdr)->e64._elm = _val;                \
   27.52 +    else                                        \
   27.53 +        (_hdr)->e32._elm = _val;                \
   27.54 +} while ( 0 )
   27.55 +
   27.56 +    /* ehdr right after the kernel image (4 byte aligned) */
   27.57 +    symbase = elf_round_up(elf, parms->virt_kend);
   27.58 +    symtab_addr = maxva = symbase + sizeof(long);
   27.59 +
   27.60 +    /* Set up Elf header. */
   27.61 +    sym_ehdr = (elf_ehdr *)symtab_addr;
   27.62 +    maxva = elf_copy_ehdr(elf, sym_ehdr);
   27.63 +
   27.64 +    elf_hdr_elm(elf, sym_ehdr, e_phoff, 0);
   27.65 +    elf_hdr_elm(elf, sym_ehdr, e_shoff, elf_uval(elf, elf->ehdr, e_ehsize));
   27.66 +    elf_hdr_elm(elf, sym_ehdr, e_phentsize, 0);
   27.67 +    elf_hdr_elm(elf, sym_ehdr, e_phnum, 0);
   27.68 +
   27.69 +    /* Copy Elf section headers. */
   27.70 +    shdr = maxva;
   27.71 +    maxva = elf_copy_shdr(elf, (elf_shdr *)shdr);
   27.72 +
   27.73 +    for ( i = 0; i < elf_shdr_count(elf); i++ )
   27.74 +    {
   27.75 +        uint8_t type;
   27.76 +        unsigned long tmp;
   27.77 +        type = elf_uval(elf, (elf_shdr *)shdr, sh_type);
   27.78 +        if ( (type == SHT_STRTAB) || (type == SHT_SYMTAB) )
   27.79 +        {
   27.80 +             elf_msg(elf, "%s: shdr %i at 0x%p -> 0x%p\n", __func__, i,
   27.81 +                     elf_section_start(elf, (elf_shdr *)shdr), (void *)maxva);
   27.82 +             tmp = elf_copy_section(elf, (elf_shdr *)shdr, (void *)maxva);
   27.83 +             /* Mangled to be based on ELF header location. */
   27.84 +             elf_hdr_elm(elf, (elf_shdr *)shdr, sh_offset,
   27.85 +                         maxva - symtab_addr);
   27.86 +             maxva = tmp;
   27.87 +        }
   27.88 +        shdr += elf_uval(elf, elf->ehdr, e_shentsize);
   27.89 +    }
   27.90 +
   27.91 +    /* Write down the actual sym size. */
   27.92 +    p = (char *)symbase;
   27.93 +    *(long *)p = maxva - symtab_addr; /* sym size */
   27.94 +
   27.95 +#undef elf_ehdr_elm
   27.96 +
   27.97 +    return 0;
   27.98 +}
   27.99 +
  27.100  static int elf_xen_addr_calc_check(struct elf_binary *elf,
  27.101                                     struct elf_dom_parms *parms)
  27.102  {
  27.103 @@ -374,22 +467,28 @@ static int elf_xen_addr_calc_check(struc
  27.104      parms->virt_offset = parms->virt_base - parms->elf_paddr_offset;
  27.105      parms->virt_kstart = elf->pstart + parms->virt_offset;
  27.106      parms->virt_kend   = elf->pend   + parms->virt_offset;
  27.107 +    parms->virt_end    = parms->virt_kend;
  27.108  
  27.109      if ( parms->virt_entry == UNSET_ADDR )
  27.110          parms->virt_entry = elf_uval(elf, elf->ehdr, e_entry);
  27.111  
  27.112 +    if ( parms->bsd_symtab )
  27.113 +        elf_xen_loadsymtab(elf, parms);
  27.114 +
  27.115      elf_msg(elf, "%s: addresses:\n", __FUNCTION__);
  27.116      elf_msg(elf, "    virt_base        = 0x%" PRIx64 "\n", parms->virt_base);
  27.117      elf_msg(elf, "    elf_paddr_offset = 0x%" PRIx64 "\n", parms->elf_paddr_offset);
  27.118      elf_msg(elf, "    virt_offset      = 0x%" PRIx64 "\n", parms->virt_offset);
  27.119      elf_msg(elf, "    virt_kstart      = 0x%" PRIx64 "\n", parms->virt_kstart);
  27.120      elf_msg(elf, "    virt_kend        = 0x%" PRIx64 "\n", parms->virt_kend);
  27.121 +    elf_msg(elf, "    virt_end         = 0x%" PRIx64 "\n", parms->virt_end);
  27.122      elf_msg(elf, "    virt_entry       = 0x%" PRIx64 "\n", parms->virt_entry);
  27.123  
  27.124      if ( (parms->virt_kstart > parms->virt_kend) ||
  27.125           (parms->virt_entry < parms->virt_kstart) ||
  27.126           (parms->virt_entry > parms->virt_kend) ||
  27.127 -         (parms->virt_base > parms->virt_kstart) )
  27.128 +         (parms->virt_base > parms->virt_kstart) ||
  27.129 +         (parms->virt_kend > parms->virt_end) )
  27.130      {
  27.131          elf_err(elf, "%s: ERROR: ELF start or entries are out of bounds.\n",
  27.132                  __FUNCTION__);
    28.1 --- a/xen/common/libelf/libelf-loader.c	Thu Aug 02 09:50:55 2007 -0500
    28.2 +++ b/xen/common/libelf/libelf-loader.c	Thu Aug 02 09:54:18 2007 -0500
    28.3 @@ -10,6 +10,8 @@ int elf_init(struct elf_binary *elf, con
    28.4  {
    28.5      const elf_shdr *shdr;
    28.6      uint64_t i, count, section, offset;
    28.7 +    uint64_t low = -1;
    28.8 +    uint64_t high = 0;
    28.9  
   28.10      if ( !elf_is_elfbinary(image) )
   28.11      {
   28.12 @@ -24,7 +26,11 @@ int elf_init(struct elf_binary *elf, con
   28.13      elf->class = elf->ehdr->e32.e_ident[EI_CLASS];
   28.14      elf->data = elf->ehdr->e32.e_ident[EI_DATA];
   28.15  
   28.16 -    /* sanity check phdr */
   28.17 +#ifdef VERBOSE
   28.18 +    elf_set_verbose(elf);
   28.19 +#endif
   28.20 +
   28.21 +    /* Sanity check phdr. */
   28.22      offset = elf_uval(elf, elf->ehdr, e_phoff) +
   28.23          elf_uval(elf, elf->ehdr, e_phentsize) * elf_phdr_count(elf);
   28.24      if ( offset > elf->size )
   28.25 @@ -34,7 +40,7 @@ int elf_init(struct elf_binary *elf, con
   28.26          return -1;
   28.27      }
   28.28  
   28.29 -    /* sanity check shdr */
   28.30 +    /* Sanity check shdr. */
   28.31      offset = elf_uval(elf, elf->ehdr, e_shoff) +
   28.32          elf_uval(elf, elf->ehdr, e_shentsize) * elf_shdr_count(elf);
   28.33      if ( offset > elf->size )
   28.34 @@ -44,29 +50,55 @@ int elf_init(struct elf_binary *elf, con
   28.35          return -1;
   28.36      }
   28.37  
   28.38 -    /* find section string table */
   28.39 +    /* Find section string table. */
   28.40      section = elf_uval(elf, elf->ehdr, e_shstrndx);
   28.41      shdr = elf_shdr_by_index(elf, section);
   28.42      if ( shdr != NULL )
   28.43          elf->sec_strtab = elf_section_start(elf, shdr);
   28.44  
   28.45 -    /* find symbol table, symbol string table */
   28.46 +    /* Find symbol table and symbol string table. */
   28.47      count = elf_shdr_count(elf);
   28.48      for ( i = 0; i < count; i++ )
   28.49      {
   28.50 +        const char *sh_symend, *sh_strend;
   28.51 +
   28.52          shdr = elf_shdr_by_index(elf, i);
   28.53          if ( elf_uval(elf, shdr, sh_type) != SHT_SYMTAB )
   28.54              continue;
   28.55          elf->sym_tab = shdr;
   28.56 +        sh_symend = (const char *)elf_section_end(elf, shdr);
   28.57          shdr = elf_shdr_by_index(elf, elf_uval(elf, shdr, sh_link));
   28.58          if ( shdr == NULL )
   28.59          {
   28.60              elf->sym_tab = NULL;
   28.61 +            sh_symend = 0;
   28.62              continue;
   28.63          }
   28.64          elf->sym_strtab = elf_section_start(elf, shdr);
   28.65 -        break;
   28.66 +        sh_strend = (const char *)elf_section_end(elf, shdr);
   28.67 +
   28.68 +        if ( low > (unsigned long)elf->sym_tab )
   28.69 +            low = (unsigned long)elf->sym_tab;
   28.70 +        if ( low > (unsigned long)shdr )
   28.71 +            low = (unsigned long)shdr;
   28.72 +
   28.73 +        if ( high < ((unsigned long)sh_symend) )
   28.74 +            high = (unsigned long)sh_symend;
   28.75 +        if ( high < ((unsigned long)sh_strend) )
   28.76 +            high = (unsigned long)sh_strend;
   28.77 +
   28.78 +        elf_msg(elf, "%s: shdr: sym_tab=%p size=0x%" PRIx64 "\n",
   28.79 +                __FUNCTION__, elf->sym_tab,
   28.80 +                elf_uval(elf, elf->sym_tab, sh_size));
   28.81 +        elf_msg(elf, "%s: shdr: str_tab=%p size=0x%" PRIx64 "\n",
   28.82 +                __FUNCTION__, elf->sym_strtab, elf_uval(elf, shdr, sh_size));
   28.83 +
   28.84 +        elf->sstart = low;
   28.85 +        elf->send = high;
   28.86 +        elf_msg(elf, "%s: symbol map: 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
   28.87 +                __FUNCTION__, elf->sstart, elf->send);
   28.88      }
   28.89 +
   28.90      return 0;
   28.91  }
   28.92  
    29.1 --- a/xen/common/libelf/libelf-tools.c	Thu Aug 02 09:50:55 2007 -0500
    29.2 +++ b/xen/common/libelf/libelf-tools.c	Thu Aug 02 09:54:18 2007 -0500
    29.3 @@ -238,6 +238,36 @@ int elf_phdr_is_loadable(struct elf_bina
    29.4      return ((p_type == PT_LOAD) && (p_flags & (PF_W | PF_X)) != 0);
    29.5  }
    29.6  
    29.7 +unsigned long
    29.8 +elf_copy_ehdr(struct elf_binary *elf, void *dest)
    29.9 +{
   29.10 +    uint64_t size;
   29.11 +
   29.12 +    size = elf_uval(elf, elf->ehdr, e_ehsize);
   29.13 +    memcpy(dest, elf->ehdr, size);
   29.14 +    return elf_round_up(elf, (unsigned long)(dest) + size);
   29.15 +}
   29.16 +
   29.17 +unsigned long
   29.18 +elf_copy_shdr(struct elf_binary *elf, void *dest)
   29.19 +{
   29.20 +    uint64_t size;
   29.21 +
   29.22 +    size = elf_shdr_count(elf) * elf_uval(elf, elf->ehdr, e_shentsize);
   29.23 +    memcpy(dest, elf->image + elf_uval(elf, elf->ehdr, e_shoff), size);
   29.24 +    return elf_round_up(elf, (unsigned long)(dest) + size);
   29.25 +}
   29.26 +
   29.27 +unsigned long
   29.28 +elf_copy_section(struct elf_binary *elf, const elf_shdr *shdr, void *dest)
   29.29 +{
   29.30 +    uint64_t size;
   29.31 +
   29.32 +    size = elf_uval(elf, shdr, sh_size);
   29.33 +    memcpy(dest, elf_section_start(elf, shdr), size);
   29.34 +    return elf_round_up(elf, (unsigned long)(dest) + size);
   29.35 +}
   29.36 +
   29.37  /*
   29.38   * Local variables:
   29.39   * mode: C
    30.1 --- a/xen/drivers/acpi/tables.c	Thu Aug 02 09:50:55 2007 -0500
    30.2 +++ b/xen/drivers/acpi/tables.c	Thu Aug 02 09:54:18 2007 -0500
    30.3 @@ -73,7 +73,6 @@ struct acpi_table_sdt {
    30.4  
    30.5  static unsigned long sdt_pa;	/* Physical Address */
    30.6  static unsigned long sdt_count;	/* Table count */
    30.7 -unsigned char acpi_rsdp_rev;
    30.8  
    30.9  static struct acpi_table_sdt sdt_entry[ACPI_MAX_TABLES] __initdata;
   30.10  
   30.11 @@ -227,6 +226,17 @@ void acpi_table_print_madt_entry(acpi_ta
   30.12  	}
   30.13  }
   30.14  
   30.15 +uint8_t
   30.16 +generate_acpi_checksum(void *tbl, unsigned long len)
   30.17 +{
   30.18 +	uint8_t *ptr, sum = 0;
   30.19 +
   30.20 +	for (ptr = tbl; len > 0 ; len--, ptr++)
   30.21 +		sum += *ptr;
   30.22 +
   30.23 +	return 0 - sum;
   30.24 +}
   30.25 +
   30.26  static int
   30.27  acpi_table_compute_checksum(void *table_pointer, unsigned long length)
   30.28  {
   30.29 @@ -599,8 +609,6 @@ int __init acpi_table_init(void)
   30.30  	       "RSDP (v%3.3d %6.6s                                ) @ 0x%p\n",
   30.31  	       rsdp->revision, rsdp->oem_id, (void *)rsdp_phys);
   30.32  
   30.33 -	acpi_rsdp_rev = rsdp->revision;
   30.34 -
   30.35  	if (rsdp->revision < 2)
   30.36  		result =
   30.37  		    acpi_table_compute_checksum(rsdp,
   30.38 @@ -623,3 +631,143 @@ int __init acpi_table_init(void)
   30.39  
   30.40  	return 0;
   30.41  }
   30.42 +
   30.43 +int __init
   30.44 +acpi_table_disable(enum acpi_table_id table_id)
   30.45 +{
   30.46 +	struct acpi_table_header *header = NULL;
   30.47 +	struct acpi_table_rsdp *rsdp;
   30.48 +	unsigned long rsdp_phys;
   30.49 +	char *table_name;
   30.50 +	int id;
   30.51 +
   30.52 +	rsdp_phys = acpi_find_rsdp();
   30.53 +	if (!rsdp_phys)
   30.54 +		return -ENODEV;
   30.55 +
   30.56 +	rsdp = (struct acpi_table_rsdp *)__acpi_map_table(rsdp_phys,
   30.57 +		sizeof(struct acpi_table_rsdp));
   30.58 +	if (!rsdp)
   30.59 +		return -ENODEV;
   30.60 +
   30.61 +	for (id = 0; id < sdt_count; id++)
   30.62 +		if (sdt_entry[id].id == table_id)
   30.63 +			break;
   30.64 +
   30.65 +	if (id == sdt_count)
   30.66 +		return -ENOENT;
   30.67 +
   30.68 +	table_name = acpi_table_signatures[table_id];
   30.69 +
   30.70 +	/* First check XSDT (but only on ACPI 2.0-compatible systems) */
   30.71 +
   30.72 +	if ((rsdp->revision >= 2) &&
   30.73 +	    (((struct acpi20_table_rsdp *)rsdp)->xsdt_address)) {
   30.74 +
   30.75 +		struct acpi_table_xsdt *mapped_xsdt = NULL;
   30.76 +
   30.77 +		sdt_pa = ((struct acpi20_table_rsdp *)rsdp)->xsdt_address;
   30.78 +
   30.79 +		/* map in just the header */
   30.80 +		header = (struct acpi_table_header *)
   30.81 +		    __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));
   30.82 +
   30.83 +		if (!header) {
   30.84 +			printk(KERN_WARNING PREFIX
   30.85 +			       "Unable to map XSDT header\n");
   30.86 +			return -ENODEV;
   30.87 +		}
   30.88 +
   30.89 +		/* remap in the entire table before processing */
   30.90 +		mapped_xsdt = (struct acpi_table_xsdt *)
   30.91 +		    __acpi_map_table(sdt_pa, header->length);
   30.92 +		if (!mapped_xsdt) {
   30.93 +			printk(KERN_WARNING PREFIX "Unable to map XSDT\n");
   30.94 +			return -ENODEV;
   30.95 +		}
   30.96 +		header = &mapped_xsdt->header;
   30.97 +
   30.98 +		if (strncmp(header->signature, "XSDT", 4)) {
   30.99 +			printk(KERN_WARNING PREFIX
  30.100 +			       "XSDT signature incorrect\n");
  30.101 +			return -ENODEV;
  30.102 +		}
  30.103 +
  30.104 +		if (acpi_table_compute_checksum(header, header->length)) {
  30.105 +			printk(KERN_WARNING PREFIX "Invalid XSDT checksum\n");
  30.106 +			return -ENODEV;
  30.107 +		}
  30.108 +
  30.109 +		if (id < sdt_count) {
  30.110 +			header = (struct acpi_table_header *)
  30.111 +			   __acpi_map_table(mapped_xsdt->entry[id], sizeof(struct acpi_table_header));
  30.112 +		} else {
  30.113 +			printk(KERN_WARNING PREFIX
  30.114 +			       "Unable to disable entry %d\n",
  30.115 +			       id);
  30.116 +			return -ENODEV;
  30.117 +		}
  30.118 +	}
  30.119 +
  30.120 +	/* Then check RSDT */
  30.121 +
  30.122 +	else if (rsdp->rsdt_address) {
  30.123 +
  30.124 +		struct acpi_table_rsdt *mapped_rsdt = NULL;
  30.125 +
  30.126 +		sdt_pa = rsdp->rsdt_address;
  30.127 +
  30.128 +		/* map in just the header */
  30.129 +		header = (struct acpi_table_header *)
  30.130 +		    __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));
  30.131 +		if (!header) {
  30.132 +			printk(KERN_WARNING PREFIX
  30.133 +			       "Unable to map RSDT header\n");
  30.134 +			return -ENODEV;
  30.135 +		}
  30.136 +
  30.137 +		/* remap in the entire table before processing */
  30.138 +		mapped_rsdt = (struct acpi_table_rsdt *)
  30.139 +		    __acpi_map_table(sdt_pa, header->length);
  30.140 +		if (!mapped_rsdt) {
  30.141 +			printk(KERN_WARNING PREFIX "Unable to map RSDT\n");
  30.142 +			return -ENODEV;
  30.143 +		}
  30.144 +		header = &mapped_rsdt->header;
  30.145 +
  30.146 +		if (strncmp(header->signature, "RSDT", 4)) {
  30.147 +			printk(KERN_WARNING PREFIX
  30.148 +			       "RSDT signature incorrect\n");
  30.149 +			return -ENODEV;
  30.150 +		}
  30.151 +
  30.152 +		if (acpi_table_compute_checksum(header, header->length)) {
  30.153 +			printk(KERN_WARNING PREFIX "Invalid RSDT checksum\n");
  30.154 +			return -ENODEV;
  30.155 +		}
  30.156 +		if (id < sdt_count) {
  30.157 +			header = (struct acpi_table_header *)
  30.158 +			   __acpi_map_table(mapped_rsdt->entry[id], sizeof(struct acpi_table_header));
  30.159 +		} else {
  30.160 +			printk(KERN_WARNING PREFIX
  30.161 +			       "Unable to disable entry %d\n",
  30.162 +			       id);
  30.163 +			return -ENODEV;
  30.164 +		}
  30.165 +	}
  30.166 +
  30.167 +	else {
  30.168 +		printk(KERN_WARNING PREFIX
  30.169 +		       "No System Description Table (RSDT/XSDT) specified in RSDP\n");
  30.170 +		return -ENODEV;
  30.171 +	}
  30.172 +
  30.173 +	memcpy(header->signature, "OEMx", 4);
  30.174 +	memcpy(header->oem_id, "xxxxxx", 6);
  30.175 +	memcpy(header->oem_id+1, table_name, 4);
  30.176 +	memcpy(header->oem_table_id, "Xen     ", 8);
  30.177 +	header->checksum = 0;
  30.178 +	header->checksum = generate_acpi_checksum(header, header->length);
  30.179 +
  30.180 +	return 0;
  30.181 +}
    31.1 --- a/xen/include/asm-ia64/dom_fw_common.h	Thu Aug 02 09:50:55 2007 -0500
    31.2 +++ b/xen/include/asm-ia64/dom_fw_common.h	Thu Aug 02 09:54:18 2007 -0500
    31.3 @@ -85,7 +85,6 @@ void
    31.4  xen_ia64_efi_make_md(efi_memory_desc_t *md,
    31.5                       uint32_t type, uint64_t attr, 
    31.6                       uint64_t start, uint64_t end);
    31.7 -uint8_t generate_acpi_checksum(void *tbl, unsigned long len);
    31.8  struct fake_acpi_tables;
    31.9  void dom_fw_fake_acpi(domain_t *d, struct fake_acpi_tables *tables);
   31.10  int efi_mdt_cmp(const void *a, const void *b); 
    32.1 --- a/xen/include/asm-x86/hvm/hvm.h	Thu Aug 02 09:50:55 2007 -0500
    32.2 +++ b/xen/include/asm-x86/hvm/hvm.h	Thu Aug 02 09:54:18 2007 -0500
    32.3 @@ -154,7 +154,7 @@ struct hvm_function_table {
    32.4  
    32.5      void (*init_hypercall_page)(struct domain *d, void *hypercall_page);
    32.6  
    32.7 -    int  (*event_injection_faulted)(struct vcpu *v);
    32.8 +    int  (*event_pending)(struct vcpu *v);
    32.9  
   32.10      int  (*cpu_up)(void);
   32.11      void (*cpu_down)(void);
   32.12 @@ -229,7 +229,8 @@ hvm_guest_x86_mode(struct vcpu *v)
   32.13      return hvm_funcs.guest_x86_mode(v);
   32.14  }
   32.15  
   32.16 -int hvm_instruction_length(unsigned long pc, int address_bytes);
   32.17 +int hvm_instruction_fetch(unsigned long pc, int address_bytes,
   32.18 +                          unsigned char *buf);
   32.19  
   32.20  static inline void
   32.21  hvm_update_host_cr3(struct vcpu *v)
   32.22 @@ -295,25 +296,72 @@ hvm_inject_exception(unsigned int trapnr
   32.23  
   32.24  int hvm_bringup_ap(int vcpuid, int trampoline_vector);
   32.25  
   32.26 -static inline int hvm_event_injection_faulted(struct vcpu *v)
   32.27 +static inline int hvm_event_pending(struct vcpu *v)
   32.28  {
   32.29 -    return hvm_funcs.event_injection_faulted(v);
   32.30 +    return hvm_funcs.event_pending(v);
   32.31  }
   32.32  
   32.33 +/* These reserved bits in lower 32 remain 0 after any load of CR0 */
   32.34 +#define HVM_CR0_GUEST_RESERVED_BITS             \
   32.35 +    (~((unsigned long)                          \
   32.36 +       (X86_CR0_PE | X86_CR0_MP | X86_CR0_EM |  \
   32.37 +        X86_CR0_TS | X86_CR0_ET | X86_CR0_NE |  \
   32.38 +        X86_CR0_WP | X86_CR0_AM | X86_CR0_NW |  \
   32.39 +        X86_CR0_CD | X86_CR0_PG)))
   32.40 +
   32.41  /* These bits in CR4 are owned by the host. */
   32.42  #define HVM_CR4_HOST_MASK (mmu_cr4_features & \
   32.43      (X86_CR4_VMXE | X86_CR4_PAE | X86_CR4_MCE))
   32.44  
   32.45  /* These bits in CR4 cannot be set by the guest. */
   32.46 -#define HVM_CR4_GUEST_RESERVED_BITS \
   32.47 -    ~(X86_CR4_VME | X86_CR4_PVI | X86_CR4_TSD | \
   32.48 -      X86_CR4_DE  | X86_CR4_PSE | X86_CR4_PAE | \
   32.49 -      X86_CR4_MCE | X86_CR4_PGE | X86_CR4_PCE | \
   32.50 -      X86_CR4_OSFXSR | X86_CR4_OSXMMEXCPT)
   32.51 +#define HVM_CR4_GUEST_RESERVED_BITS                     \
   32.52 +    (~((unsigned long)                                  \
   32.53 +       (X86_CR4_VME | X86_CR4_PVI | X86_CR4_TSD |       \
   32.54 +        X86_CR4_DE  | X86_CR4_PSE | X86_CR4_PAE |       \
   32.55 +        X86_CR4_MCE | X86_CR4_PGE | X86_CR4_PCE |       \
   32.56 +        X86_CR4_OSFXSR | X86_CR4_OSXMMEXCPT)))
   32.57  
   32.58  /* These exceptions must always be intercepted. */
   32.59  #define HVM_TRAP_MASK (1U << TRAP_machine_check)
   32.60  
   32.61 +/*
   32.62 + * x86 event types. This enumeration is valid for:
   32.63 + *  Intel VMX: {VM_ENTRY,VM_EXIT,IDT_VECTORING}_INTR_INFO[10:8]
   32.64 + *  AMD SVM: eventinj[10:8] and exitintinfo[10:8] (types 0-4 only)
   32.65 + */
   32.66 +#define X86_EVENTTYPE_EXT_INTR              0    /* external interrupt */
   32.67 +#define X86_EVENTTYPE_NMI                   2    /* NMI                */
   32.68 +#define X86_EVENTTYPE_HW_EXCEPTION          3    /* hardware exception */
   32.69 +#define X86_EVENTTYPE_SW_INTERRUPT          4    /* software interrupt */
   32.70 +#define X86_EVENTTYPE_SW_EXCEPTION          6    /* software exception */
   32.71 +
   32.72 +/*
   32.73 + * Need to re-inject a given event? We avoid re-injecting software exceptions
   32.74 + * and interrupts because the faulting/trapping instruction can simply be
   32.75 + * re-executed (neither VMX nor SVM update RIP when they VMEXIT during
   32.76 + * INT3/INTO/INTn).
   32.77 + */
   32.78 +static inline int hvm_event_needs_reinjection(uint8_t type, uint8_t vector)
   32.79 +{
   32.80 +    switch ( type )
   32.81 +    {
   32.82 +    case X86_EVENTTYPE_EXT_INTR:
   32.83 +    case X86_EVENTTYPE_NMI:
   32.84 +        return 1;
   32.85 +    case X86_EVENTTYPE_HW_EXCEPTION:
   32.86 +        /*
   32.87 +         * SVM uses type 3 ("HW Exception") for #OF and #BP. We explicitly
   32.88 +         * check for these vectors, as they are really SW Exceptions. SVM has
   32.89 +         * not updated RIP to point after the trapping instruction (INT3/INTO).
   32.90 +         */
   32.91 +        return (vector != 3) && (vector != 4);
   32.92 +    default:
   32.93 +        /* Software exceptions/interrupts can be re-executed (e.g., INT n). */
   32.94 +        break;
   32.95 +    }
   32.96 +    return 0;
   32.97 +}
   32.98 +
   32.99  static inline int hvm_cpu_up(void)
  32.100  {
  32.101      if ( hvm_funcs.cpu_up )
    33.1 --- a/xen/include/asm-x86/hvm/svm/vmcb.h	Thu Aug 02 09:50:55 2007 -0500
    33.2 +++ b/xen/include/asm-x86/hvm/svm/vmcb.h	Thu Aug 02 09:54:18 2007 -0500
    33.3 @@ -320,14 +320,6 @@ typedef union
    33.4      } fields;
    33.5  } __attribute__ ((packed)) eventinj_t;
    33.6  
    33.7 -enum EVENTTYPES
    33.8 -{
    33.9 -    EVENTTYPE_INTR = 0,
   33.10 -    EVENTTYPE_NMI = 2,
   33.11 -    EVENTTYPE_EXCEPTION = 3,
   33.12 -    EVENTTYPE_SWINT = 4,
   33.13 -};
   33.14 -
   33.15  typedef union 
   33.16  {
   33.17      u64 bytes;
    34.1 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h	Thu Aug 02 09:50:55 2007 -0500
    34.2 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h	Thu Aug 02 09:54:18 2007 -0500
    34.3 @@ -67,9 +67,6 @@ struct arch_vmx_struct {
    34.4      /* Cache of cpu execution control. */
    34.5      u32                  exec_control;
    34.6  
    34.7 -    /* If there is vector installed in the INTR_INFO_FIELD. */
    34.8 -    u32                  vector_injected;
    34.9 -
   34.10      unsigned long        cpu_cr0; /* copy of guest CR0 */
   34.11      unsigned long        cpu_shadow_cr0; /* copy of guest read shadow CR0 */
   34.12      unsigned long        cpu_shadow_cr4; /* copy of guest read shadow CR4 */
   34.13 @@ -198,7 +195,7 @@ enum vmcs_field {
   34.14      VM_EXIT_MSR_LOAD_COUNT          = 0x00004010,
   34.15      VM_ENTRY_CONTROLS               = 0x00004012,
   34.16      VM_ENTRY_MSR_LOAD_COUNT         = 0x00004014,
   34.17 -    VM_ENTRY_INTR_INFO_FIELD        = 0x00004016,
   34.18 +    VM_ENTRY_INTR_INFO              = 0x00004016,
   34.19      VM_ENTRY_EXCEPTION_ERROR_CODE   = 0x00004018,
   34.20      VM_ENTRY_INSTRUCTION_LEN        = 0x0000401a,
   34.21      TPR_THRESHOLD                   = 0x0000401c,
   34.22 @@ -207,7 +204,7 @@ enum vmcs_field {
   34.23      VM_EXIT_REASON                  = 0x00004402,
   34.24      VM_EXIT_INTR_INFO               = 0x00004404,
   34.25      VM_EXIT_INTR_ERROR_CODE         = 0x00004406,
   34.26 -    IDT_VECTORING_INFO_FIELD        = 0x00004408,
   34.27 +    IDT_VECTORING_INFO              = 0x00004408,
   34.28      IDT_VECTORING_ERROR_CODE        = 0x0000440a,
   34.29      VM_EXIT_INSTRUCTION_LEN         = 0x0000440c,
   34.30      VMX_INSTRUCTION_INFO            = 0x0000440e,
    35.1 --- a/xen/include/asm-x86/hvm/vmx/vmx.h	Thu Aug 02 09:50:55 2007 -0500
    35.2 +++ b/xen/include/asm-x86/hvm/vmx/vmx.h	Thu Aug 02 09:54:18 2007 -0500
    35.3 @@ -94,11 +94,6 @@ void vmx_vlapic_msr_changed(struct vcpu 
    35.4  #define INTR_INFO_VALID_MASK            0x80000000      /* 31 */
    35.5  #define INTR_INFO_RESVD_BITS_MASK       0x7ffff000
    35.6  
    35.7 -#define INTR_TYPE_EXT_INTR              (0 << 8)    /* external interrupt */
    35.8 -#define INTR_TYPE_NMI                   (2 << 8)    /* NMI                */
    35.9 -#define INTR_TYPE_HW_EXCEPTION          (3 << 8)    /* hardware exception */
   35.10 -#define INTR_TYPE_SW_EXCEPTION          (6 << 8)    /* software exception */
   35.11 -
   35.12  /*
   35.13   * Exit Qualifications for MOV for Control Register Access
   35.14   */
   35.15 @@ -263,8 +258,8 @@ static inline int __vmxon (u64 addr)
   35.16      return rc;
   35.17  }
   35.18  
   35.19 -static inline void __vmx_inject_exception(struct vcpu *v, int trap, int type,
   35.20 -                                         int error_code, int ilen)
   35.21 +static inline void __vmx_inject_exception(
   35.22 +    struct vcpu *v, int trap, int type, int error_code)
   35.23  {
   35.24      unsigned long intr_fields;
   35.25  
   35.26 @@ -276,16 +271,13 @@ static inline void __vmx_inject_exceptio
   35.27       *   VM entry]", PRM Vol. 3, 22.6.1 (Interruptibility State).
   35.28       */
   35.29  
   35.30 -    intr_fields = (INTR_INFO_VALID_MASK | type | trap);
   35.31 +    intr_fields = (INTR_INFO_VALID_MASK | (type<<8) | trap);
   35.32      if ( error_code != VMX_DELIVER_NO_ERROR_CODE ) {
   35.33          __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
   35.34          intr_fields |= INTR_INFO_DELIVER_CODE_MASK;
   35.35      }
   35.36  
   35.37 -    if ( ilen )
   35.38 -      __vmwrite(VM_ENTRY_INSTRUCTION_LEN, ilen);
   35.39 -
   35.40 -    __vmwrite(VM_ENTRY_INTR_INFO_FIELD, intr_fields);
   35.41 +    __vmwrite(VM_ENTRY_INTR_INFO, intr_fields);
   35.42  
   35.43      if (trap == TRAP_page_fault)
   35.44          HVMTRACE_2D(PF_INJECT, v, v->arch.hvm_vmx.cpu_cr2, error_code);
   35.45 @@ -296,29 +288,19 @@ static inline void __vmx_inject_exceptio
   35.46  static inline void vmx_inject_hw_exception(
   35.47      struct vcpu *v, int trap, int error_code)
   35.48  {
   35.49 -    v->arch.hvm_vmx.vector_injected = 1;
   35.50 -    __vmx_inject_exception(v, trap, INTR_TYPE_HW_EXCEPTION, error_code, 0);
   35.51 -}
   35.52 -
   35.53 -static inline void vmx_inject_sw_exception(
   35.54 -    struct vcpu *v, int trap, int instruction_len)
   35.55 -{
   35.56 -    v->arch.hvm_vmx.vector_injected = 1;
   35.57 -    __vmx_inject_exception(v, trap, INTR_TYPE_SW_EXCEPTION,
   35.58 -                           VMX_DELIVER_NO_ERROR_CODE,
   35.59 -                           instruction_len);
   35.60 +    __vmx_inject_exception(v, trap, X86_EVENTTYPE_HW_EXCEPTION, error_code);
   35.61  }
   35.62  
   35.63  static inline void vmx_inject_extint(struct vcpu *v, int trap)
   35.64  {
   35.65 -    __vmx_inject_exception(v, trap, INTR_TYPE_EXT_INTR,
   35.66 -                           VMX_DELIVER_NO_ERROR_CODE, 0);
   35.67 +    __vmx_inject_exception(v, trap, X86_EVENTTYPE_EXT_INTR,
   35.68 +                           VMX_DELIVER_NO_ERROR_CODE);
   35.69  }
   35.70  
   35.71  static inline void vmx_inject_nmi(struct vcpu *v)
   35.72  {
   35.73 -    __vmx_inject_exception(v, 2, INTR_TYPE_NMI,
   35.74 -                           VMX_DELIVER_NO_ERROR_CODE, 0);
   35.75 +    __vmx_inject_exception(v, 2, X86_EVENTTYPE_NMI,
   35.76 +                           VMX_DELIVER_NO_ERROR_CODE);
   35.77  }
   35.78  
   35.79  #endif /* __ASM_X86_HVM_VMX_VMX_H__ */
    36.1 --- a/xen/include/public/libelf.h	Thu Aug 02 09:50:55 2007 -0500
    36.2 +++ b/xen/include/public/libelf.h	Thu Aug 02 09:54:18 2007 -0500
    36.3 @@ -65,6 +65,8 @@ struct elf_binary {
    36.4  
    36.5      /* loaded to */
    36.6      char *dest;
    36.7 +    uint64_t sstart;
    36.8 +    uint64_t send;
    36.9      uint64_t pstart;
   36.10      uint64_t pend;
   36.11      uint64_t reloc_offset;
   36.12 @@ -91,33 +93,32 @@ struct elf_binary {
   36.13  #define elf_lsb(elf)   (ELFDATA2LSB == (elf)->data)
   36.14  #define elf_swap(elf)  (NATIVE_ELFDATA != (elf)->data)
   36.15  
   36.16 -#define elf_uval(elf, str, elem)			\
   36.17 -	((ELFCLASS64 == (elf)->class)			\
   36.18 -	? elf_access_unsigned((elf), (str),		\
   36.19 -		offsetof(typeof(*(str)),e64.elem),	\
   36.20 -		sizeof((str)->e64.elem))		\
   36.21 -	: elf_access_unsigned((elf), (str),		\
   36.22 -		offsetof(typeof(*(str)),e32.elem),	\
   36.23 -		sizeof((str)->e32.elem)))
   36.24 +#define elf_uval(elf, str, elem)                                        \
   36.25 +    ((ELFCLASS64 == (elf)->class)                                       \
   36.26 +     ? elf_access_unsigned((elf), (str),                                \
   36.27 +                           offsetof(typeof(*(str)),e64.elem),           \
   36.28 +                           sizeof((str)->e64.elem))                     \
   36.29 +     : elf_access_unsigned((elf), (str),                                \
   36.30 +                           offsetof(typeof(*(str)),e32.elem),           \
   36.31 +                           sizeof((str)->e32.elem)))
   36.32  
   36.33 -#define elf_sval(elf, str, elem)			\
   36.34 -	((ELFCLASS64 == (elf)->class)			\
   36.35 -	? elf_access_signed((elf), (str),		\
   36.36 -		offsetof(typeof(*(str)),e64.elem),	\
   36.37 -		sizeof((str)->e64.elem))		\
   36.38 -	: elf_access_signed((elf), (str),		\
   36.39 -		offsetof(typeof(*(str)),e32.elem),	\
   36.40 -		sizeof((str)->e32.elem)))
   36.41 +#define elf_sval(elf, str, elem)                                        \
   36.42 +    ((ELFCLASS64 == (elf)->class)                                       \
   36.43 +     ? elf_access_signed((elf), (str),                                  \
   36.44 +                         offsetof(typeof(*(str)),e64.elem),             \
   36.45 +                         sizeof((str)->e64.elem))                       \
   36.46 +     : elf_access_signed((elf), (str),                                  \
   36.47 +                         offsetof(typeof(*(str)),e32.elem),             \
   36.48 +                         sizeof((str)->e32.elem)))
   36.49  
   36.50 -#define elf_size(elf, str)		\
   36.51 -	((ELFCLASS64 == (elf)->class)	\
   36.52 -	? sizeof((str)->e64)		\
   36.53 -	: sizeof((str)->e32))
   36.54 +#define elf_size(elf, str)                              \
   36.55 +    ((ELFCLASS64 == (elf)->class)                       \
   36.56 +     ? sizeof((str)->e64) : sizeof((str)->e32))
   36.57  
   36.58  uint64_t elf_access_unsigned(struct elf_binary *elf, const void *ptr,
   36.59 -			     uint64_t offset, size_t size);
   36.60 +                             uint64_t offset, size_t size);
   36.61  int64_t elf_access_signed(struct elf_binary *elf, const void *ptr,
   36.62 -			  uint64_t offset, size_t size);
   36.63 +                          uint64_t offset, size_t size);
   36.64  
   36.65  uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr);
   36.66  
   36.67 @@ -149,6 +150,11 @@ const elf_note *elf_note_next(struct elf
   36.68  int elf_is_elfbinary(const void *image);
   36.69  int elf_phdr_is_loadable(struct elf_binary *elf, const elf_phdr * phdr);
   36.70  
   36.71 +unsigned long elf_copy_ehdr(struct elf_binary *elf, void *dest);
   36.72 +unsigned long elf_copy_shdr(struct elf_binary *elf, void *dest);
   36.73 +unsigned long elf_copy_section(struct elf_binary *elf,
   36.74 +                               const elf_shdr *shdr, void *dest);
   36.75 +
   36.76  /* ------------------------------------------------------------------------ */
   36.77  /* xc_libelf_loader.c                                                       */
   36.78  
   36.79 @@ -185,8 +191,8 @@ struct xen_elfnote {
   36.80      enum xen_elfnote_type type;
   36.81      const char *name;
   36.82      union {
   36.83 -	const char *str;
   36.84 -	uint64_t num;
   36.85 +        const char *str;
   36.86 +        uint64_t num;
   36.87      } data;
   36.88  };
   36.89  
   36.90 @@ -215,7 +221,8 @@ struct elf_dom_parms {
   36.91      /* calculated */
   36.92      uint64_t virt_offset;
   36.93      uint64_t virt_kstart;
   36.94 -    uint64_t virt_kend;
   36.95 +    uint64_t virt_kend; /* end of kernel image */
   36.96 +    uint64_t virt_end;  /* end of kernel symtab (== virt_kend if none) */
   36.97  };
   36.98  
   36.99  static inline void elf_xen_feature_set(int nr, uint32_t * addr)
  36.100 @@ -228,14 +235,17 @@ static inline int elf_xen_feature_get(in
  36.101  }
  36.102  
  36.103  int elf_xen_parse_features(const char *features,
  36.104 -			   uint32_t *supported,
  36.105 -			   uint32_t *required);
  36.106 +                           uint32_t *supported,
  36.107 +                           uint32_t *required);
  36.108  int elf_xen_parse_note(struct elf_binary *elf,
  36.109 -		       struct elf_dom_parms *parms,
  36.110 -		       const elf_note *note);
  36.111 +                       struct elf_dom_parms *parms,
  36.112 +                       const elf_note *note);
  36.113  int elf_xen_parse_guest_info(struct elf_binary *elf,
  36.114 -			     struct elf_dom_parms *parms);
  36.115 +                             struct elf_dom_parms *parms);
  36.116  int elf_xen_parse(struct elf_binary *elf,
  36.117 -		  struct elf_dom_parms *parms);
  36.118 +                  struct elf_dom_parms *parms);
  36.119 +
  36.120 +int elf_xen_dom_load_binary(struct elf_binary *elf,
  36.121 +                            struct elf_dom_parms *parms);
  36.122  
  36.123  #endif /* __XC_LIBELF__ */
    37.1 --- a/xen/include/xen/acpi.h	Thu Aug 02 09:50:55 2007 -0500
    37.2 +++ b/xen/include/xen/acpi.h	Thu Aug 02 09:54:18 2007 -0500
    37.3 @@ -383,6 +383,7 @@ int acpi_boot_table_init (void);
    37.4  int acpi_numa_init (void);
    37.5  
    37.6  int acpi_table_init (void);
    37.7 +int acpi_table_disable(enum acpi_table_id table_id);
    37.8  int acpi_table_parse (enum acpi_table_id id, acpi_table_handler handler);
    37.9  int acpi_get_table_header_early (enum acpi_table_id id, struct acpi_table_header **header);
   37.10  int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries);
   37.11 @@ -390,6 +391,7 @@ int acpi_table_parse_srat (enum acpi_sra
   37.12  void acpi_table_print (struct acpi_table_header *header, unsigned long phys_addr);
   37.13  void acpi_table_print_madt_entry (acpi_table_entry_header *madt);
   37.14  void acpi_table_print_srat_entry (acpi_table_entry_header *srat);
   37.15 +uint8_t generate_acpi_checksum(void *tbl, unsigned long len);
   37.16  
   37.17  /* the following four functions are architecture-dependent */
   37.18  void acpi_numa_slit_init (struct acpi_table_slit *slit);
   37.19 @@ -534,6 +536,5 @@ static inline int acpi_get_pxm(acpi_hand
   37.20  #endif
   37.21  
   37.22  extern int pnpacpi_disabled;
   37.23 -extern unsigned char acpi_rsdp_rev;
   37.24  
   37.25  #endif /*_LINUX_ACPI_H*/