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 - { 22.36 - c->pending_event = vmcb->exitintinfo.bytes & 0xffffffff; 22.37 - c->error_code = vmcb->exitintinfo.fields.errorcode; 22.38 - } 22.39 - else if ( vmcb->eventinj.fields.v ) 22.40 + c->pending_event = 0; 22.41 + c->error_code = 0; 22.42 + if ( vmcb->eventinj.fields.v && 22.43 + hvm_event_needs_reinjection(vmcb->eventinj.fields.type, 22.44 + vmcb->eventinj.fields.vector) ) 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*/