# HG changeset patch
# User djm@xxxxxxxxxxxxxxx
# Node ID b35215021b32c41a5c14e9fc42bc786652c4744a
# Parent d4d880fcef2860ebe3fd54b391147a57db06a5c7
# Parent e7c7196fa329a91c745c3e40546dc8b588ea0abb
Merge with latest xen-unstable
diff -r d4d880fcef28 -r b35215021b32 .hgignore
--- a/.hgignore Fri Sep 9 16:31:36 2005
+++ b/.hgignore Tue Sep 13 16:14:16 2005
@@ -19,6 +19,7 @@
^docs/.*\.toc$
^docs/figs/xenserver\.eps$
^docs/html/.*$
+^docs/api/.*$
^docs/interface/WARNINGS$
^docs/interface/images\.pl$
^docs/interface/images\.tex$
@@ -60,8 +61,6 @@
^pristine-.*$
^ref-.*$
^tools/.*/build/lib.*/.*\.py$
-^tools/Makefile\.smh$
-^tools/balloon/balloon$
^tools/blktap/Makefile\.smh$
^tools/blktap/blkcow$
^tools/blktap/blkcowgnbd$
@@ -85,8 +84,7 @@
^tools/blktap/ublkback/ublkback$
^tools/blktap/xen/.*$
^tools/check/\..*$
-^tools/cmdline/.*$
-^tools/cmdline/xen/.*$
+^tools/examples/xmexample\.vmx$
^tools/console/xenconsoled$
^tools/console/xenconsole$
^tools/debugger/pdb/pdb$
@@ -109,8 +107,6 @@
^tools/firmware/vmxassist/roms\.h$
^tools/firmware/vmxassist/vmxassist$
^tools/firmware/vmxassist/vmxloader$
-^tools/gdb/gdb-6\.2\.1-linux-i386-xen/.*$
-^tools/gdb/gdb-6\.2\.1/.*$
^tools/ioemu/config-host\..*$
^tools/ioemu/keysym_adapter_sdl\.h$
^tools/ioemu/keysym_adapter_vnc\.h$
@@ -141,20 +137,18 @@
^tools/vnet/vnet-module/\..*\.cmd$
^tools/vnet/vnet-module/\.tmp_versions/.*$
^tools/vnet/vnet-module/vnet_module\.mod\..*$
-^tools/vnetd/vnetd$
^tools/vtpm/vtpm*
^tools/vtpm/tpm_emulator-*
^tools/vtpm_manager/manager/vtpm_managerd
-^tools/web-shutdown\.tap$
-^tools/x2d2/minixend$
^tools/xcutils/xc_restore$
^tools/xcutils/xc_save$
^tools/xenstat/xentop/xentop$
^tools/xenstore/testsuite/tmp/.*$
^tools/xenstore/xen$
-^tools/xenstore/xenbus_dev.h$
^tools/xenstore/xenstored$
^tools/xenstore/xenstored_test$
+^tools/xenstore/xenstore-exists$
+^tools/xenstore/xenstore-list$
^tools/xenstore/xenstore-read$
^tools/xenstore/xenstore-rm$
^tools/xenstore/xenstore-write$
diff -r d4d880fcef28 -r b35215021b32 Makefile
--- a/Makefile Fri Sep 9 16:31:36 2005
+++ b/Makefile Tue Sep 13 16:14:16 2005
@@ -35,8 +35,8 @@
export pae=y
endif
-.PHONY: all dist install xen kernels tools docs world clean mkpatches
mrproper
-.PHONY: kbuild kdelete kclean
+.PHONY: all dist install xen kernels tools dev-docs docs world clean
+.PHONY: mkpatches mrproper kbuild kdelete kclean
# build and install everything into the standard system directories
install: install-xen install-kernels install-tools install-docs
@@ -65,6 +65,9 @@
docs:
sh ./docs/check_pkgs && $(MAKE) -C docs install || true
+
+dev-docs:
+ $(MAKE) -C docs dev-docs
# Build all the various kernels and modules
kbuild: kernels
@@ -123,7 +126,7 @@
@echo ' install-xen - build and install the Xen hypervisor'
@echo ' install-tools - build and install the control tools'
@echo ' install-kernels - build and install guest kernels'
- @echo ' install-docs - build and install documentation'
+ @echo ' install-docs - build and install user documentation'
@echo ''
@echo 'Building targets:'
@echo ' dist - build and install everything into local
dist directory'
@@ -133,7 +136,8 @@
@echo ' tools - build and install tools'
@echo ' kernels - build and install guest kernels'
@echo ' kbuild - synonym for make kernels'
- @echo ' docs - build and install docs'
+ @echo ' docs - build and install user documentation'
+ @echo ' dev-docs - build developer-only documentation'
@echo ''
@echo 'Cleaning targets:'
@echo ' clean - clean the Xen, tools and docs (but not'
diff -r d4d880fcef28 -r b35215021b32 docs/Makefile
--- a/docs/Makefile Fri Sep 9 16:31:36 2005
+++ b/docs/Makefile Tue Sep 13 16:14:16 2005
@@ -8,6 +8,7 @@
LATEX := latex
FIG2DEV := fig2dev
LATEX2HTML := latex2html
+DOXYGEN := doxygen
pkgdocdir := /usr/share/doc/xen
@@ -18,9 +19,13 @@
GFX = $(patsubst %.fig, %.eps, $(wildcard figs/*.fig))
+.PHONY: all build dev-docs python-dev-docs ps pdf html clean install
+
all: build
build: ps pdf html
rm -f *.aux *.dvi *.bbl *.blg *.glo *.idx *.ilg *.log *.ind *.toc
+
+dev-docs: python-dev-docs
ps: $(DOC_PS)
@@ -30,10 +35,18 @@
@if which $(LATEX2HTML) 1>/dev/null 2>/dev/null; then \
$(MAKE) $(DOC_HTML); fi
+python-dev-docs:
+ mkdir -p api/tools/python
+ @if which $(DOXYGEN) 1>/dev/null 2>/dev/null; then \
+ echo "Running doxygen to generate Python tools APIs ... "; \
+ $(DOXYGEN) Doxyfile; \
+ $(MAKE) -C api/tools/python/latex ; fi
+
clean:
rm -rf .word_count *.aux *.dvi *.bbl *.blg *.glo *.idx *~
rm -rf *.ilg *.log *.ind *.toc *.bak core
rm -rf $(GFX) ps pdf html
+ rm -rf api
install: all
rm -rf $(DESTDIR)$(pkgdocdir)
diff -r d4d880fcef28 -r b35215021b32 extras/mini-os/include/hypervisor.h
--- a/extras/mini-os/include/hypervisor.h Fri Sep 9 16:31:36 2005
+++ b/extras/mini-os/include/hypervisor.h Tue Sep 13 16:14:16 2005
@@ -414,15 +414,15 @@
static inline int
HYPERVISOR_xen_version(
- int cmd)
-{
- int ret;
- unsigned long ignore;
-
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret), "=b" (ignore)
- : "0" (__HYPERVISOR_xen_version), "1" (cmd)
+ int cmd, void *arg)
+{
+ int ret;
+ unsigned long ignore, ign2;
+
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret), "=b" (ignore), "=c" (ign2)
+ : "0" (__HYPERVISOR_xen_version), "1" (cmd), "2" (arg)
: "memory" );
return ret;
diff -r d4d880fcef28 -r b35215021b32
linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c Fri Sep 9 16:31:36 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c Tue Sep 13 16:14:16 2005
@@ -543,7 +543,7 @@
irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
s64 delta, delta_cpu;
- int cpu = smp_processor_id();
+ int i, cpu = smp_processor_id();
struct shadow_time_info *shadow = &per_cpu(shadow_time, cpu);
write_seqlock(&xtime_lock);
@@ -566,9 +566,9 @@
(s64)get_nsec_offset(shadow),
processed_system_time,
per_cpu(processed_system_time, cpu));
- for (cpu = 0; cpu < num_online_cpus(); cpu++)
- printk(" %d: %lld\n", cpu,
- per_cpu(processed_system_time, cpu));
+ for (i = 0; i < num_online_cpus(); i++)
+ printk(" %d: %lld\n", i,
+ per_cpu(processed_system_time, i));
}
/* System-wide jiffy work. */
diff -r d4d880fcef28 -r b35215021b32
linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c Fri Sep 9 16:31:36 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c Tue Sep 13 16:14:16 2005
@@ -37,7 +37,7 @@
#include <asm/atomic.h>
#include <asm/system.h>
#include <asm/ptrace.h>
-#include <asm-xen/synch_bitops.h>
+#include <asm/synch_bitops.h>
#include <asm-xen/xen-public/event_channel.h>
#include <asm-xen/xen-public/physdev.h>
#include <asm-xen/hypervisor.h>
@@ -123,7 +123,7 @@
*/
void force_evtchn_callback(void)
{
- (void)HYPERVISOR_xen_version(0);
+ (void)HYPERVISOR_xen_version(0, NULL);
}
EXPORT_SYMBOL(force_evtchn_callback);
diff -r d4d880fcef28 -r b35215021b32
linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c Fri Sep 9 16:31:36 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c Tue Sep 13 16:14:16 2005
@@ -19,7 +19,7 @@
#include <asm-xen/xen_proc.h>
#include <asm-xen/linux-public/privcmd.h>
#include <asm-xen/gnttab.h>
-#include <asm-xen/synch_bitops.h>
+#include <asm/synch_bitops.h>
#if 1
#define ASSERT(_p) \
diff -r d4d880fcef28 -r b35215021b32
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Fri Sep 9 16:31:36 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Tue Sep 13 16:14:16 2005
@@ -65,7 +65,6 @@
/* If other end is gone, delete ourself. */
if (node && !xenbus_exists(be->frontpath, "")) {
- xenbus_rm(be->dev->nodename, "");
device_unregister(&be->dev->dev);
return;
}
diff -r d4d880fcef28 -r b35215021b32
linux-2.6-xen-sparse/drivers/xen/console/console.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/console.c Fri Sep 9
16:31:36 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c Tue Sep 13
16:14:16 2005
@@ -182,9 +182,9 @@
#endif
static struct console kcons_info = {
- device: kcons_device,
- flags: CON_PRINTBUFFER,
- index: -1
+ .device = kcons_device,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
};
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
diff -r d4d880fcef28 -r b35215021b32
linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Fri Sep 9 16:31:36 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Tue Sep 13 16:14:16 2005
@@ -356,14 +356,14 @@
}
static struct file_operations evtchn_fops = {
- owner: THIS_MODULE,
- read: evtchn_read,
- write: evtchn_write,
- ioctl: evtchn_ioctl,
- poll: evtchn_poll,
- fasync: evtchn_fasync,
- open: evtchn_open,
- release: evtchn_release
+ .owner = THIS_MODULE,
+ .read = evtchn_read,
+ .write = evtchn_write,
+ .ioctl = evtchn_ioctl,
+ .poll = evtchn_poll,
+ .fasync = evtchn_fasync,
+ .open = evtchn_open,
+ .release = evtchn_release,
};
static struct miscdevice evtchn_miscdev = {
diff -r d4d880fcef28 -r b35215021b32
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
--- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Fri Sep 9
16:31:36 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Tue Sep 13
16:14:16 2005
@@ -241,8 +241,8 @@
}
static struct file_operations privcmd_file_ops = {
- ioctl : privcmd_ioctl,
- mmap: privcmd_mmap
+ .ioctl = privcmd_ioctl,
+ .mmap = privcmd_mmap,
};
diff -r d4d880fcef28 -r b35215021b32
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Fri Sep 9
16:31:36 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Tue Sep 13
16:14:16 2005
@@ -5,6 +5,7 @@
* to xenstore.
*
* Copyright (c) 2005, Christian Limpach
+ * Copyright (c) 2005, Rusty Russell, IBM Corporation
*
* This file may be distributed separately from the Linux kernel, or
* incorporated into other software packages, subject to the following license:
@@ -36,109 +37,104 @@
#include <linux/wait.h>
#include <linux/fs.h>
-#include "xenstored.h"
#include "xenbus_comms.h"
#include <asm/uaccess.h>
#include <asm-xen/xenbus.h>
-#include <asm-xen/linux-public/xenbus_dev.h>
#include <asm-xen/xen_proc.h>
+#include <asm-xen/linux-public/xenstored.h>
struct xenbus_dev_data {
- int in_transaction;
+ /* Are there bytes left to be read in this message? */
+ int bytes_left;
+ /* Are we still waiting for the reply to a message we wrote? */
+ int awaiting_reply;
+ /* Buffer for outgoing messages. */
+ unsigned int len;
+ union {
+ struct xsd_sockmsg msg;
+ char buffer[PAGE_SIZE];
+ } u;
};
static struct proc_dir_entry *xenbus_dev_intf;
-void *xs_talkv(enum xsd_sockmsg_type type, const struct kvec *iovec,
- unsigned int num_vecs, unsigned int *len);
+/* Reply can be long (dir, getperm): don't buffer, just examine
+ * headers so we can discard rest if they die. */
+static ssize_t xenbus_dev_read(struct file *filp,
+ char __user *ubuf,
+ size_t len, loff_t *ppos)
+{
+ struct xenbus_dev_data *data = filp->private_data;
+ struct xsd_sockmsg msg;
+ int err;
-static int xenbus_dev_talkv(struct xenbus_dev_data *u, unsigned long data)
-{
- struct xenbus_dev_talkv xt;
- unsigned int len;
- void *resp, *base;
- struct kvec *iovec;
- int ret = -EFAULT, v = 0;
+ /* Refill empty buffer? */
+ if (data->bytes_left == 0) {
+ if (len < sizeof(msg))
+ return -EINVAL;
- if (copy_from_user(&xt, (void *)data, sizeof(xt)))
- return -EFAULT;
-
- iovec = kmalloc(xt.num_vecs * sizeof(struct kvec), GFP_KERNEL);
- if (iovec == NULL)
- return -ENOMEM;
-
- if (copy_from_user(iovec, xt.iovec,
- xt.num_vecs * sizeof(struct kvec)))
- goto out;
-
- for (v = 0; v < xt.num_vecs; v++) {
- base = iovec[v].iov_base;
- iovec[v].iov_base = kmalloc(iovec[v].iov_len, GFP_KERNEL);
- if (iovec[v].iov_base == NULL ||
- copy_from_user(iovec[v].iov_base, base, iovec[v].iov_len))
- {
- if (iovec[v].iov_base)
- kfree(iovec[v].iov_base);
- else
- ret = -ENOMEM;
- v--;
- goto out;
- }
+ err = xb_read(&msg, sizeof(msg));
+ if (err)
+ return err;
+ data->bytes_left = msg.len;
+ if (ubuf && copy_to_user(ubuf, &msg, sizeof(msg)) != 0)
+ return -EFAULT;
+ /* We can receive spurious XS_WATCH_EVENT messages. */
+ if (msg.type != XS_WATCH_EVENT)
+ data->awaiting_reply = 0;
+ return sizeof(msg);
}
- resp = xs_talkv(xt.type, iovec, xt.num_vecs, &len);
- if (IS_ERR(resp)) {
- ret = PTR_ERR(resp);
- goto out;
- }
+ /* Don't read over next header, or over temporary buffer. */
+ if (len > sizeof(data->u.buffer))
+ len = sizeof(data->u.buffer);
+ if (len > data->bytes_left)
+ len = data->bytes_left;
- switch (xt.type) {
- case XS_TRANSACTION_START:
- u->in_transaction = 1;
- break;
- case XS_TRANSACTION_END:
- u->in_transaction = 0;
- break;
- default:
- break;
- }
+ err = xb_read(data->u.buffer, len);
+ if (err)
+ return err;
- ret = len;
- if (len > xt.len)
- len = xt.len;
-
- if (copy_to_user(xt.buf, resp, len))
- ret = -EFAULT;
-
- kfree(resp);
- out:
- while (v-- > 0)
- kfree(iovec[v].iov_base);
- kfree(iovec);
- return ret;
+ data->bytes_left -= len;
+ if (ubuf && copy_to_user(ubuf, data->u.buffer, len) != 0)
+ return -EFAULT;
+ return len;
}
-static int xenbus_dev_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long data)
+/* We do v. basic sanity checking so they don't screw up kernel later. */
+static ssize_t xenbus_dev_write(struct file *filp,
+ const char __user *ubuf,
+ size_t len, loff_t *ppos)
{
- struct xenbus_dev_data *u = filp->private_data;
- int ret = -ENOSYS;
+ struct xenbus_dev_data *data = filp->private_data;
+ int err;
- switch (cmd) {
- case IOCTL_XENBUS_DEV_TALKV:
- ret = xenbus_dev_talkv(u, data);
- break;
- default:
- ret = -EINVAL;
- break;
+ /* We gather data in buffer until we're ready to send it. */
+ if (len > data->len + sizeof(data->u))
+ return -EINVAL;
+ if (copy_from_user(data->u.buffer + data->len, ubuf, len) != 0)
+ return -EFAULT;
+ data->len += len;
+ if (data->len >= sizeof(data->u.msg) + data->u.msg.len) {
+ err = xb_write(data->u.buffer, data->len);
+ if (err)
+ return err;
+ data->len = 0;
+ data->awaiting_reply = 1;
}
- return ret;
+ return len;
}
static int xenbus_dev_open(struct inode *inode, struct file *filp)
{
struct xenbus_dev_data *u;
+
+ if (xen_start_info->store_evtchn == 0)
+ return -ENOENT;
+
+ /* Don't try seeking. */
+ nonseekable_open(inode, filp);
u = kmalloc(sizeof(*u), GFP_KERNEL);
if (u == NULL)
@@ -155,22 +151,27 @@
static int xenbus_dev_release(struct inode *inode, struct file *filp)
{
- struct xenbus_dev_data *u = filp->private_data;
+ struct xenbus_dev_data *data = filp->private_data;
- if (u->in_transaction)
- xenbus_transaction_end(1);
+ /* Discard any unread replies. */
+ while (data->bytes_left || data->awaiting_reply)
+ xenbus_dev_read(filp, NULL, sizeof(data->u.buffer), NULL);
+
+ /* Harmless if no transaction in progress. */
+ xenbus_transaction_end(1);
up(&xenbus_lock);
- kfree(u);
+ kfree(data);
return 0;
}
static struct file_operations xenbus_dev_file_ops = {
- ioctl: xenbus_dev_ioctl,
- open: xenbus_dev_open,
- release: xenbus_dev_release
+ .read = xenbus_dev_read,
+ .write = xenbus_dev_write,
+ .open = xenbus_dev_open,
+ .release = xenbus_dev_release,
};
static int __init
diff -r d4d880fcef28 -r b35215021b32
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Fri Sep 9
16:31:36 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Tue Sep 13
16:14:16 2005
@@ -166,6 +166,10 @@
buffer, buffer_size, &length,
"XENBUS_TYPE=%s", xdev->devicetype);
+ add_hotplug_env_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "XENBUS_PATH=%s", xdev->nodename);
+
/* terminate, set to next free slot, shrink available space */
envp[i] = NULL;
envp = &envp[i];
diff -r d4d880fcef28 -r b35215021b32
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Fri Sep 9
16:31:36 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Tue Sep 13
16:14:16 2005
@@ -38,7 +38,7 @@
#include <linux/fcntl.h>
#include <linux/kthread.h>
#include <asm-xen/xenbus.h>
-#include "xenstored.h"
+#include <asm-xen/linux-public/xenstored.h>
#include "xenbus_comms.h"
#define streq(a, b) (strcmp((a), (b)) == 0)
@@ -106,10 +106,10 @@
}
/* Send message to xs, get kmalloc'ed reply. ERR_PTR() on error. */
-void *xs_talkv(enum xsd_sockmsg_type type,
- const struct kvec *iovec,
- unsigned int num_vecs,
- unsigned int *len)
+static void *xs_talkv(enum xsd_sockmsg_type type,
+ const struct kvec *iovec,
+ unsigned int num_vecs,
+ unsigned int *len)
{
struct xsd_sockmsg msg;
void *ret = NULL;
diff -r d4d880fcef28 -r b35215021b32
linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h Fri Sep 9
16:31:36 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h Tue Sep 13
16:14:16 2005
@@ -270,9 +270,9 @@
static inline int
HYPERVISOR_xen_version(
- int cmd)
-{
- return _hypercall1(int, xen_version, cmd);
+ int cmd, void *arg)
+{
+ return _hypercall2(int, xen_version, cmd, arg);
}
static inline int
diff -r d4d880fcef28 -r b35215021b32
linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h Fri Sep 9
16:31:36 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h Tue Sep 13
16:14:16 2005
@@ -4,7 +4,7 @@
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/bitops.h>
-#include <asm-xen/synch_bitops.h>
+#include <asm/synch_bitops.h>
#include <asm/segment.h>
#include <asm/cpufeature.h>
#include <asm-xen/hypervisor.h>
diff -r d4d880fcef28 -r b35215021b32
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h Fri Sep
9 16:31:36 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h Tue Sep
13 16:14:16 2005
@@ -260,9 +260,9 @@
static inline int
HYPERVISOR_xen_version(
- int cmd)
-{
- return _hypercall1(int, xen_version, cmd);
+ int cmd, void *arg)
+{
+ return _hypercall2(int, xen_version, cmd, arg);
}
static inline int
diff -r d4d880fcef28 -r b35215021b32
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h Fri Sep 9
16:31:36 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h Tue Sep 13
16:14:16 2005
@@ -4,7 +4,7 @@
#include <linux/config.h>
#include <linux/kernel.h>
#include <asm/segment.h>
-#include <asm-xen/synch_bitops.h>
+#include <asm/synch_bitops.h>
#include <asm-xen/hypervisor.h>
#include <asm-xen/xen-public/arch-x86_64.h>
diff -r d4d880fcef28 -r b35215021b32
linux-2.6-xen-sparse/include/asm-xen/evtchn.h
--- a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h Fri Sep 9 16:31:36 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h Tue Sep 13 16:14:16 2005
@@ -35,7 +35,7 @@
#include <linux/interrupt.h>
#include <asm-xen/hypervisor.h>
#include <asm/ptrace.h>
-#include <asm-xen/synch_bitops.h>
+#include <asm/synch_bitops.h>
#include <asm-xen/xen-public/event_channel.h>
#include <linux/smp.h>
diff -r d4d880fcef28 -r b35215021b32 linux-2.6-xen-sparse/mkbuildtree
--- a/linux-2.6-xen-sparse/mkbuildtree Fri Sep 9 16:31:36 2005
+++ b/linux-2.6-xen-sparse/mkbuildtree Tue Sep 13 16:14:16 2005
@@ -108,5 +108,5 @@
cd ${AD}/include/asm-xen/xen-public
relative_lndir ../../../${RS}/../xen/include/public
-cd ${AD}/drivers/xen/xenbus
+cd ${AD}/include/asm-xen/linux-public
ln -sf ../../../${RS}/../tools/xenstore/xenstored.h
diff -r d4d880fcef28 -r b35215021b32 tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Fri Sep 9 16:31:36 2005
+++ b/tools/console/daemon/io.c Tue Sep 13 16:14:16 2005
@@ -87,6 +87,7 @@
struct buffer *buffer = &dom->buffer;
struct ring_head *ring = (struct ring_head *)dom->page;
size_t size;
+ u32 oldcons;
while ((size = ring->prod - ring->cons) != 0) {
if ((buffer->capacity - buffer->size) < size) {
@@ -98,7 +99,8 @@
}
}
- while (ring->cons < ring->prod) {
+ oldcons = ring->cons;
+ while (ring->cons < (oldcons + size)) {
buffer->data[buffer->size] =
ring->buf[XENCONS_IDX(ring->cons)];
buffer->size++;
diff -r d4d880fcef28 -r b35215021b32 tools/console/daemon/main.c
--- a/tools/console/daemon/main.c Fri Sep 9 16:31:36 2005
+++ b/tools/console/daemon/main.c Tue Sep 13 16:14:16 2005
@@ -30,6 +30,12 @@
#include "utils.h"
#include "io.h"
+void usage(char *prg)
+{
+ fprintf(stderr,
+ "usage: %s [-h] [-V] [-v] [-i]\n", prg);
+}
+
int main(int argc, char **argv)
{
const char *sopts = "hVvi";
@@ -49,7 +55,7 @@
while ((ch = getopt_long(argc, argv, sopts, lopts, &opt_ind)) != -1) {
switch (ch) {
case 'h':
- //usage(argv[0]);
+ usage(argv[0]);
exit(0);
case 'V':
//version(argv[0]);
diff -r d4d880fcef28 -r b35215021b32 tools/console/daemon/utils.c
--- a/tools/console/daemon/utils.c Fri Sep 9 16:31:36 2005
+++ b/tools/console/daemon/utils.c Tue Sep 13 16:14:16 2005
@@ -105,7 +105,8 @@
close(fd);
umask(027);
- chdir("/");
+ if (chdir("/") < 0)
+ exit (1);
fd = open(pidfile, O_RDWR | O_CREAT);
if (fd == -1) {
@@ -117,7 +118,8 @@
}
len = sprintf(buf, "%d\n", getpid());
- write(fd, buf, len);
+ if (write(fd, buf, len) < 0)
+ exit(1);
signal(SIGCHLD, child_exit);
signal(SIGTSTP, SIG_IGN);
diff -r d4d880fcef28 -r b35215021b32 tools/examples/Makefile
--- a/tools/examples/Makefile Fri Sep 9 16:31:36 2005
+++ b/tools/examples/Makefile Tue Sep 13 16:14:16 2005
@@ -21,10 +21,11 @@
XEN_SCRIPT_DIR = /etc/xen/scripts
XEN_SCRIPTS = network-bridge vif-bridge
XEN_SCRIPTS += network-route vif-route
+XEN_SCRIPTS += block-phy
XEN_SCRIPTS += block-file
XEN_SCRIPTS += block-enbd
-XEN_BOOT_DIR = /usr/lib/xen/boot
+XEN_BOOT_DIR = /usr/$(LIBDIR)/xen/boot
XEN_BOOT = mem-map.sxp
XEN_HOTPLUG_DIR = /etc/hotplug
@@ -36,12 +37,15 @@
install: all install-initd install-configs install-scripts install-boot \
install-hotplug
+xmexample.vmx: xmexample.vmx.in
+ sed -e 's/@@LIBDIR@@/$(LIBDIR)/' < $< > $@
+
install-initd:
[ -d $(DESTDIR)/etc/init.d ] || $(INSTALL_DIR) $(DESTDIR)/etc/init.d
$(INSTALL_PROG) $(XEND_INITD) $(DESTDIR)/etc/init.d
$(INSTALL_PROG) $(XENDOMAINS_INITD) $(DESTDIR)/etc/init.d
-install-configs:
+install-configs: $(XEN_CONFIGS)
[ -d $(DESTDIR)$(XEN_CONFIG_DIR) ] || \
$(INSTALL_DIR) $(DESTDIR)$(XEN_CONFIG_DIR)
[ -d $(DESTDIR)$(XEN_CONFIG_DIR)/auto ] || \
@@ -76,3 +80,4 @@
done
clean:
+ $(RM) xmexample.vmx
diff -r d4d880fcef28 -r b35215021b32 tools/examples/block-enbd
--- a/tools/examples/block-enbd Fri Sep 9 16:31:36 2005
+++ b/tools/examples/block-enbd Tue Sep 13 16:14:16 2005
@@ -3,31 +3,31 @@
# Usage: block-enbd [bind server ctl_port |unbind node]
#
# The file argument to the bind command is the file we are to bind to a
-# loop device. We print the path to the loop device node to stdout.
+# loop device.
#
# The node argument to unbind is the name of the device node we are to
# unbind.
#
# This assumes you're running a correctly configured server at the other end!
+set -e
+
case $1 in
- bind)
- for dev in /dev/nd*; do
- if nbd-client $2:$3 $dev; then
- echo $dev
- exit 0
- fi
- done
- exit 1
- ;;
-
- unbind)
- nbd-client -d $2
- exit 0
- ;;
-
- *)
- echo 'Unknown command: ' $1 >&2
- echo 'Valid commands are: bind, unbind' >&2
- exit 1
+ bind)
+ for dev in /dev/nd*; do
+ if nbd-client $2:$3 $dev; then
+ major=$(stat -L -c %t "$dev")
+ minor=$(stat -L -c %T "$dev")
+ pdev=$(printf "0x%02x%02x" 0x$major 0x$minor)
+ xenstore-write "$XENBUS_PATH"/physical-device $pdev \
+ "$XENBUS_PATH"/node $dev
+ exit 0
+ fi
+ done
+ exit 1
+ ;;
+ unbind)
+ nbd-client -d $2
+ exit 0
+ ;;
esac
diff -r d4d880fcef28 -r b35215021b32 tools/examples/block-file
--- a/tools/examples/block-file Fri Sep 9 16:31:36 2005
+++ b/tools/examples/block-file Tue Sep 13 16:14:16 2005
@@ -3,29 +3,29 @@
# Usage: block_loop [bind file|unbind node]
#
# The file argument to the bind command is the file we are to bind to a
-# loop device. We print the path to the loop device node to stdout.
+# loop device.
#
# The node argument to unbind is the name of the device node we are to
# unbind.
+set -e
+
case $1 in
- bind)
- for dev in /dev/loop*; do
- if losetup $dev $2; then
- echo $dev
- exit 0
- fi
- done
- exit 1
- ;;
-
- unbind)
- losetup -d $2
- exit 0
- ;;
-
- *)
- echo 'Unknown command: ' $1 >&2
- echo 'Valid commands are: bind, unbind' >&2
- exit 1
+ bind)
+ for dev in /dev/loop*; do
+ if losetup $dev $2; then
+ major=$(stat -L -c %t "$dev")
+ minor=$(stat -L -c %T "$dev")
+ pdev=$(printf "0x%02x%02x" 0x$major 0x$minor)
+ xenstore-write "$XENBUS_PATH"/physical-device $pdev \
+ "$XENBUS_PATH"/node $dev
+ exit 0
+ fi
+ done
+ exit 1
+ ;;
+ unbind)
+ losetup -d $2
+ exit 0
+ ;;
esac
diff -r d4d880fcef28 -r b35215021b32 tools/examples/xen-backend.agent
--- a/tools/examples/xen-backend.agent Fri Sep 9 16:31:36 2005
+++ b/tools/examples/xen-backend.agent Tue Sep 13 16:14:16 2005
@@ -9,8 +9,26 @@
case "$ACTION" in
add)
+ case "$XENBUS_TYPE" in
+ vbd)
+ t=$(xenstore-read "$XENBUS_PATH"/type)
+ params=$(xenstore-read "$XENBUS_PATH"/params)
+ [ -x /etc/xen/scripts/block-"$t" ] && \
+ /etc/xen/scripts/block-"$t" bind $params
+ ;;
+ esac
;;
remove)
+ case "$XENBUS_TYPE" in
+ vbd)
+ t=$(xenstore-read "$XENBUS_PATH"/type)
+ node=$(xenstore-read "$XENBUS_PATH"/node)
+ [ -x /etc/xen/scripts/block-"$t" ] && \
+ /etc/xen/scripts/block-"$t" unbind $node
+ ;;
+ esac
+ # remove device backend store entries
+ xenstore-rm "$XENBUS_PATH"
;;
online)
case "$PHYSDEVDRIVER" in
diff -r d4d880fcef28 -r b35215021b32 tools/ioemu/hw/pcnet.c
--- a/tools/ioemu/hw/pcnet.c Fri Sep 9 16:31:36 2005
+++ b/tools/ioemu/hw/pcnet.c Tue Sep 13 16:14:16 2005
@@ -380,10 +380,13 @@
return sizeof(s->buffer)-16;
}
+#define MIN_BUF_SIZE 60
+
static void pcnet_receive(void *opaque, const uint8_t *buf, int size)
{
PCNetState *s = opaque;
int is_padr = 0, is_bcast = 0, is_ladr = 0;
+ uint8_t buf1[60];
if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
return;
@@ -391,6 +394,14 @@
#ifdef PCNET_DEBUG
printf("pcnet_receive size=%d\n", size);
#endif
+
+ /* if too small buffer, then expand it */
+ if (size < MIN_BUF_SIZE) {
+ memcpy(buf1, buf, size);
+ memset(buf1 + size, 0, MIN_BUF_SIZE - size);
+ buf = buf1;
+ size = MIN_BUF_SIZE;
+ }
if (CSR_PROM(s)
|| (is_padr=padr_match(s, buf, size))
diff -r d4d880fcef28 -r b35215021b32 tools/ioemu/target-i386-dm/Makefile
--- a/tools/ioemu/target-i386-dm/Makefile Fri Sep 9 16:31:36 2005
+++ b/tools/ioemu/target-i386-dm/Makefile Tue Sep 13 16:14:16 2005
@@ -3,7 +3,7 @@
include config.mak
override TARGET_ARCH=i386
-INSTALL_DIR := $(DESTDIR)/usr/lib/xen/bin
+INSTALL_DIR := $(DESTDIR)/usr/$(LIBDIR)/xen/bin
TARGET_PATH=$(SRC_PATH)/target-$(TARGET_ARCH)
VPATH=$(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw:$(SRC_PATH)/audio
DEFINES=-I. -I$(TARGET_PATH) -I$(SRC_PATH) -I$(XEN_ROOT)/xen/include/public
diff -r d4d880fcef28 -r b35215021b32 tools/libxc/xc_linux_restore.c
--- a/tools/libxc/xc_linux_restore.c Fri Sep 9 16:31:36 2005
+++ b/tools/libxc/xc_linux_restore.c Tue Sep 13 16:14:16 2005
@@ -42,18 +42,18 @@
unsigned char *b = buf;
while (r < count) {
- s = read(fd, &b[r], count - r);
- if (s <= 0)
- break;
- r += s;
+ s = read(fd, &b[r], count - r);
+ if (s <= 0)
+ break;
+ r += s;
}
return r;
}
int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns,
- unsigned int store_evtchn, unsigned long *store_mfn,
- unsigned int console_evtchn, unsigned long *console_mfn)
+ unsigned int store_evtchn, unsigned long *store_mfn,
+ unsigned int console_evtchn, unsigned long *console_mfn)
{
dom0_op_t op;
int rc = 1, i, n, k;
@@ -91,6 +91,8 @@
/* A temporary mapping of the guest's start_info page. */
start_info_t *start_info;
+ int pt_levels = 2; /* XXX auto-detect this */
+
char *region_base;
xc_mmu_t *mmu = NULL;
@@ -112,8 +114,8 @@
}
if (read_exact(io_fd, pfn_to_mfn_frame_list, PAGE_SIZE) != PAGE_SIZE) {
- ERR("read pfn_to_mfn_frame_list failed");
- goto out;
+ ERR("read pfn_to_mfn_frame_list failed");
+ goto out;
}
/* We want zeroed memory so use calloc rather than malloc. */
@@ -289,10 +291,10 @@
if ( xpfn >= nr_pfns )
{
ERR("Frame number in type %lu page "
- "table is out of range. i=%d k=%d "
- "pfn=0x%lx nr_pfns=%lu",
- region_pfn_type[i]>>28, i,
- k, xpfn, nr_pfns);
+ "table is out of range. i=%d k=%d "
+ "pfn=0x%lx nr_pfns=%lu",
+ region_pfn_type[i]>>28, i,
+ k, xpfn, nr_pfns);
goto out;
}
@@ -317,10 +319,10 @@
if ( xpfn >= nr_pfns )
{
ERR("Frame number in type %lu page"
- " table is out of range. i=%d k=%d "
- "pfn=%lu nr_pfns=%lu",
- region_pfn_type[i]>>28, i, k,
- xpfn, nr_pfns);
+ " table is out of range. i=%d k=%d "
+ "pfn=%lu nr_pfns=%lu",
+ region_pfn_type[i]>>28, i, k,
+ xpfn, nr_pfns);
goto out;
}
@@ -334,8 +336,8 @@
default:
ERR("Bogus page type %lx page table is "
- "out of range. i=%d nr_pfns=%lu",
- region_pfn_type[i], i, nr_pfns);
+ "out of range. i=%d nr_pfns=%lu",
+ region_pfn_type[i], i, nr_pfns);
goto out;
} /* end of page type switch statement */
@@ -362,8 +364,8 @@
}
if ( xc_add_mmu_update(xc_handle, mmu,
- (mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE,
- pfn) )
+ (mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE,
+ pfn) )
{
printf("machpys mfn=%ld pfn=%ld\n",mfn,pfn);
goto out;
@@ -376,6 +378,33 @@
}
DPRINTF("Received all pages\n");
+
+ if ( pt_levels == 3 )
+ {
+ /* Get all PGDs below 4GB. */
+ for ( i = 0; i < nr_pfns; i++ )
+ {
+ if ( ((pfn_type[i] & LTABTYPE_MASK) == L3TAB) &&
+ (pfn_to_mfn_table[i] > 0xfffffUL) )
+ {
+ unsigned long new_mfn = xc_make_page_below_4G(
+ xc_handle, dom, pfn_to_mfn_table[i]);
+ if ( new_mfn == 0 )
+ {
+ fprintf(stderr, "Couldn't get a page below 4GB :-(\n");
+ goto out;
+ }
+ pfn_to_mfn_table[i] = new_mfn;
+ if ( xc_add_mmu_update(
+ xc_handle, mmu, (new_mfn << PAGE_SHIFT) |
+ MMU_MACHPHYS_UPDATE, i) )
+ {
+ fprintf(stderr, "Couldn't m2p on PAE root pgdir\n");
+ goto out;
+ }
+ }
+ }
+ }
if ( xc_finish_mmu_updates(xc_handle, mmu) )
goto out;
@@ -410,57 +439,57 @@
/* Get the list of PFNs that are not in the psuedo-phys map */
{
- unsigned int count;
+ unsigned int count;
unsigned long *pfntab;
- int rc;
-
- if ( read_exact(io_fd, &count, sizeof(count)) != sizeof(count) )
- {
- ERR("Error when reading pfn count");
- goto out;
- }
-
- pfntab = malloc( sizeof(unsigned int) * count );
- if ( pfntab == NULL )
- {
- ERR("Out of memory");
- goto out;
- }
-
- if ( read_exact(io_fd, pfntab, sizeof(unsigned int)*count) !=
+ int rc;
+
+ if ( read_exact(io_fd, &count, sizeof(count)) != sizeof(count) )
+ {
+ ERR("Error when reading pfn count");
+ goto out;
+ }
+
+ pfntab = malloc( sizeof(unsigned int) * count );
+ if ( pfntab == NULL )
+ {
+ ERR("Out of memory");
+ goto out;
+ }
+
+ if ( read_exact(io_fd, pfntab, sizeof(unsigned int)*count) !=
sizeof(unsigned int)*count )
- {
- ERR("Error when reading pfntab");
- goto out;
- }
-
- for ( i = 0; i < count; i++ )
- {
- unsigned long pfn = pfntab[i];
- pfntab[i]=pfn_to_mfn_table[pfn];
- pfn_to_mfn_table[pfn] = 0x80000001; // not in pmap
- }
-
- if ( count > 0 )
- {
+ {
+ ERR("Error when reading pfntab");
+ goto out;
+ }
+
+ for ( i = 0; i < count; i++ )
+ {
+ unsigned long pfn = pfntab[i];
+ pfntab[i]=pfn_to_mfn_table[pfn];
+ pfn_to_mfn_table[pfn] = 0x80000001; // not in pmap
+ }
+
+ if ( count > 0 )
+ {
struct xen_memory_reservation reservation = {
.extent_start = pfntab,
.nr_extents = count,
.extent_order = 0,
.domid = dom
};
- if ( (rc = xc_memory_op(xc_handle,
+ if ( (rc = xc_memory_op(xc_handle,
XENMEM_decrease_reservation,
&reservation)) != count )
- {
- ERR("Could not decrease reservation : %d",rc);
- goto out;
- }
- else
- {
- printf("Decreased reservation by %d pages\n", count);
- }
- }
+ {
+ ERR("Could not decrease reservation : %d",rc);
+ goto out;
+ }
+ else
+ {
+ printf("Decreased reservation by %d pages\n", count);
+ }
+ }
}
if ( read_exact(io_fd, &ctxt, sizeof(ctxt)) != sizeof(ctxt) ||
@@ -484,10 +513,10 @@
start_info->shared_info = shared_info_frame << PAGE_SHIFT;
start_info->flags = 0;
*store_mfn = start_info->store_mfn =
- pfn_to_mfn_table[start_info->store_mfn];
+ pfn_to_mfn_table[start_info->store_mfn];
start_info->store_evtchn = store_evtchn;
*console_mfn = start_info->console_mfn =
- pfn_to_mfn_table[start_info->console_mfn];
+ pfn_to_mfn_table[start_info->console_mfn];
start_info->console_evtchn = console_evtchn;
munmap(start_info, PAGE_SIZE);
@@ -522,7 +551,7 @@
/* clear any pending events and the selector */
memset(&(shared_info->evtchn_pending[0]), 0,
- sizeof (shared_info->evtchn_pending));
+ sizeof (shared_info->evtchn_pending));
for ( i = 0; i < MAX_VIRT_CPUS; i++ )
shared_info->vcpu_data[i].evtchn_pending_sel = 0;
@@ -548,7 +577,7 @@
}
if ( (live_pfn_to_mfn_table =
- xc_map_foreign_batch(xc_handle, dom,
+ xc_map_foreign_batch(xc_handle, dom,
PROT_WRITE,
pfn_to_mfn_frame_list,
(nr_pfns+1023)/1024 )) == 0 )
diff -r d4d880fcef28 -r b35215021b32 tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c Fri Sep 9 16:31:36 2005
+++ b/tools/libxc/xc_private.c Tue Sep 13 16:14:16 2005
@@ -425,23 +425,49 @@
int xc_version(int xc_handle, int cmd, void *arg)
{
- return do_xen_version(xc_handle, cmd, arg);
-}
-
-unsigned long xc_make_page_below_4G(int xc_handle, u32 domid,
- unsigned long mfn)
+ int rc, argsize = 0;
+
+ switch ( cmd )
+ {
+ case XENVER_extraversion: argsize = sizeof(xen_extraversion_t); break;
+ case XENVER_compile_info: argsize = sizeof(xen_compile_info_t); break;
+ case XENVER_capabilities: argsize = sizeof(xen_capabilities_info_t); break;
+ case XENVER_changeset: argsize = sizeof(xen_changeset_info_t); break;
+ case XENVER_parameters: argsize = sizeof(xen_parameters_info_t); break;
+ }
+
+ if ( (argsize != 0) && (mlock(arg, argsize) != 0) )
+ {
+ PERROR("Could not lock memory for version hypercall");
+ return -ENOMEM;
+ }
+
+ rc = do_xen_version(xc_handle, cmd, arg);
+
+ if ( argsize != 0 )
+ safe_munlock(arg, argsize);
+
+ return rc;
+}
+
+unsigned long xc_make_page_below_4G(
+ int xc_handle, u32 domid, unsigned long mfn)
{
unsigned long new_mfn;
+
if ( xc_domain_memory_decrease_reservation(
- xc_handle, domid, 1, 0, &mfn ) != 1 )
+ xc_handle, domid, 1, 0, &mfn) != 1 )
{
fprintf(stderr,"xc_make_page_below_4G decrease failed. mfn=%lx\n",mfn);
return 0;
}
- if ( xc_domain_memory_increase_reservation( xc_handle, domid, 1, 0, 32,
&new_mfn ) != 1 )
+
+ if ( xc_domain_memory_increase_reservation(
+ xc_handle, domid, 1, 0, 32, &new_mfn) != 1 )
{
fprintf(stderr,"xc_make_page_below_4G increase failed. mfn=%lx\n",mfn);
return 0;
}
+
return new_mfn;
}
diff -r d4d880fcef28 -r b35215021b32 tools/libxc/xc_vmx_build.c
--- a/tools/libxc/xc_vmx_build.c Fri Sep 9 16:31:36 2005
+++ b/tools/libxc/xc_vmx_build.c Tue Sep 13 16:14:16 2005
@@ -578,15 +578,6 @@
sp->sp_global.eport = control_evtchn;
munmap(sp, PAGE_SIZE);
- /*
- * Pin down l2tab addr as page dir page - causes hypervisor to provide
- * correct protection for the page
- */
-#ifdef __i386__
- if ( pin_table(xc_handle, MMUEXT_PIN_L2_TABLE, l2tab>>PAGE_SHIFT, dom) )
- goto error_out;
-#endif
-
/* Send the page update requests down to the hypervisor. */
if ( xc_finish_mmu_updates(xc_handle, mmu) )
goto error_out;
diff -r d4d880fcef28 -r b35215021b32 tools/python/Makefile
--- a/tools/python/Makefile Fri Sep 9 16:31:36 2005
+++ b/tools/python/Makefile Tue Sep 13 16:14:16 2005
@@ -1,6 +1,7 @@
-
XEN_ROOT = ../..
include $(XEN_ROOT)/tools/Rules.mk
+
+.PHONY: all build install clean
all: build
build:
diff -r d4d880fcef28 -r b35215021b32 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Fri Sep 9 16:31:36 2005
+++ b/tools/python/xen/lowlevel/xc/xc.c Tue Sep 13 16:14:16 2005
@@ -756,7 +756,7 @@
"xen_major", xen_version >> 16,
"xen_minor", (xen_version & 0xffff),
"xen_extra", xen_extra,
- "xen_caps", xen_caps.caps,
+ "xen_caps", xen_caps,
"xen_params", str,
"xen_changeset", xen_chgset,
"cc_compiler", xen_cc.compiler,
diff -r d4d880fcef28 -r b35215021b32 tools/python/xen/sv/DomInfo.py
--- a/tools/python/xen/sv/DomInfo.py Fri Sep 9 16:31:36 2005
+++ b/tools/python/xen/sv/DomInfo.py Tue Sep 13 16:14:16 2005
@@ -75,7 +75,7 @@
class DomGenTab( GeneralTab ):
- def __init__( self, urlWriter ):
+ def __init__( self, _ ):
titles = {}
@@ -103,7 +103,7 @@
class DomSXPTab( PreTab ):
- def __init__( self, urlWriter ):
+ def __init__( self, _ ):
self.dom = 0
PreTab.__init__( self, "" )
@@ -126,7 +126,7 @@
class DomActionTab( ActionTab ):
- def __init__( self, urlWriter ):
+ def __init__( self, _ ):
actions = { "shutdown" : "Shutdown",
"reboot" : "Reboot",
"pause" : "Pause",
@@ -188,19 +188,19 @@
title = "Device List"
- def __init__( self, urlWriter ):
+ def __init__( self, _ ):
pass
class DomDeviceOptionsTab( NullTab ):
title = "Device Options"
- def __init__( self, urlWriter ):
+ def __init__( self, _ ):
pass
class DomDeviceActionTab( ActionTab ):
- def __init__( self, urlWriter ):
+ def __init__( self, _ ):
ActionTab.__init__( self, { "addvcpu" : "Add VCPU", "addvbd" : "Add
VBD", "addvif" : "Add VIF" } )
class DomMigrateTab( CompositeTab ):
@@ -218,7 +218,7 @@
class DomMigrateActionTab( ActionTab ):
- def __init__( self, urlWriter ):
+ def __init__( self, _ ):
actions = { "migrate" : "Migrate" }
ActionTab.__init__( self, actions )
@@ -249,7 +249,7 @@
class DomSaveActionTab( ActionTab ):
- def __init__( self, urlWriter ):
+ def __init__( self, _ ):
actions = { "save" : "Save" }
ActionTab.__init__( self, actions )
diff -r d4d880fcef28 -r b35215021b32 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Fri Sep 9 16:31:36 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py Tue Sep 13 16:14:16 2005
@@ -47,6 +47,7 @@
from xen.xend.uuid import getUuid
from xen.xend.xenstore import DBVar, XenNode, DBMap
+from xen.xend.xenstore.xstransact import xstransact
"""Shutdown code for poweroff."""
DOMAIN_POWEROFF = 0
@@ -101,34 +102,6 @@
"""
return shutdown_reasons.get(code, "?")
-config_handlers = {}
-
-def add_config_handler(name, h):
- """Add a handler for a config field.
-
- @param name: field name
- @param h: handler: fn(vm, config, field, index)
- """
- config_handlers[name] = h
-
-def get_config_handler(name):
- """Get a handler for a config field.
-
- returns handler or None
- """
- return config_handlers.get(name)
-
-"""Table of handlers for devices.
-Indexed by device type.
-"""
-device_handlers = {}
-
-def add_device_handler(name, type):
- device_handlers[name] = type
-
-def get_device_handler(name):
- return device_handlers[name]
-
def dom_get(dom):
"""Get info from xen for an existing domain.
@@ -156,7 +129,8 @@
"""
uuid = getUuid()
db = parentdb.addChild(uuid)
- vm = cls(db)
+ path = parentdb.getPath()
+ vm = cls(uuid, path, db)
vm.construct(config)
vm.saveToDB(sync=True)
@@ -171,7 +145,8 @@
@param info: domain info from xc
"""
dom = info['dom']
- vm = cls(db)
+ path = "/".join(db.getPath().split("/")[0:-1])
+ vm = cls(db.getName(), path, db)
vm.setdom(dom)
db.readDB()
vm.importFromDB()
@@ -206,7 +181,8 @@
if not uuid:
uuid = getUuid()
db = parentdb.addChild(uuid)
- vm = cls(db)
+ path = parentdb.getPath()
+ vm = cls(uuid, path, db)
ssidref = int(sxp.child_value(config, 'ssidref'))
log.debug('restoring with ssidref='+str(ssidref))
id = xc.domain_create(ssidref = ssidref)
@@ -239,9 +215,10 @@
DBVar('device_model_pid', ty='int'),
]
- def __init__(self, db):
+ def __init__(self, uuid, path, db):
+ self.uuid = uuid
+ self.path = path + "/" + uuid
self.db = db
- self.uuid = db.getName()
self.recreate = 0
self.restore = 0
@@ -364,12 +341,6 @@
__repr__ = __str__
- def getDeviceTypes(self):
- return self.controllers.keys()
-
- def getDeviceControllers(self):
- return self.controllers.values()
-
def getDeviceController(self, type, error=True):
ctrl = self.controllers.get(type)
if not ctrl and error:
@@ -392,35 +363,28 @@
typedev = sxp.child_value(devconfig, 'dev')
if re.match('^ioemu:', typedev):
return;
+
backdom = domain_exists(sxp.child_value(devconfig, 'backend', '0'))
devnum = blkdev_name_to_number(sxp.child_value(devconfig, 'dev'))
- # create backend db
- backdb = backdom.db.addChild("/backend/%s/%s/%d" %
- (type, self.uuid, devnum))
-
- # create frontend db
- db = self.db.addChild("/device/%s/%d" % (type, devnum))
-
- db['virtual-device'] = "%i" % devnum
- #db['backend'] = sxp.child_value(devconfig, 'backend', '0')
- db['backend'] = backdb.getPath()
- db['backend-id'] = "%i" % backdom.id
-
- backdb['frontend'] = db.getPath()
- (type, params) = string.split(sxp.child_value(devconfig, 'uname'),
':', 1)
- node = Blkctl.block('bind', type, params)
- backdb['frontend-id'] = "%i" % self.id
- backdb['physical-device'] = "%li" % blkdev_name_to_number(node)
- backdb.saveDB(save=True)
-
- # Ok, super gross, this really doesn't belong in the frontend db...
- db['type'] = type
- db['node'] = node
- db['params'] = params
- db.saveDB(save=True)
-
+ backpath = "%s/backend/%s/%s/%d" % (backdom.path, type,
+ self.uuid, devnum)
+ frontpath = "%s/device/%s/%d" % (self.path, type, devnum)
+
+ front = { 'backend' : backpath,
+ 'backend-id' : "%i" % backdom.id,
+ 'virtual-device' : "%i" % devnum }
+ xstransact.Write(frontpath, front)
+
+ (type, params) = string.split(sxp.child_value(devconfig,
+ 'uname'), ':', 1)
+ back = { 'type' : type,
+ 'params' : params,
+ 'frontend' : frontpath,
+ 'frontend-id' : "%i" % self.id }
+ xstransact.Write(backpath, back)
+
return
if type == 'vif':
@@ -435,8 +399,6 @@
backdom = domain_exists(sxp.child_value(devconfig, 'backend', '0'))
- log.error(devconfig)
-
devnum = self.netif_idx
self.netif_idx += 1
@@ -448,30 +410,26 @@
mac = sxp.child_value(devconfig, 'mac')
ipaddr = _get_config_ipaddr(devconfig)
- # create backend db
- backdb = backdom.db.addChild("/backend/%s/%s/%d" %
- (type, self.uuid, devnum))
-
- # create frontend db
- db = self.db.addChild("/device/%s/%d" % (type, devnum))
-
- backdb['script'] = script
- backdb['domain'] = self.name
- backdb['mac'] = mac
- backdb['bridge'] = bridge
+ backpath = "%s/backend/%s/%s/%d" % (backdom.path, type,
+ self.uuid, devnum)
+ frontpath = "%s/device/%s/%d" % (self.path, type, devnum)
+
+ front = { 'backend' : backpath,
+ 'backend-id' : "%i" % backdom.id,
+ 'handle' : "%i" % devnum,
+ 'mac' : mac }
+ xstransact.Write(frontpath, front)
+
+ back = { 'script' : script,
+ 'domain' : self.name,
+ 'mac' : mac,
+ 'bridge' : bridge,
+ 'frontend' : frontpath,
+ 'frontend-id' : "%i" % self.id,
+ 'handle' : "%i" % devnum }
if ipaddr:
- backdb['ip'] = ' '.join(ipaddr)
- backdb['frontend'] = db.getPath()
- backdb['frontend-id'] = "%i" % self.id
- backdb['handle'] = "%i" % devnum
- backdb.saveDB(save=True)
-
- db['backend'] = backdb.getPath()
- db['backend-id'] = "%i" % backdom.id
- db['handle'] = "%i" % devnum
- db['mac'] = mac
-
- db.saveDB(save=True)
+ back['ip'] = ' '.join(ipaddr)
+ xstransact.Write(backpath, back)
return
@@ -481,22 +439,19 @@
devnum = int(sxp.child_value(devconfig, 'instance', '0'))
log.error("The domain has a TPM with instance %d." % devnum)
- # create backend db
- backdb = backdom.db.addChild("/backend/%s/%s/%d" %
- (type, self.uuid, devnum))
- # create frontend db
- db = self.db.addChild("/device/%s/%d" % (type, devnum))
-
- backdb['frontend'] = db.getPath()
- backdb['frontend-id'] = "%i" % self.id
- backdb['instance'] = sxp.child_value(devconfig, 'instance', '0')
- backdb.saveDB(save=True)
-
- db['handle'] = "%i" % devnum
- db['backend'] = backdb.getPath()
- db['backend-id'] = "%i" % int(sxp.child_value(devconfig,
- 'backend', '0'))
- db.saveDB(save=True)
+ backpath = "%s/backend/%s/%s/%d" % (backdom.path, type,
+ self.uuid, devnum)
+ frontpath = "%s/device/%s/%d" % (self.path, type, devnum)
+
+ front = { 'backend' : backpath,
+ 'backend-id' : "%i" % backdom.id,
+ 'handle' : "%i" % devnum }
+ xstransact.Write(frontpath, front)
+
+ back = { 'instance' : "%i" % devnum,
+ 'frontend' : frontpath,
+ 'frontend-id' : "%i" % self.id }
+ xstransact.Write(backpath, back)
return
@@ -594,7 +549,7 @@
def sxpr_devices(self):
sxpr = []
- for ty in self.getDeviceTypes():
+ for ty in self.controllers.keys():
devs = self.getDeviceSxprs(ty)
sxpr += devs
if sxpr:
@@ -795,29 +750,17 @@
"""Release all vm devices.
"""
reboot = self.restart_pending()
- for ctrl in self.getDeviceControllers():
+ for ctrl in self.controllers.values():
if ctrl.isDestroyed(): continue
ctrl.destroyController(reboot=reboot)
- ddb = self.db.addChild("/device")
- for type in ddb.keys():
- if type == 'vbd':
- typedb = ddb.addChild(type)
- for dev in typedb.keys():
- devdb = typedb.addChild(str(dev))
- Blkctl.block('unbind', devdb['type'].getData(),
- devdb['node'].getData())
- typedb[dev].delete()
- typedb.saveDB(save=True)
- if type == 'vif':
- typedb = ddb.addChild(type)
- for dev in typedb.keys():
- typedb[dev].delete()
- typedb.saveDB(save=True)
- if type == 'vtpm':
- typedb = ddb.addChild(type)
- for dev in typedb.keys():
- typedb[dev].delete()
- typedb.saveDB(save=True)
+ t = xstransact("%s/device" % self.path)
+ for d in t.list("vbd"):
+ t.remove(d)
+ for d in t.list("vif"):
+ t.remove(d)
+ for d in t.list("vtpm"):
+ t.remove(d)
+ t.commit()
def show(self):
"""Print virtual machine info.
@@ -874,6 +817,7 @@
self.store_channel = self.eventChannelOld("store_channel")
self.console_channel = self.eventChannel("console", "port")
+
def create_configured_devices(self):
devices = sxp.children(self.config, 'device')
for d in devices:
@@ -881,18 +825,20 @@
if dev_config is None:
raise VmError('invalid device')
dev_type = sxp.name(dev_config)
- ctrl_type = get_device_handler(dev_type)
- if ctrl_type is None:
+
+ if not controller.isDevControllerClass(dev_type):
raise VmError('unknown device type: ' + dev_type)
- self.createDevice(ctrl_type, dev_config)
-
+
+ self.createDevice(dev_type, dev_config)
+
+
def create_devices(self):
"""Create the devices for a vm.
@raise: VmError for invalid devices
"""
if self.rebooting():
- for ctrl in self.getDeviceControllers():
+ for ctrl in self.controllers.values():
ctrl.initController(reboot=True)
else:
self.create_configured_devices()
@@ -1043,7 +989,7 @@
msg = "Had a bootloader specified, but can't find disk"
log.error(msg)
raise VmError(msg)
- config = sxp.merge(['vm', blconfig ], self.config)
+ config = sxp.merge(['vm', blcfg ], self.config)
return config
def configure_backends(self):
@@ -1092,7 +1038,7 @@
for field in sxp.children(self.config):
field_name = sxp.name(field)
field_index = index.get(field_name, 0)
- field_handler = get_config_handler(field_name)
+ field_handler = config_handlers.get(field_name)
# Ignore unknown fields. Warn?
if field_handler:
v = field_handler(self, self.config, field, field_index)
@@ -1161,23 +1107,17 @@
# get run-time value of vcpus and update store
self.exportVCPUSToDB(dom_get(self.id)['vcpus'])
-def vm_field_ignore(vm, config, val, index):
+
+def vm_field_ignore(_, _1, _2, _3):
"""Dummy config field handler used for fields with built-in handling.
-
- @param vm: virtual machine
- @param config: vm config
- @param val: config field
- @param index: field index
+ Matches the signature required by config_handlers.
"""
pass
-def vm_field_maxmem(vm, config, val, index):
- """Configure vm memory limit.
-
- @param vm: virtual machine
- @param config: vm config
- @param val: config field
- @param index: field index
+
+def vm_field_maxmem(vm, _1, val, _2):
+ """Config field handler to configure vm memory limit. Matches the
+ signature required by config_handlers.
"""
maxmem = sxp.child0(val)
if maxmem is None:
@@ -1188,8 +1128,10 @@
raise VmError("invalid maxmem: " + str(maxmem))
xc.domain_setmaxmem(vm.id, maxmem_kb = maxmem * 1024)
+
#============================================================================
# Register image handlers.
+
from image import \
addImageHandlerClass, \
ImageHandler, \
@@ -1199,43 +1141,38 @@
addImageHandlerClass(LinuxImageHandler)
addImageHandlerClass(VmxImageHandler)
-# Ignore the fields we already handle.
-add_config_handler('name', vm_field_ignore)
-add_config_handler('memory', vm_field_ignore)
-add_config_handler('ssidref', vm_field_ignore)
-add_config_handler('cpu', vm_field_ignore)
-add_config_handler('cpu_weight', vm_field_ignore)
-add_config_handler('restart', vm_field_ignore)
-add_config_handler('image', vm_field_ignore)
-add_config_handler('device', vm_field_ignore)
-add_config_handler('backend', vm_field_ignore)
-add_config_handler('vcpus', vm_field_ignore)
-add_config_handler('bootloader', vm_field_ignore)
-
-# Register other config handlers.
-add_config_handler('maxmem', vm_field_maxmem)
+
+"""Table of handlers for field configuration.
+
+field_name[String]: fn(vm, config, field, index) -> value(ignored)
+"""
+config_handlers = {
+
+ # Ignore the fields we already handle.
+
+ 'name': vm_field_ignore,
+ 'memory': vm_field_ignore,
+ 'ssidref': vm_field_ignore,
+ 'cpu': vm_field_ignore,
+ 'cpu_weight': vm_field_ignore,
+ 'restart': vm_field_ignore,
+ 'image': vm_field_ignore,
+ 'device': vm_field_ignore,
+ 'backend': vm_field_ignore,
+ 'vcpus': vm_field_ignore,
+ 'bootloader': vm_field_ignore,
+
+ # Register other config handlers.
+ 'maxmem': vm_field_maxmem
+ }
+
#============================================================================
# Register device controllers and their device config types.
-from server import blkif
-controller.addDevControllerClass("vbd", blkif.BlkifController)
-add_device_handler("vbd", "vbd")
-
-from server import netif
-controller.addDevControllerClass("vif", netif.NetifController)
-add_device_handler("vif", "vif")
-
-from server import tpmif
+from xen.xend.server import blkif, netif, tpmif, pciif, usbif
+controller.addDevControllerClass("vbd", blkif.BlkifController)
+controller.addDevControllerClass("vif", netif.NetifController)
controller.addDevControllerClass("vtpm", tpmif.TPMifController)
-add_device_handler("vtpm", "vtpm")
-
-from server import pciif
-controller.addDevControllerClass("pci", pciif.PciController)
-add_device_handler("pci", "pci")
-
-from xen.xend.server import usbif
-controller.addDevControllerClass("usb", usbif.UsbifController)
-add_device_handler("usb", "usb")
-
-#============================================================================
+controller.addDevControllerClass("pci", pciif.PciController)
+controller.addDevControllerClass("usb", usbif.UsbifController)
diff -r d4d880fcef28 -r b35215021b32 tools/python/xen/xend/XendVnet.py
--- a/tools/python/xen/xend/XendVnet.py Fri Sep 9 16:31:36 2005
+++ b/tools/python/xen/xend/XendVnet.py Tue Sep 13 16:14:16 2005
@@ -145,7 +145,7 @@
def vnet_get(self, id):
"""Get a vnet.
- @param id: vnet id
+ @param id vnet id
"""
id = str(id)
return self.vnet.get(id)
diff -r d4d880fcef28 -r b35215021b32 tools/python/xen/xend/scheduler.py
--- a/tools/python/xen/xend/scheduler.py Fri Sep 9 16:31:36 2005
+++ b/tools/python/xen/xend/scheduler.py Tue Sep 13 16:14:16 2005
@@ -20,8 +20,8 @@
def later(delay, fn, args=(), kwargs={}):
"""Schedule a function to be called later.
- @param _delay: delay in seconds
- @param _fn: function
+ @param delay: delay in seconds
+ @param fn: function
@param args: arguments (list)
@param kwargs keyword arguments (map)
"""
@@ -32,7 +32,7 @@
def now(fn, args=(), kwargs={}):
"""Schedule a function to be called now.
- @param _fn: function
+ @param fn: function
@param args: arguments (list)
@param kwargs keyword arguments (map)
"""
diff -r d4d880fcef28 -r b35215021b32 tools/python/xen/xend/server/controller.py
--- a/tools/python/xen/xend/server/controller.py Fri Sep 9 16:31:36 2005
+++ b/tools/python/xen/xend/server/controller.py Tue Sep 13 16:14:16 2005
@@ -62,6 +62,13 @@
"""
cls.type = name
getDevControllerTable().addDevControllerClass(cls)
+
+
+def isDevControllerClass(name):
+ """@return True if a device controller class has been registered with
+ the controller table under the given name."""
+ return name in getDevControllerTable().controllerClasses
+
def createDevController(name, vm, recreate=False):
return getDevControllerTable().createDevController(name, vm,
recreate=recreate)
diff -r d4d880fcef28 -r b35215021b32
tools/python/xen/xend/xenstore/xstransact.py
--- a/tools/python/xen/xend/xenstore/xstransact.py Fri Sep 9 16:31:36 2005
+++ b/tools/python/xen/xend/xenstore/xstransact.py Tue Sep 13 16:14:16 2005
@@ -4,6 +4,7 @@
# Public License. See the file "COPYING" in the main directory of
# this archive for more details.
+import errno
import threading
from xen.lowlevel import xs
@@ -18,9 +19,18 @@
class xstransact:
def __init__(self, path):
+ self.in_transaction = False
self.path = path.rstrip("/")
- xshandle().transaction_start(path)
- self.in_transaction = True
+ while True:
+ try:
+ xshandle().transaction_start(path)
+ self.in_transaction = True
+ return
+ except RuntimeError, ex:
+ if ex.args[0] == errno.ENOENT and path != "/":
+ path = "/".join(path.split("/")[0:-1]) or "/"
+ else:
+ raise
def __del__(self):
if self.in_transaction:
@@ -78,36 +88,81 @@
else:
raise TypeError
+ def _remove(self, key):
+ path = "%s/%s" % (self.path, key)
+ return xshandle().rm(path)
+
+ def remove(self, *args):
+ if len(args) == 0:
+ raise TypeError
+ for key in args:
+ self._remove(key)
+
+ def _list(self, key):
+ path = "%s/%s" % (self.path, key)
+ return map(lambda x: key + "/" + x, xshandle().ls(path))
+
+ def list(self, *args):
+ if len(args) == 0:
+ raise TypeError
+ ret = []
+ for key in args:
+ ret.extend(self._list(key))
+ return ret
+
+
def Read(cls, path, *args):
- t = cls(path)
- v = t.read(*args)
- t.commit()
- return v
+ while True:
+ try:
+ t = cls(path)
+ v = t.read(*args)
+ t.commit()
+ return v
+ except RuntimeError, ex:
+ if ex.args[0] == errno.ETIMEDOUT:
+ pass
+ raise
Read = classmethod(Read)
def Write(cls, path, *args, **opts):
- t = cls(path)
- t.write(*args, **opts)
- t.commit()
+ while True:
+ try:
+ t = cls(path)
+ t.write(*args, **opts)
+ t.commit()
+ return
+ except RuntimeError, ex:
+ if ex.args[0] == errno.ETIMEDOUT:
+ pass
+ raise
Write = classmethod(Write)
- def SafeRead(cls, path, *args):
+ def Remove(cls, *args):
while True:
try:
- return cls.Read(path, *args)
+ t = cls(path)
+ t.remove(*args)
+ t.commit()
+ return
except RuntimeError, ex:
- pass
+ if ex.args[0] == errno.ETIMEDOUT:
+ pass
+ raise
- SafeRead = classmethod(SafeRead)
+ Remove = classmethod(Remove)
- def SafeWrite(cls, path, *args, **opts):
+ def List(cls, path, *args):
while True:
try:
- cls.Write(path, *args, **opts)
- return
+ t = cls(path)
+ v = t.list(*args)
+ t.commit()
+ return v
except RuntimeError, ex:
- pass
+ if ex.args[0] == errno.ETIMEDOUT:
+ pass
+ raise
- SafeWrite = classmethod(SafeWrite)
+ List = classmethod(List)
diff -r d4d880fcef28 -r b35215021b32 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py Fri Sep 9 16:31:36 2005
+++ b/tools/python/xen/xm/create.py Tue Sep 13 16:14:16 2005
@@ -772,30 +772,33 @@
"""Balloon out memory from dom0 if necessary"""
SLACK = 4
timeout = 20 # 2s
- ret = 0
+ ret = 1
xc = xen.lowlevel.xc.new()
- pinfo = xc.physinfo()
- free_mem = pinfo['free_pages'] / 256
+ free_mem = xc.physinfo()['free_pages'] / 256
domU_need_mem = opts.vals.memory + SLACK
+
+ # we already have enough free memory, return success
+ if free_mem >= domU_need_mem:
+ del xc
+ return 0
dom0_cur_alloc = get_dom0_alloc()
dom0_new_alloc = dom0_cur_alloc - (domU_need_mem - free_mem)
-
- if free_mem < domU_need_mem and dom0_new_alloc < dom0_min_mem:
- ret = 1
- if free_mem < domU_need_mem and ret == 0:
-
- server.xend_domain_mem_target_set(0, dom0_new_alloc)
-
- while dom0_cur_alloc > dom0_new_alloc and timeout > 0:
- time.sleep(0.1) # sleep 100ms
- dom0_cur_alloc = get_dom0_alloc()
- timeout -= 1
-
- if dom0_cur_alloc > dom0_new_alloc:
- ret = 1
-
+ if dom0_new_alloc < dom0_min_mem:
+ dom0_new_alloc = dom0_min_mem
+
+ server.xend_domain_mem_target_set(0, dom0_new_alloc)
+
+ while timeout > 0:
+ time.sleep(0.1) # sleep 100ms
+
+ free_mem = xc.physinfo()['free_pages'] / 256
+ if free_mem >= domU_need_mem:
+ ret = 0
+ break
+ timeout -= 1
+
del xc
return ret
diff -r d4d880fcef28 -r b35215021b32 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py Fri Sep 9 16:31:36 2005
+++ b/tools/python/xen/xm/main.py Tue Sep 13 16:14:16 2005
@@ -450,7 +450,10 @@
info = server.xend_node()
for x in info[1:]:
- print "%-23s:" % x[0], x[1]
+ if len(x) < 2:
+ print "%-23s: (none)" % x[0]
+ else:
+ print "%-23s:" % x[0], x[1]
# TODO: remove as soon as console server shows up
def xm_console(args):
diff -r d4d880fcef28 -r b35215021b32 tools/xenstore/Makefile
--- a/tools/xenstore/Makefile Fri Sep 9 16:31:36 2005
+++ b/tools/xenstore/Makefile Tue Sep 13 16:14:16 2005
@@ -17,15 +17,15 @@
BASECFLAGS+= -I$(XEN_ROOT)/tools/libxc
BASECFLAGS+= -I$(XEN_ROOT)/xen/include/public
BASECFLAGS+= -I.
-BASECFLAGS+= -I$(XEN_ROOT)/linux-2.6-xen-sparse/include/asm-xen/linux-public
CFLAGS += $(BASECFLAGS)
LDFLAGS += $(PROFILE) -L$(XEN_LIBXC)
-TESTDIR = `pwd`/testsuite/tmp
+TESTDIR = testsuite/tmp
TESTFLAGS= -DTESTING
TESTENV = XENSTORED_ROOTDIR=$(TESTDIR) XENSTORED_RUNDIR=$(TESTDIR)
-CLIENTS := xenstore-read xenstore-rm xenstore-write
+CLIENTS := xenstore-exists xenstore-list xenstore-read xenstore-rm
+CLIENTS += xenstore-write
CLIENTS_OBJS := $(patsubst xenstore-%,xenstore_%.o,$(CLIENTS))
all: libxenstore.so xenstored $(CLIENTS)
@@ -80,10 +80,13 @@
fullcheck: testsuite-run randomcheck stresstest
-testsuite-run: xenstored_test xs_test
+$(TESTDIR):
+ mkdir $@
+
+testsuite-run: xenstored_test xs_test $(TESTDIR)
$(TESTENV) testsuite/test.sh && echo
-testsuite-fast: xenstored_test xs_test
+testsuite-fast: xenstored_test xs_test $(TESTDIR)
@$(TESTENV) testsuite/test.sh --fast
testsuite-clean:
@@ -92,21 +95,21 @@
# Make this visible so they can see repeat tests without --fast if they
# fail.
RANDSEED=$(shell date +%s)
-randomcheck: xs_random xenstored_test
+randomcheck: xs_random xenstored_test $(TESTDIR)
$(TESTENV) ./xs_random --simple --fast /tmp/xs_random 200000
$(RANDSEED) && echo
$(TESTENV) ./xs_random --fast /tmp/xs_random 100000 $(RANDSEED) && echo
$(TESTENV) ./xs_random --fail /tmp/xs_random 10000 $(RANDSEED)
-crashme: xs_crashme xenstored_test
+crashme: xs_crashme xenstored_test $(TESTDIR)
rm -rf $(TESTDIR)/store $(TESTDIR)/transactions /tmp/xs_crashme.vglog*
/tmp/trace
export $(TESTENV); ./xs_crashme 5000 $(RANDSEED) 2>/dev/null
if [ -n "`cat /tmp/xs_crashme.vglog*`" ]; then echo Valgrind
complained; cat /tmp/xs_crashme.vglog*; exit 1; fi
rm -rf $(TESTDIR)/store $(TESTDIR)/transactions /tmp/xs_crashme.vglog*
/tmp/trace
-randomcheck-fast: xs_random xenstored_test
+randomcheck-fast: xs_random xenstored_test $(TESTDIR)
@$(TESTENV) ./xs_random --fast /tmp/xs_random 2000 $(RANDSEED)
-stresstest: xs_stress xenstored_test
+stresstest: xs_stress xenstored_test $(TESTDIR)
rm -rf $(TESTDIR)/store $(TESTDIR)/transactions
export $(TESTENV); PID=`./xenstored_test --output-pid
--trace-file=/tmp/trace`; ./xs_stress 5000; ret=$$?; kill $$PID; exit $$ret
diff -r d4d880fcef28 -r b35215021b32 tools/xenstore/fake_libxc.c
--- a/tools/xenstore/fake_libxc.c Fri Sep 9 16:31:36 2005
+++ b/tools/xenstore/fake_libxc.c Tue Sep 13 16:14:16 2005
@@ -83,6 +83,39 @@
return 0;
}
+int xc_domain_getinfo(int xc_handle __attribute__((unused)),
+ u32 first_domid, unsigned int max_doms,
+ xc_dominfo_t *info)
+{
+ assert(max_doms == 1);
+ info->domid = first_domid;
+
+ info->dying = 0;
+ info->shutdown = 0;
+ info->paused = 0;
+ info->blocked = 0;
+ info->running = 1;
+
+ info->shutdown_reason = 0;
+
+ if ( info->shutdown && (info->shutdown_reason == SHUTDOWN_crash) )
+ {
+ info->shutdown = 0;
+ info->crashed = 1;
+ }
+
+ return 1;
+}
+
+int xc_evtchn_bind_virq(int xc_handle __attribute__((unused)),
+ int virq __attribute__((unused)),
+ int *port)
+{
+ if (port)
+ *port = 0;
+ return 0;
+}
+
static void send_to_fd(int signo __attribute__((unused)))
{
int saved_errno = errno;
diff -r d4d880fcef28 -r b35215021b32 tools/xenstore/testsuite/07watch.test
--- a/tools/xenstore/testsuite/07watch.test Fri Sep 9 16:31:36 2005
+++ b/tools/xenstore/testsuite/07watch.test Tue Sep 13 16:14:16 2005
@@ -34,12 +34,13 @@
1 close
2 close
-# We don't get a watch from our own commands.
-watch /dir token
-mkdir /dir/newdir
-expect waitwatch failed: Connection timed out
-waitwatch
-close
+# Changed in b594bb976a743d509f1ffabb5bc698874ab90d8f
+## We don't get a watch from our own commands.
+#watch /dir token
+#mkdir /dir/newdir
+#expect waitwatch failed: Connection timed out
+#waitwatch
+#close
# ignore watches while doing commands, should work.
watch /dir token
diff -r d4d880fcef28 -r b35215021b32
tools/xenstore/testsuite/14complexperms.test
--- a/tools/xenstore/testsuite/14complexperms.test Fri Sep 9 16:31:36 2005
+++ b/tools/xenstore/testsuite/14complexperms.test Tue Sep 13 16:14:16 2005
@@ -30,10 +30,8 @@
expect *Permission denied
setperm /dir/file 0 NONE
watch /dir/file token
-setid 0
-write /dir/file create contents
-rm /dir/file
-setid 1
+1 write /dir/file create contents
+1 rm /dir/file
expect waitwatch failed: Connection timed out
waitwatch
unwatch /dir/file token
@@ -78,10 +76,8 @@
expect *Permission denied
setperm /dir/file 0 NONE
watch /dir/file token
-setid 0
-write /dir/file create contents
-rm /dir/file
-setid 1
+1 write /dir/file create contents
+1 rm /dir/file
expect waitwatch failed: Connection timed out
waitwatch
unwatch /dir/file token
diff -r d4d880fcef28 -r b35215021b32 tools/xenstore/xenstore_client.c
--- a/tools/xenstore/xenstore_client.c Fri Sep 9 16:31:36 2005
+++ b/tools/xenstore/xenstore_client.c Tue Sep 13 16:14:16 2005
@@ -22,7 +22,7 @@
errx(1, "Usage: %s [-h] [-p] key [...]", progname);
#elif defined(CLIENT_write)
errx(1, "Usage: %s [-h] key value [...]", progname);
-#elif defined(CLIENT_rm)
+#elif defined(CLIENT_rm) || defined(CLIENT_exists) || defined(CLIENT_list)
errx(1, "Usage: %s [-h] key [...]", progname);
#endif
}
@@ -33,8 +33,7 @@
struct xs_handle *xsh;
bool success;
int ret = 0;
-#if defined(CLIENT_read)
- char *val;
+#if defined(CLIENT_read) || defined(CLIENT_list)
int prefix = 0;
#endif
@@ -46,14 +45,14 @@
int c, index = 0;
static struct option long_options[] = {
{"help", 0, 0, 'h'},
-#if defined(CLIENT_read)
+#if defined(CLIENT_read) || defined(CLIENT_list)
{"prefix", 0, 0, 'p'},
#endif
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "h"
-#if defined(CLIENT_read)
+#if defined(CLIENT_read) || defined(CLIENT_list)
"p"
#endif
, long_options, &index);
@@ -64,7 +63,7 @@
case 'h':
usage(argv[0]);
/* NOTREACHED */
-#if defined(CLIENT_read)
+#if defined(CLIENT_read) || defined(CLIENT_list)
case 'p':
prefix = 1;
break;
@@ -77,7 +76,7 @@
/* NOTREACHED */
}
#if defined(CLIENT_write)
- if ((argc - optind) % 1) {
+ if ((argc - optind) % 2 == 1) {
usage(argv[0]);
/* NOTREACHED */
}
@@ -90,7 +89,7 @@
while (optind < argc) {
#if defined(CLIENT_read)
- val = xs_read(xsh, argv[optind], NULL);
+ char *val = xs_read(xsh, argv[optind], NULL);
if (val == NULL) {
warnx("couldn't read path %s", argv[optind]);
ret = 1;
@@ -118,6 +117,29 @@
goto out;
}
optind++;
+#elif defined(CLIENT_exists)
+ char *val = xs_read(xsh, argv[optind], NULL);
+ if (val == NULL) {
+ ret = 1;
+ goto out;
+ }
+ free(val);
+ optind++;
+#elif defined(CLIENT_list)
+ unsigned int i, num;
+ char **list = xs_directory(xsh, argv[optind], &num);
+ if (list == NULL) {
+ warnx("could not list path %s", argv[optind]);
+ ret = 1;
+ goto out;
+ }
+ for (i = 0; i < num; i++) {
+ if (prefix)
+ printf("%s/", argv[optind]);
+ printf("%s\n", list[i]);
+ }
+ free(list);
+ optind++;
#endif
}
diff -r d4d880fcef28 -r b35215021b32 tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c Fri Sep 9 16:31:36 2005
+++ b/tools/xenstore/xenstored_core.c Tue Sep 13 16:14:16 2005
@@ -1640,8 +1640,10 @@
/* Session leader so ^C doesn't whack us. */
setsid();
+#ifndef TESTING /* Relative paths for socket names */
/* Move off any mount points we might be in. */
chdir("/");
+#endif
/* Discard our parent's old-fashioned umask prejudices. */
umask(0);
}
diff -r d4d880fcef28 -r b35215021b32 tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Fri Sep 9 16:31:36 2005
+++ b/tools/xenstore/xenstored_domain.c Tue Sep 13 16:14:16 2005
@@ -216,6 +216,26 @@
munmap(domain->page, getpagesize());
return 0;
+}
+
+static void domain_cleanup(void)
+{
+ xc_dominfo_t dominfo;
+ struct domain *domain, *tmp;
+ int released = 0;
+
+ list_for_each_entry_safe(domain, tmp, &domains, list) {
+ if (xc_domain_getinfo(*xc_handle, domain->domid, 1,
+ &dominfo) == 1 &&
+ dominfo.domid == domain->domid &&
+ !dominfo.dying && !dominfo.crashed && !dominfo.shutdown)
+ continue;
+ talloc_free(domain->conn);
+ released++;
+ }
+
+ if (released)
+ fire_watches(NULL, "@releaseDomain", false);
}
/* We scan all domains rather than use the information given here. */
@@ -371,26 +391,6 @@
send_ack(conn, XS_RELEASE);
}
-void domain_cleanup(void)
-{
- xc_dominfo_t dominfo;
- struct domain *domain, *tmp;
- int released = 0;
-
- list_for_each_entry_safe(domain, tmp, &domains, list) {
- if (xc_domain_getinfo(*xc_handle, domain->domid, 1,
- &dominfo) == 1 &&
- dominfo.domid == domain->domid &&
- !dominfo.dying && !dominfo.crashed && !dominfo.shutdown)
- continue;
- talloc_free(domain->conn);
- released++;
- }
-
- if (released)
- fire_watches(NULL, "@releaseDomain", false);
-}
-
void do_get_domain_path(struct connection *conn, const char *domid_str)
{
struct domain *domain;
@@ -457,6 +457,7 @@
#ifdef TESTING
eventchn_fd = fake_open_eventchn();
+ (void)&st;
#else
/* Make sure any existing device file links to correct device. */
if ((lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) ||
diff -r d4d880fcef28 -r b35215021b32 tools/xenstore/xenstored_domain.h
--- a/tools/xenstore/xenstored_domain.h Fri Sep 9 16:31:36 2005
+++ b/tools/xenstore/xenstored_domain.h Tue Sep 13 16:14:16 2005
@@ -28,10 +28,6 @@
/* domid */
void do_release(struct connection *conn, const char *domid_str);
-/* Enumerate domains and release connections for non-existant or dying
- * domains. */
-void domain_cleanup(void);
-
/* domid */
void do_get_domain_path(struct connection *conn, const char *domid_str);
diff -r d4d880fcef28 -r b35215021b32 tools/xenstore/xenstored_watch.c
--- a/tools/xenstore/xenstored_watch.c Fri Sep 9 16:31:36 2005
+++ b/tools/xenstore/xenstored_watch.c Tue Sep 13 16:14:16 2005
@@ -105,7 +105,6 @@
*/
if (!check_node_perms(conn, node, XS_PERM_READ|XS_PERM_ENOENT_OK) &&
!check_event_node(node)) {
- fprintf(stderr, "No permission for %s\n", node);
return;
}
@@ -135,11 +134,8 @@
if (conn && conn->transaction)
return;
- /* Create an event for each watch. Don't send to self. */
+ /* Create an event for each watch. */
list_for_each_entry(i, &connections, list) {
- if (i == conn)
- continue;
-
list_for_each_entry(watch, &i->watches, list) {
if (is_child(node, watch->node))
add_event(i, watch, node);
diff -r d4d880fcef28 -r b35215021b32 tools/xenstore/xs.c
--- a/tools/xenstore/xs.c Fri Sep 9 16:31:36 2005
+++ b/tools/xenstore/xs.c Tue Sep 13 16:14:16 2005
@@ -36,12 +36,10 @@
#include "xenstored.h"
#include "xs_lib.h"
#include "utils.h"
-#include "xenbus_dev.h"
struct xs_handle
{
int fd;
- enum { SOCK, DEV } type;
};
/* Get the socket from the store daemon handle.
@@ -68,7 +66,6 @@
h = malloc(sizeof(*h));
if (h) {
h->fd = sock;
- h->type = SOCK;
return h;
}
}
@@ -82,16 +79,15 @@
static struct xs_handle *get_dev(const char *connect_to)
{
int fd, saved_errno;
- struct xs_handle *h = NULL;
-
- fd = open(connect_to, O_RDONLY);
+ struct xs_handle *h;
+
+ fd = open(connect_to, O_RDWR);
if (fd < 0)
return NULL;
h = malloc(sizeof(*h));
if (h) {
h->fd = fd;
- h->type = DEV;
return h;
}
@@ -101,19 +97,32 @@
return NULL;
}
+static struct xs_handle *get_handle(const char *connect_to)
+{
+ struct stat buf;
+
+ if (stat(connect_to, &buf) != 0)
+ return NULL;
+
+ if (S_ISSOCK(buf.st_mode))
+ return get_socket(connect_to);
+ else
+ return get_dev(connect_to);
+}
+
struct xs_handle *xs_daemon_open(void)
{
- return get_socket(xs_daemon_socket());
+ return get_handle(xs_daemon_socket());
}
struct xs_handle *xs_daemon_open_readonly(void)
{
- return get_socket(xs_daemon_socket_ro());
+ return get_handle(xs_daemon_socket_ro());
}
struct xs_handle *xs_domain_open(void)
{
- return get_dev(xs_domain_dev());
+ return get_handle(xs_domain_dev());
}
void xs_daemon_close(struct xs_handle *h)
@@ -190,9 +199,9 @@
}
/* Send message to xs, get malloc'ed reply. NULL and set errno on error. */
-static void *xs_talkv_sock(struct xs_handle *h, enum xsd_sockmsg_type type,
- const struct iovec *iovec, unsigned int num_vecs,
- unsigned int *len)
+static void *xs_talkv(struct xs_handle *h, enum xsd_sockmsg_type type,
+ const struct iovec *iovec, unsigned int num_vecs,
+ unsigned int *len)
{
struct xsd_sockmsg msg;
void *ret = NULL;
@@ -250,54 +259,6 @@
close(h->fd);
h->fd = -1;
errno = saved_errno;
- return NULL;
-}
-
-/* Send message to xs, get malloc'ed reply. NULL and set errno on error. */
-static void *xs_talkv_dev(struct xs_handle *h, enum xsd_sockmsg_type type,
- const struct iovec *iovec, unsigned int num_vecs,
- unsigned int *len)
-{
- struct xenbus_dev_talkv dt;
- char *buf;
- int err, buflen = 1024;
-
- again:
- buf = malloc(buflen);
- if (buf == NULL) {
- errno = ENOMEM;
- return NULL;
- }
- dt.type = type;
- dt.iovec = (struct kvec *)iovec;
- dt.num_vecs = num_vecs;
- dt.buf = buf;
- dt.len = buflen;
- err = ioctl(h->fd, IOCTL_XENBUS_DEV_TALKV, &dt);
- if (err < 0) {
- free(buf);
- errno = err;
- return NULL;
- }
- if (err > buflen) {
- free(buf);
- buflen = err;
- goto again;
- }
- if (len)
- *len = err;
- return buf;
-}
-
-/* Send message to xs, get malloc'ed reply. NULL and set errno on error. */
-static void *xs_talkv(struct xs_handle *h, enum xsd_sockmsg_type type,
- const struct iovec *iovec, unsigned int num_vecs,
- unsigned int *len)
-{
- if (h->type == SOCK)
- return xs_talkv_sock(h, type, iovec, num_vecs, len);
- if (h->type == DEV)
- return xs_talkv_dev(h, type, iovec, num_vecs, len);
return NULL;
}
diff -r d4d880fcef28 -r b35215021b32 tools/xenstore/xs_lib.c
--- a/tools/xenstore/xs_lib.c Fri Sep 9 16:31:36 2005
+++ b/tools/xenstore/xs_lib.c Tue Sep 13 16:14:16 2005
@@ -38,37 +38,55 @@
return (s ? s : "/var/run/xenstored");
}
+static const char *xs_daemon_path(void)
+{
+ static char buf[PATH_MAX];
+ char *s = getenv("XENSTORED_PATH");
+ if (s)
+ return s;
+ if (snprintf(buf, PATH_MAX, "%s/socket",
+ xs_daemon_rundir()) >= PATH_MAX)
+ return NULL;
+ return buf;
+}
+
const char *xs_daemon_socket(void)
{
- static char buf[PATH_MAX];
- sprintf(buf, "%s/socket", xs_daemon_rundir());
- return buf;
+ return xs_daemon_path();
}
const char *xs_daemon_socket_ro(void)
{
static char buf[PATH_MAX];
- sprintf(buf, "%s/socket_ro", xs_daemon_rundir());
+ const char *s = xs_daemon_path();
+ if (s == NULL)
+ return NULL;
+ if (snprintf(buf, PATH_MAX, "%s_ro", s) >= PATH_MAX)
+ return NULL;
return buf;
}
const char *xs_daemon_store(void)
{
static char buf[PATH_MAX];
- sprintf(buf, "%s/store", xs_daemon_rootdir());
+ if (snprintf(buf, PATH_MAX, "%s/store",
+ xs_daemon_rootdir()) >= PATH_MAX)
+ return NULL;
return buf;
}
const char *xs_daemon_transactions(void)
{
static char buf[PATH_MAX];
- sprintf(buf, "%s/transactions", xs_daemon_rootdir());
+ if (snprintf(buf, PATH_MAX, "%s/transactions",
+ xs_daemon_rootdir()) >= PATH_MAX)
+ return NULL;
return buf;
}
const char *xs_domain_dev(void)
{
- char *s = getenv("XENSTORED_DOMAIN_DEV");
+ char *s = getenv("XENSTORED_PATH");
return (s ? s : "/proc/xen/xenbus");
}
diff -r d4d880fcef28 -r b35215021b32 tools/xenstore/xs_test.c
--- a/tools/xenstore/xs_test.c Fri Sep 9 16:31:36 2005
+++ b/tools/xenstore/xs_test.c Tue Sep 13 16:14:16 2005
@@ -43,7 +43,7 @@
static struct xs_handle *handles[10] = { NULL };
-static unsigned int timeout_ms = 200;
+static unsigned int timeout_ms = 500;
static bool timeout_suppressed = true;
static bool readonly = false;
static bool print_input = false;
diff -r d4d880fcef28 -r b35215021b32 xen/Makefile
--- a/xen/Makefile Fri Sep 9 16:31:36 2005
+++ b/xen/Makefile Tue Sep 13 16:14:16 2005
@@ -31,11 +31,11 @@
install: $(TARGET).gz
[ -d $(DESTDIR)/boot ] || $(INSTALL_DIR) $(DESTDIR)/boot
- $(INSTALL_DATA) $(TARGET).gz $(DESTDIR)/boot/$(notdir
$(TARGET))-$(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION).gz
- ln -f -s $(notdir
$(TARGET))-$(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION).gz
$(DESTDIR)/boot/$(notdir $(TARGET))-$(XEN_VERSION).$(XEN_SUBVERSION).gz
- ln -f -s $(notdir
$(TARGET))-$(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION).gz
$(DESTDIR)/boot/$(notdir $(TARGET))-$(XEN_VERSION).gz
- ln -f -s $(notdir
$(TARGET))-$(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION).gz
$(DESTDIR)/boot/$(notdir $(TARGET)).gz
- $(INSTALL_DATA) $(TARGET)-syms $(DESTDIR)/boot/$(notdir
$(TARGET))-syms-$(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION)
+ $(INSTALL_DATA) $(TARGET).gz $(DESTDIR)/boot/$(notdir
$(TARGET))-$(XEN_FULLVERSION).gz
+ ln -f -s $(notdir $(TARGET))-$(XEN_FULLVERSION).gz
$(DESTDIR)/boot/$(notdir $(TARGET))-$(XEN_VERSION).$(XEN_SUBVERSION).gz
+ ln -f -s $(notdir $(TARGET))-$(XEN_FULLVERSION).gz
$(DESTDIR)/boot/$(notdir $(TARGET))-$(XEN_VERSION).gz
+ ln -f -s $(notdir $(TARGET))-$(XEN_FULLVERSION).gz
$(DESTDIR)/boot/$(notdir $(TARGET)).gz
+ $(INSTALL_DATA) $(TARGET)-syms $(DESTDIR)/boot/$(notdir
$(TARGET))-syms-$(XEN_FULLVERSION)
[ -d $(DESTDIR)/usr/include/xen/io ] || \
$(INSTALL_DIR) $(DESTDIR)/usr/include/xen/io
$(INSTALL_DATA) include/public/*.h $(DESTDIR)/usr/include/xen
diff -r d4d880fcef28 -r b35215021b32 xen/arch/ia64/xen/xensetup.c
--- a/xen/arch/ia64/xen/xensetup.c Fri Sep 9 16:31:36 2005
+++ b/xen/arch/ia64/xen/xensetup.c Tue Sep 13 16:14:16 2005
@@ -386,16 +386,17 @@
startup_cpu_idle_loop();
}
-void arch_get_xen_caps(xen_capabilities_info_t *info)
-{
- char *p=info->caps;
+void arch_get_xen_caps(xen_capabilities_info_t info)
+{
+ char *p=info;
*p=0;
p+=sprintf(p,"xen_%d.%d_ia64 ",XEN_VERSION,XEN_SUBVERSION);
- BUG_ON((p-info->caps)>sizeof(*info));
-
- if(p>info->caps) *(p-1) = 0;
-}
-
+ *(p-1) = 0;
+
+ BUG_ON((p-info)>sizeof(xen_capabilities_info_t));
+
+}
+
diff -r d4d880fcef28 -r b35215021b32 xen/arch/x86/dom0_ops.c
--- a/xen/arch/x86/dom0_ops.c Fri Sep 9 16:31:36 2005
+++ b/xen/arch/x86/dom0_ops.c Tue Sep 13 16:14:16 2005
@@ -35,13 +35,13 @@
static void write_msr_for(void *unused)
{
- if (((1 << current->processor) & msr_cpu_mask))
+ if ( ((1 << current->processor) & msr_cpu_mask) )
(void)wrmsr_user(msr_addr, msr_lo, msr_hi);
}
static void read_msr_for(void *unused)
{
- if (((1 << current->processor) & msr_cpu_mask))
+ if ( ((1 << current->processor) & msr_cpu_mask) )
(void)rdmsr_user(msr_addr, msr_lo, msr_hi);
}
@@ -189,11 +189,11 @@
pi->total_pages = max_page;
pi->free_pages = avail_domheap_pages();
pi->cpu_khz = cpu_khz;
- memset( pi->hw_cap, 0, sizeof(pi->hw_cap) );
- memcpy( pi->hw_cap, boot_cpu_data.x86_capability, NCAPINTS*4 );
+ memset(pi->hw_cap, 0, sizeof(pi->hw_cap));
+ memcpy(pi->hw_cap, boot_cpu_data.x86_capability, NCAPINTS*4);
ret = 0;
- if( copy_to_user(u_dom0_op, op, sizeof(*op)) )
- ret = -EINVAL;
+ if ( copy_to_user(u_dom0_op, op, sizeof(*op)) )
+ ret = -EFAULT;
}
break;
diff -r d4d880fcef28 -r b35215021b32 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c Fri Sep 9 16:31:36 2005
+++ b/xen/arch/x86/domain.c Tue Sep 13 16:14:16 2005
@@ -461,14 +461,11 @@
if ( !get_page(&frame_table[phys_basetab>>PAGE_SHIFT], d) )
return -EINVAL;
}
- else
- {
-#ifdef __x86_64__
- if ( !(c->flags & VGCF_VMX_GUEST) )
-#endif
- if ( !get_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT], d,
- PGT_base_page_table) )
- return -EINVAL;
+ else if ( !(c->flags & VGCF_VMX_GUEST) )
+ {
+ if ( !get_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT], d,
+ PGT_base_page_table) )
+ return -EINVAL;
}
if ( (rc = (int)set_gdt(v, c->gdt_frames, c->gdt_ents)) != 0 )
@@ -677,10 +674,10 @@
if ( VMX_DOMAIN(v) )
rdmsrl(MSR_SHADOW_GS_BASE, v->arch.arch_vmx.msr_content.shadow_gs);
- __asm__ __volatile__ ( "movl %%ds,%0" : "=m" (regs->ds) );
- __asm__ __volatile__ ( "movl %%es,%0" : "=m" (regs->es) );
- __asm__ __volatile__ ( "movl %%fs,%0" : "=m" (regs->fs) );
- __asm__ __volatile__ ( "movl %%gs,%0" : "=m" (regs->gs) );
+ __asm__ __volatile__ ( "mov %%ds,%0" : "=m" (regs->ds) );
+ __asm__ __volatile__ ( "mov %%es,%0" : "=m" (regs->es) );
+ __asm__ __volatile__ ( "mov %%fs,%0" : "=m" (regs->fs) );
+ __asm__ __volatile__ ( "mov %%gs,%0" : "=m" (regs->gs) );
if ( regs->ds )
dirty_segment_mask |= DIRTY_DS;
diff -r d4d880fcef28 -r b35215021b32 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c Fri Sep 9 16:31:36 2005
+++ b/xen/arch/x86/setup.c Tue Sep 13 16:14:16 2005
@@ -93,8 +93,6 @@
#endif
EXPORT_SYMBOL(mmu_cr4_features);
-int hvm_enabled = 0; /* can we run unmodified guests */
-
struct vcpu *idle_task[NR_CPUS] = { &idle0_vcpu };
int acpi_disabled;
@@ -533,43 +531,44 @@
startup_cpu_idle_loop();
}
-void arch_get_xen_caps(xen_capabilities_info_t *info)
+void arch_get_xen_caps(xen_capabilities_info_t info)
{
- char *p=info->caps;
-
- *p=0;
-
-#ifdef CONFIG_X86_32
-
-#ifndef CONFIG_X86_PAE
- p+=sprintf(p,"xen_%d.%d_x86_32 ",XEN_VERSION,XEN_SUBVERSION);
- if(hvm_enabled)
- {
- p+=sprintf(p,"hvm_%d.%d_x86_32 ",XEN_VERSION,XEN_SUBVERSION);
- }
+ char *p = info;
+
+#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_PAE)
+
+ p += sprintf(p, "xen_%d.%d_x86_32 ", XEN_VERSION, XEN_SUBVERSION);
+ if ( hvm_enabled )
+ p += sprintf(p, "hvm_%d.%d_x86_32 ", XEN_VERSION, XEN_SUBVERSION);
+
+#elif defined(CONFIG_X86_32) && defined(CONFIG_X86_PAE)
+
+ p += sprintf(p, "xen_%d.%d_x86_32p ", XEN_VERSION, XEN_SUBVERSION);
+ if ( hvm_enabled )
+ {
+ //p += sprintf(p, "hvm_%d.%d_x86_32 ", XEN_VERSION, XEN_SUBVERSION);
+ //p += sprintf(p, "hvm_%d.%d_x86_32p ", XEN_VERSION, XEN_SUBVERSION);
+ }
+
+#elif defined(CONFIG_X86_64)
+
+ p += sprintf(p, "xen_%d.%d_x86_64 ", XEN_VERSION, XEN_SUBVERSION);
+ if ( hvm_enabled )
+ {
+ //p += sprintf(p, "hvm_%d.%d_x86_32 ", XEN_VERSION, XEN_SUBVERSION);
+ //p += sprintf(p, "hvm_%d.%d_x86_32p ", XEN_VERSION, XEN_SUBVERSION);
+ p += sprintf(p, "hvm_%d.%d_x86_64 ", XEN_VERSION, XEN_SUBVERSION);
+ }
+
#else
- p+=sprintf(p,"xen_%d.%d_x86_32p ",XEN_VERSION,XEN_SUBVERSION);
- if(hvm_enabled)
- {
- //p+=sprintf(p,"hvm_%d.%d_x86_32 ",XEN_VERSION,XEN_SUBVERSION);
- //p+=sprintf(p,"hvm_%d.%d_x86_32p ",XEN_VERSION,XEN_SUBVERSION);
- }
-
-#endif
-
-#else /* !CONFIG_X86_32 */
- p+=sprintf(p,"xen_%d.%d_x86_64 ",XEN_VERSION,XEN_SUBVERSION);
- if(hvm_enabled)
- {
- //p+=sprintf(p,"hvm_%d.%d_x86_32 ",XEN_VERSION,XEN_SUBVERSION);
- //p+=sprintf(p,"hvm_%d.%d_x86_32p ",XEN_VERSION,XEN_SUBVERSION);
- p+=sprintf(p,"hvm_%d.%d_x86_64 ",XEN_VERSION,XEN_SUBVERSION);
- }
+
+ p++;
+
#endif
- BUG_ON((p-info->caps)>sizeof(*info));
-
- if(p>info->caps) *(p-1) = 0;
+ *(p-1) = 0;
+
+ BUG_ON((p - info) > sizeof(xen_capabilities_info_t));
}
/*
diff -r d4d880fcef28 -r b35215021b32 xen/arch/x86/shadow.c
--- a/xen/arch/x86/shadow.c Fri Sep 9 16:31:36 2005
+++ b/xen/arch/x86/shadow.c Tue Sep 13 16:14:16 2005
@@ -54,7 +54,7 @@
static void shadow_map_into_current(struct vcpu *v,
unsigned long va, unsigned int from, unsigned int to);
static inline void validate_bl2e_change( struct domain *d,
- guest_root_pgentry_t *new_gle_p, pgentry_64_t *shadow_l3, int index);
+ guest_root_pgentry_t *new_gle_p, pgentry_64_t *shadow_l3, int index);
#endif
diff -r d4d880fcef28 -r b35215021b32 xen/arch/x86/shadow32.c
--- a/xen/arch/x86/shadow32.c Fri Sep 9 16:31:36 2005
+++ b/xen/arch/x86/shadow32.c Tue Sep 13 16:14:16 2005
@@ -2214,7 +2214,7 @@
struct domain *d, unsigned long l1mfn, unsigned long forbidden_gmfn)
{
l1_pgentry_t *pl1e = map_domain_page(l1mfn);
- l1_pgentry_t match;
+ l1_pgentry_t match, ol2e;
unsigned long flags = _PAGE_PRESENT;
int i;
u32 count = 0;
@@ -2226,17 +2226,17 @@
for (i = 0; i < L1_PAGETABLE_ENTRIES; i++)
{
- if ( unlikely(!l1e_has_changed(pl1e[i], match, flags) == 0) )
- {
- l1_pgentry_t ol2e = pl1e[i];
- pl1e[i] = l1e_empty();
- count++;
-
- if ( is_l1_shadow )
- shadow_put_page_from_l1e(ol2e, d);
- else /* must be an hl2 page */
- put_page(&frame_table[forbidden_gmfn]);
- }
+ if ( l1e_has_changed(pl1e[i], match, flags) )
+ continue;
+
+ ol2e = pl1e[i];
+ pl1e[i] = l1e_empty();
+ count++;
+
+ if ( is_l1_shadow )
+ shadow_put_page_from_l1e(ol2e, d);
+ else /* must be an hl2 page */
+ put_page(&frame_table[forbidden_gmfn]);
}
unmap_domain_page(pl1e);
diff -r d4d880fcef28 -r b35215021b32 xen/arch/x86/shadow_public.c
--- a/xen/arch/x86/shadow_public.c Fri Sep 9 16:31:36 2005
+++ b/xen/arch/x86/shadow_public.c Tue Sep 13 16:14:16 2005
@@ -54,24 +54,24 @@
switch(levels) {
#if CONFIG_PAGING_LEVELS >= 4
case 4:
- if ( d->arch.ops != &MODE_F_HANDLER )
- d->arch.ops = &MODE_F_HANDLER;
- shadow_unlock(d);
+ if ( d->arch.ops != &MODE_F_HANDLER )
+ d->arch.ops = &MODE_F_HANDLER;
+ shadow_unlock(d);
return 1;
#endif
case 3:
case 2:
#if CONFIG_PAGING_LEVELS == 2
- if ( d->arch.ops != &MODE_A_HANDLER )
- d->arch.ops = &MODE_A_HANDLER;
+ if ( d->arch.ops != &MODE_A_HANDLER )
+ d->arch.ops = &MODE_A_HANDLER;
#elif CONFIG_PAGING_LEVELS == 4
- if ( d->arch.ops != &MODE_D_HANDLER )
- d->arch.ops = &MODE_D_HANDLER;
+ if ( d->arch.ops != &MODE_D_HANDLER )
+ d->arch.ops = &MODE_D_HANDLER;
#endif
- shadow_unlock(d);
+ shadow_unlock(d);
return 1;
- default:
- shadow_unlock(d);
+ default:
+ shadow_unlock(d);
return 0;
}
}
@@ -115,10 +115,10 @@
struct out_of_sync_entry *
shadow_mark_mfn_out_of_sync(struct vcpu *v, unsigned long gpfn,
- unsigned long mfn)
-{
- struct domain *d = v->domain;
- return d->arch.ops->mark_mfn_out_of_sync(v, gpfn, mfn);
+ unsigned long mfn)
+{
+ struct domain *d = v->domain;
+ return d->arch.ops->mark_mfn_out_of_sync(v, gpfn, mfn);
}
/*
@@ -181,7 +181,7 @@
l4_pgentry_t *mpl4e;
struct pfn_info *mmfn_info;
struct domain *d = v->domain;
- pagetable_t phys_table;
+ pagetable_t phys_table;
ASSERT(!pagetable_get_paddr(v->arch.monitor_table)); /* we should only get
called once */
@@ -192,13 +192,13 @@
mpl4e = (l4_pgentry_t *) map_domain_page(mmfn);
memcpy(mpl4e, &idle_pg_table[0], PAGE_SIZE);
mpl4e[l4_table_offset(PERDOMAIN_VIRT_START)] =
- l4e_from_paddr(__pa(d->arch.mm_perdomain_l3), __PAGE_HYPERVISOR);
+ l4e_from_paddr(__pa(d->arch.mm_perdomain_l3), __PAGE_HYPERVISOR);
/* map the phys_to_machine map into the per domain Read-Only MPT space */
phys_table = page_table_convert(d);
mpl4e[l4_table_offset(RO_MPT_VIRT_START)] =
- l4e_from_paddr(pagetable_get_paddr(phys_table),
- __PAGE_HYPERVISOR);
+ l4e_from_paddr(pagetable_get_paddr(phys_table),
+ __PAGE_HYPERVISOR);
v->arch.monitor_table = mk_pagetable(mmfn << PAGE_SHIFT);
v->arch.monitor_vtable = (l2_pgentry_t *) mpl4e;
}
@@ -245,7 +245,7 @@
for ( i = 0; i < PAGETABLE_ENTRIES; i++ )
if ( external || is_guest_l4_slot(i) )
if ( entry_get_flags(ple[i]) & _PAGE_PRESENT )
- put_shadow_ref(entry_get_pfn(ple[i]));
+ put_shadow_ref(entry_get_pfn(ple[i]));
unmap_domain_page(ple);
}
@@ -306,12 +306,12 @@
mpl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
l2e_from_paddr(__pa(d->arch.mm_perdomain_pt),
- __PAGE_HYPERVISOR);
+ __PAGE_HYPERVISOR);
// map the phys_to_machine map into the Read-Only MPT space for this domain
mpl2e[l2_table_offset(RO_MPT_VIRT_START)] =
l2e_from_paddr(pagetable_get_paddr(d->arch.phys_table),
- __PAGE_HYPERVISOR);
+ __PAGE_HYPERVISOR);
// Don't (yet) have mappings for these...
// Don't want to accidentally see the idle_pg_table's linear mapping.
@@ -365,7 +365,7 @@
v->arch.monitor_table = mk_pagetable(0);
v->arch.monitor_vtable = 0;
}
-#endif
+#endif
static void
shadow_free_snapshot(struct domain *d, struct out_of_sync_entry *entry)
@@ -850,16 +850,16 @@
perfc_decr(free_l1_pages);
struct pfn_info *page = list_entry(list_ent, struct pfn_info, list);
- if (d->arch.ops->guest_paging_levels == PAGING_L2)
- {
+ if (d->arch.ops->guest_paging_levels == PAGING_L2)
+ {
#if CONFIG_PAGING_LEVELS >=4
- free_domheap_pages(page, SL1_ORDER);
+ free_domheap_pages(page, SL1_ORDER);
#else
- free_domheap_page(page);
+ free_domheap_page(page);
#endif
- }
- else
- free_domheap_page(page);
+ }
+ else
+ free_domheap_page(page);
}
shadow_audit(d, 0);
@@ -930,9 +930,9 @@
#if defined(CONFIG_PAGING_LEVELS)
if(!shadow_set_guest_paging_levels(d,
- CONFIG_PAGING_LEVELS)) {
- printk("Unsupported guest paging levels\n");
- domain_crash_synchronous(); /* need to take a clean path */
+ CONFIG_PAGING_LEVELS)) {
+ printk("Unsupported guest paging levels\n");
+ domain_crash_synchronous(); /* need to take a clean path */
}
#endif
@@ -1004,7 +1004,7 @@
goto nomem;
memset(d->arch.shadow_ht, 0,
- shadow_ht_buckets * sizeof(struct shadow_status));
+ shadow_ht_buckets * sizeof(struct shadow_status));
}
if ( new_modes & SHM_log_dirty )
@@ -1013,7 +1013,7 @@
d->arch.shadow_dirty_bitmap_size = (d->max_pages + 63) & ~63;
d->arch.shadow_dirty_bitmap =
xmalloc_array(unsigned long, d->arch.shadow_dirty_bitmap_size /
- (8 * sizeof(unsigned long)));
+ (8 * sizeof(unsigned long)));
if ( d->arch.shadow_dirty_bitmap == NULL )
{
d->arch.shadow_dirty_bitmap_size = 0;
@@ -1039,7 +1039,7 @@
// external guests provide their own memory for their P2M maps.
//
ASSERT( d == page_get_owner(
- &frame_table[pagetable_get_pfn(d->arch.phys_table)]) );
+ &frame_table[pagetable_get_pfn(d->arch.phys_table)]) );
}
}
@@ -1188,9 +1188,9 @@
chunk : (d->max_pages - i)) + 7) / 8;
if (copy_to_user(
- sc->dirty_bitmap + (i/(8*sizeof(unsigned long))),
- d->arch.shadow_dirty_bitmap +(i/(8*sizeof(unsigned long))),
- bytes))
+ sc->dirty_bitmap + (i/(8*sizeof(unsigned long))),
+ d->arch.shadow_dirty_bitmap +(i/(8*sizeof(unsigned long))),
+ bytes))
{
// copy_to_user can fail when copying to guest app memory.
// app should zero buffer after mallocing, and pin it
@@ -1474,8 +1474,8 @@
spl3e = (pgentry_64_t *) map_domain_page_with_cache(sl3mfn, cache);
validate_entry_change(d, (pgentry_64_t *) &gpde,
- &spl3e[(pa & ~PAGE_MASK) / sizeof(l3_pgentry_t)],
- shadow_type_to_level(PGT_l3_shadow));
+ &spl3e[(pa & ~PAGE_MASK) /
sizeof(l3_pgentry_t)],
+ shadow_type_to_level(PGT_l3_shadow));
unmap_domain_page_with_cache(spl3e, cache);
}
@@ -1502,8 +1502,8 @@
spl4e = (pgentry_64_t *)map_domain_page_with_cache(sl4mfn, cache);
validate_entry_change(d, (pgentry_64_t *)&gpde,
- &spl4e[(pa & ~PAGE_MASK) / sizeof(l4_pgentry_t)],
- shadow_type_to_level(PGT_l4_shadow));
+ &spl4e[(pa & ~PAGE_MASK) /
sizeof(l4_pgentry_t)],
+ shadow_type_to_level(PGT_l4_shadow));
unmap_domain_page_with_cache(spl4e, cache);
}
@@ -1619,32 +1619,32 @@
}
static u32 remove_all_access_in_page(
- struct domain *d, unsigned long l1mfn, unsigned long forbidden_gmfn)
+ struct domain *d, unsigned long l1mfn, unsigned long forbidden_gmfn)
{
l1_pgentry_t *pl1e = map_domain_page(l1mfn);
- l1_pgentry_t match;
+ l1_pgentry_t match, ol2e;
unsigned long flags = _PAGE_PRESENT;
int i;
u32 count = 0;
int is_l1_shadow =
- ((frame_table[l1mfn].u.inuse.type_info & PGT_type_mask) ==
- PGT_l1_shadow);
+ ((frame_table[l1mfn].u.inuse.type_info & PGT_type_mask) ==
+ PGT_l1_shadow);
match = l1e_from_pfn(forbidden_gmfn, flags);
for (i = 0; i < L1_PAGETABLE_ENTRIES; i++)
{
- if ( unlikely(!l1e_has_changed(pl1e[i], match, flags) == 0) )
- {
- l1_pgentry_t ol2e = pl1e[i];
- pl1e[i] = l1e_empty();
- count++;
-
- if ( is_l1_shadow )
- shadow_put_page_from_l1e(ol2e, d);
- else /* must be an hl2 page */
- put_page(&frame_table[forbidden_gmfn]);
- }
+ if ( l1e_has_changed(pl1e[i], match, flags) )
+ continue;
+
+ ol2e = pl1e[i];
+ pl1e[i] = l1e_empty();
+ count++;
+
+ if ( is_l1_shadow )
+ shadow_put_page_from_l1e(ol2e, d);
+ else /* must be an hl2 page */
+ put_page(&frame_table[forbidden_gmfn]);
}
unmap_domain_page(pl1e);
@@ -1671,19 +1671,19 @@
{
switch (a->gpfn_and_flags & PGT_type_mask)
{
- case PGT_l1_shadow:
- case PGT_l2_shadow:
- case PGT_l3_shadow:
- case PGT_l4_shadow:
- case PGT_hl2_shadow:
- count += remove_all_access_in_page(d, a->smfn,
forbidden_gmfn);
- break;
- case PGT_snapshot:
- case PGT_writable_pred:
- // these can't hold refs to the forbidden page
- break;
- default:
- BUG();
+ case PGT_l1_shadow:
+ case PGT_l2_shadow:
+ case PGT_l3_shadow:
+ case PGT_l4_shadow:
+ case PGT_hl2_shadow:
+ count += remove_all_access_in_page(d, a->smfn, forbidden_gmfn);
+ break;
+ case PGT_snapshot:
+ case PGT_writable_pred:
+ // these can't hold refs to the forbidden page
+ break;
+ default:
+ BUG();
}
a = a->next;
@@ -1694,29 +1694,29 @@
}
void shadow_drop_references(
- struct domain *d, struct pfn_info *page)
+ struct domain *d, struct pfn_info *page)
{
if ( likely(!shadow_mode_refcounts(d)) ||
- ((page->u.inuse.type_info & PGT_count_mask) == 0) )
+ ((page->u.inuse.type_info & PGT_count_mask) == 0) )
return;
/* XXX This needs more thought... */
printk("%s: needing to call __shadow_remove_all_access for mfn=%lx\n",
- __func__, page_to_pfn(page));
+ __func__, page_to_pfn(page));
printk("Before: mfn=%lx c=%08x t=%" PRtype_info "\n", page_to_pfn(page),
- page->count_info, page->u.inuse.type_info);
+ page->count_info, page->u.inuse.type_info);
shadow_lock(d);
__shadow_remove_all_access(d, page_to_pfn(page));
shadow_unlock(d);
printk("After: mfn=%lx c=%08x t=%" PRtype_info "\n", page_to_pfn(page),
- page->count_info, page->u.inuse.type_info);
+ page->count_info, page->u.inuse.type_info);
}
/* XXX Needs more thought. Neither pretty nor fast: a place holder. */
void shadow_sync_and_drop_references(
- struct domain *d, struct pfn_info *page)
+ struct domain *d, struct pfn_info *page)
{
if ( likely(!shadow_mode_refcounts(d)) )
return;
@@ -1730,3 +1730,13 @@
shadow_unlock(d);
}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r d4d880fcef28 -r b35215021b32 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c Fri Sep 9 16:31:36 2005
+++ b/xen/arch/x86/traps.c Tue Sep 13 16:14:16 2005
@@ -106,7 +106,7 @@
#define ESP_BEFORE_EXCEPTION(regs) ((unsigned long *)®s->esp)
#else
#define stack_words_per_line 4
-#define ESP_BEFORE_EXCEPTION(regs) ((unsigned long *)regs->esp)
+#define ESP_BEFORE_EXCEPTION(regs) ((unsigned long *)regs->rsp)
#endif
int is_kernel_text(unsigned long addr)
@@ -238,7 +238,7 @@
unsigned long *stack = ESP_BEFORE_EXCEPTION(regs), addr;
int i;
- if ( GUEST_MODE(regs) )
+ if ( GUEST_CONTEXT(current, regs) )
return show_guest_stack(regs);
printk("Xen stack trace from "__OP"sp=%p:\n ", stack);
diff -r d4d880fcef28 -r b35215021b32 xen/arch/x86/vmx.c
--- a/xen/arch/x86/vmx.c Fri Sep 9 16:31:36 2005
+++ b/xen/arch/x86/vmx.c Tue Sep 13 16:14:16 2005
@@ -44,13 +44,13 @@
#include <public/io/ioreq.h>
+int hvm_enabled;
+
#ifdef CONFIG_VMX
int vmcs_size;
unsigned int opt_vmx_debug_level = 0;
integer_param("vmx_debug", opt_vmx_debug_level);
-
-extern int hvm_enabled;
#ifdef TRACE_BUFFER
static unsigned long trace_values[NR_CPUS][4];
@@ -122,37 +122,37 @@
struct vcpu *vc = current;
struct msr_state * msr = &vc->arch.arch_vmx.msr_content;
switch(regs->ecx){
- case MSR_EFER:
- msr_content = msr->msr_items[VMX_INDEX_MSR_EFER];
- VMX_DBG_LOG(DBG_LEVEL_2, "EFER msr_content %llx\n", (unsigned long
long)msr_content);
- if (test_bit(VMX_CPU_STATE_LME_ENABLED,
- &vc->arch.arch_vmx.cpu_state))
- msr_content |= 1 << _EFER_LME;
-
- if (VMX_LONG_GUEST(vc))
- msr_content |= 1 << _EFER_LMA;
- break;
- case MSR_FS_BASE:
- if (!(VMX_LONG_GUEST(vc)))
- /* XXX should it be GP fault */
- domain_crash();
- __vmread(GUEST_FS_BASE, &msr_content);
- break;
- case MSR_GS_BASE:
- if (!(VMX_LONG_GUEST(vc)))
- domain_crash();
- __vmread(GUEST_GS_BASE, &msr_content);
- break;
- case MSR_SHADOW_GS_BASE:
- msr_content = msr->shadow_gs;
- break;
+ case MSR_EFER:
+ msr_content = msr->msr_items[VMX_INDEX_MSR_EFER];
+ VMX_DBG_LOG(DBG_LEVEL_2, "EFER msr_content %llx\n", (unsigned long
long)msr_content);
+ if (test_bit(VMX_CPU_STATE_LME_ENABLED,
+ &vc->arch.arch_vmx.cpu_state))
+ msr_content |= 1 << _EFER_LME;
+
+ if (VMX_LONG_GUEST(vc))
+ msr_content |= 1 << _EFER_LMA;
+ break;
+ case MSR_FS_BASE:
+ if (!(VMX_LONG_GUEST(vc)))
+ /* XXX should it be GP fault */
+ domain_crash();
+ __vmread(GUEST_FS_BASE, &msr_content);
+ break;
+ case MSR_GS_BASE:
+ if (!(VMX_LONG_GUEST(vc)))
+ domain_crash();
+ __vmread(GUEST_GS_BASE, &msr_content);
+ break;
+ case MSR_SHADOW_GS_BASE:
+ msr_content = msr->shadow_gs;
+ break;
CASE_READ_MSR(STAR);
CASE_READ_MSR(LSTAR);
CASE_READ_MSR(CSTAR);
CASE_READ_MSR(SYSCALL_MASK);
- default:
- return 0;
+ default:
+ return 0;
}
VMX_DBG_LOG(DBG_LEVEL_2, "mode_do_msr_read: msr_content: %lx\n",
msr_content);
regs->eax = msr_content & 0xffffffff;
@@ -166,68 +166,68 @@
struct vcpu *vc = current;
struct msr_state * msr = &vc->arch.arch_vmx.msr_content;
struct msr_state * host_state =
- &percpu_msr[smp_processor_id()];
+ &percpu_msr[smp_processor_id()];
VMX_DBG_LOG(DBG_LEVEL_1, " mode_do_msr_write msr %lx msr_content %lx\n",
regs->ecx, msr_content);
switch (regs->ecx){
- case MSR_EFER:
- if ((msr_content & EFER_LME) ^
- test_bit(VMX_CPU_STATE_LME_ENABLED,
- &vc->arch.arch_vmx.cpu_state)){
- if (test_bit(VMX_CPU_STATE_PG_ENABLED,
- &vc->arch.arch_vmx.cpu_state) ||
- !test_bit(VMX_CPU_STATE_PAE_ENABLED,
- &vc->arch.arch_vmx.cpu_state)){
- vmx_inject_exception(vc, TRAP_gp_fault, 0);
- }
+ case MSR_EFER:
+ if ((msr_content & EFER_LME) ^
+ test_bit(VMX_CPU_STATE_LME_ENABLED,
+ &vc->arch.arch_vmx.cpu_state)){
+ if (test_bit(VMX_CPU_STATE_PG_ENABLED,
+ &vc->arch.arch_vmx.cpu_state) ||
+ !test_bit(VMX_CPU_STATE_PAE_ENABLED,
+ &vc->arch.arch_vmx.cpu_state)){
+ vmx_inject_exception(vc, TRAP_gp_fault, 0);
}
- if (msr_content & EFER_LME)
- set_bit(VMX_CPU_STATE_LME_ENABLED,
- &vc->arch.arch_vmx.cpu_state);
- /* No update for LME/LMA since it have no effect */
- msr->msr_items[VMX_INDEX_MSR_EFER] =
- msr_content;
- if (msr_content & ~(EFER_LME | EFER_LMA)){
- msr->msr_items[VMX_INDEX_MSR_EFER] = msr_content;
- if (!test_bit(VMX_INDEX_MSR_EFER, &msr->flags)){
- rdmsrl(MSR_EFER,
- host_state->msr_items[VMX_INDEX_MSR_EFER]);
- set_bit(VMX_INDEX_MSR_EFER, &host_state->flags);
- set_bit(VMX_INDEX_MSR_EFER, &msr->flags);
- wrmsrl(MSR_EFER, msr_content);
- }
+ }
+ if (msr_content & EFER_LME)
+ set_bit(VMX_CPU_STATE_LME_ENABLED,
+ &vc->arch.arch_vmx.cpu_state);
+ /* No update for LME/LMA since it have no effect */
+ msr->msr_items[VMX_INDEX_MSR_EFER] =
+ msr_content;
+ if (msr_content & ~(EFER_LME | EFER_LMA)){
+ msr->msr_items[VMX_INDEX_MSR_EFER] = msr_content;
+ if (!test_bit(VMX_INDEX_MSR_EFER, &msr->flags)){
+ rdmsrl(MSR_EFER,
+ host_state->msr_items[VMX_INDEX_MSR_EFER]);
+ set_bit(VMX_INDEX_MSR_EFER, &host_state->flags);
+ set_bit(VMX_INDEX_MSR_EFER, &msr->flags);
+ wrmsrl(MSR_EFER, msr_content);
}
- break;
-
- case MSR_FS_BASE:
- case MSR_GS_BASE:
- if (!(VMX_LONG_GUEST(vc)))
- domain_crash();
- if (!IS_CANO_ADDRESS(msr_content)){
- VMX_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write\n");
- vmx_inject_exception(vc, TRAP_gp_fault, 0);
- }
- if (regs->ecx == MSR_FS_BASE)
- __vmwrite(GUEST_FS_BASE, msr_content);
- else
- __vmwrite(GUEST_GS_BASE, msr_content);
- break;
-
- case MSR_SHADOW_GS_BASE:
- if (!(VMX_LONG_GUEST(vc)))
- domain_crash();
- vc->arch.arch_vmx.msr_content.shadow_gs = msr_content;
- wrmsrl(MSR_SHADOW_GS_BASE, msr_content);
- break;
-
- CASE_WRITE_MSR(STAR);
- CASE_WRITE_MSR(LSTAR);
- CASE_WRITE_MSR(CSTAR);
- CASE_WRITE_MSR(SYSCALL_MASK);
- default:
- return 0;
+ }
+ break;
+
+ case MSR_FS_BASE:
+ case MSR_GS_BASE:
+ if (!(VMX_LONG_GUEST(vc)))
+ domain_crash();
+ if (!IS_CANO_ADDRESS(msr_content)){
+ VMX_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write\n");
+ vmx_inject_exception(vc, TRAP_gp_fault, 0);
+ }
+ if (regs->ecx == MSR_FS_BASE)
+ __vmwrite(GUEST_FS_BASE, msr_content);
+ else
+ __vmwrite(GUEST_GS_BASE, msr_content);
+ break;
+
+ case MSR_SHADOW_GS_BASE:
+ if (!(VMX_LONG_GUEST(vc)))
+ domain_crash();
+ vc->arch.arch_vmx.msr_content.shadow_gs = msr_content;
+ wrmsrl(MSR_SHADOW_GS_BASE, msr_content);
+ break;
+
+ CASE_WRITE_MSR(STAR);
+ CASE_WRITE_MSR(LSTAR);
+ CASE_WRITE_MSR(CSTAR);
+ CASE_WRITE_MSR(SYSCALL_MASK);
+ default:
+ return 0;
}
return 1;
}
@@ -252,8 +252,8 @@
i = find_first_set_bit(guest_flags);
VMX_DBG_LOG(DBG_LEVEL_2,
- "restore guest's index %d msr %lx with %lx\n",
- i, (unsigned long) msr_data_index[i], (unsigned long)
guest_state->msr_items[i]);
+ "restore guest's index %d msr %lx with %lx\n",
+ i, (unsigned long) msr_data_index[i], (unsigned long)
guest_state->msr_items[i]);
set_bit(i, &host_state->flags);
wrmsrl(msr_data_index[i], guest_state->msr_items[i]);
clear_bit(i, &guest_flags);
@@ -309,8 +309,8 @@
if (eax & IA32_FEATURE_CONTROL_MSR_LOCK) {
if ((eax & IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON) == 0x0) {
- printk("VMX disabled by Feature Control MSR.\n");
- return 0;
+ printk("VMX disabled by Feature Control MSR.\n");
+ return 0;
}
}
else {
@@ -320,16 +320,16 @@
}
if (!check_vmx_controls(MONITOR_PIN_BASED_EXEC_CONTROLS,
- MSR_IA32_VMX_PINBASED_CTLS_MSR))
+ MSR_IA32_VMX_PINBASED_CTLS_MSR))
return 0;
if (!check_vmx_controls(MONITOR_CPU_BASED_EXEC_CONTROLS,
- MSR_IA32_VMX_PROCBASED_CTLS_MSR))
+ MSR_IA32_VMX_PROCBASED_CTLS_MSR))
return 0;
if (!check_vmx_controls(MONITOR_VM_EXIT_CONTROLS,
- MSR_IA32_VMX_EXIT_CTLS_MSR))
+ MSR_IA32_VMX_EXIT_CTLS_MSR))
return 0;
if (!check_vmx_controls(MONITOR_VM_ENTRY_CONTROLS,
- MSR_IA32_VMX_ENTRY_CTLS_MSR))
+ MSR_IA32_VMX_ENTRY_CTLS_MSR))
return 0;
set_in_cr4(X86_CR4_VMXE); /* Enable VMXE */
@@ -385,8 +385,8 @@
{
__vmread(GUEST_RIP, &eip);
VMX_DBG_LOG(DBG_LEVEL_VMMU,
- "vmx_do_page_fault = 0x%lx, eip = %lx, error_code = %lx",
- va, eip, (unsigned long)regs->error_code);
+ "vmx_do_page_fault = 0x%lx, eip = %lx, error_code = %lx",
+ va, eip, (unsigned long)regs->error_code);
}
#endif
@@ -478,8 +478,8 @@
regs->edx = (unsigned long) edx;
VMX_DBG_LOG(DBG_LEVEL_1,
- "vmx_vmexit_do_cpuid: eip: %lx, input: %lx, out:eax=%x, ebx=%x,
ecx=%x, edx=%x",
- eip, input, eax, ebx, ecx, edx);
+ "vmx_vmexit_do_cpuid: eip: %lx, input: %lx, out:eax=%x,
ebx=%x, ecx=%x, edx=%x",
+ eip, input, eax, ebx, ecx, edx);
}
@@ -607,7 +607,7 @@
}
void send_pio_req(struct cpu_user_regs *regs, unsigned long port,
- unsigned long count, int size, long value, int dir, int pvalid)
+ unsigned long count, int size, long value, int dir, int
pvalid)
{
struct vcpu *v = current;
vcpu_iodata_t *vio;
@@ -620,8 +620,8 @@
}
if (test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags)) {
- printf("VMX I/O has not yet completed\n");
- domain_crash_synchronous();
+ printf("VMX I/O has not yet completed\n");
+ domain_crash_synchronous();
}
set_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags);
@@ -656,7 +656,7 @@
}
static void vmx_io_instruction(struct cpu_user_regs *regs,
- unsigned long exit_qualification, unsigned long inst_len)
+ unsigned long exit_qualification, unsigned long
inst_len)
{
struct mi_per_cpu_info *mpcip;
unsigned long eip, cs, eflags;
@@ -686,10 +686,10 @@
dir = test_bit(3, &exit_qualification); /* direction */
if (test_bit(4, &exit_qualification)) { /* string instruction */
- unsigned long addr, count = 1;
- int sign = regs->eflags & EF_DF ? -1 : 1;
-
- __vmread(GUEST_LINEAR_ADDRESS, &addr);
+ unsigned long addr, count = 1;
+ int sign = regs->eflags & EF_DF ? -1 : 1;
+
+ __vmread(GUEST_LINEAR_ADDRESS, &addr);
/*
* In protected mode, guest linear address is invalid if the
@@ -699,35 +699,35 @@
addr = dir == IOREQ_WRITE ? regs->esi : regs->edi;
if (test_bit(5, &exit_qualification)) { /* "rep" prefix */
- mpcip->flags |= REPZ;
- count = vm86 ? regs->ecx & 0xFFFF : regs->ecx;
- }
-
- /*
- * Handle string pio instructions that cross pages or that
- * are unaligned. See the comments in vmx_platform.c/handle_mmio()
- */
- if ((addr & PAGE_MASK) != ((addr + size - 1) & PAGE_MASK)) {
- unsigned long value = 0;
-
- mpcip->flags |= OVERLAP;
- if (dir == IOREQ_WRITE)
- vmx_copy(&value, addr, size, VMX_COPY_IN);
- send_pio_req(regs, port, 1, size, value, dir, 0);
- } else {
- if ((addr & PAGE_MASK) != ((addr + count * size - 1) & PAGE_MASK)) {
+ mpcip->flags |= REPZ;
+ count = vm86 ? regs->ecx & 0xFFFF : regs->ecx;
+ }
+
+ /*
+ * Handle string pio instructions that cross pages or that
+ * are unaligned. See the comments in vmx_platform.c/handle_mmio()
+ */
+ if ((addr & PAGE_MASK) != ((addr + size - 1) & PAGE_MASK)) {
+ unsigned long value = 0;
+
+ mpcip->flags |= OVERLAP;
+ if (dir == IOREQ_WRITE)
+ vmx_copy(&value, addr, size, VMX_COPY_IN);
+ send_pio_req(regs, port, 1, size, value, dir, 0);
+ } else {
+ if ((addr & PAGE_MASK) != ((addr + count * size - 1) & PAGE_MASK))
{
if (sign > 0)
count = (PAGE_SIZE - (addr & ~PAGE_MASK)) / size;
else
count = (addr & ~PAGE_MASK) / size;
- } else
- __update_guest_eip(inst_len);
-
- send_pio_req(regs, port, count, size, addr, dir, 1);
- }
+ } else
+ __update_guest_eip(inst_len);
+
+ send_pio_req(regs, port, count, size, addr, dir, 1);
+ }
} else {
__update_guest_eip(inst_len);
- send_pio_req(regs, port, 1, size, regs->eax, dir, 0);
+ send_pio_req(regs, port, 1, size, regs->eax, dir, 0);
}
}
@@ -739,30 +739,30 @@
int count;
while (size > 0) {
- count = PAGE_SIZE - (laddr & ~PAGE_MASK);
- if (count > size)
- count = size;
-
- if (vmx_paging_enabled(current)) {
- gpa = gva_to_gpa(laddr);
- mfn = get_mfn_from_pfn(gpa >> PAGE_SHIFT);
- } else
- mfn = get_mfn_from_pfn(laddr >> PAGE_SHIFT);
- if (mfn == INVALID_MFN)
- return 0;
-
- addr = (char *)map_domain_page(mfn) + (laddr & ~PAGE_MASK);
-
- if (dir == VMX_COPY_IN)
- memcpy(buf, addr, count);
- else
- memcpy(addr, buf, count);
-
- unmap_domain_page(addr);
-
- laddr += count;
- buf += count;
- size -= count;
+ count = PAGE_SIZE - (laddr & ~PAGE_MASK);
+ if (count > size)
+ count = size;
+
+ if (vmx_paging_enabled(current)) {
+ gpa = gva_to_gpa(laddr);
+ mfn = get_mfn_from_pfn(gpa >> PAGE_SHIFT);
+ } else
+ mfn = get_mfn_from_pfn(laddr >> PAGE_SHIFT);
+ if (mfn == INVALID_MFN)
+ return 0;
+
+ addr = (char *)map_domain_page(mfn) + (laddr & ~PAGE_MASK);
+
+ if (dir == VMX_COPY_IN)
+ memcpy(buf, addr, count);
+ else
+ memcpy(addr, buf, count);
+
+ unmap_domain_page(addr);
+
+ laddr += count;
+ buf += count;
+ size -= count;
}
return 1;
@@ -846,47 +846,47 @@
error |= __vmwrite(CR0_READ_SHADOW, c->cr0);
if (!vmx_paging_enabled(d)) {
- VMX_DBG_LOG(DBG_LEVEL_VMMU, "switching to vmxassist. use phys table");
- __vmwrite(GUEST_CR3, pagetable_get_paddr(d->domain->arch.phys_table));
+ VMX_DBG_LOG(DBG_LEVEL_VMMU, "switching to vmxassist. use phys table");
+ __vmwrite(GUEST_CR3, pagetable_get_paddr(d->domain->arch.phys_table));
goto skip_cr3;
}
if (c->cr3 == d->arch.arch_vmx.cpu_cr3) {
- /*
- * This is simple TLB flush, implying the guest has
- * removed some translation or changed page attributes.
- * We simply invalidate the shadow.
- */
- mfn = get_mfn_from_pfn(c->cr3 >> PAGE_SHIFT);
- if (mfn != pagetable_get_pfn(d->arch.guest_table)) {
- printk("Invalid CR3 value=%x", c->cr3);
- domain_crash_synchronous();
- return 0;
- }
- shadow_sync_all(d->domain);
+ /*
+ * This is simple TLB flush, implying the guest has
+ * removed some translation or changed page attributes.
+ * We simply invalidate the shadow.
+ */
+ mfn = get_mfn_from_pfn(c->cr3 >> PAGE_SHIFT);
+ if (mfn != pagetable_get_pfn(d->arch.guest_table)) {
+ printk("Invalid CR3 value=%x", c->cr3);
+ domain_crash_synchronous();
+ return 0;
+ }
+ shadow_sync_all(d->domain);
} else {
- /*
- * If different, make a shadow. Check if the PDBR is valid
- * first.
- */
- VMX_DBG_LOG(DBG_LEVEL_VMMU, "CR3 c->cr3 = %x", c->cr3);
- if ((c->cr3 >> PAGE_SHIFT) > d->domain->max_pages) {
- printk("Invalid CR3 value=%x", c->cr3);
- domain_crash_synchronous();
- return 0;
- }
- mfn = get_mfn_from_pfn(c->cr3 >> PAGE_SHIFT);
- d->arch.guest_table = mk_pagetable(mfn << PAGE_SHIFT);
- update_pagetables(d);
- /*
- * arch.shadow_table should now hold the next CR3 for shadow
- */
- d->arch.arch_vmx.cpu_cr3 = c->cr3;
- VMX_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %x", c->cr3);
- __vmwrite(GUEST_CR3, pagetable_get_paddr(d->arch.shadow_table));
- }
-
-skip_cr3:
+ /*
+ * If different, make a shadow. Check if the PDBR is valid
+ * first.
+ */
+ VMX_DBG_LOG(DBG_LEVEL_VMMU, "CR3 c->cr3 = %x", c->cr3);
+ if ((c->cr3 >> PAGE_SHIFT) > d->domain->max_pages) {
+ printk("Invalid CR3 value=%x", c->cr3);
+ domain_crash_synchronous();
+ return 0;
+ }
+ mfn = get_mfn_from_pfn(c->cr3 >> PAGE_SHIFT);
+ d->arch.guest_table = mk_pagetable(mfn << PAGE_SHIFT);
+ update_pagetables(d);
+ /*
+ * arch.shadow_table should now hold the next CR3 for shadow
+ */
+ d->arch.arch_vmx.cpu_cr3 = c->cr3;
+ VMX_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %x", c->cr3);
+ __vmwrite(GUEST_CR3, pagetable_get_paddr(d->arch.shadow_table));
+ }
+
+ skip_cr3:
error |= __vmread(CR4_READ_SHADOW, &old_cr4);
error |= __vmwrite(GUEST_CR4, (c->cr4 | VMX_CR4_HOST_MASK));
@@ -952,59 +952,59 @@
/* make sure vmxassist exists (this is not an error) */
if (!vmx_copy(&magic, VMXASSIST_MAGIC_OFFSET, sizeof(magic), VMX_COPY_IN))
- return 0;
+ return 0;
if (magic != VMXASSIST_MAGIC)
- return 0;
+ return 0;
switch (mode) {
- /*
- * Transfer control to vmxassist.
- * Store the current context in VMXASSIST_OLD_CONTEXT and load
- * the new VMXASSIST_NEW_CONTEXT context. This context was created
- * by vmxassist and will transfer control to it.
- */
+ /*
+ * Transfer control to vmxassist.
+ * Store the current context in VMXASSIST_OLD_CONTEXT and load
+ * the new VMXASSIST_NEW_CONTEXT context. This context was created
+ * by vmxassist and will transfer control to it.
+ */
case VMX_ASSIST_INVOKE:
- /* save the old context */
- if (!vmx_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), VMX_COPY_IN))
- goto error;
- if (cp != 0) {
- if (!vmx_world_save(d, &c))
- goto error;
- if (!vmx_copy(&c, cp, sizeof(c), VMX_COPY_OUT))
- goto error;
- }
-
- /* restore the new context, this should activate vmxassist */
- if (!vmx_copy(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp), VMX_COPY_IN))
- goto error;
- if (cp != 0) {
+ /* save the old context */
+ if (!vmx_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), VMX_COPY_IN))
+ goto error;
+ if (cp != 0) {
+ if (!vmx_world_save(d, &c))
+ goto error;
+ if (!vmx_copy(&c, cp, sizeof(c), VMX_COPY_OUT))
+ goto error;
+ }
+
+ /* restore the new context, this should activate vmxassist */
+ if (!vmx_copy(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp), VMX_COPY_IN))
+ goto error;
+ if (cp != 0) {
if (!vmx_copy(&c, cp, sizeof(c), VMX_COPY_IN))
- goto error;
- if (!vmx_world_restore(d, &c))
- goto error;
- return 1;
- }
- break;
-
- /*
- * Restore the VMXASSIST_OLD_CONTEXT that was saved by VMX_ASSIST_INVOKE
- * above.
- */
+ goto error;
+ if (!vmx_world_restore(d, &c))
+ goto error;
+ return 1;
+ }
+ break;
+
+ /*
+ * Restore the VMXASSIST_OLD_CONTEXT that was saved by
VMX_ASSIST_INVOKE
+ * above.
+ */
case VMX_ASSIST_RESTORE:
- /* save the old context */
- if (!vmx_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), VMX_COPY_IN))
- goto error;
- if (cp != 0) {
+ /* save the old context */
+ if (!vmx_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), VMX_COPY_IN))
+ goto error;
+ if (cp != 0) {
if (!vmx_copy(&c, cp, sizeof(c), VMX_COPY_IN))
- goto error;
- if (!vmx_world_restore(d, &c))
- goto error;
- return 1;
- }
- break;
- }
-
-error:
+ goto error;
+ if (!vmx_world_restore(d, &c))
+ goto error;
+ return 1;
+ }
+ break;
+ }
+
+ error:
printf("Failed to transfer to vmxassist\n");
domain_crash_synchronous();
return 0;
@@ -1031,7 +1031,7 @@
* The guest CR3 must be pointing to the guest physical.
*/
if ( !VALID_MFN(mfn = get_mfn_from_pfn(
- d->arch.arch_vmx.cpu_cr3 >> PAGE_SHIFT)) ||
+ d->arch.arch_vmx.cpu_cr3 >> PAGE_SHIFT)) ||
!get_page(pfn_to_page(mfn), d->domain) )
{
printk("Invalid CR3 value = %lx", d->arch.arch_vmx.cpu_cr3);
@@ -1040,18 +1040,18 @@
#if defined(__x86_64__)
if (test_bit(VMX_CPU_STATE_LME_ENABLED,
- &d->arch.arch_vmx.cpu_state) &&
- !test_bit(VMX_CPU_STATE_PAE_ENABLED,
- &d->arch.arch_vmx.cpu_state)){
+ &d->arch.arch_vmx.cpu_state) &&
+ !test_bit(VMX_CPU_STATE_PAE_ENABLED,
+ &d->arch.arch_vmx.cpu_state)){
VMX_DBG_LOG(DBG_LEVEL_1, "Enable paging before PAE enable\n");
vmx_inject_exception(d, TRAP_gp_fault, 0);
}
if (test_bit(VMX_CPU_STATE_LME_ENABLED,
- &d->arch.arch_vmx.cpu_state)){
+ &d->arch.arch_vmx.cpu_state)){
/* Here the PAE is should to be opened */
VMX_DBG_LOG(DBG_LEVEL_1, "Enable the Long mode\n");
set_bit(VMX_CPU_STATE_LMA_ENABLED,
- &d->arch.arch_vmx.cpu_state);
+ &d->arch.arch_vmx.cpu_state);
__vmread(VM_ENTRY_CONTROLS, &vm_entry_value);
vm_entry_value |= VM_ENTRY_CONTROLS_IA32E_MODE;
__vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
@@ -1073,20 +1073,15 @@
#endif
}
- unsigned long crn;
+ unsigned long crn;
/* update CR4's PAE if needed */
__vmread(GUEST_CR4, &crn);
if ( (!(crn & X86_CR4_PAE)) &&
- test_bit(VMX_CPU_STATE_PAE_ENABLED,
- &d->arch.arch_vmx.cpu_state)){
+ test_bit(VMX_CPU_STATE_PAE_ENABLED,
+ &d->arch.arch_vmx.cpu_state)){
VMX_DBG_LOG(DBG_LEVEL_1, "enable PAE on cr4\n");
__vmwrite(GUEST_CR4, crn | X86_CR4_PAE);
}
-#elif defined( __i386__)
- unsigned long old_base_mfn;
- old_base_mfn = pagetable_get_pfn(d->arch.guest_table);
- if (old_base_mfn)
- put_page(pfn_to_page(old_base_mfn));
#endif
/*
* Now arch.guest_table points to machine physical.
@@ -1095,14 +1090,14 @@
update_pagetables(d);
VMX_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
- (unsigned long) (mfn << PAGE_SHIFT));
+ (unsigned long) (mfn << PAGE_SHIFT));
__vmwrite(GUEST_CR3, pagetable_get_paddr(d->arch.shadow_table));
/*
* arch->shadow_table should hold the next CR3 for shadow
*/
VMX_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx, mfn = %lx",
- d->arch.arch_vmx.cpu_cr3, mfn);
+ d->arch.arch_vmx.cpu_cr3, mfn);
}
/*
@@ -1129,29 +1124,29 @@
__vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
}
}
- __vmread(GUEST_RIP, &eip);
- VMX_DBG_LOG(DBG_LEVEL_1,
- "Disabling CR0.PE at %%eip 0x%lx\n", eip);
- if (vmx_assist(d, VMX_ASSIST_INVOKE)) {
- set_bit(VMX_CPU_STATE_ASSIST_ENABLED, &d->arch.arch_vmx.cpu_state);
- __vmread(GUEST_RIP, &eip);
- VMX_DBG_LOG(DBG_LEVEL_1,
- "Transfering control to vmxassist %%eip 0x%lx\n", eip);
- return 0; /* do not update eip! */
- }
+ __vmread(GUEST_RIP, &eip);
+ VMX_DBG_LOG(DBG_LEVEL_1,
+ "Disabling CR0.PE at %%eip 0x%lx\n", eip);
+ if (vmx_assist(d, VMX_ASSIST_INVOKE)) {
+ set_bit(VMX_CPU_STATE_ASSIST_ENABLED, &d->arch.arch_vmx.cpu_state);
+ __vmread(GUEST_RIP, &eip);
+ VMX_DBG_LOG(DBG_LEVEL_1,
+ "Transfering control to vmxassist %%eip 0x%lx\n", eip);
+ return 0; /* do not update eip! */
+ }
} else if (test_bit(VMX_CPU_STATE_ASSIST_ENABLED,
- &d->arch.arch_vmx.cpu_state)) {
- __vmread(GUEST_RIP, &eip);
- VMX_DBG_LOG(DBG_LEVEL_1,
- "Enabling CR0.PE at %%eip 0x%lx\n", eip);
- if (vmx_assist(d, VMX_ASSIST_RESTORE)) {
- clear_bit(VMX_CPU_STATE_ASSIST_ENABLED,
- &d->arch.arch_vmx.cpu_state);
- __vmread(GUEST_RIP, &eip);
- VMX_DBG_LOG(DBG_LEVEL_1,
- "Restoring to %%eip 0x%lx\n", eip);
- return 0; /* do not update eip! */
- }
+ &d->arch.arch_vmx.cpu_state)) {
+ __vmread(GUEST_RIP, &eip);
+ VMX_DBG_LOG(DBG_LEVEL_1,
+ "Enabling CR0.PE at %%eip 0x%lx\n", eip);
+ if (vmx_assist(d, VMX_ASSIST_RESTORE)) {
+ clear_bit(VMX_CPU_STATE_ASSIST_ENABLED,
+ &d->arch.arch_vmx.cpu_state);
+ __vmread(GUEST_RIP, &eip);
+ VMX_DBG_LOG(DBG_LEVEL_1,
+ "Restoring to %%eip 0x%lx\n", eip);
+ return 0; /* do not update eip! */
+ }
}
return 1;
@@ -1198,8 +1193,8 @@
CASE_GET_REG(ESI, esi);
CASE_GET_REG(EDI, edi);
CASE_EXTEND_GET_REG
- case REG_ESP:
- __vmread(GUEST_RSP, &value);
+ case REG_ESP:
+ __vmread(GUEST_RSP, &value);
break;
default:
printk("invalid gp: %d\n", gp);
@@ -1212,7 +1207,7 @@
switch(cr) {
case 0:
{
- return vmx_set_cr0(value);
+ return vmx_set_cr0(value);
}
case 3:
{
@@ -1262,7 +1257,7 @@
*/
d->arch.arch_vmx.cpu_cr3 = value;
VMX_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx",
- value);
+ value);
__vmwrite(GUEST_CR3, pagetable_get_paddr(d->arch.shadow_table));
}
break;
@@ -1332,8 +1327,8 @@
CASE_SET_REG(ESI, esi);
CASE_SET_REG(EDI, edi);
CASE_EXTEND_SET_REG
- case REG_ESP:
- __vmwrite(GUEST_RSP, value);
+ case REG_ESP:
+ __vmwrite(GUEST_RSP, value);
regs->esp = value;
break;
default:
@@ -1381,9 +1376,9 @@
case TYPE_LMSW:
TRACE_VMEXIT(1,TYPE_LMSW);
__vmread(CR0_READ_SHADOW, &value);
- value = (value & ~0xF) |
- (((exit_qualification & LMSW_SOURCE_DATA) >> 16) & 0xF);
- return vmx_set_cr0(value);
+ value = (value & ~0xF) |
+ (((exit_qualification & LMSW_SOURCE_DATA) >> 16) & 0xF);
+ return vmx_set_cr0(value);
break;
default:
__vmx_bug(regs);
@@ -1394,28 +1389,30 @@
static inline void vmx_do_msr_read(struct cpu_user_regs *regs)
{
+ u64 msr_content = 0;
+
VMX_DBG_LOG(DBG_LEVEL_1, "vmx_do_msr_read: ecx=%lx, eax=%lx, edx=%lx",
(unsigned long)regs->ecx, (unsigned long)regs->eax,
(unsigned long)regs->edx);
switch (regs->ecx) {
- case MSR_IA32_SYSENTER_CS:
- __vmread(GUEST_SYSENTER_CS, ®s->eax);
- regs->edx = 0;
- break;
- case MSR_IA32_SYSENTER_ESP:
- __vmread(GUEST_SYSENTER_ESP, ®s->eax);
- regs->edx = 0;
- break;
- case MSR_IA32_SYSENTER_EIP:
- __vmread(GUEST_SYSENTER_EIP, ®s->eax);
- regs->edx = 0;
- break;
- default:
- if(long_mode_do_msr_read(regs))
- return;
- rdmsr_user(regs->ecx, regs->eax, regs->edx);
- break;
- }
+ case MSR_IA32_SYSENTER_CS:
+ __vmread(GUEST_SYSENTER_CS, (u32 *)&msr_content);
+ break;
+ case MSR_IA32_SYSENTER_ESP:
+ __vmread(GUEST_SYSENTER_ESP, &msr_content);
+ break;
+ case MSR_IA32_SYSENTER_EIP:
+ __vmread(GUEST_SYSENTER_EIP, &msr_content);
+ break;
+ default:
+ if(long_mode_do_msr_read(regs))
+ return;
+ rdmsr_user(regs->ecx, regs->eax, regs->edx);
+ break;
+ }
+
+ regs->eax = msr_content & 0xFFFFFFFF;
+ regs->edx = msr_content >> 32;
VMX_DBG_LOG(DBG_LEVEL_1, "vmx_do_msr_read returns: "
"ecx=%lx, eax=%lx, edx=%lx",
@@ -1425,22 +1422,27 @@
static inline void vmx_do_msr_write(struct cpu_user_regs *regs)
{
+ u64 msr_content;
+
VMX_DBG_LOG(DBG_LEVEL_1, "vmx_do_msr_write: ecx=%lx, eax=%lx, edx=%lx",
(unsigned long)regs->ecx, (unsigned long)regs->eax,
(unsigned long)regs->edx);
+
+ msr_content = (regs->eax & 0xFFFFFFFF) | ((u64)regs->edx << 32);
+
switch (regs->ecx) {
- case MSR_IA32_SYSENTER_CS:
- __vmwrite(GUEST_SYSENTER_CS, regs->eax);
- break;
- case MSR_IA32_SYSENTER_ESP:
- __vmwrite(GUEST_SYSENTER_ESP, regs->eax);
- break;
- case MSR_IA32_SYSENTER_EIP:
- __vmwrite(GUEST_SYSENTER_EIP, regs->eax);
- break;
- default:
- long_mode_do_msr_write(regs);
- break;
+ case MSR_IA32_SYSENTER_CS:
+ __vmwrite(GUEST_SYSENTER_CS, msr_content);
+ break;
+ case MSR_IA32_SYSENTER_ESP:
+ __vmwrite(GUEST_SYSENTER_ESP, msr_content);
+ break;
+ case MSR_IA32_SYSENTER_EIP:
+ __vmwrite(GUEST_SYSENTER_EIP, msr_content);
+ break;
+ default:
+ long_mode_do_msr_write(regs);
+ break;
}
VMX_DBG_LOG(DBG_LEVEL_1, "vmx_do_msr_write returns: "
@@ -1484,28 +1486,28 @@
local_irq_disable();
switch(vector) {
- case LOCAL_TIMER_VECTOR:
- smp_apic_timer_interrupt(regs);
- break;
- case EVENT_CHECK_VECTOR:
- smp_event_check_interrupt();
- break;
- case INVALIDATE_TLB_VECTOR:
- smp_invalidate_interrupt();
- break;
- case CALL_FUNCTION_VECTOR:
- smp_call_function_interrupt();
- break;
- case SPURIOUS_APIC_VECTOR:
- smp_spurious_interrupt(regs);
- break;
- case ERROR_APIC_VECTOR:
- smp_error_interrupt(regs);
- break;
- default:
- regs->entry_vector = vector;
- do_IRQ(regs);
- break;
+ case LOCAL_TIMER_VECTOR:
+ smp_apic_timer_interrupt(regs);
+ break;
+ case EVENT_CHECK_VECTOR:
+ smp_event_check_interrupt();
+ break;
+ case INVALIDATE_TLB_VECTOR:
+ smp_invalidate_interrupt();
+ break;
+ case CALL_FUNCTION_VECTOR:
+ smp_call_function_interrupt();
+ break;
+ case SPURIOUS_APIC_VECTOR:
+ smp_spurious_interrupt(regs);
+ break;
+ case ERROR_APIC_VECTOR:
+ smp_error_interrupt(regs);
+ break;
+ default:
+ regs->entry_vector = vector;
+ do_IRQ(regs);
+ break;
}
}
@@ -1597,17 +1599,17 @@
__vmread(IDT_VECTORING_INFO_FIELD, &idtv_info_field);
if (idtv_info_field & INTR_INFO_VALID_MASK) {
- __vmwrite(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field);
-
- __vmread(VM_EXIT_INSTRUCTION_LEN, &inst_len);
- if (inst_len >= 1 && inst_len <= 15)
- __vmwrite(VM_ENTRY_INSTRUCTION_LEN, inst_len);
-
- if (idtv_info_field & 0x800) { /* valid error code */
- unsigned long error_code;
- __vmread(IDT_VECTORING_ERROR_CODE, &error_code);
- __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
- }
+ __vmwrite(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field);
+
+ __vmread(VM_EXIT_INSTRUCTION_LEN, &inst_len);
+ if (inst_len >= 1 && inst_len <= 15)
+ __vmwrite(VM_ENTRY_INSTRUCTION_LEN, inst_len);
+
+ if (idtv_info_field & 0x800) { /* valid error code */
+ unsigned long error_code;
+ __vmread(IDT_VECTORING_ERROR_CODE, &error_code);
+ __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
+ }
VMX_DBG_LOG(DBG_LEVEL_1, "idtv_info_field=%x", idtv_info_field);
}
@@ -1645,7 +1647,7 @@
__vmx_bug(®s);
vector &= 0xff;
- TRACE_VMEXIT(1,vector);
+ TRACE_VMEXIT(1,vector);
perfc_incra(cause_vector, vector);
TRACE_3D(TRC_VMX_VECTOR, v->domain->domain_id, eip, vector);
@@ -1691,8 +1693,8 @@
__vmread(EXIT_QUALIFICATION, &va);
__vmread(VM_EXIT_INTR_ERROR_CODE, ®s.error_code);
- TRACE_VMEXIT(3,regs.error_code);
- TRACE_VMEXIT(4,va);
+ TRACE_VMEXIT(3,regs.error_code);
+ TRACE_VMEXIT(4,va);
VMX_DBG_LOG(DBG_LEVEL_VMMU,
"eax=%lx, ebx=%lx, ecx=%lx, edx=%lx, esi=%lx, edi=%lx",
@@ -1725,7 +1727,7 @@
break;
case EXIT_REASON_PENDING_INTERRUPT:
__vmwrite(CPU_BASED_VM_EXEC_CONTROL,
- MONITOR_CPU_BASED_EXEC_CONTROLS);
+ MONITOR_CPU_BASED_EXEC_CONTROLS);
break;
case EXIT_REASON_TASK_SWITCH:
__vmx_bug(®s);
@@ -1765,10 +1767,10 @@
__vmread(EXIT_QUALIFICATION, &exit_qualification);
VMX_DBG_LOG(DBG_LEVEL_1, "eip = %lx, inst_len =%lx, exit_qualification
= %lx",
- eip, inst_len, exit_qualification);
+ eip, inst_len, exit_qualification);
if (vmx_cr_access(exit_qualification, ®s))
- __update_guest_eip(inst_len);
- TRACE_VMEXIT(3,regs.error_code);
+ __update_guest_eip(inst_len);
+ TRACE_VMEXIT(3,regs.error_code);
TRACE_VMEXIT(4,exit_qualification);
break;
}
@@ -1821,8 +1823,8 @@
asmlinkage void trace_vmentry (void)
{
TRACE_5D(TRC_VMENTRY,trace_values[current->processor][0],
-
trace_values[current->processor][1],trace_values[current->processor][2],
-
trace_values[current->processor][3],trace_values[current->processor][4]);
+
trace_values[current->processor][1],trace_values[current->processor][2],
+
trace_values[current->processor][3],trace_values[current->processor][4]);
TRACE_VMEXIT(0,9);
TRACE_VMEXIT(1,9);
TRACE_VMEXIT(2,9);
diff -r d4d880fcef28 -r b35215021b32 xen/arch/x86/vmx_intercept.c
--- a/xen/arch/x86/vmx_intercept.c Fri Sep 9 16:31:36 2005
+++ b/xen/arch/x86/vmx_intercept.c Tue Sep 13 16:14:16 2005
@@ -45,8 +45,8 @@
addr = handler->hdl_list[i].addr;
offset = handler->hdl_list[i].offset;
if (p->addr >= addr &&
- p->addr < addr + offset)
- return handler->hdl_list[i].action(p);
+ p->addr < addr + offset)
+ return handler->hdl_list[i].action(p);
}
return 0;
}
@@ -172,22 +172,22 @@
if (p->size != 1 ||
p->pdata_valid ||
- p->type != IOREQ_TYPE_PIO)
+ p->type != IOREQ_TYPE_PIO)
return 0;
if (p->addr == PIT_MODE &&
- p->dir == 0 && /* write */
- ((p->u.data >> 4) & 0x3) == 0 && /* latch command */
+ p->dir == 0 && /* write */
+ ((p->u.data >> 4) & 0x3) == 0 && /* latch command */
((p->u.data >> 6) & 0x3) == (vpit->channel)) {/* right channel */
pit_latch_io(vpit);
- return 1;
+ return 1;
}
if (p->addr == (PIT_CH0 + vpit->channel) &&
- p->dir == 1) { /* read */
+ p->dir == 1) { /* read */
p->u.data = pit_read_io(vpit);
resume_pit_io(p);
- return 1;
+ return 1;
}
return 0;
@@ -253,8 +253,8 @@
vpit->channel = ((p->u.data >> 24) & 0x3);
vpit->first_injected = 0;
- vpit->count_LSB_latched = 0;
- vpit->count_MSB_latched = 0;
+ vpit->count_LSB_latched = 0;
+ vpit->count_MSB_latched = 0;
rw_mode = ((p->u.data >> 26) & 0x3);
switch(rw_mode) {
@@ -280,9 +280,19 @@
/*restore the state*/
p->state = STATE_IORESP_READY;
- /* register handler to intercept the PIT io when vm_exit */
+ /* register handler to intercept the PIT io when vm_exit */
if (!reinit)
- register_portio_handler(0x40, 4, intercept_pit_io);
+ register_portio_handler(0x40, 4, intercept_pit_io);
}
}
#endif /* CONFIG_VMX */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r d4d880fcef28 -r b35215021b32 xen/arch/x86/vmx_io.c
--- a/xen/arch/x86/vmx_io.c Fri Sep 9 16:31:36 2005
+++ b/xen/arch/x86/vmx_io.c Tue Sep 13 16:14:16 2005
@@ -16,6 +16,7 @@
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
*/
+
#include <xen/config.h>
#include <xen/init.h>
#include <xen/mm.h>
@@ -99,7 +100,6 @@
printk("Error: size:%x, index:%x are invalid!\n", size, index);
domain_crash_synchronous();
break;
-
}
break;
case WORD:
@@ -199,24 +199,24 @@
static inline void __set_reg_value(unsigned long *reg, int size, long value)
{
switch (size) {
- case BYTE_64:
- *reg &= ~0xFF;
- *reg |= (value & 0xFF);
- break;
- case WORD:
- *reg &= ~0xFFFF;
- *reg |= (value & 0xFFFF);
- break;
- case LONG:
- *reg &= ~0xFFFFFFFF;
- *reg |= (value & 0xFFFFFFFF);
- break;
- case QUAD:
- *reg = value;
- break;
- default:
- printk("Error: <__set_reg_value> : Unknown size for register\n");
- domain_crash_synchronous();
+ case BYTE_64:
+ *reg &= ~0xFF;
+ *reg |= (value & 0xFF);
+ break;
+ case WORD:
+ *reg &= ~0xFFFF;
+ *reg |= (value & 0xFFFF);
+ break;
+ case LONG:
+ *reg &= ~0xFFFFFFFF;
+ *reg |= (value & 0xFFFFFFFF);
+ break;
+ case QUAD:
+ *reg = value;
+ break;
+ default:
+ printk("Error: <__set_reg_value>: size:%x is invalid\n", size);
+ domain_crash_synchronous();
}
}
@@ -224,98 +224,98 @@
{
if (size == BYTE) {
switch (index) {
- case 0:
- regs->rax &= ~0xFF;
- regs->rax |= (value & 0xFF);
- break;
- case 1:
- regs->rcx &= ~0xFF;
- regs->rcx |= (value & 0xFF);
- break;
- case 2:
- regs->rdx &= ~0xFF;
- regs->rdx |= (value & 0xFF);
- break;
- case 3:
- regs->rbx &= ~0xFF;
- regs->rbx |= (value & 0xFF);
- break;
- case 4:
- regs->rax &= 0xFFFFFFFFFFFF00FF;
- regs->rax |= ((value & 0xFF) << 8);
- break;
- case 5:
- regs->rcx &= 0xFFFFFFFFFFFF00FF;
- regs->rcx |= ((value & 0xFF) << 8);
- break;
- case 6:
- regs->rdx &= 0xFFFFFFFFFFFF00FF;
- regs->rdx |= ((value & 0xFF) << 8);
- break;
- case 7:
- regs->rbx &= 0xFFFFFFFFFFFF00FF;
- regs->rbx |= ((value & 0xFF) << 8);
- break;
- default:
- printk("Error: size:%x, index:%x are invalid!\n", size, index);
- domain_crash_synchronous();
- break;
- }
-
+ case 0:
+ regs->rax &= ~0xFF;
+ regs->rax |= (value & 0xFF);
+ break;
+ case 1:
+ regs->rcx &= ~0xFF;
+ regs->rcx |= (value & 0xFF);
+ break;
+ case 2:
+ regs->rdx &= ~0xFF;
+ regs->rdx |= (value & 0xFF);
+ break;
+ case 3:
+ regs->rbx &= ~0xFF;
+ regs->rbx |= (value & 0xFF);
+ break;
+ case 4:
+ regs->rax &= 0xFFFFFFFFFFFF00FF;
+ regs->rax |= ((value & 0xFF) << 8);
+ break;
+ case 5:
+ regs->rcx &= 0xFFFFFFFFFFFF00FF;
+ regs->rcx |= ((value & 0xFF) << 8);
+ break;
+ case 6:
+ regs->rdx &= 0xFFFFFFFFFFFF00FF;
+ regs->rdx |= ((value & 0xFF) << 8);
+ break;
+ case 7:
+ regs->rbx &= 0xFFFFFFFFFFFF00FF;
+ regs->rbx |= ((value & 0xFF) << 8);
+ break;
+ default:
+ printk("Error: size:%x, index:%x are invalid!\n", size, index);
+ domain_crash_synchronous();
+ break;
+ }
+ return;
}
switch (index) {
- case 0:
- __set_reg_value(®s->rax, size, value);
- break;
- case 1:
- __set_reg_value(®s->rcx, size, value);
- break;
- case 2:
- __set_reg_value(®s->rdx, size, value);
- break;
- case 3:
- __set_reg_value(®s->rbx, size, value);
- break;
- case 4:
- __set_reg_value(®s->rsp, size, value);
- break;
- case 5:
- __set_reg_value(®s->rbp, size, value);
- break;
- case 6:
- __set_reg_value(®s->rsi, size, value);
- break;
- case 7:
- __set_reg_value(®s->rdi, size, value);
- break;
- case 8:
- __set_reg_value(®s->r8, size, value);
- break;
- case 9:
- __set_reg_value(®s->r9, size, value);
- break;
- case 10:
- __set_reg_value(®s->r10, size, value);
- break;
- case 11:
- __set_reg_value(®s->r11, size, value);
- break;
- case 12:
- __set_reg_value(®s->r12, size, value);
- break;
- case 13:
- __set_reg_value(®s->r13, size, value);
- break;
- case 14:
- __set_reg_value(®s->r14, size, value);
- break;
- case 15:
- __set_reg_value(®s->r15, size, value);
- break;
- default:
- printk("Error: <set_reg_value> Invalid index\n");
- domain_crash_synchronous();
+ case 0:
+ __set_reg_value(®s->rax, size, value);
+ break;
+ case 1:
+ __set_reg_value(®s->rcx, size, value);
+ break;
+ case 2:
+ __set_reg_value(®s->rdx, size, value);
+ break;
+ case 3:
+ __set_reg_value(®s->rbx, size, value);
+ break;
+ case 4:
+ __set_reg_value(®s->rsp, size, value);
+ break;
+ case 5:
+ __set_reg_value(®s->rbp, size, value);
+ break;
+ case 6:
+ __set_reg_value(®s->rsi, size, value);
+ break;
+ case 7:
+ __set_reg_value(®s->rdi, size, value);
+ break;
+ case 8:
+ __set_reg_value(®s->r8, size, value);
+ break;
+ case 9:
+ __set_reg_value(®s->r9, size, value);
+ break;
+ case 10:
+ __set_reg_value(®s->r10, size, value);
+ break;
+ case 11:
+ __set_reg_value(®s->r11, size, value);
+ break;
+ case 12:
+ __set_reg_value(®s->r12, size, value);
+ break;
+ case 13:
+ __set_reg_value(®s->r13, size, value);
+ break;
+ case 14:
+ __set_reg_value(®s->r14, size, value);
+ break;
+ case 15:
+ __set_reg_value(®s->r15, size, value);
+ break;
+ default:
+ printk("Error: <set_reg_value> Invalid index\n");
+ domain_crash_synchronous();
}
return;
}
@@ -324,44 +324,44 @@
extern long get_reg_value(int size, int index, int seg, struct cpu_user_regs
*regs);
static inline void set_eflags_CF(int size, unsigned long v1,
- unsigned long v2, struct cpu_user_regs *regs)
+ unsigned long v2, struct cpu_user_regs *regs)
{
unsigned long mask = (1 << (8 * size)) - 1;
if ((v1 & mask) > (v2 & mask))
- regs->eflags |= X86_EFLAGS_CF;
+ regs->eflags |= X86_EFLAGS_CF;
else
- regs->eflags &= ~X86_EFLAGS_CF;
+ regs->eflags &= ~X86_EFLAGS_CF;
}
static inline void set_eflags_OF(int size, unsigned long v1,
- unsigned long v2, unsigned long v3, struct cpu_user_regs *regs)
+ unsigned long v2, unsigned long v3, struct
cpu_user_regs *regs)
{
if ((v3 ^ v2) & (v3 ^ v1) & (1 << ((8 * size) - 1)))
- regs->eflags |= X86_EFLAGS_OF;
+ regs->eflags |= X86_EFLAGS_OF;
}
static inline void set_eflags_AF(int size, unsigned long v1,
- unsigned long v2, unsigned long v3, struct cpu_user_regs *regs)
+ unsigned long v2, unsigned long v3, struct
cpu_user_regs *regs)
{
if ((v1 ^ v2 ^ v3) & 0x10)
- regs->eflags |= X86_EFLAGS_AF;
+ regs->eflags |= X86_EFLAGS_AF;
}
static inline void set_eflags_ZF(int size, unsigned long v1,
- struct cpu_user_regs *regs)
+ struct cpu_user_regs *regs)
{
unsigned long mask = (1 << (8 * size)) - 1;
if ((v1 & mask) == 0)
- regs->eflags |= X86_EFLAGS_ZF;
+ regs->eflags |= X86_EFLAGS_ZF;
}
static inline void set_eflags_SF(int size, unsigned long v1,
- struct cpu_user_regs *regs)
+ struct cpu_user_regs *regs)
{
if (v1 & (1 << ((8 * size) - 1)))
- regs->eflags |= X86_EFLAGS_SF;
+ regs->eflags |= X86_EFLAGS_SF;
}
static char parity_table[256] = {
@@ -384,14 +384,14 @@
};
static inline void set_eflags_PF(int size, unsigned long v1,
- struct cpu_user_regs *regs)
+ struct cpu_user_regs *regs)
{
if (parity_table[v1 & 0xFF])
- regs->eflags |= X86_EFLAGS_PF;
+ regs->eflags |= X86_EFLAGS_PF;
}
static void vmx_pio_assist(struct cpu_user_regs *regs, ioreq_t *p,
- struct mi_per_cpu_info *mpcip)
+ struct mi_per_cpu_info *mpcip)
{
unsigned long old_eax;
int sign = p->df ? -1 : 1;
@@ -399,28 +399,28 @@
if (p->dir == IOREQ_WRITE) {
if (p->pdata_valid) {
regs->esi += sign * p->count * p->size;
- if (mpcip->flags & REPZ)
- regs->ecx -= p->count;
+ if (mpcip->flags & REPZ)
+ regs->ecx -= p->count;
}
} else {
- if (mpcip->flags & OVERLAP) {
- unsigned long addr;
+ if (mpcip->flags & OVERLAP) {
+ unsigned long addr;
regs->edi += sign * p->count * p->size;
- if (mpcip->flags & REPZ)
- regs->ecx -= p->count;
-
- addr = regs->edi;
- if (sign > 0)
- addr -= p->size;
- vmx_copy(&p->u.data, addr, p->size, VMX_COPY_OUT);
- } else if (p->pdata_valid) {
+ if (mpcip->flags & REPZ)
+ regs->ecx -= p->count;
+
+ addr = regs->edi;
+ if (sign > 0)
+ addr -= p->size;
+ vmx_copy(&p->u.data, addr, p->size, VMX_COPY_OUT);
+ } else if (p->pdata_valid) {
regs->edi += sign * p->count * p->size;
- if (mpcip->flags & REPZ)
- regs->ecx -= p->count;
+ if (mpcip->flags & REPZ)
+ regs->ecx -= p->count;
} else {
- old_eax = regs->eax;
- switch (p->size) {
+ old_eax = regs->eax;
+ switch (p->size) {
case 1:
regs->eax = (old_eax & 0xffffff00) | (p->u.data & 0xff);
break;
@@ -431,15 +431,15 @@
regs->eax = (p->u.data & 0xffffffff);
break;
default:
- printk("Error: %s unknown port size\n", __FUNCTION__);
- domain_crash_synchronous();
- }
- }
+ printk("Error: %s unknown port size\n", __FUNCTION__);
+ domain_crash_synchronous();
+ }
+ }
}
}
static void vmx_mmio_assist(struct cpu_user_regs *regs, ioreq_t *p,
- struct mi_per_cpu_info *mpcip)
+ struct mi_per_cpu_info *mpcip)
{
int sign = p->df ? -1 : 1;
int size = -1, index = -1;
@@ -452,178 +452,178 @@
switch (mpcip->instr) {
case INSTR_MOV:
- if (dst & REGISTER) {
- index = operand_index(dst);
- set_reg_value(size, index, 0, regs, p->u.data);
- }
- break;
+ if (dst & REGISTER) {
+ index = operand_index(dst);
+ set_reg_value(size, index, 0, regs, p->u.data);
+ }
+ break;
case INSTR_MOVZ:
- if (dst & REGISTER) {
- index = operand_index(dst);
- switch (size) {
- case BYTE: p->u.data = p->u.data & 0xFFULL; break;
- case WORD: p->u.data = p->u.data & 0xFFFFULL; break;
- case LONG: p->u.data = p->u.data & 0xFFFFFFFFULL; break;
- }
- set_reg_value(operand_size(dst), index, 0, regs, p->u.data);
- }
- break;
+ if (dst & REGISTER) {
+ index = operand_index(dst);
+ switch (size) {
+ case BYTE: p->u.data = p->u.data & 0xFFULL; break;
+ case WORD: p->u.data = p->u.data & 0xFFFFULL; break;
+ case LONG: p->u.data = p->u.data & 0xFFFFFFFFULL; break;
+ }
+ set_reg_value(operand_size(dst), index, 0, regs, p->u.data);
+ }
+ break;
case INSTR_MOVS:
- sign = p->df ? -1 : 1;
- regs->esi += sign * p->count * p->size;
- regs->edi += sign * p->count * p->size;
-
- if ((mpcip->flags & OVERLAP) && p->dir == IOREQ_READ) {
- unsigned long addr = regs->edi;
-
- if (sign > 0)
- addr -= p->size;
- vmx_copy(&p->u.data, addr, p->size, VMX_COPY_OUT);
- }
-
- if (mpcip->flags & REPZ)
- regs->ecx -= p->count;
- break;
+ sign = p->df ? -1 : 1;
+ regs->esi += sign * p->count * p->size;
+ regs->edi += sign * p->count * p->size;
+
+ if ((mpcip->flags & OVERLAP) && p->dir == IOREQ_READ) {
+ unsigned long addr = regs->edi;
+
+ if (sign > 0)
+ addr -= p->size;
+ vmx_copy(&p->u.data, addr, p->size, VMX_COPY_OUT);
+ }
+
+ if (mpcip->flags & REPZ)
+ regs->ecx -= p->count;
+ break;
case INSTR_STOS:
- sign = p->df ? -1 : 1;
- regs->edi += sign * p->count * p->size;
- if (mpcip->flags & REPZ)
- regs->ecx -= p->count;
- break;
+ sign = p->df ? -1 : 1;
+ regs->edi += sign * p->count * p->size;
+ if (mpcip->flags & REPZ)
+ regs->ecx -= p->count;
+ break;
case INSTR_AND:
- if (src & REGISTER) {
- index = operand_index(src);
- value = get_reg_value(size, index, 0, regs);
- diff = (unsigned long) p->u.data & value;
- } else if (src & IMMEDIATE) {
- value = mpcip->immediate;
- diff = (unsigned long) p->u.data & value;
- } else if (src & MEMORY) {
- index = operand_index(dst);
- value = get_reg_value(size, index, 0, regs);
- diff = (unsigned long) p->u.data & value;
- set_reg_value(size, index, 0, regs, diff);
- }
-
- /*
- * The OF and CF flags are cleared; the SF, ZF, and PF
- * flags are set according to the result. The state of
- * the AF flag is undefined.
- */
- regs->eflags &= ~(X86_EFLAGS_CF|X86_EFLAGS_PF|
- X86_EFLAGS_ZF|X86_EFLAGS_SF|X86_EFLAGS_OF);
- set_eflags_ZF(size, diff, regs);
- set_eflags_SF(size, diff, regs);
- set_eflags_PF(size, diff, regs);
- break;
+ if (src & REGISTER) {
+ index = operand_index(src);
+ value = get_reg_value(size, index, 0, regs);
+ diff = (unsigned long) p->u.data & value;
+ } else if (src & IMMEDIATE) {
+ value = mpcip->immediate;
+ diff = (unsigned long) p->u.data & value;
+ } else if (src & MEMORY) {
+ index = operand_index(dst);
+ value = get_reg_value(size, index, 0, regs);
+ diff = (unsigned long) p->u.data & value;
+ set_reg_value(size, index, 0, regs, diff);
+ }
+
+ /*
+ * The OF and CF flags are cleared; the SF, ZF, and PF
+ * flags are set according to the result. The state of
+ * the AF flag is undefined.
+ */
+ regs->eflags &= ~(X86_EFLAGS_CF|X86_EFLAGS_PF|
+ X86_EFLAGS_ZF|X86_EFLAGS_SF|X86_EFLAGS_OF);
+ set_eflags_ZF(size, diff, regs);
+ set_eflags_SF(size, diff, regs);
+ set_eflags_PF(size, diff, regs);
+ break;
case INSTR_OR:
- if (src & REGISTER) {
- index = operand_index(src);
- value = get_reg_value(size, index, 0, regs);
- diff = (unsigned long) p->u.data | value;
- } else if (src & IMMEDIATE) {
- value = mpcip->immediate;
- diff = (unsigned long) p->u.data | value;
- } else if (src & MEMORY) {
- index = operand_index(dst);
- value = get_reg_value(size, index, 0, regs);
- diff = (unsigned long) p->u.data | value;
- set_reg_value(size, index, 0, regs, diff);
- }
-
- /*
- * The OF and CF flags are cleared; the SF, ZF, and PF
- * flags are set according to the result. The state of
- * the AF flag is undefined.
- */
- regs->eflags &= ~(X86_EFLAGS_CF|X86_EFLAGS_PF|
- X86_EFLAGS_ZF|X86_EFLAGS_SF|X86_EFLAGS_OF);
- set_eflags_ZF(size, diff, regs);
- set_eflags_SF(size, diff, regs);
- set_eflags_PF(size, diff, regs);
- break;
+ if (src & REGISTER) {
+ index = operand_index(src);
+ value = get_reg_value(size, index, 0, regs);
+ diff = (unsigned long) p->u.data | value;
+ } else if (src & IMMEDIATE) {
+ value = mpcip->immediate;
+ diff = (unsigned long) p->u.data | value;
+ } else if (src & MEMORY) {
+ index = operand_index(dst);
+ value = get_reg_value(size, index, 0, regs);
+ diff = (unsigned long) p->u.data | value;
+ set_reg_value(size, index, 0, regs, diff);
+ }
+
+ /*
+ * The OF and CF flags are cleared; the SF, ZF, and PF
+ * flags are set according to the result. The state of
+ * the AF flag is undefined.
+ */
+ regs->eflags &= ~(X86_EFLAGS_CF|X86_EFLAGS_PF|
+ X86_EFLAGS_ZF|X86_EFLAGS_SF|X86_EFLAGS_OF);
+ set_eflags_ZF(size, diff, regs);
+ set_eflags_SF(size, diff, regs);
+ set_eflags_PF(size, diff, regs);
+ break;
case INSTR_XOR:
- if (src & REGISTER) {
- index = operand_index(src);
- value = get_reg_value(size, index, 0, regs);
- diff = (unsigned long) p->u.data ^ value;
- } else if (src & IMMEDIATE) {
- value = mpcip->immediate;
- diff = (unsigned long) p->u.data ^ value;
- } else if (src & MEMORY) {
- index = operand_index(dst);
- value = get_reg_value(size, index, 0, regs);
- diff = (unsigned long) p->u.data ^ value;
- set_reg_value(size, index, 0, regs, diff);
- }
-
- /*
- * The OF and CF flags are cleared; the SF, ZF, and PF
- * flags are set according to the result. The state of
- * the AF flag is undefined.
- */
- regs->eflags &= ~(X86_EFLAGS_CF|X86_EFLAGS_PF|
- X86_EFLAGS_ZF|X86_EFLAGS_SF|X86_EFLAGS_OF);
- set_eflags_ZF(size, diff, regs);
- set_eflags_SF(size, diff, regs);
- set_eflags_PF(size, diff, regs);
- break;
+ if (src & REGISTER) {
+ index = operand_index(src);
+ value = get_reg_value(size, index, 0, regs);
+ diff = (unsigned long) p->u.data ^ value;
+ } else if (src & IMMEDIATE) {
+ value = mpcip->immediate;
+ diff = (unsigned long) p->u.data ^ value;
+ } else if (src & MEMORY) {
+ index = operand_index(dst);
+ value = get_reg_value(size, index, 0, regs);
+ diff = (unsigned long) p->u.data ^ value;
+ set_reg_value(size, index, 0, regs, diff);
+ }
+
+ /*
+ * The OF and CF flags are cleared; the SF, ZF, and PF
+ * flags are set according to the result. The state of
+ * the AF flag is undefined.
+ */
+ regs->eflags &= ~(X86_EFLAGS_CF|X86_EFLAGS_PF|
+ X86_EFLAGS_ZF|X86_EFLAGS_SF|X86_EFLAGS_OF);
+ set_eflags_ZF(size, diff, regs);
+ set_eflags_SF(size, diff, regs);
+ set_eflags_PF(size, diff, regs);
+ break;
case INSTR_CMP:
- if (src & REGISTER) {
- index = operand_index(src);
- value = get_reg_value(size, index, 0, regs);
- diff = (unsigned long) p->u.data - value;
- } else if (src & IMMEDIATE) {
- value = mpcip->immediate;
- diff = (unsigned long) p->u.data - value;
- } else if (src & MEMORY) {
- index = operand_index(dst);
- value = get_reg_value(size, index, 0, regs);
- diff = value - (unsigned long) p->u.data;
- }
-
- /*
- * The CF, OF, SF, ZF, AF, and PF flags are set according
- * to the result
- */
- regs->eflags &= ~(X86_EFLAGS_CF|X86_EFLAGS_PF|X86_EFLAGS_AF|
- X86_EFLAGS_ZF|X86_EFLAGS_SF|X86_EFLAGS_OF);
- set_eflags_CF(size, value, (unsigned long) p->u.data, regs);
- set_eflags_OF(size, diff, value, (unsigned long) p->u.data, regs);
- set_eflags_AF(size, diff, value, (unsigned long) p->u.data, regs);
- set_eflags_ZF(size, diff, regs);
- set_eflags_SF(size, diff, regs);
- set_eflags_PF(size, diff, regs);
- break;
+ if (src & REGISTER) {
+ index = operand_index(src);
+ value = get_reg_value(size, index, 0, regs);
+ diff = (unsigned long) p->u.data - value;
+ } else if (src & IMMEDIATE) {
+ value = mpcip->immediate;
+ diff = (unsigned long) p->u.data - value;
+ } else if (src & MEMORY) {
+ index = operand_index(dst);
+ value = get_reg_value(size, index, 0, regs);
+ diff = value - (unsigned long) p->u.data;
+ }
+
+ /*
+ * The CF, OF, SF, ZF, AF, and PF flags are set according
+ * to the result
+ */
+ regs->eflags &= ~(X86_EFLAGS_CF|X86_EFLAGS_PF|X86_EFLAGS_AF|
+ X86_EFLAGS_ZF|X86_EFLAGS_SF|X86_EFLAGS_OF);
+ set_eflags_CF(size, value, (unsigned long) p->u.data, regs);
+ set_eflags_OF(size, diff, value, (unsigned long) p->u.data, regs);
+ set_eflags_AF(size, diff, value, (unsigned long) p->u.data, regs);
+ set_eflags_ZF(size, diff, regs);
+ set_eflags_SF(size, diff, regs);
+ set_eflags_PF(size, diff, regs);
+ break;
case INSTR_TEST:
- if (src & REGISTER) {
- index = operand_index(src);
- value = get_reg_value(size, index, 0, regs);
- } else if (src & IMMEDIATE) {
- value = mpcip->immediate;
- } else if (src & MEMORY) {
- index = operand_index(dst);
- value = get_reg_value(size, index, 0, regs);
- }
- diff = (unsigned long) p->u.data & value;
-
- /*
- * Sets the SF, ZF, and PF status flags. CF and OF are set to 0
- */
- regs->eflags &= ~(X86_EFLAGS_CF|X86_EFLAGS_PF|
- X86_EFLAGS_ZF|X86_EFLAGS_SF|X86_EFLAGS_OF);
- set_eflags_ZF(size, diff, regs);
- set_eflags_SF(size, diff, regs);
- set_eflags_PF(size, diff, regs);
- break;
+ if (src & REGISTER) {
+ index = operand_index(src);
+ value = get_reg_value(size, index, 0, regs);
+ } else if (src & IMMEDIATE) {
+ value = mpcip->immediate;
+ } else if (src & MEMORY) {
+ index = operand_index(dst);
+ value = get_reg_value(size, index, 0, regs);
+ }
+ diff = (unsigned long) p->u.data & value;
+
+ /*
+ * Sets the SF, ZF, and PF status flags. CF and OF are set to 0
+ */
+ regs->eflags &= ~(X86_EFLAGS_CF|X86_EFLAGS_PF|
+ X86_EFLAGS_ZF|X86_EFLAGS_SF|X86_EFLAGS_OF);
+ set_eflags_ZF(size, diff, regs);
+ set_eflags_SF(size, diff, regs);
+ set_eflags_PF(size, diff, regs);
+ break;
}
load_cpu_user_regs(regs);
@@ -645,7 +645,7 @@
if (vio == 0) {
VMX_DBG_LOG(DBG_LEVEL_1,
"bad shared page: %lx", (unsigned long) vio);
- printf("bad shared page: %lx\n", (unsigned long) vio);
+ printf("bad shared page: %lx\n", (unsigned long) vio);
domain_crash_synchronous();
}
@@ -656,15 +656,15 @@
/* clear IO wait VMX flag */
if (test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags)) {
if (p->state == STATE_IORESP_READY) {
- p->state = STATE_INVALID;
+ p->state = STATE_INVALID;
clear_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags);
- if (p->type == IOREQ_TYPE_PIO)
- vmx_pio_assist(regs, p, mpci_p);
- else
- vmx_mmio_assist(regs, p, mpci_p);
- }
- /* else an interrupt send event raced us */
+ if (p->type == IOREQ_TYPE_PIO)
+ vmx_pio_assist(regs, p, mpci_p);
+ else
+ vmx_mmio_assist(regs, p, mpci_p);
+ }
+ /* else an interrupt send event raced us */
}
}
@@ -731,7 +731,7 @@
return word ? bit : -1;
}
#else
-#define __fls(x) generic_fls(x)
+#define __fls(x) generic_fls(x)
static __inline__ int generic_fls(u32 x)
{
int r = 31;
@@ -840,23 +840,23 @@
struct vmx_virpit_t *vpit = &(v->domain->arch.vmx_platform.vmx_pit);
switch(type)
{
- case VLAPIC_DELIV_MODE_EXT:
- if (vpit->pending_intr_nr && vector == vpit->vector)
- vpit->pending_intr_nr--;
- else
- clear_highest_bit(v, vector);
-
- if (vector == vpit->vector && !vpit->first_injected){
- vpit->first_injected = 1;
- vpit->pending_intr_nr = 0;
- }
- if (vector == vpit->vector)
- vpit->inject_point = NOW();
- break;
-
- default:
- printk("Not support interrupt type\n");
- break;
+ case VLAPIC_DELIV_MODE_EXT:
+ if (vpit->pending_intr_nr && vector == vpit->vector)
+ vpit->pending_intr_nr--;
+ else
+ clear_highest_bit(v, vector);
+
+ if (vector == vpit->vector && !vpit->first_injected){
+ vpit->first_injected = 1;
+ vpit->pending_intr_nr = 0;
+ }
+ if (vector == vpit->vector)
+ vpit->inject_point = NOW();
+ break;
+
+ default:
+ printk("Not support interrupt type\n");
+ break;
}
}
@@ -898,51 +898,51 @@
return;
}
- __vmread(VM_ENTRY_INTR_INFO_FIELD, &intr_fields);
-
- if (intr_fields & INTR_INFO_VALID_MASK) {
- VMX_DBG_LOG(DBG_LEVEL_1, "vmx_intr_assist: intr_fields: %lx",
- intr_fields);
- return;
- }
-
- __vmread(GUEST_INTERRUPTIBILITY_INFO, &interruptibility);
-
- if (interruptibility) {
- enable_irq_window(cpu_exec_control);
- VMX_DBG_LOG(DBG_LEVEL_1, "guesting pending: %x, interruptibility:
%lx",
- highest_vector, interruptibility);
- return;
- }
-
- __vmread(GUEST_RFLAGS, &eflags);
-
- switch (intr_type) {
- case VLAPIC_DELIV_MODE_EXT:
- if (irq_masked(eflags)) {
- enable_irq_window(cpu_exec_control);
- VMX_DBG_LOG(DBG_LEVEL_1, "guesting pending: %x, eflags: %lx",
- highest_vector, eflags);
- return;
- }
-
- vmx_inject_extint(v, highest_vector, VMX_INVALID_ERROR_CODE);
- TRACE_3D(TRC_VMX_INT, v->domain->domain_id, highest_vector, 0);
- break;
- case VLAPIC_DELIV_MODE_FIXED:
- case VLAPIC_DELIV_MODE_LPRI:
- case VLAPIC_DELIV_MODE_SMI:
- case VLAPIC_DELIV_MODE_NMI:
- case VLAPIC_DELIV_MODE_INIT:
- case VLAPIC_DELIV_MODE_STARTUP:
- default:
- printk("Unsupported interrupt type\n");
- BUG();
- break;
- }
-
- interrupt_post_injection(v, highest_vector, intr_type);
- return;
+ __vmread(VM_ENTRY_INTR_INFO_FIELD, &intr_fields);
+
+ if (intr_fields & INTR_INFO_VALID_MASK) {
+ VMX_DBG_LOG(DBG_LEVEL_1, "vmx_intr_assist: intr_fields: %lx",
+ intr_fields);
+ return;
+ }
+
+ __vmread(GUEST_INTERRUPTIBILITY_INFO, &interruptibility);
+
+ if (interruptibility) {
+ enable_irq_window(cpu_exec_control);
+ VMX_DBG_LOG(DBG_LEVEL_1, "guesting pending: %x, interruptibility: %lx",
+ highest_vector, interruptibility);
+ return;
+ }
+
+ __vmread(GUEST_RFLAGS, &eflags);
+
+ switch (intr_type) {
+ case VLAPIC_DELIV_MODE_EXT:
+ if (irq_masked(eflags)) {
+ enable_irq_window(cpu_exec_control);
+ VMX_DBG_LOG(DBG_LEVEL_1, "guesting pending: %x, eflags: %lx",
+ highest_vector, eflags);
+ return;
+ }
+
+ vmx_inject_extint(v, highest_vector, VMX_INVALID_ERROR_CODE);
+ TRACE_3D(TRC_VMX_INT, v->domain->domain_id, highest_vector, 0);
+ break;
+ case VLAPIC_DELIV_MODE_FIXED:
+ case VLAPIC_DELIV_MODE_LPRI:
+ case VLAPIC_DELIV_MODE_SMI:
+ case VLAPIC_DELIV_MODE_NMI:
+ case VLAPIC_DELIV_MODE_INIT:
+ case VLAPIC_DELIV_MODE_STARTUP:
+ default:
+ printk("Unsupported interrupt type\n");
+ BUG();
+ break;
+ }
+
+ interrupt_post_injection(v, highest_vector, intr_type);
+ return;
}
void vmx_do_resume(struct vcpu *d)
diff -r d4d880fcef28 -r b35215021b32 xen/arch/x86/vmx_platform.c
--- a/xen/arch/x86/vmx_platform.c Fri Sep 9 16:31:36 2005
+++ b/xen/arch/x86/vmx_platform.c Tue Sep 13 16:14:16 2005
@@ -55,17 +55,17 @@
static inline long __get_reg_value(unsigned long reg, int size)
{
switch(size) {
- case BYTE_64:
- return (char)(reg & 0xFF);
- case WORD:
- return (short)(reg & 0xFFFF);
- case LONG:
- return (int)(reg & 0xFFFFFFFF);
- case QUAD:
- return (long)(reg);
- default:
- printf("Error: (__get_reg_value) Invalid reg size\n");
- domain_crash_synchronous();
+ case BYTE_64:
+ return (char)(reg & 0xFF);
+ case WORD:
+ return (short)(reg & 0xFFFF);
+ case LONG:
+ return (int)(reg & 0xFFFFFFFF);
+ case QUAD:
+ return (long)(reg);
+ default:
+ printf("Error: (__get_reg_value) Invalid reg size\n");
+ domain_crash_synchronous();
}
}
@@ -73,48 +73,49 @@
{
if (size == BYTE) {
switch (index) {
- case 0: /* %al */
- return (char)(regs->rax & 0xFF);
- case 1: /* %cl */
- return (char)(regs->rcx & 0xFF);
- case 2: /* %dl */
- return (char)(regs->rdx & 0xFF);
- case 3: /* %bl */
- return (char)(regs->rbx & 0xFF);
- case 4: /* %ah */
- return (char)((regs->rax & 0xFF00) >> 8);
- case 5: /* %ch */
- return (char)((regs->rcx & 0xFF00) >> 8);
- case 6: /* %dh */
- return (char)((regs->rdx & 0xFF00) >> 8);
- case 7: /* %bh */
- return (char)((regs->rbx & 0xFF00) >> 8);
- default:
- printf("Error: (get_reg_value) Invalid index value\n");
- domain_crash_synchronous();
+ case 0: /* %al */
+ return (char)(regs->rax & 0xFF);
+ case 1: /* %cl */
+ return (char)(regs->rcx & 0xFF);
+ case 2: /* %dl */
+ return (char)(regs->rdx & 0xFF);
+ case 3: /* %bl */
+ return (char)(regs->rbx & 0xFF);
+ case 4: /* %ah */
+ return (char)((regs->rax & 0xFF00) >> 8);
+ case 5: /* %ch */
+ return (char)((regs->rcx & 0xFF00) >> 8);
+ case 6: /* %dh */
+ return (char)((regs->rdx & 0xFF00) >> 8);
+ case 7: /* %bh */
+ return (char)((regs->rbx & 0xFF00) >> 8);
+ default:
+ printf("Error: (get_reg_value) Invalid index value\n");
+ domain_crash_synchronous();
}
+ /* NOTREACHED */
}
switch (index) {
- case 0: return __get_reg_value(regs->rax, size);
- case 1: return __get_reg_value(regs->rcx, size);
- case 2: return __get_reg_value(regs->rdx, size);
- case 3: return __get_reg_value(regs->rbx, size);
- case 4: return __get_reg_value(regs->rsp, size);
- case 5: return __get_reg_value(regs->rbp, size);
- case 6: return __get_reg_value(regs->rsi, size);
- case 7: return __get_reg_value(regs->rdi, size);
- case 8: return __get_reg_value(regs->r8, size);
- case 9: return __get_reg_value(regs->r9, size);
- case 10: return __get_reg_value(regs->r10, size);
- case 11: return __get_reg_value(regs->r11, size);
- case 12: return __get_reg_value(regs->r12, size);
- case 13: return __get_reg_value(regs->r13, size);
- case 14: return __get_reg_value(regs->r14, size);
- case 15: return __get_reg_value(regs->r15, size);
- default:
- printf("Error: (get_reg_value) Invalid index value\n");
- domain_crash_synchronous();
+ case 0: return __get_reg_value(regs->rax, size);
+ case 1: return __get_reg_value(regs->rcx, size);
+ case 2: return __get_reg_value(regs->rdx, size);
+ case 3: return __get_reg_value(regs->rbx, size);
+ case 4: return __get_reg_value(regs->rsp, size);
+ case 5: return __get_reg_value(regs->rbp, size);
+ case 6: return __get_reg_value(regs->rsi, size);
+ case 7: return __get_reg_value(regs->rdi, size);
+ case 8: return __get_reg_value(regs->r8, size);
+ case 9: return __get_reg_value(regs->r9, size);
+ case 10: return __get_reg_value(regs->r10, size);
+ case 11: return __get_reg_value(regs->r11, size);
+ case 12: return __get_reg_value(regs->r12, size);
+ case 13: return __get_reg_value(regs->r13, size);
+ case 14: return __get_reg_value(regs->r14, size);
+ case 15: return __get_reg_value(regs->r15, size);
+ default:
+ printf("Error: (get_reg_value) Invalid index value\n");
+ domain_crash_synchronous();
}
}
#elif defined (__i386__)
@@ -133,12 +134,12 @@
{
switch(size) {
case WORD:
- return (short)(reg & 0xFFFF);
+ return (short)(reg & 0xFFFF);
case LONG:
- return (int)(reg & 0xFFFFFFFF);
+ return (int)(reg & 0xFFFFFFFF);
default:
- printf("Error: (__get_reg_value) Invalid reg size\n");
- domain_crash_synchronous();
+ printf("Error: (__get_reg_value) Invalid reg size\n");
+ domain_crash_synchronous();
}
}
@@ -146,29 +147,29 @@
{
if (size == BYTE) {
switch (index) {
- case 0: /* %al */
+ case 0: /* %al */
return (char)(regs->eax & 0xFF);
- case 1: /* %cl */
+ case 1: /* %cl */
return (char)(regs->ecx & 0xFF);
- case 2: /* %dl */
+ case 2: /* %dl */
return (char)(regs->edx & 0xFF);
- case 3: /* %bl */
+ case 3: /* %bl */
return (char)(regs->ebx & 0xFF);
- case 4: /* %ah */
+ case 4: /* %ah */
return (char)((regs->eax & 0xFF00) >> 8);
- case 5: /* %ch */
+ case 5: /* %ch */
return (char)((regs->ecx & 0xFF00) >> 8);
- case 6: /* %dh */
+ case 6: /* %dh */
return (char)((regs->edx & 0xFF00) >> 8);
- case 7: /* %bh */
+ case 7: /* %bh */
return (char)((regs->ebx & 0xFF00) >> 8);
default:
- printf("Error: (get_reg_value) Invalid index value\n");
+ printf("Error: (get_reg_value) Invalid index value\n");
domain_crash_synchronous();
}
- }
-
- switch (index) {
+ }
+
+ switch (index) {
case 0: return __get_reg_value(regs->eax, size);
case 1: return __get_reg_value(regs->ecx, size);
case 2: return __get_reg_value(regs->edx, size);
@@ -178,46 +179,46 @@
case 6: return __get_reg_value(regs->esi, size);
case 7: return __get_reg_value(regs->edi, size);
default:
- printf("Error: (get_reg_value) Invalid index value\n");
+ printf("Error: (get_reg_value) Invalid index value\n");
domain_crash_synchronous();
}
}
#endif
static inline unsigned char *check_prefix(unsigned char *inst,
- struct instruction *thread_inst, unsigned char *rex_p)
+ struct instruction *thread_inst,
unsigned char *rex_p)
{
while (1) {
switch (*inst) {
- /* rex prefix for em64t instructions */
- case 0x40 ... 0x4e:
- *rex_p = *inst;
- break;
+ /* rex prefix for em64t instructions */
+ case 0x40 ... 0x4e:
+ *rex_p = *inst;
+ break;
case 0xf3: /* REPZ */
- thread_inst->flags = REPZ;
- break;
+ thread_inst->flags = REPZ;
+ break;
case 0xf2: /* REPNZ */
- thread_inst->flags = REPNZ;
- break;
+ thread_inst->flags = REPNZ;
+ break;
case 0xf0: /* LOCK */
- break;
+ break;
case 0x2e: /* CS */
case 0x36: /* SS */
case 0x3e: /* DS */
case 0x26: /* ES */
case 0x64: /* FS */
case 0x65: /* GS */
- thread_inst->seg_sel = *inst;
- break;
+ thread_inst->seg_sel = *inst;
+ break;
case 0x66: /* 32bit->16bit */
- thread_inst->op_size = WORD;
- break;
- case 0x67:
- printf("Error: Not handling 0x67 (yet)\n");
- domain_crash_synchronous();
- break;
- default:
- return inst;
+ thread_inst->op_size = WORD;
+ break;
+ case 0x67:
+ printf("Error: Not handling 0x67 (yet)\n");
+ domain_crash_synchronous();
+ break;
+ default:
+ return inst;
}
inst++;
}
@@ -239,23 +240,23 @@
}
switch(mod) {
- case 0:
- if (rm == 5 || rm == 4) {
- if (op16)
- inst = inst + 2; //disp16, skip 2 bytes
- else
- inst = inst + 4; //disp32, skip 4 bytes
- }
- break;
- case 1:
- inst++; //disp8, skip 1 byte
- break;
- case 2:
+ case 0:
+ if (rm == 5 || rm == 4) {
if (op16)
inst = inst + 2; //disp16, skip 2 bytes
else
inst = inst + 4; //disp32, skip 4 bytes
- break;
+ }
+ break;
+ case 1:
+ inst++; //disp8, skip 1 byte
+ break;
+ case 2:
+ if (op16)
+ inst = inst + 2; //disp16, skip 2 bytes
+ else
+ inst = inst + 4; //disp32, skip 4 bytes
+ break;
}
if (op_size == QUAD)
@@ -303,19 +304,19 @@
}
#define GET_OP_SIZE_FOR_BYTE(op_size) \
- do { \
- if (rex) \
- op_size = BYTE_64; \
- else \
- op_size = BYTE; \
+ do { \
+ if (rex) \
+ op_size = BYTE_64; \
+ else \
+ op_size = BYTE; \
} while(0)
#define GET_OP_SIZE_FOR_NONEBYTE(op_size) \
- do { \
- if (rex & 0x8) \
- op_size = QUAD; \
- else if (op_size != WORD) \
- op_size = LONG; \
+ do { \
+ if (rex & 0x8) \
+ op_size = QUAD; \
+ else if (op_size != WORD) \
+ op_size = LONG; \
} while(0)
@@ -343,7 +344,7 @@
* Decode mem,reg operands (as in <opcode> r32/16, m32/16)
*/
static int mem_reg(unsigned char size, unsigned char *opcode,
- struct instruction *instr, unsigned char rex)
+ struct instruction *instr, unsigned char rex)
{
int index = get_index(opcode + 1, rex);
@@ -356,7 +357,7 @@
* Decode reg,mem operands (as in <opcode> m32/16, r32/16)
*/
static int reg_mem(unsigned char size, unsigned char *opcode,
- struct instruction *instr, unsigned char rex)
+ struct instruction *instr, unsigned char rex)
{
int index = get_index(opcode + 1, rex);
@@ -381,205 +382,210 @@
vm86 = 1;
if (vm86) { /* meaning is reversed */
- if (instr->op_size == WORD)
- instr->op_size = LONG;
- else if (instr->op_size == LONG)
- instr->op_size = WORD;
- else if (instr->op_size == 0)
- instr->op_size = WORD;
+ if (instr->op_size == WORD)
+ instr->op_size = LONG;
+ else if (instr->op_size == LONG)
+ instr->op_size = WORD;
+ else if (instr->op_size == 0)
+ instr->op_size = WORD;
}
switch (*opcode) {
case 0x0B: /* or m32/16, r32/16 */
- instr->instr = INSTR_OR;
- GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
- return mem_reg(instr->op_size, opcode, instr, rex);
+ instr->instr = INSTR_OR;
+ GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
+ return mem_reg(instr->op_size, opcode, instr, rex);
case 0x20: /* and r8, m8 */
- instr->instr = INSTR_AND;
- GET_OP_SIZE_FOR_BYTE(instr->op_size);
- return reg_mem(instr->op_size, opcode, instr, rex);
+ instr->instr = INSTR_AND;
+ GET_OP_SIZE_FOR_BYTE(instr->op_size);
+ return reg_mem(instr->op_size, opcode, instr, rex);
case 0x21: /* and r32/16, m32/16 */
- instr->instr = INSTR_AND;
- GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
- return reg_mem(instr->op_size, opcode, instr, rex);
+ instr->instr = INSTR_AND;
+ GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
+ return reg_mem(instr->op_size, opcode, instr, rex);
case 0x23: /* and m32/16, r32/16 */
- instr->instr = INSTR_AND;
- GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
- return mem_reg(instr->op_size, opcode, instr, rex);
+ instr->instr = INSTR_AND;
+ GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
+ return mem_reg(instr->op_size, opcode, instr, rex);
case 0x30: /* xor r8, m8 */
- instr->instr = INSTR_XOR;
- GET_OP_SIZE_FOR_BYTE(instr->op_size);
- return reg_mem(instr->op_size, opcode, instr, rex);
+ instr->instr = INSTR_XOR;
+ GET_OP_SIZE_FOR_BYTE(instr->op_size);
+ return reg_mem(instr->op_size, opcode, instr, rex);
case 0x31: /* xor r32/16, m32/16 */
- instr->instr = INSTR_XOR;
- GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
- return reg_mem(instr->op_size, opcode, instr, rex);
+ instr->instr = INSTR_XOR;
+ GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
+ return reg_mem(instr->op_size, opcode, instr, rex);
case 0x39: /* cmp r32/16, m32/16 */
- instr->instr = INSTR_CMP;
- GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
- return reg_mem(instr->op_size, opcode, instr, rex);
-
+ instr->instr = INSTR_CMP;
+ GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
+ return reg_mem(instr->op_size, opcode, instr, rex);
+
+ case 0x80:
case 0x81:
- if (((opcode[1] >> 3) & 7) == 7) { /* cmp $imm, m32/16 */
- instr->instr = INSTR_CMP;
- GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
-
- instr->operand[0] = mk_operand(instr->op_size, 0, 0, IMMEDIATE);
- instr->immediate = get_immediate(vm86, opcode+1, BYTE);
- instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY);
+ if (((opcode[1] >> 3) & 7) == 7) { /* cmp $imm, m32/16 */
+ instr->instr = INSTR_CMP;
+
+ if (opcode[0] == 0x80)
+ GET_OP_SIZE_FOR_BYTE(instr->op_size);
+ else
+ GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
+
+ instr->operand[0] = mk_operand(instr->op_size, 0, 0, IMMEDIATE);
+ instr->immediate = get_immediate(vm86, opcode+1, BYTE);
+ instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY);
return DECODE_success;
- } else
- return DECODE_failure;
+ } else
+ return DECODE_failure;
case 0x84: /* test m8, r8 */
- instr->instr = INSTR_TEST;
- instr->op_size = BYTE;
- GET_OP_SIZE_FOR_BYTE(tmp_size);
- return mem_reg(tmp_size, opcode, instr, rex);
+ instr->instr = INSTR_TEST;
+ instr->op_size = BYTE;
+ GET_OP_SIZE_FOR_BYTE(tmp_size);
+ return mem_reg(tmp_size, opcode, instr, rex);
case 0x88: /* mov r8, m8 */
- instr->instr = INSTR_MOV;
- instr->op_size = BYTE;
+ instr->instr = INSTR_MOV;
+ instr->op_size = BYTE;
GET_OP_SIZE_FOR_BYTE(tmp_size);
- return reg_mem(tmp_size, opcode, instr, rex);
+ return reg_mem(tmp_size, opcode, instr, rex);
case 0x89: /* mov r32/16, m32/16 */
- instr->instr = INSTR_MOV;
- GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
- return reg_mem(instr->op_size, opcode, instr, rex);
+ instr->instr = INSTR_MOV;
+ GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
+ return reg_mem(instr->op_size, opcode, instr, rex);
case 0x8A: /* mov m8, r8 */
- instr->instr = INSTR_MOV;
- instr->op_size = BYTE;
+ instr->instr = INSTR_MOV;
+ instr->op_size = BYTE;
GET_OP_SIZE_FOR_BYTE(tmp_size);
- return mem_reg(tmp_size, opcode, instr, rex);
+ return mem_reg(tmp_size, opcode, instr, rex);
case 0x8B: /* mov m32/16, r32/16 */
- instr->instr = INSTR_MOV;
- GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
- return mem_reg(instr->op_size, opcode, instr, rex);
+ instr->instr = INSTR_MOV;
+ GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
+ return mem_reg(instr->op_size, opcode, instr, rex);
case 0xA0: /* mov <addr>, al */
- instr->instr = INSTR_MOV;
- instr->op_size = BYTE;
+ instr->instr = INSTR_MOV;
+ instr->op_size = BYTE;
GET_OP_SIZE_FOR_BYTE(tmp_size);
- return mem_acc(tmp_size, instr);
+ return mem_acc(tmp_size, instr);
case 0xA1: /* mov <addr>, ax/eax */
- instr->instr = INSTR_MOV;
- GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
- return mem_acc(instr->op_size, instr);
+ instr->instr = INSTR_MOV;
+ GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
+ return mem_acc(instr->op_size, instr);
case 0xA2: /* mov al, <addr> */
- instr->instr = INSTR_MOV;
- instr->op_size = BYTE;
+ instr->instr = INSTR_MOV;
+ instr->op_size = BYTE;
GET_OP_SIZE_FOR_BYTE(tmp_size);
- return acc_mem(tmp_size, instr);
+ return acc_mem(tmp_size, instr);
case 0xA3: /* mov ax/eax, <addr> */
- instr->instr = INSTR_MOV;
- GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
- return acc_mem(instr->op_size, instr);
+ instr->instr = INSTR_MOV;
+ GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
+ return acc_mem(instr->op_size, instr);
case 0xA4: /* movsb */
- instr->instr = INSTR_MOVS;
- instr->op_size = BYTE;
+ instr->instr = INSTR_MOVS;
+ instr->op_size = BYTE;
return DECODE_success;
case 0xA5: /* movsw/movsl */
- instr->instr = INSTR_MOVS;
- GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
- return DECODE_success;
+ instr->instr = INSTR_MOVS;
+ GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
+ return DECODE_success;
case 0xAA: /* stosb */
- instr->instr = INSTR_STOS;
- instr->op_size = BYTE;
+ instr->instr = INSTR_STOS;
+ instr->op_size = BYTE;
return DECODE_success;
case 0xAB: /* stosw/stosl */
- instr->instr = INSTR_STOS;
- GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
- return DECODE_success;
+ instr->instr = INSTR_STOS;
+ GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
+ return DECODE_success;
case 0xC6:
- if (((opcode[1] >> 3) & 7) == 0) { /* mov $imm8, m8 */
- instr->instr = INSTR_MOV;
- instr->op_size = BYTE;
-
- instr->operand[0] = mk_operand(instr->op_size, 0, 0, IMMEDIATE);
- instr->immediate = get_immediate(vm86, opcode+1, instr->op_size);
- instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY);
+ if (((opcode[1] >> 3) & 7) == 0) { /* mov $imm8, m8 */
+ instr->instr = INSTR_MOV;
+ instr->op_size = BYTE;
+
+ instr->operand[0] = mk_operand(instr->op_size, 0, 0, IMMEDIATE);
+ instr->immediate = get_immediate(vm86, opcode+1, instr->op_size);
+ instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY);
return DECODE_success;
- } else
- return DECODE_failure;
+ } else
+ return DECODE_failure;
case 0xC7:
- if (((opcode[1] >> 3) & 7) == 0) { /* mov $imm16/32, m16/32 */
- instr->instr = INSTR_MOV;
- GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
-
- instr->operand[0] = mk_operand(instr->op_size, 0, 0, IMMEDIATE);
- instr->immediate = get_immediate(vm86, opcode+1, instr->op_size);
- instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY);
+ if (((opcode[1] >> 3) & 7) == 0) { /* mov $imm16/32, m16/32 */
+ instr->instr = INSTR_MOV;
+ GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
+
+ instr->operand[0] = mk_operand(instr->op_size, 0, 0, IMMEDIATE);
+ instr->immediate = get_immediate(vm86, opcode+1, instr->op_size);
+ instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY);
return DECODE_success;
- } else
- return DECODE_failure;
+ } else
+ return DECODE_failure;
case 0xF6:
- if (((opcode[1] >> 3) & 7) == 0) { /* testb $imm8, m8 */
- instr->instr = INSTR_TEST;
- instr->op_size = BYTE;
-
- instr->operand[0] = mk_operand(instr->op_size, 0, 0, IMMEDIATE);
- instr->immediate = get_immediate(vm86, opcode+1, instr->op_size);
- instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY);
-
- return DECODE_success;
- } else
- return DECODE_failure;
+ if (((opcode[1] >> 3) & 7) == 0) { /* testb $imm8, m8 */
+ instr->instr = INSTR_TEST;
+ instr->op_size = BYTE;
+
+ instr->operand[0] = mk_operand(instr->op_size, 0, 0, IMMEDIATE);
+ instr->immediate = get_immediate(vm86, opcode+1, instr->op_size);
+ instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY);
+
+ return DECODE_success;
+ } else
+ return DECODE_failure;
case 0x0F:
- break;
+ break;
default:
- printf("%x, This opcode isn't handled yet!\n", *opcode);
+ printf("%x, This opcode isn't handled yet!\n", *opcode);
return DECODE_failure;
}
switch (*++opcode) {
case 0xB6: /* movz m8, r16/r32 */
- instr->instr = INSTR_MOVZ;
- GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
- index = get_index(opcode + 1, rex);
- instr->operand[0] = mk_operand(BYTE, 0, 0, MEMORY);
- instr->operand[1] = mk_operand(instr->op_size, index, 0, REGISTER);
- return DECODE_success;
+ instr->instr = INSTR_MOVZ;
+ GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
+ index = get_index(opcode + 1, rex);
+ instr->operand[0] = mk_operand(BYTE, 0, 0, MEMORY);
+ instr->operand[1] = mk_operand(instr->op_size, index, 0, REGISTER);
+ return DECODE_success;
case 0xB7: /* movz m16, r32 */
- instr->instr = INSTR_MOVZ;
- index = get_index(opcode + 1, rex);
- if (rex & 0x8) {
- instr->op_size = LONG;
- instr->operand[1] = mk_operand(QUAD, index, 0, REGISTER);
- } else {
- instr->op_size = WORD;
- instr->operand[1] = mk_operand(LONG, index, 0, REGISTER);
- }
- instr->operand[0] = mk_operand(instr->op_size, 0, 0, MEMORY);
- return DECODE_success;
+ instr->instr = INSTR_MOVZ;
+ index = get_index(opcode + 1, rex);
+ if (rex & 0x8) {
+ instr->op_size = LONG;
+ instr->operand[1] = mk_operand(QUAD, index, 0, REGISTER);
+ } else {
+ instr->op_size = WORD;
+ instr->operand[1] = mk_operand(LONG, index, 0, REGISTER);
+ }
+ instr->operand[0] = mk_operand(instr->op_size, 0, 0, MEMORY);
+ return DECODE_success;
default:
- printf("0f %x, This opcode isn't handled yet\n", *opcode);
- return DECODE_failure;
+ printf("0f %x, This opcode isn't handled yet\n", *opcode);
+ return DECODE_failure;
}
}
@@ -593,7 +599,7 @@
}
void send_mmio_req(unsigned char type, unsigned long gpa,
- unsigned long count, int size, long value, int dir, int pvalid)
+ unsigned long count, int size, long value, int dir, int
pvalid)
{
struct vcpu *d = current;
vcpu_iodata_t *vio;
@@ -630,12 +636,12 @@
p->df = regs->eflags & EF_DF ? 1 : 0;
if (pvalid) {
- if (vmx_paging_enabled(current))
- p->u.pdata = (void *) gva_to_gpa(value);
+ if (vmx_paging_enabled(current))
+ p->u.pdata = (void *) gva_to_gpa(value);
else
- p->u.pdata = (void *) value; /* guest VA == guest PA */
+ p->u.pdata = (void *) value; /* guest VA == guest PA */
} else
- p->u.data = value;
+ p->u.data = value;
p->state = STATE_IOREQ_READY;
@@ -650,7 +656,7 @@
}
static void mmio_operands(int type, unsigned long gpa, struct instruction
*inst,
- struct mi_per_cpu_info *mpcip, struct cpu_user_regs *regs)
+ struct mi_per_cpu_info *mpcip, struct cpu_user_regs
*regs)
{
unsigned long value = 0;
int index, size;
@@ -663,24 +669,24 @@
mpcip->operand[1] = inst->operand[1]; /* destination */
if (inst->operand[0] & REGISTER) { /* dest is memory */
- index = operand_index(inst->operand[0]);
- value = get_reg_value(size, index, 0, regs);
- send_mmio_req(type, gpa, 1, size, value, IOREQ_WRITE, 0);
+ index = operand_index(inst->operand[0]);
+ value = get_reg_value(size, index, 0, regs);
+ send_mmio_req(type, gpa, 1, size, value, IOREQ_WRITE, 0);
} else if (inst->operand[0] & IMMEDIATE) { /* dest is memory */
- value = inst->immediate;
- send_mmio_req(type, gpa, 1, size, value, IOREQ_WRITE, 0);
+ value = inst->immediate;
+ send_mmio_req(type, gpa, 1, size, value, IOREQ_WRITE, 0);
} else if (inst->operand[0] & MEMORY) { /* dest is register */
- /* send the request and wait for the value */
- send_mmio_req(type, gpa, 1, size, 0, IOREQ_READ, 0);
+ /* send the request and wait for the value */
+ send_mmio_req(type, gpa, 1, size, 0, IOREQ_READ, 0);
} else {
- printf("mmio_operands: invalid operand\n");
- domain_crash_synchronous();
+ printf("mmio_operands: invalid operand\n");
+ domain_crash_synchronous();
}
}
#define GET_REPEAT_COUNT() \
(mmio_inst.flags & REPZ ? (vm86 ? regs->ecx & 0xFFFF : regs->ecx) : 1)
-
+
void handle_mmio(unsigned long va, unsigned long gpa)
{
unsigned long eip, eflags, cs;
@@ -715,11 +721,11 @@
init_instruction(&mmio_inst);
if (vmx_decode(inst, &mmio_inst) == DECODE_failure) {
- printf("mmio opcode: va 0x%lx, gpa 0x%lx, len %ld:",
- va, gpa, inst_len);
- for (i = 0; i < inst_len; i++)
- printf(" %02x", inst[i] & 0xFF);
- printf("\n");
+ printf("mmio opcode: va 0x%lx, gpa 0x%lx, len %ld:",
+ va, gpa, inst_len);
+ for (i = 0; i < inst_len; i++)
+ printf(" %02x", inst[i] & 0xFF);
+ printf("\n");
domain_crash_synchronous();
}
@@ -728,116 +734,116 @@
switch (mmio_inst.instr) {
case INSTR_MOV:
- mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mpcip, regs);
- break;
+ mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mpcip, regs);
+ break;
case INSTR_MOVS:
{
- unsigned long count = GET_REPEAT_COUNT();
- unsigned long size = mmio_inst.op_size;
- int sign = regs->eflags & EF_DF ? -1 : 1;
- unsigned long addr = 0;
- int dir;
-
- /* determine non-MMIO address */
- if (vm86) {
- unsigned long seg;
-
- __vmread(GUEST_ES_SELECTOR, &seg);
- if (((seg << 4) + (regs->edi & 0xFFFF)) == va) {
- dir = IOREQ_WRITE;
- __vmread(GUEST_DS_SELECTOR, &seg);
- addr = (seg << 4) + (regs->esi & 0xFFFF);
- } else {
- dir = IOREQ_READ;
- addr = (seg << 4) + (regs->edi & 0xFFFF);
- }
- } else {
- if (va == regs->edi) {
- dir = IOREQ_WRITE;
- addr = regs->esi;
- } else {
- dir = IOREQ_READ;
- addr = regs->edi;
- }
- }
-
- mpcip->flags = mmio_inst.flags;
- mpcip->instr = mmio_inst.instr;
-
- /*
- * In case of a movs spanning multiple pages, we break the accesses
- * up into multiple pages (the device model works with non-continguous
- * physical guest pages). To copy just one page, we adjust %ecx and
- * do not advance %eip so that the next "rep movs" copies the next page.
- * Unaligned accesses, for example movsl starting at PGSZ-2, are
- * turned into a single copy where we handle the overlapping memory
- * copy ourself. After this copy succeeds, "rep movs" is executed
- * again.
- */
- if ((addr & PAGE_MASK) != ((addr + size - 1) & PAGE_MASK)) {
- unsigned long value = 0;
-
- mpcip->flags |= OVERLAP;
-
- regs->eip -= inst_len; /* do not advance %eip */
-
- if (dir == IOREQ_WRITE)
- vmx_copy(&value, addr, size, VMX_COPY_IN);
- send_mmio_req(IOREQ_TYPE_COPY, gpa, 1, size, value, dir, 0);
- } else {
- if ((addr & PAGE_MASK) != ((addr + count * size - 1) & PAGE_MASK)) {
- regs->eip -= inst_len; /* do not advance %eip */
-
- if (sign > 0)
- count = (PAGE_SIZE - (addr & ~PAGE_MASK)) / size;
- else
- count = (addr & ~PAGE_MASK) / size;
- }
-
- send_mmio_req(IOREQ_TYPE_COPY, gpa, count, size, addr, dir, 1);
- }
+ unsigned long count = GET_REPEAT_COUNT();
+ unsigned long size = mmio_inst.op_size;
+ int sign = regs->eflags & EF_DF ? -1 : 1;
+ unsigned long addr = 0;
+ int dir;
+
+ /* determine non-MMIO address */
+ if (vm86) {
+ unsigned long seg;
+
+ __vmread(GUEST_ES_SELECTOR, &seg);
+ if (((seg << 4) + (regs->edi & 0xFFFF)) == va) {
+ dir = IOREQ_WRITE;
+ __vmread(GUEST_DS_SELECTOR, &seg);
+ addr = (seg << 4) + (regs->esi & 0xFFFF);
+ } else {
+ dir = IOREQ_READ;
+ addr = (seg << 4) + (regs->edi & 0xFFFF);
+ }
+ } else {
+ if (va == regs->edi) {
+ dir = IOREQ_WRITE;
+ addr = regs->esi;
+ } else {
+ dir = IOREQ_READ;
+ addr = regs->edi;
+ }
+ }
+
+ mpcip->flags = mmio_inst.flags;
+ mpcip->instr = mmio_inst.instr;
+
+ /*
+ * In case of a movs spanning multiple pages, we break the accesses
+ * up into multiple pages (the device model works with non-continguous
+ * physical guest pages). To copy just one page, we adjust %ecx and
+ * do not advance %eip so that the next "rep movs" copies the next
page.
+ * Unaligned accesses, for example movsl starting at PGSZ-2, are
+ * turned into a single copy where we handle the overlapping memory
+ * copy ourself. After this copy succeeds, "rep movs" is executed
+ * again.
+ */
+ if ((addr & PAGE_MASK) != ((addr + size - 1) & PAGE_MASK)) {
+ unsigned long value = 0;
+
+ mpcip->flags |= OVERLAP;
+
+ regs->eip -= inst_len; /* do not advance %eip */
+
+ if (dir == IOREQ_WRITE)
+ vmx_copy(&value, addr, size, VMX_COPY_IN);
+ send_mmio_req(IOREQ_TYPE_COPY, gpa, 1, size, value, dir, 0);
+ } else {
+ if ((addr & PAGE_MASK) != ((addr + count * size - 1) & PAGE_MASK))
{
+ regs->eip -= inst_len; /* do not advance %eip */
+
+ if (sign > 0)
+ count = (PAGE_SIZE - (addr & ~PAGE_MASK)) / size;
+ else
+ count = (addr & ~PAGE_MASK) / size;
+ }
+
+ send_mmio_req(IOREQ_TYPE_COPY, gpa, count, size, addr, dir, 1);
+ }
break;
}
case INSTR_MOVZ:
- mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mpcip, regs);
- break;
+ mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mpcip, regs);
+ break;
case INSTR_STOS:
- /*
- * Since the destination is always in (contiguous) mmio space we don't
- * need to break it up into pages.
- */
- mpcip->flags = mmio_inst.flags;
- mpcip->instr = mmio_inst.instr;
+ /*
+ * Since the destination is always in (contiguous) mmio space we don't
+ * need to break it up into pages.
+ */
+ mpcip->flags = mmio_inst.flags;
+ mpcip->instr = mmio_inst.instr;
send_mmio_req(IOREQ_TYPE_COPY, gpa,
- GET_REPEAT_COUNT(), mmio_inst.op_size, regs->eax, IOREQ_WRITE, 0);
- break;
+ GET_REPEAT_COUNT(), mmio_inst.op_size, regs->eax,
IOREQ_WRITE, 0);
+ break;
case INSTR_OR:
- mmio_operands(IOREQ_TYPE_OR, gpa, &mmio_inst, mpcip, regs);
- break;
+ mmio_operands(IOREQ_TYPE_OR, gpa, &mmio_inst, mpcip, regs);
+ break;
case INSTR_AND:
- mmio_operands(IOREQ_TYPE_AND, gpa, &mmio_inst, mpcip, regs);
- break;
+ mmio_operands(IOREQ_TYPE_AND, gpa, &mmio_inst, mpcip, regs);
+ break;
case INSTR_XOR:
- mmio_operands(IOREQ_TYPE_XOR, gpa, &mmio_inst, mpcip, regs);
- break;
+ mmio_operands(IOREQ_TYPE_XOR, gpa, &mmio_inst, mpcip, regs);
+ break;
case INSTR_CMP:
- mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mpcip, regs);
- break;
+ mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mpcip, regs);
+ break;
case INSTR_TEST:
- mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mpcip, regs);
- break;
+ mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mpcip, regs);
+ break;
default:
- printf("Unhandled MMIO instruction\n");
- domain_crash_synchronous();
+ printf("Unhandled MMIO instruction\n");
+ domain_crash_synchronous();
}
}
diff -r d4d880fcef28 -r b35215021b32 xen/arch/x86/vmx_vmcs.c
--- a/xen/arch/x86/vmx_vmcs.c Fri Sep 9 16:31:36 2005
+++ b/xen/arch/x86/vmx_vmcs.c Tue Sep 13 16:14:16 2005
@@ -179,10 +179,10 @@
p = map_domain_page(mpfn);
d->domain->arch.vmx_platform.shared_page_va = (unsigned long)p;
- VMX_DBG_LOG(DBG_LEVEL_1, "eport: %x\n", iopacket_port(d->domain));
-
- clear_bit(iopacket_port(d->domain),
- &d->domain->shared_info->evtchn_mask[0]);
+ VMX_DBG_LOG(DBG_LEVEL_1, "eport: %x\n", iopacket_port(d->domain));
+
+ clear_bit(iopacket_port(d->domain),
+ &d->domain->shared_info->evtchn_mask[0]);
return 0;
}
@@ -497,7 +497,7 @@
__vmptrst(old_phys_ptr);
if ((error = load_vmcs(arch_vmx, vmcs_phys_ptr))) {
printk("modify_vmcs: load_vmcs failed: VMCS = %lx\n",
- (unsigned long) vmcs_phys_ptr);
+ (unsigned long) vmcs_phys_ptr);
return -EINVAL;
}
load_cpu_user_regs(regs);
diff -r d4d880fcef28 -r b35215021b32 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S Fri Sep 9 16:31:36 2005
+++ b/xen/arch/x86/x86_32/entry.S Tue Sep 13 16:14:16 2005
@@ -834,7 +834,7 @@
.byte 4 /* do_update_va_mapping */
.byte 2 /* do_set_timer_op */ /* 15 */
.byte 1 /* do_event_channel_op */
- .byte 1 /* do_xen_version */
+ .byte 2 /* do_xen_version */
.byte 3 /* do_console_io */
.byte 1 /* do_physdev_op */
.byte 3 /* do_grant_table_op */ /* 20 */
diff -r d4d880fcef28 -r b35215021b32 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S Fri Sep 9 16:31:36 2005
+++ b/xen/arch/x86/x86_64/entry.S Tue Sep 13 16:14:16 2005
@@ -655,7 +655,7 @@
.byte 3 /* do_update_va_mapping */
.byte 1 /* do_set_timer_op */ /* 15 */
.byte 1 /* do_event_channel_op */
- .byte 1 /* do_xen_version */
+ .byte 2 /* do_xen_version */
.byte 3 /* do_console_io */
.byte 1 /* do_physdev_op */
.byte 3 /* do_grant_table_op */ /* 20 */
diff -r d4d880fcef28 -r b35215021b32 xen/arch/x86/x86_64/traps.c
--- a/xen/arch/x86/x86_64/traps.c Fri Sep 9 16:31:36 2005
+++ b/xen/arch/x86/x86_64/traps.c Tue Sep 13 16:14:16 2005
@@ -12,25 +12,51 @@
#include <asm/current.h>
#include <asm/flushtlb.h>
#include <asm/msr.h>
+#include <asm/vmx.h>
void show_registers(struct cpu_user_regs *regs)
{
- printk("CPU: %d\nRIP: %04x:[<%016lx>]",
- smp_processor_id(), 0xffff & regs->cs, regs->rip);
+ unsigned long rip, rsp, rflags, cs, cr0, cr3;
+ const char *context;
+
+ if ( VMX_DOMAIN(current) && (regs->eflags == 0) )
+ {
+ __vmread(GUEST_RIP, &rip);
+ __vmread(GUEST_RSP, &rsp);
+ __vmread(GUEST_RFLAGS, &rflags);
+ __vmread(GUEST_CS_SELECTOR, &cs);
+ __vmread(CR0_READ_SHADOW, &cr0);
+ __vmread(GUEST_CR3, &cr3);
+ context = "vmx guest";
+ }
+ else
+ {
+ rip = regs->rip;
+ rflags = regs->rflags;
+ cr0 = read_cr0();
+ cr3 = read_cr3();
+ rsp = regs->rsp;
+ cs = regs->cs & 0xffff;
+ context = GUEST_MODE(regs) ? "guest" : "hypervisor";
+ }
+
+ printk("CPU: %d\nRIP: %04lx:[<%016lx>]",
+ smp_processor_id(), cs, rip);
if ( !GUEST_MODE(regs) )
- print_symbol(" %s", regs->rip);
- printk("\nRFLAGS: %016lx\n", regs->eflags);
+ print_symbol(" %s", rip);
+ printk("\nRFLAGS: %016lx CONTEXT: %s\n", rflags, context);
printk("rax: %016lx rbx: %016lx rcx: %016lx\n",
regs->rax, regs->rbx, regs->rcx);
printk("rdx: %016lx rsi: %016lx rdi: %016lx\n",
regs->rdx, regs->rsi, regs->rdi);
printk("rbp: %016lx rsp: %016lx r8: %016lx\n",
- regs->rbp, regs->rsp, regs->r8);
+ regs->rbp, rsp, regs->r8);
printk("r9: %016lx r10: %016lx r11: %016lx\n",
regs->r9, regs->r10, regs->r11);
printk("r12: %016lx r13: %016lx r14: %016lx\n",
regs->r12, regs->r13, regs->r14);
- printk("r15: %016lx\n", regs->r15);
+ printk("r15: %016lx cr0: %016lx cr3: %016lx\n",
+ regs->r15, cr0, cr3);
show_stack(regs);
}
@@ -194,3 +220,13 @@
return 0;
}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r d4d880fcef28 -r b35215021b32 xen/common/Makefile
--- a/xen/common/Makefile Fri Sep 9 16:31:36 2005
+++ b/xen/common/Makefile Tue Sep 13 16:14:16 2005
@@ -19,3 +19,6 @@
clean:
rm -f *.o *~ core
+
+# Object file contains changeset and compiler information.
+kernel.o: $(BASEDIR)/include/xen/compile.h
diff -r d4d880fcef28 -r b35215021b32 xen/common/kernel.c
--- a/xen/common/kernel.c Fri Sep 9 16:31:36 2005
+++ b/xen/common/kernel.c Tue Sep 13 16:14:16 2005
@@ -114,12 +114,12 @@
case XENVER_capabilities:
{
xen_capabilities_info_t info;
- extern void arch_get_xen_caps(xen_capabilities_info_t * info);
-
- memset(&info, 0, sizeof(info));
- arch_get_xen_caps(&info);
+ extern void arch_get_xen_caps(xen_capabilities_info_t info);
- if ( copy_to_user(arg, &info, sizeof(info)) )
+ memset(info, 0, sizeof(info));
+ arch_get_xen_caps(info);
+
+ if ( copy_to_user(arg, info, sizeof(info)) )
return -EFAULT;
return 0;
}
@@ -127,7 +127,6 @@
case XENVER_parameters:
{
xen_parameters_info_t info = { .virt_start = HYPERVISOR_VIRT_START };
-
if ( copy_to_user(arg, &info, sizeof(info)) )
return -EFAULT;
return 0;
diff -r d4d880fcef28 -r b35215021b32 xen/common/memory.c
--- a/xen/common/memory.c Fri Sep 9 16:31:36 2005
+++ b/xen/common/memory.c Tue Sep 13 16:14:16 2005
@@ -29,7 +29,7 @@
int *preempted)
{
struct pfn_info *page;
- unsigned long i;
+ unsigned int i;
if ( (extent_list != NULL) &&
!array_access_ok(extent_list, nr_extents, sizeof(*extent_list)) )
@@ -37,7 +37,7 @@
if ( (extent_order != 0) && !IS_CAPABLE_PHYSDEV(current->domain) )
{
- DPRINTK("Only I/O-capable domains may allocate > order-0 memory.\n");
+ DPRINTK("Only I/O-capable domains may allocate multi-page extents.\n");
return 0;
}
@@ -52,8 +52,9 @@
if ( unlikely((page = alloc_domheap_pages(
d, extent_order, flags)) == NULL) )
{
- DPRINTK("Could not allocate order=%d extent: id=%d flags=%x\n",
- extent_order, d->domain_id, flags);
+ DPRINTK("Could not allocate order=%d extent: "
+ "id=%d flags=%x (%d of %d)\n",
+ extent_order, d->domain_id, flags, i, nr_extents);
return i;
}
diff -r d4d880fcef28 -r b35215021b32 xen/drivers/char/Makefile
--- a/xen/drivers/char/Makefile Fri Sep 9 16:31:36 2005
+++ b/xen/drivers/char/Makefile Tue Sep 13 16:14:16 2005
@@ -8,4 +8,5 @@
clean:
rm -f *.o *~ core
+# Object file contains changeset and compiler information.
console.o: $(BASEDIR)/include/xen/compile.h
diff -r d4d880fcef28 -r b35215021b32 xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h Fri Sep 9 16:31:36 2005
+++ b/xen/include/asm-x86/mm.h Tue Sep 13 16:14:16 2005
@@ -98,9 +98,10 @@
/* 16-bit count of uses of this frame as its current type. */
#define PGT_count_mask ((1U<<16)-1)
-#define PGT_mfn_mask ((1U<<20)-1) /* mfn mask for shadow types */
-
-#define PGT_score_shift 20
+ /* 23-bit mfn mask for shadow types: good for up to 32GB RAM. */
+#define PGT_mfn_mask ((1U<<23)-1)
+
+#define PGT_score_shift 23
#define PGT_score_mask (((1U<<4)-1)<<PGT_score_shift)
/* Cleared when the owning guest 'frees' this page. */
diff -r d4d880fcef28 -r b35215021b32 xen/include/asm-x86/shadow_64.h
--- a/xen/include/asm-x86/shadow_64.h Fri Sep 9 16:31:36 2005
+++ b/xen/include/asm-x86/shadow_64.h Tue Sep 13 16:14:16 2005
@@ -353,7 +353,7 @@
entry_remove_flags(sle, _PAGE_PSE);
if ( shadow_mode_log_dirty(d) ||
- !(entry_get_flags(gle) & _PAGE_DIRTY) )
+ !(entry_get_flags(gle) & _PAGE_DIRTY) )
{
pgentry_64_t *l1_p;
int i;
@@ -365,8 +365,9 @@
unmap_domain_page(l1_p);
}
} else {
- sle = entry_from_pfn(smfn,
- (entry_get_flags(gle) | _PAGE_RW |
_PAGE_ACCESSED) & ~_PAGE_AVAIL);
+ sle = entry_from_pfn(
+ smfn,
+ (entry_get_flags(gle) | _PAGE_RW | _PAGE_ACCESSED) &
~_PAGE_AVAIL);
entry_add_flags(gle, _PAGE_ACCESSED);
}
// XXX mafetter: Hmm...
diff -r d4d880fcef28 -r b35215021b32 xen/include/asm-x86/shadow_ops.h
--- a/xen/include/asm-x86/shadow_ops.h Fri Sep 9 16:31:36 2005
+++ b/xen/include/asm-x86/shadow_ops.h Tue Sep 13 16:14:16 2005
@@ -127,4 +127,4 @@
#define guest_va_to_l1mfn va_to_l1mfn
#endif
-#endif /* _XEN_SHADOW_OPS_H */
+#endif /* _XEN_SHADOW_OPS_H */
diff -r d4d880fcef28 -r b35215021b32 xen/include/asm-x86/vmx.h
--- a/xen/include/asm-x86/vmx.h Fri Sep 9 16:31:36 2005
+++ b/xen/include/asm-x86/vmx.h Tue Sep 13 16:14:16 2005
@@ -28,6 +28,8 @@
#include <public/io/ioreq.h>
+extern int hvm_enabled;
+
extern void vmx_asm_vmexit_handler(struct cpu_user_regs);
extern void vmx_asm_do_resume(void);
extern void vmx_asm_do_launch(void);
@@ -148,9 +150,9 @@
#define TYPE_MOV_TO_CR (0 << 4)
#define TYPE_MOV_FROM_CR (1 << 4)
#define TYPE_CLTS (2 << 4)
-#define TYPE_LMSW (3 << 4)
+#define TYPE_LMSW (3 << 4)
#define CONTROL_REG_ACCESS_REG 0xf00 /* 10:8, general purpose
register */
-#define LMSW_SOURCE_DATA (0xFFFF << 16) /* 16:31 lmsw
source */
+#define LMSW_SOURCE_DATA (0xFFFF << 16) /* 16:31 lmsw source */
#define REG_EAX (0 << 8)
#define REG_ECX (1 << 8)
#define REG_EDX (2 << 8)
diff -r d4d880fcef28 -r b35215021b32 xen/include/asm-x86/vmx_platform.h
--- a/xen/include/asm-x86/vmx_platform.h Fri Sep 9 16:31:36 2005
+++ b/xen/include/asm-x86/vmx_platform.h Tue Sep 13 16:14:16 2005
@@ -16,6 +16,7 @@
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
*/
+
#ifndef __ASM_X86_VMX_PLATFORM_H__
#define __ASM_X86_VMX_PLATFORM_H__
@@ -52,19 +53,19 @@
#define REPNZ 0x2
#define OVERLAP 0x4
-#define INSTR_PIO 1
-#define INSTR_OR 2
-#define INSTR_AND 3
-#define INSTR_XOR 4
-#define INSTR_CMP 5
-#define INSTR_MOV 6
-#define INSTR_MOVS 7
-#define INSTR_MOVZ 8
-#define INSTR_STOS 9
-#define INSTR_TEST 10
+#define INSTR_PIO 1
+#define INSTR_OR 2
+#define INSTR_AND 3
+#define INSTR_XOR 4
+#define INSTR_CMP 5
+#define INSTR_MOV 6
+#define INSTR_MOVS 7
+#define INSTR_MOVZ 8
+#define INSTR_STOS 9
+#define INSTR_TEST 10
struct instruction {
- __s8 instr; /* instruction type */
+ __s8 instr; /* instruction type */
__s16 op_size; /* the operand's bit size, e.g. 16-bit or 32-bit */
__u64 immediate;
__u16 seg_sel; /* segmentation selector */
@@ -76,18 +77,18 @@
struct mi_per_cpu_info {
int flags;
- int instr; /* instruction */
- unsigned long operand[2]; /* operands */
- unsigned long immediate; /* immediate portion */
- struct cpu_user_regs *inst_decoder_regs; /* current context */
+ int instr; /* instruction */
+ unsigned long operand[2]; /* operands */
+ unsigned long immediate; /* immediate portion */
+ struct cpu_user_regs *inst_decoder_regs; /* current context */
};
struct virtual_platform_def {
- unsigned long *real_mode_data; /* E820, etc. */
+ unsigned long *real_mode_data; /* E820, etc. */
unsigned long shared_page_va;
struct vmx_virpit_t vmx_pit;
struct vmx_handler_t vmx_handler;
- struct mi_per_cpu_info mpci; /* MMIO */
+ struct mi_per_cpu_info mpci; /* MMIO */
};
extern void handle_mmio(unsigned long, unsigned long);
diff -r d4d880fcef28 -r b35215021b32 xen/include/asm-x86/vmx_virpit.h
--- a/xen/include/asm-x86/vmx_virpit.h Fri Sep 9 16:31:36 2005
+++ b/xen/include/asm-x86/vmx_virpit.h Tue Sep 13 16:14:16 2005
@@ -1,5 +1,6 @@
#ifndef _VMX_VIRPIT_H
#define _VMX_VIRPIT_H
+
#include <xen/config.h>
#include <xen/init.h>
#include <xen/lib.h>
@@ -17,14 +18,14 @@
struct vmx_virpit_t {
/* for simulation of counter 0 in mode 2*/
- int vector; /* the pit irq vector */
- unsigned int period; /* the frequency. e.g. 10ms*/
+ int vector; /* the pit irq vector */
+ unsigned int period; /* the frequency. e.g. 10ms*/
s_time_t scheduled; /* scheduled timer interrupt */
- unsigned int channel; /* the pit channel, counter 0~2 */
+ unsigned int channel; /* the pit channel, counter 0~2 */
u64 *intr_bitmap;
- unsigned int pending_intr_nr; /* the couner for pending timer
interrupts */
- unsigned long long inject_point; /* the time inject virt intr */
- struct ac_timer pit_timer; /* periodic timer for mode 2*/
+ unsigned int pending_intr_nr; /* the couner for pending timer interrupts */
+ unsigned long long inject_point; /* the time inject virt intr */
+ struct ac_timer pit_timer; /* periodic timer for mode 2*/
int first_injected; /* flag to prevent shadow window */
/* virtual PIT state for handle related I/O */
@@ -32,8 +33,8 @@
int count_LSB_latched;
int count_MSB_latched;
- unsigned int count; /* the 16 bit channel count */
- unsigned int init_val; /* the init value for the counter */
+ unsigned int count; /* the 16 bit channel count */
+ unsigned int init_val; /* the init value for the counter */
} ;
diff -r d4d880fcef28 -r b35215021b32 xen/include/public/version.h
--- a/xen/include/public/version.h Fri Sep 9 16:31:36 2005
+++ b/xen/include/public/version.h Tue Sep 13 16:14:16 2005
@@ -29,16 +29,14 @@
} xen_compile_info_t;
#define XENVER_capabilities 3
-typedef struct xen_capabilities_info {
- char caps[1024];
-} xen_capabilities_info_t;
+typedef char xen_capabilities_info_t[1024];
#define XENVER_changeset 4
typedef char xen_changeset_info_t[64];
#define XENVER_parameters 5
-typedef struct xen_paramaters_info {
-unsigned long virt_start;
+typedef struct xen_parameters_info {
+ unsigned long virt_start;
} xen_parameters_info_t;
#endif /* __XEN_PUBLIC_VERSION_H__ */
diff -r d4d880fcef28 -r b35215021b32 docs/Doxyfile
--- /dev/null Fri Sep 9 16:31:36 2005
+++ b/docs/Doxyfile Tue Sep 13 16:14:16 2005
@@ -0,0 +1,1218 @@
+# Doxyfile 1.4.2
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = Xen Python Tools
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = api/tools/python
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish,
+# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese,
+# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish,
+# Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# This tag can be used to specify the encoding used in the generated output.
+# The encoding is not always determined by the language that is chosen,
+# but also whether or not the output is meant for Windows or non-Windows
users.
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
+# forces the Windows encoding (this is the default for the Windows binary),
+# whereas setting the tag to NO uses a Unix-style encoding (the default for
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed
description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and
assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
sources
+# only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = YES
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the
documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory
hierarchy
+# in the documentation.
+
+SHOW_DIRECTORIES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically
from the
+# version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the progam writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their
parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that
contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = ../tools/python/xen/
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
*.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
+
+FILE_PATTERNS = *.py *.c
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT
tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+
+EXCLUDE_PATTERNS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER = "sh ./Doxyfilter ../tools/python"
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these
sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be
expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with
base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph
visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
+# generate a call dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a
run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_WIDTH = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that a graph may be further truncated if the graph's
+# image dimensions are not sufficient to fit the graph (see
MAX_DOT_GRAPH_WIDTH
+# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default),
+# the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, which results in a white
background.
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
diff -r d4d880fcef28 -r b35215021b32 docs/Doxyfilter
--- /dev/null Fri Sep 9 16:31:36 2005
+++ b/docs/Doxyfilter Tue Sep 13 16:14:16 2005
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+#
+# Doxyfilter <source-root> <filename>
+#
+
+dir=$(dirname "$0")
+
+PYFILTER="$dir/pythfilter.py"
+
+if [ "${2/.py/}" != "$2" ]
+then
+ python "$PYFILTER" -r "$1" -f "$2"
+else
+ cat "$2"
+fi
diff -r d4d880fcef28 -r b35215021b32 docs/pythfilter.py
--- /dev/null Fri Sep 9 16:31:36 2005
+++ b/docs/pythfilter.py Tue Sep 13 16:14:16 2005
@@ -0,0 +1,658 @@
+#!/usr/bin/env python
+
+# pythfilter.py v1.5.5, written by Matthias Baas (baas@xxxxxxxxxx)
+
+# Doxygen filter which can be used to document Python source code.
+# Classes (incl. methods) and functions can be documented.
+# Every comment that begins with ## is literally turned into an
+# Doxygen comment. Consecutive comment lines are turned into
+# comment blocks (-> /** ... */).
+# All the stuff is put inside a namespace with the same name as
+# the source file.
+
+# Conversions:
+# ============
+# ##-blocks -> /** ... */
+# "class name(base): ..." -> "class name : public base {...}"
+# "def name(params): ..." -> "name(params) {...}"
+
+# Changelog:
+# 21.01.2003: Raw (r"") or unicode (u"") doc string will now be properly
+# handled. (thanks to Richard Laager for the patch)
+# 22.12.2003: Fixed a bug where no function names would be output for "def"
+# blocks that were not in a class.
+# (thanks to Richard Laager for the patch)
+# 12.12.2003: Implemented code to handle static and class methods with
+# this logic: Methods with "self" as the first argument are
+# non-static. Methods with "cls" are Python class methods,
+# which translate into static methods for Doxygen. Other
+# methods are assumed to be static methods. As should be
+# obvious, this logic doesn't take into account if the method
+# is actually setup as a classmethod() or a staticmethod(),
+# just if it follows the normal conventions.
+# (thanks to Richard Laager for the patch)
+# 11.12.2003: Corrected #includes to use os.path.sep instead of ".". Corrected
+# namespace code to use "::" instead of ".".
+# (thanks to Richard Laager for the patch)
+# 11.12.2003: Methods beginning with two underscores that end with
+# something other than two underscores are considered private
+# and are handled accordingly.
+# (thanks to Richard Laager for the patch)
+# 03.12.2003: The first parameter of class methods (self) is removed from
+# the documentation.
+# 03.11.2003: The module docstring will be used as namespace documentation
+# (thanks to Joe Bronkema for the patch)
+# 08.07.2003: Namespaces get a default documentation so that the namespace
+# and its contents will show up in the generated documentation.
+# 05.02.2003: Directories will be delted during synchronization.
+# 31.01.2003: -f option & filtering entire directory trees.
+# 10.08.2002: In base classes the '.' will be replaced by '::'
+# 18.07.2002: * and ** will be translated into arguments
+# 18.07.2002: Argument lists may contain default values using constructors.
+# 18.06.2002: Support for ## public:
+# 21.01.2002: from ... import will be translated to "using namespace ...;"
+# TODO: "from ... import *" vs "from ... import names"
+# TODO: Using normal imports: name.name -> name::name
+# 20.01.2002: #includes will be placed in front of the namespace
+
+######################################################################
+
+# The program is written as a state machine with the following states:
+#
+# - OUTSIDE The current position is outside any comment,
+# class definition or function.
+#
+# - BUILD_COMMENT Begins with first "##".
+# Ends with the first token that is no "##"
+# at the same column as before.
+#
+# - BUILD_CLASS_DECL Begins with "class".
+# Ends with ":"
+# - BUILD_CLASS_BODY Begins just after BUILD_CLASS_DECL.
+# The first following token (which is no comment)
+# determines indentation depth.
+# Ends with a token that has a smaller indendation.
+#
+# - BUILD_DEF_DECL Begins with "def".
+# Ends with ":".
+# - BUILD_DEF_BODY Begins just after BUILD_DEF_DECL.
+# The first following token (which is no comment)
+# determines indentation depth.
+# Ends with a token that has a smaller indendation.
+
+import getopt
+import glob
+import os.path
+import re
+import shutil
+import string
+import sys
+import token
+import tokenize
+
+from stat import *
+
+OUTSIDE = 0
+BUILD_COMMENT = 1
+BUILD_CLASS_DECL = 2
+BUILD_CLASS_BODY = 3
+BUILD_DEF_DECL = 4
+BUILD_DEF_BODY = 5
+IMPORT = 6
+IMPORT_OP = 7
+IMPORT_APPEND = 8
+
+# Output file stream
+outfile = sys.stdout
+
+# Output buffer
+outbuffer = []
+
+out_row = 1
+out_col = 0
+
+# Variables used by rec_name_n_param()
+name = ""
+param = ""
+doc_string = ""
+record_state = 0
+bracket_counter = 0
+
+# Tuple: (row,column)
+class_spos = (0,0)
+def_spos = (0,0)
+import_spos = (0,0)
+
+# Which import was used? ("import" or "from")
+import_token = ""
+
+# Comment block buffer
+comment_block = []
+comment_finished = 0
+
+# Imported modules
+modules = []
+
+# Program state
+stateStack = [OUTSIDE]
+
+# Keep track of whether module has a docstring
+module_has_docstring = False
+
+# Keep track of member protection
+protection_level = "public"
+private_member = False
+
+# Keep track of the module namespace
+namespace = ""
+
+######################################################################
+# Output string s. '\n' may only be at the end of the string (not
+# somewhere in the middle).
+#
+# In: s - String
+# spos - Startpos
+######################################################################
+def output(s,spos, immediate=0):
+ global outbuffer, out_row, out_col, outfile
+
+ os = string.rjust(s,spos[1]-out_col+len(s))
+
+ if immediate:
+ outfile.write(os)
+ else:
+ outbuffer.append(os)
+
+ assert -1 == string.find(s[0:-2], "\n"), s
+
+ if (s[-1:]=="\n"):
+ out_row = out_row+1
+ out_col = 0
+ else:
+ out_col = spos[1]+len(s)
+
+
+######################################################################
+# Records a name and parameters. The name is either a class name or
+# a function name. Then the parameter is either the base class or
+# the function parameters.
+# The name is stored in the global variable "name", the parameters
+# in "param".
+# The variable "record_state" holds the current state of this internal
+# state machine.
+# The recording is started by calling start_recording().
+#
+# In: type, tok
+######################################################################
+def rec_name_n_param(type, tok):
+ global record_state,name,param,doc_string,bracket_counter
+ s = record_state
+ # State 0: Do nothing.
+ if (s==0):
+ return
+ # State 1: Remember name.
+ elif (s==1):
+ name = tok
+ record_state = 2
+ # State 2: Wait for opening bracket or colon
+ elif (s==2):
+ if (tok=='('):
+ bracket_counter = 1
+ record_state=3
+ if (tok==':'): record_state=4
+ # State 3: Store parameter (or base class) and wait for an ending bracket
+ elif (s==3):
+ if (tok=='*' or tok=='**'):
+ tok=''
+ if (tok=='('):
+ bracket_counter = bracket_counter+1
+ if (tok==')'):
+ bracket_counter = bracket_counter-1
+ if bracket_counter==0:
+ record_state=4
+ else:
+ param=param+tok
+ # State 4: Look for doc string
+ elif (s==4):
+ if (type==token.NEWLINE or type==token.INDENT or
type==token.SLASHEQUAL):
+ return
+ elif (tok==":"):
+ return
+ elif (type==token.STRING):
+ while tok[:1]=='r' or tok[:1]=='u':
+ tok=tok[1:]
+ while tok[:1]=='"':
+ tok=tok[1:]
+ while tok[-1:]=='"':
+ tok=tok[:-1]
+ doc_string=tok
+ record_state=0
+
+######################################################################
+# Starts the recording of a name & param part.
+# The function rec_name_n_param() has to be fed with tokens. After
+# the necessary tokens are fed the name and parameters can be found
+# in the global variables "name" und "param".
+######################################################################
+def start_recording():
+ global record_state,param,name, doc_string
+ record_state=1
+ name=""
+ param=""
+ doc_string=""
+
+######################################################################
+# Test if recording is finished
+######################################################################
+def is_recording_finished():
+ global record_state
+ return record_state==0
+
+######################################################################
+## Gather comment block
+######################################################################
+def gather_comment(type,tok,spos):
+ global comment_block,comment_finished
+ if (type!=tokenize.COMMENT):
+ comment_finished = 1
+ else:
+ # Output old comment block if a new one is started.
+ if (comment_finished):
+ print_comment(spos)
+ comment_finished=0
+ if (tok[0:2]=="##" and tok[0:3]!="###"):
+ append_comment_lines(tok[2:])
+
+######################################################################
+## Output comment block and empty buffer.
+######################################################################
+def print_comment(spos):
+ global comment_block,comment_finished
+ if (comment_block!=[]):
+ output("/** ",spos)
+ for c in comment_block:
+ output(c,spos)
+ output("*/\n",spos)
+ comment_block = []
+ comment_finished = 0
+
+######################################################################
+def set_state(s):
+ global stateStack
+ stateStack[len(stateStack)-1]=s
+
+######################################################################
+def get_state():
+ global stateStack
+ return stateStack[len(stateStack)-1]
+
+######################################################################
+def push_state(s):
+ global stateStack
+ stateStack.append(s)
+
+######################################################################
+def pop_state():
+ global stateStack
+ stateStack.pop()
+
+
+######################################################################
+def tok_eater(type, tok, spos, epos, line):
+ global stateStack,name,param,class_spos,def_spos,import_spos
+ global doc_string, modules, import_token, module_has_docstring
+ global protection_level, private_member
+ global out_row
+
+ while out_row + 1 < spos[0]:
+ output("\n", (0, 0))
+
+ rec_name_n_param(type,tok)
+ if (string.replace(string.strip(tok)," ","")=="##private:"):
+ protection_level = "private"
+ output("private:\n",spos)
+ elif (string.replace(string.strip(tok)," ","")=="##protected:"):
+ protection_level = "protected"
+ output("protected:\n",spos)
+ elif (string.replace(string.strip(tok)," ","")=="##public:"):
+ protection_level = "public"
+ output("public:\n",spos)
+ else:
+ gather_comment(type,tok,spos)
+
+ state = get_state()
+
+# sys.stderr.write("%d: %s\n"%(state, tok))
+
+ # OUTSIDE
+ if (state==OUTSIDE):
+ if (tok=="class"):
+ start_recording()
+ class_spos = spos
+ push_state(BUILD_CLASS_DECL)
+ elif (tok=="def"):
+ start_recording()
+ def_spos = spos
+ push_state(BUILD_DEF_DECL)
+ elif (tok=="import") or (tok=="from"):
+ import_token = tok
+ import_spos = spos
+ modules = []
+ push_state(IMPORT)
+ elif (spos[1] == 0 and tok[:3] == '"""'):
+ # Capture module docstring as namespace documentation
+ module_has_docstring = True
+ append_comment_lines("\\namespace %s\n" % namespace)
+ append_comment_lines(tok[3:-3])
+ print_comment(spos)
+
+ # IMPORT
+ elif (state==IMPORT):
+ if (type==token.NAME):
+ modules.append(tok)
+ set_state(IMPORT_OP)
+ # IMPORT_OP
+ elif (state==IMPORT_OP):
+ if (tok=="."):
+ set_state(IMPORT_APPEND)
+ elif (tok==","):
+ set_state(IMPORT)
+ else:
+ for m in modules:
+ output('#include "'+m.replace('.',os.path.sep)+'.py"\n',
import_spos, immediate=1)
+ if import_token=="from":
+ output('using namespace '+m.replace('.', '::')+';\n',
import_spos)
+ pop_state()
+ # IMPORT_APPEND
+ elif (state==IMPORT_APPEND):
+ if (type==token.NAME):
+ modules[len(modules)-1]+="."+tok
+ set_state(IMPORT_OP)
+ # BUILD_CLASS_DECL
+ elif (state==BUILD_CLASS_DECL):
+ if (is_recording_finished()):
+ s = "class "+name
+ if (param!=""): s = s+" : public "+param.replace('.','::')
+ if (doc_string!=""):
+ append_comment_lines(doc_string)
+ print_comment(class_spos)
+ output(s+"\n",class_spos)
+ output("{\n",(class_spos[0]+1,class_spos[1]))
+ protection_level = "public"
+ output(" public:\n",(class_spos[0]+2,class_spos[1]))
+ set_state(BUILD_CLASS_BODY)
+ # BUILD_CLASS_BODY
+ elif (state==BUILD_CLASS_BODY):
+ if (type!=token.INDENT and type!=token.NEWLINE and type!=40 and
+ type!=tokenize.NL and type!=tokenize.COMMENT and
+ (spos[1]<=class_spos[1])):
+ output("}; // end of class\n",(out_row+1,class_spos[1]))
+ pop_state()
+ elif (tok=="def"):
+ start_recording()
+ def_spos = spos
+ push_state(BUILD_DEF_DECL)
+ # BUILD_DEF_DECL
+ elif (state==BUILD_DEF_DECL):
+ if (is_recording_finished()):
+ param = param.replace("\n", " ")
+ param = param.replace("=", " = ")
+ params = param.split(",")
+ if BUILD_CLASS_BODY in stateStack:
+ if len(name) > 1 \
+ and name[0:2] == '__' \
+ and name[len(name)-2:len(name)] != '__' \
+ and protection_level != 'private':
+ private_member = True
+ output(" private:\n",(def_spos[0]+2,def_spos[1]))
+
+ if (doc_string != ""):
+ append_comment_lines(doc_string)
+
+ print_comment(def_spos)
+
+ output_function_decl(name, params)
+# output("{\n",(def_spos[0]+1,def_spos[1]))
+ set_state(BUILD_DEF_BODY)
+ # BUILD_DEF_BODY
+ elif (state==BUILD_DEF_BODY):
+ if (type!=token.INDENT and type!=token.NEWLINE \
+ and type!=40 and type!=tokenize.NL \
+ and (spos[1]<=def_spos[1])):
+# output("} // end of method/function\n",(out_row+1,def_spos[1]))
+ if private_member and protection_level != 'private':
+ private_member = False
+ output(" " + protection_level +
":\n",(def_spos[0]+2,def_spos[1]))
+ pop_state()
+# else:
+# output(tok,spos)
+
+
+def output_function_decl(name, params):
+ global def_spos
+
+ # Do we document a class method? then remove the 'self' parameter
+ if params[0] == 'self':
+ preamble = ''
+ params = params[1:]
+ else:
+ preamble = 'static '
+ if params[0] == 'cls':
+ params = params[1:]
+
+ param_string = string.join(params, ", Type ")
+
+ if param_string == '':
+ param_string = '(' + param_string + ');\n'
+ else:
+ param_string = '(Type ' + param_string + ');\n'
+
+ output(preamble, def_spos)
+ output(name, def_spos)
+ output(param_string, def_spos)
+
+
+def append_comment_lines(lines):
+ map(append_comment_line, doc_string.split('\n'))
+
+paramRE = re.compile(r'(@param \w+):')
+
+def append_comment_line(line):
+ global paramRE
+
+ comment_block.append(paramRE.sub(r'\1', line) + '\n')
+
+def dump(filename):
+ f = open(filename)
+ r = f.readlines()
+ for s in r:
+ sys.stdout.write(s)
+
+def filter(filename):
+ global name, module_has_docstring, source_root
+
+ path,name = os.path.split(filename)
+ root,ext = os.path.splitext(name)
+
+ if source_root and path.find(source_root) == 0:
+ path = path[len(source_root):]
+
+ if path[0] == os.sep:
+ path = path[1:]
+
+ ns = path.split(os.sep)
+ else:
+ ns = []
+
+ ns.append(root)
+
+ for n in ns:
+ output("namespace " + n + " {\n",(0,0))
+
+ # set module name for tok_eater to use if there's a module doc string
+ name = root
+
+# sys.stderr.write('Filtering "'+filename+'"...')
+ f = open(filename)
+ tokenize.tokenize(f.readline, tok_eater)
+ f.close()
+ print_comment((0,0))
+
+ output("\n",(0,0))
+
+ for n in ns:
+ output("} // end of namespace\n",(0,0))
+
+ if not module_has_docstring:
+ # Put in default namespace documentation
+ output('/** \\namespace '+root+' \n',(0,0))
+ output(' \\brief Module "%s" */\n'%(root),(0,0))
+
+ for s in outbuffer:
+ outfile.write(s)
+
+
+def filterFile(filename, out=sys.stdout):
+ global outfile
+
+ outfile = out
+
+ try:
+ root,ext = os.path.splitext(filename)
+
+ if ext==".py":
+ filter(filename)
+ else:
+ dump(filename)
+
+# sys.stderr.write("OK\n")
+ except IOError,e:
+ sys.stderr.write(e[1]+"\n")
+
+
+######################################################################
+
+# preparePath
+def preparePath(path):
+ """Prepare a path.
+
+ Checks if the path exists and creates it if it does not exist.
+ """
+ if not os.path.exists(path):
+ parent = os.path.dirname(path)
+ if parent!="":
+ preparePath(parent)
+ os.mkdir(path)
+
+# isNewer
+def isNewer(file1,file2):
+ """Check if file1 is newer than file2.
+
+ file1 must be an existing file.
+ """
+ if not os.path.exists(file2):
+ return True
+ return os.stat(file1)[ST_MTIME]>os.stat(file2)[ST_MTIME]
+
+# convert
+def convert(srcpath, destpath):
+ """Convert a Python source tree into a C+ stub tree.
+
+ All *.py files in srcpath (including sub-directories) are filtered
+ and written to destpath. If destpath exists, only the files
+ that have been modified are filtered again. Files that were deleted
+ from srcpath are also deleted in destpath if they are still present.
+ The function returns the number of processed *.py files.
+ """
+ count=0
+ sp = os.path.join(srcpath,"*")
+ sfiles = glob.glob(sp)
+ dp = os.path.join(destpath,"*")
+ dfiles = glob.glob(dp)
+ leftovers={}
+ for df in dfiles:
+ leftovers[os.path.basename(df)]=1
+
+ for srcfile in sfiles:
+ basename = os.path.basename(srcfile)
+ if basename in leftovers:
+ del leftovers[basename]
+
+ # Is it a subdirectory?
+ if os.path.isdir(srcfile):
+ sdir = os.path.join(srcpath,basename)
+ ddir = os.path.join(destpath,basename)
+ count+=convert(sdir, ddir)
+ continue
+ # Check the extension (only *.py will be converted)
+ root, ext = os.path.splitext(srcfile)
+ if ext.lower()!=".py":
+ continue
+
+ destfile = os.path.join(destpath,basename)
+ if destfile==srcfile:
+ print "WARNING: Input and output names are identical!"
+ sys.exit(1)
+
+ count+=1
+# sys.stdout.write("%s\015"%(srcfile))
+
+ if isNewer(srcfile, destfile):
+ preparePath(os.path.dirname(destfile))
+# out=open(destfile,"w")
+# filterFile(srcfile, out)
+# out.close()
+ os.system("python %s -f %s>%s"%(sys.argv[0],srcfile,destfile))
+
+ # Delete obsolete files in destpath
+ for df in leftovers:
+ dname=os.path.join(destpath,df)
+ if os.path.isdir(dname):
+ try:
+ shutil.rmtree(dname)
+ except:
+ print "Can't remove obsolete directory '%s'"%dname
+ else:
+ try:
+ os.remove(dname)
+ except:
+ print "Can't remove obsolete file '%s'"%dname
+
+ return count
+
+
+######################################################################
+######################################################################
+######################################################################
+
+filter_file = False
+source_root = None
+
+try:
+ opts, args = getopt.getopt(sys.argv[1:], "hfr:", ["help"])
+except getopt.GetoptError,e:
+ print e
+ sys.exit(1)
+
+for o,a in opts:
+ if o=="-f":
+ filter_file = True
+
+ if o=="-r":
+ source_root = os.path.abspath(a)
+
+if filter_file:
+ # Filter the specified file and print the result to stdout
+ filename = string.join(args)
+ filterFile(os.path.abspath(filename))
+else:
+
+ if len(args)!=2:
+ sys.stderr.write("%s options input
output\n"%(os.path.basename(sys.argv[0])))
+ sys.exit(1)
+
+ # Filter an entire Python source tree
+ print '"%s" -> "%s"\n'%(args[0],args[1])
+ c=convert(args[0],args[1])
+ print "%d files"%(c)
+
diff -r d4d880fcef28 -r b35215021b32
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/synch_bitops.h
--- /dev/null Fri Sep 9 16:31:36 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/synch_bitops.h Tue Sep
13 16:14:16 2005
@@ -0,0 +1,2 @@
+
+#include <asm-i386/synch_bitops.h>
diff -r d4d880fcef28 -r b35215021b32 tools/examples/block-phy
--- /dev/null Fri Sep 9 16:31:36 2005
+++ b/tools/examples/block-phy Tue Sep 13 16:14:16 2005
@@ -0,0 +1,30 @@
+#! /bin/sh
+
+set -e
+
+expand_dev() {
+ local dev
+ case $1 in
+ /*)
+ dev=$1
+ ;;
+ *)
+ dev=/dev/$1
+ ;;
+ esac
+ echo -n $dev
+}
+
+case $1 in
+ bind)
+ dev=$(expand_dev $2)
+ major=$(stat -L -c %t "$dev")
+ minor=$(stat -L -c %T "$dev")
+ pdev=$(printf "0x%02x%02x" 0x$major 0x$minor)
+ xenstore-write "$XENBUS_PATH"/physical-device $pdev \
+ "$XENBUS_PATH"/node $dev
+ exit 0
+ ;;
+ unbind)
+ ;;
+esac
diff -r d4d880fcef28 -r b35215021b32 tools/examples/xmexample.vmx.in
--- /dev/null Fri Sep 9 16:31:36 2005
+++ b/tools/examples/xmexample.vmx.in Tue Sep 13 16:14:16 2005
@@ -0,0 +1,96 @@
+# -*- mode: python; -*-
+#============================================================================
+# Python configuration setup for 'xm create'.
+# This script sets the parameters used when a domain is created using 'xm
create'.
+# You use a separate script for each domain you want to create, or
+# you can set the parameters for the domain on the xm command line.
+#============================================================================
+
+#----------------------------------------------------------------------------
+# Kernel image file.
+kernel = "/usr/@@LIBDIR@@/xen/boot/vmxloader"
+
+# The domain build function. VMX domain uses 'vmx'.
+builder='vmx'
+
+# Initial memory allocation (in megabytes) for the new domain.
+memory = 128
+
+# A name for your domain. All domains must have different names.
+name = "ExampleVMXDomain"
+
+# Which CPU to start domain on?
+#cpu = -1 # leave to Xen to pick
+
+# Optionally define mac and/or bridge for the network interfaces.
+# Random MACs are assigned if not given.
+#vif = [ 'mac=aa:00:00:00:00:11, bridge=xen-br0' ]
+
+#----------------------------------------------------------------------------
+# Define the disk devices you want the domain to have access to, and
+# what you want them accessible as.
+# Each disk entry is of the form phy:UNAME,DEV,MODE
+# where UNAME is the device, DEV is the device name the domain will see,
+# and MODE is r for read-only, w for read-write.
+
+#disk = [ 'phy:hda1,hda1,r' ]
+disk = [ 'file:/var/images/min-el3-i386.img,ioemu:hda,w' ]
+
+#----------------------------------------------------------------------------
+# Set according to whether you want the domain restarted when it exits.
+# The default is 'onreboot', which restarts the domain when it shuts down
+# with exit code reboot.
+# Other values are 'always', and 'never'.
+
+#restart = 'onreboot'
+
+#============================================================================
+
+
+# New stuff
+device_model = '/usr/@@LIBDIR@@/xen/bin/qemu-dm'
+
+# Advanced users only. Don't touch if you don't know what you're doing
+memmap = '/usr/@@LIBDIR@@/xen/boot/mem-map.sxp'
+
+#-----------------------------------------------------------------------------
+# Disk image for
+#cdrom=
+
+#-----------------------------------------------------------------------------
+# boot on floppy (a), hard disk (c) or CD-ROM (d)
+#boot=[a|c|d]
+#-----------------------------------------------------------------------------
+# write to temporary files instead of disk image files
+#snapshot=1
+
+#----------------------------------------------------------------------------
+# enable SDL library for graphics, default = 0
+sdl=0
+
+#----------------------------------------------------------------------------
+# enable VNC library for graphics, default = 1
+vnc=1
+
+#----------------------------------------------------------------------------
+# enable spawning vncviewer(only valid when vnc=1), default = 1
+vncviewer=1
+
+#----------------------------------------------------------------------------
+# no graphics, use serial port
+#nographic=0
+
+
+#-----------------------------------------------------------------------------
+# enable audio support
+#enable-audio=1
+
+
+#-----------------------------------------------------------------------------
+# set the real time clock to local time [default=0 i.e. set to utc]
+#localtime=1
+
+
+#-----------------------------------------------------------------------------
+# start in full screen
+#full-screen=1
diff -r d4d880fcef28 -r b35215021b32 tools/python/pylintrc
--- /dev/null Fri Sep 9 16:31:36 2005
+++ b/tools/python/pylintrc Tue Sep 13 16:14:16 2005
@@ -0,0 +1,307 @@
+# lint Python modules using external checkers.
+#
+# This is the main checker controling the other ones and the reports
+# generation. It is itself both a raw checker and an astng checker in
order
+# to:
+# * handle message activation / deactivation at the module level
+# * handle some basic but necessary stats'data (number of classes,
methods...)
+#
+# This checker also defines the following reports:
+# * R0001: Total errors / warnings
+# * R0002: % errors / warnings by module
+# * R0003: Messages
+# * R0004: Global evaluation
+#
+[MASTER]
+# Add <file or directory> to the black list. It should be a base name, not a
+# path. You may set this option multiple times.
+ignore=CVS
+
+# Pickle collected data for later comparisons.
+persistent=yes
+
+# Set the cache size for astng objects.
+cache-size=500
+
+
+
+[REPORTS]
+# Tells wether to display a full report or only the messages
+reports=yes
+
+# Use HTML as output format instead of text
+html=no
+
+# Use a parseable text output format, so your favorite text editor will be able
+# to jump to the line corresponding to a message.
+parseable=no
+
+# Colorizes text output using ansi escape codes
+color=no
+
+# Put messages in a separate file for each module / package specified on the
+# command line instead of printing them on stdout. Reports (if any) will be
+# written in a file name "pylint_global.[txt|html]".
+files-output=no
+
+# Python expression which should return a note less than 10 (10 is the highest
+# note).You have access to the variables errors warning, statement which
+# respectivly contain the number of errors / warnings messages and the total
+# number of statements analyzed. This is used by the global evaluation report
+# (R0004).
+evaluation=10.0 - ((float(5 * error + warning + refactor + convention) /
statement) * 10)
+
+# Add a comment according to your evaluation note. This is used by the global
+# evaluation report (R0004).
+comment=no
+
+# Include message's id in output
+include-ids=yes
+
+
+
+# checks for
+# * unused variables / imports
+# * undefined variables
+# * redefinition of variable from builtins or from an outer scope
+# * use of variable before assigment
+#
+[VARIABLES]
+# Enable / disable this checker
+enable-variables=yes
+
+# Tells wether we should check for unused import in __init__ files.
+init-import=no
+
+# List of variable names used for dummy variables (i.e. not used).
+dummy-variables=_,dummy
+
+
+
+# checks for :
+# * doc strings
+# * modules / classes / functions / methods / arguments / variables name
+# * number of arguments, local variables, branchs, returns and statements
in
+# functions, methods
+# * required module attributes
+# * dangerous default values as arguments
+# * redefinition of function / method / class
+# * uses of the global statement
+#
+# This checker also defines the following reports:
+# * R0101: Statistics by type
+#
+[BASIC]
+# Enable / disable this checker
+enable-basic=yes
+
+# Required attributes for module, separated by a comma
+required-attributes=
+
+# Regular expression which should only match functions or classes name which do
+# not require a docstring
+no-docstring-rgx=.*
+
+# Minimal length for module / class / function / method / argument / variable
+# names
+min-name-length=1
+
+# Regular expression which should only match correct module names
+module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
+
+# Regular expression which should only match correct class names
+class-rgx=[A-Z_][a-zA-Z0-9]+$
+
+# Regular expression which should only match correct function names
+function-rgx=[a-z_][A-Za-z0-9_]*$
+
+# Regular expression which should only match correct method names
+method-rgx=[a-z_][A-Za-z0-9_]*$
+
+# Regular expression which should only match correct argument names
+argument-rgx=[a-z_][A-Za-z0-9_]*$
+
+# Regular expression which should only match correct variable names
+variable-rgx=[a-z_][A-Za-z0-9_]*$
+
+# Good variable names which should always be accepted, separated by a comma
+good-names=i,j,k,ex,Run,_
+
+# Bad variable names which should always be refused, separated by a comma
+bad-names=foo,bar,baz,toto,tutu,tata
+
+# List of builtins function names that should not be used, separated by a comma
+bad-functions=map,filter,apply,input
+
+
+
+# checks for sign of poor/misdesign:
+# * number of methods, attributes, local variables...
+# * size, complexity of functions, methods
+#
+[DESIGN]
+# Enable / disable this checker
+enable-design=yes
+
+# Maximum number of arguments for function / method
+max-args=15
+
+# Maximum number of locals for function / method body
+max-locals=15
+
+# Maximum number of return / yield for function / method body
+max-returns=6
+
+# Maximum number of branch for function / method body
+max-branchs=12
+
+# Maximum number of statements in function / method body
+max-statements=50
+
+# Maximum number of parents for a class (see R0901).
+max-parents=7
+
+# Maximum number of attributes for a class (see R0902).
+max-attributes=7
+
+# Minimum number of public methods for a class (see R0903).
+min-public-methods=2
+
+# Maximum number of public methods for a class (see R0904).
+max-public-methods=20
+
+
+
+# checks for :
+# * methods without self as first argument
+# * overriden methods signature
+# * access only to existant members via self
+# * attributes not defined in the __init__ method
+# * supported interfaces implementation
+# * unreachable code
+#
+[CLASSES]
+# Enable / disable this checker
+enable-classes=yes
+
+# List of interface methods to ignore, separated by a comma. This is used for
+# instance to not check methods defines in Zope's Interface base class.
+ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
+
+# Tells wether missing members accessed in mixin class should be ignored. A
+# mixin class is detected if its name ends with "mixin" (case insensitive).
+ignore-mixin-members=yes
+
+
+
+# checks for
+# * external modules dependencies
+# * relative / wildcard imports
+# * cyclic imports
+# * uses of deprecated modules
+#
+# This checker also defines the following reports:
+# * R0401: External dependencies
+# * R0402: Modules dependencies graph
+#
+[IMPORTS]
+# Enable / disable this checker
+enable-imports=no
+
+# Deprecated modules which should not be used, separated by a comma
+deprecated-modules=regsub,string,TERMIOS,Bastion,rexec
+
+# Create a graph of every (i.e. internal and external) dependencies in the
given
+# file (report R0402 must not be disabled)
+import-graph=
+
+# Create a graph of external dependencies in the given file (report R0402 must
+# not be disabled)
+ext-import-graph=
+
+# Create a graph of internal dependencies in the given file (report R0402 must
+# not be disabled)
+int-import-graph=
+
+
+
+# checks for
+# * excepts without exception filter
+# * string exceptions
+#
+[EXCEPTIONS]
+# Enable / disable this checker
+enable-exceptions=yes
+
+
+
+# checks for :
+# * unauthorized constructions
+# * strict indentation
+# * line length
+# * use of <> instead of !=
+#
+[FORMAT]
+# Enable / disable this checker
+enable-format=no
+
+# Maximum number of characters on a single line.
+max-line-length=80
+
+# Maximum number of lines in a module
+max-module-lines=1000
+
+# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
tab).
+indent-string=' '
+
+
+
+# does not check anything but gives some raw metrics :
+# * total number of lines
+# * total number of code lines
+# * total number of docstring lines
+# * total number of comments lines
+# * total number of empty lines
+#
+# This checker also defines the following reports:
+# * R0701: Raw metrics
+#
+[METRICS]
+# Enable / disable this checker
+enable-metrics=yes
+
+
+
+# checks for:
+# * warning notes in the code like FIXME, XXX
+# * PEP 263: source code with non ascii character but no encoding
declaration
+#
+[MISCELLANEOUS]
+# Enable / disable this checker
+enable-miscellaneous=yes
+
+# List of note tags to take in consideration, separated by a comma. Default to
+# FIXME, XXX, TODO
+notes=FIXME,XXX,TODO
+
+
+
+# checks for similarities and duplicated code. This computation may be
+# memory / CPU intensive, so you should disable it if you experiments some
+# problems.
+#
+# This checker also defines the following reports:
+# * R0801: Duplication
+#
+[SIMILARITIES]
+# Enable / disable this checker
+enable-similarities=yes
+
+# Minimum lines number of a similarity.
+min-similarity-lines=4
+
+# Ignore comments when computing similarities.
+ignore-comments=yes
+
+
+
diff -r d4d880fcef28 -r b35215021b32 tools/vnet/Make.env
--- /dev/null Fri Sep 9 16:31:36 2005
+++ b/tools/vnet/Make.env Tue Sep 13 16:14:16 2005
@@ -0,0 +1,20 @@
+# -*- mode: Makefile; -*-
+
+export XEN_ROOT = $(shell cd $(VNET_ROOT)/../.. && pwd)
+export LINUX_SERIES ?= 2.6
+
+DISTDIR ?= $(XEN_ROOT)/dist
+export DESTDIR ?= $(DISTDIR)/install
+
+export VNET_MODULE_DIR = $(VNET_ROOT)/vnet-module
+export VNETD_DIR = $(VNET_ROOT)/vnetd
+export LIBXUTIL_DIR = $(VNET_ROOT)/libxutil
+
+export GC_DIR = $(VNET_ROOT)/build/gc
+export GC_INCLUDE = $(GC_DIR)/include
+export GC_LIB_DIR = $(GC_DIR)/lib
+export GC_LIB_A = $(GC_LIB_DIR)/libgc.a
+export GC_LIB_SO = $(GC_LIB_DIR)/libgc.so
+
+#$(warning XEN_ROOT = $(XEN_ROOT))
+#$(warning DESTDIR = $(DESTDIR))
diff -r d4d880fcef28 -r b35215021b32 tools/vnet/examples/vnet-insert
--- /dev/null Fri Sep 9 16:31:36 2005
+++ b/tools/vnet/examples/vnet-insert Tue Sep 13 16:14:16 2005
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+# Insert the vnet module if it can be found and
+# it's not already there.
+vnet_insert () {
+ local module="vnet_module"
+ local mod_dir=/lib/modules/$(uname -r)
+ local mod_obj=""
+
+ if lsmod | grep -q ${module} ; then
+ echo "VNET: ${module} loaded"
+ return
+ fi
+ local mods=$(find ${mod_dir} -name "${module}.*o")
+ if [[ ${mods} ]] ; then
+ for mod_obj in ${mods} ; do
+ break
+ done
+ fi
+ if [ -z "${mod_obj}" ] ; then
+ echo "VNET: ${module} not found"
+ exit 1
+ fi
+ echo "VNET: Loading ${module} from ${mod_obj}"
+ insmod ${mod_obj} "$@"
+}
+
+vnet_insert "$@"
diff -r d4d880fcef28 -r b35215021b32 tools/vnet/libxutil/mem_stream.c
--- /dev/null Fri Sep 9 16:31:36 2005
+++ b/tools/vnet/libxutil/mem_stream.c Tue Sep 13 16:14:16 2005
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/** @file
+ * IOStream subtype for input and output to memory.
+ * Usable from user or kernel code (with __KERNEL__ defined).
+ */
+
+#include "sys_string.h"
+#include "mem_stream.h"
+#include "allocate.h"
+
+/** Internal state for a memory stream.
+ *
+ * The memory stream buffer is treated as a circular buffer.
+ * The lo and hi markers indicate positions in the buffer, but
+ * are not reduced modulo the buffer size. This avoids the ambiguity
+ * between a full and empty buffer when using reduced values.
+ *
+ * If x is a marker, then buf + (x % buf_n) is the corresponding
+ * pointer into the buffer. When the buffer is empty, lo == hi,
+ * and the corresponding pointers are equal. When the buffer is
+ * full, hi == lo + buf_n, and the corresponding pointers
+ * are also equal.
+ *
+ * Data is written after the high pointer and read from the lo pointer.
+ * The value hi - lo is the number of bytes in the buffer.
+ */
+typedef struct MemData {
+ /** Data buffer. */
+ char *buf;
+ /** Low marker - start of readable area. */
+ unsigned long lo;
+ /** High marker - end of readable area, start of writeable area. */
+ unsigned long hi;
+ /** Size of the buffer. */
+ unsigned int buf_n;
+ /** Maximum size the buffer can grow to. */
+ unsigned int buf_max;
+ /** Error code. */
+ int err;
+} MemData;
+
+/** Get number of bytes available to read.
+ *
+ * @param data mem stream
+ * @return bytes
+ */
+static inline int mem_len(struct MemData *data){
+ return data->hi - data->lo;
+}
+
+/** Get available space left in the buffer.
+ *
+ * @param data mem stream
+ * @return bytes
+ */
+static inline int mem_room(struct MemData *data){
+ return data->buf_n - mem_len(data);
+}
+
+/** Get a pointer to the start of the data in the buffer.
+ *
+ * @param data mem stream
+ * @return lo pointer
+ */
+static inline char * mem_lo(struct MemData *data){
+ return data->buf + (data->lo % data->buf_n);
+}
+
+/** Get a pointer to the end of the data in the buffer.
+ *
+ * @param data mem stream
+ * @return hi pointer
+ */
+static inline char * mem_hi(struct MemData *data){
+ return data->buf + (data->hi % data->buf_n);
+}
+
+/** Get a pointer to the end of the buffer.
+ *
+ * @param data mem stream
+ * @return end pointer
+ */
+static inline char * mem_end(struct MemData *data){
+ return data->buf + data->buf_n;
+}
+
+static int mem_error(IOStream *io);
+static int mem_close(IOStream *io);
+static void mem_free(IOStream *io);
+static int mem_write(IOStream *io, const void *msg, size_t n);
+static int mem_read(IOStream *io, void *buf, size_t n);
+
+/** Minimum delta used to increment the buffer. */
+static int delta_min = 256;
+
+/** Methods for a memory stream. */
+static IOMethods mem_methods = {
+ read: mem_read,
+ write: mem_write,
+ error: mem_error,
+ close: mem_close,
+ free: mem_free,
+};
+
+/** Get the memory stream state.
+ *
+ * @param io memory stream
+ * @return state
+ */
+static inline MemData *get_mem_data(IOStream *io){
+ return (MemData*)io->data;
+}
+
+/** Get the number of bytes available to read.
+ *
+ * @param io memory stream
+ * @return number of bytes
+ */
+int mem_stream_avail(IOStream *io){
+ MemData *data = get_mem_data(io);
+ return (data->err ? -data->err : mem_len(data));
+}
+
+/** Copy bytes from a memory stream into a buffer.
+ *
+ * @param data mem stream
+ * @param buf buffer
+ * @param n number of bytes to copy
+ */
+static void mem_get(MemData *data, char *buf, size_t n){
+ char *start = mem_lo(data);
+ char *end = mem_end(data);
+ if (start + n < end) {
+ memcpy(buf, start, n);
+ } else {
+ int k = end - start;
+ memcpy(buf, start, k);
+ memcpy(buf + k, data->buf, n - k);
+ }
+}
+
+/** Copy bytes from a buffer into a memory stream.
+ *
+ * @param data mem stream
+ * @param buf buffer
+ * @param n number of bytes to copy
+ */
+static void mem_put(MemData *data, const char *buf, size_t n){
+ char *start = mem_hi(data);
+ char *end = mem_end(data);
+ if(start + n < end){
+ memcpy(start, buf, n);
+ } else {
+ int k = end - start;
+ memcpy(start, buf, k);
+ memcpy(data->buf, buf + k, n - k);
+ }
+}
+
+/** Expand the buffer used by a memory stream.
+ *
+ * @param data mem stream
+ * @param extra number of bytes to expand by
+ * @return 0 on success, negative error otherwise
+ */
+static int mem_expand(MemData *data, size_t extra){
+ int err = -ENOMEM;
+ int delta = (extra < delta_min ? delta_min : extra);
+ if(data->buf_max > 0){
+ int delta_max = data->buf_max - data->buf_n;
+ if(delta > delta_max){
+ delta = extra;
+ if(delta > delta_max) goto exit;
+ }
+ }
+ int buf_n = data->buf_n + delta;
+ char *buf = allocate(buf_n);
+ if(!buf) goto exit;
+ mem_get(data, buf, mem_len(data));
+ data->hi = mem_len(data);
+ data->lo = 0;
+ deallocate(data->buf);
+ data->buf = buf;
+ data->buf_n = buf_n;
+ err = 0;
+ exit:
+ if(err){
+ data->err = -err;
+ }
+ return err;
+}
+
+/** Write bytes from a buffer into a memory stream.
+ * The internal buffer is expanded as needed to hold the data,
+ * up to the stream maximum (if specified). If the buffer cannot
+ * be expanded -ENOMEM is returned.
+ *
+ * @param io mem stream
+ * @param buf buffer
+ * @param n number of bytes to write
+ * @return number of bytes written on success, negative error code otherwise
+ */
+static int mem_write(IOStream *io, const void *msg, size_t n){
+ MemData *data = get_mem_data(io);
+ if(data->err) return -data->err;
+ int room = mem_room(data);
+ if(n > room){
+ int err = mem_expand(data, n - room);
+ if(err) return err;
+ }
+ mem_put(data, msg, n);
+ data->hi += n;
+ return n;
+}
+
+/** Read bytes from a memory stream into a buffer.
+ *
+ * @param io mem stream
+ * @param buf buffer
+ * @param n maximum number of bytes to read
+ * @return number of bytes read on success, negative error code otherwise
+ */
+static int mem_read(IOStream *io, void *buf, size_t n){
+ MemData *data = get_mem_data(io);
+ if(data->err) return -data->err;
+ int k = mem_len(data);
+ if(n > k){
+ n = k;
+ }
+ mem_get(data, buf, n);
+ data->lo += n;
+ return n;
+}
+
+/** Test if a memory stream has an error.
+ *
+ * @param io mem stream
+ * @return 0 if ok, error code otherwise
+ */
+static int mem_error(IOStream *io){
+ MemData *data = get_mem_data(io);
+ return data->err;
+}
+
+/** Close a memory stream.
+ *
+ * @param io mem stream
+ * @return 0
+ */
+static int mem_close(IOStream *io){
+ MemData *data = get_mem_data(io);
+ if(!data->err){
+ data->err = ENOTCONN;
+ }
+ return 0;
+}
+
+/** Free a memory stream.
+ *
+ * @param io mem stream
+ */
+static void mem_free(IOStream *io){
+ MemData *data = get_mem_data(io);
+ deallocate(data->buf);
+ memzero(data, sizeof(*data));
+ deallocate(data);
+}
+
+/** Allocate and initialise a memory stream.
+ *
+ * @param buf_n initial buffer size (0 means default)
+ * @param buf_max maximum buffer size (0 means no max)
+ * @return new stream (free using IOStream_close)
+ */
+IOStream *mem_stream_new_size(size_t buf_n, size_t buf_max){
+ int err = -ENOMEM;
+ MemData *data = ALLOCATE(MemData);
+ if(!data) goto exit;
+ IOStream *io = ALLOCATE(IOStream);
+ if(!io) goto exit;
+ if(buf_n <= delta_min){
+ buf_n = delta_min;
+ }
+ if(buf_max > 0 && buf_max < buf_n){
+ buf_max = buf_n;
+ }
+ data->buf = allocate(buf_n);
+ if(!data->buf) goto exit;
+ data->buf_n = buf_n;
+ data->buf_max = buf_max;
+ io->methods = &mem_methods;
+ io->data = data;
+ io->nofree = 0;
+ err = 0;
+ exit:
+ if(err){
+ deallocate(data);
+ deallocate(io);
+ io = NULL;
+ }
+ return io;
+}
diff -r d4d880fcef28 -r b35215021b32 tools/vnet/libxutil/mem_stream.h
--- /dev/null Fri Sep 9 16:31:36 2005
+++ b/tools/vnet/libxutil/mem_stream.h Tue Sep 13 16:14:16 2005
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _XUTIL_MEM_STREAM_H_
+#define _XUTIL_MEM_STREAM_H_
+
+#include "iostream.h"
+
+extern IOStream *mem_stream_new_size(size_t buf_n, size_t buf_max);
+
+extern int mem_stream_avail(IOStream *io);
+
+static inline IOStream *mem_stream_new(void){
+ return mem_stream_new_size(0, 0);
+}
+
+#endif /* !_XUTIL_MEM_STREAM_H_ */
diff -r d4d880fcef28 -r b35215021b32 tools/vnet/vnet-module/varp_util.c
--- /dev/null Fri Sep 9 16:31:36 2005
+++ b/tools/vnet/vnet-module/varp_util.c Tue Sep 13 16:14:16 2005
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free software Foundation, Inc.,
+ * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+static int hex16(char *s, uint16_t *val)
+{
+ int err = -EINVAL;
+ uint16_t v = 0;
+
+ for( ; *s; s++){
+ v <<= 4;
+ if('0' <= *s && *s <= '9'){
+ v |= *s - '0';
+ } else if('A' <= *s && *s <= 'F'){
+ v |= *s - 'A' + 10;
+ } else if('a' <= *s && *s <= 'f'){
+ v |= *s - 'a' + 10;
+ } else {
+ goto exit;
+ }
+ }
+ err = 0;
+ exit:
+ *val = (err ? 0 : v);
+ return err;
+}
+
+int VnetId_aton(const char *s, VnetId *vnet){
+ int err = -EINVAL;
+ const char *p, *q;
+ uint16_t v;
+ char buf[5];
+ int buf_n = sizeof(buf) - 1;
+ int i, n;
+ const int elts_n = 8;
+
+ q = s;
+ p = strchr(q, ':');
+ i = (p ? 0 : elts_n - 1);
+ do {
+ if(!p){
+ if(i < elts_n - 1) goto exit;
+ p = s + strlen(s);
+ }
+ n = p - q;
+ if(n > buf_n) goto exit;
+ memcpy(buf, q, n);
+ buf[n] = '\0';
+ err = hex16(buf, &v);
+ if(err) goto exit;
+ vnet->u.vnet16[i] = htons(v);
+ q = p+1;
+ p = strchr(q, ':');
+ i++;
+ } while(i < elts_n);
+ err = 0;
+ exit:
+ if(err){
+ *vnet = (VnetId){};
+ }
+ return err;
+}
diff -r d4d880fcef28 -r b35215021b32 tools/vnet/vnet-module/varp_util.h
--- /dev/null Fri Sep 9 16:31:36 2005
+++ b/tools/vnet/vnet-module/varp_util.h Tue Sep 13 16:14:16 2005
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free software Foundation, Inc.,
+ * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef _VNET_VARP_UTIL_H
+#define _VNET_VARP_UTIL_H
+
+#include "hash_table.h"
+
+/** Size of a string buffer to store a varp address. */
+#define VARP_ADDR_BUF 56
+
+/** Size of a string buffer to store a vnet id. */
+#define VNET_ID_BUF 56
+
+#ifndef NIPQUAD
+#define NIPQUAD(addr) \
+ ((unsigned char *)&addr)[0], \
+ ((unsigned char *)&addr)[1], \
+ ((unsigned char *)&addr)[2], \
+ ((unsigned char *)&addr)[3]
+#endif
+
+#ifndef NIP6
+#define NIP6(addr) \
+ ntohs((addr).s6_addr16[0]), \
+ ntohs((addr).s6_addr16[1]), \
+ ntohs((addr).s6_addr16[2]), \
+ ntohs((addr).s6_addr16[3]), \
+ ntohs((addr).s6_addr16[4]), \
+ ntohs((addr).s6_addr16[5]), \
+ ntohs((addr).s6_addr16[6]), \
+ ntohs((addr).s6_addr16[7])
+#endif
+
+
+static inline const char *VarpAddr_ntoa(VarpAddr *addr, char
buf[VARP_ADDR_BUF])
+{
+ switch(addr->family){
+ default:
+ case AF_INET:
+ sprintf(buf, "%u.%u.%u.%u",
+ NIPQUAD(addr->u.ip4));
+ break;
+ case AF_INET6:
+ sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
+ NIP6(addr->u.ip6));
+ break;
+ }
+ return buf;
+}
+
+static inline const char *VnetId_ntoa(VnetId *vnet, char buf[VNET_ID_BUF])
+{
+ sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
+ ntohs(vnet->u.vnet16[0]), \
+ ntohs(vnet->u.vnet16[1]), \
+ ntohs(vnet->u.vnet16[2]), \
+ ntohs(vnet->u.vnet16[3]), \
+ ntohs(vnet->u.vnet16[4]), \
+ ntohs(vnet->u.vnet16[5]), \
+ ntohs(vnet->u.vnet16[6]), \
+ ntohs(vnet->u.vnet16[7]));
+ return buf;
+}
+
+extern int VnetId_aton(const char *s, VnetId *vnet);
+
+/** Convert an unsigned in host order to a vnet id.
+ */
+static inline struct VnetId toVnetId(uint32_t vnetid){
+ struct VnetId vnet = {};
+ vnet.u.vnet32[3] = htonl(vnetid);
+ return vnet;
+}
+
+static inline uint32_t VnetId_hash(uint32_t h, VnetId *vnet)
+{
+ h = hash_hul(h, vnet->u.vnet32[0]);
+ h = hash_hul(h, vnet->u.vnet32[1]);
+ h = hash_hul(h, vnet->u.vnet32[2]);
+ h = hash_hul(h, vnet->u.vnet32[3]);
+ return h;
+}
+
+static inline int VnetId_eq(VnetId *vnet1, VnetId *vnet2)
+{
+ return memcmp(vnet1, vnet2, sizeof(VnetId)) == 0;
+}
+
+static inline uint32_t VarpAddr_hash(uint32_t h, VarpAddr *addr)
+{
+ h = hash_hul(h, addr->family);
+ if(addr->family == AF_INET6){
+ h = hash_hul(h, addr->u.ip6.s6_addr32[0]);
+ h = hash_hul(h, addr->u.ip6.s6_addr32[1]);
+ h = hash_hul(h, addr->u.ip6.s6_addr32[2]);
+ h = hash_hul(h, addr->u.ip6.s6_addr32[3]);
+ } else {
+ h = hash_hul(h, addr->u.ip4.s_addr);
+ }
+ return h;
+}
+
+static inline int VarpAddr_eq(VarpAddr *addr1, VarpAddr*addr2)
+{
+ return memcmp(addr1, addr2, sizeof(VarpAddr)) == 0;
+}
+
+static inline uint32_t Vmac_hash(uint32_t h, Vmac *vmac)
+{
+ h = hash_hul(h,
+ (vmac->mac[0] << 24) |
+ (vmac->mac[1] << 16) |
+ (vmac->mac[2] << 8) |
+ (vmac->mac[3] ));
+ h = hash_hul(h,
+ (vmac->mac[4] << 8) |
+ (vmac->mac[5] ));
+ return h;
+}
+
+static inline int Vmac_eq(Vmac *vmac1, Vmac *vmac2)
+{
+ return memcmp(vmac1, vmac2, sizeof(Vmac)) == 0;
+}
+
+#endif /* _VNET_VARP_UTIL_H */
diff -r d4d880fcef28 -r b35215021b32
linux-2.6-xen-sparse/include/asm-xen/linux-public/xenbus_dev.h
--- a/linux-2.6-xen-sparse/include/asm-xen/linux-public/xenbus_dev.h Fri Sep
9 16:31:36 2005
+++ /dev/null Tue Sep 13 16:14:16 2005
@@ -1,47 +0,0 @@
-/*
- * xenbus_dev.h
- *
- * Copyright (c) 2005, Christian Limpach
- *
- * This file may be distributed separately from the Linux kernel, or
- * incorporated into other software packages, subject to the following license:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this source file (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy, modify,
- * merge, publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef _XENBUS_DEV_H_
-#define _XENBUS_DEV_H_
-
-struct xenbus_dev_talkv {
- enum xsd_sockmsg_type type;
- const struct kvec *iovec;
- unsigned int num_vecs;
- char *buf;
- unsigned int len;
-};
-
-/*
- * @cmd: IOCTL_XENBUS_DEV_TALKV
- * @arg: struct xenbus_dev_talkv
- * Return: 0 on success, error code on failure.
- */
-#define IOCTL_XENBUS_DEV_TALKV \
- _IOC(_IOC_NONE, 'X', 0, sizeof(struct xenbus_dev_talkv))
-
-#endif /* _XENBUS_DEV_H_ */
diff -r d4d880fcef28 -r b35215021b32
linux-2.6-xen-sparse/include/asm-xen/synch_bitops.h
--- a/linux-2.6-xen-sparse/include/asm-xen/synch_bitops.h Fri Sep 9
16:31:36 2005
+++ /dev/null Tue Sep 13 16:14:16 2005
@@ -1,2 +0,0 @@
-
-#include <asm-i386/synch_bitops.h>
diff -r d4d880fcef28 -r b35215021b32 tools/examples/xmexample.vmx
--- a/tools/examples/xmexample.vmx Fri Sep 9 16:31:36 2005
+++ /dev/null Tue Sep 13 16:14:16 2005
@@ -1,96 +0,0 @@
-# -*- mode: python; -*-
-#============================================================================
-# Python configuration setup for 'xm create'.
-# This script sets the parameters used when a domain is created using 'xm
create'.
-# You use a separate script for each domain you want to create, or
-# you can set the parameters for the domain on the xm command line.
-#============================================================================
-
-#----------------------------------------------------------------------------
-# Kernel image file.
-kernel = "/usr/lib/xen/boot/vmxloader"
-
-# The domain build function. VMX domain uses 'vmx'.
-builder='vmx'
-
-# Initial memory allocation (in megabytes) for the new domain.
-memory = 128
-
-# A name for your domain. All domains must have different names.
-name = "ExampleVMXDomain"
-
-# Which CPU to start domain on?
-#cpu = -1 # leave to Xen to pick
-
-# Optionally define mac and/or bridge for the network interfaces.
-# Random MACs are assigned if not given.
-#vif = [ 'mac=aa:00:00:00:00:11, bridge=xen-br0' ]
-
-#----------------------------------------------------------------------------
-# Define the disk devices you want the domain to have access to, and
-# what you want them accessible as.
-# Each disk entry is of the form phy:UNAME,DEV,MODE
-# where UNAME is the device, DEV is the device name the domain will see,
-# and MODE is r for read-only, w for read-write.
-
-#disk = [ 'phy:hda1,hda1,r' ]
-disk = [ 'file:/var/images/min-el3-i386.img,ioemu:hda,w' ]
-
-#----------------------------------------------------------------------------
-# Set according to whether you want the domain restarted when it exits.
-# The default is 'onreboot', which restarts the domain when it shuts down
-# with exit code reboot.
-# Other values are 'always', and 'never'.
-
-#restart = 'onreboot'
-
-#============================================================================
-
-
-# New stuff
-device_model = '/usr/lib/xen/bin/qemu-dm'
-
-# Advanced users only. Don't touch if you don't know what you're doing
-memmap = '/usr/lib/xen/boot/mem-map.sxp'
-
-#-----------------------------------------------------------------------------
-# Disk image for
-#cdrom=
-
-#-----------------------------------------------------------------------------
-# boot on floppy (a), hard disk (c) or CD-ROM (d)
-#boot=[a|c|d]
-#-----------------------------------------------------------------------------
-# write to temporary files instead of disk image files
-#snapshot=1
-
-#----------------------------------------------------------------------------
-# enable SDL library for graphics, default = 0
-sdl=0
-
-#----------------------------------------------------------------------------
-# enable VNC library for graphics, default = 1
-vnc=1
-
-#----------------------------------------------------------------------------
-# enable spawning vncviewer(only valid when vnc=1), default = 1
-vncviewer=1
-
-#----------------------------------------------------------------------------
-# no graphics, use serial port
-#nographic=0
-
-
-#-----------------------------------------------------------------------------
-# enable audio support
-#enable-audio=1
-
-
-#-----------------------------------------------------------------------------
-# set the real time clock to local time [default=0 i.e. set to utc]
-#localtime=1
-
-
-#-----------------------------------------------------------------------------
-# start in full screen
-#full-screen=1
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|