# HG changeset patch
# User emellor@xxxxxxxxxxxxxxxxxxxxxx
# Node ID d3b10a2a82d47bb3e52faf2fa4ba27217f486c54
# Parent 11cd619db03540476cef8ec523d46d9a1d13973c
# Parent 931acb64fbaf762fd47f9035b411ae6f1b5cb50b
Merged.
diff -r 11cd619db035 -r d3b10a2a82d4 Makefile
--- a/Makefile Tue Dec 20 17:16:15 2005
+++ b/Makefile Tue Dec 20 17:16:24 2005
@@ -10,7 +10,7 @@
# Export target architecture overrides to Xen and Linux sub-trees.
ifneq ($(XEN_TARGET_ARCH),)
SUBARCH := $(subst x86_32,i386,$(XEN_TARGET_ARCH))
-export XEN_TARGET_ARCH SUBARCH
+export XEN_TARGET_ARCH SUBARCH XEN_SYSTYPE
endif
# Default target must appear before any include lines
diff -r 11cd619db035 -r d3b10a2a82d4 buildconfigs/mk.linux-2.6-xen
--- a/buildconfigs/mk.linux-2.6-xen Tue Dec 20 17:16:15 2005
+++ b/buildconfigs/mk.linux-2.6-xen Tue Dec 20 17:16:24 2005
@@ -30,7 +30,7 @@
CONFIG_VERSION=$$(sed -ne 's/^EXTRAVERSION = //p'
$(LINUX_DIR)/Makefile); \
[ -r
$(DESTDIR)/boot/config-$(LINUX_VER)$$CONFIG_VERSION-$(EXTRAVERSION) ] && \
cp
$(DESTDIR)/boot/config-$(LINUX_VER)$$CONFIG_VERSION-$(EXTRAVERSION)
$(LINUX_DIR)/.config \
- || cp
$(LINUX_DIR)/arch/xen/configs/$(EXTRAVERSION)_defconfig_$(XEN_TARGET_ARCH) \
+ || cp
$(LINUX_DIR)/arch/xen/configs/$(EXTRAVERSION)_defconfig_$(XEN_TARGET_ARCH)$(XEN_SYSTYPE)
\
$(LINUX_DIR)/.config
# See if we need to munge config to enable PAE
$(MAKE) CONFIG_FILE=$(LINUX_DIR)/.config -f buildconfigs/Rules.mk
config-update-pae
diff -r 11cd619db035 -r d3b10a2a82d4
linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c Tue Dec 20 17:16:15 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c Tue Dec 20 17:16:24 2005
@@ -186,8 +186,7 @@
static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
{
struct mm_struct * mm = current->mm;
- __u32 entry_1, entry_2, *lp;
- maddr_t mach_lp;
+ __u32 entry_1, entry_2;
int error;
struct user_desc ldt_info;
@@ -215,9 +214,6 @@
goto out_unlock;
}
- lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *)
mm->context.ldt);
- mach_lp = arbitrary_virt_to_machine(lp);
-
/* Allow LDTs to be cleared by the user. */
if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
if (oldmode || LDT_empty(&ldt_info)) {
@@ -234,8 +230,8 @@
/* Install the new entry ... */
install:
- error = HYPERVISOR_update_descriptor(
- mach_lp, (u64)entry_1 | ((u64)entry_2<<32));
+ error = write_ldt_entry(mm->context.ldt, ldt_info.entry_number,
+ entry_1, entry_2);
out_unlock:
up(&mm->context.sem);
diff -r 11cd619db035 -r d3b10a2a82d4
linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c Tue Dec 20
17:16:15 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c Tue Dec 20
17:16:24 2005
@@ -24,6 +24,7 @@
#include <asm/io.h>
#include <asm/pci.h>
#include <asm/dma.h>
+#include <asm/uaccess.h>
#include <asm-xen/xen-public/memory.h>
#define OFFSET(val,align) ((unsigned long)((val) & ( (align) - 1)))
@@ -201,6 +202,12 @@
printk(KERN_INFO "Software IO TLB disabled\n");
}
+/*
+ * We use __copy_to_user to transfer to the host buffer because the buffer
+ * may be mapped read-only (e.g, in blkback driver) but lower-level
+ * drivers map the buffer for DMA_BIDIRECTIONAL access. This causes an
+ * unnecessary copy from the aperture to the host buffer, and a page fault.
+ */
static void
__sync_single(struct phys_addr buffer, char *dma_addr, size_t size, int dir)
{
@@ -214,9 +221,11 @@
kmp = kmap_atomic(buffer.page, KM_SWIOTLB);
dev = dma_addr + size - len;
host = kmp + buffer.offset;
- memcpy((dir == DMA_FROM_DEVICE) ? host : dev,
- (dir == DMA_FROM_DEVICE) ? dev : host,
- bytes);
+ if (dir == DMA_FROM_DEVICE) {
+ if (__copy_to_user(host, dev, bytes))
+ /* inaccessible */;
+ } else
+ memcpy(dev, host, bytes);
kunmap_atomic(kmp, KM_SWIOTLB);
len -= bytes;
buffer.page++;
@@ -225,9 +234,10 @@
} else {
char *host = (char *)phys_to_virt(
page_to_pseudophys(buffer.page)) + buffer.offset;
- if (dir == DMA_FROM_DEVICE)
- memcpy(host, dma_addr, size);
- else if (dir == DMA_TO_DEVICE)
+ if (dir == DMA_FROM_DEVICE) {
+ if (__copy_to_user(host, dma_addr, size))
+ /* inaccessible */;
+ } else if (dir == DMA_TO_DEVICE)
memcpy(dma_addr, host, size);
}
}
diff -r 11cd619db035 -r d3b10a2a82d4
linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c Tue Dec 20
17:16:15 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c Tue Dec 20
17:16:24 2005
@@ -438,6 +438,16 @@
balloon_unlock(flags);
}
+#ifdef __i386__
+int write_ldt_entry(void *ldt, int entry, __u32 entry_a, __u32 entry_b)
+{
+ __u32 *lp = (__u32 *)((char *)ldt + entry * 8);
+ maddr_t mach_lp = arbitrary_virt_to_machine(lp);
+ return HYPERVISOR_update_descriptor(
+ mach_lp, (u64)entry_a | ((u64)entry_b<<32));
+}
+#endif
+
/*
* Local variables:
* c-file-style: "linux"
diff -r 11cd619db035 -r d3b10a2a82d4
linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c Tue Dec 20 17:16:15 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c Tue Dec 20 17:16:24 2005
@@ -163,11 +163,10 @@
while (l1 != 0) {
l1i = __ffs(l1);
l1 &= ~(1UL << l1i);
-
+
while ((l2 = active_evtchns(cpu, s, l1i)) != 0) {
l2i = __ffs(l2);
- l2 &= ~(1UL << l2i);
-
+
port = (l1i * BITS_PER_LONG) + l2i;
if ((irq = evtchn_to_irq[port]) != -1)
do_IRQ(irq, regs);
diff -r 11cd619db035 -r d3b10a2a82d4
linux-2.6-xen-sparse/include/asm-xen/asm-i386/desc.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/desc.h Tue Dec 20
17:16:15 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/desc.h Tue Dec 20
17:16:24 2005
@@ -87,6 +87,8 @@
(info)->seg_not_present == 1 && \
(info)->useable == 0 )
+extern int write_ldt_entry(void *ldt, int entry, __u32 entry_a, __u32 entry_b);
+
#if TLS_SIZE != 24
# error update this code.
#endif
diff -r 11cd619db035 -r d3b10a2a82d4
tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c
--- a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c
Tue Dec 20 17:16:15 2005
+++ b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c
Tue Dec 20 17:16:24 2005
@@ -36,11 +36,26 @@
#include <unistd.h>
#include <errno.h>
#include <xenctrl.h>
+#include <thread_db.h>
+#include <xc_ptrace.h>
+
#define TRACE_ENTER /* printf("enter %s\n", __FUNCTION__) */
long (*myptrace)(int xc_handle, enum __ptrace_request, uint32_t, long, long);
int (*myxcwait)(int xc_handle, int domain, int *status, int options) ;
static int xc_handle;
+
+static inline int
+curvcpuid()
+{
+ struct process_info *process;
+ if (current_inferior == NULL)
+ return 0;
+ process = get_thread_process(current_inferior);
+ return (process->thread_known ? process->tid : 0);
+
+}
+
#define DOMFLAGS_DYING (1<<0) /* Domain is scheduled to die. */
#define DOMFLAGS_SHUTDOWN (1<<2) /* The guest OS has shut down. */
@@ -48,11 +63,14 @@
#define DOMFLAGS_BLOCKED (1<<4) /* Currently blocked pending an event. */
#define DOMFLAGS_RUNNING (1<<5) /* Domain is currently running. */
+
+
struct inferior_list all_processes;
-static int current_domain;
+static int current_domid;
static int expect_signal = 0;
static int signal_to_send = 0;
static void linux_resume (struct thread_resume *resume_info);
+static void linux_set_inferior (void);
int debug_threads;
int using_threads;
@@ -96,7 +114,6 @@
point at the following instruction. If we continue and hit a
breakpoint instruction, our PC will point at the breakpoint
instruction. */
-#if 0
static CORE_ADDR
get_stop_pc (void)
{
@@ -107,9 +124,9 @@
else
return stop_pc - the_low_target.decr_pc_after_break;
}
-#endif
+
static void *
-add_process (int pid)
+add_process (int pid, long tid)
{
struct process_info *process;
@@ -118,9 +135,8 @@
process->head.id = pid;
- /* Default to tid == lwpid == pid. */
- process->tid = pid;
- process->lwpid = pid;
+ process->tid = tid;
+ process->lwpid = tid;
add_inferior_to_list (&all_processes, &process->head);
@@ -143,23 +159,25 @@
}
int
-linux_attach (int domain)
+linux_attach (int domid)
{
struct process_info *new_process;
- current_domain = domain;
- if (myptrace (xc_handle, PTRACE_ATTACH, domain, 0, 0) != 0) {
- fprintf (stderr, "Cannot attach to domain %d: %s (%d)\n", domain,
+ current_domid = domid;
+ /* this is handled for all active vcpus in PTRACE_ATTACH via the
thread_create_callback */
+ new_process = (struct process_info *) add_process (domid, curvcpuid());
+ /* Don't ignore the initial SIGSTOP if we just attached to this process.
*/
+ /* vcpuid == 0 */
+ add_thread (0, new_process);
+ new_process->stop_expected = 0;
+
+ if (myptrace (xc_handle, PTRACE_ATTACH, domid, 0, 0) != 0) {
+ fprintf (stderr, "Cannot attach to domain %d: %s (%d)\n", domid,
strerror (errno), errno);
fflush (stderr);
- _exit (0177);
- }
-
- new_process = (struct process_info *) add_process (domain);
- add_thread (domain, new_process);
-
- /* Don't ignore the initial SIGSTOP if we just attached to this process.
*/
- new_process->stop_expected = 0;
-
+ if (!using_threads)
+ _exit (0177);
+ }
+
return 0;
}
@@ -173,20 +191,18 @@
myptrace (xc_handle, PTRACE_KILL, pid_of (process), 0, 0);
}
+
static void
linux_kill (void)
{
for_each_inferior (&all_threads, linux_kill_one_process);
}
-
static void
linux_detach_one_process (struct inferior_list_entry *entry)
{
- struct thread_info *thread = (struct thread_info *) entry;
- struct process_info *process = get_thread_process (thread);
-
- myptrace (xc_handle, PTRACE_DETACH, pid_of (process), 0, 0);
+
+ myptrace (xc_handle, PTRACE_DETACH, current_domid, 0, 0);
}
@@ -212,14 +228,10 @@
linux_wait (char *status)
{
int w;
- if (myxcwait(xc_handle, current_domain, &w, 0))
+ if (myxcwait(xc_handle, current_domid, &w, 0))
return -1;
- if (w & (DOMFLAGS_SHUTDOWN|DOMFLAGS_DYING)) {
- *status = 'W';
- return 0;
- }
-
+ linux_set_inferior();
*status = 'T';
if (expect_signal)
@@ -236,8 +248,10 @@
TRACE_ENTER;
expect_signal = resume_info->sig;
for_each_inferior(&all_threads, regcache_invalidate_one);
-
- myptrace (xc_handle, step ? PTRACE_SINGLESTEP : PTRACE_CONT, current_domain,
0, 0);
+ if (debug_threads)
+ fprintf(stderr, "step: %d\n", step);
+ myptrace (xc_handle, step ? PTRACE_SINGLESTEP : PTRACE_CONT,
+ resume_info->thread, 0, 0);
}
@@ -261,7 +275,9 @@
}
buf = malloc (regset->size);
- res = myptrace (xc_handle, regset->get_request, inferior_pid, 0,
(PTRACE_XFER_TYPE)buf);
+ res = myptrace (xc_handle, regset->get_request,
+ curvcpuid(),
+ 0, (PTRACE_XFER_TYPE)buf);
if (res < 0)
{
if (errno == EIO)
@@ -313,7 +329,7 @@
buf = malloc (regset->size);
regset->fill_function (buf);
- res = myptrace (xc_handle, regset->set_request, inferior_pid, 0,
(PTRACE_XFER_TYPE)buf);
+ res = myptrace (xc_handle, regset->set_request, curvcpuid(), 0,
(PTRACE_XFER_TYPE)buf);
if (res < 0)
{
if (errno == EIO)
@@ -391,7 +407,7 @@
for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
{
errno = 0;
- buffer[i] = myptrace (xc_handle, PTRACE_PEEKTEXT, inferior_pid,
(PTRACE_ARG3_TYPE) addr, 0);
+ buffer[i] = myptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(),
(PTRACE_ARG3_TYPE) addr, 0);
if (errno)
return errno;
}
@@ -424,13 +440,13 @@
/* Fill start and end extra bytes of buffer with existing memory data. */
- buffer[0] = myptrace (xc_handle, PTRACE_PEEKTEXT, inferior_pid,
+ buffer[0] = myptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(),
(PTRACE_ARG3_TYPE) addr, 0);
if (count > 1)
{
buffer[count - 1]
- = myptrace (xc_handle, PTRACE_PEEKTEXT, inferior_pid,
+ = myptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(),
(PTRACE_ARG3_TYPE) (addr + (count - 1)
* sizeof (PTRACE_XFER_TYPE)),
0);
@@ -444,7 +460,8 @@
for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
{
errno = 0;
- myptrace (xc_handle, PTRACE_POKETEXT, inferior_pid, (PTRACE_ARG3_TYPE)
addr, buffer[i]);
+ myptrace (xc_handle, PTRACE_POKETEXT, curvcpuid(),
+ (PTRACE_ARG3_TYPE) addr, buffer[i]);
if (errno)
return errno;
}
@@ -455,9 +472,11 @@
static void
linux_look_up_symbols (void)
{
-#if 0
+ if (using_threads)
+ return;
+
using_threads = thread_db_init ();
-#endif
+
}
static void
@@ -535,6 +554,7 @@
void
initialize_low (void)
{
+ using_threads = 0;
xc_handle = xc_interface_open();
set_target_ops (&linux_xen_target_ops);
set_breakpoint_data (the_low_target.breakpoint,
@@ -548,5 +568,122 @@
myptrace = xc_ptrace;
myxcwait = xc_waitdomain;
}
-
-}
+ using_threads = thread_db_init ();
+
+}
+
+
+static void
+thread_create_callback(long vcpuid)
+{
+ struct thread_info *inferior;
+ struct process_info *process;
+
+ /* If we are attaching to our first thread, things are a little
+ * different.
+ */
+ if (all_threads.head == all_threads.tail)
+ {
+ inferior = (struct thread_info *) all_threads.head;
+ process = get_thread_process (inferior);
+ if (process->thread_known == 0)
+ {
+ /* Switch to indexing the threads list by TID. */
+ change_inferior_id (&all_threads, vcpuid);
+ goto found;
+ }
+ }
+ if (debug_threads)
+ fprintf (stderr, "looking up thread %ld\n",
+ vcpuid);
+ inferior = (struct thread_info *) find_inferior_id (&all_threads,
+ vcpuid);
+ /* if vcpu alread registered - do nothing */
+ if (inferior != NULL)
+ return;
+
+ if (debug_threads)
+ fprintf (stderr, "Attaching to thread %ld\n",
+ vcpuid);
+
+ process = add_process(current_domid, vcpuid);
+
+ add_thread(vcpuid, process);
+ inferior = (struct thread_info *) find_inferior_id (&all_threads,
+ vcpuid);
+ if (inferior == NULL)
+ {
+ warning ("Could not attach to thread %ld\n",
+ vcpuid);
+ return;
+ }
+
+
+found:
+ if (debug_threads)
+ fprintf (stderr, "notifying of new thread %ld\n",
+ vcpuid);
+ new_thread_notify (vcpuid);
+
+ process->tid = vcpuid;
+ process->lwpid = vcpuid;
+
+ process->thread_known = 1;
+}
+
+static void
+thread_death_callback(long vcpuid)
+{
+ if (debug_threads)
+ fprintf (stderr, "Buuurp...! CPU down event.\n");
+}
+
+int
+thread_db_init(void)
+{
+ debug_threads = 0;
+ xc_register_event_handler(thread_create_callback, TD_CREATE);
+ xc_register_event_handler(thread_death_callback, TD_DEATH);
+ return 1;
+}
+
+/* XXX GAG ME */
+static int breakpoint_found;
+static void
+set_breakpoint_inferior (struct inferior_list_entry *entry)
+{
+ struct thread_info *thread = (struct thread_info *) entry;
+ struct thread_info *saved_inferior = current_inferior;
+ CORE_ADDR eip;
+ unsigned char buf[2] = {0, 0};
+ current_inferior = thread;
+ if (!breakpoint_found) {
+ eip = get_stop_pc();
+ linux_read_memory(eip, buf, 1);
+ if (buf[0] == 0xcc) {
+ breakpoint_found = 1;
+ return;
+ }
+ } else if (breakpoint_found == 2) {
+ if (get_thread_process (current_inferior)->stepping) {
+ printf("stepping\n");
+ breakpoint_found = 1;
+ return;
+ }
+ }
+ current_inferior = saved_inferior;
+
+
+}
+
+static void
+linux_set_inferior (void)
+{
+ breakpoint_found = 0;
+ for_each_inferior (&all_threads, set_breakpoint_inferior);
+ if (!breakpoint_found) {
+ breakpoint_found = 2;
+ for_each_inferior (&all_threads, set_breakpoint_inferior);
+ }
+}
+
diff -r 11cd619db035 -r d3b10a2a82d4
tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/server.c
--- a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/server.c Tue Dec
20 17:16:15 2005
+++ b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/server.c Tue Dec
20 17:16:24 2005
@@ -20,7 +20,7 @@
Boston, MA 02111-1307, USA. */
#include "server.h"
-
+#include "linux-low.h"
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
@@ -102,7 +102,15 @@
strcpy (own_buf, "OK");
return;
}
-
+ if (strcmp ("qC", own_buf) == 0)
+ {
+ struct process_info *process;
+ if (current_inferior == NULL)
+ return;
+ process = get_thread_process(current_inferior);
+ sprintf(own_buf, "QC%x", process->thread_known ? process->tid : 0);
+
+ }
if (strcmp ("qfThreadInfo", own_buf) == 0)
{
thread_ptr = all_threads.head;
diff -r 11cd619db035 -r d3b10a2a82d4 tools/examples/xend-config.sxp
--- a/tools/examples/xend-config.sxp Tue Dec 20 17:16:15 2005
+++ b/tools/examples/xend-config.sxp Tue Dec 20 17:16:24 2005
@@ -4,9 +4,9 @@
# Xend configuration file.
#
-# This example configuration is appropriate for an installation that trusts
-# only localhost connections, and is otherwise fully functional, with a
-# bridged network configuration.
+# This example configuration is appropriate for an installation that
+# utilizes a bridged network configuration. Access to xend via http
+# is disabled.
# Commented out entries show the default for that entry, unless otherwise
# specified.
@@ -15,7 +15,6 @@
#(loglevel DEBUG)
#(xend-http-server no)
-(xend-http-server yes)
#(xend-unix-server yes)
#(xend-relocation-server no)
(xend-relocation-server yes)
@@ -34,7 +33,7 @@
# Specifying 'localhost' prevents remote connections.
# Specifying the empty string '' (the default) allows all connections.
#(xend-address '')
-(xend-address localhost)
+#(xend-address localhost)
# Address xend should listen on for relocation-socket connections, if
# xend-relocation-server is set.
diff -r 11cd619db035 -r d3b10a2a82d4 tools/examples/xmexample.vmx
--- a/tools/examples/xmexample.vmx Tue Dec 20 17:16:15 2005
+++ b/tools/examples/xmexample.vmx Tue Dec 20 17:16:24 2005
@@ -135,7 +135,7 @@
#-----------------------------------------------------------------------------
# enable audio support
-#enable-audio=1
+#audio=1
#-----------------------------------------------------------------------------
diff -r 11cd619db035 -r d3b10a2a82d4 tools/ioemu/cpu-all.h
--- a/tools/ioemu/cpu-all.h Tue Dec 20 17:16:15 2005
+++ b/tools/ioemu/cpu-all.h Tue Dec 20 17:16:24 2005
@@ -668,7 +668,7 @@
#endif
/* memory API */
-extern int phys_ram_size;
+extern uint64_t phys_ram_size;
extern int phys_ram_fd;
extern uint8_t *phys_ram_base;
extern uint8_t *phys_ram_dirty;
diff -r 11cd619db035 -r d3b10a2a82d4 tools/ioemu/exec.c
--- a/tools/ioemu/exec.c Tue Dec 20 17:16:15 2005
+++ b/tools/ioemu/exec.c Tue Dec 20 17:16:24 2005
@@ -61,7 +61,7 @@
uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE];
uint8_t *code_gen_ptr;
-int phys_ram_size;
+uint64_t phys_ram_size;
int phys_ram_fd;
uint8_t *phys_ram_base;
uint8_t *phys_ram_dirty;
diff -r 11cd619db035 -r d3b10a2a82d4 tools/ioemu/hw/pc.c
--- a/tools/ioemu/hw/pc.c Tue Dec 20 17:16:15 2005
+++ b/tools/ioemu/hw/pc.c Tue Dec 20 17:16:24 2005
@@ -119,7 +119,7 @@
}
/* hd_table must contain 4 block drivers */
-static void cmos_init(int ram_size, int boot_device, BlockDriverState
**hd_table)
+static void cmos_init(uint64_t ram_size, int boot_device, BlockDriverState
**hd_table)
{
RTCState *s = rtc_state;
int val;
@@ -375,7 +375,7 @@
#define NOBIOS 1
/* PC hardware initialisation */
-void pc_init(int ram_size, int vga_ram_size, int boot_device,
+void pc_init(uint64_t ram_size, int vga_ram_size, int boot_device,
DisplayState *ds, const char **fd_filename, int snapshot,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename)
@@ -563,6 +563,15 @@
kbd_init();
DMA_init(0);
+
+ if (audio_enabled) {
+ AUD_init();
+#ifdef USE_SB16
+ if (sb16_enabled)
+ SB16_init();
+#endif
+ }
+
floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table);
diff -r 11cd619db035 -r d3b10a2a82d4 tools/ioemu/hw/pcnet.h
--- a/tools/ioemu/hw/pcnet.h Tue Dec 20 17:16:15 2005
+++ b/tools/ioemu/hw/pcnet.h Tue Dec 20 17:16:24 2005
@@ -92,7 +92,7 @@
#define CSR_NRBA(S) ((S)->csr[22] | ((S)->csr[23] << 16))
#define CSR_BADR(S) ((S)->csr[24] | ((S)->csr[25] << 16))
#define CSR_NRDA(S) ((S)->csr[26] | ((S)->csr[27] << 16))
-#define CSR_CRDA(S) ((S)->csr[28] | ((S)->csr[29] << 16))
+#define CSR_CRDA(S) ((S)->csr[28] | (((uint32_t)((S)->csr[29])) << 16))
#define CSR_BADX(S) ((S)->csr[30] | ((S)->csr[31] << 16))
#define CSR_NXDA(S) ((S)->csr[32] | ((S)->csr[33] << 16))
#define CSR_CXDA(S) ((S)->csr[34] | ((S)->csr[35] << 16))
@@ -102,7 +102,7 @@
#define CSR_NXBA(S) ((S)->csr[64] | ((S)->csr[65] << 16))
#define PHYSADDR(S,A) \
- (BCR_SSIZE32(S) ? (A) : (A) | ((0xff00 & (uint32_t)(s)->csr[2])<<16))
+ (BCR_SSIZE32(S) ? (A) : (A) | ((0xff00 & (uint32_t)(S)->csr[2])<<16))
struct pcnet_initblk16 {
uint16_t mode;
diff -r 11cd619db035 -r d3b10a2a82d4 tools/ioemu/target-i386-dm/Makefile
--- a/tools/ioemu/target-i386-dm/Makefile Tue Dec 20 17:16:15 2005
+++ b/tools/ioemu/target-i386-dm/Makefile Tue Dec 20 17:16:24 2005
@@ -272,6 +272,7 @@
VL_OBJS+= ide.o ne2000.o pckbd.o vga.o dma.o
VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259_stub.o i8254.o pc.o port-e9.o
VL_OBJS+= cirrus_vga.o pcnet.o
+VL_OBJS+= $(SOUND_HW) $(AUDIODRV) mixeng.o
ifeq ($(TARGET_ARCH), ppc)
VL_OBJS+= ppc.o ide.o ne2000.o pckbd.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
diff -r 11cd619db035 -r d3b10a2a82d4 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c Tue Dec 20 17:16:15 2005
+++ b/tools/ioemu/vl.c Tue Dec 20 17:16:24 2005
@@ -119,7 +119,7 @@
const char* keyboard_layout = 0;
int64_t ticks_per_sec;
int boot_device = 'c';
-int ram_size;
+uint64_t ram_size;
int domid = -1;
static char network_script[1024];
int pit_min_timer_count = 0;
@@ -2906,7 +2906,7 @@
help();
break;
case QEMU_OPTION_m:
- ram_size = atoi(optarg) * 1024 * 1024;
+ ram_size = atol(optarg) * 1024 * 1024;
if (ram_size <= 0)
help();
break;
diff -r 11cd619db035 -r d3b10a2a82d4 tools/ioemu/vl.h
--- a/tools/ioemu/vl.h Tue Dec 20 17:16:15 2005
+++ b/tools/ioemu/vl.h Tue Dec 20 17:16:24 2005
@@ -37,6 +37,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
+#include "audio/audio.h"
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
@@ -116,7 +117,7 @@
extern int sb16_enabled;
extern int adlib_enabled;
extern int gus_enabled;
-extern int ram_size;
+extern uint64_t ram_size;
extern int bios_size;
extern int rtc_utc;
extern int cirrus_vga_enabled;
@@ -649,7 +650,7 @@
int pit_get_out(PITState *pit, int channel, int64_t current_time);
/* pc.c */
-void pc_init(int ram_size, int vga_ram_size, int boot_device,
+void pc_init(uint64_t ram_size, int vga_ram_size, int boot_device,
DisplayState *ds, const char **fd_filename, int snapshot,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename);
diff -r 11cd619db035 -r d3b10a2a82d4 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c Tue Dec 20 17:16:15 2005
+++ b/tools/libxc/xc_domain.c Tue Dec 20 17:16:24 2005
@@ -380,6 +380,30 @@
return do_dom0_op(xc_handle, &op);
}
+int xc_domain_setinfo(int xc_handle,
+ uint32_t domid,
+ uint32_t vcpu,
+ vcpu_guest_context_t *ctxt)
+{
+ dom0_op_t op;
+ int rc;
+
+ op.cmd = DOM0_SETDOMAININFO;
+ op.u.setdomaininfo.domain = domid;
+ op.u.setdomaininfo.vcpu = vcpu;
+ op.u.setdomaininfo.ctxt = ctxt;
+
+ if ( (rc = mlock(ctxt, sizeof(*ctxt))) != 0 )
+ return rc;
+
+ rc = do_dom0_op(xc_handle, &op);
+
+ safe_munlock(ctxt, sizeof(*ctxt));
+
+ return rc;
+
+}
+
/*
* Local variables:
* mode: C
diff -r 11cd619db035 -r d3b10a2a82d4 tools/libxc/xc_ptrace.c
--- a/tools/libxc/xc_ptrace.c Tue Dec 20 17:16:15 2005
+++ b/tools/libxc/xc_ptrace.c Tue Dec 20 17:16:24 2005
@@ -1,130 +1,134 @@
+#define XC_PTRACE_PRIVATE
+
+
#include <sys/ptrace.h>
#include <sys/wait.h>
+#include <time.h>
+
#include "xc_private.h"
#include "xg_private.h"
-#include <time.h>
-
-#define X86_CR0_PE 0x00000001 /* Enable Protected Mode (RW) */
-#define X86_CR0_PG 0x80000000 /* Paging (RW) */
-#define BSD_PAGE_MASK (PAGE_SIZE-1)
-#define PDRSHIFT 22
-#define PSL_T 0x00000100 /* trace enable bit */
-#define VCPU 0 /* XXX */
-
-char * ptrace_names[] = {
- "PTRACE_TRACEME",
- "PTRACE_PEEKTEXT",
- "PTRACE_PEEKDATA",
- "PTRACE_PEEKUSER",
- "PTRACE_POKETEXT",
- "PTRACE_POKEDATA",
- "PTRACE_POKEUSER",
- "PTRACE_CONT",
- "PTRACE_KILL",
- "PTRACE_SINGLESTEP",
- "PTRACE_INVALID",
- "PTRACE_INVALID",
- "PTRACE_GETREGS",
- "PTRACE_SETREGS",
- "PTRACE_GETFPREGS",
- "PTRACE_SETFPREGS",
- "PTRACE_ATTACH",
- "PTRACE_DETACH",
- "PTRACE_GETFPXREGS",
- "PTRACE_SETFPXREGS",
- "PTRACE_INVALID",
- "PTRACE_INVALID",
- "PTRACE_INVALID",
- "PTRACE_INVALID",
- "PTRACE_SYSCALL",
-};
-
-struct gdb_regs {
- long ebx; /* 0 */
- long ecx; /* 4 */
- long edx; /* 8 */
- long esi; /* 12 */
- long edi; /* 16 */
- long ebp; /* 20 */
- long eax; /* 24 */
- int xds; /* 28 */
- int xes; /* 32 */
- int xfs; /* 36 */
- int xgs; /* 40 */
- long orig_eax; /* 44 */
- long eip; /* 48 */
- int xcs; /* 52 */
- long eflags; /* 56 */
- long esp; /* 60 */
- int xss; /* 64 */
-};
-
-#define FETCH_REGS(cpu) \
- if (!regs_valid[cpu]) \
- { \
- int retval = xc_domain_get_vcpu_context( \
- xc_handle, domid, cpu, &ctxt[cpu]); \
- if (retval) \
- goto error_out; \
- cr3[cpu] = ctxt[cpu].ctrlreg[3]; /* physical address */ \
- regs_valid[cpu] = 1; \
- }
-
-#define printval(x) printf("%s = %lx\n", #x, (long)x);
-#define SET_PT_REGS(pt, xc) \
-{ \
- pt.ebx = xc.ebx; \
- pt.ecx = xc.ecx; \
- pt.edx = xc.edx; \
- pt.esi = xc.esi; \
- pt.edi = xc.edi; \
- pt.ebp = xc.ebp; \
- pt.eax = xc.eax; \
- pt.eip = xc.eip; \
- pt.xcs = xc.cs; \
- pt.eflags = xc.eflags; \
- pt.esp = xc.esp; \
- pt.xss = xc.ss; \
- pt.xes = xc.es; \
- pt.xds = xc.ds; \
- pt.xfs = xc.fs; \
- pt.xgs = xc.gs; \
-}
-
-#define SET_XC_REGS(pt, xc) \
-{ \
- xc.ebx = pt->ebx; \
- xc.ecx = pt->ecx; \
- xc.edx = pt->edx; \
- xc.esi = pt->esi; \
- xc.edi = pt->edi; \
- xc.ebp = pt->ebp; \
- xc.eax = pt->eax; \
- xc.eip = pt->eip; \
- xc.cs = pt->xcs; \
- xc.eflags = pt->eflags; \
- xc.esp = pt->esp; \
- xc.ss = pt->xss; \
- xc.es = pt->xes; \
- xc.ds = pt->xds; \
- xc.fs = pt->xfs; \
- xc.gs = pt->xgs; \
-}
-
-#define vtopdi(va) ((va) >> PDRSHIFT)
-#define vtopti(va) (((va) >> PAGE_SHIFT) & 0x3ff)
+#include <thread_db.h>
+#include "xc_ptrace.h"
+
/* XXX application state */
-static long nr_pages = 0;
-unsigned long *page_array = NULL;
-static int regs_valid[MAX_VIRT_CPUS];
-static unsigned long cr3[MAX_VIRT_CPUS];
-static vcpu_guest_context_t ctxt[MAX_VIRT_CPUS];
-
-static inline int paging_enabled(vcpu_guest_context_t *v)
+static long nr_pages = 0;
+static unsigned long *page_array = NULL;
+static int current_domid = -1;
+
+static cpumap_t online_cpumap;
+static cpumap_t regs_valid;
+static vcpu_guest_context_t ctxt[MAX_VIRT_CPUS];
+
+extern int ffsll(long long int);
+#define FOREACH_CPU(cpumap, i) for ( cpumap = online_cpumap; (i =
ffsll(cpumap)); cpumap &= ~(1 << (index - 1)) )
+
+
+static int
+fetch_regs(int xc_handle, int cpu, int *online)
+{
+ xc_vcpuinfo_t info;
+ int retval = 0;
+
+ if (online)
+ *online = 0;
+ if ( !(regs_valid & (1 << cpu)) ) {
+ retval = xc_domain_get_vcpu_context(xc_handle, current_domid,
+ cpu, &ctxt[cpu]);
+ if ( retval )
+ goto done;
+ regs_valid |= (1 << cpu);
+
+ }
+ if ( online == NULL )
+ goto done;
+
+ retval = xc_domain_get_vcpu_info(xc_handle, current_domid,
+ cpu, &info);
+ *online = info.online;
+
+ done:
+ return retval;
+}
+
+#define FETCH_REGS(cpu) if (fetch_regs(xc_handle, cpu, NULL)) goto error_out;
+
+
+static struct thr_ev_handlers {
+ thr_ev_handler_t td_create;
+ thr_ev_handler_t td_death;
+} handlers;
+
+void
+xc_register_event_handler(thr_ev_handler_t h,
+ td_event_e e)
+{
+ switch (e) {
+ case TD_CREATE:
+ handlers.td_create = h;
+ break;
+ case TD_DEATH:
+ handlers.td_death = h;
+ break;
+ default:
+ abort(); /* XXX */
+ }
+}
+
+static inline int
+paging_enabled(vcpu_guest_context_t *v)
{
unsigned long cr0 = v->ctrlreg[0];
return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG);
+}
+
+/*
+ * Fetch registers for all online cpus and set the cpumap
+ * to indicate which cpus are online
+ *
+ */
+
+static int
+get_online_cpumap(int xc_handle, dom0_getdomaininfo_t *d, cpumap_t *cpumap)
+{
+ int i, online, retval;
+
+ *cpumap = 0;
+ for (i = 0; i <= d->max_vcpu_id; i++) {
+ if ((retval = fetch_regs(xc_handle, i, &online)))
+ goto error_out;
+ if (online)
+ *cpumap |= (1 << i);
+ }
+
+ return 0;
+ error_out:
+ return retval;
+}
+
+/*
+ * Notify GDB of any vcpus that have come online or gone offline
+ * update online_cpumap
+ *
+ */
+
+static void
+online_vcpus_changed(cpumap_t cpumap)
+{
+ cpumap_t changed_cpumap = cpumap ^ online_cpumap;
+ int index;
+
+ while ( (index = ffsll(changed_cpumap)) ) {
+ if ( cpumap & (1 << (index - 1)) ) {
+ if (handlers.td_create) handlers.td_create(index - 1);
+ } else {
+ printf("thread death: %d\n", index - 1);
+ if (handlers.td_death) handlers.td_death(index - 1);
+ }
+ changed_cpumap &= ~(1 << (index - 1));
+ }
+ online_cpumap = cpumap;
+
}
/* --------------------- */
@@ -132,7 +136,6 @@
static void *
map_domain_va_pae(
int xc_handle,
- unsigned long domid,
int cpu,
void *guest_va,
int perm)
@@ -144,24 +147,24 @@
FETCH_REGS(cpu);
l3 = xc_map_foreign_range(
- xc_handle, domid, PAGE_SIZE, PROT_READ, cr3[cpu] >> PAGE_SHIFT);
+ xc_handle, current_domid, PAGE_SIZE, PROT_READ, ctxt[cpu].ctrlreg[3]
>> PAGE_SHIFT);
if ( l3 == NULL )
goto error_out;
l2p = l3[l3_table_offset_pae(va)] >> PAGE_SHIFT;
- l2 = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, PROT_READ, l2p);
+ l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ,
l2p);
if ( l2 == NULL )
goto error_out;
l1p = l2[l2_table_offset_pae(va)] >> PAGE_SHIFT;
- l1 = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, perm, l1p);
+ l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p);
if ( l1 == NULL )
goto error_out;
p = l1[l1_table_offset_pae(va)] >> PAGE_SHIFT;
if ( v != NULL )
munmap(v, PAGE_SIZE);
- v = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, perm, p);
+ v = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p);
if ( v == NULL )
goto error_out;
@@ -174,16 +177,17 @@
static void *
map_domain_va(
int xc_handle,
- unsigned long domid,
int cpu,
void *guest_va,
int perm)
{
+
unsigned long pde, page;
unsigned long va = (unsigned long)guest_va;
- long npgs = xc_get_tot_pages(xc_handle, domid);
-
- static unsigned long cr3_phys[MAX_VIRT_CPUS];
+ long npgs = xc_get_tot_pages(xc_handle, current_domid);
+
+
+ static uint32_t cr3_phys[MAX_VIRT_CPUS];
static unsigned long *cr3_virt[MAX_VIRT_CPUS];
static unsigned long pde_phys[MAX_VIRT_CPUS];
static unsigned long *pde_virt[MAX_VIRT_CPUS];
@@ -202,7 +206,7 @@
}
if ( mode == MODE_PAE )
- return map_domain_va_pae(xc_handle, domid, cpu, guest_va, perm);
+ return map_domain_va_pae(xc_handle, cpu, guest_va, perm);
if ( nr_pages != npgs )
{
@@ -214,7 +218,7 @@
printf("Could not allocate memory\n");
goto error_out;
}
- if ( xc_get_pfn_list(xc_handle, domid,
+ if ( xc_get_pfn_list(xc_handle, current_domid,
page_array, nr_pages) != nr_pages )
{
printf("Could not get the page frame list\n");
@@ -224,13 +228,13 @@
FETCH_REGS(cpu);
- if ( cr3[cpu] != cr3_phys[cpu] )
- {
- cr3_phys[cpu] = cr3[cpu];
+ if ( ctxt[cpu].ctrlreg[3] != cr3_phys[cpu] )
+ {
+ cr3_phys[cpu] = ctxt[cpu].ctrlreg[3];
if ( cr3_virt[cpu] )
munmap(cr3_virt[cpu], PAGE_SIZE);
cr3_virt[cpu] = xc_map_foreign_range(
- xc_handle, domid, PAGE_SIZE, PROT_READ,
+ xc_handle, current_domid, PAGE_SIZE, PROT_READ,
cr3_phys[cpu] >> PAGE_SHIFT);
if ( cr3_virt[cpu] == NULL )
goto error_out;
@@ -245,7 +249,7 @@
if ( pde_virt[cpu] )
munmap(pde_virt[cpu], PAGE_SIZE);
pde_virt[cpu] = xc_map_foreign_range(
- xc_handle, domid, PAGE_SIZE, PROT_READ,
+ xc_handle, current_domid, PAGE_SIZE, PROT_READ,
pde_phys[cpu] >> PAGE_SHIFT);
if ( pde_virt[cpu] == NULL )
goto error_out;
@@ -260,7 +264,7 @@
if ( page_virt[cpu] )
munmap(page_virt[cpu], PAGE_SIZE);
page_virt[cpu] = xc_map_foreign_range(
- xc_handle, domid, PAGE_SIZE, perm,
+ xc_handle, current_domid, PAGE_SIZE, perm,
page_phys[cpu] >> PAGE_SHIFT);
if ( page_virt[cpu] == NULL )
{
@@ -286,12 +290,15 @@
DECLARE_DOM0_OP;
int retval;
struct timespec ts;
+ cpumap_t cpumap;
+
ts.tv_sec = 0;
ts.tv_nsec = 10*1000*1000;
op.cmd = DOM0_GETDOMAININFO;
op.u.getdomaininfo.domain = domain;
-
+
+
retry:
retval = do_dom0_op(xc_handle, &op);
if ( retval || (op.u.getdomaininfo.domain != domain) )
@@ -309,17 +316,22 @@
nanosleep(&ts,NULL);
goto retry;
}
-
+ /* XXX check for ^C here */
done:
+ if (get_online_cpumap(xc_handle, &op.u.getdomaininfo, &cpumap))
+ printf("get_online_cpumap failed\n");
+ if (online_cpumap != cpumap)
+ online_vcpus_changed(cpumap);
return retval;
}
+
long
xc_ptrace(
int xc_handle,
enum __ptrace_request request,
- uint32_t domid,
+ uint32_t domid_tid,
long eaddr,
long edata)
{
@@ -328,18 +340,19 @@
struct gdb_regs pt;
long retval = 0;
unsigned long *guest_va;
- int cpu = VCPU;
+ cpumap_t cpumap;
+ int cpu, index;
void *addr = (char *)eaddr;
void *data = (char *)edata;
- op.interface_version = DOM0_INTERFACE_VERSION;
+ cpu = (request != PTRACE_ATTACH) ? domid_tid : 0;
switch ( request )
{
case PTRACE_PEEKTEXT:
case PTRACE_PEEKDATA:
guest_va = (unsigned long *)map_domain_va(
- xc_handle, domid, cpu, addr, PROT_READ);
+ xc_handle, cpu, addr, PROT_READ);
if ( guest_va == NULL )
{
status = EFAULT;
@@ -350,10 +363,10 @@
case PTRACE_POKETEXT:
case PTRACE_POKEDATA:
+ /* XXX assume that all CPUs have the same address space */
guest_va = (unsigned long *)map_domain_va(
- xc_handle, domid, cpu, addr, PROT_READ|PROT_WRITE);
- if ( guest_va == NULL )
- {
+ xc_handle, cpu, addr, PROT_READ|PROT_WRITE);
+ if ( guest_va == NULL ) {
status = EFAULT;
goto error_out;
}
@@ -363,6 +376,7 @@
case PTRACE_GETREGS:
case PTRACE_GETFPREGS:
case PTRACE_GETFPXREGS:
+
FETCH_REGS(cpu);
if ( request == PTRACE_GETREGS )
{
@@ -380,44 +394,18 @@
break;
case PTRACE_SETREGS:
- op.cmd = DOM0_SETDOMAININFO;
- SET_XC_REGS(((struct gdb_regs *)data), ctxt[VCPU].user_regs);
- op.u.setdomaininfo.domain = domid;
- /* XXX need to understand multiple vcpus */
- op.u.setdomaininfo.vcpu = cpu;
- op.u.setdomaininfo.ctxt = &ctxt[cpu];
- retval = do_dom0_op(xc_handle, &op);
+ SET_XC_REGS(((struct gdb_regs *)data), ctxt[cpu].user_regs);
+ retval = xc_domain_setinfo(xc_handle, current_domid, cpu, &ctxt[cpu]);
if (retval)
goto error_out;
break;
- case PTRACE_ATTACH:
- op.cmd = DOM0_GETDOMAININFO;
- op.u.getdomaininfo.domain = domid;
- retval = do_dom0_op(xc_handle, &op);
- if ( retval || (op.u.getdomaininfo.domain != domid) )
- {
- perror("dom0 op failed");
- goto error_out;
- }
- if ( op.u.getdomaininfo.flags & DOMFLAGS_PAUSED )
- {
- printf("domain currently paused\n");
- goto error_out;
- }
- printf("domain not currently paused\n");
- op.cmd = DOM0_PAUSEDOMAIN;
- op.u.pausedomain.domain = domid;
- retval = do_dom0_op(xc_handle, &op);
- break;
-
case PTRACE_SINGLESTEP:
- ctxt[VCPU].user_regs.eflags |= PSL_T;
- op.cmd = DOM0_SETDOMAININFO;
- op.u.setdomaininfo.domain = domid;
- op.u.setdomaininfo.vcpu = 0;
- op.u.setdomaininfo.ctxt = &ctxt[cpu];
- retval = do_dom0_op(xc_handle, &op);
+ /* XXX we can still have problems if the user switches threads
+ * during single-stepping - but that just seems retarded
+ */
+ ctxt[cpu].user_regs.eflags |= PSL_T;
+ retval = xc_domain_setinfo(xc_handle, current_domid, cpu, &ctxt[cpu]);
if ( retval )
{
perror("dom0 op failed");
@@ -429,27 +417,56 @@
case PTRACE_DETACH:
if ( request != PTRACE_SINGLESTEP )
{
- FETCH_REGS(cpu);
- /* Clear trace flag */
- if ( ctxt[cpu].user_regs.eflags & PSL_T )
- {
- ctxt[cpu].user_regs.eflags &= ~PSL_T;
- op.cmd = DOM0_SETDOMAININFO;
- op.u.setdomaininfo.domain = domid;
- op.u.setdomaininfo.vcpu = cpu;
- op.u.setdomaininfo.ctxt = &ctxt[cpu];
- retval = do_dom0_op(xc_handle, &op);
- if ( retval )
- {
- perror("dom0 op failed");
- goto error_out;
+ FOREACH_CPU(cpumap, index) {
+ cpu = index - 1;
+ FETCH_REGS(cpu);
+ /* Clear trace flag */
+ if ( ctxt[cpu].user_regs.eflags & PSL_T ) {
+ ctxt[cpu].user_regs.eflags &= ~PSL_T;
+ retval = xc_domain_setinfo(xc_handle, current_domid,
+ cpu, &ctxt[cpu]);
+ if ( retval ) {
+ perror("dom0 op failed");
+ goto error_out;
+ }
}
}
}
- regs_valid[cpu] = 0;
- op.cmd = DOM0_UNPAUSEDOMAIN;
- op.u.unpausedomain.domain = domid > 0 ? domid : -domid;
+ if ( request == PTRACE_DETACH )
+ {
+ op.cmd = DOM0_SETDEBUGGING;
+ op.u.setdebugging.domain = current_domid;
+ op.u.setdebugging.enable = 0;
+ retval = do_dom0_op(xc_handle, &op);
+ }
+ regs_valid = 0;
+ xc_domain_unpause(xc_handle, current_domid > 0 ? current_domid :
-current_domid);
+ break;
+
+ case PTRACE_ATTACH:
+ current_domid = domid_tid;
+ op.cmd = DOM0_GETDOMAININFO;
+ op.u.getdomaininfo.domain = current_domid;
retval = do_dom0_op(xc_handle, &op);
+ if ( retval || (op.u.getdomaininfo.domain != current_domid) )
+ {
+ perror("dom0 op failed");
+ goto error_out;
+ }
+ if ( op.u.getdomaininfo.flags & DOMFLAGS_PAUSED )
+ {
+ printf("domain currently paused\n");
+ } else
+ retval = xc_domain_pause(xc_handle, current_domid);
+ op.cmd = DOM0_SETDEBUGGING;
+ op.u.setdebugging.domain = current_domid;
+ op.u.setdebugging.enable = 1;
+ retval = do_dom0_op(xc_handle, &op);
+
+ if (get_online_cpumap(xc_handle, &op.u.getdomaininfo, &cpumap))
+ printf("get_online_cpumap failed\n");
+ if (online_cpumap != cpumap)
+ online_vcpus_changed(cpumap);
break;
case PTRACE_SETFPREGS:
diff -r 11cd619db035 -r d3b10a2a82d4 tools/libxc/xc_vmx_build.c
--- a/tools/libxc/xc_vmx_build.c Tue Dec 20 17:16:15 2005
+++ b/tools/libxc/xc_vmx_build.c Tue Dec 20 17:16:24 2005
@@ -288,11 +288,11 @@
l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
unsigned long *page_array = NULL;
#ifdef __x86_64__
- l3_pgentry_t *vl3tab=NULL, *vl3e=NULL;
+ l3_pgentry_t *vl3tab=NULL;
unsigned long l3tab;
#endif
- unsigned long l2tab;
- unsigned long l1tab;
+ unsigned long l2tab = 0;
+ unsigned long l1tab = 0;
unsigned long count, i;
shared_info_t *shared_info;
void *e820_page;
@@ -323,7 +323,7 @@
}
/* memsize is in megabytes */
- v_end = memsize << 20;
+ v_end = (unsigned long)memsize << 20;
#ifdef __i386__
nr_pt_pages = 1 + ((memsize + 3) >> 2);
@@ -435,15 +435,16 @@
goto error_out;
memset(vl2tab, 0, PAGE_SIZE);
munmap(vl2tab, PAGE_SIZE);
+ vl2tab = NULL;
vl3tab[i] = l2tab | L3_PROT;
}
- vl3e = &vl3tab[l3_table_offset(0)];
for ( count = 0; count < (v_end >> PAGE_SHIFT); count++ )
{
- if (!(count & (1 << (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)))){
+ if ( !(count & ((1 << (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)) - 1))
)
+ {
l2tab = vl3tab[count >> (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)]
- & PAGE_MASK;
+ & PAGE_MASK;
if (vl2tab != NULL)
munmap(vl2tab, PAGE_SIZE);
diff -r 11cd619db035 -r d3b10a2a82d4 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Tue Dec 20 17:16:15 2005
+++ b/tools/libxc/xenctrl.h Tue Dec 20 17:16:24 2005
@@ -94,25 +94,12 @@
} xc_core_header_t;
-long xc_ptrace(
- int xc_handle,
- enum __ptrace_request request,
- uint32_t domid,
- long addr,
- long data);
-
long xc_ptrace_core(
int xc_handle,
enum __ptrace_request request,
uint32_t domid,
long addr,
long data);
-
-int xc_waitdomain(
- int xc_handle,
- int domain,
- int *status,
- int options);
int xc_waitdomain_core(
int xc_handle,
@@ -219,6 +206,20 @@
unsigned int max_doms,
xc_dominfo_t *info);
+
+/**
+ * This function will set the vcpu context for the specified domain.
+ *
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm domid the domain to set the vcpu context for
+ * @parm vcpu the vcpu number for the context
+ * @parm ctxt pointer to the the cpu context with the values to set
+ * @return the number of domains enumerated or -1 on error
+ */
+int xc_domain_setinfo(int xc_handle,
+ uint32_t domid,
+ uint32_t vcpu,
+ vcpu_guest_context_t *ctxt);
/**
* This function will return information about one or more domains, using a
* single hypercall. The domain information will be stored into the supplied
diff -r 11cd619db035 -r d3b10a2a82d4 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py Tue Dec 20 17:16:15 2005
+++ b/tools/python/xen/xend/image.py Tue Dec 20 17:16:24 2005
@@ -237,7 +237,7 @@
# Return a list of cmd line args to the device models based on the
# xm config file
def parseDeviceModelArgs(self, imageConfig, deviceConfig):
- dmargs = [ 'cdrom', 'boot', 'fda', 'fdb', 'ne2000',
+ dmargs = [ 'cdrom', 'boot', 'fda', 'fdb', 'ne2000', 'audio',
'localtime', 'serial', 'stdvga', 'isa', 'vcpus']
ret = []
for a in dmargs:
@@ -246,9 +246,10 @@
# python doesn't allow '-' in variable names
if a == 'stdvga': a = 'std-vga'
if a == 'ne2000': a = 'nic-ne2000'
+ if a == 'audio': a = 'enable-audio'
# Handle booleans gracefully
- if a in ['localtime', 'std-vga', 'isa', 'nic-ne2000']:
+ if a in ['localtime', 'std-vga', 'isa', 'nic-ne2000',
'enable-audio']:
if v != None: v = int(v)
if v: ret.append("-%s" % a)
else:
diff -r 11cd619db035 -r d3b10a2a82d4 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py Tue Dec 20 17:16:15 2005
+++ b/tools/python/xen/xm/create.py Tue Dec 20 17:16:24 2005
@@ -371,6 +371,10 @@
gopts.var('ne2000', val='no|yes',
fn=set_bool, default=0,
use="Should device models use ne2000?")
+
+gopts.var('audio', val='no|yes',
+ fn=set_bool, default=0,
+ use="Should device models enable audio?")
gopts.var('vnc', val='',
fn=set_value, default=None,
@@ -521,7 +525,7 @@
"""Create the config for VMX devices.
"""
args = [ 'device_model', 'vcpus', 'cdrom', 'boot', 'fda', 'fdb',
- 'localtime', 'serial', 'stdvga', 'isa', 'nographic',
+ 'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'audio',
'vnc', 'vncviewer', 'sdl', 'display', 'ne2000', 'lapic']
for a in args:
if (vals.__dict__[a]):
diff -r 11cd619db035 -r d3b10a2a82d4 tools/vtpm_manager/manager/securestorage.c
--- a/tools/vtpm_manager/manager/securestorage.c Tue Dec 20 17:16:15 2005
+++ b/tools/vtpm_manager/manager/securestorage.c Tue Dec 20 17:16:24 2005
@@ -54,48 +54,138 @@
#include "buffer.h"
#include "log.h"
+TPM_RESULT envelope_encrypt(const buffer_t *inbuf,
+ CRYPTO_INFO *asymkey,
+ buffer_t *sealed_data) {
+ TPM_RESULT status = TPM_SUCCESS;
+ symkey_t symkey;
+ buffer_t data_cipher = NULL_BUF,
+ symkey_cipher = NULL_BUF;
+
+ UINT32 i;
+ struct pack_constbuf_t symkey_cipher32, data_cipher32;
+
+ vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping[%d]: 0x", buffer_len(inbuf));
+ for (i=0; i< buffer_len(inbuf); i++)
+ vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", inbuf->bytes[i]);
+ vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+
+ // Generate a sym key and encrypt state with it
+ TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_genkey (&symkey) );
+ TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_encrypt (&symkey, inbuf,
&data_cipher) );
+
+ // Encrypt symmetric key
+ TPMTRYRETURN( VTSP_Bind( asymkey,
+ &symkey.key,
+ &symkey_cipher) );
+
+ // Create output blob: symkey_size + symkey_cipher + state_cipher_size +
state_cipher
+
+ symkey_cipher32.size = buffer_len(&symkey_cipher);
+ symkey_cipher32.data = symkey_cipher.bytes;
+
+ data_cipher32.size = buffer_len(&data_cipher);
+ data_cipher32.data = data_cipher.bytes;
+
+ TPMTRYRETURN( buffer_init(sealed_data, 2 * sizeof(UINT32) +
symkey_cipher32.size + data_cipher32.size, NULL));
+
+ BSG_PackList(sealed_data->bytes, 2,
+ BSG_TPM_SIZE32_DATA, &symkey_cipher32,
+ BSG_TPM_SIZE32_DATA, &data_cipher32);
+
+ vtpmloginfo(VTPM_LOG_VTPM, "Saved %d bytes of E(symkey) + %d bytes of
E(data)\n", buffer_len(&symkey_cipher), buffer_len(&data_cipher));
+ goto egress;
+
+ abort_egress:
+ vtpmlogerror(VTPM_LOG_VTPM, "Failed to envelope encrypt\n.");
+
+ egress:
+
+ buffer_free ( &data_cipher);
+ buffer_free ( &symkey_cipher);
+ Crypto_symcrypto_freekey (&symkey);
+
+ return status;
+}
+
+TPM_RESULT envelope_decrypt(const long cipher_size,
+ const BYTE *cipher,
+ TCS_CONTEXT_HANDLE TCSContext,
+ TPM_HANDLE keyHandle,
+ const TPM_AUTHDATA *key_usage_auth,
+ buffer_t *unsealed_data) {
+
+ TPM_RESULT status = TPM_SUCCESS;
+ symkey_t symkey;
+ buffer_t data_cipher = NULL_BUF,
+ symkey_clear = NULL_BUF,
+ symkey_cipher = NULL_BUF;
+ struct pack_buf_t symkey_cipher32, data_cipher32;
+ int i;
+
+ memset(&symkey, 0, sizeof(symkey_t));
+
+ vtpmloginfo(VTPM_LOG_VTPM_DEEP, "envelope decrypting[%ld]: 0x", cipher_size);
+ for (i=0; i< cipher_size; i++)
+ vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cipher[i]);
+ vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+
+ BSG_UnpackList(cipher, 2,
+ BSG_TPM_SIZE32_DATA, &symkey_cipher32,
+ BSG_TPM_SIZE32_DATA, &data_cipher32);
+
+ TPMTRYRETURN( buffer_init_convert (&symkey_cipher,
+ symkey_cipher32.size,
+ symkey_cipher32.data) );
+
+ TPMTRYRETURN( buffer_init_convert (&data_cipher,
+ data_cipher32.size,
+ data_cipher32.data) );
+
+ // Decrypt Symmetric Key
+ TPMTRYRETURN( VTSP_Unbind( TCSContext,
+ keyHandle,
+ &symkey_cipher,
+ key_usage_auth,
+ &symkey_clear,
+ &(vtpm_globals->keyAuth) ) );
+
+ // create symmetric key using saved bits
+ Crypto_symcrypto_initkey (&symkey, &symkey_clear);
+
+ // Decrypt State
+ TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey, &data_cipher,
unsealed_data) );
+
+ goto egress;
+
+ abort_egress:
+ vtpmlogerror(VTPM_LOG_VTPM, "Failed to envelope decrypt data\n.");
+
+ egress:
+ buffer_free ( &data_cipher);
+ buffer_free ( &symkey_clear);
+ buffer_free ( &symkey_cipher);
+ Crypto_symcrypto_freekey (&symkey);
+
+ return status;
+}
+
TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE *myDMI,
const buffer_t *inbuf,
buffer_t *outbuf) {
TPM_RESULT status = TPM_SUCCESS;
- symkey_t symkey;
- buffer_t state_cipher = NULL_BUF,
- symkey_cipher = NULL_BUF;
int fh;
long bytes_written;
- BYTE *sealed_NVM=NULL;
- UINT32 sealed_NVM_size, i;
- struct pack_constbuf_t symkey_cipher32, state_cipher32;
-
- vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Save_NVMing[%d]: 0x", buffer_len(inbuf));
- for (i=0; i< buffer_len(inbuf); i++)
- vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", inbuf->bytes[i]);
- vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
-
- // Generate a sym key and encrypt state with it
- TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_genkey (&symkey) );
- TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_encrypt (&symkey, inbuf,
&state_cipher) );
-
- // Encrypt symmetric key
- TPMTRYRETURN( VTSP_Bind( &vtpm_globals->storageKey,
- &symkey.key,
- &symkey_cipher) );
-
- // Create output blob: symkey_size + symkey_cipher + state_cipher_size +
state_cipher
-
- symkey_cipher32.size = buffer_len(&symkey_cipher);
- symkey_cipher32.data = symkey_cipher.bytes;
-
- state_cipher32.size = buffer_len(&state_cipher);
- state_cipher32.data = state_cipher.bytes;
-
- sealed_NVM = (BYTE *) malloc( 2 * sizeof(UINT32) + symkey_cipher32.size +
state_cipher32.size);
-
- sealed_NVM_size = BSG_PackList(sealed_NVM, 2,
- BSG_TPM_SIZE32_DATA, &symkey_cipher32,
- BSG_TPM_SIZE32_DATA, &state_cipher32);
-
+ buffer_t sealed_NVM;
+
+
+ vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Save_NVMing[%d]: 0x\n", buffer_len(inbuf));
+
+ TPMTRYRETURN( envelope_encrypt(inbuf,
+ &vtpm_globals->storageKey,
+ &sealed_NVM) );
+
// Mark DMI Table so new save state info will get pushed to disk on return.
vtpm_globals->DMI_table_dirty = TRUE;
@@ -104,28 +194,22 @@
// after writing the file? We can't get the old one back.
// TODO: Backup old file and try and recover that way.
fh = open(myDMI->NVMLocation, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
- if ( (bytes_written = write(fh, sealed_NVM, sealed_NVM_size) ) != (long)
sealed_NVM_size) {
- vtpmlogerror(VTPM_LOG_VTPM, "We just overwrote a DMI_NVM and failed to
finish. %ld/%ld bytes.\n", bytes_written, (long)sealed_NVM_size);
+ if ( (bytes_written = write(fh, sealed_NVM.bytes, buffer_len(&sealed_NVM) )
!= (long) buffer_len(&sealed_NVM))) {
+ vtpmlogerror(VTPM_LOG_VTPM, "We just overwrote a DMI_NVM and failed to
finish. %ld/%ld bytes.\n", bytes_written, (long)buffer_len(&sealed_NVM));
status = TPM_IOERROR;
goto abort_egress;
}
close(fh);
- Crypto_SHA1Full (sealed_NVM, sealed_NVM_size, (BYTE *)
&myDMI->NVM_measurement);
-
- vtpmloginfo(VTPM_LOG_VTPM, "Saved %d bytes of E(symkey) + %d bytes of
E(NVM)\n", buffer_len(&symkey_cipher), buffer_len(&state_cipher));
- goto egress;
-
- abort_egress:
- vtpmlogerror(VTPM_LOG_VTPM, "Failed to load NVM\n.");
-
- egress:
-
- buffer_free ( &state_cipher);
- buffer_free ( &symkey_cipher);
- free(sealed_NVM);
- Crypto_symcrypto_freekey (&symkey);
-
+ Crypto_SHA1Full (sealed_NVM.bytes, buffer_len(&sealed_NVM), (BYTE *)
&myDMI->NVM_measurement);
+
+ goto egress;
+
+ abort_egress:
+ vtpmlogerror(VTPM_LOG_VTPM, "Failed to save NVM\n.");
+
+ egress:
+ buffer_free(&sealed_NVM);
return status;
}
@@ -136,11 +220,7 @@
buffer_t *outbuf) {
TPM_RESULT status = TPM_SUCCESS;
- symkey_t symkey;
- buffer_t state_cipher = NULL_BUF,
- symkey_clear = NULL_BUF,
- symkey_cipher = NULL_BUF;
- struct pack_buf_t symkey_cipher32, state_cipher32;
+
UINT32 sealed_NVM_size;
BYTE *sealed_NVM = NULL;
@@ -148,9 +228,7 @@
int fh, stat_ret, i;
struct stat file_stat;
TPM_DIGEST sealedNVMHash;
-
- memset(&symkey, 0, sizeof(symkey_t));
-
+
if (myDMI->NVMLocation == NULL) {
vtpmlogerror(VTPM_LOG_VTPM, "Unable to load NVM because the file name
NULL.\n");
status = TPM_AUTHFAIL;
@@ -168,28 +246,14 @@
}
sealed_NVM = (BYTE *) malloc(fh_size);
+ sealed_NVM_size = (UINT32) fh_size;
if (read(fh, sealed_NVM, fh_size) != fh_size) {
status = TPM_IOERROR;
goto abort_egress;
}
close(fh);
- vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%ld]: 0x", fh_size);
- for (i=0; i< fh_size; i++)
- vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", sealed_NVM[i]);
- vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
-
- sealed_NVM_size = BSG_UnpackList(sealed_NVM, 2,
- BSG_TPM_SIZE32_DATA, &symkey_cipher32,
- BSG_TPM_SIZE32_DATA, &state_cipher32);
-
- TPMTRYRETURN( buffer_init_convert (&symkey_cipher,
- symkey_cipher32.size,
- symkey_cipher32.data) );
-
- TPMTRYRETURN( buffer_init_convert (&state_cipher,
- state_cipher32.size,
- state_cipher32.data) );
+ vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%ld],\n", fh_size);
Crypto_SHA1Full(sealed_NVM, sealed_NVM_size, (BYTE *) &sealedNVMHash);
@@ -210,32 +274,19 @@
goto abort_egress;
}
- // Decrypt Symmetric Key
- TPMTRYRETURN( VTSP_Unbind( myDMI->TCSContext,
- vtpm_globals->storageKeyHandle,
- &symkey_cipher,
- (const
TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
- &symkey_clear,
- &(vtpm_globals->keyAuth) ) );
-
- // create symmetric key using saved bits
- Crypto_symcrypto_initkey (&symkey, &symkey_clear);
-
- // Decrypt State
- TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey, &state_cipher,
outbuf) );
-
+ TPMTRYRETURN( envelope_decrypt(fh_size,
+ sealed_NVM,
+ myDMI->TCSContext,
+ vtpm_globals->storageKeyHandle,
+ (const
TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
+ outbuf) );
goto egress;
abort_egress:
vtpmlogerror(VTPM_LOG_VTPM, "Failed to load NVM\n.");
egress:
-
- buffer_free ( &state_cipher);
- buffer_free ( &symkey_clear);
- buffer_free ( &symkey_cipher);
free( sealed_NVM );
- Crypto_symcrypto_freekey (&symkey);
return status;
}
diff -r 11cd619db035 -r d3b10a2a82d4 tools/xm-test/README
--- a/tools/xm-test/README Tue Dec 20 17:16:15 2005
+++ b/tools/xm-test/README Tue Dec 20 17:16:24 2005
@@ -54,6 +54,26 @@
you should not attempt to use a ramdisk from a previous minor version
of xm-test (i.e., don't use a ramdisk from 0.4.0 with 0.5.0. 0.5.0
should work for 0.5.3 though)
+
+If you'd like to build and run this with hardware virtual machine assist
+(HVM) support to test fully virtualized disk images on VMX hardware,
+please add the --enable-vmx-support option to configure:
+
+ # ./autogen
+ # ./configure --enable-vmx-support
+ # make
+
+The ramdisk/bin/create_disk_image script, which builds the full virt
+disk.img, requires Lilo 22.7+ to be installed on the system. Lilo is
+used to install the bootloader on the disk.img.
+
+If HVM / VMX support is enabled, the ramdisk/bin/create_disk_image script
+will be run to create a full virt disk.img in the ramdisk directory. The
+script, by default, will look in /boot for the first non-Xen kernel it
+runs across. If you wish to use a different kernel or the script fails
+to find a kernel, please run the script manually to make a disk.img
+using the -k option. Xm-test will look for disk.img in the ramdisk
+directory when run by default.
Running
diff -r 11cd619db035 -r d3b10a2a82d4 tools/xm-test/ramdisk/Makefile.am
--- a/tools/xm-test/ramdisk/Makefile.am Tue Dec 20 17:16:15 2005
+++ b/tools/xm-test/ramdisk/Makefile.am Tue Dec 20 17:16:24 2005
@@ -45,7 +45,7 @@
disk.img: $(XMTEST_VER_IMG)
chmod a+x $(VMX_SCRIPT)
- $(VMX_SCRIPT) -r $(XMTEST_VER_IMG) -i disk.img
+ $(VMX_SCRIPT) -r $(XMTEST_VER_IMG)
existing:
@[ -f $(XMTEST_VER_IMG) ] && ln -sf $(XMTEST_VER_IMG) initrd.img || \
diff -r 11cd619db035 -r d3b10a2a82d4 tools/xm-test/ramdisk/bin/create_disk_image
--- a/tools/xm-test/ramdisk/bin/create_disk_image Tue Dec 20 17:16:15 2005
+++ b/tools/xm-test/ramdisk/bin/create_disk_image Tue Dec 20 17:16:24 2005
@@ -77,7 +77,7 @@
function initialize_globals()
{
PROGNAME="create_disk_image"
- IMAGE="hvm.img"
+ IMAGE="disk.img"
KERNEL=""
LCONF="lilo.conf"
LOOPD="" # Loop device for entire disk image
diff -r 11cd619db035 -r d3b10a2a82d4 xen/Rules.mk
--- a/xen/Rules.mk Tue Dec 20 17:16:15 2005
+++ b/xen/Rules.mk Tue Dec 20 17:16:24 2005
@@ -6,7 +6,6 @@
debug ?= n
perfc ?= n
perfc_arrays?= n
-domu_debug ?= n
crash_debug ?= n
XEN_ROOT=$(BASEDIR)/..
@@ -54,10 +53,6 @@
CFLAGS += -g -DVERBOSE
endif
-ifeq ($(domu_debug),y)
-CFLAGS += -DDOMU_DEBUG
-endif
-
ifeq ($(crash_debug),y)
CFLAGS += -g -DCRASH_DEBUG
endif
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/audit.c
--- a/xen/arch/x86/audit.c Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/audit.c Tue Dec 20 17:16:24 2005
@@ -61,7 +61,7 @@
#ifdef __i386__
#ifdef CONFIG_X86_PAE
/* 32b PAE */
- if ( (( frame_table[mfn].u.inuse.type_info & PGT_va_mask )
+ if ( (( pfn_to_page(mfn)->u.inuse.type_info & PGT_va_mask )
>> PGT_va_shift) == 3 )
return l2_table_offset(HYPERVISOR_VIRT_START);
else
@@ -364,7 +364,7 @@
{
gmfn = __gpfn_to_mfn(d, a->gpfn_and_flags & PGT_mfn_mask);
smfn = a->smfn;
- page = &frame_table[smfn];
+ page = pfn_to_page(smfn);
switch ( a->gpfn_and_flags & PGT_type_mask ) {
case PGT_writable_pred:
@@ -433,11 +433,13 @@
for_each_vcpu(d, v)
{
if ( pagetable_get_paddr(v->arch.guest_table) )
- adjust(&frame_table[pagetable_get_pfn(v->arch.guest_table)],
!shadow_mode_refcounts(d));
+ adjust(pfn_to_page(pagetable_get_pfn(v->arch.guest_table)),
+ !shadow_mode_refcounts(d));
if ( pagetable_get_paddr(v->arch.shadow_table) )
- adjust(&frame_table[pagetable_get_pfn(v->arch.shadow_table)],
0);
+ adjust(pfn_to_page(pagetable_get_pfn(v->arch.shadow_table)),
+ 0);
if ( v->arch.monitor_shadow_ref )
- adjust(&frame_table[v->arch.monitor_shadow_ref], 0);
+ adjust(pfn_to_page(v->arch.monitor_shadow_ref), 0);
}
}
@@ -617,7 +619,7 @@
void scan_for_pfn_in_mfn(struct domain *d, unsigned long xmfn,
unsigned long mfn)
{
- struct pfn_info *page = &frame_table[mfn];
+ struct pfn_info *page = pfn_to_page(mfn);
l1_pgentry_t *pt = map_domain_page(mfn);
int i;
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/dom0_ops.c
--- a/xen/arch/x86/dom0_ops.c Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/dom0_ops.c Tue Dec 20 17:16:24 2005
@@ -210,7 +210,7 @@
unlikely((d = find_domain_by_id(dom)) == NULL) )
break;
- page = &frame_table[pfn];
+ page = pfn_to_page(pfn);
if ( likely(get_page(page, d)) )
{
@@ -285,7 +285,7 @@
struct pfn_info *page;
unsigned long mfn = l_arr[j];
- page = &frame_table[mfn];
+ page = pfn_to_page(mfn);
if ( likely(pfn_valid(mfn) && get_page(page, d)) )
{
@@ -350,15 +350,14 @@
list_ent = d->page_list.next;
for ( i = 0; (i < max_pfns) && (list_ent != &d->page_list); i++ )
{
- pfn = list_entry(list_ent, struct pfn_info, list) -
- frame_table;
+ pfn = page_to_pfn(list_entry(list_ent, struct pfn_info, list));
if ( put_user(pfn, buffer) )
{
ret = -EFAULT;
break;
}
buffer++;
- list_ent = frame_table[pfn].list.next;
+ list_ent = pfn_to_page(pfn)->list.next;
}
spin_unlock(&d->page_alloc_lock);
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/domain.c Tue Dec 20 17:16:24 2005
@@ -190,7 +190,7 @@
list_for_each_entry ( page, &d->page_list, list )
{
printk("Page %p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
- _p(page_to_phys(page)), _p(page - frame_table),
+ _p(page_to_phys(page)), _p(page_to_pfn(page)),
page->count_info, page->u.inuse.type_info);
}
}
@@ -198,13 +198,13 @@
list_for_each_entry ( page, &d->xenpage_list, list )
{
printk("XenPage %p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
- _p(page_to_phys(page)), _p(page - frame_table),
+ _p(page_to_phys(page)), _p(page_to_pfn(page)),
page->count_info, page->u.inuse.type_info);
}
page = virt_to_page(d->shared_info);
printk("Shared_info@%p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
- _p(page_to_phys(page)), _p(page - frame_table), page->count_info,
+ _p(page_to_phys(page)), _p(page_to_pfn(page)), page->count_info,
page->u.inuse.type_info);
}
@@ -391,19 +391,19 @@
if ( shadow_mode_refcounts(d) )
{
- if ( !get_page(&frame_table[phys_basetab>>PAGE_SHIFT], d) )
+ if ( !get_page(pfn_to_page(phys_basetab>>PAGE_SHIFT), d) )
return -EINVAL;
}
else if ( !(c->flags & VGCF_VMX_GUEST) )
{
- if ( !get_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT], d,
+ if ( !get_page_and_type(pfn_to_page(phys_basetab>>PAGE_SHIFT), d,
PGT_base_page_table) )
return -EINVAL;
}
if ( (rc = (int)set_gdt(v, c->gdt_frames, c->gdt_ents)) != 0 )
{
- put_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT]);
+ put_page_and_type(pfn_to_page(phys_basetab>>PAGE_SHIFT));
return rc;
}
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/domain_build.c Tue Dec 20 17:16:24 2005
@@ -405,7 +405,7 @@
*l1tab = l1e_from_pfn(mfn, L1_PROT);
l1tab++;
- page = &frame_table[mfn];
+ page = pfn_to_page(mfn);
if ( !get_page_and_type(page, d, PGT_writable_page) )
BUG();
@@ -418,7 +418,7 @@
l1tab += l1_table_offset(vpt_start);
for ( count = 0; count < nr_pt_pages; count++ )
{
- page = &frame_table[l1e_get_pfn(*l1tab)];
+ page = pfn_to_page(l1e_get_pfn(*l1tab));
if ( !opt_dom0_shadow )
l1e_remove_flags(*l1tab, _PAGE_RW);
else
@@ -548,7 +548,7 @@
*l1tab = l1e_from_pfn(mfn, L1_PROT);
l1tab++;
- page = &frame_table[mfn];
+ page = pfn_to_page(mfn);
if ( (page->u.inuse.type_info == 0) &&
!get_page_and_type(page, d, PGT_writable_page) )
BUG();
@@ -567,7 +567,7 @@
for ( count = 0; count < nr_pt_pages; count++ )
{
l1e_remove_flags(*l1tab, _PAGE_RW);
- page = &frame_table[l1e_get_pfn(*l1tab)];
+ page = pfn_to_page(l1e_get_pfn(*l1tab));
/* Read-only mapping + PGC_allocated + page-table page. */
page->count_info = PGC_allocated | 3;
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/mm.c Tue Dec 20 17:16:24 2005
@@ -202,7 +202,7 @@
/* First 1MB of RAM is historically marked as I/O. */
for ( i = 0; i < 0x100; i++ )
{
- page = &frame_table[i];
+ page = pfn_to_page(i);
page->count_info = PGC_allocated | 1;
page->u.inuse.type_info = PGT_writable_page | PGT_validated | 1;
page_set_owner(page, dom_io);
@@ -216,10 +216,10 @@
/* Every page from cursor to start of next RAM region is I/O. */
rstart_pfn = PFN_UP(e820.map[i].addr);
rend_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
- while ( pfn < rstart_pfn )
+ for ( ; pfn < rstart_pfn; pfn++ )
{
BUG_ON(!pfn_valid(pfn));
- page = &frame_table[pfn++];
+ page = pfn_to_page(pfn);
page->count_info = PGC_allocated | 1;
page->u.inuse.type_info = PGT_writable_page | PGT_validated | 1;
page_set_owner(page, dom_io);
@@ -253,7 +253,7 @@
pfn = l1e_get_pfn(v->arch.perdomain_ptes[i]);
if ( pfn == 0 ) continue;
v->arch.perdomain_ptes[i] = l1e_empty();
- page = &frame_table[pfn];
+ page = pfn_to_page(pfn);
ASSERT_PAGE_IS_TYPE(page, PGT_ldt_page);
ASSERT_PAGE_IS_DOMAIN(page, v->domain);
put_page_and_type(page);
@@ -320,13 +320,13 @@
if ( unlikely(!VALID_MFN(gmfn)) )
return 0;
- res = get_page_and_type(&frame_table[gmfn], d, PGT_ldt_page);
+ res = get_page_and_type(pfn_to_page(gmfn), d, PGT_ldt_page);
if ( !res && unlikely(shadow_mode_refcounts(d)) )
{
shadow_lock(d);
shadow_remove_all_write_access(d, gpfn, gmfn);
- res = get_page_and_type(&frame_table[gmfn], d, PGT_ldt_page);
+ res = get_page_and_type(pfn_to_page(gmfn), d, PGT_ldt_page);
shadow_unlock(d);
}
@@ -344,7 +344,7 @@
static int get_page_from_pagenr(unsigned long page_nr, struct domain *d)
{
- struct pfn_info *page = &frame_table[page_nr];
+ struct pfn_info *page = pfn_to_page(page_nr);
if ( unlikely(!pfn_valid(page_nr)) || unlikely(!get_page(page, d)) )
{
@@ -360,7 +360,7 @@
unsigned long type,
struct domain *d)
{
- struct pfn_info *page = &frame_table[page_nr];
+ struct pfn_info *page = pfn_to_page(page_nr);
if ( unlikely(!get_page_from_pagenr(page_nr, d)) )
return 0;
@@ -412,7 +412,7 @@
* Make sure that the mapped frame is an already-validated L2 table.
* If so, atomically increment the count (checking for overflow).
*/
- page = &frame_table[pfn];
+ page = pfn_to_page(pfn);
y = page->u.inuse.type_info;
do {
x = y;
@@ -435,7 +435,7 @@
l1_pgentry_t l1e, struct domain *d)
{
unsigned long mfn = l1e_get_pfn(l1e);
- struct pfn_info *page = &frame_table[mfn];
+ struct pfn_info *page = pfn_to_page(mfn);
int okay;
extern int domain_iomem_in_pfn(struct domain *d, unsigned long pfn);
@@ -587,7 +587,7 @@
void put_page_from_l1e(l1_pgentry_t l1e, struct domain *d)
{
unsigned long pfn = l1e_get_pfn(l1e);
- struct pfn_info *page = &frame_table[pfn];
+ struct pfn_info *page = pfn_to_page(pfn);
struct domain *e;
struct vcpu *v;
@@ -645,7 +645,7 @@
{
if ( (l2e_get_flags(l2e) & _PAGE_PRESENT) &&
(l2e_get_pfn(l2e) != pfn) )
- put_page_and_type(&frame_table[l2e_get_pfn(l2e)]);
+ put_page_and_type(pfn_to_page(l2e_get_pfn(l2e)));
}
@@ -655,7 +655,7 @@
{
if ( (l3e_get_flags(l3e) & _PAGE_PRESENT) &&
(l3e_get_pfn(l3e) != pfn) )
- put_page_and_type(&frame_table[l3e_get_pfn(l3e)]);
+ put_page_and_type(pfn_to_page(l3e_get_pfn(l3e)));
}
#endif
@@ -666,7 +666,7 @@
{
if ( (l4e_get_flags(l4e) & _PAGE_PRESENT) &&
(l4e_get_pfn(l4e) != pfn) )
- put_page_and_type(&frame_table[l4e_get_pfn(l4e)]);
+ put_page_and_type(pfn_to_page(l4e_get_pfn(l4e)));
}
#endif
@@ -1584,9 +1584,9 @@
write_ptbase(v);
if ( shadow_mode_refcounts(d) )
- put_page(&frame_table[old_base_mfn]);
+ put_page(pfn_to_page(old_base_mfn));
else
- put_page_and_type(&frame_table[old_base_mfn]);
+ put_page_and_type(pfn_to_page(old_base_mfn));
/* CR3 also holds a ref to its shadow... */
if ( shadow_mode_enabled(d) )
@@ -1595,7 +1595,7 @@
put_shadow_ref(v->arch.monitor_shadow_ref);
v->arch.monitor_shadow_ref =
pagetable_get_pfn(v->arch.monitor_table);
- ASSERT(!page_get_owner(&frame_table[v->arch.monitor_shadow_ref]));
+ ASSERT(!page_get_owner(pfn_to_page(v->arch.monitor_shadow_ref)));
get_shadow_ref(v->arch.monitor_shadow_ref);
}
}
@@ -1763,7 +1763,7 @@
okay = 1;
mfn = op.arg1.mfn;
- page = &frame_table[mfn];
+ page = pfn_to_page(mfn);
switch ( op.cmd )
{
@@ -1845,7 +1845,7 @@
pagetable_get_pfn(v->arch.guest_table_user);
v->arch.guest_table_user = mk_pagetable(mfn << PAGE_SHIFT);
if ( old_mfn != 0 )
- put_page_and_type(&frame_table[old_mfn]);
+ put_page_and_type(pfn_to_page(old_mfn));
}
break;
#endif
@@ -2145,7 +2145,7 @@
va = map_domain_page_with_cache(mfn, &mapcache);
va = (void *)((unsigned long)va +
(unsigned long)(req.ptr & ~PAGE_MASK));
- page = &frame_table[mfn];
+ page = pfn_to_page(mfn);
switch ( (type_info = page->u.inuse.type_info) & PGT_type_mask )
{
@@ -2285,7 +2285,7 @@
mark_dirty(FOREIGNDOM, mfn);
- put_page(&frame_table[mfn]);
+ put_page(pfn_to_page(mfn));
break;
default:
@@ -2728,7 +2728,7 @@
for ( i = 0; i < FIRST_RESERVED_GDT_PAGE; i++ )
{
if ( (pfn = l1e_get_pfn(v->arch.perdomain_ptes[i])) != 0 )
- put_page_and_type(&frame_table[pfn]);
+ put_page_and_type(pfn_to_page(pfn));
v->arch.perdomain_ptes[i] = l1e_empty();
v->arch.guest_context.gdt_frames[i] = 0;
}
@@ -2753,7 +2753,7 @@
for ( i = 0; i < nr_pages; i++ ) {
pfn = frames[i];
if ((pfn >= max_page) ||
- !get_page_and_type(&frame_table[pfn], d, PGT_gdt_page) )
+ !get_page_and_type(pfn_to_page(pfn), d, PGT_gdt_page) )
goto fail;
}
@@ -2773,7 +2773,7 @@
fail:
while ( i-- > 0 )
- put_page_and_type(&frame_table[frames[i]]);
+ put_page_and_type(pfn_to_page(frames[i]));
return -EINVAL;
}
@@ -2827,7 +2827,7 @@
return -EINVAL;
}
- page = &frame_table[mfn];
+ page = pfn_to_page(mfn);
if ( unlikely(!get_page(page, dom)) )
{
UNLOCK_BIGLOCK(dom);
@@ -3037,7 +3037,7 @@
if ( likely(l1e_get_intpte(ol1e) == (l1e_get_intpte(nl1e)|_PAGE_RW)) )
{
if ( likely(l1e_get_flags(nl1e) & _PAGE_PRESENT) )
- put_page_type(&frame_table[l1e_get_pfn(nl1e)]);
+ put_page_type(pfn_to_page(l1e_get_pfn(nl1e)));
continue;
}
@@ -3220,7 +3220,7 @@
}
pfn = l1e_get_pfn(pte);
- page = &frame_table[pfn];
+ page = pfn_to_page(pfn);
/* We are looking only for read-only mappings of p.t. pages. */
if ( ((l1e_get_flags(pte) & (_PAGE_RW|_PAGE_PRESENT)) != _PAGE_PRESENT) ||
@@ -3331,7 +3331,7 @@
}
pfn = l1e_get_pfn(pte);
- page = &frame_table[pfn];
+ page = pfn_to_page(pfn);
#ifdef CONFIG_X86_64
#define WRPT_PTE_FLAGS (_PAGE_RW | _PAGE_PRESENT | _PAGE_USER)
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/setup.c Tue Dec 20 17:16:24 2005
@@ -264,7 +264,7 @@
unsigned long _initrd_start = 0, _initrd_len = 0;
unsigned int initrdidx = 1;
physaddr_t s, e;
- int i, e820_raw_nr = 0, bytes = 0;
+ int i, e820_warn = 0, e820_raw_nr = 0, bytes = 0;
struct ns16550_defaults ns16550 = {
.data_bits = 8,
.parity = 'n',
@@ -313,6 +313,22 @@
while ( bytes < mbi->mmap_length )
{
memory_map_t *map = __va(mbi->mmap_addr + bytes);
+
+ /*
+ * This is a gross workaround for a BIOS bug. Some bootloaders do
+ * not write e820 map entries into pre-zeroed memory. This is
+ * okay if the BIOS fills in all fields of the map entry, but
+ * some broken BIOSes do not bother to write the high word of
+ * the length field if the length is smaller than 4GB. We
+ * detect and fix this by flagging sections below 4GB that
+ * appear to be larger than 4GB in size.
+ */
+ if ( (map->base_addr_high == 0) && (map->length_high != 0) )
+ {
+ e820_warn = 1;
+ map->length_high = 0;
+ }
+
e820_raw[e820_raw_nr].addr =
((u64)map->base_addr_high << 32) | (u64)map->base_addr_low;
e820_raw[e820_raw_nr].size =
@@ -320,6 +336,7 @@
e820_raw[e820_raw_nr].type =
(map->type > E820_SHARED_PAGE) ? E820_RESERVED : map->type;
e820_raw_nr++;
+
bytes += map->size + 4;
}
}
@@ -338,6 +355,10 @@
printk("FATAL ERROR: Bootloader provided no memory information.\n");
for ( ; ; ) ;
}
+
+ if ( e820_warn )
+ printk("WARNING: Buggy e820 map detected and fixed "
+ "(truncated length fields).\n");
max_page = init_e820(e820_raw, &e820_raw_nr);
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/shadow.c
--- a/xen/arch/x86/shadow.c Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/shadow.c Tue Dec 20 17:16:24 2005
@@ -504,7 +504,7 @@
l2e_from_pfn(smfn, __PAGE_HYPERVISOR);
spl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
-
l2e_from_paddr(__pa(page_get_owner(&frame_table[gmfn])->arch.mm_perdomain_pt),
+
l2e_from_paddr(__pa(page_get_owner(pfn_to_page(gmfn))->arch.mm_perdomain_pt),
__PAGE_HYPERVISOR);
if ( shadow_mode_translate(d) ) // NB: not external
@@ -670,7 +670,7 @@
set_guest_back_ptr(d, sl1e, sl1mfn, i);
}
- frame_table[sl1mfn].tlbflush_timestamp =
+ pfn_to_page(sl1mfn)->tlbflush_timestamp =
SHADOW_ENCODE_MIN_MAX(min, max);
unmap_domain_page(gpl1e);
@@ -907,7 +907,7 @@
u32 min_max = 0;
int min, max, length;
- if ( test_and_set_bit(_PGC_out_of_sync, &frame_table[gmfn].count_info) )
+ if ( test_and_set_bit(_PGC_out_of_sync, &pfn_to_page(gmfn)->count_info) )
{
ASSERT(__shadow_status(d, gpfn, PGT_snapshot));
return SHADOW_SNAPSHOT_ELSEWHERE;
@@ -953,7 +953,7 @@
unsigned long mfn)
{
struct domain *d = v->domain;
- struct pfn_info *page = &frame_table[mfn];
+ struct pfn_info *page = pfn_to_page(mfn);
struct out_of_sync_entry *entry = shadow_alloc_oos_entry(d);
ASSERT(shadow_lock_is_acquired(d));
@@ -1174,7 +1174,7 @@
&& i == PAGING_L4)
continue; /* skip the top-level for 3-level */
- if ( page_out_of_sync(&frame_table[gmfn]) &&
+ if ( page_out_of_sync(pfn_to_page(gmfn)) &&
!snapshot_entry_matches(
d, guest_pt, gpfn, table_offset_64(va, i)) )
{
@@ -1200,7 +1200,7 @@
}
/* L2 */
- if ( page_out_of_sync(&frame_table[gmfn]) &&
+ if ( page_out_of_sync(pfn_to_page(gmfn)) &&
!snapshot_entry_matches(d, guest_pt, gpfn, l2_table_offset(va)) )
{
unmap_and_return (1);
@@ -1214,7 +1214,7 @@
#undef unmap_and_return
#endif /* CONFIG_PAGING_LEVELS >= 3 */
{
- if ( page_out_of_sync(&frame_table[l2mfn]) &&
+ if ( page_out_of_sync(pfn_to_page(l2mfn)) &&
!snapshot_entry_matches(d, (guest_l1_pgentry_t
*)v->arch.guest_vtable,
l2pfn, guest_l2_table_offset(va)) )
return 1;
@@ -1234,7 +1234,7 @@
guest_pt = (guest_l1_pgentry_t *) map_domain_page(l1mfn);
- if ( page_out_of_sync(&frame_table[l1mfn]) &&
+ if ( page_out_of_sync(pfn_to_page(l1mfn)) &&
!snapshot_entry_matches(
d, guest_pt, l1pfn, guest_l1_table_offset(va)) )
{
@@ -1324,18 +1324,18 @@
int i;
u32 found = 0;
int is_l1_shadow =
- ((frame_table[pt_mfn].u.inuse.type_info & PGT_type_mask) ==
+ ((pfn_to_page(pt_mfn)->u.inuse.type_info & PGT_type_mask) ==
PGT_l1_shadow);
#if CONFIG_PAGING_LEVELS == 4
is_l1_shadow |=
- ((frame_table[pt_mfn].u.inuse.type_info & PGT_type_mask) ==
+ ((pfn_to_page(pt_mfn)->u.inuse.type_info & PGT_type_mask) ==
PGT_fl1_shadow);
#endif
match = l1e_from_pfn(readonly_gmfn, flags);
if ( shadow_mode_external(d) ) {
- i = (frame_table[readonly_gmfn].u.inuse.type_info & PGT_va_mask)
+ i = (pfn_to_page(readonly_gmfn)->u.inuse.type_info & PGT_va_mask)
>> PGT_va_shift;
if ( (i >= 0 && i < L1_PAGETABLE_ENTRIES) &&
@@ -1373,7 +1373,7 @@
// If it's not a writable page, then no writable refs can be outstanding.
//
- if ( (frame_table[readonly_gmfn].u.inuse.type_info & PGT_type_mask) !=
+ if ( (pfn_to_page(readonly_gmfn)->u.inuse.type_info & PGT_type_mask) !=
PGT_writable_page )
{
perfc_incrc(remove_write_not_writable);
@@ -1383,7 +1383,7 @@
// How many outstanding writable PTEs for this page are there?
//
write_refs =
- (frame_table[readonly_gmfn].u.inuse.type_info & PGT_count_mask);
+ (pfn_to_page(readonly_gmfn)->u.inuse.type_info & PGT_count_mask);
if ( write_refs && MFN_PINNED(readonly_gmfn) )
{
write_refs--;
@@ -1401,7 +1401,7 @@
// Use the back pointer to locate the shadow page that can contain
// the PTE of interest
- if ( (predicted_smfn = frame_table[readonly_gmfn].tlbflush_timestamp)
) {
+ if ( (predicted_smfn =
pfn_to_page(readonly_gmfn)->tlbflush_timestamp) ) {
found += remove_all_write_access_in_ptpage(
d, predicted_smfn, predicted_smfn, readonly_gpfn,
readonly_gmfn, write_refs, 0);
if ( found == write_refs )
@@ -1670,7 +1670,7 @@
if ( !(entry_get_flags(guest_pt[i]) & _PAGE_PRESENT) &&
unlikely(entry_get_value(guest_pt[i]) != 0) &&
!unshadow &&
- (frame_table[smfn].u.inuse.type_info & PGT_pinned) )
+ (pfn_to_page(smfn)->u.inuse.type_info & PGT_pinned) )
unshadow = 1;
}
#endif
@@ -1718,7 +1718,7 @@
if ( !(guest_root_get_flags(new_root_e) & _PAGE_PRESENT) &&
unlikely(guest_root_get_intpte(new_root_e) != 0) &&
!unshadow &&
- (frame_table[smfn].u.inuse.type_info & PGT_pinned) )
+ (pfn_to_page(smfn)->u.inuse.type_info & PGT_pinned) )
unshadow = 1;
}
if ( max == -1 )
@@ -2401,7 +2401,7 @@
{
printk("eff_guest_pfn=%lx eff_guest_mfn=%lx shadow_mfn=%lx t=0x%08lx
page_table_page=%d\n",
eff_guest_pfn, eff_guest_mfn, shadow_mfn,
- frame_table[eff_guest_mfn].u.inuse.type_info,
+ pfn_to_page(eff_guest_mfn)->u.inuse.type_info,
page_table_page);
FAIL("RW coherence");
}
@@ -2412,7 +2412,7 @@
{
printk("eff_guest_pfn=%lx eff_guest_mfn=%lx shadow_mfn=%lx t=0x%08lx
page_table_page=%d\n",
eff_guest_pfn, eff_guest_mfn, shadow_mfn,
- frame_table[eff_guest_mfn].u.inuse.type_info,
+ pfn_to_page(eff_guest_mfn)->u.inuse.type_info,
page_table_page);
FAIL("RW2 coherence");
}
@@ -2781,7 +2781,7 @@
* When we free L2 pages, we need to tell if the page contains
* Xen private mappings. Use the va_mask part.
*/
- frame_table[s2mfn].u.inuse.type_info |=
+ pfn_to_page(s2mfn)->u.inuse.type_info |=
(unsigned long) 3 << PGT_score_shift;
memset(spl2e, 0,
@@ -2794,7 +2794,7 @@
for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
spl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i] =
l2e_from_page(
-
virt_to_page(page_get_owner(&frame_table[gmfn])->arch.mm_perdomain_pt) + i,
+
virt_to_page(page_get_owner(pfn_to_page(gmfn))->arch.mm_perdomain_pt) + i,
__PAGE_HYPERVISOR);
for ( i = 0; i < (LINEARPT_MBYTES >> (L2_PAGETABLE_SHIFT - 20)); i++ )
spl2e[l2_table_offset(LINEAR_PT_VIRT_START) + i] =
@@ -2896,7 +2896,7 @@
ROOT_PAGETABLE_XEN_SLOTS * sizeof(l4_pgentry_t));
spl4e[l4_table_offset(PERDOMAIN_VIRT_START)] =
-
l4e_from_paddr(__pa(page_get_owner(&frame_table[gmfn])->arch.mm_perdomain_l3),
+
l4e_from_paddr(__pa(page_get_owner(pfn_to_page(gmfn))->arch.mm_perdomain_l3),
__PAGE_HYPERVISOR);
if ( shadow_mode_translate(d) ) // NB: not external
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/shadow32.c
--- a/xen/arch/x86/shadow32.c Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/shadow32.c Tue Dec 20 17:16:24 2005
@@ -30,7 +30,7 @@
#include <xen/sched.h>
#include <xen/trace.h>
-#define MFN_PINNED(_x) (frame_table[_x].u.inuse.type_info & PGT_pinned)
+#define MFN_PINNED(_x) (pfn_to_page(_x)->u.inuse.type_info & PGT_pinned)
#define va_to_l1mfn(_ed, _va) \
(l2e_get_pfn(linear_l2_table(_ed)[_va>>L2_PAGETABLE_SHIFT]))
@@ -144,11 +144,11 @@
if ( !shadow_mode_refcounts(d) )
return;
- ASSERT(frame_table[gmfn].count_info & PGC_page_table);
+ ASSERT(pfn_to_page(gmfn)->count_info & PGC_page_table);
if ( shadow_max_pgtable_type(d, gpfn, NULL) == PGT_none )
{
- clear_bit(_PGC_page_table, &frame_table[gmfn].count_info);
+ clear_bit(_PGC_page_table, &pfn_to_page(gmfn)->count_info);
if ( page_out_of_sync(pfn_to_page(gmfn)) )
{
@@ -380,7 +380,7 @@
void free_shadow_page(unsigned long smfn)
{
- struct pfn_info *page = &frame_table[smfn];
+ struct pfn_info *page = pfn_to_page(smfn);
unsigned long gmfn = page->u.inuse.type_info & PGT_mfn_mask;
struct domain *d = page_get_owner(pfn_to_page(gmfn));
unsigned long gpfn = __mfn_to_gpfn(d, gmfn);
@@ -465,8 +465,8 @@
{
struct pfn_info *page;
- page = &frame_table[entry->gmfn];
-
+ page = pfn_to_page(entry->gmfn);
+
// Decrement ref count of guest & shadow pages
//
put_page(page);
@@ -795,7 +795,7 @@
*/
mfn = pagetable_get_pfn(v->arch.monitor_table);
unmap_domain_page(v->arch.monitor_vtable);
- free_domheap_page(&frame_table[mfn]);
+ free_domheap_page(pfn_to_page(mfn));
v->arch.monitor_table = mk_pagetable(0);
v->arch.monitor_vtable = 0;
@@ -1018,8 +1018,8 @@
{
// external guests provide their own memory for their P2M maps.
//
- ASSERT( d == page_get_owner(
- &frame_table[pagetable_get_pfn(d->arch.phys_table)]) );
+ ASSERT(d == page_get_owner(pfn_to_page(pagetable_get_pfn(
+ d->arch.phys_table))));
}
}
@@ -1543,7 +1543,7 @@
l2e_from_pfn(smfn, __PAGE_HYPERVISOR);
spl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
-
l2e_from_paddr(__pa(page_get_owner(&frame_table[gmfn])->arch.mm_perdomain_pt),
+
l2e_from_paddr(__pa(page_get_owner(pfn_to_page(gmfn))->arch.mm_perdomain_pt),
__PAGE_HYPERVISOR);
if ( shadow_mode_translate(d) ) // NB: not external
@@ -1675,7 +1675,7 @@
set_guest_back_ptr(d, sl1e, sl1mfn, i);
}
- frame_table[sl1mfn].tlbflush_timestamp =
+ pfn_to_page(sl1mfn)->tlbflush_timestamp =
SHADOW_ENCODE_MIN_MAX(min, max);
}
}
@@ -1758,7 +1758,7 @@
u32 min_max = 0;
int min, max, length;
- if ( test_and_set_bit(_PGC_out_of_sync, &frame_table[gmfn].count_info) )
+ if ( test_and_set_bit(_PGC_out_of_sync, &pfn_to_page(gmfn)->count_info) )
{
ASSERT(__shadow_status(d, gpfn, PGT_snapshot));
return SHADOW_SNAPSHOT_ELSEWHERE;
@@ -1809,7 +1809,7 @@
// Clear the out_of_sync bit.
//
- clear_bit(_PGC_out_of_sync, &frame_table[entry->gmfn].count_info);
+ clear_bit(_PGC_out_of_sync, &pfn_to_page(entry->gmfn)->count_info);
// XXX Need to think about how to protect the domain's
// information less expensively.
@@ -1826,7 +1826,7 @@
unsigned long mfn)
{
struct domain *d = v->domain;
- struct pfn_info *page = &frame_table[mfn];
+ struct pfn_info *page = pfn_to_page(mfn);
struct out_of_sync_entry *entry = shadow_alloc_oos_entry(d);
ASSERT(shadow_lock_is_acquired(d));
@@ -1992,7 +1992,7 @@
perfc_incrc(shadow_out_of_sync_calls);
- if ( page_out_of_sync(&frame_table[l2mfn]) &&
+ if ( page_out_of_sync(pfn_to_page(l2mfn)) &&
!snapshot_entry_matches(d, (l1_pgentry_t *)v->arch.guest_vtable,
l2pfn, l2_table_offset(va)) )
return 1;
@@ -2008,7 +2008,7 @@
if ( !VALID_MFN(l1mfn) )
return 0;
- if ( page_out_of_sync(&frame_table[l1mfn]) &&
+ if ( page_out_of_sync(pfn_to_page(l1mfn)) &&
!snapshot_entry_matches(
d, &linear_pg_table[l1_linear_offset(va) &
~(L1_PAGETABLE_ENTRIES-1)],
l1pfn, l1_table_offset(va)) )
@@ -2136,13 +2136,13 @@
int i;
u32 found = 0;
int is_l1_shadow =
- ((frame_table[pt_mfn].u.inuse.type_info & PGT_type_mask) ==
+ ((pfn_to_page(pt_mfn)->u.inuse.type_info & PGT_type_mask) ==
PGT_l1_shadow);
match = l1e_from_pfn(readonly_gmfn, flags);
if ( shadow_mode_external(d) ) {
- i = (frame_table[readonly_gmfn].u.inuse.type_info & PGT_va_mask)
+ i = (pfn_to_page(readonly_gmfn)->u.inuse.type_info & PGT_va_mask)
>> PGT_va_shift;
if ( (i >= 0 && i < L1_PAGETABLE_ENTRIES) &&
@@ -2180,7 +2180,7 @@
// If it's not a writable page, then no writable refs can be outstanding.
//
- if ( (frame_table[readonly_gmfn].u.inuse.type_info & PGT_type_mask) !=
+ if ( (pfn_to_page(readonly_gmfn)->u.inuse.type_info & PGT_type_mask) !=
PGT_writable_page )
{
perfc_incrc(remove_write_not_writable);
@@ -2190,7 +2190,7 @@
// How many outstanding writable PTEs for this page are there?
//
write_refs =
- (frame_table[readonly_gmfn].u.inuse.type_info & PGT_count_mask);
+ (pfn_to_page(readonly_gmfn)->u.inuse.type_info & PGT_count_mask);
if ( write_refs && MFN_PINNED(readonly_gmfn) )
{
write_refs--;
@@ -2208,7 +2208,7 @@
// Use the back pointer to locate the shadow page that can contain
// the PTE of interest
- if ( (predicted_smfn = frame_table[readonly_gmfn].tlbflush_timestamp)
) {
+ if ( (predicted_smfn =
pfn_to_page(readonly_gmfn)->tlbflush_timestamp) ) {
found += remove_all_write_access_in_ptpage(
d, predicted_smfn, predicted_smfn, readonly_gpfn,
readonly_gmfn, write_refs, 0);
if ( found == write_refs )
@@ -2249,7 +2249,7 @@
int i;
u32 count = 0;
int is_l1_shadow =
- ((frame_table[l1mfn].u.inuse.type_info & PGT_type_mask) ==
+ ((pfn_to_page(l1mfn)->u.inuse.type_info & PGT_type_mask) ==
PGT_l1_shadow);
match = l1e_from_pfn(forbidden_gmfn, flags);
@@ -2266,7 +2266,7 @@
if ( is_l1_shadow )
shadow_put_page_from_l1e(ol2e, d);
else /* must be an hl2 page */
- put_page(&frame_table[forbidden_gmfn]);
+ put_page(pfn_to_page(forbidden_gmfn));
}
unmap_domain_page(pl1e);
@@ -2982,6 +2982,23 @@
}
}
+void clear_all_shadow_status(struct domain *d)
+{
+ shadow_lock(d);
+ free_shadow_pages(d);
+ free_shadow_ht_entries(d);
+ d->arch.shadow_ht =
+ xmalloc_array(struct shadow_status, shadow_ht_buckets);
+ if ( d->arch.shadow_ht == NULL ) {
+ printk("clear all shadow status:xmalloc fail\n");
+ domain_crash_synchronous();
+ }
+ memset(d->arch.shadow_ht, 0,
+ shadow_ht_buckets * sizeof(struct shadow_status));
+
+ free_out_of_sync_entries(d);
+ shadow_unlock(d);
+}
/************************************************************************/
/************************************************************************/
@@ -3139,7 +3156,7 @@
{
printk("eff_guest_pfn=%lx eff_guest_mfn=%lx shadow_mfn=%lx t=%lx
page_table_page=%d\n",
eff_guest_pfn, eff_guest_mfn, shadow_mfn,
- frame_table[eff_guest_mfn].u.inuse.type_info,
+ pfn_to_page(eff_guest_mfn)->u.inuse.type_info,
page_table_page);
FAIL("RW coherence");
}
@@ -3150,7 +3167,7 @@
{
printk("eff_guest_pfn=%lx eff_guest_mfn=%lx shadow_mfn=%lx t=%lx
page_table_page=%d\n",
eff_guest_pfn, eff_guest_mfn, shadow_mfn,
- frame_table[eff_guest_mfn].u.inuse.type_info,
+ pfn_to_page(eff_guest_mfn)->u.inuse.type_info,
page_table_page);
FAIL("RW2 coherence");
}
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/shadow_public.c
--- a/xen/arch/x86/shadow_public.c Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/shadow_public.c Tue Dec 20 17:16:24 2005
@@ -168,14 +168,14 @@
#if CONFIG_PAGING_LEVELS >=3
if ( d->arch.ops->guest_paging_levels == PAGING_L2 )
{
- struct pfn_info *page = &frame_table[smfn];
+ struct pfn_info *page = pfn_to_page(smfn);
for ( i = 0; i < PDP_ENTRIES; i++ )
{
if ( entry_get_flags(ple[i]) & _PAGE_PRESENT )
free_fake_shadow_l2(d,entry_get_pfn(ple[i]));
}
- page = &frame_table[entry_get_pfn(ple[0])];
+ page = pfn_to_page(entry_get_pfn(ple[0]));
free_domheap_pages(page, SL2_ORDER);
unmap_domain_page(ple);
}
@@ -208,7 +208,7 @@
break;
if ( level == PAGING_L2 )
{
- struct pfn_info *page = &frame_table[smfn];
+ struct pfn_info *page = pfn_to_page(smfn);
if ( is_xen_l2_slot(page->u.inuse.type_info, i) )
continue;
}
@@ -299,7 +299,7 @@
*/
mfn = pagetable_get_pfn(v->arch.monitor_table);
unmap_domain_page(v->arch.monitor_vtable);
- free_domheap_page(&frame_table[mfn]);
+ free_domheap_page(pfn_to_page(mfn));
v->arch.monitor_table = mk_pagetable(0);
v->arch.monitor_vtable = 0;
@@ -394,7 +394,7 @@
*/
mfn = pagetable_get_pfn(v->arch.monitor_table);
unmap_domain_page(v->arch.monitor_vtable);
- free_domheap_page(&frame_table[mfn]);
+ free_domheap_page(pfn_to_page(mfn));
v->arch.monitor_table = mk_pagetable(0);
v->arch.monitor_vtable = 0;
@@ -411,7 +411,7 @@
// Clear the out_of_sync bit.
//
- clear_bit(_PGC_out_of_sync, &frame_table[entry->gmfn].count_info);
+ clear_bit(_PGC_out_of_sync, &pfn_to_page(entry->gmfn)->count_info);
// XXX Need to think about how to protect the domain's
// information less expensively.
@@ -428,7 +428,7 @@
{
struct pfn_info *page;
- page = &frame_table[entry->gmfn];
+ page = pfn_to_page(entry->gmfn);
// Decrement ref count of guest & shadow pages
//
@@ -501,11 +501,11 @@
if ( !shadow_mode_refcounts(d) )
return;
- ASSERT(frame_table[gmfn].count_info & PGC_page_table);
+ ASSERT(pfn_to_page(gmfn)->count_info & PGC_page_table);
if ( shadow_max_pgtable_type(d, gpfn, NULL) == PGT_none )
{
- clear_bit(_PGC_page_table, &frame_table[gmfn].count_info);
+ clear_bit(_PGC_page_table, &pfn_to_page(gmfn)->count_info);
if ( page_out_of_sync(pfn_to_page(gmfn)) )
{
@@ -600,7 +600,7 @@
void free_shadow_page(unsigned long smfn)
{
- struct pfn_info *page = &frame_table[smfn];
+ struct pfn_info *page = pfn_to_page(smfn);
unsigned long gmfn = page->u.inuse.type_info & PGT_mfn_mask;
struct domain *d = page_get_owner(pfn_to_page(gmfn));
@@ -1067,8 +1067,8 @@
{
// external guests provide their own memory for their P2M maps.
//
- ASSERT( d == page_get_owner(
- &frame_table[pagetable_get_pfn(d->arch.phys_table)]) );
+ ASSERT(d == page_get_owner(pfn_to_page(pagetable_get_pfn(
+ d->arch.phys_table))));
}
}
@@ -1643,7 +1643,7 @@
int i;
u32 count = 0;
int is_l1_shadow =
- ((frame_table[l1mfn].u.inuse.type_info & PGT_type_mask) ==
+ ((pfn_to_page(l1mfn)->u.inuse.type_info & PGT_type_mask) ==
PGT_l1_shadow);
match = l1e_from_pfn(forbidden_gmfn, flags);
@@ -1660,7 +1660,7 @@
if ( is_l1_shadow )
shadow_put_page_from_l1e(ol2e, d);
else /* must be an hl2 page */
- put_page(&frame_table[forbidden_gmfn]);
+ put_page(pfn_to_page(forbidden_gmfn));
}
unmap_domain_page(pl1e);
@@ -1747,6 +1747,24 @@
shadow_unlock(d);
}
+void clear_all_shadow_status(struct domain *d)
+{
+ shadow_lock(d);
+ free_shadow_pages(d);
+ free_shadow_ht_entries(d);
+ d->arch.shadow_ht =
+ xmalloc_array(struct shadow_status, shadow_ht_buckets);
+ if ( d->arch.shadow_ht == NULL ) {
+ printk("clear all shadow status:xmalloc fail\n");
+ domain_crash_synchronous();
+ }
+ memset(d->arch.shadow_ht, 0,
+ shadow_ht_buckets * sizeof(struct shadow_status));
+
+ free_out_of_sync_entries(d);
+ shadow_unlock(d);
+}
+
/*
* Local variables:
* mode: C
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/traps.c Tue Dec 20 17:16:24 2005
@@ -1074,29 +1074,35 @@
return 0;
}
-unsigned long nmi_softirq_reason;
-static void nmi_softirq(void)
+
+/* Defer dom0 notification to softirq context (unsafe in NMI context). */
+static unsigned long nmi_dom0_softirq_reason;
+#define NMI_DOM0_PARITY_ERR 0
+#define NMI_DOM0_IO_ERR 1
+#define NMI_DOM0_UNKNOWN 2
+
+static void nmi_dom0_softirq(void)
{
if ( dom0 == NULL )
return;
- if ( test_and_clear_bit(0, &nmi_softirq_reason) )
+ if ( test_and_clear_bit(NMI_DOM0_PARITY_ERR, &nmi_dom0_softirq_reason) )
send_guest_virq(dom0->vcpu[0], VIRQ_PARITY_ERR);
- if ( test_and_clear_bit(1, &nmi_softirq_reason) )
+ if ( test_and_clear_bit(NMI_DOM0_IO_ERR, &nmi_dom0_softirq_reason) )
send_guest_virq(dom0->vcpu[0], VIRQ_IO_ERR);
+
+ if ( test_and_clear_bit(NMI_DOM0_UNKNOWN, &nmi_dom0_softirq_reason) )
+ send_guest_virq(dom0->vcpu[0], VIRQ_NMI);
}
asmlinkage void mem_parity_error(struct cpu_user_regs *regs)
{
- /* Clear and disable the parity-error line. */
- outb((inb(0x61)&15)|4,0x61);
-
switch ( opt_nmi[0] )
{
case 'd': /* 'dom0' */
- set_bit(0, &nmi_softirq_reason);
- raise_softirq(NMI_SOFTIRQ);
+ set_bit(NMI_DOM0_PARITY_ERR, &nmi_dom0_softirq_reason);
+ raise_softirq(NMI_DOM0_SOFTIRQ);
case 'i': /* 'ignore' */
break;
default: /* 'fatal' */
@@ -1104,18 +1110,19 @@
printk("\n\nNMI - MEMORY ERROR\n");
fatal_trap(TRAP_nmi, regs);
}
+
+ outb((inb(0x61) & 0x0f) | 0x04, 0x61); /* clear-and-disable parity check */
+ mdelay(1);
+ outb((inb(0x61) & 0x0b) | 0x00, 0x61); /* enable parity check */
}
asmlinkage void io_check_error(struct cpu_user_regs *regs)
{
- /* Clear and disable the I/O-error line. */
- outb((inb(0x61)&15)|8,0x61);
-
switch ( opt_nmi[0] )
{
case 'd': /* 'dom0' */
- set_bit(0, &nmi_softirq_reason);
- raise_softirq(NMI_SOFTIRQ);
+ set_bit(NMI_DOM0_IO_ERR, &nmi_dom0_softirq_reason);
+ raise_softirq(NMI_DOM0_SOFTIRQ);
case 'i': /* 'ignore' */
break;
default: /* 'fatal' */
@@ -1123,43 +1130,59 @@
printk("\n\nNMI - I/O ERROR\n");
fatal_trap(TRAP_nmi, regs);
}
+
+ outb((inb(0x61) & 0x0f) | 0x08, 0x61); /* clear-and-disable IOCK */
+ mdelay(1);
+ outb((inb(0x61) & 0x07) | 0x00, 0x61); /* enable IOCK */
}
static void unknown_nmi_error(unsigned char reason)
{
- printk("Uhhuh. NMI received for unknown reason %02x.\n", reason);
- printk("Dazed and confused, but trying to continue\n");
- printk("Do you have a strange power saving mode enabled?\n");
-}
-
-static void default_do_nmi(struct cpu_user_regs *regs, unsigned long reason)
-{
- if ( nmi_watchdog )
- nmi_watchdog_tick(regs);
-
- if ( reason & 0x80 )
- mem_parity_error(regs);
- else if ( reason & 0x40 )
- io_check_error(regs);
- else if ( !nmi_watchdog )
- unknown_nmi_error((unsigned char)(reason&0xff));
+ switch ( opt_nmi[0] )
+ {
+ case 'd': /* 'dom0' */
+ set_bit(NMI_DOM0_UNKNOWN, &nmi_dom0_softirq_reason);
+ raise_softirq(NMI_DOM0_SOFTIRQ);
+ case 'i': /* 'ignore' */
+ break;
+ default: /* 'fatal' */
+ printk("Uhhuh. NMI received for unknown reason %02x.\n", reason);
+ printk("Dazed and confused, but trying to continue\n");
+ printk("Do you have a strange power saving mode enabled?\n");
+ }
}
static int dummy_nmi_callback(struct cpu_user_regs *regs, int cpu)
{
- return 0;
+ return 0;
}
static nmi_callback_t nmi_callback = dummy_nmi_callback;
-asmlinkage void do_nmi(struct cpu_user_regs *regs, unsigned long reason)
+asmlinkage void do_nmi(struct cpu_user_regs *regs)
{
unsigned int cpu = smp_processor_id();
+ unsigned char reason;
++nmi_count(cpu);
- if ( !nmi_callback(regs, cpu) )
- default_do_nmi(regs, reason);
+ if ( nmi_callback(regs, cpu) )
+ return;
+
+ if ( nmi_watchdog )
+ nmi_watchdog_tick(regs);
+
+ /* Only the BSP gets external NMIs from the system. */
+ if ( cpu == 0 )
+ {
+ reason = inb(0x61);
+ if ( reason & 0x80 )
+ mem_parity_error(regs);
+ else if ( reason & 0x40 )
+ io_check_error(regs);
+ else if ( !nmi_watchdog )
+ unknown_nmi_error((unsigned char)(reason&0xff));
+ }
}
void set_nmi_callback(nmi_callback_t callback)
@@ -1169,7 +1192,7 @@
void unset_nmi_callback(void)
{
- nmi_callback = dummy_nmi_callback;
+ nmi_callback = dummy_nmi_callback;
}
asmlinkage int math_state_restore(struct cpu_user_regs *regs)
@@ -1318,7 +1341,7 @@
cpu_init();
- open_softirq(NMI_SOFTIRQ, nmi_softirq);
+ open_softirq(NMI_DOM0_SOFTIRQ, nmi_dom0_softirq);
}
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/vmx.c
--- a/xen/arch/x86/vmx.c Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/vmx.c Tue Dec 20 17:16:24 2005
@@ -102,7 +102,8 @@
if (v->vcpu_id == 0) {
/* unmap IO shared page */
struct domain *d = v->domain;
- unmap_domain_page((void *)d->arch.vmx_platform.shared_page_va);
+ if ( d->arch.vmx_platform.shared_page_va )
+ unmap_domain_page((void *)d->arch.vmx_platform.shared_page_va);
}
destroy_vmcs(&v->arch.arch_vmx);
@@ -110,12 +111,12 @@
vpit = &v->domain->arch.vmx_platform.vmx_pit;
if ( active_ac_timer(&(vpit->pit_timer)) )
rem_ac_timer(&vpit->pit_timer);
- if ( active_ac_timer(&v->arch.arch_vmx.hlt_timer) ) {
+ if ( active_ac_timer(&v->arch.arch_vmx.hlt_timer) )
rem_ac_timer(&v->arch.arch_vmx.hlt_timer);
- }
- if ( vmx_apic_support(v->domain) ) {
- rem_ac_timer( &(VLAPIC(v)->vlapic_timer) );
- xfree( VLAPIC(v) );
+ if ( vmx_apic_support(v->domain) && (VLAPIC(v) != NULL) )
+ {
+ rem_ac_timer(&VLAPIC(v)->vlapic_timer);
+ xfree(VLAPIC(v));
}
}
@@ -334,7 +335,7 @@
extern long evtchn_send(int lport);
extern long do_block(void);
-void do_nmi(struct cpu_user_regs *, unsigned long);
+void do_nmi(struct cpu_user_regs *);
static int check_vmx_controls(ctrls, msr)
{
@@ -543,6 +544,13 @@
clear_bit(X86_FEATURE_VMXE & 31, &ecx);
clear_bit(X86_FEATURE_MWAIT & 31, &ecx);
}
+#ifdef __i386__
+ else if ( input == 0x80000001 )
+ {
+ /* Mask feature for Intel ia32e or AMD long mode. */
+ clear_bit(X86_FEATURE_LM & 31, &edx);
+ }
+#endif
regs->eax = (unsigned long) eax;
regs->ebx = (unsigned long) ebx;
@@ -1223,6 +1231,7 @@
}
}
+ clear_all_shadow_status(v->domain);
if (vmx_assist(v, VMX_ASSIST_INVOKE)) {
set_bit(VMX_CPU_STATE_ASSIST_ENABLED, &v->arch.arch_vmx.cpu_state);
__vmread(GUEST_RIP, &eip);
@@ -1841,7 +1850,7 @@
break;
}
case TRAP_nmi:
- do_nmi(®s, 0);
+ do_nmi(®s);
break;
default:
vmx_reflect_exception(v);
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/vmx_intercept.c
--- a/xen/arch/x86/vmx_intercept.c Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/vmx_intercept.c Tue Dec 20 17:16:24 2005
@@ -203,6 +203,12 @@
u64 nsec_delta = (unsigned int)((NOW() - vpit->inject_point));
if (nsec_delta > vpit->period)
VMX_DBG_LOG(DBG_LEVEL_1, "VMX_PIT:long time has passed from last
injection!");
+ if(vpit->init_val == 0)
+ {
+ printk("PIT init value == 0!\n");
+ domain_crash_synchronous();
+ }
+
vpit->count = vpit->init_val - ((nsec_delta * PIT_FREQ / 1000000000ULL) %
vpit->init_val );
}
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/x86_32/entry.S Tue Dec 20 17:16:24 2005
@@ -601,15 +601,7 @@
pushl %eax
SAVE_ALL_NOSEGREGS(a)
- # Check for hardware problems.
- inb $0x61,%al
- testb $0x80,%al
- jne nmi_parity_err
- testb $0x40,%al
- jne nmi_io_err
- movl %eax,%ebx
-
- # Okay, its almost a normal NMI tick. We can only process it if:
+ # We can only process the NMI if:
# A. We are the outermost Xen activation (in which case we have
# the selectors safely saved on our stack)
# B. DS and ES contain sane Xen values.
@@ -619,7 +611,7 @@
movl UREGS_eflags(%esp),%eax
movb UREGS_cs(%esp),%al
testl $(3|X86_EFLAGS_VM),%eax
- jnz do_watchdog_tick
+ jnz continue_nmi
movl %ds,%eax
cmpw $(__HYPERVISOR_DS),%ax
jne defer_nmi
@@ -627,15 +619,14 @@
cmpw $(__HYPERVISOR_DS),%ax
jne defer_nmi
-do_watchdog_tick:
+continue_nmi:
movl $(__HYPERVISOR_DS),%edx
movl %edx,%ds
movl %edx,%es
movl %esp,%edx
- pushl %ebx # reason
- pushl %edx # regs
+ pushl %edx
call do_nmi
- addl $8,%esp
+ addl $4,%esp
jmp ret_from_intr
defer_nmi:
@@ -648,55 +639,6 @@
movl $(APIC_DM_FIXED | APIC_DEST_SELF | APIC_DEST_LOGICAL | \
TRAP_deferred_nmi),%ss:APIC_ICR(%eax)
jmp restore_all_xen
-
-nmi_parity_err:
- # Clear and disable the parity-error line
- andb $0xf,%al
- orb $0x4,%al
- outb %al,$0x61
- cmpb $'i',%ss:opt_nmi # nmi=ignore
- je nmi_out
- bts $0,%ss:nmi_softirq_reason
- bts $NMI_SOFTIRQ,%ss:irq_stat
- cmpb $'d',%ss:opt_nmi # nmi=dom0
- je nmi_out
- movl $(__HYPERVISOR_DS),%edx # nmi=fatal
- movl %edx,%ds
- movl %edx,%es
- movl %esp,%edx
- push %edx
- call mem_parity_error
- addl $4,%esp
-nmi_out:movl %ss:UREGS_eflags(%esp),%eax
- movb %ss:UREGS_cs(%esp),%al
- testl $(3|X86_EFLAGS_VM),%eax
- jz restore_all_xen
- movl $(__HYPERVISOR_DS),%edx
- movl %edx,%ds
- movl %edx,%es
- GET_CURRENT(%ebx)
- jmp test_all_events
-
-nmi_io_err:
- # Clear and disable the I/O-error line
- andb $0xf,%al
- orb $0x8,%al
- outb %al,$0x61
- cmpb $'i',%ss:opt_nmi # nmi=ignore
- je nmi_out
- bts $1,%ss:nmi_softirq_reason
- bts $NMI_SOFTIRQ,%ss:irq_stat
- cmpb $'d',%ss:opt_nmi # nmi=dom0
- je nmi_out
- movl $(__HYPERVISOR_DS),%edx # nmi=fatal
- movl %edx,%ds
- movl %edx,%es
- movl %esp,%edx
- push %edx
- call io_check_error
- addl $4,%esp
- jmp nmi_out
-
ENTRY(setup_vm86_frame)
# Copies the entire stack frame forwards by 16 bytes.
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/x86_32/mm.c
--- a/xen/arch/x86/x86_32/mm.c Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/x86_32/mm.c Tue Dec 20 17:16:24 2005
@@ -177,10 +177,11 @@
idle_pg_table_l2[l2_linear_offset(RDWR_MPT_VIRT_START) + i]);
for ( j = 0; j < L2_PAGETABLE_ENTRIES; j++ )
{
- frame_table[m2p_start_mfn+j].count_info = PGC_allocated | 1;
+ struct pfn_info *page = pfn_to_page(m2p_start_mfn + j);
+ page->count_info = PGC_allocated | 1;
/* Ensure it's only mapped read-only by domains. */
- frame_table[m2p_start_mfn+j].u.inuse.type_info = PGT_gdt_page | 1;
- page_set_owner(&frame_table[m2p_start_mfn+j], dom_xen);
+ page->u.inuse.type_info = PGT_gdt_page | 1;
+ page_set_owner(page, dom_xen);
}
}
}
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/x86_32/traps.c Tue Dec 20 17:16:24 2005
@@ -160,9 +160,9 @@
BUILD_SMP_INTERRUPT(deferred_nmi, TRAP_deferred_nmi)
asmlinkage void smp_deferred_nmi(struct cpu_user_regs regs)
{
- asmlinkage void do_nmi(struct cpu_user_regs *, unsigned long);
+ asmlinkage void do_nmi(struct cpu_user_regs *);
ack_APIC_irq();
- do_nmi(®s, 0);
+ do_nmi(®s);
}
void __init percpu_traps_init(void)
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/x86_64/entry.S Tue Dec 20 17:16:24 2005
@@ -567,9 +567,7 @@
ENTRY(nmi)
pushq $0
SAVE_ALL
- inb $0x61,%al
- movl %eax,%esi # reason
- movq %rsp,%rdi # regs
+ movq %rsp,%rdi
call do_nmi
jmp restore_all_xen
diff -r 11cd619db035 -r d3b10a2a82d4 xen/arch/x86/x86_64/mm.c
--- a/xen/arch/x86/x86_64/mm.c Tue Dec 20 17:16:15 2005
+++ b/xen/arch/x86/x86_64/mm.c Tue Dec 20 17:16:24 2005
@@ -166,11 +166,12 @@
for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ )
{
- frame_table[m2p_start_mfn+i].count_info = PGC_allocated | 1;
+ struct pfn_info *page = pfn_to_page(m2p_start_mfn + i);
+ page->count_info = PGC_allocated | 1;
/* gdt to make sure it's only mapped read-only by non-privileged
domains. */
- frame_table[m2p_start_mfn+i].u.inuse.type_info = PGT_gdt_page | 1;
- page_set_owner(&frame_table[m2p_start_mfn+i], dom_xen);
+ page->u.inuse.type_info = PGT_gdt_page | 1;
+ page_set_owner(page, dom_xen);
}
}
}
diff -r 11cd619db035 -r d3b10a2a82d4 xen/common/dom0_ops.c
--- a/xen/common/dom0_ops.c Tue Dec 20 17:16:15 2005
+++ b/xen/common/dom0_ops.c Tue Dec 20 17:16:24 2005
@@ -358,12 +358,17 @@
case DOM0_GETDOMAININFO:
{
struct domain *d;
+ domid_t dom;
+
+ dom = op->u.getdomaininfo.domain;
+ if ( dom == DOMID_SELF )
+ dom = current->domain->domain_id;
read_lock(&domlist_lock);
for_each_domain ( d )
{
- if ( d->domain_id >= op->u.getdomaininfo.domain )
+ if ( d->domain_id >= dom )
break;
}
@@ -577,6 +582,22 @@
}
}
break;
+ case DOM0_SETDEBUGGING:
+ {
+ struct domain *d;
+ ret = -ESRCH;
+ d = find_domain_by_id(op->u.setdebugging.domain);
+ if ( d != NULL )
+ {
+ if ( op->u.setdebugging.enable )
+ set_bit(_DOMF_debugging, &d->domain_flags);
+ else
+ clear_bit(_DOMF_debugging, &d->domain_flags);
+ put_domain(d);
+ ret = 0;
+ }
+ }
+ break;
#ifdef PERF_COUNTERS
case DOM0_PERFCCONTROL:
diff -r 11cd619db035 -r d3b10a2a82d4 xen/common/grant_table.c
--- a/xen/common/grant_table.c Tue Dec 20 17:16:15 2005
+++ b/xen/common/grant_table.c Tue Dec 20 17:16:24 2005
@@ -238,8 +238,8 @@
if ( unlikely(!pfn_valid(frame)) ||
unlikely(!((dev_hst_ro_flags & GNTMAP_readonly) ?
- get_page(&frame_table[frame], rd) :
- get_page_and_type(&frame_table[frame], rd,
+ get_page(pfn_to_page(frame), rd) :
+ get_page_and_type(pfn_to_page(frame), rd,
PGT_writable_page))) )
{
clear_bit(_GTF_writing, &sha->flags);
@@ -301,7 +301,7 @@
sflags = prev_sflags;
}
- if ( unlikely(!get_page_type(&frame_table[frame],
+ if ( unlikely(!get_page_type(pfn_to_page(frame),
PGT_writable_page)) )
{
clear_bit(_GTF_writing, &sha->flags);
@@ -347,14 +347,14 @@
if ( (act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) == 0 )
{
clear_bit(_GTF_writing, &sha->flags);
- put_pag |