# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID d75a6cc5e68abe8541c326afa2a614bf1973c609
# Parent 7e3cbc40967620fb6b89eff6d931269d21416546
# Parent 4109c4e7804abeabe3b222673f2ba4dd1375be53
merge with xen-unstable.hg
diff -r 7e3cbc409676 -r d75a6cc5e68a .hgtags
--- a/.hgtags Mon Mar 27 15:36:47 2006 -0700
+++ b/.hgtags Tue Mar 28 08:54:58 2006 -0700
@@ -13,3 +13,4 @@ 30c521db4c71960b0cf1d9c9e1b658e77b535a3e
30c521db4c71960b0cf1d9c9e1b658e77b535a3e split-1.0
3d330e41f41ce1bc118c02346e18949ad5d67f6b split-1.1
c8fdb0caa77b429cf47f9707926e83947778cb48 RELEASE-3.0.0
+af0573e9e5258db0a9d28aa954dd302ddd2c2d23 3.0.2-rc
diff -r 7e3cbc409676 -r d75a6cc5e68a Makefile
--- a/Makefile Mon Mar 27 15:36:47 2006 -0700
+++ b/Makefile Tue Mar 28 08:54:58 2006 -0700
@@ -2,7 +2,7 @@
# Grand Unified Makefile for Xen.
#
-KERNELS ?= linux-2.6-xen0 linux-2.6-xenU
+KERNELS ?= linux-2.6-xen
# You may use wildcards in the above e.g. KERNELS=*2.6*
XKERNELS := $(foreach kernel, $(KERNELS), $(patsubst
buildconfigs/mk.%,%,$(wildcard buildconfigs/mk.$(kernel))) )
diff -r 7e3cbc409676 -r d75a6cc5e68a buildconfigs/linux-defconfig_xen0_ia64
--- a/buildconfigs/linux-defconfig_xen0_ia64 Mon Mar 27 15:36:47 2006 -0700
+++ b/buildconfigs/linux-defconfig_xen0_ia64 Tue Mar 28 08:54:58 2006 -0700
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc3-xen0
-# Thu Feb 16 13:20:46 2006
+# Linux kernel version: 2.6.16-xen0
+# Mon Mar 27 14:46:03 2006
#
#
@@ -95,8 +95,7 @@ CONFIG_XEN_PRIVILEGED_GUEST=y
CONFIG_XEN_PRIVILEGED_GUEST=y
CONFIG_XEN_BLKDEV_GRANT=y
CONFIG_XEN_BLKDEV_FRONTEND=y
-CONFIG_XEN_VT=y
-CONFIG_VT=y
+CONFIG_XEN_BLKDEV_BACKEND=y
CONFIG_XEN_SYSFS=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
CONFIG_DMA_IS_DMA32=y
@@ -378,7 +377,7 @@ CONFIG_BLK_DEV_IDESCSI=y
#
# IDE chipset support/bugfixes
#
-CONFIG_IDE_GENERIC=y
+# CONFIG_IDE_GENERIC is not set
CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_IDEPCI_SHARE_IRQ is not set
# CONFIG_BLK_DEV_OFFBOARD is not set
@@ -706,6 +705,7 @@ CONFIG_GAMEPORT=y
#
# Character devices
#
+CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
CONFIG_SERIAL_NONSTANDARD=y
@@ -1252,11 +1252,7 @@ CONFIG_USB_MON=y
# CONFIG_INFINIBAND is not set
#
-# SN Devices
-#
-
-#
-# EDAC - error detection and reporting (RAS)
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
#
#
diff -r 7e3cbc409676 -r d75a6cc5e68a buildconfigs/linux-defconfig_xenU_ia64
--- a/buildconfigs/linux-defconfig_xenU_ia64 Mon Mar 27 15:36:47 2006 -0700
+++ b/buildconfigs/linux-defconfig_xenU_ia64 Tue Mar 28 08:54:58 2006 -0700
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc3-xenU
-# Thu Feb 16 13:47:59 2006
+# Linux kernel version: 2.6.16-xenU
+# Mon Mar 27 14:01:13 2006
#
#
@@ -92,8 +92,7 @@ CONFIG_XEN_PRIVILEGED_GUEST=y
CONFIG_XEN_PRIVILEGED_GUEST=y
CONFIG_XEN_BLKDEV_GRANT=y
CONFIG_XEN_BLKDEV_FRONTEND=y
-# CONFIG_XEN_VT is not set
-# CONFIG_VT is not set
+CONFIG_XEN_BLKDEV_BACKEND=y
CONFIG_XEN_SYSFS=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
CONFIG_DMA_IS_DMA32=y
@@ -607,6 +606,9 @@ CONFIG_SERIO=y
#
# Character devices
#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
# CONFIG_SERIAL_NONSTANDARD is not set
#
@@ -863,6 +865,13 @@ CONFIG_FB_RADEON_DEBUG=y
# CONFIG_FB_VOODOO1 is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
#
# Logo configuration
@@ -1122,11 +1131,7 @@ CONFIG_USB_MON=y
# CONFIG_INFINIBAND is not set
#
-# SN Devices
-#
-
-#
-# EDAC - error detection and reporting (RAS)
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
#
#
diff -r 7e3cbc409676 -r d75a6cc5e68a buildconfigs/linux-defconfig_xen_x86_64
--- a/buildconfigs/linux-defconfig_xen_x86_64 Mon Mar 27 15:36:47 2006 -0700
+++ b/buildconfigs/linux-defconfig_xen_x86_64 Tue Mar 28 08:54:58 2006 -0700
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc3-xen
-# Mon Feb 20 11:37:11 2006
+# Linux kernel version: 2.6.16-xen
+# Mon Mar 27 09:43:44 2006
#
CONFIG_X86_64=y
CONFIG_64BIT=y
@@ -102,6 +102,8 @@ CONFIG_X86_PC=y
# CONFIG_MPSC is not set
CONFIG_GENERIC_CPU=y
CONFIG_X86_64_XEN=y
+CONFIG_X86_NO_TSS=y
+CONFIG_X86_NO_IDT=y
CONFIG_X86_L1_CACHE_BYTES=128
CONFIG_X86_L1_CACHE_SHIFT=7
CONFIG_X86_GOOD_APIC=y
@@ -1138,7 +1140,7 @@ CONFIG_AMD8111E_NAPI=y
CONFIG_AMD8111E_NAPI=y
CONFIG_ADAPTEC_STARFIRE=m
CONFIG_ADAPTEC_STARFIRE_NAPI=y
-CONFIG_B44=m
+# CONFIG_B44 is not set
CONFIG_FORCEDETH=m
CONFIG_DGRS=m
CONFIG_EEPRO100=m
@@ -1782,8 +1784,8 @@ CONFIG_VIDEO_HEXIUM_ORION=m
CONFIG_VIDEO_HEXIUM_ORION=m
CONFIG_VIDEO_HEXIUM_GEMINI=m
CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
CONFIG_VIDEO_CX88_DVB=m
-CONFIG_VIDEO_CX88_ALSA=m
CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y
CONFIG_VIDEO_CX88_VP3054=m
CONFIG_VIDEO_EM28XX=m
@@ -2331,11 +2333,7 @@ CONFIG_INFINIBAND_SRP=m
CONFIG_INFINIBAND_SRP=m
#
-# SN Devices
-#
-
-#
-# EDAC - error detection and reporting (RAS)
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
#
CONFIG_EDAC=m
diff -r 7e3cbc409676 -r d75a6cc5e68a docs/src/user.tex
--- a/docs/src/user.tex Mon Mar 27 15:36:47 2006 -0700
+++ b/docs/src/user.tex Tue Mar 28 08:54:58 2006 -0700
@@ -51,6 +51,40 @@ are licensed under the terms of the GNU
are licensed under the terms of the GNU Lesser General Public License, the
Zope Public License 2.0, or under ``BSD-style'' licenses. Please refer to the
COPYING file for details.
+
+Xen includes software by Christopher Clark. This software is covered by the
+following licence:
+
+\begin{quote}
+Copyright (c) 2002, Christopher Clark. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+\begin{itemize}
+\item Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+\item Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+\item Neither the name of the original author; nor the names of any
+contributors may be used to endorse or promote products derived from this
+software without specific prior written permission.
+\end{itemize}
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\end{quote}
\cleardoublepage
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/Makefile
--- a/extras/mini-os/Makefile Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/Makefile Tue Mar 28 08:54:58 2006 -0700
@@ -41,8 +41,7 @@ default: $(TARGET)
links:
[ -e include/xen ] || ln -sf ../../../xen/include/public include/xen
- [ -e xenbus/xenstored.h ] || ln -sf ../../../tools/xenstore/xenstored.h
xenbus/xenstored.h
-
+
$(TARGET): links $(OBJS)
$(LD) -N -T minios-$(TARGET_ARCH).lds $(OBJS) -o $@.elf
gzip -f -9 -c $@.elf >$@.gz
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/console/console.c
--- a/extras/mini-os/console/console.c Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/console/console.c Tue Mar 28 08:54:58 2006 -0700
@@ -116,12 +116,12 @@ void print(int direct, const char *fmt,
{
(void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
return;
+ } else {
+ if(!console_initialised)
+ (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
+
+ console_print(buf, strlen(buf));
}
-
- if(!console_initialised)
- (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
-
- console_print(buf, strlen(buf));
}
void printk(const char *fmt, ...)
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/console/xencons_ring.c
--- a/extras/mini-os/console/xencons_ring.c Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/console/xencons_ring.c Tue Mar 28 08:54:58 2006 -0700
@@ -10,7 +10,6 @@
/* TODO - need to define BUG_ON for whole mini-os, need crash-dump as well */
-extern void do_exit(void);
#define BUG_ON(_cond) do{if(_cond) do_exit();} while(0);
static inline struct xencons_interface *xencons_interface(void)
@@ -29,7 +28,6 @@ int xencons_ring_send_no_notify(const ch
int sent = 0;
struct xencons_interface *intf = xencons_interface();
XENCONS_RING_IDX cons, prod;
-
cons = intf->out_cons;
prod = intf->out_prod;
mb();
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/events.c
--- a/extras/mini-os/events.c Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/events.c Tue Mar 28 08:54:58 2006 -0700
@@ -74,9 +74,9 @@ int bind_evtchn( u32 port, void (*handle
void unbind_evtchn( u32 port )
{
- if (ev_actions[port].handler)
+ if (ev_actions[port].handler == default_handler)
printk("WARN: No handler for port %d when unbinding\n", port);
- ev_actions[port].handler = NULL;
+ ev_actions[port].handler = default_handler;
ev_actions[port].status |= EVS_DISABLED;
}
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/include/os.h
--- a/extras/mini-os/include/os.h Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/include/os.h Tue Mar 28 08:54:58 2006 -0700
@@ -9,6 +9,7 @@
#define NULL 0
+
#if __GNUC__ == 2 && __GNUC_MINOR__ < 96
#define __builtin_expect(x, expected_value) (x)
#endif
@@ -20,6 +21,10 @@
#ifndef __ASSEMBLY__
#include <types.h>
#include <hypervisor.h>
+
+extern void do_exit(void);
+#define BUG do_exit
+
#endif
#include <xen/xen.h>
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/include/wait.h
--- a/extras/mini-os/include/wait.h Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/include/wait.h Tue Mar 28 08:54:58 2006 -0700
@@ -66,6 +66,14 @@ static inline void wake_up(struct wait_q
}
}
+#define add_waiter(w, wq) do { \
+ unsigned long flags; \
+ local_irq_save(flags); \
+ add_wait_queue(&wq, &w); \
+ block(current); \
+ local_irq_restore(flags); \
+} while (0)
+
#define wait_event(wq, condition) do{ \
unsigned long flags; \
if(condition) \
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/include/xenbus.h
--- a/extras/mini-os/include/xenbus.h Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/include/xenbus.h Tue Mar 28 08:54:58 2006 -0700
@@ -1,224 +1,6 @@
-/******************************************************************************
- * xenbus.h
- *
- * Talks to Xen Store to figure out what devices we have.
- *
- * Copyright (C) 2005 Rusty Russell, IBM Corporation
- * Copyright (C) 2005 XenSource Ltd.
- *
- * 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_H__
+#define XENBUS_H__
-#ifndef _ASM_XEN_XENBUS_H
-#define _ASM_XEN_XENBUS_H
+void init_xenbus(void);
-#include <errno.h>
-#include <xen/io/xenbus.h>
-#include <xen/io/xs_wire.h>
-
-/* Register callback to watch this node. */
-struct xenbus_watch
-{
- struct list_head list;
-
- /* Path being watched. */
- const char *node;
-
- /* Callback (executed in a process context with no locks held). */
- void (*callback)(struct xenbus_watch *,
- const char **vec, unsigned int len);
-};
-
-
-/* A xenbus device. */
-struct xenbus_device {
- const char *devicetype;
- const char *nodename;
- const char *otherend;
- int otherend_id;
- struct xenbus_watch otherend_watch;
- int has_error;
- void *data;
-};
-
-struct xenbus_device_id
-{
- /* .../device/<device_type>/<identifier> */
- char devicetype[32]; /* General class of device. */
-};
-
-/* A xenbus driver. */
-struct xenbus_driver {
- char *name;
- struct module *owner;
- const struct xenbus_device_id *ids;
- int (*probe)(struct xenbus_device *dev,
- const struct xenbus_device_id *id);
- void (*otherend_changed)(struct xenbus_device *dev,
- XenbusState backend_state);
- int (*remove)(struct xenbus_device *dev);
- int (*suspend)(struct xenbus_device *dev);
- int (*resume)(struct xenbus_device *dev);
- int (*hotplug)(struct xenbus_device *, char **, int, char *, int);
- int (*read_otherend_details)(struct xenbus_device *dev);
-};
-
-int xenbus_register_frontend(struct xenbus_driver *drv);
-int xenbus_register_backend(struct xenbus_driver *drv);
-void xenbus_unregister_driver(struct xenbus_driver *drv);
-
-struct xenbus_transaction;
-
-char **xenbus_directory(struct xenbus_transaction *t,
- const char *dir, const char *node, unsigned int *num);
-void *xenbus_read(struct xenbus_transaction *t,
- const char *dir, const char *node, unsigned int *len);
-int xenbus_write(struct xenbus_transaction *t,
- const char *dir, const char *node, const char *string);
-int xenbus_mkdir(struct xenbus_transaction *t,
- const char *dir, const char *node);
-int xenbus_exists(struct xenbus_transaction *t,
- const char *dir, const char *node);
-int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node);
-struct xenbus_transaction *xenbus_transaction_start(void);
-int xenbus_transaction_end(struct xenbus_transaction *t, int abort);
-
-/* Single read and scanf: returns -errno or num scanned if > 0. */
-int xenbus_scanf(struct xenbus_transaction *t,
- const char *dir, const char *node, const char *fmt, ...)
- __attribute__((format(scanf, 4, 5)));
-
-/* Single printf and write: returns -errno or 0. */
-int xenbus_printf(struct xenbus_transaction *t,
- const char *dir, const char *node, const char *fmt, ...)
- __attribute__((format(printf, 4, 5)));
-
-/* Generic read function: NULL-terminated triples of name,
- * sprintf-style type string, and pointer. Returns 0 or errno.*/
-int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...);
-
-int register_xenbus_watch(struct xenbus_watch *watch);
-void unregister_xenbus_watch(struct xenbus_watch *watch);
-void xs_suspend(void);
-void xs_resume(void);
-
-/* Used by xenbus_dev to borrow kernel's store connection. */
-void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg);
-
-/* Called from xen core code. */
-void xenbus_suspend(void);
-void xenbus_resume(void);
-
-#define XENBUS_IS_ERR_READ(str) ({ \
- if (!IS_ERR(str) && strlen(str) == 0) { \
- kfree(str); \
- str = ERR_PTR(-ERANGE); \
- } \
- IS_ERR(str); \
-})
-
-#define XENBUS_EXIST_ERR(err) ((err) == -ENOENT || (err) == -ERANGE)
-
-
-/**
- * Register a watch on the given path, using the given xenbus_watch structure
- * for storage, and the given callback function as the callback. Return 0 on
- * success, or -errno on error. On success, the given path will be saved as
- * watch->node, and remains the caller's to free. On error, watch->node will
- * be NULL, the device will switch to XenbusStateClosing, and the error will
- * be saved in the store.
- */
-int xenbus_watch_path(struct xenbus_device *dev, const char *path,
- struct xenbus_watch *watch,
- void (*callback)(struct xenbus_watch *,
- const char **, unsigned int));
-
-
-/**
- * Register a watch on the given path/path2, using the given xenbus_watch
- * structure for storage, and the given callback function as the callback.
- * Return 0 on success, or -errno on error. On success, the watched path
- * (path/path2) will be saved as watch->node, and becomes the caller's to
- * kfree(). On error, watch->node will be NULL, so the caller has nothing to
- * free, the device will switch to XenbusStateClosing, and the error will be
- * saved in the store.
- */
-int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
- const char *path2, struct xenbus_watch *watch,
- void (*callback)(struct xenbus_watch *,
- const char **, unsigned int));
-
-
-/**
- * Advertise in the store a change of the given driver to the given new_state.
- * Perform the change inside the given transaction xbt. xbt may be NULL, in
- * which case this is performed inside its own transaction. Return 0 on
- * success, or -errno on error. On error, the device will switch to
- * XenbusStateClosing, and the error will be saved in the store.
- */
-int xenbus_switch_state(struct xenbus_device *dev,
- struct xenbus_transaction *xbt,
- XenbusState new_state);
-
-
-/**
- * Grant access to the given ring_mfn to the peer of the given device. Return
- * 0 on success, or -errno on error. On error, the device will switch to
- * XenbusStateClosing, and the error will be saved in the store.
- */
-int xenbus_grant_ring(struct xenbus_device *dev, unsigned long ring_mfn);
-
-
-/**
- * Allocate an event channel for the given xenbus_device, assigning the newly
- * created local port to *port. Return 0 on success, or -errno on error. On
- * error, the device will switch to XenbusStateClosing, and the error will be
- * saved in the store.
- */
-int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port);
-
-
-/**
- * Return the state of the driver rooted at the given store path, or
- * XenbusStateClosed if no state can be read.
- */
-XenbusState xenbus_read_driver_state(const char *path);
-
-
-/***
- * Report the given negative errno into the store, along with the given
- * formatted message.
- */
-void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt,
- ...);
-
-
-/***
- * Equivalent to xenbus_dev_error(dev, err, fmt, args), followed by
- * xenbus_switch_state(dev, NULL, XenbusStateClosing) to schedule an orderly
- * closedown of this driver and its peer.
- */
-void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
- ...);
-
-
-#endif /* _ASM_XEN_XENBUS_H */
+#endif /* XENBUS_H__ */
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/kernel.c
--- a/extras/mini-os/kernel.c Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/kernel.c Tue Mar 28 08:54:58 2006 -0700
@@ -35,7 +35,6 @@
#include <lib.h>
#include <sched.h>
#include <xenbus.h>
-#include "xenbus/xenbus_comms.h"
/*
* Shared page for communicating with the hypervisor.
@@ -76,7 +75,15 @@ static shared_info_t *map_shared_info(un
}
-extern void init_console(void);
+void test_xenbus(void);
+
+/* Do initialisation from a thread once the scheduler's available */
+static void init_xs(void *ign)
+{
+ init_xenbus();
+
+ test_xenbus();
+}
/*
* INITIAL C ENTRY POINT.
@@ -84,11 +91,13 @@ void start_kernel(start_info_t *si)
void start_kernel(start_info_t *si)
{
static char hello[] = "Bootstrapping...\n";
+
(void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(hello), hello);
/* Copy the start_info struct to a globally-accessible area. */
+ /* WARN: don't do printk before here, it uses information from
+ shared_info. Use xprintk instead. */
memcpy(&start_info, si, sizeof(*si));
-
/* Grab the shared_info pointer and put it in a safe place. */
HYPERVISOR_shared_info = map_shared_info(start_info.shared_info);
@@ -120,28 +129,24 @@ void start_kernel(start_info_t *si)
si->cmd_line ? (const char *)si->cmd_line : "NULL");
- /*
- * If used for porting another OS, start here to figure out your
- * guest os entry point. Otherwise continue below...
- */
- /* init memory management */
+ /* Init memory management. */
init_mm();
- /* set up events */
+ /* Set up events. */
init_events();
- /* init time and timers */
+ /* Init time and timers. */
init_time();
- /* init the console driver */
+ /* Init the console driver. */
init_console();
-
- /* init scheduler */
+
+ /* Init scheduler. */
init_sched();
-
- /* init xenbus */
- xs_init();
-
+
+ /* Init XenBus from a separate thread */
+ create_thread("init_xs", init_xs, NULL);
+
/* Everything initialised, start idle thread */
run_idle_thread();
}
@@ -156,6 +161,6 @@ void start_kernel(start_info_t *si)
void do_exit(void)
{
- printk("do_exit called!\n");
+ printk("Do_exit called!\n");
for ( ;; ) HYPERVISOR_sched_op(SCHEDOP_shutdown, SHUTDOWN_crash);
}
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/minios-x86_32.lds
--- a/extras/mini-os/minios-x86_32.lds Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/minios-x86_32.lds Tue Mar 28 08:54:58 2006 -0700
@@ -21,15 +21,6 @@ SECTIONS
_edata = .; /* End of data section */
- . = ALIGN(8192); /* init_task */
- .data.init_task : { *(.data.init_task) }
-
- . = ALIGN(4096);
- .data.page_aligned : { *(.data.idt) }
-
- . = ALIGN(32);
- .data.cacheline_aligned : { *(.data.cacheline_aligned) }
-
__bss_start = .; /* BSS */
.bss : {
*(.bss)
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/mm.c
--- a/extras/mini-os/mm.c Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/mm.c Tue Mar 28 08:54:58 2006 -0700
@@ -51,7 +51,6 @@ unsigned long *phys_to_machine_mapping;
unsigned long *phys_to_machine_mapping;
extern char *stack;
extern char _text, _etext, _edata, _end;
-extern void do_exit(void);
extern void page_walk(unsigned long virt_addr);
/*********************
@@ -373,7 +372,7 @@ void new_pt_frame(unsigned long *pt_pfn,
unsigned long *tab = (unsigned long *)start_info.pt_base;
unsigned long pt_page = (unsigned long)pfn_to_virt(*pt_pfn);
unsigned long prot_e, prot_t, pincmd;
- mmu_update_t mmu_updates[0];
+ mmu_update_t mmu_updates[1];
struct mmuext_op pin_request;
DEBUG("Allocating new L%d pt frame for pt_pfn=%lx, "
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/sched.c
--- a/extras/mini-os/sched.c Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/sched.c Tue Mar 28 08:54:58 2006 -0700
@@ -64,6 +64,8 @@
struct thread *idle_thread = NULL;
LIST_HEAD(exited_threads);
+
+void idle_thread_fn(void *unused);
void dump_stack(struct thread *thread)
{
@@ -132,7 +134,7 @@ void schedule(void)
xfree(thread);
}
}
- next = idle_thread;
+ next = idle_thread;
/* Thread list needs to be protected */
list_for_each(iterator, &idle_thread->thread_list)
{
@@ -203,8 +205,13 @@ struct thread* create_thread(char *name,
set_runnable(thread);
local_irq_save(flags);
- if(idle_thread != NULL)
+ if(idle_thread != NULL) {
list_add_tail(&thread->thread_list, &idle_thread->thread_list);
+ } else if(function != idle_thread_fn)
+ {
+ printk("BUG: Not allowed to create thread before initialising
scheduler.\n");
+ BUG();
+ }
local_irq_restore(flags);
return thread;
@@ -282,19 +289,9 @@ void th_f2(void *data)
void init_sched(void)
{
- printk("Initialising scheduler\n");
-
+ printk("Initialising scheduler, idle_thread %p\n", idle_thread);
+
idle_thread = create_thread("Idle", idle_thread_fn, NULL);
INIT_LIST_HEAD(&idle_thread->thread_list);
-
-
-/* create_thread("1", th_f1, (void *)0x1234);
- create_thread("2", th_f1, (void *)0x1234);
- create_thread("3", th_f1, (void *)0x1234);
- create_thread("4", th_f1, (void *)0x1234);
- create_thread("5", th_f1, (void *)0x1234);
- create_thread("6", th_f1, (void *)0x1234);
- create_thread("second", th_f2, NULL);
-*/
-}
-
+}
+
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/traps.c
--- a/extras/mini-os/traps.c Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/traps.c Tue Mar 28 08:54:58 2006 -0700
@@ -29,11 +29,18 @@ void machine_check(void);
void machine_check(void);
-extern void do_exit(void);
-
void dump_regs(struct pt_regs *regs)
{
- printk("FIXME: proper register dump (with the stack dump)\n");
+ printk("EIP: %x, EFLAGS %x.\n", regs->eip, regs->eflags);
+ printk("EBX: %08x ECX: %08x EDX: %08x\n",
+ regs->ebx, regs->ecx, regs->edx);
+ printk("ESI: %08x EDI: %08x EBP: %08x EAX: %08x\n",
+ regs->esi, regs->edi, regs->ebp, regs->eax);
+ printk("DS: %04x ES: %04x orig_eax: %08x, eip: %08x\n",
+ regs->xds, regs->xes, regs->orig_eax, regs->eip);
+ printk("CS: %04x EFLAGS: %08x esp: %08x ss: %04x\n",
+ regs->xcs, regs->eflags, regs->esp, regs->xss);
+
}
@@ -94,10 +101,14 @@ void page_walk(unsigned long virt_addres
}
-void do_page_fault(struct pt_regs *regs, unsigned long error_code,
-
unsigned long addr)
-{
- printk("Page fault at linear address %p\n", addr);
+#define read_cr2() \
+ (HYPERVISOR_shared_info->vcpu_info[smp_processor_id()].arch.cr2)
+
+void do_page_fault(struct pt_regs *regs, unsigned long error_code)
+{
+ unsigned long addr = read_cr2();
+ printk("Page fault at linear address %p, regs %p, code %lx\n", addr, regs,
+ error_code);
dump_regs(regs);
#ifdef __x86_64__
/* FIXME: _PAGE_PSE */
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/x86_32.S
--- a/extras/mini-os/x86_32.S Mon Mar 27 15:36:47 2006 -0700
+++ b/extras/mini-os/x86_32.S Tue Mar 28 08:54:58 2006 -0700
@@ -30,10 +30,10 @@ hypercall_page:
hypercall_page:
.org 0x3000
-ES = 0x20
-ORIG_EAX = 0x24
-EIP = 0x28
-CS = 0x2C
+ES = 0x1c
+ORIG_EAX = 0x20
+EIP = 0x24
+CS = 0x28
#define ENTRY(X) .globl X ; X :
@@ -94,32 +94,6 @@ do_exception:
call *%edi
addl $8,%esp
-/* pushl %ds
- pushl %eax
- xorl %eax,%eax
- pushl %ebp
- pushl %edi
- pushl %esi
- pushl %edx
- decl %eax # eax = -1
- pushl %ecx
- pushl %ebx
- cld
- movl %es,%ecx
- movl ORIG_EAX(%esp), %esi # get the error code
- movl ES(%esp), %edi # get the function address
- movl %eax, ORIG_EAX(%esp)
- movl %ecx, ES(%esp)
- movl %esp,%edx
- pushl %esi # push the error code
- pushl %edx # push the pt_regs pointer
- movl $(__KERNEL_DS),%edx
- movl %edx,%ds
- movl %edx,%es
- call *%edi
- addl $8,%esp */
-
-
ret_from_exception:
movb CS(%esp),%cl
test $2,%cl # slow return to ring 2 or 3
@@ -290,15 +264,16 @@ ENTRY(page_fault)
pushl %ecx
pushl %ebx
cld
- movl %es,%edi
- movl ES(%esp), %ecx /* get the faulting address */
- movl ORIG_EAX(%esp), %edx /* get the error code */
+ movl ORIG_EAX(%esp), %edi
movl %eax, ORIG_EAX(%esp)
- movl %edi, ES(%esp)
+ movl %es, %ecx
+ movl %ecx, ES(%esp)
movl $(__KERNEL_DS),%eax
movl %eax, %ds
movl %eax, %es
- movl %esp,%eax /* pt_regs pointer */
+ pushl %edi
+ movl %esp, %eax
+ pushl %eax
call do_page_fault
jmp ret_from_exception
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/arch/i386/kernel/cpu/common-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/cpu/common-xen.c Mon Mar 27
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/cpu/common-xen.c Tue Mar 28
08:54:58 2006 -0700
@@ -33,8 +33,6 @@ static int disable_x86_serial_nr __devin
static int disable_x86_serial_nr __devinitdata = 1;
struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
-
-extern void machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c);
extern int disable_pse;
@@ -425,8 +423,6 @@ void __devinit identify_cpu(struct cpuin
c->x86_vendor, c->x86_model);
}
- machine_specific_modify_cpu_capabilities(c);
-
/* Now the feature flags better reflect actual CPU features! */
printk(KERN_DEBUG "CPU: After all inits, caps:");
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S
--- a/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S Mon Mar 27 15:36:47
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S Tue Mar 28 08:54:58
2006 -0700
@@ -462,7 +462,7 @@ ENTRY(irq_entries_start)
ENTRY(irq_entries_start)
.rept NR_IRQS
ALIGN
-1: pushl $vector-256
+1: pushl 0x80000000+$vector
jmp common_interrupt
.data
.long 1b
@@ -479,7 +479,7 @@ common_interrupt:
#define BUILD_INTERRUPT(name, nr) \
ENTRY(name) \
- pushl $nr-256; \
+ pushl 0x80000000+$nr; \
SAVE_ALL \
movl %esp,%eax; \
call smp_/**/name; \
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S
--- a/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S Mon Mar 27 15:36:47
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S Tue Mar 28 08:54:58
2006 -0700
@@ -32,14 +32,14 @@ ENTRY(startup_32)
/* get vendor info */
xorl %eax,%eax # call CPUID with 0 -> return vendor ID
- cpuid
+ XEN_CPUID
movl %eax,X86_CPUID # save CPUID level
movl %ebx,X86_VENDOR_ID # lo 4 chars
movl %edx,X86_VENDOR_ID+4 # next 4 chars
movl %ecx,X86_VENDOR_ID+8 # last 4 chars
movl $1,%eax # Use the CPUID instruction to get CPU type
- cpuid
+ XEN_CPUID
movb %al,%cl # save reg for future use
andb $0x0f,%ah # mask processor family
movb %ah,X86
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/arch/i386/kernel/irq-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/irq-xen.c Mon Mar 27 15:36:47
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/irq-xen.c Tue Mar 28 08:54:58
2006 -0700
@@ -53,8 +53,8 @@ static union irq_ctx *softirq_ctx[NR_CPU
*/
fastcall unsigned int do_IRQ(struct pt_regs *regs)
{
- /* high bits used in ret_from_ code */
- int irq = regs->orig_eax & __IRQ_MASK(HARDIRQ_BITS);
+ /* high bit used in ret_from_ code */
+ int irq = regs->orig_eax & __IRQ_MASK(BITS_PER_LONG - 1);
#ifdef CONFIG_4KSTACKS
union irq_ctx *curctx, *irqctx;
u32 *isp;
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c Mon Mar 27 15:36:47
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c Tue Mar 28 08:54:58
2006 -0700
@@ -32,13 +32,13 @@
#endif
static int direct_remap_area_pte_fn(pte_t *pte,
- struct page *pte_page,
+ struct page *pmd_page,
unsigned long address,
void *data)
{
mmu_update_t **v = (mmu_update_t **)data;
- (*v)->ptr = ((u64)pfn_to_mfn(page_to_pfn(pte_page)) <<
+ (*v)->ptr = ((u64)pfn_to_mfn(page_to_pfn(pmd_page)) <<
PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
(*v)++;
@@ -67,9 +67,9 @@ static int __direct_remap_pfn_range(stru
for (i = 0; i < size; i += PAGE_SIZE) {
if ((v - u) == (PAGE_SIZE / sizeof(mmu_update_t))) {
/* Fill in the PTE pointers. */
- rc = generic_page_range(mm, start_address,
- address - start_address,
- direct_remap_area_pte_fn, &w);
+ rc = apply_to_page_range(mm, start_address,
+ address - start_address,
+ direct_remap_area_pte_fn, &w);
if (rc)
goto out;
w = u;
@@ -93,8 +93,9 @@ static int __direct_remap_pfn_range(stru
if (v != u) {
/* get the ptep's filled in */
- rc = generic_page_range(mm, start_address, address -
start_address,
- direct_remap_area_pte_fn, &w);
+ rc = apply_to_page_range(mm, start_address,
+ address - start_address,
+ direct_remap_area_pte_fn, &w);
if (rc)
goto out;
rc = -EFAULT;
@@ -142,11 +143,11 @@ EXPORT_SYMBOL(direct_kernel_remap_pfn_ra
EXPORT_SYMBOL(direct_kernel_remap_pfn_range);
static int lookup_pte_fn(
- pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
+ pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
{
uint64_t *ptep = (uint64_t *)data;
if (ptep)
- *ptep = ((uint64_t)pfn_to_mfn(page_to_pfn(pte_page)) <<
+ *ptep = ((uint64_t)pfn_to_mfn(page_to_pfn(pmd_page)) <<
PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
return 0;
}
@@ -155,13 +156,14 @@ int create_lookup_pte_addr(struct mm_str
unsigned long address,
uint64_t *ptep)
{
- return generic_page_range(mm, address, PAGE_SIZE, lookup_pte_fn, ptep);
+ return apply_to_page_range(mm, address, PAGE_SIZE,
+ lookup_pte_fn, ptep);
}
EXPORT_SYMBOL(create_lookup_pte_addr);
static int noop_fn(
- pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
+ pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
{
return 0;
}
@@ -170,7 +172,7 @@ int touch_pte_range(struct mm_struct *mm
unsigned long address,
unsigned long size)
{
- return generic_page_range(mm, address, size, noop_fn, NULL);
+ return apply_to_page_range(mm, address, size, noop_fn, NULL);
}
EXPORT_SYMBOL(touch_pte_range);
diff -r 7e3cbc409676 -r d75a6cc5e68a linux-2.6-xen-sparse/arch/ia64/Kconfig
--- a/linux-2.6-xen-sparse/arch/ia64/Kconfig Mon Mar 27 15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig Tue Mar 28 08:54:58 2006 -0700
@@ -83,19 +83,6 @@ config XEN_BLKDEV_BACKEND
depends on XEN
bool
default y
-
-config XEN_VT
- bool "Override for turning on CONFIG_VT for domU"
- default y
- help
- Hack to turn off CONFIG_VT for domU
-
-config VT
- bool
- default y if XEN && XEN_VT
- default n if XEN && !XEN_VT
- help
- Hack to turn off CONFIG_VT for domU
config XEN_SYSFS
bool "Export Xen attributes in sysfs"
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/arch/ia64/kernel/setup.c
--- a/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c Mon Mar 27 15:36:47
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c Tue Mar 28 08:54:58
2006 -0700
@@ -506,6 +506,22 @@ setup_arch (char **cmdline_p)
conswitchp = &vga_con;
# endif
}
+#ifdef CONFIG_XEN
+ if (running_on_xen) {
+ extern shared_info_t *HYPERVISOR_shared_info;
+
+ /* xen_start_info isn't setup yet, get the flags manually */
+ if (HYPERVISOR_shared_info->arch.flags & SIF_INITDOMAIN) {
+ if (!(HYPERVISOR_shared_info->arch.flags &
SIF_PRIVILEGED))
+ panic("Xen granted us console access "
+ "but not privileged status");
+ } else {
+ extern int console_use_vt;
+ conswitchp = NULL;
+ console_use_vt = 0;
+ }
+ }
+#endif
#endif
/* enable IA-64 Machine Check Abort Handling unless disabled */
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/arch/x86_64/kernel/apic-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/apic-xen.c Mon Mar 27
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/apic-xen.c Tue Mar 28
08:54:58 2006 -0700
@@ -113,8 +113,6 @@ void smp_apic_timer_interrupt(struct pt_
smp_local_timer_interrupt(regs);
irq_exit();
}
-
-int __initdata unsync_tsc_on_multicluster;
/*
* This interrupt should _never_ happen with our APIC/SMP architecture
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S Mon Mar 27
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S Tue Mar 28
08:54:58 2006 -0700
@@ -584,7 +584,7 @@ retint_kernel:
*/
.macro apicinterrupt num,func
INTR_FRAME
- pushq $\num-256
+ pushq 0x8000000000000000+$\num
CFI_ADJUST_CFA_OFFSET 8
interrupt \func
jmp error_entry
@@ -855,32 +855,12 @@ ecrit: /**** END OF CRITICAL REGION ***
# i.e. it just resumes from the next instruction interrupted with the same
context.
# Hypervisor uses this for application faults while it executes.
+# Unlike i386 there is no need to reload the saved segment selectors:
+# Xen already reloaded all valid ones and zeroed the others.
ENTRY(failsafe_callback)
- addq $0x10,%rsp /* skip rcx and r11 */
-1: mov (%rsp),%ds
-2: mov 8(%rsp),%es
-3: mov 16(%rsp),%fs
-4: mov 24(%rsp),%gs
- addq $0x20,%rsp /* skip the above selectors */
+ addq $0x30,%rsp /* skip %rcx,%r11,%ds,%es,%fs,%gs */
SAVE_ALL
jmp error_exit
-.section .fixup,"ax"; \
-6: movq $0,(%rsp); \
- jmp 1b; \
-7: movq $0,8(%rsp); \
- jmp 2b; \
-8: movq $0,16(%rsp); \
- jmp 3b; \
-9: movq $0,24(%rsp); \
- jmp 4b; \
-.previous; \
-.section __ex_table,"a";\
- .align 16; \
- .quad 1b,6b; \
- .quad 2b,7b; \
- .quad 3b,8b; \
- .quad 4b,9b; \
-.previous
#if 0
.section __ex_table,"a"
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/arch/x86_64/kernel/irq-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/irq-xen.c Mon Mar 27 15:36:47
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/irq-xen.c Tue Mar 28 08:54:58
2006 -0700
@@ -96,8 +96,8 @@ skip:
*/
asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
{
- /* high bits used in ret_from_ code */
- int irq = regs->orig_rax & __IRQ_MASK(HARDIRQ_BITS);
+ /* high bit used in ret_from_ code */
+ int irq = regs->orig_rax & __IRQ_MASK(BITS_PER_LONG - 1);
exit_idle();
irq_enter();
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Mon Mar 27
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Tue Mar 28
08:54:58 2006 -0700
@@ -82,8 +82,6 @@ extern unsigned long start_pfn;
extern unsigned long start_pfn;
extern struct edid_info edid_info;
-extern void machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c);
-
shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
EXPORT_SYMBOL(HYPERVISOR_shared_info);
@@ -1433,8 +1431,6 @@ void __cpuinit identify_cpu(struct cpuin
select_idle_routine(c);
detect_ht(c);
- machine_specific_modify_cpu_capabilities(c);
-
/*
* On SMP, boot_cpu_data holds the common feature set between
* all CPUs; so make sure that we indicate which features are
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Mon Mar 27
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Tue Mar 28
08:54:58 2006 -0700
@@ -517,7 +517,7 @@ void balloon_update_driver_allowance(lon
}
static int dealloc_pte_fn(
- pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
+ pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
{
unsigned long mfn = pte_mfn(*pte);
int ret;
@@ -547,8 +547,8 @@ struct page *balloon_alloc_empty_page_ra
scrub_pages(vstart, 1 << order);
balloon_lock(flags);
- ret = generic_page_range(
- &init_mm, vstart, PAGE_SIZE << order, dealloc_pte_fn, NULL);
+ ret = apply_to_page_range(&init_mm, vstart,
+ PAGE_SIZE << order, dealloc_pte_fn, NULL);
BUG_ON(ret);
current_pages -= 1UL << order;
totalram_pages = current_pages;
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/drivers/xen/core/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c Mon Mar 27 15:36:47
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c Tue Mar 28 08:54:58
2006 -0700
@@ -58,17 +58,37 @@ static int evtchn_to_irq[NR_EVENT_CHANNE
/* Packed IRQ information: binding type, sub-type index, and event channel. */
static u32 irq_info[NR_IRQS];
+
/* Binding types. */
enum { IRQT_UNBOUND, IRQT_PIRQ, IRQT_VIRQ, IRQT_IPI, IRQT_EVTCHN };
+
/* Constructor for packed IRQ information. */
-#define mk_irq_info(type, index, evtchn) \
- (((u32)(type) << 24) | ((u32)(index) << 16) | (u32)(evtchn))
+static inline u32 mk_irq_info(u32 type, u32 index, u32 evtchn)
+{
+ return ((type << 24) | (index << 16) | evtchn);
+}
+
/* Convenient shorthand for packed representation of an unbound IRQ. */
#define IRQ_UNBOUND mk_irq_info(IRQT_UNBOUND, 0, 0)
-/* Accessor macros for packed IRQ information. */
-#define evtchn_from_irq(irq) ((u16)(irq_info[irq]))
-#define index_from_irq(irq) ((u8)(irq_info[irq] >> 16))
-#define type_from_irq(irq) ((u8)(irq_info[irq] >> 24))
+
+/*
+ * Accessors for packed IRQ information.
+ */
+
+static inline unsigned int evtchn_from_irq(int irq)
+{
+ return (u16)(irq_info[irq]);
+}
+
+static inline unsigned int index_from_irq(int irq)
+{
+ return (u8)(irq_info[irq] >> 16);
+}
+
+static inline unsigned int type_from_irq(int irq)
+{
+ return (u8)(irq_info[irq] >> 24);
+}
/* IRQ <-> VIRQ mapping. */
DEFINE_PER_CPU(int, virq_to_irq[NR_VIRQS]);
@@ -90,10 +110,13 @@ static u8 cpu_evtchn[NR_EVENT_CHANNELS];
static u8 cpu_evtchn[NR_EVENT_CHANNELS];
static unsigned long cpu_evtchn_mask[NR_CPUS][NR_EVENT_CHANNELS/BITS_PER_LONG];
-#define active_evtchns(cpu,sh,idx) \
- ((sh)->evtchn_pending[idx] & \
- cpu_evtchn_mask[cpu][idx] & \
- ~(sh)->evtchn_mask[idx])
+static inline unsigned long active_evtchns(unsigned int cpu, shared_info_t *sh,
+ unsigned int idx)
+{
+ return (sh->evtchn_pending[idx] &
+ cpu_evtchn_mask[cpu][idx] &
+ ~sh->evtchn_mask[idx]);
+}
static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
{
@@ -109,16 +132,31 @@ static void init_evtchn_cpu_bindings(voi
memset(cpu_evtchn_mask[0], ~0, sizeof(cpu_evtchn_mask[0]));
}
-#define cpu_from_evtchn(evtchn) (cpu_evtchn[evtchn])
+static inline unsigned int cpu_from_evtchn(unsigned int evtchn)
+{
+ return cpu_evtchn[evtchn];
+}
#else
-#define active_evtchns(cpu,sh,idx) \
- ((sh)->evtchn_pending[idx] & \
- ~(sh)->evtchn_mask[idx])
-#define bind_evtchn_to_cpu(chn,cpu) ((void)0)
-#define init_evtchn_cpu_bindings() ((void)0)
-#define cpu_from_evtchn(evtchn) (0)
+static inline unsigned long active_evtchns(unsigned int cpu, shared_info_t *sh,
+ unsigned int idx)
+{
+ return (sh->evtchn_pending[idx] & ~sh->evtchn_mask[idx]);
+}
+
+static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
+{
+}
+
+static void init_evtchn_cpu_bindings(void)
+{
+}
+
+static inline unsigned int cpu_from_evtchn(unsigned int evtchn)
+{
+ return 0;
+}
#endif
@@ -132,9 +170,9 @@ static inline void exit_idle(void) {}
#include <asm/idle.h>
#define IRQ_REG orig_rax
#endif
-#define do_IRQ(irq, regs) do { \
- (regs)->IRQ_REG = (irq); \
- do_IRQ((regs)); \
+#define do_IRQ(irq, regs) do { \
+ (regs)->IRQ_REG = (irq) | (1UL << (BITS_PER_LONG - 1)); \
+ do_IRQ((regs)); \
} while (0)
#endif
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/drivers/xen/core/gnttab.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c Mon Mar 27 15:36:47
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c Tue Mar 28 08:54:58
2006 -0700
@@ -360,7 +360,7 @@ gnttab_request_free_callback(struct gntt
}
#ifndef __ia64__
-static int map_pte_fn(pte_t *pte, struct page *pte_page,
+static int map_pte_fn(pte_t *pte, struct page *pmd_page,
unsigned long addr, void *data)
{
unsigned long **frames = (unsigned long **)data;
@@ -370,7 +370,7 @@ static int map_pte_fn(pte_t *pte, struct
return 0;
}
-static int unmap_pte_fn(pte_t *pte, struct page *pte_page,
+static int unmap_pte_fn(pte_t *pte, struct page *pmd_page,
unsigned long addr, void *data)
{
@@ -384,6 +384,7 @@ gnttab_resume(void)
{
gnttab_setup_table_t setup;
unsigned long frames[NR_GRANT_FRAMES];
+ int rc;
#ifndef __ia64__
void *pframes = frames;
struct vm_struct *area;
@@ -393,8 +394,8 @@ gnttab_resume(void)
setup.nr_frames = NR_GRANT_FRAMES;
setup.frame_list = frames;
- BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1));
- BUG_ON(setup.status != 0);
+ rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
+ BUG_ON(rc || setup.status);
#ifndef __ia64__
if (shared == NULL) {
@@ -402,9 +403,10 @@ gnttab_resume(void)
BUG_ON(area == NULL);
shared = area->addr;
}
- BUG_ON(generic_page_range(&init_mm, (unsigned long)shared,
- PAGE_SIZE * NR_GRANT_FRAMES,
- map_pte_fn, &pframes));
+ rc = apply_to_page_range(&init_mm, (unsigned long)shared,
+ PAGE_SIZE * NR_GRANT_FRAMES,
+ map_pte_fn, &pframes);
+ BUG_ON(rc);
#else
shared = __va(frames[0] << PAGE_SHIFT);
printk("grant table at %p\n", shared);
@@ -418,9 +420,9 @@ gnttab_suspend(void)
{
#ifndef __ia64__
- generic_page_range(&init_mm, (unsigned long)shared,
- PAGE_SIZE * NR_GRANT_FRAMES,
- unmap_pte_fn, NULL);
+ apply_to_page_range(&init_mm, (unsigned long)shared,
+ PAGE_SIZE * NR_GRANT_FRAMES,
+ unmap_pte_fn, NULL);
#endif
return 0;
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/drivers/xen/core/reboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c Mon Mar 27 15:36:47
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c Tue Mar 28 08:54:58
2006 -0700
@@ -25,9 +25,10 @@ EXPORT_SYMBOL(pm_power_off);
EXPORT_SYMBOL(pm_power_off);
#endif
+extern void ctrl_alt_del(void);
+
#define SHUTDOWN_INVALID -1
#define SHUTDOWN_POWEROFF 0
-#define SHUTDOWN_REBOOT 1
#define SHUTDOWN_SUSPEND 2
/* Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only
* report a crash, not be instructed to crash!
@@ -234,33 +235,19 @@ static int shutdown_process(void *__unus
{
static char *envp[] = { "HOME=/", "TERM=linux",
"PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
- static char *restart_argv[] = { "/sbin/reboot", NULL };
static char *poweroff_argv[] = { "/sbin/poweroff", NULL };
extern asmlinkage long sys_reboot(int magic1, int magic2,
unsigned int cmd, void *arg);
- daemonize("shutdown");
-
- switch (shutting_down) {
- case SHUTDOWN_POWEROFF:
- case SHUTDOWN_HALT:
+ if ((shutting_down == SHUTDOWN_POWEROFF) ||
+ (shutting_down == SHUTDOWN_HALT)) {
if (execve("/sbin/poweroff", poweroff_argv, envp) < 0) {
sys_reboot(LINUX_REBOOT_MAGIC1,
LINUX_REBOOT_MAGIC2,
LINUX_REBOOT_CMD_POWER_OFF,
NULL);
}
- break;
-
- case SHUTDOWN_REBOOT:
- if (execve("/sbin/reboot", restart_argv, envp) < 0) {
- sys_reboot(LINUX_REBOOT_MAGIC1,
- LINUX_REBOOT_MAGIC2,
- LINUX_REBOOT_CMD_RESTART,
- NULL);
- }
- break;
}
shutting_down = SHUTDOWN_INVALID; /* could try again */
@@ -331,7 +318,7 @@ static void shutdown_handler(struct xenb
if (strcmp(str, "poweroff") == 0)
shutting_down = SHUTDOWN_POWEROFF;
else if (strcmp(str, "reboot") == 0)
- shutting_down = SHUTDOWN_REBOOT;
+ ctrl_alt_del();
else if (strcmp(str, "suspend") == 0)
shutting_down = SHUTDOWN_SUSPEND;
else if (strcmp(str, "halt") == 0)
@@ -391,8 +378,6 @@ static struct xenbus_watch sysrq_watch =
};
#endif
-static struct notifier_block xenstore_notifier;
-
static int setup_shutdown_watcher(struct notifier_block *notifier,
unsigned long event,
void *data)
@@ -420,11 +405,10 @@ static int setup_shutdown_watcher(struct
static int __init setup_shutdown_event(void)
{
-
- xenstore_notifier.notifier_call = setup_shutdown_watcher;
-
+ static struct notifier_block xenstore_notifier = {
+ .notifier_call = setup_shutdown_watcher
+ };
register_xenstore_notifier(&xenstore_notifier);
-
return 0;
}
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Mon Mar 27
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Tue Mar 28
08:54:58 2006 -0700
@@ -331,7 +331,7 @@ static void net_rx_action(unsigned long
if (make_rx_response(netif, id, status,
(unsigned long)skb->data & ~PAGE_MASK,
size, skb->proto_csum_valid ?
- NETRXF_csum_valid : 0) &&
+ NETRXF_data_validated : 0) &&
(rx_notify[irq] == 0)) {
rx_notify[irq] = 1;
notify_list[notify_nr++] = irq;
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Mon Mar 27
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Tue Mar 28
08:54:58 2006 -0700
@@ -68,18 +68,12 @@
#define NET_TX_RING_SIZE __RING_SIZE((netif_tx_sring_t *)0, PAGE_SIZE)
#define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE)
-#define alloc_xen_skb(_l) __dev_alloc_skb((_l), GFP_ATOMIC|__GFP_NOWARN)
-
-#define init_skb_shinfo(_skb) \
- do { \
- atomic_set(&(skb_shinfo(_skb)->dataref), 1); \
- skb_shinfo(_skb)->nr_frags = 0; \
- skb_shinfo(_skb)->frag_list = NULL; \
- } while (0)
-
-static unsigned long rx_pfn_array[NET_RX_RING_SIZE];
-static multicall_entry_t rx_mcl[NET_RX_RING_SIZE+1];
-static mmu_update_t rx_mmu[NET_RX_RING_SIZE];
+static inline void init_skb_shinfo(struct sk_buff *skb)
+{
+ atomic_set(&(skb_shinfo(skb)->dataref), 1);
+ skb_shinfo(skb)->nr_frags = 0;
+ skb_shinfo(skb)->frag_list = NULL;
+}
struct netfront_info
{
@@ -134,16 +128,28 @@ struct netfront_info
int tx_ring_ref;
int rx_ring_ref;
u8 mac[ETH_ALEN];
+
+ unsigned long rx_pfn_array[NET_RX_RING_SIZE];
+ multicall_entry_t rx_mcl[NET_RX_RING_SIZE+1];
+ mmu_update_t rx_mmu[NET_RX_RING_SIZE];
};
-/* Access macros for acquiring freeing slots in {tx,rx}_skbs[]. */
-#define ADD_ID_TO_FREELIST(_list, _id) \
- (_list)[(_id)] = (_list)[0]; \
- (_list)[0] = (void *)(unsigned long)(_id);
-#define GET_ID_FROM_FREELIST(_list) \
- ({ unsigned long _id = (unsigned long)(_list)[0]; \
- (_list)[0] = (_list)[_id]; \
- (unsigned short)_id; })
+/*
+ * Access macros for acquiring freeing slots in {tx,rx}_skbs[].
+ */
+
+static inline void add_id_to_freelist(struct sk_buff **list, unsigned short id)
+{
+ list[id] = list[0];
+ list[0] = (void *)(unsigned long)id;
+}
+
+static inline unsigned short get_id_from_freelist(struct sk_buff **list)
+{
+ unsigned int id = (unsigned int)(unsigned long)list[0];
+ list[0] = list[id];
+ return id;
+}
#ifdef DEBUG
static char *be_state_name[] = {
@@ -484,7 +490,7 @@ static void network_tx_buf_gc(struct net
gnttab_release_grant_reference(
&np->gref_tx_head, np->grant_tx_ref[id]);
np->grant_tx_ref[id] = GRANT_INVALID_REF;
- ADD_ID_TO_FREELIST(np->tx_skbs, id);
+ add_id_to_freelist(np->tx_skbs, id);
dev_kfree_skb_irq(skb);
}
@@ -545,9 +551,10 @@ static void network_alloc_rx_buffers(str
* Subtract dev_alloc_skb headroom (16 bytes) and shared info
* tailroom then round down to SKB_DATA_ALIGN boundary.
*/
- skb = alloc_xen_skb(
+ skb = __dev_alloc_skb(
((PAGE_SIZE - sizeof(struct skb_shared_info)) &
- (-SKB_DATA_ALIGN(1))) - 16);
+ (-SKB_DATA_ALIGN(1))) - 16,
+ GFP_ATOMIC|__GFP_NOWARN);
if (skb == NULL) {
/* Any skbuffs queued for refill? Force them out. */
if (i != 0)
@@ -576,7 +583,7 @@ static void network_alloc_rx_buffers(str
skb->dev = dev;
- id = GET_ID_FROM_FREELIST(np->rx_skbs);
+ id = get_id_from_freelist(np->rx_skbs);
np->rx_skbs[id] = skb;
@@ -588,13 +595,13 @@ static void network_alloc_rx_buffers(str
np->xbdev->otherend_id,
__pa(skb->head) >>
PAGE_SHIFT);
RING_GET_REQUEST(&np->rx, req_prod + i)->gref = ref;
- rx_pfn_array[i] = virt_to_mfn(skb->head);
+ np->rx_pfn_array[i] = virt_to_mfn(skb->head);
if (!xen_feature(XENFEAT_auto_translated_physmap)) {
/* Remove this page before passing back to Xen. */
set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT,
INVALID_P2M_ENTRY);
- MULTI_update_va_mapping(rx_mcl+i,
+ MULTI_update_va_mapping(np->rx_mcl+i,
(unsigned long)skb->head,
__pte(0), 0);
}
@@ -603,7 +610,7 @@ static void network_alloc_rx_buffers(str
/* Tell the ballon driver what is going on. */
balloon_update_driver_allowance(i);
- reservation.extent_start = rx_pfn_array;
+ reservation.extent_start = np->rx_pfn_array;
reservation.nr_extents = i;
reservation.extent_order = 0;
reservation.address_bits = 0;
@@ -611,19 +618,19 @@ static void network_alloc_rx_buffers(str
if (!xen_feature(XENFEAT_auto_translated_physmap)) {
/* After all PTEs have been zapped, flush the TLB. */
- rx_mcl[i-1].args[MULTI_UVMFLAGS_INDEX] =
+ np->rx_mcl[i-1].args[MULTI_UVMFLAGS_INDEX] =
UVMF_TLB_FLUSH|UVMF_ALL;
/* Give away a batch of pages. */
- rx_mcl[i].op = __HYPERVISOR_memory_op;
- rx_mcl[i].args[0] = XENMEM_decrease_reservation;
- rx_mcl[i].args[1] = (unsigned long)&reservation;
+ np->rx_mcl[i].op = __HYPERVISOR_memory_op;
+ np->rx_mcl[i].args[0] = XENMEM_decrease_reservation;
+ np->rx_mcl[i].args[1] = (unsigned long)&reservation;
/* Zap PTEs and give away pages in one big multicall. */
- (void)HYPERVISOR_multicall(rx_mcl, i+1);
+ (void)HYPERVISOR_multicall(np->rx_mcl, i+1);
/* Check return status of HYPERVISOR_memory_op(). */
- if (unlikely(rx_mcl[i].result != i))
+ if (unlikely(np->rx_mcl[i].result != i))
panic("Unable to reduce memory reservation\n");
} else
if (HYPERVISOR_memory_op(XENMEM_decrease_reservation,
@@ -656,7 +663,8 @@ static int network_start_xmit(struct sk_
if (unlikely((((unsigned long)skb->data & ~PAGE_MASK) + skb->len) >=
PAGE_SIZE)) {
struct sk_buff *nskb;
- if (unlikely((nskb = alloc_xen_skb(skb->len)) == NULL))
+ nskb = __dev_alloc_skb(skb->len, GFP_ATOMIC|__GFP_NOWARN);
+ if (unlikely(nskb == NULL))
goto drop;
skb_put(nskb, skb->len);
memcpy(nskb->data, skb->data, skb->len);
@@ -674,7 +682,7 @@ static int network_start_xmit(struct sk_
i = np->tx.req_prod_pvt;
- id = GET_ID_FROM_FREELIST(np->tx_skbs);
+ id = get_id_from_freelist(np->tx_skbs);
np->tx_skbs[id] = skb;
tx = RING_GET_REQUEST(&np->tx, i);
@@ -739,8 +747,8 @@ static int netif_poll(struct net_device
struct sk_buff *skb, *nskb;
netif_rx_response_t *rx;
RING_IDX i, rp;
- mmu_update_t *mmu = rx_mmu;
- multicall_entry_t *mcl = rx_mcl;
+ mmu_update_t *mmu = np->rx_mmu;
+ multicall_entry_t *mcl = np->rx_mcl;
int work_done, budget, more_to_do = 1;
struct sk_buff_head rxq;
unsigned long flags;
@@ -796,14 +804,14 @@ static int netif_poll(struct net_device
np->grant_rx_ref[rx->id] = GRANT_INVALID_REF;
skb = np->rx_skbs[rx->id];
- ADD_ID_TO_FREELIST(np->rx_skbs, rx->id);
+ add_id_to_freelist(np->rx_skbs, rx->id);
/* NB. We handle skb overflow later. */
skb->data = skb->head + rx->offset;
skb->len = rx->status;
skb->tail = skb->data + skb->len;
- if (rx->flags & NETRXF_csum_valid)
+ if (rx->flags & NETRXF_data_validated)
skb->ip_summed = CHECKSUM_UNNECESSARY;
np->stats.rx_packets++;
@@ -831,14 +839,14 @@ static int netif_poll(struct net_device
balloon_update_driver_allowance(-work_done);
/* Do all the remapping work, and M2P updates, in one big hypercall. */
- if (likely((mcl - rx_mcl) != 0)) {
+ if (likely((mcl - np->rx_mcl) != 0)) {
mcl->op = __HYPERVISOR_mmu_update;
- mcl->args[0] = (unsigned long)rx_mmu;
- mcl->args[1] = mmu - rx_mmu;
+ mcl->args[0] = (unsigned long)np->rx_mmu;
+ mcl->args[1] = mmu - np->rx_mmu;
mcl->args[2] = 0;
mcl->args[3] = DOMID_SELF;
mcl++;
- (void)HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
+ (void)HYPERVISOR_multicall(np->rx_mcl, mcl - np->rx_mcl);
}
while ((skb = __skb_dequeue(&rxq)) != NULL) {
@@ -871,7 +879,8 @@ static int netif_poll(struct net_device
16 - (skb->data - skb->head));
}
- nskb = alloc_xen_skb(skb->len + 2);
+ nskb = __dev_alloc_skb(skb->len + 2,
+ GFP_ATOMIC|__GFP_NOWARN);
if (nskb != NULL) {
skb_reserve(nskb, 2);
skb_put(nskb, skb->len);
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/drivers/xen/pciback/passthrough.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/passthrough.c Mon Mar 27
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/passthrough.c Tue Mar 28
08:54:58 2006 -0700
@@ -7,10 +7,13 @@
#include <linux/list.h>
#include <linux/pci.h>
+#include <linux/spinlock.h>
#include "pciback.h"
struct passthrough_dev_data {
+ /* Access to dev_list must be protected by lock */
struct list_head dev_list;
+ spinlock_t lock;
};
struct pci_dev *pciback_get_pci_dev(struct pciback_device *pdev,
@@ -19,31 +22,64 @@ struct pci_dev *pciback_get_pci_dev(stru
{
struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
struct pci_dev_entry *dev_entry;
+ struct pci_dev *dev = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev_data->lock, flags);
list_for_each_entry(dev_entry, &dev_data->dev_list, list) {
if (domain == (unsigned int)pci_domain_nr(dev_entry->dev->bus)
&& bus == (unsigned int)dev_entry->dev->bus->number
- && devfn == dev_entry->dev->devfn)
- return dev_entry->dev;
+ && devfn == dev_entry->dev->devfn) {
+ dev = dev_entry->dev;
+ break;
+ }
}
- return NULL;
+ spin_unlock_irqrestore(&dev_data->lock, flags);
+
+ return dev;
}
-/* Must hold pciback_device->dev_lock when calling this */
int pciback_add_pci_dev(struct pciback_device *pdev, struct pci_dev *dev)
{
struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
struct pci_dev_entry *dev_entry;
+ unsigned long flags;
dev_entry = kmalloc(sizeof(*dev_entry), GFP_KERNEL);
if (!dev_entry)
return -ENOMEM;
dev_entry->dev = dev;
+ spin_lock_irqsave(&dev_data->lock, flags);
list_add_tail(&dev_entry->list, &dev_data->dev_list);
+ spin_unlock_irqrestore(&dev_data->lock, flags);
return 0;
+}
+
+void pciback_release_pci_dev(struct pciback_device *pdev, struct pci_dev *dev)
+{
+ struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
+ struct pci_dev_entry *dev_entry, *t;
+ struct pci_dev *found_dev = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev_data->lock, flags);
+
+ list_for_each_entry_safe(dev_entry, t, &dev_data->dev_list, list) {
+ if (dev_entry->dev == dev) {
+ list_del(&dev_entry->list);
+ found_dev = dev_entry->dev;
+ kfree(dev_entry);
+ }
+ }
+
+ spin_unlock_irqrestore(&dev_data->lock, flags);
+
+ if (found_dev)
+ pcistub_put_pci_dev(found_dev);
}
int pciback_init_devices(struct pciback_device *pdev)
@@ -53,6 +89,8 @@ int pciback_init_devices(struct pciback_
dev_data = kmalloc(sizeof(*dev_data), GFP_KERNEL);
if (!dev_data)
return -ENOMEM;
+
+ spin_lock_init(&dev_data->lock);
INIT_LIST_HEAD(&dev_data->dev_list);
@@ -70,6 +108,8 @@ int pciback_publish_pci_roots(struct pci
struct pci_dev *dev;
int found;
unsigned int domain, bus;
+
+ spin_lock(&dev_data->lock);
list_for_each_entry(dev_entry, &dev_data->dev_list, list) {
/* Only publish this device as a root if none of its
@@ -96,10 +136,11 @@ int pciback_publish_pci_roots(struct pci
}
}
+ spin_unlock(&dev_data->lock);
+
return err;
}
-/* Must hold pciback_device->dev_lock when calling this */
void pciback_release_devices(struct pciback_device *pdev)
{
struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c Mon Mar 27
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c Tue Mar 28
08:54:58 2006 -0700
@@ -7,110 +7,190 @@
#include <linux/init.h>
#include <linux/list.h>
#include <linux/spinlock.h>
+#include <linux/kref.h>
#include <asm/atomic.h>
#include "pciback.h"
static char *pci_devs_to_hide = NULL;
module_param_named(hide, pci_devs_to_hide, charp, 0444);
-struct pci_stub_device_id {
+struct pcistub_device_id {
struct list_head slot_list;
int domain;
unsigned char bus;
unsigned int devfn;
};
-LIST_HEAD(pci_stub_device_ids);
-
-struct pci_stub_device {
+static LIST_HEAD(pcistub_device_ids);
+static DEFINE_SPINLOCK(device_ids_lock);
+
+struct pcistub_device {
+ struct kref kref;
struct list_head dev_list;
+ spinlock_t lock;
+
struct pci_dev *dev;
- atomic_t in_use;
+ struct pciback_device *pdev; /* non-NULL if struct pci_dev is in use
*/
};
-/* Access to pci_stub_devices & seized_devices lists and the initialize_devices
- * flag must be locked with pci_stub_devices_lock
+/* Access to pcistub_devices & seized_devices lists and the initialize_devices
+ * flag must be locked with pcistub_devices_lock
*/
-DEFINE_SPINLOCK(pci_stub_devices_lock);
-LIST_HEAD(pci_stub_devices);
+static DEFINE_SPINLOCK(pcistub_devices_lock);
+static LIST_HEAD(pcistub_devices);
/* wait for device_initcall before initializing our devices
* (see pcistub_init_devices_late)
*/
static int initialize_devices = 0;
-LIST_HEAD(seized_devices);
-
-static inline struct pci_dev *get_pci_dev(struct pci_stub_device *psdev)
-{
- if (atomic_dec_and_test(&psdev->in_use))
- return psdev->dev;
- else {
- atomic_inc(&psdev->in_use);
+static LIST_HEAD(seized_devices);
+
+static struct pcistub_device *pcistub_device_alloc(struct pci_dev *dev)
+{
+ struct pcistub_device *psdev;
+
+ dev_dbg(&dev->dev, "pcistub_device_alloc\n");
+
+ psdev = kzalloc(sizeof(*psdev), GFP_ATOMIC);
+ if (!psdev)
return NULL;
- }
-}
-
-struct pci_dev *pcistub_get_pci_dev_by_slot(int domain, int bus,
+
+ psdev->dev = pci_dev_get(dev);
+ if (!psdev->dev) {
+ kfree(psdev);
+ return NULL;
+ }
+
+ kref_init(&psdev->kref);
+ spin_lock_init(&psdev->lock);
+
+ return psdev;
+}
+
+/* Don't call this directly as it's called by pcistub_device_put */
+static void pcistub_device_release(struct kref *kref)
+{
+ struct pcistub_device *psdev;
+
+ psdev = container_of(kref, struct pcistub_device, kref);
+
+ dev_dbg(&psdev->dev->dev, "pcistub_device_release\n");
+
+ /* Clean-up the device */
+ pciback_reset_device(psdev->dev);
+ pciback_config_free(psdev->dev);
+ kfree(pci_get_drvdata(psdev->dev));
+ pci_set_drvdata(psdev->dev, NULL);
+
+ pci_dev_put(psdev->dev);
+
+ kfree(psdev);
+}
+
+static inline void pcistub_device_get(struct pcistub_device *psdev)
+{
+ kref_get(&psdev->kref);
+}
+
+static inline void pcistub_device_put(struct pcistub_device *psdev)
+{
+ kref_put(&psdev->kref, pcistub_device_release);
+}
+
+static struct pci_dev *pcistub_device_get_pci_dev(struct pciback_device *pdev,
+ struct pcistub_device *psdev)
+{
+ struct pci_dev *pci_dev = NULL;
+ unsigned long flags;
+
+ pcistub_device_get(psdev);
+
+ spin_lock_irqsave(&psdev->lock, flags);
+ if (!psdev->pdev) {
+ psdev->pdev = pdev;
+ pci_dev = psdev->dev;
+ }
+ spin_unlock_irqrestore(&psdev->lock, flags);
+
+ if (!pci_dev)
+ pcistub_device_put(psdev);
+
+ return pci_dev;
+}
+
+struct pci_dev *pcistub_get_pci_dev_by_slot(struct pciback_device *pdev,
+ int domain, int bus,
int slot, int func)
{
- struct pci_stub_device *psdev;
+ struct pcistub_device *psdev;
struct pci_dev *found_dev = NULL;
-
- spin_lock(&pci_stub_devices_lock);
-
- list_for_each_entry(psdev, &pci_stub_devices, dev_list) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&pcistub_devices_lock, flags);
+
+ list_for_each_entry(psdev, &pcistub_devices, dev_list) {
if (psdev->dev != NULL
&& domain == pci_domain_nr(psdev->dev->bus)
&& bus == psdev->dev->bus->number
&& PCI_DEVFN(slot, func) == psdev->dev->devfn) {
- found_dev = get_pci_dev(psdev);
+ found_dev = pcistub_device_get_pci_dev(pdev, psdev);
break;
}
}
- spin_unlock(&pci_stub_devices_lock);
+ spin_unlock_irqrestore(&pcistub_devices_lock, flags);
return found_dev;
}
-struct pci_dev *pcistub_get_pci_dev(struct pci_dev *dev)
-{
- struct pci_stub_device *psdev;
+struct pci_dev *pcistub_get_pci_dev(struct pciback_device *pdev,
+ struct pci_dev *dev)
+{
+ struct pcistub_device *psdev;
struct pci_dev *found_dev = NULL;
-
- spin_lock(&pci_stub_devices_lock);
-
- list_for_each_entry(psdev, &pci_stub_devices, dev_list) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&pcistub_devices_lock, flags);
+
+ list_for_each_entry(psdev, &pcistub_devices, dev_list) {
if (psdev->dev == dev) {
- found_dev = get_pci_dev(psdev);
+ found_dev = pcistub_device_get_pci_dev(pdev, psdev);
break;
}
}
- spin_unlock(&pci_stub_devices_lock);
+ spin_unlock_irqrestore(&pcistub_devices_lock, flags);
return found_dev;
}
void pcistub_put_pci_dev(struct pci_dev *dev)
{
- struct pci_stub_device *psdev;
-
- spin_lock(&pci_stub_devices_lock);
-
- list_for_each_entry(psdev, &pci_stub_devices, dev_list) {
+ struct pcistub_device *psdev, *found_psdev = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&pcistub_devices_lock, flags);
+
+ list_for_each_entry(psdev, &pcistub_devices, dev_list) {
if (psdev->dev == dev) {
- /* Cleanup our device
- * (so it's ready for the next domain)
- */
- pciback_reset_device(psdev->dev);
-
- atomic_inc(&psdev->in_use);
+ found_psdev = psdev;
break;
}
}
- spin_unlock(&pci_stub_devices_lock);
-}
-
-static int __devinit pcistub_match(struct pci_dev *dev,
- struct pci_stub_device_id *pdev_id)
+ spin_unlock_irqrestore(&pcistub_devices_lock, flags);
+
+ /* Cleanup our device
+ * (so it's ready for the next domain)
+ */
+ pciback_reset_device(found_psdev->dev);
+ pciback_config_reset(found_psdev->dev);
+
+ spin_lock_irqsave(&found_psdev->lock, flags);
+ found_psdev->pdev = NULL;
+ spin_unlock_irqrestore(&found_psdev->lock, flags);
+
+ pcistub_device_put(found_psdev);
+}
+
+static int __devinit pcistub_match_one(struct pci_dev *dev,
+ struct pcistub_device_id *pdev_id)
{
/* Match the specified device by domain, bus, slot, func and also if
* any of the device's parent bridges match.
@@ -125,23 +205,44 @@ static int __devinit pcistub_match(struc
return 0;
}
+static int __devinit pcistub_match(struct pci_dev *dev)
+{
+ struct pcistub_device_id *pdev_id;
+ unsigned long flags;
+ int found = 0;
+
+ spin_lock_irqsave(&device_ids_lock, flags);
+ list_for_each_entry(pdev_id, &pcistub_device_ids, slot_list) {
+ if (pcistub_match_one(dev, pdev_id)) {
+ found = 1;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&device_ids_lock, flags);
+
+ return found;
+}
+
static int __devinit pcistub_init_device(struct pci_dev *dev)
{
struct pciback_dev_data *dev_data;
int err = 0;
+
+ dev_dbg(&dev->dev, "initializing...\n");
/* The PCI backend is not intended to be a module (or to work with
* removable PCI devices (yet). If it were, pciback_config_free()
* would need to be called somewhere to free the memory allocated
* here and then to call kfree(pci_get_drvdata(psdev->dev)).
*/
- dev_data = kmalloc(sizeof(*dev_data), GFP_KERNEL);
+ dev_data = kmalloc(sizeof(*dev_data), GFP_ATOMIC);
if (!dev_data) {
err = -ENOMEM;
goto out;
}
pci_set_drvdata(dev, dev_data);
+ dev_dbg(&dev->dev, "initializing config\n");
err = pciback_config_init(dev);
if (err)
goto out;
@@ -153,14 +254,15 @@ static int __devinit pcistub_init_device
* This makes the assumption that the device's resources won't
* change after this point (otherwise this code may break!)
*/
+ dev_dbg(&dev->dev, "enabling device\n");
err = pci_enable_device(dev);
if (err)
goto config_release;
/* Now disable the device (this also ensures some private device
* data is setup before we export)
- * This calls pciback_config_reset(dev)
- */
+ */
+ dev_dbg(&dev->dev, "reset device\n");
pciback_reset_device(dev);
return 0;
@@ -182,60 +284,82 @@ static int __devinit pcistub_init_device
*/
static int __init pcistub_init_devices_late(void)
{
- struct pci_stub_device *psdev, *t;
+ struct pcistub_device *psdev;
+ unsigned long flags;
int err = 0;
- spin_lock(&pci_stub_devices_lock);
-
- list_for_each_entry_safe(psdev, t, &seized_devices, dev_list) {
+ pr_debug("pciback: pcistub_init_devices_late\n");
+
+ spin_lock_irqsave(&pcistub_devices_lock, flags);
+
+ while (!list_empty(&seized_devices)) {
+ psdev = container_of(seized_devices.next,
+ struct pcistub_device, dev_list);
list_del(&psdev->dev_list);
+
+ spin_unlock_irqrestore(&pcistub_devices_lock, flags);
+
err = pcistub_init_device(psdev->dev);
if (err) {
- printk(KERN_ERR
- "pciback: %s error %d initializing device\n",
- pci_name(psdev->dev), err);
+ dev_err(&psdev->dev->dev,
+ "error %d initializing device\n", err);
kfree(psdev);
- continue;
- }
-
- list_add_tail(&psdev->dev_list, &pci_stub_devices);
+ psdev = NULL;
+ }
+
+ spin_lock_irqsave(&pcistub_devices_lock, flags);
+
+ if (psdev)
+ list_add_tail(&psdev->dev_list, &pcistub_devices);
}
initialize_devices = 1;
- spin_unlock(&pci_stub_devices_lock);
+ spin_unlock_irqrestore(&pcistub_devices_lock, flags);
return 0;
}
static int __devinit pcistub_seize(struct pci_dev *dev)
{
- struct pci_stub_device *psdev;
+ struct pcistub_device *psdev;
+ unsigned long flags;
+ int initialize_devices_copy;
int err = 0;
- psdev = kmalloc(sizeof(*psdev), GFP_KERNEL);
+ psdev = pcistub_device_alloc(dev);
if (!psdev)
return -ENOMEM;
- psdev->dev = dev;
- atomic_set(&psdev->in_use, 1);
-
- spin_lock(&pci_stub_devices_lock);
-
- if (initialize_devices) {
+ /* initialize_devices has to be accessed under a spin lock. But since
+ * it can only change from 0 -> 1, if it's already 1, we don't have to
+ * worry about it changing. That's why we can take a *copy* of
+ * initialize_devices and wait till we're outside of the lock to
+ * check if it's 1 (don't ever check if it's 0 outside of the lock)
+ */
+ spin_lock_irqsave(&pcistub_devices_lock, flags);
+
+ initialize_devices_copy = initialize_devices;
+
+ if (!initialize_devices_copy) {
+ dev_dbg(&dev->dev, "deferring initialization\n");
+ list_add(&psdev->dev_list, &seized_devices);
+ }
+
+ spin_unlock_irqrestore(&pcistub_devices_lock, flags);
+
+ if (initialize_devices_copy) {
+ /* don't want irqs disabled when calling pcistub_init_device */
err = pcistub_init_device(psdev->dev);
if (err)
goto out;
- list_add(&psdev->dev_list, &pci_stub_devices);
- } else
- list_add(&psdev->dev_list, &seized_devices);
+ list_add(&psdev->dev_list, &pcistub_devices);
+ }
out:
- spin_unlock(&pci_stub_devices_lock);
-
if (err)
- kfree(psdev);
+ pcistub_device_put(psdev);
return err;
}
@@ -243,47 +367,78 @@ static int __devinit pcistub_probe(struc
static int __devinit pcistub_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
- struct pci_stub_device_id *pdev_id;
- struct pci_dev *seized_dev;
int err = 0;
- list_for_each_entry(pdev_id, &pci_stub_device_ids, slot_list) {
-
- if (!pcistub_match(dev, pdev_id))
- continue;
+ dev_dbg(&dev->dev, "probing...\n");
+
+ if (pcistub_match(dev)) {
if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL
&& dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
- printk(KERN_ERR
- "pciback: %s: can't export pci devices that "
- "don't have a normal (0) or bridge (1) "
- "header type!\n", pci_name(dev));
+ dev_err(&dev->dev, "can't export pci devices that "
+ "don't have a normal (0) or bridge (1) "
+ "header type!\n");
+ err = -ENODEV;
+ goto out;
+ }
+
+ dev_info(&dev->dev, "seizing device\n");
+ err = pcistub_seize(dev);
+ } else
+ /* Didn't find the device */
+ err = -ENODEV;
+
+ out:
+ return err;
+}
+
+static void pcistub_remove(struct pci_dev *dev)
+{
+ struct pcistub_device *psdev, *found_psdev = NULL;
+ unsigned long flags;
+
+ dev_dbg(&dev->dev, "removing\n");
+
+ spin_lock_irqsave(&pcistub_devices_lock, flags);
+
+ list_for_each_entry(psdev, &pcistub_devices, dev_list) {
+ if (psdev->dev == dev) {
+ found_psdev = psdev;
break;
}
-
- pr_info("pciback: seizing PCI device %s\n", pci_name(dev));
- seized_dev = pci_dev_get(dev);
-
- if (seized_dev) {
- err = pcistub_seize(seized_dev);
- if (err) {
- pci_dev_put(dev);
- goto out;
- }
-
- /* Success! */
- goto out;
- }
- }
-
- /* Didn't find the device */
- err = -ENODEV;
-
- out:
- return err;
-}
-
-struct pci_device_id pcistub_ids[] = {
+ }
+
+ spin_unlock_irqrestore(&pcistub_devices_lock, flags);
+
+ if (found_psdev) {
+ dev_dbg(&dev->dev, "found device to remove - in use? %p\n",
+ found_psdev->pdev);
+
+ if (found_psdev->pdev) {
+ printk(KERN_WARNING "pciback: ****** removing device "
+ "%s while still in-use! ******\n",
+ pci_name(found_psdev->dev));
+ printk(KERN_WARNING "pciback: ****** driver domain may "
+ "still access this device's i/o resources!\n");
+ printk(KERN_WARNING "pciback: ****** shutdown driver "
+ "domain before binding device\n");
+ printk(KERN_WARNING "pciback: ****** to other drivers "
+ "or domains\n");
+
+ pciback_release_pci_dev(found_psdev->pdev,
+ found_psdev->dev);
+ }
+
+ spin_lock_irqsave(&pcistub_devices_lock, flags);
+ list_del(&found_psdev->dev_list);
+ spin_unlock_irqrestore(&pcistub_devices_lock, flags);
+
+ /* the final put for releasing from the list */
+ pcistub_device_put(found_psdev);
+ }
+}
+
+static struct pci_device_id pcistub_ids[] = {
{
.vendor = PCI_ANY_ID,
.device = PCI_ANY_ID,
@@ -298,16 +453,152 @@ struct pci_device_id pcistub_ids[] = {
* for a normal device. I don't want it to be loaded automatically.
*/
-struct pci_driver pciback_pci_driver = {
+static struct pci_driver pciback_pci_driver = {
.name = "pciback",
.id_table = pcistub_ids,
.probe = pcistub_probe,
+ .remove = pcistub_remove,
};
+static inline int str_to_slot(const char *buf, int *domain, int *bus,
+ int *slot, int *func)
+{
+ int err;
+
+ err = sscanf(buf, " %x:%x:%x.%x", domain, bus, slot, func);
+ if (err == 4)
+ return 0;
+ else if (err < 0)
+ return -EINVAL;
+
+ /* try again without domain */
+ *domain = 0;
+ err = sscanf(buf, " %x:%x.%x", bus, slot, func);
+ if (err == 3)
+ return 0;
+
+ return -EINVAL;
+}
+
+static int pcistub_device_id_add(int domain, int bus, int slot, int func)
+{
+ struct pcistub_device_id *pci_dev_id;
+ unsigned long flags;
+
+ pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL);
+ if (!pci_dev_id)
+ return -ENOMEM;
+
+ pci_dev_id->domain = domain;
+ pci_dev_id->bus = bus;
+ pci_dev_id->devfn = PCI_DEVFN(slot, func);
+
+ pr_debug("pciback: wants to seize %04x:%02x:%02x.%01x\n",
+ domain, bus, slot, func);
+
+ spin_lock_irqsave(&device_ids_lock, flags);
+ list_add_tail(&pci_dev_id->slot_list, &pcistub_device_ids);
+ spin_unlock_irqrestore(&device_ids_lock, flags);
+
+ return 0;
+}
+
+static int pcistub_device_id_remove(int domain, int bus, int slot, int func)
+{
+ struct pcistub_device_id *pci_dev_id, *t;
+ int devfn = PCI_DEVFN(slot, func);
+ int err = -ENOENT;
+ unsigned long flags;
+
+ spin_lock_irqsave(&device_ids_lock, flags);
+ list_for_each_entry_safe(pci_dev_id, t, &pcistub_device_ids, slot_list)
{
+
+ if (pci_dev_id->domain == domain
+ && pci_dev_id->bus == bus && pci_dev_id->devfn == devfn) {
+ /* Don't break; here because it's possible the same
+ * slot could be in the list more than once
+ */
+ list_del(&pci_dev_id->slot_list);
+ kfree(pci_dev_id);
+
+ err = 0;
+
+ pr_debug("pciback: removed %04x:%02x:%02x.%01x from "
+ "seize list\n", domain, bus, slot, func);
+ }
+ }
+ spin_unlock_irqrestore(&device_ids_lock, flags);
+
+ return err;
+}
+
+static ssize_t pcistub_slot_add(struct device_driver *drv, const char *buf,
+ size_t count)
+{
+ int domain, bus, slot, func;
+ int err;
+
+ err = str_to_slot(buf, &domain, &bus, &slot, &func);
+ if (err)
+ goto out;
+
+ err = pcistub_device_id_add(domain, bus, slot, func);
+
+ out:
+ if (!err)
+ err = count;
+ return err;
+}
+
+DRIVER_ATTR(new_slot, S_IWUSR, NULL, pcistub_slot_add);
+
+static ssize_t pcistub_slot_remove(struct device_driver *drv, const char *buf,
+ size_t count)
+{
+ int domain, bus, slot, func;
+ int err;
+
+ err = str_to_slot(buf, &domain, &bus, &slot, &func);
+ if (err)
+ goto out;
+
+ err = pcistub_device_id_remove(domain, bus, slot, func);
+
+ out:
+ if (!err)
+ err = count;
+ return err;
+}
+
+DRIVER_ATTR(remove_slot, S_IWUSR, NULL, pcistub_slot_remove);
+
+static ssize_t pcistub_slot_show(struct device_driver *drv, char *buf)
+{
+ struct pcistub_device_id *pci_dev_id;
+ size_t count = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&device_ids_lock, flags);
+ list_for_each_entry(pci_dev_id, &pcistub_device_ids, slot_list) {
+ if (count >= PAGE_SIZE)
+ break;
+
+ count += scnprintf(buf + count, PAGE_SIZE - count,
+ "%04x:%02x:%02x.%01x\n",
+ pci_dev_id->domain, pci_dev_id->bus,
+ PCI_SLOT(pci_dev_id->devfn),
+ PCI_FUNC(pci_dev_id->devfn));
+ }
+ spin_unlock_irqrestore(&device_ids_lock, flags);
+
+ return count;
+}
+
+DRIVER_ATTR(slots, S_IRUSR, pcistub_slot_show, NULL);
+
static int __init pcistub_init(void)
{
int pos = 0;
- struct pci_stub_device_id *pci_dev_id;
int err = 0;
int domain, bus, slot, func;
int parsed;
@@ -328,33 +619,27 @@ static int __init pcistub_init(void)
goto parse_error;
}
- pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL);
- if (!pci_dev_id) {
- err = -ENOMEM;
+ err = pcistub_device_id_add(domain, bus, slot, func);
+ if (err)
goto out;
- }
-
- pci_dev_id->domain = domain;
- pci_dev_id->bus = bus;
- pci_dev_id->devfn = PCI_DEVFN(slot, func);
-
- pr_debug
- ("pciback: wants to seize %04x:%02x:%02x.%01x\n",
- domain, bus, slot, func);
-
- list_add_tail(&pci_dev_id->slot_list,
- &pci_stub_device_ids);
/* if parsed<=0, we've reached the end of the string */
pos += parsed;
} while (parsed > 0 && pci_devs_to_hide[pos]);
-
- /* If we're the first PCI Device Driver to register, we're the
- * first one to get offered PCI devices as they become
- * available (and thus we can be the first to grab them)
- */
- pci_register_driver(&pciback_pci_driver);
- }
+ }
+
+ /* If we're the first PCI Device Driver to register, we're the
+ * first one to get offered PCI devices as they become
+ * available (and thus we can be the first to grab them)
+ */
+ err = pci_register_driver(&pciback_pci_driver);
+ if (err < 0)
+ goto out;
+
+ driver_create_file(&pciback_pci_driver.driver, &driver_attr_new_slot);
+ driver_create_file(&pciback_pci_driver.driver,
+ &driver_attr_remove_slot);
+ driver_create_file(&pciback_pci_driver.driver, &driver_attr_slots);
out:
return err;
@@ -386,19 +671,22 @@ static int __init pciback_init(void)
return err;
#endif
- if (list_empty(&pci_stub_device_ids))
- return -ENODEV;
pcistub_init_devices_late();
pciback_xenbus_register();
- __unsafe(THIS_MODULE);
-
return 0;
}
-static void pciback_cleanup(void)
-{
- BUG();
+static void __exit pciback_cleanup(void)
+{
+ pciback_xenbus_unregister();
+
+ driver_remove_file(&pciback_pci_driver.driver, &driver_attr_new_slot);
+ driver_remove_file(&pciback_pci_driver.driver,
+ &driver_attr_remove_slot);
+ driver_remove_file(&pciback_pci_driver.driver, &driver_attr_slots);
+
+ pci_unregister_driver(&pciback_pci_driver);
}
module_init(pciback_init);
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/drivers/xen/pciback/pciback.h
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/pciback.h Mon Mar 27
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/pciback.h Tue Mar 28
08:54:58 2006 -0700
@@ -37,9 +37,11 @@ struct pciback_dev_data {
};
/* Get/Put PCI Devices that are hidden from the PCI Backend Domain */
-struct pci_dev *pcistub_get_pci_dev_by_slot(int domain, int bus,
+struct pci_dev *pcistub_get_pci_dev_by_slot(struct pciback_device *pdev,
+ int domain, int bus,
int slot, int func);
-struct pci_dev *pcistub_get_pci_dev(struct pci_dev *dev);
+struct pci_dev *pcistub_get_pci_dev(struct pciback_device *pdev,
+ struct pci_dev *dev);
void pcistub_put_pci_dev(struct pci_dev *dev);
/* Ensure a device is turned off or reset */
@@ -57,6 +59,7 @@ typedef int (*publish_pci_root_cb) (stru
typedef int (*publish_pci_root_cb) (struct pciback_device * pdev,
unsigned int domain, unsigned int bus);
int pciback_add_pci_dev(struct pciback_device *pdev, struct pci_dev *dev);
+void pciback_release_pci_dev(struct pciback_device *pdev, struct pci_dev *dev);
struct pci_dev *pciback_get_pci_dev(struct pciback_device *pdev,
unsigned int domain, unsigned int bus,
unsigned int devfn);
@@ -69,6 +72,7 @@ irqreturn_t pciback_handle_event(int irq
irqreturn_t pciback_handle_event(int irq, void *dev_id, struct pt_regs *regs);
int pciback_xenbus_register(void);
+void pciback_xenbus_unregister(void);
extern int verbose_request;
#endif
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/drivers/xen/pciback/pciback_ops.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/pciback_ops.c Mon Mar 27
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/pciback_ops.c Tue Mar 28
08:54:58 2006 -0700
@@ -12,9 +12,8 @@ module_param(verbose_request, int, 0644)
module_param(verbose_request, int, 0644);
/* Ensure a device is "turned off" and ready to be exported.
- * This also sets up the device's private data to keep track of what should
- * be in the base address registers (BARs) so that we can keep the
- * client from manipulating them directly.
+ * (Also see pciback_config_reset to ensure virtual configuration space is
+ * ready to be re-exported)
*/
void pciback_reset_device(struct pci_dev *dev)
{
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/drivers/xen/pciback/vpci.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/vpci.c Mon Mar 27 15:36:47
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/vpci.c Tue Mar 28 08:54:58
2006 -0700
@@ -8,12 +8,15 @@
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/pci.h>
+#include <linux/spinlock.h>
#include "pciback.h"
#define PCI_SLOT_MAX 32
struct vpci_dev_data {
+ /* Access to dev_list must be protected by lock */
struct list_head dev_list[PCI_SLOT_MAX];
+ spinlock_t lock;
};
static inline struct list_head *list_first(struct list_head *head)
@@ -25,25 +28,29 @@ struct pci_dev *pciback_get_pci_dev(stru
unsigned int domain, unsigned int bus,
unsigned int devfn)
{
- struct pci_dev_entry *dev_entry;
- struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
+ struct pci_dev_entry *entry;
+ struct pci_dev *dev = NULL;
+ struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
+ unsigned long flags;
if (domain != 0 || bus != 0)
return NULL;
if (PCI_SLOT(devfn) < PCI_SLOT_MAX) {
- /* we don't need to lock the list here because once the backend
- * is in operation, it won't have any more devices addeded
- * (or removed).
- */
- list_for_each_entry(dev_entry,
+ spin_lock_irqsave(&vpci_dev->lock, flags);
+
+ list_for_each_entry(entry,
&vpci_dev->dev_list[PCI_SLOT(devfn)],
list) {
- if (PCI_FUNC(dev_entry->dev->devfn) == PCI_FUNC(devfn))
- return dev_entry->dev;
- }
- }
- return NULL;
+ if (PCI_FUNC(entry->dev->devfn) == PCI_FUNC(devfn)) {
+ dev = entry->dev;
+ break;
+ }
+ }
+
+ spin_unlock_irqrestore(&vpci_dev->lock, flags);
+ }
+ return dev;
}
static inline int match_slot(struct pci_dev *l, struct pci_dev *r)
@@ -55,12 +62,12 @@ static inline int match_slot(struct pci_
return 0;
}
-/* Must hold pciback_device->dev_lock when calling this */
int pciback_add_pci_dev(struct pciback_device *pdev, struct pci_dev *dev)
{
int err = 0, slot;
struct pci_dev_entry *t, *dev_entry;
struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
+ unsigned long flags;
if ((dev->class >> 24) == PCI_BASE_CLASS_BRIDGE) {
err = -EFAULT;
@@ -78,6 +85,8 @@ int pciback_add_pci_dev(struct pciback_d
}
dev_entry->dev = dev;
+
+ spin_lock_irqsave(&vpci_dev->lock, flags);
/* Keep multi-function devices together on the virtual PCI bus */
for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
@@ -92,7 +101,7 @@ int pciback_add_pci_dev(struct pciback_d
PCI_FUNC(dev->devfn));
list_add_tail(&dev_entry->list,
&vpci_dev->dev_list[slot]);
- goto out;
+ goto unlock;
}
}
}
@@ -105,7 +114,7 @@ int pciback_add_pci_dev(struct pciback_d
pci_name(dev), slot);
list_add_tail(&dev_entry->list,
&vpci_dev->dev_list[slot]);
- goto out;
+ goto unlock;
}
}
@@ -113,8 +122,39 @@ int pciback_add_pci_dev(struct pciback_d
xenbus_dev_fatal(pdev->xdev, err,
"No more space on root virtual PCI bus");
+ unlock:
+ spin_unlock_irqrestore(&vpci_dev->lock, flags);
out:
return err;
+}
+
+void pciback_release_pci_dev(struct pciback_device *pdev, struct pci_dev *dev)
+{
+ int slot;
+ struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
+ struct pci_dev *found_dev = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&vpci_dev->lock, flags);
+
+ for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
+ struct pci_dev_entry *e, *tmp;
+ list_for_each_entry_safe(e, tmp, &vpci_dev->dev_list[slot],
+ list) {
+ if (e->dev == dev) {
+ list_del(&e->list);
+ found_dev = e->dev;
+ kfree(e);
+ goto out;
+ }
+ }
+ }
+
+ out:
+ spin_unlock_irqrestore(&vpci_dev->lock, flags);
+
+ if (found_dev)
+ pcistub_put_pci_dev(found_dev);
}
int pciback_init_devices(struct pciback_device *pdev)
@@ -126,6 +166,8 @@ int pciback_init_devices(struct pciback_
if (!vpci_dev)
return -ENOMEM;
+ spin_lock_init(&vpci_dev->lock);
+
for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
INIT_LIST_HEAD(&vpci_dev->dev_list[slot]);
}
@@ -142,7 +184,6 @@ int pciback_publish_pci_roots(struct pci
return publish_cb(pdev, 0, 0);
}
-/* Must hold pciback_device->dev_lock when calling this */
void pciback_release_devices(struct pciback_device *pdev)
{
int slot;
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c Mon Mar 27 15:36:47
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c Tue Mar 28 08:54:58
2006 -0700
@@ -12,7 +12,7 @@
#define INVALID_EVTCHN_IRQ (-1)
-struct pciback_device *alloc_pdev(struct xenbus_device *xdev)
+static struct pciback_device *alloc_pdev(struct xenbus_device *xdev)
{
struct pciback_device *pdev;
@@ -38,7 +38,7 @@ struct pciback_device *alloc_pdev(struct
return pdev;
}
-void free_pdev(struct pciback_device *pdev)
+static void free_pdev(struct pciback_device *pdev)
{
if (pdev->be_watching)
unregister_xenbus_watch(&pdev->be_watch);
@@ -247,7 +247,7 @@ static int pciback_export_device(struct
dev_dbg(&pdev->xdev->dev, "exporting dom %x bus %x slot %x func %x\n",
domain, bus, slot, func);
- dev = pcistub_get_pci_dev_by_slot(domain, bus, slot, func);
+ dev = pcistub_get_pci_dev_by_slot(pdev, domain, bus, slot, func);
if (!dev) {
err = -EINVAL;
xenbus_dev_fatal(pdev->xdev, err,
@@ -434,3 +434,8 @@ int __init pciback_xenbus_register(void)
{
return xenbus_register_backend(&xenbus_pciback_driver);
}
+
+void __exit pciback_xenbus_unregister(void)
+{
+ xenbus_unregister_driver(&xenbus_pciback_driver);
+}
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/drivers/xen/pcifront/pci_op.c
--- a/linux-2.6-xen-sparse/drivers/xen/pcifront/pci_op.c Mon Mar 27
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/pcifront/pci_op.c Tue Mar 28
08:54:58 2006 -0700
@@ -56,19 +56,19 @@ static int do_pci_op(struct pcifront_dev
notify_remote_via_evtchn(port);
/*
- * We set a poll timeout of 5 seconds but give up on return after
- * 4 seconds. It is better to time out too late rather than too early
+ * We set a poll timeout of 3 seconds but give up on return after
+ * 2 seconds. It is better to time out too late rather than too early
* (in the latter case we end up continually re-executing poll() with a
* timeout in the past). 1s difference gives plenty of slack for error.
*/
do_gettimeofday(&tv);
- ns_timeout = timeval_to_ns(&tv) + 4 * (nsec_t)NSEC_PER_SEC;
+ ns_timeout = timeval_to_ns(&tv) + 2 * (nsec_t)NSEC_PER_SEC;
clear_evtchn(port);
while (test_bit(_XEN_PCIF_active,
(unsigned long *)&pdev->sh_info->flags)) {
- if (HYPERVISOR_poll(&port, 1, jiffies + 5*HZ))
+ if (HYPERVISOR_poll(&port, 1, jiffies + 3*HZ))
BUG();
clear_evtchn(port);
do_gettimeofday(&tv);
@@ -173,7 +173,7 @@ static void pcifront_claim_resource(stru
if (!r->parent && r->start && r->flags) {
dev_dbg(&pdev->xdev->dev, "claiming resource %s/%d\n",
- pci_name(dev), i);
+ pci_name(dev), i);
pci_claim_resource(dev, i);
}
}
@@ -234,25 +234,38 @@ int pcifront_scan_root(struct pcifront_d
return err;
}
+static void free_root_bus_devs(struct pci_bus *bus)
+{
+ struct pci_dev *dev;
+
+ spin_lock(&pci_bus_lock);
+ while (!list_empty(&bus->devices)) {
+ dev = container_of(bus->devices.next, struct pci_dev, bus_list);
+ spin_unlock(&pci_bus_lock);
+
+ dev_dbg(&dev->dev, "removing device\n");
+ pci_remove_bus_device(dev);
+
+ spin_lock(&pci_bus_lock);
+ }
+ spin_unlock(&pci_bus_lock);
+}
+
void pcifront_free_roots(struct pcifront_device *pdev)
{
struct pci_bus_entry *bus_entry, *t;
+ dev_dbg(&pdev->xdev->dev, "cleaning up root buses\n");
+
list_for_each_entry_safe(bus_entry, t, &pdev->root_buses, list) {
- /* TODO: Removing a PCI Bus is untested (as it normally
- * just goes away on domain shutdown)
- */
list_del(&bus_entry->list);
- spin_lock(&pci_bus_lock);
- list_del(&bus_entry->bus->node);
- spin_unlock(&pci_bus_lock);
+ free_root_bus_devs(bus_entry->bus);
kfree(bus_entry->bus->sysdata);
device_unregister(bus_entry->bus->bridge);
-
- /* Do we need to free() the bus itself? */
+ pci_remove_bus(bus_entry->bus);
kfree(bus_entry);
}
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c Mon Mar 27
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c Tue Mar 28
08:54:58 2006 -0700
@@ -50,6 +50,8 @@ static void free_pdev(struct pcifront_de
{
dev_dbg(&pdev->xdev->dev, "freeing pdev @ 0x%p\n", pdev);
+ pcifront_free_roots(pdev);
+
if (pdev->evtchn != INVALID_EVTCHN)
xenbus_free_evtchn(pdev->xdev, pdev->evtchn);
diff -r 7e3cbc409676 -r d75a6cc5e68a linux-2.6-xen-sparse/drivers/xen/util.c
--- a/linux-2.6-xen-sparse/drivers/xen/util.c Mon Mar 27 15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/util.c Tue Mar 28 08:54:58 2006 -0700
@@ -6,9 +6,9 @@
#include <asm/uaccess.h>
#include <xen/driver_util.h>
-static int f(pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
+static int f(pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
{
- /* generic_page_range() does all the hard work. */
+ /* apply_to_page_range() does all the hard work. */
return 0;
}
@@ -24,8 +24,8 @@ struct vm_struct *alloc_vm_area(unsigned
* This ensures that page tables are constructed for this region
* of kernel virtual address space and mapped into init_mm.
*/
- if (generic_page_range(&init_mm, (unsigned long)area->addr,
- area->size, f, NULL)) {
+ if (apply_to_page_range(&init_mm, (unsigned long)area->addr,
+ area->size, f, NULL)) {
free_vm_area(area);
return NULL;
}
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Mon Mar 27
15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Tue Mar 28
08:54:58 2006 -0700
@@ -1039,8 +1039,7 @@ static int __init xenbus_probe_init(void
xsd_port_intf = create_xen_proc_entry("xsd_port", 0400);
if (xsd_port_intf)
xsd_port_intf->read_proc = xsd_port_read;
- }
- else
+ } else
xenstored_ready = 1;
/* Initialize the interface to xenstore. */
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h Mon Mar
27 15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h Tue Mar
28 08:54:58 2006 -0700
@@ -146,7 +146,7 @@ static inline void detect_ht(struct cpui
*/
static inline void cpuid(unsigned int op, unsigned int *eax, unsigned int
*ebx, unsigned int *ecx, unsigned int *edx)
{
- __asm__("cpuid"
+ __asm__(XEN_CPUID
: "=a" (*eax),
"=b" (*ebx),
"=c" (*ecx),
@@ -158,7 +158,7 @@ static inline void cpuid_count(int op, i
static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx,
int *edx)
{
- __asm__("cpuid"
+ __asm__(XEN_CPUID
: "=a" (*eax),
"=b" (*ebx),
"=c" (*ecx),
@@ -173,7 +173,7 @@ static inline unsigned int cpuid_eax(uns
{
unsigned int eax;
- __asm__("cpuid"
+ __asm__(XEN_CPUID
: "=a" (eax)
: "0" (op)
: "bx", "cx", "dx");
@@ -183,7 +183,7 @@ static inline unsigned int cpuid_ebx(uns
{
unsigned int eax, ebx;
- __asm__("cpuid"
+ __asm__(XEN_CPUID
: "=a" (eax), "=b" (ebx)
: "0" (op)
: "cx", "dx" );
@@ -193,7 +193,7 @@ static inline unsigned int cpuid_ecx(uns
{
unsigned int eax, ecx;
- __asm__("cpuid"
+ __asm__(XEN_CPUID
: "=a" (eax), "=c" (ecx)
: "0" (op)
: "bx", "dx" );
@@ -203,7 +203,7 @@ static inline unsigned int cpuid_edx(uns
{
unsigned int eax, edx;
- __asm__("cpuid"
+ __asm__(XEN_CPUID
: "=a" (eax), "=d" (edx)
: "0" (op)
: "bx", "cx");
@@ -237,20 +237,11 @@ extern unsigned long mmu_cr4_features;
static inline void set_in_cr4 (unsigned long mask)
{
+ unsigned cr4;
mmu_cr4_features |= mask;
- switch (mask) {
- case X86_CR4_OSFXSR:
- case X86_CR4_OSXMMEXCPT:
- break;
- default:
- do {
- const char *msg = "Xen unsupported cr4 update\n";
- (void)HYPERVISOR_console_io(
- CONSOLEIO_write, __builtin_strlen(msg),
- (char *)msg);
- BUG();
- } while (0);
- }
+ cr4 = read_cr4();
+ cr4 |= mask;
+ write_cr4(cr4);
}
static inline void clear_in_cr4 (unsigned long mask)
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Mon Mar
27 15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Tue Mar
28 08:54:58 2006 -0700
@@ -14,18 +14,6 @@ static char * __init machine_specific_me
add_memory_region(0, PFN_PHYS(max_pfn), E820_RAM);
return "Xen";
-}
-
-void __devinit machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c)
-{
- clear_bit(X86_FEATURE_VME, c->x86_capability);
- clear_bit(X86_FEATURE_DE, c->x86_capability);
- clear_bit(X86_FEATURE_PSE, c->x86_capability);
- clear_bit(X86_FEATURE_PGE, c->x86_capability);
- clear_bit(X86_FEATURE_SEP, c->x86_capability);
- if (!(xen_start_info->flags & SIF_PRIVILEGED))
- clear_bit(X86_FEATURE_MTRR, c->x86_capability);
- c->hlt_works_ok = 0;
}
extern void hypervisor_callback(void);
@@ -51,8 +39,6 @@ static void __init machine_specific_arch
cb.handler_address = (unsigned long)&nmi;
HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
- machine_specific_modify_cpu_capabilities(&boot_cpu_data);
-
if (HYPERVISOR_xen_version(XENVER_platform_parameters,
&pp) == 0)
set_fixaddr_top(pp.virt_start - PAGE_SIZE);
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/processor.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/processor.h Mon Mar
27 15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/processor.h Tue Mar
28 08:54:58 2006 -0700
@@ -141,31 +141,21 @@ static inline void set_in_cr4 (unsigned
static inline void set_in_cr4 (unsigned long mask)
{
mmu_cr4_features |= mask;
- switch (mask) {
- case X86_CR4_OSFXSR:
- case X86_CR4_OSXMMEXCPT:
- break;
- default:
- do {
- const char *msg = "Xen unsupported cr4 update\n";
- (void)HYPERVISOR_console_io(
- CONSOLEIO_write, __builtin_strlen(msg),
- (char *)msg);
- BUG();
- } while (0);
- }
+ __asm__("movq %%cr4,%%rax\n\t"
+ "orq %0,%%rax\n\t"
+ "movq %%rax,%%cr4\n"
+ : : "irg" (mask)
+ :"ax");
}
static inline void clear_in_cr4 (unsigned long mask)
{
-#ifndef CONFIG_XEN
mmu_cr4_features &= ~mask;
__asm__("movq %%cr4,%%rax\n\t"
"andq %0,%%rax\n\t"
"movq %%rax,%%cr4\n"
: : "irg" (~mask)
:"ax");
-#endif
}
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h
Mon Mar 27 15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h
Tue Mar 28 08:54:58 2006 -0700
@@ -5,17 +5,6 @@
* This is included late in kernel/setup.c so that it can make
* use of all of the static functions.
**/
-
-void __cpuinit machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c)
-{
- clear_bit(X86_FEATURE_VME, c->x86_capability);
- clear_bit(X86_FEATURE_DE, c->x86_capability);
- clear_bit(X86_FEATURE_PSE, c->x86_capability);
- clear_bit(X86_FEATURE_PGE, c->x86_capability);
- clear_bit(X86_FEATURE_SEP, c->x86_capability);
- if (!(xen_start_info->flags & SIF_PRIVILEGED))
- clear_bit(X86_FEATURE_MTRR, c->x86_capability);
-}
extern void hypervisor_callback(void);
extern void failsafe_callback(void);
@@ -36,6 +25,4 @@ static void __init machine_specific_arch
cb.handler_address = (unsigned long)&nmi;
HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
#endif
-
- machine_specific_modify_cpu_capabilities(&boot_cpu_data);
}
diff -r 7e3cbc409676 -r d75a6cc5e68a linux-2.6-xen-sparse/include/linux/mm.h
--- a/linux-2.6-xen-sparse/include/linux/mm.h Mon Mar 27 15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/include/linux/mm.h Tue Mar 28 08:54:58 2006 -0700
@@ -1020,10 +1020,10 @@ struct page *follow_page(struct vm_area_
#define FOLL_ANON 0x08 /* give ZERO_PAGE if no pgtable */
#ifdef CONFIG_XEN
-typedef int (*pte_fn_t)(pte_t *pte, struct page *pte_page, unsigned long addr,
- void *data);
-extern int generic_page_range(struct mm_struct *mm, unsigned long address,
- unsigned long size, pte_fn_t fn, void *data);
+typedef int (*pte_fn_t)(pte_t *pte, struct page *pmd_page, unsigned long addr,
+ void *data);
+extern int apply_to_page_range(struct mm_struct *mm, unsigned long address,
+ unsigned long size, pte_fn_t fn, void *data);
#endif
#ifdef CONFIG_PROC_FS
diff -r 7e3cbc409676 -r d75a6cc5e68a linux-2.6-xen-sparse/mm/memory.c
--- a/linux-2.6-xen-sparse/mm/memory.c Mon Mar 27 15:36:47 2006 -0700
+++ b/linux-2.6-xen-sparse/mm/memory.c Tue Mar 28 08:54:58 2006 -0700
@@ -1378,36 +1378,39 @@ EXPORT_SYMBOL(remap_pfn_range);
EXPORT_SYMBOL(remap_pfn_range);
#ifdef CONFIG_XEN
-static inline int generic_pte_range(struct mm_struct *mm, pmd_t *pmd,
- unsigned long addr, unsigned long end,
- pte_fn_t fn, void *data)
+static inline int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
+ unsigned long addr, unsigned long end,
+ pte_fn_t fn, void *data)
{
pte_t *pte;
int err;
- struct page *pte_page;
+ struct page *pmd_page;
+ spinlock_t *ptl;
pte = (mm == &init_mm) ?
pte_alloc_kernel(pmd, addr) :
- pte_alloc_map(mm, pmd, addr);
+ pte_alloc_map_lock(mm, pmd, addr, &ptl);
if (!pte)
return -ENOMEM;
- pte_page = pmd_page(*pmd);
+ BUG_ON(pmd_huge(*pmd));
+
+ pmd_page = pmd_page(*pmd);
do {
- err = fn(pte, pte_page, addr, data);
+ err = fn(pte, pmd_page, addr, data);
if (err)
break;
} while (pte++, addr += PAGE_SIZE, addr != end);
if (mm != &init_mm)
- pte_unmap(pte-1);
+ pte_unmap_unlock(pte-1, ptl);
return err;
}
-static inline int generic_pmd_range(struct mm_struct *mm, pud_t *pud,
- unsigned long addr, unsigned long end,
- pte_fn_t fn, void *data)
+static inline int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud,
+ unsigned long addr, unsigned long end,
+ pte_fn_t fn, void *data)
{
pmd_t *pmd;
unsigned long next;
@@ -1418,16 +1421,16 @@ static inline int generic_pmd_range(stru
return -ENOMEM;
do {
next = pmd_addr_end(addr, end);
- err = generic_pte_range(mm, pmd, addr, next, fn, data);
+ err = apply_to_pte_range(mm, pmd, addr, next, fn, data);
if (err)
break;
} while (pmd++, addr = next, addr != end);
return err;
}
-static inline int generic_pud_range(struct mm_struct *mm, pgd_t *pgd,
- unsigned long addr, unsigned long end,
- pte_fn_t fn, void *data)
+static inline int apply_to_pud_range(struct mm_struct *mm, pgd_t *pgd,
+ unsigned long addr, unsigned long end,
+ pte_fn_t fn, void *data)
{
pud_t *pud;
unsigned long next;
@@ -1438,7 +1441,7 @@ static inline int generic_pud_range(stru
return -ENOMEM;
do {
next = pud_addr_end(addr, end);
- err = generic_pmd_range(mm, pud, addr, next, fn, data);
+ err = apply_to_pmd_range(mm, pud, addr, next, fn, data);
if (err)
break;
} while (pud++, addr = next, addr != end);
@@ -1449,8 +1452,8 @@ static inline int generic_pud_range(stru
* Scan a region of virtual memory, filling in page tables as necessary
* and calling a provided function on each leaf page table.
*/
-int generic_page_range(struct mm_struct *mm, unsigned long addr,
- unsigned long size, pte_fn_t fn, void *data)
+int apply_to_page_range(struct mm_struct *mm, unsigned long addr,
+ unsigned long size, pte_fn_t fn, void *data)
{
pgd_t *pgd;
unsigned long next;
@@ -1461,12 +1464,13 @@ int generic_page_range(struct mm_struct
pgd = pgd_offset(mm, addr);
do {
next = pgd_addr_end(addr, end);
- err = generic_pud_range(mm, pgd, addr, next, fn, data);
+ err = apply_to_pud_range(mm, pgd, addr, next, fn, data);
if (err)
break;
} while (pgd++, addr = next, addr != end);
return err;
}
+EXPORT_SYMBOL_GPL(apply_to_page_range);
#endif
/*
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/Makefile
--- a/tools/Makefile Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/Makefile Tue Mar 28 08:54:58 2006 -0700
@@ -37,6 +37,7 @@ install: check
$(MAKE) -C $$subdir $@; \
done
$(MAKE) ioemuinstall
+ $(INSTALL_DIR) -p $(DESTDIR)/var/xen/dump
clean: check_clean
@set -e; for subdir in $(SUBDIRS); do \
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/debugger/gdb/README
--- a/tools/debugger/gdb/README Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/debugger/gdb/README Tue Mar 28 08:54:58 2006 -0700
@@ -11,8 +11,8 @@ To build the GDB server:
to your test machine.
To build a debuggable guest kernel image:
- 1. cd linux-2.6.12-xenU
- 2. ARCH=xen make menuconfig
+ 1. cd linux-2.6.xx-xenU
+ 2. make menuconfig
3. From within the configurator, enable the following options:
# Kernel hacking -> Compile the kernel with debug info [*]
-> Compile the kernel with frame pointers
diff -r 7e3cbc409676 -r d75a6cc5e68a
tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure.srv
--- a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure.srv
Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure.srv
Tue Mar 28 08:54:58 2006 -0700
@@ -61,7 +61,7 @@ case "${target}" in
srv_linux_thread_db=yes
;;
x86_64-*-linux*) srv_regobj=reg-x86-64.o
- srv_tgtobj="linux-low.o linux-x86-64-low.o i387-fp.o"
+ srv_tgtobj="linux-xen-low.o linux-x86-64-low.o
i387-fp.o"
srv_linux_regsets=yes
;;
xscale*-*-linux*) srv_regobj=reg-arm.o
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/examples/xen-backend.agent
--- a/tools/examples/xen-backend.agent Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/examples/xen-backend.agent Tue Mar 28 08:54:58 2006 -0700
@@ -1,6 +1,10 @@
#! /bin/sh
PATH=/etc/xen/scripts:$PATH
+
+. /etc/xen/scripts/locking.sh
+
+claim_lock xenbus_hotplug_global
case "$XENBUS_TYPE" in
vbd)
@@ -25,3 +29,5 @@ case "$ACTION" in
offline)
;;
esac
+
+release_lock xenbus_hotplug_global
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/examples/xend-config.sxp
--- a/tools/examples/xend-config.sxp Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/examples/xend-config.sxp Tue Mar 28 08:54:58 2006 -0700
@@ -15,7 +15,9 @@
#(loglevel DEBUG)
#(xend-http-server no)
-#(xend-unix-server yes)
+#(xend-unix-server no)
+#(xend-tcp-xmlrpc-server no)
+#(xend-unix-xmlrpc-server yes)
#(xend-relocation-server no)
(xend-relocation-server yes)
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/ioemu/hw/pcnet.c
--- a/tools/ioemu/hw/pcnet.c Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/ioemu/hw/pcnet.c Tue Mar 28 08:54:58 2006 -0700
@@ -45,21 +45,6 @@
#define PCNET_PNPMMIO_SIZE 0x20
-typedef struct PCNetState_st PCNetState;
-
-struct PCNetState_st {
- PCIDevice dev;
- NetDriverState *nd;
- int mmio_io_addr, rap, isr, lnkst;
- target_phys_addr_t rdra, tdra;
- uint8_t prom[16];
- uint16_t csr[128];
- uint16_t bcr[32];
- uint64_t timer;
- int xmit_pos, recv_pos;
- uint8_t buffer[4096];
-};
-
#include "pcnet.h"
static void pcnet_poll(PCNetState *s);
@@ -217,6 +202,11 @@ static void pcnet_init(PCNetState *s)
CSR_RCVRC(s) = CSR_RCVRL(s);
CSR_XMTRC(s) = CSR_XMTRL(s);
+ /* flush any cached receive descriptors */
+ s->crmd.rmd1.own = 0;
+ s->nrmd.rmd1.own = 0;
+ s->nnrmd.rmd1.own = 0;
+
#ifdef PCNET_DEBUG
printf("pcnet ss32=%d rdra=0x%08x[%d] tdra=0x%08x[%d]\n",
BCR_SSIZE32(s),
@@ -239,6 +229,11 @@ static void pcnet_start(PCNetState *s)
if (!CSR_DRX(s))
s->csr[0] |= 0x0020; /* set RXON */
+ /* flush any cached receive descriptors */
+ s->crmd.rmd1.own = 0;
+ s->nrmd.rmd1.own = 0;
+ s->nnrmd.rmd1.own = 0;
+
s->csr[0] &= ~0x0004; /* clear STOP bit */
s->csr[0] |= 0x0002;
}
@@ -260,29 +255,21 @@ static void pcnet_rdte_poll(PCNetState *
s->csr[28] = s->csr[29] = 0;
if (s->rdra) {
int bad = 0;
-#if 1
target_phys_addr_t crda = pcnet_rdra_addr(s, CSR_RCVRC(s));
target_phys_addr_t nrda = pcnet_rdra_addr(s, -1 + CSR_RCVRC(s));
target_phys_addr_t nnrd = pcnet_rdra_addr(s, -2 + CSR_RCVRC(s));
-#else
- target_phys_addr_t crda = s->rdra +
- (CSR_RCVRL(s) - CSR_RCVRC(s)) *
- (BCR_SWSTYLE(s) ? 16 : 8 );
- int nrdc = CSR_RCVRC(s)<=1 ? CSR_RCVRL(s) : CSR_RCVRC(s)-1;
- target_phys_addr_t nrda = s->rdra +
- (CSR_RCVRL(s) - nrdc) *
- (BCR_SWSTYLE(s) ? 16 : 8 );
- int nnrc = nrdc<=1 ? CSR_RCVRL(s) : nrdc-1;
- target_phys_addr_t nnrd = s->rdra +
- (CSR_RCVRL(s) - nnrc) *
- (BCR_SWSTYLE(s) ? 16 : 8 );
-#endif
-
- CHECK_RMD(PHYSADDR(s,crda), bad);
+
+ if (!s->crmd.rmd1.own) {
+ CHECK_RMD(&(s->crmd),PHYSADDR(s,crda), bad);
+ }
if (!bad) {
- CHECK_RMD(PHYSADDR(s,nrda), bad);
+ if (s->crmd.rmd1.own && !s->nrmd.rmd1.own) {
+ CHECK_RMD(&(s->nrmd),PHYSADDR(s,nrda), bad);
+ }
if (bad || (nrda == crda)) nrda = 0;
- CHECK_RMD(PHYSADDR(s,nnrd), bad);
+ if (s->crmd.rmd1.own && s->nrmd.rmd1.own && !s->nnrmd.rmd1.own) {
+ CHECK_RMD(&(s->nnrmd),PHYSADDR(s,nnrd), bad);
+ }
if (bad || (nnrd == crda)) nnrd = 0;
s->csr[28] = crda & 0xffff;
@@ -303,14 +290,12 @@ static void pcnet_rdte_poll(PCNetState *
}
if (CSR_CRDA(s)) {
- struct pcnet_RMD rmd;
- RMDLOAD(&rmd, PHYSADDR(s,CSR_CRDA(s)));
- CSR_CRBC(s) = rmd.rmd1.bcnt;
- CSR_CRST(s) = ((uint32_t *)&rmd)[1] >> 16;
+ CSR_CRBC(s) = s->crmd.rmd1.bcnt;
+ CSR_CRST(s) = ((uint32_t *)&(s->crmd))[1] >> 16;
#ifdef PCNET_DEBUG_RMD_X
printf("CRDA=0x%08x CRST=0x%04x RCVRC=%d RMD1=0x%08x RMD2=0x%08x\n",
PHYSADDR(s,CSR_CRDA(s)), CSR_CRST(s), CSR_RCVRC(s),
- ((uint32_t *)&rmd)[1], ((uint32_t *)&rmd)[2]);
+ ((uint32_t *)&(s->crmd))[1], ((uint32_t *)&(s->crmd))[2]);
PRINT_RMD(&rmd);
#endif
} else {
@@ -318,10 +303,8 @@ static void pcnet_rdte_poll(PCNetState *
}
if (CSR_NRDA(s)) {
- struct pcnet_RMD rmd;
- RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s)));
- CSR_NRBC(s) = rmd.rmd1.bcnt;
- CSR_NRST(s) = ((uint32_t *)&rmd)[1] >> 16;
+ CSR_NRBC(s) = s->nrmd.rmd1.bcnt;
+ CSR_NRST(s) = ((uint32_t *)&(s->nrmd))[1] >> 16;
} else {
CSR_NRBC(s) = CSR_NRST(s) = 0;
}
@@ -336,6 +319,7 @@ static int pcnet_tdte_poll(PCNetState *s
(CSR_XMTRL(s) - CSR_XMTRC(s)) *
(BCR_SWSTYLE(s) ? 16 : 8 );
int bad = 0;
+ s->csr[0] &= ~0x0008; /* clear TDMD */
CHECK_TMD(PHYSADDR(s, cxda),bad);
if (!bad) {
if (CSR_CXDA(s) != cxda) {
@@ -354,12 +338,8 @@ static int pcnet_tdte_poll(PCNetState *s
}
if (CSR_CXDA(s)) {
- struct pcnet_TMD tmd;
-
- TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
-
- CSR_CXBC(s) = tmd.tmd1.bcnt;
- CSR_CXST(s) = ((uint32_t *)&tmd)[1] >> 16;
+ CSR_CXBC(s) = s->tmd.tmd1.bcnt;
+ CSR_CXST(s) = ((uint32_t *)&(s->tmd))[1] >> 16;
} else {
CSR_CXBC(s) = CSR_CXST(s) = 0;
}
@@ -373,14 +353,11 @@ static int pcnet_can_receive(void *opaqu
if (CSR_STOP(s) || CSR_SPND(s))
return 0;
- if (s->recv_pos > 0)
- return 0;
-
pcnet_rdte_poll(s);
if (!(CSR_CRST(s) & 0x8000)) {
return 0;
}
- return sizeof(s->buffer)-16;
+ return sizeof(s->rx_buffer)-16;
}
#define MIN_BUF_SIZE 60
@@ -389,7 +366,7 @@ static void pcnet_receive(void *opaque,
{
PCNetState *s = opaque;
int is_padr = 0, is_bcast = 0, is_ladr = 0;
- uint8_t buf1[60];
+ int pad;
if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
return;
@@ -399,12 +376,10 @@ static void pcnet_receive(void *opaque,
#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 (size < MIN_BUF_SIZE)
+ pad = MIN_BUF_SIZE - size + 4;
+ else
+ pad = 4;
if (CSR_PROM(s)
|| (is_padr=padr_match(s, buf, size))
@@ -413,124 +388,74 @@ static void pcnet_receive(void *opaque,
pcnet_rdte_poll(s);
- if (!(CSR_CRST(s) & 0x8000) && s->rdra) {
- struct pcnet_RMD rmd;
- int rcvrc = CSR_RCVRC(s)-1,i;
- target_phys_addr_t nrda;
- for (i = CSR_RCVRL(s)-1; i > 0; i--, rcvrc--) {
- if (rcvrc <= 1)
- rcvrc = CSR_RCVRL(s);
- nrda = s->rdra +
- (CSR_RCVRL(s) - rcvrc) *
- (BCR_SWSTYLE(s) ? 16 : 8 );
- RMDLOAD(&rmd, PHYSADDR(s,nrda));
- if (rmd.rmd1.own) {
+ if (size > 2000) {
#ifdef PCNET_DEBUG_RMD
- printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n",
- rcvrc, CSR_RCVRC(s));
-#endif
- CSR_RCVRC(s) = rcvrc;
- pcnet_rdte_poll(s);
- break;
- }
- }
- }
-
- if (!(CSR_CRST(s) & 0x8000)) {
+ printf("pcnet - oversize packet discarded.\n");
+#endif
+ } else if (!(CSR_CRST(s) & 0x8000)) {
#ifdef PCNET_DEBUG_RMD
printf("pcnet - no buffer: RCVRC=%d\n", CSR_RCVRC(s));
#endif
s->csr[0] |= 0x1000; /* Set MISS flag */
CSR_MISSC(s)++;
} else {
- uint8_t *src = &s->buffer[8];
+ uint8_t *src = &s->rx_buffer[8];
target_phys_addr_t crda = CSR_CRDA(s);
- struct pcnet_RMD rmd;
+ target_phys_addr_t nrda = CSR_NRDA(s);
+ target_phys_addr_t nnrda = CSR_NNRD(s);
int pktcount = 0;
+ int packet_size = size + pad;
memcpy(src, buf, size);
-
- if (!CSR_ASTRP_RCV(s)) {
- uint32_t fcs = ~0;
-#if 0
- uint8_t *p = s->buffer;
-
- ((uint32_t *)p)[0] = ((uint32_t *)p)[1] = 0xaaaaaaaa;
- p[7] = 0xab;
-#else
- uint8_t *p = src;
-#endif
-
- while (size < 46) {
- src[size++] = 0;
- }
-
- while (p != &src[size]) {
- CRC(fcs, *p++);
- }
- ((uint32_t *)&src[size])[0] = htonl(fcs);
- size += 4; /* FCS at end of packet */
- } else size += 4;
+ memset(src + size, 0, pad);
+ size += pad;
#ifdef PCNET_DEBUG_MATCH
PRINT_PKTHDR(buf);
#endif
- RMDLOAD(&rmd, PHYSADDR(s,crda));
- /*if (!CSR_LAPPEN(s))*/
- rmd.rmd1.stp = 1;
-
-#define PCNET_RECV_STORE() do { \
- int count = MIN(4096 - rmd.rmd1.bcnt,size); \
- target_phys_addr_t rbadr = PHYSADDR(s, rmd.rmd0.rbadr); \
- cpu_physical_memory_write(rbadr, src, count); \
- cpu_physical_memory_set_dirty(rbadr); \
- cpu_physical_memory_set_dirty(rbadr+count); \
- src += count; size -= count; \
- rmd.rmd2.mcnt = count; rmd.rmd1.own = 0; \
- RMDSTORE(&rmd, PHYSADDR(s,crda)); \
- pktcount++; \
-} while (0)
-
- PCNET_RECV_STORE();
- if ((size > 0) && CSR_NRDA(s)) {
- target_phys_addr_t nrda = CSR_NRDA(s);
- RMDLOAD(&rmd, PHYSADDR(s,nrda));
- if (rmd.rmd1.own) {
- crda = nrda;
- PCNET_RECV_STORE();
- if ((size > 0) && (nrda=CSR_NNRD(s))) {
- RMDLOAD(&rmd, PHYSADDR(s,nrda));
- if (rmd.rmd1.own) {
- crda = nrda;
- PCNET_RECV_STORE();
- }
- }
- }
+ s->crmd.rmd1.stp = 1;
+ do {
+ int count = MIN(4096 - s->crmd.rmd1.bcnt,size);
+ target_phys_addr_t rbadr = PHYSADDR(s, s->crmd.rmd0.rbadr);
+ cpu_physical_memory_write(rbadr, src, count);
+ cpu_physical_memory_set_dirty(rbadr);
+ cpu_physical_memory_set_dirty(rbadr+count);
+ src += count; size -= count;
+ if (size > 0 && s->nrmd.rmd1.own) {
+ RMDSTORE(&(s->crmd), PHYSADDR(s,crda));
+ crda = nrda;
+ nrda = nnrda;
+ s->crmd = s->nrmd;
+ s->nrmd = s->nnrmd;
+ s->nnrmd.rmd1.own = 0;
+ }
+ pktcount++;
+ } while (size > 0 && s->crmd.rmd1.own);
+
+ if (size == 0) {
+ s->crmd.rmd1.enp = 1;
+ s->crmd.rmd2.mcnt = packet_size;
+ s->crmd.rmd1.pam = !CSR_PROM(s) && is_padr;
+ s->crmd.rmd1.lafm = !CSR_PROM(s) && is_ladr;
+ s->crmd.rmd1.bam = !CSR_PROM(s) && is_bcast;
+ } else {
+ s->crmd.rmd1.oflo = 1;
+ s->crmd.rmd1.buff = 1;
+ s->crmd.rmd1.err = 1;
}
-
-#undef PCNET_RECV_STORE
-
- RMDLOAD(&rmd, PHYSADDR(s,crda));
- if (size == 0) {
- rmd.rmd1.enp = 1;
- rmd.rmd1.pam = !CSR_PROM(s) && is_padr;
- rmd.rmd1.lafm = !CSR_PROM(s) && is_ladr;
- rmd.rmd1.bam = !CSR_PROM(s) && is_bcast;
- } else {
- rmd.rmd1.oflo = 1;
- rmd.rmd1.buff = 1;
- rmd.rmd1.err = 1;
- }
- RMDSTORE(&rmd, PHYSADDR(s,crda));
+ RMDSTORE(&(s->crmd), PHYSADDR(s,crda));
s->csr[0] |= 0x0400;
+ s->crmd = s->nrmd;
+ s->nrmd = s->nnrmd;
+ s->nnrmd.rmd1.own = 0;
#ifdef PCNET_DEBUG
printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n",
CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount);
#endif
#ifdef PCNET_DEBUG_RMD
- PRINT_RMD(&rmd);
+ PRINT_RMD(&s->crmd);
#endif
while (pktcount--) {
@@ -551,80 +476,88 @@ static void pcnet_receive(void *opaque,
static void pcnet_transmit(PCNetState *s)
{
- target_phys_addr_t xmit_cxda = 0;
+ target_phys_addr_t start_addr = 0;
+ struct pcnet_TMD start_tmd;
int count = CSR_XMTRL(s)-1;
- s->xmit_pos = -1;
+ int xmit_pos = 0;
+ int len;
+
if (!CSR_TXON(s)) {
s->csr[0] &= ~0x0008;
return;
}
- txagain:
- if (pcnet_tdte_poll(s)) {
- struct pcnet_TMD tmd;
-
- TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
+ while (pcnet_tdte_poll(s)) {
#ifdef PCNET_DEBUG_TMD
printf(" TMDLOAD 0x%08x\n", PHYSADDR(s,CSR_CXDA(s)));
- PRINT_TMD(&tmd);
-#endif
- if (tmd.tmd1.stp) {
- s->xmit_pos = 0;
- if (!tmd.tmd1.enp) {
- cpu_physical_memory_read(PHYSADDR(s, tmd.tmd0.tbadr),
- s->buffer, 4096 - tmd.tmd1.bcnt);
- s->xmit_pos += 4096 - tmd.tmd1.bcnt;
- }
- xmit_cxda = PHYSADDR(s,CSR_CXDA(s));
- }
- if (tmd.tmd1.enp && (s->xmit_pos >= 0)) {
- cpu_physical_memory_read(PHYSADDR(s, tmd.tmd0.tbadr),
- s->buffer + s->xmit_pos, 4096 - tmd.tmd1.bcnt);
- s->xmit_pos += 4096 - tmd.tmd1.bcnt;
-
- tmd.tmd1.own = 0;
- TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
-
-#ifdef PCNET_DEBUG
- printf("pcnet_transmit size=%d\n", s->xmit_pos);
-#endif
- if (CSR_LOOP(s))
- pcnet_receive(s, s->buffer, s->xmit_pos);
- else
- qemu_send_packet(s->nd, s->buffer, s->xmit_pos);
-
- s->csr[0] &= ~0x0008; /* clear TDMD */
- s->csr[4] |= 0x0004; /* set TXSTRT */
- s->xmit_pos = -1;
- } else {
- tmd.tmd1.own = 0;
- TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
- }
- if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && tmd.tmd1.ltint))
- s->csr[0] |= 0x0200; /* set TINT */
-
- if (CSR_XMTRC(s)<=1)
+ PRINT_TMD(&(s->tmd));
+#endif
+ len = 4096 - s->tmd.tmd1.bcnt;
+ if (CSR_XMTRC(s) <= 1)
CSR_XMTRC(s) = CSR_XMTRL(s);
else
CSR_XMTRC(s)--;
- if (count--)
- goto txagain;
-
- } else
- if (s->xmit_pos >= 0) {
- struct pcnet_TMD tmd;
- TMDLOAD(&tmd, PHYSADDR(s,xmit_cxda));
- tmd.tmd2.buff = tmd.tmd2.uflo = tmd.tmd1.err = 1;
- tmd.tmd1.own = 0;
- TMDSTORE(&tmd, PHYSADDR(s,xmit_cxda));
+
+ /* handle start followed by start */
+ if (s->tmd.tmd1.stp && start_addr) {
+ TMDSTORE(&start_tmd, start_addr);
+ start_addr = 0;
+ xmit_pos = 0;
+ }
+ if ((xmit_pos + len) < sizeof(s->tx_buffer)) {
+ cpu_physical_memory_read(PHYSADDR(s, s->tmd.tmd0.tbadr),
+ s->tx_buffer + xmit_pos, len);
+ xmit_pos += len;
+ } else {
+ s->tmd.tmd2.buff = s->tmd.tmd2.uflo = s->tmd.tmd1.err = 1;
+ TMDSTORE(&(s->tmd), PHYSADDR(s,CSR_CXDA(s)));
+ if (start_addr == PHYSADDR(s,CSR_CXDA(s)))
+ start_addr = 0; /* don't clear own bit twice */
+ continue;
+ }
+ if (s->tmd.tmd1.stp) {
+ if (s->tmd.tmd1.enp) {
+ if (CSR_LOOP(s))
+ pcnet_receive(s, s->tx_buffer, xmit_pos);
+ else
+ qemu_send_packet(s->nd, s->tx_buffer, xmit_pos);
+
+ s->csr[4] |= 0x0008; /* set TXSTRT */
+ TMDSTORE(&(s->tmd), PHYSADDR(s,CSR_CXDA(s)));
+ xmit_pos = 0;
+ count--;
+ } else {
+ start_tmd = s->tmd;
+ start_addr = PHYSADDR(s,CSR_CXDA(s));
+ }
+ } else if (s->tmd.tmd1.enp) {
+ TMDSTORE(&(s->tmd), PHYSADDR(s,CSR_CXDA(s)));
+ if (start_addr) {
+ TMDSTORE(&start_tmd, start_addr);
+ }
+ start_addr = 0;
+ xmit_pos = 0;
+ count--;
+
+ } else {
+ TMDSTORE(&(s->tmd), PHYSADDR(s,CSR_CXDA(s)));
+ }
+ if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && s->tmd.tmd1.ltint))
+ s->csr[0] |= 0x0200; /* set TINT */
+
+ if (count <= 0)
+ break;
+
+ }
+ if (start_addr) {
+ start_tmd.tmd2.buff = start_tmd.tmd2.uflo = start_tmd.tmd1.err = 1;
+ TMDSTORE(&start_tmd, PHYSADDR(s,start_addr));
s->csr[0] |= 0x0200; /* set TINT */
if (!CSR_DXSUFLO(s)) {
s->csr[0] &= ~0x0010;
- } else
- if (count--)
- goto txagain;
+ }
}
}
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/ioemu/hw/pcnet.h
--- a/tools/ioemu/hw/pcnet.h Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/ioemu/hw/pcnet.h Tue Mar 28 08:54:58 2006 -0700
@@ -177,6 +177,26 @@ struct pcnet_RMD {
} rmd3;
};
+typedef struct PCNetState_st PCNetState;
+
+struct PCNetState_st {
+ PCIDevice dev;
+ NetDriverState *nd;
+ int mmio_io_addr, rap, isr, lnkst;
+ target_phys_addr_t rdra, tdra;
+ uint8_t prom[16];
+ uint16_t csr[128];
+ uint16_t bcr[32];
+ uint64_t timer;
+ int recv_pos;
+ uint8_t tx_buffer[2048];
+ uint8_t rx_buffer[2048];
+ struct pcnet_TMD tmd;
+ struct pcnet_RMD crmd;
+ struct pcnet_RMD nrmd;
+ struct pcnet_RMD nnrmd;
+};
+
#define PRINT_TMD(T) printf( \
"TMD0 : TBADR=0x%08x\n" \
@@ -230,18 +250,17 @@ static inline void pcnet_tmd_load(PCNetS
cpu_physical_memory_read(addr+4, (void *)&tmd->tmd1, 4);
cpu_physical_memory_read(addr, (void *)&tmd->tmd0, 4);
} else {
- uint32_t xda[4];
- cpu_physical_memory_read(addr,
- (void *)&xda[0], sizeof(xda));
- ((uint32_t *)tmd)[0] = xda[2];
- ((uint32_t *)tmd)[1] = xda[1];
- ((uint32_t *)tmd)[2] = xda[0];
- ((uint32_t *)tmd)[3] = xda[3];
+ uint32_t xda[2];
+ cpu_physical_memory_read(addr+4, (void *)&xda[0], sizeof(xda));
+ ((uint32_t *)tmd)[0] = xda[1];
+ ((uint32_t *)tmd)[1] = xda[0];
+ ((uint32_t *)tmd)[2] = 0;
}
}
static inline void pcnet_tmd_store(PCNetState *s, struct pcnet_TMD *tmd,
target_phys_addr_t addr)
{
+ tmd->tmd1.own = 0;
cpu_physical_memory_set_dirty(addr);
if (!BCR_SWSTYLE(s)) {
uint16_t xda[4];
@@ -259,13 +278,10 @@ static inline void pcnet_tmd_store(PCNet
cpu_physical_memory_write(addr+8, (void *)&tmd->tmd2, 4);
cpu_physical_memory_write(addr+4, (void *)&tmd->tmd1, 4);
} else {
- uint32_t xda[4];
+ uint32_t xda[2];
xda[0] = ((uint32_t *)tmd)[2];
xda[1] = ((uint32_t *)tmd)[1];
- xda[2] = ((uint32_t *)tmd)[0];
- xda[3] = ((uint32_t *)tmd)[3];
- cpu_physical_memory_write(addr,
- (void *)&xda[0], sizeof(xda));
+ cpu_physical_memory_write(addr, (void *)&xda[0], sizeof(xda));
}
cpu_physical_memory_set_dirty(addr+15);
}
@@ -286,22 +302,21 @@ static inline void pcnet_rmd_load(PCNetS
}
else
if (BCR_SWSTYLE(s) != 3) {
- rmd->rmd2.zeros = 0;
+ ((uint32_t *)rmd)[2] = 0;
cpu_physical_memory_read(addr+4, (void *)&rmd->rmd1, 4);
cpu_physical_memory_read(addr, (void *)&rmd->rmd0, 4);
} else {
- uint32_t rda[4];
- cpu_physical_memory_read(addr,
- (void *)&rda[0], sizeof(rda));
- ((uint32_t *)rmd)[0] = rda[2];
- ((uint32_t *)rmd)[1] = rda[1];
- ((uint32_t *)rmd)[2] = rda[0];
- ((uint32_t *)rmd)[3] = rda[3];
+ uint32_t rda[2];
+ cpu_physical_memory_read(addr+4, (void *)&rda[0], sizeof(rda));
+ ((uint32_t *)rmd)[0] = rda[1];
+ ((uint32_t *)rmd)[1] = rda[0];
+ ((uint32_t *)rmd)[2] = 0;
}
}
static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd,
target_phys_addr_t addr)
{
+ rmd->rmd1.own = 0;
cpu_physical_memory_set_dirty(addr);
if (!BCR_SWSTYLE(s)) {
uint16_t rda[4]; \
@@ -319,13 +334,10 @@ static inline void pcnet_rmd_store(PCNet
cpu_physical_memory_write(addr+8, (void *)&rmd->rmd2, 4);
cpu_physical_memory_write(addr+4, (void *)&rmd->rmd1, 4);
} else {
- uint32_t rda[4];
+ uint32_t rda[2];
rda[0] = ((uint32_t *)rmd)[2];
rda[1] = ((uint32_t *)rmd)[1];
- rda[2] = ((uint32_t *)rmd)[0];
- rda[3] = ((uint32_t *)rmd)[3];
- cpu_physical_memory_write(addr,
- (void *)&rda[0], sizeof(rda));
+ cpu_physical_memory_write(addr, (void *)&rda[0], sizeof(rda));
}
cpu_physical_memory_set_dirty(addr+15);
}
@@ -340,79 +352,16 @@ static inline void pcnet_rmd_store(PCNet
#define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR)
-#if 1
-
-#define CHECK_RMD(ADDR,RES) do { \
- struct pcnet_RMD rmd; \
- RMDLOAD(&rmd,(ADDR)); \
- (RES) |= (rmd.rmd1.ones != 15); \
+#define CHECK_RMD(RMD,ADDR,RES) do { \
+ RMDLOAD((RMD),(ADDR)); \
+ (RES) |= ((RMD)->rmd1.ones != 15); \
} while (0)
-#define CHECK_TMD(ADDR,RES) do { \
- struct pcnet_TMD tmd; \
- TMDLOAD(&tmd,(ADDR)); \
- (RES) |= (tmd.tmd1.ones != 15); \
+#define CHECK_TMD(ADDR,RES) do { \
+ TMDLOAD(&(s->tmd),(ADDR)); \
+ (RES) |= (s->tmd.tmd1.ones != 15); \
} while (0)
-#else
-
-#define CHECK_RMD(ADDR,RES) do { \
- switch (BCR_SWSTYLE(s)) { \
- case 0x00: \
- do { \
- uint16_t rda[4]; \
- cpu_physical_memory_read((ADDR), \
- (void *)&rda[0], sizeof(rda)); \
- (RES) |= (rda[2] & 0xf000)!=0xf000; \
- (RES) |= (rda[3] & 0xf000)!=0x0000; \
- } while (0); \
- break; \
- case 0x01: \
- case 0x02: \
- do { \
- uint32_t rda[4]; \
- cpu_physical_memory_read((ADDR), \
- (void *)&rda[0], sizeof(rda)); \
- (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
- (RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \
- } while (0); \
- break; \
- case 0x03: \
- do { \
- uint32_t rda[4]; \
- cpu_physical_memory_read((ADDR), \
- (void *)&rda[0], sizeof(rda)); \
- (RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \
- (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
- } while (0); \
- break; \
- } \
-} while (0)
-
-#define CHECK_TMD(ADDR,RES) do { \
- switch (BCR_SWSTYLE(s)) { \
- case 0x00: \
- do { \
- uint16_t xda[4]; \
- cpu_physical_memory_read((ADDR), \
- (void *)&xda[0], sizeof(xda)); \
- (RES) |= (xda[2] & 0xf000)!=0xf000;\
- } while (0); \
- break; \
- case 0x01: \
- case 0x02: \
- case 0x03: \
- do { \
- uint32_t xda[4]; \
- cpu_physical_memory_read((ADDR), \
- (void *)&xda[0], sizeof(xda)); \
- (RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \
- } while (0); \
- break; \
- } \
-} while (0)
-
-#endif
#define PRINT_PKTHDR(BUF) do { \
struct ether_header *hdr = (void *)(BUF); \
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/libxc/Makefile
--- a/tools/libxc/Makefile Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/libxc/Makefile Tue Mar 28 08:54:58 2006 -0700
@@ -21,13 +21,9 @@ SRCS += xc_sedf.c
SRCS += xc_sedf.c
SRCS += xc_tbuf.c
-ifeq ($(XEN_TARGET_ARCH),x86_32)
+ifeq ($(patsubst x86%,x86,$(XEN_TARGET_ARCH)),x86)
SRCS += xc_ptrace.c
SRCS += xc_ptrace_core.c
-SRCS += xc_pagetab.c
-endif
-
-ifeq ($(XEN_TARGET_ARCH),x86_64)
SRCS += xc_pagetab.c
endif
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/libxc/xc_core.c
--- a/tools/libxc/xc_core.c Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/libxc/xc_core.c Tue Mar 28 08:54:58 2006 -0700
@@ -3,7 +3,6 @@
#include "xc_elf.h"
#include <stdlib.h>
#include <unistd.h>
-#include <zlib.h>
/* number of pages to write at a time */
#define DUMP_INCREMENT (4 * 1024)
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/libxc/xc_private.c Tue Mar 28 08:54:58 2006 -0700
@@ -4,7 +4,6 @@
* Helper functions for the rest of the library.
*/
-#include <zlib.h>
#include "xc_private.h"
#include <xen/memory.h>
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/libxc/xc_ptrace.c
--- a/tools/libxc/xc_ptrace.c Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/libxc/xc_ptrace.c Tue Mar 28 08:54:58 2006 -0700
@@ -38,9 +38,6 @@ static char *ptrace_names[] = {
};
#endif
-/* XXX application state */
-static long nr_pages = 0;
-static unsigned long *page_array = NULL;
static int current_domid = -1;
static int current_isfile;
@@ -196,6 +193,60 @@ map_domain_va_pae(
return (void *)((unsigned long)v | (va & (PAGE_SIZE - 1)));
}
+#ifdef __x86_64__
+static void *
+map_domain_va(
+ int xc_handle,
+ int cpu,
+ void *guest_va,
+ int perm)
+{
+ unsigned long l3p, l2p, l1p, p, va = (unsigned long)guest_va;
+ uint64_t *l4, *l3, *l2, *l1;
+ static void *v;
+
+ if ((ctxt[cpu].ctrlreg[4] & 0x20) == 0 ) /* legacy ia32 mode */
+ return map_domain_va_pae(xc_handle, cpu, guest_va, perm);
+
+ if (fetch_regs(xc_handle, cpu, NULL))
+ return NULL;
+
+ l4 = xc_map_foreign_range(
+ xc_handle, current_domid, PAGE_SIZE, PROT_READ, ctxt[cpu].ctrlreg[3]
>> PAGE_SHIFT);
+ if ( l4 == NULL )
+ return NULL;
+
+ l3p = l4[l4_table_offset(va)] >> PAGE_SHIFT;
+ l3 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ,
l3p);
+ if ( l3 == NULL )
+ return NULL;
+
+ l2p = l3[l3_table_offset(va)] >> PAGE_SHIFT;
+ l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ,
l2p);
+ if ( l2 == NULL )
+ return NULL;
+
+ l1p = l2[l2_table_offset(va)] >> PAGE_SHIFT;
+ l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p);
+ if ( l1 == NULL )
+ return NULL;
+
+ p = l1[l1_table_offset(va)] >> PAGE_SHIFT;
+ if ( v != NULL )
+ munmap(v, PAGE_SIZE);
+ v = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p);
+ if ( v == NULL )
+ return NULL;
+
+ return (void *)((unsigned long)v | (va & (PAGE_SIZE - 1)));
+}
+#endif
+
+#ifdef __i386__
+/* XXX application state */
+static long nr_pages = 0;
+static unsigned long *page_array = NULL;
+
static void *
map_domain_va(
int xc_handle,
@@ -216,15 +267,18 @@ map_domain_va(
static unsigned long page_phys[MAX_VIRT_CPUS];
static unsigned long *page_virt[MAX_VIRT_CPUS];
static int prev_perm[MAX_VIRT_CPUS];
- static enum { MODE_UNKNOWN, MODE_32, MODE_PAE } mode;
+ static enum { MODE_UNKNOWN, MODE_32, MODE_PAE, MODE_64 } mode;
if ( mode == MODE_UNKNOWN )
{
xen_capabilities_info_t caps;
(void)xc_version(xc_handle, XENVER_capabilities, caps);
- mode = MODE_32;
- if ( strstr(caps, "_x86_32p") )
+ if ( strstr(caps, "-x86_64") )
+ mode = MODE_64;
+ else if ( strstr(caps, "-x86_32p") )
mode = MODE_PAE;
+ else if ( strstr(caps, "-x86_32") )
+ mode = MODE_32;
}
if ( mode == MODE_PAE )
@@ -303,6 +357,8 @@ map_domain_va(
return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK));
}
+
+#endif
static int
__xc_waitdomain(
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/libxc/xc_ptrace.h
--- a/tools/libxc/xc_ptrace.h Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/libxc/xc_ptrace.h Tue Mar 28 08:54:58 2006 -0700
@@ -9,6 +9,96 @@
#define BSD_PAGE_MASK (PAGE_SIZE-1)
#define PDRSHIFT 22
#define PSL_T 0x00000100 /* trace enable bit */
+
+#ifdef __x86_64__
+struct gdb_regs
+{
+ unsigned long r15;
+ unsigned long r14;
+ unsigned long r13;
+ unsigned long r12;
+ unsigned long rbp;
+ unsigned long rbx;
+ unsigned long r11;
+ unsigned long r10;
+ unsigned long r9;
+ unsigned long r8;
+ unsigned long rax;
+ unsigned long rcx;
+ unsigned long rdx;
+ unsigned long rsi;
+ unsigned long rdi;
+ unsigned long orig_rax;
+ unsigned long rip;
+ unsigned long xcs;
+ unsigned long eflags;
+ unsigned long rsp;
+ unsigned long xss;
+ unsigned long fs_base;
+ unsigned long gs_base;
+ unsigned long xds;
+ unsigned long xes;
+ unsigned long xfs;
+ unsigned long xgs;
+};
+
+#define SET_PT_REGS(pt, xc) \
+{ \
+ pt.r8 = xc.r8; \
+ pt.r9 = xc.r9; \
+ pt.r10 = xc.r10; \
+ pt.r11 = xc.r11; \
+ pt.r12 = xc.r12; \
+ pt.r13 = xc.r13; \
+ pt.r14 = xc.r14; \
+ pt.r15 = xc.r15; \
+ pt.rbx = xc.rbx; \
+ pt.rcx = xc.rcx; \
+ pt.rdx = xc.rdx; \
+ pt.rsi = xc.rsi; \
+ pt.rdi = xc.rdi; \
+ pt.rbp = xc.rbp; \
+ pt.rax = xc.rax; \
+ pt.rip = xc.rip; \
+ pt.xcs = xc.cs; \
+ pt.eflags = xc.eflags; \
+ pt.rsp = xc.rsp; \
+ pt.xss = xc.ss; \
+ pt.xes = xc.es; \
+ pt.xds = xc.ds; \
+ pt.xfs = xc.fs; \
+ pt.xgs = xc.gs; \
+}
+
+#define SET_XC_REGS(pt, xc) \
+{ \
+ xc.r8 = pt->r8; \
+ xc.r9 = pt->r9; \
+ xc.r10 = pt->r10; \
+ xc.r11 = pt->r11; \
+ xc.r12 = pt->r12; \
+ xc.r13 = pt->r13; \
+ xc.r14 = pt->r14; \
+ xc.r15 = pt->r15; \
+ xc.rbx = pt->rbx; \
+ xc.rcx = pt->rcx; \
+ xc.rdx = pt->rdx; \
+ xc.rsi = pt->rsi; \
+ xc.rdi = pt->rdi; \
+ xc.rbp = pt->rbp; \
+ xc.rax = pt->rax; \
+ xc.rip = pt->rip; \
+ xc.cs = pt->xcs; \
+ xc.eflags = pt->eflags; \
+ xc.rsp = pt->rsp; \
+ xc.ss = pt->xss; \
+ xc.es = pt->xes; \
+ xc.ds = pt->xds; \
+ xc.fs = pt->xfs; \
+ xc.gs = pt->xgs; \
+}
+
+#elif __i386__
struct gdb_regs {
long ebx; /* 0 */
@@ -30,8 +120,6 @@ struct gdb_regs {
int xss; /* 64 */
};
-
-#define printval(x) printf("%s = %lx\n", #x, (long)x);
#define SET_PT_REGS(pt, xc) \
{ \
pt.ebx = xc.ebx; \
@@ -71,7 +159,9 @@ struct gdb_regs {
xc.fs = pt->xfs; \
xc.gs = pt->xgs; \
}
+#endif
+#define printval(x) printf("%s = %lx\n", #x, (long)x);
#define vtopdi(va) ((va) >> PDRSHIFT)
#define vtopti(va) (((va) >> PAGE_SHIFT) & 0x3ff)
#endif
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/xend/XendClient.py
--- a/tools/python/xen/xend/XendClient.py Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/python/xen/xend/XendClient.py Tue Mar 28 08:54:58 2006 -0700
@@ -14,403 +14,15 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
+# Copyright (C) 2006 Anthony Liguori <aliguori@xxxxxxxxxx>
#============================================================================
-"""Client API for the HTTP interface on xend.
-Callable as a script - see main().
-Supports inet or unix connection to xend.
+from xen.util.xmlrpclib2 import ServerProxy
-This API is the 'control-plane' for xend.
-The 'data-plane' is done separately.
-"""
-import os
-import sys
-import types
+XML_RPC_SOCKET = "/var/run/xend-xmlrpc.sock"
-import sxp
-import PrettyPrint
-from XendProtocol import HttpXendClientProtocol, \
- UnixXendClientProtocol, \
- XendError
+ERROR_INTERNAL = 1
+ERROR_GENERIC = 2
+ERROR_INVALID_DOMAIN = 3
-def fileof(val):
- """Converter for passing configs or other 'large' data.
- Handles lists, files directly.
- Assumes a string is a file name and passes its contents.
- """
- if isinstance(val, types.ListType):
- return sxp.to_string(val)
- if isinstance(val, types.StringType):
- return file(val)
- if hasattr(val, 'readlines'):
- return val
- raise XendError('cannot convert value')
-
-class URL:
- """A URL.
- """
-
- def __init__(self, proto='http', host='localhost', port=None, path='',
query=None, frag=None):
- self.proto = proto
- self.host = host
- if port: port = int(port)
- self.port = port
- self.path = path
- self.query = query
- self.frag = frag
-
- def url(self):
- """Get the full URL string including protocol, location and the full
path.
- """
- return self.proto + '://' + self.location() + self.fullpath()
-
- def location(self):
- """Get the location part of the URL, including host and port, if
present.
- """
- if self.port:
- return self.host + ':' + str(self.port)
- else:
- return self.host
-
- def fullpath(self):
- """Get the full path part of the URL, including query and fragment if
present.
- """
- u = [ self.path ]
- if self.query:
- u.append('?')
- u.append(self.query)
- if self.frag:
- u.append('#')
- u.append(self.frag)
- return ''.join(u)
-
- def relative(self, path='', query=None, frag=None):
- """Create a URL relative to this one.
- """
- return URL(proto=self.proto,
- host=self.host,
- port=self.port,
- path=self.path + path,
- query=query,
- frag=frag)
-
-class Xend:
- """Client interface to Xend.
- """
-
- """Default location of the xend server."""
- SRV_DEFAULT = "localhost:8000"
-
- """Environment variable to set the location of xend."""
- SRV_VAR = "XEND"
-
- """Default path to the xend root on the server."""
- ROOT_DEFAULT = "/xend/"
-
- """Environment variable to set the xend root path."""
- ROOT_VAR = "XEND_ROOT"
-
- def __init__(self, client=None, srv=None, root=None):
- """Create a xend client interface.
- If the client protocol is not specified, the default
- is to use a synchronous protocol.
-
- @param client: client protocol to use
- @param srv: server host, and optional port (format host:port)
- @param root: xend root path on the server
- """
- if client is None:
- client = HttpXendClientProtocol()
- self.client = client
- self.bind(srv, root)
-
- def default_server(self):
- """Get the default location of the xend server.
- """
- return os.getenv(self.SRV_VAR, self.SRV_DEFAULT)
-
- def default_root(self):
- """Get the default root path on the xend server.
- """
- return os.getenv(self.ROOT_VAR, self.ROOT_DEFAULT)
-
- def bind(self, srv=None, root=None):
- """Bind to a given server.
-
- @param srv: server location (host:port)
- @param root: xend root path on the server
- """
- if srv is None: srv = self.default_server()
- if root is None: root = self.default_root()
- if not root.endswith('/'): root += '/'
- (host, port) = srv.split(':', 1)
- self.url = URL(host=host, port=port, path=root)
-
- def xendGet(self, url, args=None):
- return self.client.xendGet(url, args)
-
- def xendPost(self, url, data):
- return self.client.xendPost(url, data)
-
- def nodeurl(self, id=''):
- return self.url.relative('node/' + str(id))
-
- def domainurl(self, id=''):
- return self.url.relative('domain/' + str(id))
-
- def deviceurl(self, id=''):
- return self.url.relative('device/' + str(id))
-
- def vneturl(self, id=''):
- return self.url.relative('vnet/' + str(id))
-
- def xend(self):
- return self.xendGet(self.url)
-
- def xend_node(self):
- return self.xendGet(self.nodeurl())
-
- def xend_node_shutdown(self):
- return self.xendPost(self.nodeurl(),
- {'op' : 'shutdown'})
-
- def xend_node_restart(self):
- return self.xendPost(self.nodeurl(),
- {'op' : 'reboot'})
-
- def xend_node_get_dmesg(self):
- return self.xendGet(self.nodeurl('dmesg'))
-
- def xend_node_clear_dmesg(self):
- return self.xendPost(self.nodeurl('dmesg'),
- {'op' : 'clear' } )
-
- def xend_node_log(self):
- return self.xendGet(self.nodeurl('log'))
-
- def xend_node_cpu_bvt_slice_set(self, ctx_allow):
- return self.xendPost(self.nodeurl(),
- {'op' : 'cpu_bvt_slice_set',
- 'ctx_allow' : ctx_allow })
-
- def xend_domains(self):
- return self.xendGet(self.domainurl())
-
- def xend_list_domains(self, detail = True):
- return self.xendGet(self.domainurl(),
- {'detail': detail and '1' or '0'})
-
- def xend_domain_vcpuinfo(self, dom):
- return self.xendGet(self.domainurl(dom), {'op': 'vcpuinfo'})
-
- def xend_domain_create(self, conf):
- return self.xendPost(self.domainurl(),
- {'op' : 'create',
- 'config' : fileof(conf) })
-
- def xend_domain_restore(self, filename):
- return self.xendPost(self.domainurl(),
- {'op' : 'restore',
- 'file' : filename })
-
- def xend_domain_configure(self, id, conf):
- return self.xendPost(self.domainurl(id),
- {'op' : 'configure',
- 'config' : fileof(conf) })
-
- def xend_domain(self, id):
- return self.xendGet(self.domainurl(id))
-
- def xend_domain_wait_for_devices(self, id):
- return self.xendPost(self.domainurl(id),
- {'op' : 'wait_for_devices' })
-
- def xend_domain_unpause(self, id):
- return self.xendPost(self.domainurl(id),
- {'op' : 'unpause' })
-
- def xend_domain_pause(self, id):
- return self.xendPost(self.domainurl(id),
- {'op' : 'pause' })
-
- def xend_domain_rename(self, id, name):
- return self.xendPost(self.domainurl(id),
- {'op' : 'rename',
- 'name' : name})
-
- def xend_domain_shutdown(self, id, reason):
- return self.xendPost(self.domainurl(id),
- {'op' : 'shutdown',
- 'reason' : reason})
-
- def xend_domain_sysrq(self, id, key):
- return self.xendPost(self.domainurl(id),
- {'op' : 'sysrq',
- 'key' : key})
-
- def xend_domain_destroy(self, id):
- return self.xendPost(self.domainurl(id),
- {'op' : 'destroy' })
-
- def xend_domain_save(self, id, filename):
- return self.xendPost(self.domainurl(id),
- {'op' : 'save',
- 'file' : filename })
-
- def xend_domain_migrate(self, id, dst, live=0, resource=0, port=0):
- return self.xendPost(self.domainurl(id),
- {'op' : 'migrate',
- 'destination': dst,
- 'live' : live,
- 'resource' : resource,
- 'port' : port })
-
- def xend_domain_pincpu(self, id, vcpu, cpumap):
- return self.xendPost(self.domainurl(id),
- {'op' : 'pincpu',
- 'vcpu' : vcpu,
- 'cpumap' : str(cpumap) })
-
- def xend_domain_cpu_bvt_set(self, id, mcuadv, warpback, warpvalue, warpl,
warpu):
- return self.xendPost(self.domainurl(id),
- {'op' : 'cpu_bvt_set',
- 'mcuadv' : mcuadv,
- 'warpback' : warpback,
- 'warpvalue': warpvalue,
- 'warpl' : warpl,
- 'warpu' : warpu })
-
- def xend_domain_cpu_sedf_get(self, id):
- return self.xendPost(self.domainurl(id),
- {'op' : 'cpu_sedf_get'})
-
- def xend_domain_cpu_sedf_set(self, id, period, slice, latency, extratime,
weight):
- return self.xendPost(self.domainurl(id),
- {'op' : 'cpu_sedf_set',
- 'period' : period,
- 'slice' : slice,
- 'latency' : latency,
- 'extratime' : extratime,
- 'weight' : weight })
-
- def xend_domain_maxmem_set(self, id, memory):
- return self.xendPost(self.domainurl(id),
- { 'op' : 'maxmem_set',
- 'memory' : memory })
-
- def xend_domain_mem_target_set(self, id, mem_target):
- val = self.xendPost(self.domainurl(id),
- {'op' : 'mem_target_set',
- 'target' : mem_target })
- return val
-
- def xend_domain_set_vcpus(self, dom, vcpus):
- return self.xendPost(self.domainurl(dom),
- {'op' : 'set_vcpus',
- 'vcpus' : vcpus })
-
- def xend_domain_devices(self, id, type):
- return self.xendPost(self.domainurl(id),
- {'op' : 'devices',
- 'type' : type })
-
- def xend_domain_device_create(self, id, config):
- return self.xendPost(self.domainurl(id),
- {'op' : 'device_create',
- 'config' : fileof(config) })
-
- def xend_domain_device_refresh(self, id, type, dev):
- return self.xendPost(self.domainurl(id),
- {'op' : 'device_refresh',
- 'type' : type,
- 'dev' : dev })
-
- def xend_domain_device_destroy(self, id, type, dev):
- return self.xendPost(self.domainurl(id),
- {'op' : 'device_destroy',
- 'type' : type,
- 'dev' : dev })
-
- def xend_domain_device_configure(self, id, config, dev):
- return self.xendPost(self.domainurl(id),
- {'op' : 'device_configure',
- 'dev' : dev,
- 'config' : fileof(config) })
-
- def xend_vnets(self):
- return self.xendGet(self.vneturl())
-
- def xend_vnet_create(self, conf):
- return self.xendPost(self.vneturl(),
- {'op' : 'create',
- 'config' : fileof(conf) })
-
- def xend_vnet(self, id):
- return self.xendGet(self.vneturl(id))
-
- def xend_vnet_delete(self, id):
- return self.xendPost(self.vneturl(id),
- {'op' : 'delete' })
-
-def getHttpServer(srv=None):
- """Create and return a xend client.
- """
- return Xend(srv=srv, client=HttpXendClientProtocol())
-
-def getUnixServer(srv=None):
- """Create and return a unix-domain xend client.
- """
- return Xend(client=UnixXendClientProtocol(srv))
-
-def xendmain(srv, fn, args, unix=False):
- if unix:
- xend = getUnixServer(srv)
- else:
- xend = getHttpServer(srv)
- xend.rc = 0
- try:
- v = getattr(xend, fn)(*args)
- PrettyPrint.prettyprint(v)
- return 0
- except XendError, err:
- print 'ERROR:', err
- return 1
-
-def main(argv):
- """Call an API function:
-
- python XendClient.py fn args...
-
- The leading 'xend_' on the function can be omitted.
- Example:
-
-python XendClient.py domains
- (0 8)
-python XendClient.py domain 0
- (domain (id 0) (name Domain-0) (memory 128))
- """
- from getopt import getopt
- short_options = 'x:au:d'
- long_options = ['xend=', 'unix=', 'debug']
- (options, args) = getopt(argv[1:], short_options, long_options)
- srv = None
- unix = 1
- for k, v in options:
- if k in ['-x', '--xend']:
- srv = v
- elif k in ['-u', '--unix']:
- unix = int(v)
- if len(args):
- fn = args[0]
- args = args[1:]
- else:
- fn = 'xend'
- args = []
- if not fn.startswith('xend'):
- fn = 'xend_' + fn
- sys.exit(xendmain(srv, fn, args, unix=unix))
-
-if __name__ == "__main__":
- main(sys.argv)
-else:
- server = getUnixServer()
+server = ServerProxy('httpu:///var/run/xend-xmlrpc.sock')
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/python/xen/xend/XendDomain.py Tue Mar 28 08:54:58 2006 -0700
@@ -81,7 +81,8 @@ class XendDomain:
# that we're sure that we haven't missed any releases, but inside
# the domains_lock, as we don't want the watch to fire until after
# the refresh call has completed.
- xswatch("@releaseDomain", self.onReleaseDomain)
+ xswatch("@introduceDomain", self.onChangeDomain)
+ xswatch("@releaseDomain", self.onChangeDomain)
self.refresh(True)
finally:
@@ -121,7 +122,7 @@ class XendDomain:
## private:
- def onReleaseDomain(self, _):
+ def onChangeDomain(self, _):
self.domains_lock.acquire()
try:
self.refresh()
@@ -355,7 +356,7 @@ class XendDomain:
def domain_unpause(self, domid):
"""Unpause domain execution."""
try:
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
log.info("Domain %s (%d) unpaused.", dominfo.getName(),
dominfo.getDomid())
return dominfo.unpause()
@@ -366,7 +367,7 @@ class XendDomain:
def domain_pause(self, domid):
"""Pause domain execution."""
try:
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
log.info("Domain %s (%d) paused.", dominfo.getName(),
dominfo.getDomid())
return dominfo.pause()
@@ -377,10 +378,10 @@ class XendDomain:
def domain_destroy(self, domid):
"""Terminate domain immediately."""
- if domid == PRIV_DOMAIN:
- raise XendError("Cannot destroy privileged domain %i" % domid)
-
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+ if dominfo and dominfo.getDomid() == PRIV_DOMAIN:
+ raise XendError("Cannot destroy privileged domain %s" % domid)
+
if dominfo:
val = dominfo.destroy()
else:
@@ -393,7 +394,7 @@ class XendDomain:
def domain_migrate(self, domid, dst, live=False, resource=0, port=0):
"""Start domain migration."""
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
if dominfo.getDomid() == PRIV_DOMAIN:
raise XendError("Cannot migrate privileged domain %i" % domid)
@@ -418,7 +419,7 @@ class XendDomain:
"""
try:
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
if dominfo.getDomid() == PRIV_DOMAIN:
raise XendError("Cannot save privileged domain %i" % domid)
@@ -438,7 +439,7 @@ class XendDomain:
@param cpumap: string repr of list of usable cpus
"""
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
# convert cpumap string into a list of ints
cpumap = map(lambda x: int(x),
cpumap.replace("[", "").replace("]", "").split(","))
@@ -451,7 +452,7 @@ class XendDomain:
warpu):
"""Set BVT (Borrowed Virtual Time) scheduler parameters for a domain.
"""
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
try:
return xc.bvtsched_domain_set(dom=dominfo.getDomid(),
mcuadv=mcuadv,
@@ -464,7 +465,7 @@ class XendDomain:
def domain_cpu_bvt_get(self, domid):
"""Get BVT (Borrowed Virtual Time) scheduler parameters for a domain.
"""
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
try:
return xc.bvtsched_domain_get(dominfo.getDomid())
except Exception, ex:
@@ -475,7 +476,7 @@ class XendDomain:
weight):
"""Set Simple EDF scheduler parameters for a domain.
"""
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
try:
return xc.sedf_domain_set(dominfo.getDomid(), period, slice_,
latency, extratime, weight)
@@ -485,7 +486,7 @@ class XendDomain:
def domain_cpu_sedf_get(self, domid):
"""Get Simple EDF scheduler parameters for a domain.
"""
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
try:
sedf_info = xc.sedf_domain_get(dominfo.getDomid())
@@ -507,7 +508,7 @@ class XendDomain:
@param mem: memory limit (in MiB)
@return: 0 on success, -1 on error
"""
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
maxmem = int(mem) * 1024
try:
return xc.domain_setmaxmem(dominfo.getDomid(), maxmem)
@@ -521,7 +522,7 @@ class XendDomain:
@param last: last IO port
@return: 0 on success, -1 on error
"""
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
nr_ports = last - first + 1
try:
return xc.domain_ioport_permission(dominfo.getDomid(),
@@ -538,7 +539,7 @@ class XendDomain:
@param last: last IO port
@return: 0 on success, -1 on error
"""
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
nr_ports = last - first + 1
try:
return xc.domain_ioport_permission(dominfo.getDomid(),
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/xend/XendError.py
--- a/tools/python/xen/xend/XendError.py Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/python/xen/xend/XendError.py Tue Mar 28 08:54:58 2006 -0700
@@ -15,9 +15,18 @@
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
#============================================================================
-class XendError(ValueError):
+from xmlrpclib import Fault
+
+import XendClient
+
+class XendInvalidDomain(Fault):
+ def __init__(self, value):
+ Fault.__init__(self, XendClient.ERROR_INVALID_DOMAIN, value)
+
+class XendError(Fault):
def __init__(self, value):
+ Fault.__init__(self, XendClient.ERROR_GENERIC, value)
self.value = value
def __str__(self):
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/xend/XendRoot.py
--- a/tools/python/xen/xend/XendRoot.py Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/python/xen/xend/XendRoot.py Tue Mar 28 08:54:58 2006 -0700
@@ -57,8 +57,13 @@ class XendRoot:
"""Default level of information to be logged."""
loglevel_default = 'DEBUG'
- """Default for the flag indicating whether xend should run an http
server."""
+ """Default for the flag indicating whether xend should run an http server
+ (deprecated)."""
xend_http_server_default = 'no'
+
+ xend_tcp_xmlrpc_server_default = 'no'
+
+ xend_unix_xmlrpc_server_default = 'yes'
"""Default interface address xend listens at. """
xend_address_default = ''
@@ -77,8 +82,9 @@ class XendRoot:
xend_relocation_hosts_allow_default = ''
- """Default for the flag indicating whether xend should run a unix-domain
server."""
- xend_unix_server_default = 'yes'
+ """Default for the flag indicating whether xend should run a unix-domain
+ server (deprecated)."""
+ xend_unix_server_default = 'no'
"""Default path the unix-domain server listens at."""
xend_unix_path_default = '/var/lib/xend/xend-socket'
@@ -180,6 +186,12 @@ class XendRoot:
"""
return self.get_config_bool("xend-http-server",
self.xend_http_server_default)
+ def get_xend_tcp_xmlrpc_server(self):
+ return self.get_config_bool("xend-tcp-xmlrpc-server",
self.xend_tcp_xmlrpc_server_default)
+
+ def get_xend_unix_xmlrpc_server(self):
+ return self.get_config_bool("xend-unix-xmlrpc-server",
self.xend_unix_xmlrpc_server_default)
+
def get_xend_relocation_server(self):
"""Get the flag indicating whether xend should run a relocation server.
"""
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/xend/server/SrvServer.py
--- a/tools/python/xen/xend/server/SrvServer.py Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/python/xen/xend/server/SrvServer.py Tue Mar 28 08:54:58 2006 -0700
@@ -52,6 +52,7 @@ from xen.web.SrvDir import SrvDir
from xen.web.SrvDir import SrvDir
from SrvRoot import SrvRoot
+from XMLRPCServer import XMLRPCServer
xroot = XendRoot.instance()
@@ -114,4 +115,10 @@ def create():
path = xroot.get_xend_unix_path()
log.info('unix path=' + path)
servers.add(UnixHttpServer(root, path))
+
+ if xroot.get_xend_tcp_xmlrpc_server():
+ servers.add(XMLRPCServer(True))
+
+ if xroot.get_xend_unix_xmlrpc_server():
+ servers.add(XMLRPCServer())
return servers
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/xend/server/pciif.py
--- a/tools/python/xen/xend/server/pciif.py Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/python/xen/xend/server/pciif.py Tue Mar 28 08:54:58 2006 -0700
@@ -118,10 +118,12 @@ class PciController(DevController):
"parse it's resources - %s"+str(e))
if dev.driver!='pciback':
- raise VmError(("pci: PCI Backend does not own device "+
- "%s\n"+
- "See the pciback.hide kernel "+
- "command-line parameter")%(dev.name))
+ raise VmError(("pci: PCI Backend does not own device "+ \
+ "%s\n"+ \
+ "See the pciback.hide kernel "+ \
+ "command-line parameter or\n"+ \
+ "bind your slot/device to the PCI backend using sysfs" \
+ )%(dev.name))
for (start, size) in dev.ioports:
log.debug('pci: enabling ioport 0x%x/0x%x'%(start,size))
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/python/xen/xm/create.py Tue Mar 28 08:54:58 2006 -0700
@@ -30,7 +30,7 @@ import re
from xen.xend import sxp
from xen.xend import PrettyPrint
-from xen.xend.XendClient import server, XendError
+from xen.xend.XendClient import server
from xen.xend.XendBootloader import bootloader
from xen.util import blkif
@@ -813,8 +813,8 @@ def make_domain(opts, config):
"""
try:
- dominfo = server.xend_domain_create(config)
- except XendError, ex:
+ dominfo = server.xend.domain.create(config)
+ except Exception, ex:
import signal
if vncpid:
os.kill(vncpid, signal.SIGKILL)
@@ -822,13 +822,17 @@ def make_domain(opts, config):
dom = sxp.child_value(dominfo, 'name')
- if server.xend_domain_wait_for_devices(dom) < 0:
- server.xend_domain_destroy(dom)
+ try:
+ server.xend.domain.waitForDevices(dom)
+ except:
+ server.xend.domain.destroy(dom)
err("Device creation failed for domain %s" % dom)
if not opts.vals.paused:
- if server.xend_domain_unpause(dom) < 0:
- server.xend_domain_destroy(dom)
+ try:
+ server.xend.domain.unpause(dom)
+ except:
+ server.xend.domain.destroy(dom)
err("Failed to unpause domain %s" % dom)
opts.info("Started domain %s" % (dom))
return int(sxp.child_value(dominfo, 'domid'))
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/python/xen/xm/main.py Tue Mar 28 08:54:58 2006 -0700
@@ -1,6 +1,6 @@
# (C) Copyright IBM Corp. 2005
# Copyright (C) 2004 Mike Wray
-# Copyright (c) 2005 XenSource Ltd
+# Copyright (c) 2005-2006 XenSource Ltd.
#
# Authors:
# Sean Dague <sean at dague dot net>
@@ -29,8 +29,8 @@ import socket
import socket
import warnings
warnings.filterwarnings('ignore', category=FutureWarning)
-
-import xen.xend.XendError
+import xmlrpclib
+
import xen.xend.XendProtocol
from xen.xend import PrettyPrint
@@ -38,7 +38,8 @@ from xen.xm.opts import *
from xen.xm.opts import *
import console
-
+import xen.xend.XendClient
+from xen.xend.XendClient import server
# getopt.gnu_getopt is better, but only exists in Python 2.3+. Use
# getopt.getopt if gnu_getopt is not available. This will mean that options
@@ -319,8 +320,7 @@ def xm_save(args):
err("xm save: Unable to create file %s" % savefile)
sys.exit(1)
- from xen.xend.XendClient import server
- server.xend_domain_save(dom, savefile)
+ server.xend.domain.save(dom, savefile)
def xm_restore(args):
arg_check(args, "restore", 1)
@@ -331,16 +331,14 @@ def xm_restore(args):
err("xm restore: Unable to read file %s" % savefile)
sys.exit(1)
- from xen.xend.XendClient import server
- server.xend_domain_restore(savefile)
+ server.xend.domain.restore(savefile)
def getDomains(domain_names):
- from xen.xend.XendClient import server
if domain_names:
- return map(server.xend_domain, domain_names)
- else:
- return server.xend_list_domains()
+ return map(server.xend.domain, domain_names)
+ else:
+ return server.xend.domains(1)
def xm_list(args):
@@ -416,12 +414,11 @@ def xm_brief_list(doms):
def xm_vcpu_list(args):
- from xen.xend.XendClient import server
if args:
- dominfo = map(server.xend_domain_vcpuinfo, args)
- else:
- doms = server.xend_list_domains(False)
- dominfo = map(server.xend_domain_vcpuinfo, doms)
+ dominfo = map(server.xend.domain.getVCPUInfo, args)
+ else:
+ doms = server.xend.domains(False)
+ dominfo = map(server.xend.domain.getVCPUInfo, doms)
print 'Name ID VCPU CPU State Time(s)
CPU Affinity'
@@ -475,8 +472,7 @@ def xm_vcpu_list(args):
cpumap = map(lambda x: int(x), cpumap)
cpumap.sort()
- from xen.xend.XendClient import server
- for x in server.xend_node()[1:]:
+ for x in server.xend.node.info()[1:]:
if len(x) > 1 and x[0] == 'nr_cpus':
nr_cpus = int(x[1])
# normalize cpumap by modulus nr_cpus, and drop duplicates
@@ -532,21 +528,18 @@ def xm_pause(args):
arg_check(args, "pause", 1)
dom = args[0]
- from xen.xend.XendClient import server
- server.xend_domain_pause(dom)
+ server.xend.domain.pause(dom)
def xm_unpause(args):
arg_check(args, "unpause", 1)
dom = args[0]
- from xen.xend.XendClient import server
- server.xend_domain_unpause(dom)
+ server.xend.domain.unpause(dom)
def xm_rename(args):
arg_check(args, "rename", 2)
- from xen.xend.XendClient import server
- server.xend_domain_rename(args[0], args[1])
+ server.xend.domain.setName(args[0], args[1])
def xm_subcommand(command, args):
cmd = __import__(command, globals(), locals(), 'xen.xm')
@@ -574,8 +567,7 @@ def xm_vcpu_pin(args):
vcpu = int(args[1])
cpumap = cpu_make_map(args[2])
- from xen.xend.XendClient import server
- server.xend_domain_pincpu(dom, vcpu, cpumap)
+ server.xend.domain.pincpu(dom, vcpu, cpumap)
def xm_mem_max(args):
arg_check(args, "mem-max", 2)
@@ -583,8 +575,7 @@ def xm_mem_max(args):
dom = args[0]
mem = int_unit(args[1], 'm')
- from xen.xend.XendClient import server
- server.xend_domain_maxmem_set(dom, mem)
+ server.xend.domain.maxmem_set(dom, mem)
def xm_mem_set(args):
arg_check(args, "mem-set", 2)
@@ -592,20 +583,17 @@ def xm_mem_set(args):
dom = args[0]
mem_target = int_unit(args[1], 'm')
- from xen.xend.XendClient import server
- server.xend_domain_mem_target_set(dom, mem_target)
+ server.xend.domain.setMemoryTarget(dom, mem_target)
def xm_vcpu_set(args):
arg_check(args, "vcpu-set", 2)
- from xen.xend.XendClient import server
- server.xend_domain_set_vcpus(args[0], int(args[1]))
+ server.xend.domain.setVCpuCount(args[0], int(args[1]))
def xm_destroy(args):
arg_check(args, "destroy", 1)
- from xen.xend.XendClient import server
- server.xend_domain_destroy(args[0])
+ server.xend.domain.destroy(args[0])
def xm_domid(args):
@@ -613,8 +601,7 @@ def xm_domid(args):
name = args[0]
- from xen.xend.XendClient import server
- dom = server.xend_domain(name)
+ dom = server.xend.domain(name)
print sxp.child_value(dom, 'domid')
def xm_domname(args):
@@ -622,23 +609,20 @@ def xm_domname(args):
name = args[0]
- from xen.xend.XendClient import server
- dom = server.xend_domain(name)
+ dom = server.xend.domain(name)
print sxp.child_value(dom, 'name')
def xm_sched_bvt(args):
arg_check(args, "sched-bvt", 6)
dom = args[0]
v = map(long, args[1:6])
- from xen.xend.XendClient import server
- server.xend_domain_cpu_bvt_set(dom, *v)
+ server.xend.domain.cpu_bvt_set(dom, *v)
def xm_sched_bvt_ctxallow(args):
arg_check(args, "sched-bvt-ctxallow", 1)
slice = int(args[0])
- from xen.xend.XendClient import server
- server.xend_node_cpu_bvt_slice_set(slice)
+ server.xend.node.cpu_bvt_slice_set(slice)
def xm_sched_sedf(args):
def ns_to_ms(val):
@@ -695,13 +679,12 @@ def xm_sched_sedf(args):
'Slice(ms)', 'Lat(ms)',
'Extra','Weight')
- from xen.xend.XendClient import server
doms = filter(lambda x : domid_match(domid, x),
[parse_doms_info(dom) for dom in getDomains("")])
for d in doms:
# fetch current values so as not to clobber them
sedf_info = \
- parse_sedf_info(server.xend_domain_cpu_sedf_get(d['dom']))
+ parse_sedf_info(server.xend.domain.cpu_sedf_get(d['dom']))
sedf_info['name'] = d['name']
# update values in case of call to set
@@ -713,7 +696,7 @@ def xm_sched_sedf(args):
v = map(int, [sedf_info['period'], sedf_info['slice'],
sedf_info['latency'],sedf_info['extratime'],
sedf_info['weight']])
- rv = server.xend_domain_cpu_sedf_set(d['dom'], *v)
+ rv = server.xend.domain.cpu_sedf_set(d['dom'], *v)
if int(rv) != 0:
err("Failed to set sedf parameters (rv=%d)."%(rv))
@@ -725,8 +708,7 @@ def xm_info(args):
def xm_info(args):
arg_check(args, "info", 0)
- from xen.xend.XendClient import server
- info = server.xend_node()
+ info = server.xend.node.info()
for x in info[1:]:
if len(x) < 2:
@@ -738,8 +720,7 @@ def xm_console(args):
arg_check(args, "console", 1)
dom = args[0]
- from xen.xend.XendClient import server
- info = server.xend_domain(dom)
+ info = server.xend.domain(dom)
domid = int(sxp.child_value(info, 'domid', '-1'))
console.execConsole(domid)
@@ -768,17 +749,15 @@ its contents if the [-c|--clear] flag is
if not (1 <= len(myargs) <= 2):
err('Invalid arguments: ' + str(myargs))
- from xen.xend.XendClient import server
if not gopts.vals.clear:
- print server.xend_node_get_dmesg()
- else:
- server.xend_node_clear_dmesg()
+ print server.xend.node.dmesg.info()
+ else:
+ server.xend.node.dmesg.clear()
def xm_log(args):
arg_check(args, "log", 0)
- from xen.xend.XendClient import server
- print server.xend_node_log()
+ print server.xend.node.log()
def parse_dev_info(info):
def get_info(n, t, d):
@@ -826,13 +805,12 @@ def xm_network_list(args):
print 'No domain parameter given'
sys.exit(1)
dom = params[0]
- from xen.xend.XendClient import server
if use_long:
- devs = server.xend_domain_devices(dom, 'vif')
+ devs = server.xend.domain.getDeviceSxprs(dom, 'vif')
map(PrettyPrint.prettyprint, devs)
else:
hdr = 0
- for x in server.xend_domain_devices(dom, 'vif'):
+ for x in server.xend.domain.getDeviceSxprs(dom, 'vif'):
if hdr == 0:
print 'Idx BE MAC Addr. handle state evt-ch
tx-/rx-ring-ref BE-path'
hdr = 1
@@ -857,13 +835,12 @@ def xm_block_list(args):
print 'No domain parameter given'
sys.exit(1)
dom = params[0]
- from xen.xend.XendClient import server
if use_long:
- devs = server.xend_domain_devices(dom, 'vbd')
+ devs = server.xend.domain.getDeviceSxprs(dom, 'vbd')
map(PrettyPrint.prettyprint, devs)
else:
hdr = 0
- for x in server.xend_domain_devices(dom, 'vbd'):
+ for x in server.xend.domain.getDeviceSxprs(dom, 'vbd'):
if hdr == 0:
print 'Vdev BE handle state evt-ch ring-ref BE-path'
hdr = 1
@@ -887,13 +864,12 @@ def xm_vtpm_list(args):
print 'No domain parameter given'
sys.exit(1)
dom = params[0]
- from xen.xend.XendClient import server
if use_long:
- devs = server.xend_domain_devices(dom, 'vtpm')
+ devs = server.xend.domain.getDeviceSxprs(dom, 'vtpm')
map(PrettyPrint.prettyprint, devs)
else:
hdr = 0
- for x in server.xend_domain_devices(dom, 'vtpm'):
+ for x in server.xend.domain.getDeviceSxprs(dom, 'vtpm'):
if hdr == 0:
print 'Idx BE handle state evt-ch ring-ref BE-path'
hdr = 1
@@ -919,8 +895,7 @@ def xm_block_attach(args):
if len(args) == 5:
vbd.append(['backend', args[4]])
- from xen.xend.XendClient import server
- server.xend_domain_device_create(dom, vbd)
+ server.xend.domain.device_create(dom, vbd)
def xm_network_attach(args):
@@ -932,8 +907,7 @@ def xm_network_attach(args):
for a in args[1:]:
vif.append(a.split("="))
- from xen.xend.XendClient import server
- server.xend_domain_device_create(dom, vif)
+ server.xend.domain.device_create(dom, vif)
def detach(args, command, deviceClass):
@@ -942,8 +916,7 @@ def detach(args, command, deviceClass):
dom = args[0]
dev = args[1]
- from xen.xend.XendClient import server
- server.xend_domain_device_destroy(dom, deviceClass, dev)
+ server.xend.domain.destroyDevice(dom, deviceClass, dev)
def xm_block_detach(args):
@@ -955,7 +928,6 @@ def xm_network_detach(args):
def xm_vnet_list(args):
- from xen.xend.XendClient import server
try:
(options, params) = getopt.gnu_getopt(args, 'l', ['long'])
except getopt.GetoptError, opterr:
@@ -990,13 +962,11 @@ def xm_vnet_create(args):
print "File not found: %s" % conf
sys.exit(1)
- from xen.xend.XendClient import server
server.xend_vnet_create(conf)
def xm_vnet_delete(args):
arg_check(args, "vnet-delete", 1)
vnet = args[0]
- from xen.xend.XendClient import server
server.xend_vnet_delete(vnet)
commands = {
@@ -1132,23 +1102,13 @@ def main(argv=sys.argv):
else:
err("Error connecting to xend: %s." % ex[1])
sys.exit(1)
- except xen.xend.XendError.XendError, ex:
- if len(args) > 0:
- handle_xend_error(argv[1], args, ex)
+ except SystemExit:
+ sys.exit(1)
+ except xmlrpclib.Fault, ex:
+ if ex.faultCode == xen.xend.XendClient.ERROR_INVALID_DOMAIN:
+ print "Error: the domain '%s' does not exist." % ex.faultString
else:
- print "Unexpected error:", sys.exc_info()[0]
- print
- print "Please report to xen-devel@xxxxxxxxxxxxxxxxxxx"
- raise
- except xen.xend.XendProtocol.XendError, ex:
- if len(args) > 0:
- handle_xend_error(argv[1], args, ex)
- else:
- print "Unexpected error:", sys.exc_info()[0]
- print
- print "Please report to xen-devel@xxxxxxxxxxxxxxxxxxx"
- raise
- except SystemExit:
+ print "Error: %s" % ex.faultString
sys.exit(1)
except:
print "Unexpected error:", sys.exc_info()[0]
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/xm/migrate.py
--- a/tools/python/xen/xm/migrate.py Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/python/xen/xm/migrate.py Tue Mar 28 08:54:58 2006 -0700
@@ -60,4 +60,4 @@ def main(argv):
opts.err('Invalid arguments: ' + str(args))
dom = args[0]
dst = args[1]
- server.xend_domain_migrate(dom, dst, opts.vals.live, opts.vals.resource,
opts.vals.port)
+ server.xend.domain.migrate(dom, dst, opts.vals.live, opts.vals.resource,
opts.vals.port)
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/xm/shutdown.py
--- a/tools/python/xen/xm/shutdown.py Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/python/xen/xm/shutdown.py Tue Mar 28 08:54:58 2006 -0700
@@ -53,8 +53,8 @@ gopts.opt('reboot', short='R',
use='Shutdown and reboot.')
def shutdown(opts, doms, mode, wait):
- if doms == None: doms = server.xend_domains()
- dom0_name = sxp.child_value(server.xend_domain(0), 'name')
+ if doms == None: doms = server.xend.domains(0)
+ dom0_name = sxp.child_value(server.xend.domain(0), 'name')
for x in [dom0_name, DOM0_ID]:
if x in doms:
if opts.vals.all:
@@ -62,10 +62,10 @@ def shutdown(opts, doms, mode, wait):
else:
opts.err("Can't specify Domain-0")
for d in doms:
- server.xend_domain_shutdown(d, mode)
+ server.xend.domain.shutdown(d, mode)
if wait:
while doms:
- alive = server.xend_domains()
+ alive = server.xend.domains(0)
dead = []
for d in doms:
if d in alive: continue
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/xm/sysrq.py
--- a/tools/python/xen/xm/sysrq.py Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/python/xen/xm/sysrq.py Tue Mar 28 08:54:58 2006 -0700
@@ -28,4 +28,4 @@ def main(argv):
if len(args) < 2: opts.err('Missing sysrq character')
dom = args[0]
req = ord(args[1][0])
- server.xend_domain_sysrq(dom, req)
+ server.xend.domain.send_sysrq(dom, req)
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/xenstore/talloc.c
--- a/tools/xenstore/talloc.c Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/xenstore/talloc.c Tue Mar 28 08:54:58 2006 -0700
@@ -1,4 +1,4 @@
-/*
+/*
Samba Unix SMB/CIFS implementation.
Samba trivial allocation library - new interface
@@ -6,26 +6,29 @@
NOTE: Please read talloc_guide.txt for full documentation
Copyright (C) Andrew Tridgell 2004
-
- 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,
+
+ ** NOTE! The following LGPL license applies to the talloc
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
+
+ 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 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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ 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
*/
/*
inspired by http://swapped.cc/halloc/
*/
-
#ifdef _SAMBA_BUILD_
#include "includes.h"
@@ -52,15 +55,13 @@
/* use this to force every realloc to change the pointer, to stress test
code that might not cope */
-#ifdef TESTING
-#define ALWAYS_REALLOC 1
-void *test_malloc(size_t size);
-#define malloc test_malloc
-#endif
+#define ALWAYS_REALLOC 0
+
#define MAX_TALLOC_SIZE 0x10000000
-#define TALLOC_MAGIC 0xe814ec4f
-#define TALLOC_MAGIC_FREE 0x7faebef3
+#define TALLOC_MAGIC 0xe814ec70
+#define TALLOC_FLAG_FREE 0x01
+#define TALLOC_FLAG_LOOP 0x02
#define TALLOC_MAGIC_REFERENCE ((const char *)1)
/* by default we abort when given a bad pointer (such as when talloc_free() is
called
@@ -83,8 +84,7 @@ void *test_malloc(size_t size);
*/
static const void *null_context;
static void *cleanup_context;
-static int (*malloc_fail_handler)(void *);
-static void *malloc_fail_data;
+
struct talloc_reference_handle {
struct talloc_reference_handle *next, *prev;
@@ -97,24 +97,27 @@ struct talloc_chunk {
struct talloc_chunk *next, *prev;
struct talloc_chunk *parent, *child;
struct talloc_reference_handle *refs;
- size_t size;
- unsigned magic;
talloc_destructor_t destructor;
const char *name;
+ size_t size;
+ unsigned flags;
};
+
+/* 16 byte alignment seems to keep everyone happy */
+#define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
+#define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
/* panic if we get a bad magic value */
static struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
{
- struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, ptr)-1;
- if (tc->magic != TALLOC_MAGIC) {
- if (tc->magic == TALLOC_MAGIC_FREE) {
- TALLOC_ABORT("Bad talloc magic value - double free");
- } else {
- TALLOC_ABORT("Bad talloc magic value - unknown value");
- }
- }
-
+ const char *pp = ptr;
+ struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp -
TC_HDR_SIZE);
+ if ((tc->flags & ~0xF) != TALLOC_MAGIC) {
+ TALLOC_ABORT("Bad talloc magic value - unknown value");
+ }
+ if (tc->flags & TALLOC_FLAG_FREE) {
+ TALLOC_ABORT("Bad talloc magic value - double free");
+ }
return tc;
}
@@ -159,7 +162,7 @@ void *talloc_parent(const void *ptr)
void *talloc_parent(const void *ptr)
{
struct talloc_chunk *tc = talloc_parent_chunk(ptr);
- return (void *)(tc+1);
+ return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
}
/*
@@ -177,17 +180,11 @@ void *_talloc(const void *context, size_
return NULL;
}
- tc = malloc(sizeof(*tc)+size);
- if (tc == NULL) {
- if (malloc_fail_handler)
- if (malloc_fail_handler(malloc_fail_data))
- tc = malloc(sizeof(*tc)+size);
- if (!tc)
- return NULL;
- }
+ tc = malloc(TC_HDR_SIZE+size);
+ if (tc == NULL) return NULL;
tc->size = size;
- tc->magic = TALLOC_MAGIC;
+ tc->flags = TALLOC_MAGIC;
tc->destructor = NULL;
tc->child = NULL;
tc->name = NULL;
@@ -207,7 +204,7 @@ void *_talloc(const void *context, size_
tc->next = tc->prev = tc->parent = NULL;
}
- return (void *)(tc+1);
+ return TC_PTR_FROM_CHUNK(tc);
}
@@ -292,7 +289,11 @@ static int talloc_unreference(const void
for (h=tc->refs;h;h=h->next) {
struct talloc_chunk *p = talloc_parent_chunk(h);
- if ((p==NULL && context==NULL) || p+1 == context) break;
+ if (p == NULL) {
+ if (context == NULL) break;
+ } else if (TC_PTR_FROM_CHUNK(p) == context) {
+ break;
+ }
}
if (h == NULL) {
return -1;
@@ -343,7 +344,7 @@ int talloc_unlink(const void *context, v
new_p = talloc_parent_chunk(tc_p->refs);
if (new_p) {
- new_parent = new_p+1;
+ new_parent = TC_PTR_FROM_CHUNK(new_p);
} else {
new_parent = NULL;
}
@@ -470,6 +471,8 @@ void *talloc_init(const char *fmt, ...)
{
va_list ap;
void *ptr;
+
+ talloc_enable_null_tracking();
ptr = _talloc(NULL, 0);
if (ptr == NULL) return NULL;
@@ -502,16 +505,16 @@ void talloc_free_children(void *ptr)
choice is owner of any remaining reference to this
pointer, the second choice is our parent, and the
final choice is the null context. */
- void *child = tc->child+1;
+ void *child = TC_PTR_FROM_CHUNK(tc->child);
const void *new_parent = null_context;
if (tc->child->refs) {
struct talloc_chunk *p =
talloc_parent_chunk(tc->child->refs);
- if (p) new_parent = p+1;
+ if (p) new_parent = TC_PTR_FROM_CHUNK(p);
}
if (talloc_free(child) == -1) {
if (new_parent == null_context) {
struct talloc_chunk *p =
talloc_parent_chunk(ptr);
- if (p) new_parent = p+1;
+ if (p) new_parent = TC_PTR_FROM_CHUNK(p);
}
talloc_steal(new_parent, child);
}
@@ -539,6 +542,11 @@ int talloc_free(void *ptr)
if (tc->refs) {
talloc_reference_destructor(tc->refs);
return -1;
+ }
+
+ if (tc->flags & TALLOC_FLAG_LOOP) {
+ /* we have a free loop - stop looping */
+ return 0;
}
if (tc->destructor) {
@@ -554,6 +562,8 @@ int talloc_free(void *ptr)
tc->destructor = NULL;
}
+ tc->flags |= TALLOC_FLAG_LOOP;
+
talloc_free_children(ptr);
if (tc->parent) {
@@ -566,7 +576,7 @@ int talloc_free(void *ptr)
if (tc->next) tc->next->prev = tc->prev;
}
- tc->magic = TALLOC_MAGIC_FREE;
+ tc->flags |= TALLOC_FLAG_FREE;
free(tc);
return 0;
@@ -606,36 +616,24 @@ void *_talloc_realloc(const void *contex
}
/* by resetting magic we catch users of the old memory */
- tc->magic = TALLOC_MAGIC_FREE;
+ tc->flags |= TALLOC_FLAG_FREE;
#if ALWAYS_REALLOC
- new_ptr = malloc(size + sizeof(*tc));
- if (!new_ptr) {
- tc->magic = TALLOC_MAGIC;
- if (malloc_fail_handler)
- if (malloc_fail_handler(malloc_fail_data))
- new_ptr = malloc(size + sizeof(*tc));
- }
+ new_ptr = malloc(size + TC_HDR_SIZE);
if (new_ptr) {
- memcpy(new_ptr, tc, tc->size + sizeof(*tc));
+ memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
free(tc);
}
#else
- new_ptr = realloc(tc, size + sizeof(*tc));
- if (!new_ptr) {
- tc->magic = TALLOC_MAGIC;
- if (malloc_fail_handler)
- if (malloc_fail_handler(malloc_fail_data))
- new_ptr = realloc(tc, size + sizeof(*tc));
- }
+ new_ptr = realloc(tc, size + TC_HDR_SIZE);
#endif
if (!new_ptr) {
- tc->magic = TALLOC_MAGIC;
+ tc->flags &= ~TALLOC_FLAG_FREE;
return NULL;
}
tc = new_ptr;
- tc->magic = TALLOC_MAGIC;
+ tc->flags &= ~TALLOC_FLAG_FREE;
if (tc->parent) {
tc->parent->child = new_ptr;
}
@@ -651,9 +649,9 @@ void *_talloc_realloc(const void *contex
}
tc->size = size;
- talloc_set_name_const(tc+1, name);
-
- return (void *)(tc+1);
+ talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
+
+ return TC_PTR_FROM_CHUNK(tc);
}
/*
@@ -730,10 +728,19 @@ off_t talloc_total_size(const void *ptr)
tc = talloc_chunk_from_ptr(ptr);
+ if (tc->flags & TALLOC_FLAG_LOOP) {
+ return 0;
+ }
+
+ tc->flags |= TALLOC_FLAG_LOOP;
+
total = tc->size;
for (c=tc->child;c;c=c->next) {
- total += talloc_total_size(c+1);
- }
+ total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
+ }
+
+ tc->flags &= ~TALLOC_FLAG_LOOP;
+
return total;
}
@@ -743,20 +750,21 @@ off_t talloc_total_blocks(const void *pt
off_t talloc_total_blocks(const void *ptr)
{
off_t total = 0;
- struct talloc_chunk *c, *tc;
-
- if (ptr == NULL) {
- ptr = null_context;
- }
- if (ptr == NULL) {
+ struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
+
+ if (tc->flags & TALLOC_FLAG_LOOP) {
return 0;
}
- tc = talloc_chunk_from_ptr(ptr);
+
+ tc->flags |= TALLOC_FLAG_LOOP;
total++;
for (c=tc->child;c;c=c->next) {
- total += talloc_total_blocks(c+1);
- }
+ total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
+ }
+
+ tc->flags &= ~TALLOC_FLAG_LOOP;
+
return total;
}
@@ -782,23 +790,29 @@ void talloc_report_depth(const void *ptr
{
struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
+ if (tc->flags & TALLOC_FLAG_LOOP) {
+ return;
+ }
+
+ tc->flags |= TALLOC_FLAG_LOOP;
+
for (c=tc->child;c;c=c->next) {
if (c->name == TALLOC_MAGIC_REFERENCE) {
- struct talloc_reference_handle *handle = (void *)(c+1);
+ struct talloc_reference_handle *handle =
TC_PTR_FROM_CHUNK(c);
const char *name2 = talloc_get_name(handle->ptr);
fprintf(f, "%*sreference to: %s\n", depth*4, "", name2);
} else {
- const char *name = talloc_get_name(c+1);
+ const char *name =
talloc_get_name(TC_PTR_FROM_CHUNK(c));
fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks
(ref %d)\n",
depth*4, "",
name,
- (unsigned long)talloc_total_size(c+1),
- (unsigned long)talloc_total_blocks(c+1),
- talloc_reference_count(c+1));
- talloc_report_depth(c+1, f, depth+1);
- }
- }
-
+ (unsigned
long)talloc_total_size(TC_PTR_FROM_CHUNK(c)),
+ (unsigned
long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)),
+ talloc_reference_count(TC_PTR_FROM_CHUNK(c)));
+ talloc_report_depth(TC_PTR_FROM_CHUNK(c), f, depth+1);
+ }
+ }
+ tc->flags &= ~TALLOC_FLAG_LOOP;
}
/*
@@ -841,9 +855,9 @@ void talloc_report(const void *ptr, FILE
for (c=tc->child;c;c=c->next) {
fprintf(f, "\t%-30s contains %6lu bytes in %3lu blocks\n",
- talloc_get_name(c+1),
- (unsigned long)talloc_total_size(c+1),
- (unsigned long)talloc_total_blocks(c+1));
+ talloc_get_name(TC_PTR_FROM_CHUNK(c)),
+ (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c)),
+ (unsigned
long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)));
}
fflush(f);
}
@@ -877,6 +891,74 @@ void talloc_enable_null_tracking(void)
null_context = talloc_named_const(NULL, 0, "null_context");
}
}
+
+#ifdef _SAMBA_BUILD_
+/* Ugly calls to Samba-specific sprintf_append... JRA. */
+
+/*
+ report on memory usage by all children of a pointer, giving a full tree view
+*/
+static void talloc_report_depth_str(const void *ptr, char **pps, ssize_t
*plen, size_t *pbuflen, int depth)
+{
+ struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
+
+ if (tc->flags & TALLOC_FLAG_LOOP) {
+ return;
+ }
+
+ tc->flags |= TALLOC_FLAG_LOOP;
+
+ for (c=tc->child;c;c=c->next) {
+ if (c->name == TALLOC_MAGIC_REFERENCE) {
+ struct talloc_reference_handle *handle =
TC_PTR_FROM_CHUNK(c);
+ const char *name2 = talloc_get_name(handle->ptr);
+
+ sprintf_append(NULL, pps, plen, pbuflen,
+ "%*sreference to: %s\n", depth*4, "", name2);
+
+ } else {
+ const char *name =
talloc_get_name(TC_PTR_FROM_CHUNK(c));
+
+ sprintf_append(NULL, pps, plen, pbuflen,
+ "%*s%-30s contains %6lu bytes in %3lu blocks
(ref %d)\n",
+ depth*4, "",
+ name,
+ (unsigned
long)talloc_total_size(TC_PTR_FROM_CHUNK(c)),
+ (unsigned
long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)),
+ talloc_reference_count(TC_PTR_FROM_CHUNK(c)));
+
+ talloc_report_depth_str(TC_PTR_FROM_CHUNK(c), pps,
plen, pbuflen, depth+1);
+ }
+ }
+ tc->flags &= ~TALLOC_FLAG_LOOP;
+}
+
+/*
+ report on memory usage by all children of a pointer
+*/
+char *talloc_describe_all(void)
+{
+ ssize_t len = 0;
+ size_t buflen = 512;
+ char *s = NULL;
+
+ if (null_context == NULL) {
+ return NULL;
+ }
+
+ sprintf_append(NULL, &s, &len, &buflen,
+ "full talloc report on '%s' (total %lu bytes in %lu blocks)\n",
+ talloc_get_name(null_context),
+ (unsigned long)talloc_total_size(null_context),
+ (unsigned long)talloc_total_blocks(null_context));
+
+ if (!s) {
+ return NULL;
+ }
+ talloc_report_depth_str(null_context, &s, &len, &buflen, 1);
+ return s;
+}
+#endif
/*
enable leak reporting on exit
@@ -942,6 +1024,30 @@ char *talloc_strdup(const void *t, const
}
/*
+ append to a talloced string
+*/
+char *talloc_append_string(const void *t, char *orig, const char *append)
+{
+ char *ret;
+ size_t olen = strlen(orig);
+ size_t alenz;
+
+ if (!append)
+ return orig;
+
+ alenz = strlen(append) + 1;
+
+ ret = talloc_realloc(t, orig, char, olen + alenz);
+ if (!ret)
+ return NULL;
+
+ /* append the string with the trailing \0 */
+ memcpy(&ret[olen], append, alenz);
+
+ return ret;
+}
+
+/*
strndup with a talloc
*/
char *talloc_strndup(const void *t, const char *p, size_t n)
@@ -949,7 +1055,7 @@ char *talloc_strndup(const void *t, cons
size_t len;
char *ret;
- for (len=0; p[len] && len<n; len++) ;
+ for (len=0; len<n && p[len]; len++) ;
ret = _talloc(t, len + 1);
if (!ret) { return NULL; }
@@ -974,10 +1080,14 @@ char *talloc_vasprintf(const void *t, co
int len;
char *ret;
va_list ap2;
+ char c;
VA_COPY(ap2, ap);
- len = vsnprintf(NULL, 0, fmt, ap2);
+ /* this call looks strange, but it makes it work on older solaris boxes
*/
+ if ((len = vsnprintf(&c, 1, fmt, ap2)) < 0) {
+ return NULL;
+ }
ret = _talloc(t, len+1);
if (ret) {
@@ -1029,7 +1139,15 @@ static char *talloc_vasprintf_append(cha
VA_COPY(ap2, ap);
s_len = tc->size - 1;
- len = vsnprintf(NULL, 0, fmt, ap2);
+ if ((len = vsnprintf(NULL, 0, fmt, ap2)) <= 0) {
+ /* Either the vsnprintf failed or the format resulted in
+ * no characters being formatted. In the former case, we
+ * ought to return NULL, in the latter we ought to return
+ * the original string. Most current callers of this
+ * function expect it to never return NULL.
+ */
+ return s;
+ }
s = talloc_realloc(NULL, s, char, s_len + len+1);
if (!s) return NULL;
@@ -1133,11 +1251,45 @@ size_t talloc_get_size(const void *conte
return tc->size;
}
-talloc_fail_handler *talloc_set_fail_handler(talloc_fail_handler *handler,
- void *data)
-{
- talloc_fail_handler *old = malloc_fail_handler;
- malloc_fail_handler = handler;
- malloc_fail_data = data;
- return old;
-}
+/*
+ find a parent of this context that has the given name, if any
+*/
+void *talloc_find_parent_byname(const void *context, const char *name)
+{
+ struct talloc_chunk *tc;
+
+ if (context == NULL) {
+ return NULL;
+ }
+
+ tc = talloc_chunk_from_ptr(context);
+ while (tc) {
+ if (tc->name && strcmp(tc->name, name) == 0) {
+ return TC_PTR_FROM_CHUNK(tc);
+ }
+ while (tc && tc->prev) tc = tc->prev;
+ tc = tc->parent;
+ }
+ return NULL;
+}
+
+/*
+ show the parentage of a context
+*/
+void talloc_show_parents(const void *context, FILE *file)
+{
+ struct talloc_chunk *tc;
+
+ if (context == NULL) {
+ fprintf(file, "talloc no parents for NULL\n");
+ return;
+ }
+
+ tc = talloc_chunk_from_ptr(context);
+ fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
+ while (tc) {
+ fprintf(file, "\t'%s'\n",
talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
+ while (tc && tc->prev) tc = tc->prev;
+ tc = tc->parent;
+ }
+}
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/xenstore/talloc.h
--- a/tools/xenstore/talloc.h Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/xenstore/talloc.h Tue Mar 28 08:54:58 2006 -0700
@@ -6,19 +6,23 @@
Copyright (C) Andrew Tridgell 2004-2005
- 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.
+ ** NOTE! The following LGPL license applies to the talloc
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
- This program is distributed in the hope that it will be useful,
+ 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 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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ 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
*/
/* this is only needed for compatibility with the old talloc */
@@ -58,12 +62,17 @@ typedef void TALLOC_CTX;
#define malloc_array_p(type, count) (type *)realloc_array(NULL, sizeof(type),
count)
#define realloc_p(p, type, count) (type *)realloc_array(p, sizeof(type), count)
+#if 0
+/* Not correct for Samba3. */
#define data_blob(ptr, size) data_blob_named(ptr, size, "DATA_BLOB:
"__location__)
#define data_blob_talloc(ctx, ptr, size) data_blob_talloc_named(ctx, ptr,
size, "DATA_BLOB: "__location__)
#define data_blob_dup_talloc(ctx, blob) data_blob_talloc_named(ctx,
(blob)->data, (blob)->length, "DATA_BLOB: "__location__)
+#endif
#define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type)
#define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type)
+
+#define talloc_find_parent_bytype(ptr, type) (type
*)talloc_find_parent_byname(ptr, #type)
#if TALLOC_DEPRECATED
@@ -117,6 +126,7 @@ void *_talloc_memdup(const void *t, cons
void *_talloc_memdup(const void *t, const void *p, size_t size, const char
*name);
char *talloc_strdup(const void *t, const char *p);
char *talloc_strndup(const void *t, const char *p, size_t n);
+char *talloc_append_string(const void *t, char *orig, const char *append);
char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
PRINTF_ATTRIBUTE(2,0);
char *talloc_asprintf(const void *t, const char *fmt, ...)
PRINTF_ATTRIBUTE(2,3);
char *talloc_asprintf_append(char *s,
@@ -127,8 +137,8 @@ void *talloc_realloc_fn(const void *cont
void *talloc_realloc_fn(const void *context, void *ptr, size_t size);
void *talloc_autofree_context(void);
size_t talloc_get_size(const void *ctx);
+void *talloc_find_parent_byname(const void *ctx, const char *name);
+void talloc_show_parents(const void *context, FILE *file);
-typedef int talloc_fail_handler(void *);
-talloc_fail_handler *talloc_set_fail_handler(talloc_fail_handler *, void *);
#endif
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/xenstore/xenstored_core.c Tue Mar 28 08:54:58 2006 -0700
@@ -1231,39 +1231,17 @@ static void process_message(struct conne
conn->transaction = NULL;
}
-static int out_of_mem(void *data)
-{
- longjmp(*(jmp_buf *)data, 1);
-}
-
static void consider_message(struct connection *conn)
{
- jmp_buf talloc_fail;
-
if (verbose)
xprintf("Got message %s len %i from %p\n",
sockmsg_string(conn->in->hdr.msg.type),
conn->in->hdr.msg.len, conn);
- /* For simplicity, we kill the connection on OOM. */
- talloc_set_fail_handler(out_of_mem, &talloc_fail);
- if (setjmp(talloc_fail)) {
- talloc_free(conn);
- goto end;
- }
-
process_message(conn, conn->in);
talloc_free(conn->in);
conn->in = new_buffer(conn);
-
-end:
- talloc_set_fail_handler(NULL, NULL);
- if (talloc_total_blocks(NULL)
- != talloc_total_blocks(talloc_autofree_context()) + 1) {
- talloc_report_full(NULL, stderr);
- abort();
- }
}
/* Errors in reading or allocating here mean we get out of sync, so we
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/xentrace/Makefile
--- a/tools/xentrace/Makefile Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/xentrace/Makefile Tue Mar 28 08:54:58 2006 -0700
@@ -6,7 +6,7 @@ XEN_ROOT=../..
XEN_ROOT=../..
include $(XEN_ROOT)/tools/Rules.mk
-CFLAGS += -Werror
+CFLAGS += -Werror -D_LARGEFILE64_SOURCE
CFLAGS += -I $(XEN_XC)
CFLAGS += -I $(XEN_LIBXC)
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/xentrace/formats
--- a/tools/xentrace/formats Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/xentrace/formats Tue Mar 28 08:54:58 2006 -0700
@@ -16,6 +16,6 @@ 0x00080002 CPU%(cpu)d %(tsc)d VMX_
0x00080002 CPU%(cpu)d %(tsc)d VMX_VECTOR [ domid
= 0x%(1)08x, eip = 0x%(2)08x, vector = 0x%(3)08x ]
0x00080003 CPU%(cpu)d %(tsc)d VMX_INT [ domid
= 0x%(1)08x, trap = 0x%(2)08x, va = 0x%(3)08x ]
-0x00090001 CPU%(cpu)d %(tsc)d VMENTRY
0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x
-0x00090002 CPU%(cpu)d %(tsc)d VMEXIT
0x%(1)08x 0x%(2)08x 0x%(3)08x
+0x00081001 CPU%(cpu)d %(tsc)d VMEXIT
0x%(1)08x 0x%(2)08x 0x%(3)08x
+0x00081002 CPU%(cpu)d %(tsc)d VMENTRY
0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/xentrace/xentrace.c
--- a/tools/xentrace/xentrace.c Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/xentrace/xentrace.c Tue Mar 28 08:54:58 2006 -0700
@@ -498,7 +498,7 @@ int main(int argc, char **argv)
}
if ( opts.outfile )
- outfd = open(opts.outfile, O_WRONLY | O_CREAT);
+ outfd = open(opts.outfile, O_WRONLY | O_CREAT | O_LARGEFILE, 0644);
if(outfd < 0)
{
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/xm-test/lib/XmTestLib/Test.py
--- a/tools/xm-test/lib/XmTestLib/Test.py Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/xm-test/lib/XmTestLib/Test.py Tue Mar 28 08:54:58 2006 -0700
@@ -131,12 +131,12 @@ def becomeNonRoot():
if os.geteuid() == 0:
FAIL("Could not become a non-root user")
-def FAIL(reason):
- print "\nREASON: %s" % reason
+def FAIL(format, *args):
+ print "\nREASON:", (format % args)
sys.exit(TEST_FAIL)
-def SKIP(reason):
- print "\nREASON: %s" % reason
+def SKIP(format, *args):
+ print "\nREASON:", (format % args)
sys.exit(TEST_SKIP)
def saveLog(logText, filename=None):
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/xm-test/ramdisk/Makefile.am
--- a/tools/xm-test/ramdisk/Makefile.am Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/xm-test/ramdisk/Makefile.am Tue Mar 28 08:54:58 2006 -0700
@@ -1,3 +1,4 @@
+INITRD ?= http://xm-test.xensource.com/ramdisks
EXTRA_DIST = skel configs patches
@@ -60,7 +61,7 @@ disk.img: existing
fi
existing:
- @if test -n "$(INITRD)"; then \
+ @if [ -n "$(INITRD)" ] && [ ! -f $(XMTEST_VER_IMG) ] ; then \
wget $(INITRD)/$(XMTEST_VER_IMG); \
fi
@if [ -f $(XMTEST_VER_IMG) ] ; then \
diff -r 7e3cbc409676 -r d75a6cc5e68a
tools/xm-test/tests/block-create/Makefile.am
--- a/tools/xm-test/tests/block-create/Makefile.am Mon Mar 27 15:36:47
2006 -0700
+++ b/tools/xm-test/tests/block-create/Makefile.am Tue Mar 28 08:54:58
2006 -0700
@@ -12,7 +12,7 @@ TESTS = 01_block_attach_device_pos.test
11_block_attach_shared_dom0.test \
12_block_attach_shared_domU.test
-EXTRA_DIST = $(TESTS) $(XFAIL_TESTS)
+EXTRA_DIST = $(TESTS)
TESTS_ENVIRONMENT=@TENV@
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/xm-test/tests/create/Makefile.am
--- a/tools/xm-test/tests/create/Makefile.am Mon Mar 27 15:36:47 2006 -0700
+++ b/tools/xm-test/tests/create/Makefile.am Tue Mar 28 08:54:58 2006 -0700
@@ -15,7 +15,7 @@ TESTS = 01_create_basic_pos.test \
14_create_blockroot_pos.test \
15_create_smallmem_pos.test
-EXTRA_DIST = $(TESTS) $(XFAIL_TESTS)
+EXTRA_DIST = $(TESTS)
TESTS_ENVIRONMENT=@TENV@
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/dom0_ops.c
--- a/xen/arch/x86/dom0_ops.c Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/dom0_ops.c Tue Mar 28 08:54:58 2006 -0700
@@ -460,8 +460,7 @@ void arch_getdomaininfo_ctxt(
if ( hvm_guest(v) )
{
- hvm_store_cpu_guest_regs(v, &c->user_regs);
- hvm_store_cpu_guest_ctrl_regs(v, c->ctrlreg);
+ hvm_store_cpu_guest_regs(v, &c->user_regs, c->ctrlreg);
}
else
{
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/hvm/platform.c Tue Mar 28 08:54:58 2006 -0700
@@ -773,7 +773,7 @@ void handle_mmio(unsigned long va, unsig
mmio_opp = &v->arch.hvm_vcpu.mmio_op;
regs = mmio_opp->inst_decoder_regs;
- hvm_store_cpu_guest_regs(v, regs);
+ hvm_store_cpu_guest_regs(v, regs, NULL);
if ((inst_len = hvm_instruction_length(v)) <= 0) {
printf("handle_mmio: failed to get instruction length\n");
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/hvm/svm/intr.c Tue Mar 28 08:54:58 2006 -0700
@@ -44,6 +44,58 @@
*/
#define BSP_CPU(v) (!(v->vcpu_id))
+u64 svm_get_guest_time(struct vcpu *v)
+{
+ struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
+ u64 host_tsc;
+
+ rdtscll(host_tsc);
+ return host_tsc + vpit->cache_tsc_offset;
+}
+
+void svm_set_guest_time(struct vcpu *v, u64 gtime)
+{
+ struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
+ u64 host_tsc;
+
+ rdtscll(host_tsc);
+
+ vpit->cache_tsc_offset = gtime - host_tsc;
+ v->arch.hvm_svm.vmcb->tsc_offset = vpit->cache_tsc_offset;
+}
+
+static inline void
+interrupt_post_injection(struct vcpu * v, int vector, int type)
+{
+ struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
+
+ if ( is_pit_irq(v, vector, type) ) {
+ if ( !vpit->first_injected ) {
+ vpit->pending_intr_nr = 0;
+ vpit->last_pit_gtime = svm_get_guest_time(v);
+ vpit->scheduled = NOW() + vpit->period;
+ set_timer(&vpit->pit_timer, vpit->scheduled);
+ vpit->first_injected = 1;
+ } else {
+ vpit->pending_intr_nr--;
+ }
+ vpit->inject_point = NOW();
+
+ vpit->last_pit_gtime += vpit->period;
+ svm_set_guest_time(v, vpit->last_pit_gtime);
+ }
+
+ switch(type)
+ {
+ case VLAPIC_DELIV_MODE_EXT:
+ break;
+
+ default:
+ vlapic_post_injection(v, vector, type);
+ break;
+ }
+}
+
static inline int svm_inject_extint(struct vcpu *v, int trap, int error_code)
{
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
@@ -62,45 +114,6 @@ static inline int svm_inject_extint(stru
vmcb->vintr = intr;
// printf( "IRQ = %d\n", trap );
return 0;
-}
-
-void svm_set_tsc_shift(struct vcpu *v, struct hvm_virpit *vpit)
-{
- struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
- u64 drift;
-
- if ( vpit->first_injected )
- drift = vpit->period_cycles * vpit->pending_intr_nr;
- else
- drift = 0;
- vmcb->tsc_offset = ( 0 - drift );
-}
-
-static inline void
-interrupt_post_injection(struct vcpu * v, int vector, int type)
-{
- struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
-
- if ( is_pit_irq(v, vector, type) ) {
- if ( !vpit->first_injected ) {
- vpit->first_injected = 1;
- vpit->pending_intr_nr = 0;
- }
- else if (vpit->pending_intr_nr) {
- --vpit->pending_intr_nr;
- }
- vpit->inject_point = NOW();
- svm_set_tsc_shift (v, vpit);
- }
-
- switch(type)
- {
- case VLAPIC_DELIV_MODE_EXT:
- break;
-
- default:
- vlapic_post_injection(v, vector, type);
- }
}
asmlinkage void svm_intr_assist(void)
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/hvm/svm/svm.c Tue Mar 28 08:54:58 2006 -0700
@@ -201,31 +201,41 @@ int svm_initialize_guest_resources(struc
}
static void svm_store_cpu_guest_regs(
- struct vcpu *v, struct cpu_user_regs *regs)
+ struct vcpu *v, struct cpu_user_regs *regs, unsigned long *crs)
{
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+ if ( regs != NULL )
+ {
#if defined (__x86_64__)
- regs->rip = vmcb->rip;
- regs->rsp = vmcb->rsp;
- regs->rflags = vmcb->rflags;
- regs->cs = vmcb->cs.sel;
- regs->ds = vmcb->ds.sel;
- regs->es = vmcb->es.sel;
- regs->ss = vmcb->ss.sel;
- regs->gs = vmcb->gs.sel;
- regs->fs = vmcb->fs.sel;
+ regs->rip = vmcb->rip;
+ regs->rsp = vmcb->rsp;
+ regs->rflags = vmcb->rflags;
+ regs->cs = vmcb->cs.sel;
+ regs->ds = vmcb->ds.sel;
+ regs->es = vmcb->es.sel;
+ regs->ss = vmcb->ss.sel;
+ regs->gs = vmcb->gs.sel;
+ regs->fs = vmcb->fs.sel;
#elif defined (__i386__)
- regs->eip = vmcb->rip;
- regs->esp = vmcb->rsp;
- regs->eflags = vmcb->rflags;
- regs->cs = vmcb->cs.sel;
- regs->ds = vmcb->ds.sel;
- regs->es = vmcb->es.sel;
- regs->ss = vmcb->ss.sel;
- regs->gs = vmcb->gs.sel;
- regs->fs = vmcb->fs.sel;
+ regs->eip = vmcb->rip;
+ regs->esp = vmcb->rsp;
+ regs->eflags = vmcb->rflags;
+ regs->cs = vmcb->cs.sel;
+ regs->ds = vmcb->ds.sel;
+ regs->es = vmcb->es.sel;
+ regs->ss = vmcb->ss.sel;
+ regs->gs = vmcb->gs.sel;
+ regs->fs = vmcb->fs.sel;
#endif
+ }
+
+ if ( crs != NULL )
+ {
+ crs[0] = vmcb->cr0;
+ crs[3] = vmcb->cr3;
+ crs[4] = vmcb->cr4;
+ }
}
static void svm_load_cpu_guest_regs(
@@ -372,15 +382,6 @@ static inline int long_mode_do_msr_write
return 1;
}
-void svm_store_cpu_guest_ctrl_regs(struct vcpu *v, unsigned long crs[8])
-{
- struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-
- crs[0] = vmcb->cr0;
- crs[3] = vmcb->cr3;
- crs[4] = vmcb->cr4;
-}
-
void svm_modify_guest_state(struct vcpu *v)
{
svm_modify_vmcb(v, &v->arch.guest_context.user_regs);
@@ -448,7 +449,6 @@ int start_svm(void)
hvm_funcs.store_cpu_guest_regs = svm_store_cpu_guest_regs;
hvm_funcs.load_cpu_guest_regs = svm_load_cpu_guest_regs;
- hvm_funcs.store_cpu_guest_ctrl_regs = svm_store_cpu_guest_ctrl_regs;
hvm_funcs.modify_guest_state = svm_modify_guest_state;
hvm_funcs.realmode = svm_realmode;
@@ -670,8 +670,18 @@ static void arch_svm_do_launch(struct vc
reset_stack_and_jump(svm_asm_do_launch);
}
+static void svm_freeze_time(struct vcpu *v)
+{
+ struct hvm_virpit *vpit = &v->domain->arch.hvm_domain.vpit;
+
+ v->domain->arch.hvm_domain.guest_time = svm_get_guest_time(v);
+ if ( vpit->first_injected )
+ stop_timer(&(vpit->pit_timer));
+}
+
static void svm_ctxt_switch_from(struct vcpu *v)
{
+ svm_freeze_time(v);
}
static void svm_ctxt_switch_to(struct vcpu *v)
@@ -718,6 +728,8 @@ static void svm_relinquish_guest_resourc
for_each_vcpu ( d, v )
{
+ if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+ continue;
#if 0
/* Memory leak by not freeing this. XXXKAF: *Why* is not per core?? */
free_host_save_area(v->arch.hvm_svm.host_save_area);
@@ -911,7 +923,7 @@ static void svm_vmexit_do_cpuid(struct v
if (input == 1)
{
- if ( hvm_apic_support(v->domain) &&
+ if ( !hvm_apic_support(v->domain) ||
!vlapic_global_enabled((VLAPIC(v))) )
clear_bit(X86_FEATURE_APIC, &edx);
@@ -1251,11 +1263,6 @@ static void svm_io_instruction(struct vc
/* Need the original rip, here. */
addr = svm_get_io_address(vmcb, regs, dir, real);
- /*
- * On SVM, the RIP of the intruction following the IN/OUT is saved in
- * ExitInfo2
- */
- vmcb->rip = vmcb->exitinfo2;
/* "rep" prefix */
if (info.fields.rep)
@@ -1288,6 +1295,8 @@ static void svm_io_instruction(struct vc
else
count = (addr & ~PAGE_MASK) / size;
}
+ else
+ vmcb->rip = vmcb->exitinfo2;
send_pio_req(regs, port, count, size, addr, dir, 1);
}
@@ -1693,7 +1702,7 @@ static inline void svm_do_msr_access(str
{
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
int inst_len;
- int64_t tsc_sum;
+ u64 msr_content=0;
ASSERT(vmcb);
@@ -1708,24 +1717,27 @@ static inline void svm_do_msr_access(str
inst_len = __get_instruction_length(vmcb, INSTR_RDMSR, NULL);
regs->edx = 0;
- switch (regs->ecx)
+ switch (regs->ecx) {
+ case MSR_IA32_TIME_STAMP_COUNTER:
{
+ struct hvm_virpit *vpit;
+
+ rdtscll(msr_content);
+ vpit = &(v->domain->arch.hvm_domain.vpit);
+ msr_content += vpit->cache_tsc_offset;
+ break;
+ }
case MSR_IA32_SYSENTER_CS:
- regs->eax = vmcb->sysenter_cs;
+ msr_content = vmcb->sysenter_cs;
break;
case MSR_IA32_SYSENTER_ESP:
- regs->eax = vmcb->sysenter_esp;
+ msr_content = vmcb->sysenter_esp;
break;
case MSR_IA32_SYSENTER_EIP:
- regs->eax = vmcb->sysenter_eip;
+ msr_content = vmcb->sysenter_eip;
break;
- case MSR_IA32_TIME_STAMP_COUNTER:
- __asm__ __volatile__("rdtsc" : "=a" (regs->eax), "=d" (regs->edx));
- tsc_sum = regs->edx;
- tsc_sum = (tsc_sum << 32) + regs->eax;
- tsc_sum += (int64_t) vmcb->tsc_offset;
- regs->eax = tsc_sum & 0xFFFFFFFF;
- regs->edx = (tsc_sum >> 32) & 0xFFFFFFFF;
+ case MSR_IA32_APICBASE:
+ msr_content = VLAPIC(v) ? VLAPIC(v)->apic_base_msr : 0;
break;
default:
if (long_mode_do_msr_read(regs))
@@ -1733,21 +1745,30 @@ static inline void svm_do_msr_access(str
rdmsr_safe(regs->ecx, regs->eax, regs->edx);
break;
}
+ regs->eax = msr_content & 0xFFFFFFFF;
+ regs->edx = msr_content >> 32;
}
else
{
inst_len = __get_instruction_length(vmcb, INSTR_WRMSR, NULL);
+ msr_content = (regs->eax & 0xFFFFFFFF) | ((u64)regs->edx << 32);
switch (regs->ecx)
{
+ case MSR_IA32_TIME_STAMP_COUNTER:
+ svm_set_guest_time(v, msr_content);
+ break;
case MSR_IA32_SYSENTER_CS:
- vmcb->sysenter_cs = regs->eax;
+ vmcb->sysenter_cs = msr_content;
break;
case MSR_IA32_SYSENTER_ESP:
- vmcb->sysenter_esp = regs->eax;
+ vmcb->sysenter_esp = msr_content;
break;
case MSR_IA32_SYSENTER_EIP:
- vmcb->sysenter_eip = regs->eax;
+ vmcb->sysenter_eip = msr_content;
+ break;
+ case MSR_IA32_APICBASE:
+ vlapic_msr_set(VLAPIC(v), msr_content);
break;
default:
long_mode_do_msr_write(regs);
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/hvm/svm/vmcb.c Tue Mar 28 08:54:58 2006 -0700
@@ -123,7 +123,7 @@ static int construct_vmcb_controls(struc
GENERAL1_INTERCEPT_RDTSC | GENERAL1_INTERCEPT_PUSHF |
GENERAL1_INTERCEPT_SWINT | GENERAL1_INTERCEPT_POPF |
GENERAL1_INTERCEPT_IRET | GENERAL1_INTERCEPT_PAUSE |
- GENERAL1_INTERCEPT_TASK_SWITCH | GENERAL1_INTERCEPT_SMI
+ GENERAL1_INTERCEPT_TASK_SWITCH
);
/* turn on the general 2 intercepts */
@@ -467,6 +467,8 @@ void svm_do_launch(struct vcpu *v)
v->arch.hvm_svm.injecting_event = 0;
v->arch.hvm_svm.saved_irq_vector = -1;
+ svm_set_guest_time(v, 0);
+
if (svm_dbg_on)
svm_dump_vmcb(__func__, vmcb);
}
@@ -494,15 +496,16 @@ void svm_do_resume(struct vcpu *v)
struct hvm_virpit *vpit = &d->arch.hvm_domain.vpit;
svm_stts(v);
+
+ /* pick up the elapsed PIT ticks and re-enable pit_timer */
+ if ( vpit->first_injected) {
+ svm_set_guest_time(v, v->domain->arch.hvm_domain.guest_time);
+ pickup_deactive_ticks(vpit);
+ }
if ( test_bit(iopacket_port(v), &d->shared_info->evtchn_pending[0]) ||
test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags) )
hvm_wait_io();
-
- /* pick up the elapsed PIT ticks and re-enable pit_timer */
- if ( vpit->first_injected )
- pickup_deactive_ticks(vpit);
- svm_set_tsc_shift(v, vpit);
/* We can't resume the guest if we're waiting on I/O */
ASSERT(!test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags));
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/hvm/vmx/io.c
--- a/xen/arch/x86/hvm/vmx/io.c Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/hvm/vmx/io.c Tue Mar 28 08:54:58 2006 -0700
@@ -86,7 +86,7 @@ interrupt_post_injection(struct vcpu * v
}
vpit->inject_point = NOW();
- vpit->last_pit_gtime += vpit->period;
+ vpit->last_pit_gtime += vpit->period_cycles;
set_guest_time(v, vpit->last_pit_gtime);
}
@@ -206,8 +206,11 @@ void vmx_do_resume(struct vcpu *v)
vmx_stts();
/* pick up the elapsed PIT ticks and re-enable pit_timer */
- if ( vpit->first_injected) {
- set_guest_time(v, v->domain->arch.hvm_domain.guest_time);
+ if ( vpit->first_injected ) {
+ if ( v->domain->arch.hvm_domain.guest_time ) {
+ set_guest_time(v, v->domain->arch.hvm_domain.guest_time);
+ v->domain->arch.hvm_domain.guest_time = 0;
+ }
pickup_deactive_ticks(vpit);
}
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/hvm/vmx/vmx.c Tue Mar 28 08:54:58 2006 -0700
@@ -89,6 +89,8 @@ static void vmx_relinquish_guest_resourc
for_each_vcpu ( d, v )
{
+ if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+ continue;
vmx_request_clear_vmcs(v);
destroy_vmcs(&v->arch.hvm_vmx);
free_monitor_pagetable(v);
@@ -358,9 +360,10 @@ static void vmx_freeze_time(struct vcpu
{
struct hvm_virpit *vpit = &v->domain->arch.hvm_domain.vpit;
- v->domain->arch.hvm_domain.guest_time = get_guest_time(v);
- if ( vpit->first_injected )
+ if ( vpit->first_injected && !v->domain->arch.hvm_domain.guest_time ) {
+ v->domain->arch.hvm_domain.guest_time = get_guest_time(v);
stop_timer(&(vpit->pit_timer));
+ }
}
static void vmx_ctxt_switch_from(struct vcpu *v)
@@ -397,31 +400,81 @@ void vmx_migrate_timers(struct vcpu *v)
migrate_timer(&(VLAPIC(v)->vlapic_timer), v->processor);
}
-void vmx_store_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
-{
+struct vmx_store_cpu_guest_regs_callback_info {
+ struct vcpu *v;
+ struct cpu_user_regs *regs;
+ unsigned long *crs;
+};
+
+static void vmx_store_cpu_guest_regs(
+ struct vcpu *v, struct cpu_user_regs *regs, unsigned long *crs);
+
+static void vmx_store_cpu_guest_regs_callback(void *data)
+{
+ struct vmx_store_cpu_guest_regs_callback_info *info = data;
+ vmx_store_cpu_guest_regs(info->v, info->regs, info->crs);
+}
+
+static void vmx_store_cpu_guest_regs(
+ struct vcpu *v, struct cpu_user_regs *regs, unsigned long *crs)
+{
+ if ( v != current )
+ {
+ /* Non-current VCPUs must be paused to get a register snapshot. */
+ ASSERT(atomic_read(&v->pausecnt) != 0);
+
+ if ( v->arch.hvm_vmx.launch_cpu != smp_processor_id() )
+ {
+ /* Get register details from remote CPU. */
+ struct vmx_store_cpu_guest_regs_callback_info info = {
+ .v = v, .regs = regs, .crs = crs };
+ cpumask_t cpumask = cpumask_of_cpu(v->arch.hvm_vmx.launch_cpu);
+ on_selected_cpus(cpumask, vmx_store_cpu_guest_regs_callback,
+ &info, 1, 1);
+ return;
+ }
+
+ /* Register details are on this CPU. Load the correct VMCS. */
+ __vmptrld(virt_to_maddr(v->arch.hvm_vmx.vmcs));
+ }
+
+ ASSERT(v->arch.hvm_vmx.launch_cpu == smp_processor_id());
+
+ if ( regs != NULL )
+ {
#if defined (__x86_64__)
- __vmread(GUEST_RFLAGS, ®s->rflags);
- __vmread(GUEST_SS_SELECTOR, ®s->ss);
- __vmread(GUEST_CS_SELECTOR, ®s->cs);
- __vmread(GUEST_DS_SELECTOR, ®s->ds);
- __vmread(GUEST_ES_SELECTOR, ®s->es);
- __vmread(GUEST_GS_SELECTOR, ®s->gs);
- __vmread(GUEST_FS_SELECTOR, ®s->fs);
- __vmread(GUEST_RIP, ®s->rip);
- __vmread(GUEST_RSP, ®s->rsp);
+ __vmread(GUEST_RFLAGS, ®s->rflags);
+ __vmread(GUEST_SS_SELECTOR, ®s->ss);
+ __vmread(GUEST_CS_SELECTOR, ®s->cs);
+ __vmread(GUEST_DS_SELECTOR, ®s->ds);
+ __vmread(GUEST_ES_SELECTOR, ®s->es);
+ __vmread(GUEST_GS_SELECTOR, ®s->gs);
+ __vmread(GUEST_FS_SELECTOR, ®s->fs);
+ __vmread(GUEST_RIP, ®s->rip);
+ __vmread(GUEST_RSP, ®s->rsp);
#elif defined (__i386__)
- __vmread(GUEST_RFLAGS, ®s->eflags);
- __vmread(GUEST_SS_SELECTOR, ®s->ss);
- __vmread(GUEST_CS_SELECTOR, ®s->cs);
- __vmread(GUEST_DS_SELECTOR, ®s->ds);
- __vmread(GUEST_ES_SELECTOR, ®s->es);
- __vmread(GUEST_GS_SELECTOR, ®s->gs);
- __vmread(GUEST_FS_SELECTOR, ®s->fs);
- __vmread(GUEST_RIP, ®s->eip);
- __vmread(GUEST_RSP, ®s->esp);
-#else
-#error Unsupported architecture
+ __vmread(GUEST_RFLAGS, ®s->eflags);
+ __vmread(GUEST_SS_SELECTOR, ®s->ss);
+ __vmread(GUEST_CS_SELECTOR, ®s->cs);
+ __vmread(GUEST_DS_SELECTOR, ®s->ds);
+ __vmread(GUEST_ES_SELECTOR, ®s->es);
+ __vmread(GUEST_GS_SELECTOR, ®s->gs);
+ __vmread(GUEST_FS_SELECTOR, ®s->fs);
+ __vmread(GUEST_RIP, ®s->eip);
+ __vmread(GUEST_RSP, ®s->esp);
#endif
+ }
+
+ if ( crs != NULL )
+ {
+ __vmread(CR0_READ_SHADOW, &crs[0]);
+ __vmread(GUEST_CR3, &crs[3]);
+ __vmread(CR4_READ_SHADOW, &crs[4]);
+ }
+
+ /* Reload current VCPU's VMCS if it was temporarily unloaded. */
+ if ( (v != current) && hvm_guest(current) )
+ __vmptrld(virt_to_maddr(current->arch.hvm_vmx.vmcs));
}
void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
@@ -453,13 +506,6 @@ void vmx_load_cpu_guest_regs(struct vcpu
#else
#error Unsupported architecture
#endif
-}
-
-void vmx_store_cpu_guest_ctrl_regs(struct vcpu *v, unsigned long crs[8])
-{
- __vmread(CR0_READ_SHADOW, &crs[0]);
- __vmread(GUEST_CR3, &crs[3]);
- __vmread(CR4_READ_SHADOW, &crs[4]);
}
void vmx_modify_guest_state(struct vcpu *v)
@@ -615,7 +661,6 @@ int start_vmx(void)
hvm_funcs.store_cpu_guest_regs = vmx_store_cpu_guest_regs;
hvm_funcs.load_cpu_guest_regs = vmx_load_cpu_guest_regs;
- hvm_funcs.store_cpu_guest_ctrl_regs = vmx_store_cpu_guest_ctrl_regs;
hvm_funcs.modify_guest_state = vmx_modify_guest_state;
hvm_funcs.realmode = vmx_realmode;
@@ -945,7 +990,7 @@ static void vmx_io_instruction(struct cp
port = (exit_qualification >> 16) & 0xFFFF;
else
port = regs->edx & 0xffff;
- TRACE_VMEXIT(2, port);
+ TRACE_VMEXIT(1, port);
size = (exit_qualification & 7) + 1;
dir = test_bit(3, &exit_qualification); /* direction */
@@ -1308,7 +1353,8 @@ static int vmx_set_cr0(unsigned long val
vm_entry_value |= VM_ENTRY_CONTROLS_IA32E_MODE;
__vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
- if ( !shadow_set_guest_paging_levels(v->domain, 4) ) {
+ if ( !shadow_set_guest_paging_levels(v->domain, PAGING_L4) )
+ {
printk("Unsupported guest paging levels\n");
domain_crash_synchronous(); /* need to take a clean path */
}
@@ -1317,9 +1363,26 @@ static int vmx_set_cr0(unsigned long val
#endif /* __x86_64__ */
{
#if CONFIG_PAGING_LEVELS >= 3
- if ( !shadow_set_guest_paging_levels(v->domain, 2) ) {
- printk("Unsupported guest paging levels\n");
- domain_crash_synchronous(); /* need to take a clean path */
+ /* seems it's a 32-bit or 32-bit PAE guest */
+
+ if ( test_bit(VMX_CPU_STATE_PAE_ENABLED,
+ &v->arch.hvm_vmx.cpu_state) )
+ {
+ /* The guest enables PAE first and then it enables PG, it is
+ * really a PAE guest */
+ if ( !shadow_set_guest_paging_levels(v->domain, PAGING_L3) )
+ {
+ printk("Unsupported guest paging levels\n");
+ domain_crash_synchronous();
+ }
+ }
+ else
+ {
+ if ( !shadow_set_guest_paging_levels(v->domain, PAGING_L2) )
+ {
+ printk("Unsupported guest paging levels\n");
+ domain_crash_synchronous(); /* need to take a clean path */
+ }
}
#endif
}
@@ -1398,6 +1461,12 @@ static int vmx_set_cr0(unsigned long val
"Restoring to %%eip 0x%lx\n", eip);
return 0; /* do not update eip! */
}
+ }
+ else if ( (value & (X86_CR0_PE | X86_CR0_PG)) == X86_CR0_PE )
+ {
+ /* we should take care of this kind of situation */
+ clear_all_shadow_status(v->domain);
+ __vmwrite(GUEST_CR3, pagetable_get_paddr(v->domain->arch.phys_table));
}
return 1;
@@ -1528,11 +1597,11 @@ static int mov_to_cr(int gp, int cr, str
if ( vmx_pgbit_test(v) )
{
- /* The guest is 32 bit. */
+ /* The guest is a 32-bit PAE guest. */
#if CONFIG_PAGING_LEVELS >= 4
unsigned long mfn, old_base_mfn;
- if( !shadow_set_guest_paging_levels(v->domain, 3) )
+ if( !shadow_set_guest_paging_levels(v->domain, PAGING_L3) )
{
printk("Unsupported guest paging levels\n");
domain_crash_synchronous(); /* need to take a clean path */
@@ -1572,12 +1641,31 @@ static int mov_to_cr(int gp, int cr, str
}
else
{
- /* The guest is 64 bit. */
+ /* The guest is a 64 bit or 32-bit PAE guest. */
#if CONFIG_PAGING_LEVELS >= 4
- if ( !shadow_set_guest_paging_levels(v->domain, 4) )
+ if ( (v->domain->arch.ops != NULL) &&
+ v->domain->arch.ops->guest_paging_levels == PAGING_L2)
{
- printk("Unsupported guest paging levels\n");
- domain_crash_synchronous(); /* need to take a clean path */
+ /* Seems the guest first enables PAE without enabling PG,
+ * it must enable PG after that, and it is a 32-bit PAE
+ * guest */
+
+ if ( !shadow_set_guest_paging_levels(v->domain,
+ PAGING_L3) )
+ {
+ printk("Unsupported guest paging levels\n");
+ /* need to take a clean path */
+ domain_crash_synchronous();
+ }
+ }
+ else
+ {
+ if ( !shadow_set_guest_paging_levels(v->domain,
+ PAGING_L4) )
+ {
+ printk("Unsupported guest paging levels\n");
+ domain_crash_synchronous();
+ }
}
#endif
}
@@ -1827,6 +1915,7 @@ static inline void vmx_vmexit_do_extint(
vector &= 0xff;
local_irq_disable();
+ TRACE_VMEXIT(1,vector);
switch(vector) {
case LOCAL_TIMER_VECTOR:
@@ -1956,7 +2045,6 @@ asmlinkage void vmx_vmexit_handler(struc
{
__vmread(GUEST_RIP, &eip);
- TRACE_3D(TRC_VMX_VMEXIT, v->domain->domain_id, eip, exit_reason);
TRACE_VMEXIT(0,exit_reason);
}
@@ -1980,7 +2068,6 @@ asmlinkage void vmx_vmexit_handler(struc
TRACE_VMEXIT(1,vector);
perfc_incra(cause_vector, vector);
- TRACE_3D(TRC_VMX_VECTOR, v->domain->domain_id, eip, vector);
switch (vector) {
#ifdef XEN_DEBUGGER
case TRAP_debug:
@@ -2164,7 +2251,7 @@ asmlinkage void vmx_load_cr2(void)
asmlinkage void vmx_trace_vmentry (void)
{
- TRACE_5D(TRC_VMENTRY,
+ TRACE_5D(TRC_VMX_VMENTRY,
trace_values[smp_processor_id()][0],
trace_values[smp_processor_id()][1],
trace_values[smp_processor_id()][2],
@@ -2180,7 +2267,7 @@ asmlinkage void vmx_trace_vmentry (void)
asmlinkage void vmx_trace_vmexit (void)
{
- TRACE_3D(TRC_VMEXIT,0,0,0);
+ TRACE_3D(TRC_VMX_VMEXIT,0,0,0);
return;
}
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/mm.c Tue Mar 28 08:54:58 2006 -0700
@@ -3351,8 +3351,9 @@ int ptwr_do_page_fault(struct domain *d,
* permissions in page directories by writing back to the linear mapping.
*/
if ( (flags = l1e_get_flags(pte) & WRPT_PTE_FLAGS) == WRPT_PTE_FLAGS )
- return !__put_user(
- pte.l1, &linear_pg_table[l1_linear_offset(addr)].l1);
+ return __put_user(
+ pte.l1, &linear_pg_table[l1_linear_offset(addr)].l1) ?
+ 0 : EXCRET_not_a_fault;
/* We are looking only for read-only mappings of p.t. pages. */
if ( ((flags | _PAGE_RW) != WRPT_PTE_FLAGS) ||
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/shadow.c
--- a/xen/arch/x86/shadow.c Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/shadow.c Tue Mar 28 08:54:58 2006 -0700
@@ -1807,6 +1807,16 @@ static int resync_all(struct domain *d,
entry_has_changed(
guest_pt[i], snapshot_pt[i], PAGE_FLAG_MASK) )
{
+
+ unsigned long gpfn;
+
+ gpfn = entry_get_pfn(guest_pt[i]);
+ /*
+ * Looks like it's longer a page table.
+ */
+ if ( unlikely(gpfn != (gpfn & PGT_mfn_mask)) )
+ continue;
+
need_flush |= validate_entry_change(
d, &guest_pt[i], &shadow_pt[i],
shadow_type_to_level(stype));
@@ -1851,6 +1861,14 @@ static int resync_all(struct domain *d,
{
#ifndef GUEST_PGENTRY_32
l4_pgentry_t *shadow4 = shadow;
+ unsigned long gpfn;
+
+ gpfn = l4e_get_pfn(new_root_e);
+ /*
+ * Looks like it's longer a page table.
+ */
+ if ( unlikely(gpfn != (gpfn & PGT_mfn_mask)) )
+ continue;
if ( d->arch.ops->guest_paging_levels == PAGING_L4 )
{
@@ -1894,7 +1912,7 @@ static int resync_all(struct domain *d,
unmap_domain_page(snapshot);
unmap_domain_page(guest);
- if ( unlikely(unshadow) )
+ if ( unlikely(unshadow && stype == PGT_root_page_table) )
{
for_each_vcpu(d, v)
if(smfn == pagetable_get_pfn(v->arch.shadow_table))
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/smp.c
--- a/xen/arch/x86/smp.c Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/smp.c Tue Mar 28 08:54:58 2006 -0700
@@ -106,6 +106,16 @@ void send_IPI_self(int vector)
__send_IPI_shortcut(APIC_DEST_SELF, vector);
}
+static inline void check_IPI_mask(cpumask_t cpumask)
+{
+ /*
+ * Sanity, and necessary. An IPI with no target generates a send accept
+ * error with Pentium and P6 APICs.
+ */
+ ASSERT(cpus_subset(cpumask, cpu_online_map));
+ ASSERT(!cpus_empty(cpumask));
+}
+
/*
* This is only used on smaller machines.
*/
@@ -115,6 +125,8 @@ void send_IPI_mask_bitmask(cpumask_t cpu
unsigned long cfg;
unsigned long flags;
+ check_IPI_mask(cpumask);
+
local_irq_save(flags);
/*
@@ -145,6 +157,8 @@ inline void send_IPI_mask_sequence(cpuma
{
unsigned long cfg, flags;
unsigned int query_cpu;
+
+ check_IPI_mask(mask);
/*
* Hack. The clustered APIC addressing mode doesn't allow us to send
@@ -304,6 +318,9 @@ extern int on_selected_cpus(
ASSERT(local_irq_is_enabled());
+ if ( nr_cpus == 0 )
+ return 0;
+
data.func = func;
data.info = info;
data.wait = wait;
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/traps.c Tue Mar 28 08:54:58 2006 -0700
@@ -286,7 +286,7 @@ asmlinkage void fatal_trap(int trapnr, s
unsigned long cr2;
static char *trapstr[] = {
"divide error", "debug", "nmi", "bkpt", "overflow", "bounds",
- "invalid operation", "device not available", "double fault",
+ "invalid opcode", "device not available", "double fault",
"coprocessor segment", "invalid tss", "segment not found",
"stack error", "general protection fault", "page fault",
"spurious interrupt", "coprocessor error", "alignment check",
@@ -382,7 +382,6 @@ DO_ERROR_NOCODE( 0, "divide error", divi
DO_ERROR_NOCODE( 0, "divide error", divide_error)
DO_ERROR_NOCODE( 4, "overflow", overflow)
DO_ERROR_NOCODE( 5, "bounds", bounds)
-DO_ERROR_NOCODE( 6, "invalid operand", invalid_op)
DO_ERROR_NOCODE( 9, "coprocessor segment overrun", coprocessor_segment_overrun)
DO_ERROR(10, "invalid TSS", invalid_TSS)
DO_ERROR(11, "segment not present", segment_not_present)
@@ -391,6 +390,85 @@ DO_ERROR(17, "alignment check", alignmen
DO_ERROR(17, "alignment check", alignment_check)
DO_ERROR_NOCODE(19, "simd error", simd_coprocessor_error)
+static int emulate_forced_invalid_op(struct cpu_user_regs *regs)
+{
+ char signature[5], instr[2];
+ unsigned long a, b, c, d, eip;
+
+ a = regs->eax;
+ b = regs->ebx;
+ c = regs->ecx;
+ d = regs->edx;
+ eip = regs->eip;
+
+ /* Check for forced emulation signature: ud2 ; .ascii "xen". */
+ if ( copy_from_user(signature, (char *)eip, sizeof(signature)) ||
+ memcmp(signature, "\xf\xbxen", sizeof(signature)) )
+ return 0;
+ eip += sizeof(signature);
+
+ /* We only emulate CPUID. */
+ if ( copy_from_user(instr, (char *)eip, sizeof(instr)) ||
+ memcmp(instr, "\xf\xa2", sizeof(instr)) )
+ return 0;
+ eip += sizeof(instr);
+
+ __asm__ (
+ "cpuid"
+ : "=a" (a), "=b" (b), "=c" (c), "=d" (d)
+ : "0" (a), "1" (b), "2" (c), "3" (d) );
+
+ if ( regs->eax == 1 )
+ {
+ /* Modify Feature Information. */
+ clear_bit(X86_FEATURE_VME, &d);
+ clear_bit(X86_FEATURE_DE, &d);
+ clear_bit(X86_FEATURE_PSE, &d);
+ clear_bit(X86_FEATURE_PGE, &d);
+ clear_bit(X86_FEATURE_SEP, &d);
+ if ( !IS_PRIV(current->domain) )
+ clear_bit(X86_FEATURE_MTRR, &d);
+ }
+
+ regs->eax = a;
+ regs->ebx = b;
+ regs->ecx = c;
+ regs->edx = d;
+ regs->eip = eip;
+
+ return EXCRET_fault_fixed;
+}
+
+asmlinkage int do_invalid_op(struct cpu_user_regs *regs)
+{
+ struct vcpu *v = current;
+ struct trap_bounce *tb = &v->arch.trap_bounce;
+ struct trap_info *ti;
+ int rc;
+
+ DEBUGGER_trap_entry(TRAP_invalid_op, regs);
+
+ if ( unlikely(!guest_mode(regs)) )
+ {
+ DEBUGGER_trap_fatal(TRAP_invalid_op, regs);
+ show_registers(regs);
+ panic("CPU%d FATAL TRAP: vector = %d (invalid opcode)\n",
+ smp_processor_id(), TRAP_invalid_op);
+ }
+
+ if ( (rc = emulate_forced_invalid_op(regs)) != 0 )
+ return rc;
+
+ ti = ¤t->arch.guest_context.trap_ctxt[TRAP_invalid_op];
+ tb->flags = TBF_EXCEPTION;
+ tb->cs = ti->cs;
+ tb->eip = ti->address;
+ if ( TI_GET_IF(ti) )
+ tb->flags |= TBF_INTERRUPT;
+
+ return 0;
+}
+
asmlinkage int do_int3(struct cpu_user_regs *regs)
{
struct vcpu *v = current;
@@ -540,6 +618,46 @@ static int fixup_page_fault(unsigned lon
}
return 0;
+}
+
+static int spurious_page_fault(unsigned long addr, struct cpu_user_regs *regs)
+{
+ struct vcpu *v = current;
+ struct domain *d = v->domain;
+ int rc;
+
+ /*
+ * The only possible reason for a spurious page fault not to be picked
+ * up already is that a page directory was unhooked by writable page table
+ * logic and then reattached before the faulting VCPU could detect it.
+ */
+ if ( is_idle_domain(d) || /* no ptwr in idle domain */
+ IN_HYPERVISOR_RANGE(addr) || /* no ptwr on hypervisor addrs */
+ shadow_mode_enabled(d) || /* no ptwr logic in shadow mode */
+ ((regs->error_code & 0x1d) != 0) ) /* simple not-present fault? */
+ return 0;
+
+ LOCK_BIGLOCK(d);
+
+ /*
+ * The page directory could have been detached again while we weren't
+ * holding the per-domain lock. Detect that and fix up if it's the case.
+ */
+ if ( unlikely(d->arch.ptwr[PTWR_PT_ACTIVE].l1va) &&
+ unlikely(l2_linear_offset(addr) ==
+ d->arch.ptwr[PTWR_PT_ACTIVE].l2_idx) )
+ {
+ ptwr_flush(d, PTWR_PT_ACTIVE);
+ rc = 1;
+ }
+ else
+ {
+ /* Okay, walk the page tables. Only check for not-present faults.*/
+ rc = __spurious_page_fault(addr);
+ }
+
+ UNLOCK_BIGLOCK(d);
+ return rc;
}
/*
@@ -566,6 +684,13 @@ asmlinkage int do_page_fault(struct cpu_
if ( unlikely(!guest_mode(regs)) )
{
+ if ( spurious_page_fault(addr, regs) )
+ {
+ DPRINTK("Spurious fault in domain %u:%u at addr %lx\n",
+ current->domain->domain_id, current->vcpu_id, addr);
+ return EXCRET_not_a_fault;
+ }
+
if ( likely((fixup = search_exception_table(regs->eip)) != 0) )
{
perfc_incrc(copy_user_faults);
@@ -580,7 +705,7 @@ asmlinkage int do_page_fault(struct cpu_
panic("CPU%d FATAL PAGE FAULT\n"
"[error_code=%04x]\n"
"Faulting linear address: %p\n",
- smp_processor_id(), regs->error_code, addr);
+ smp_processor_id(), regs->error_code, _p(addr));
}
propagate_page_fault(addr, regs->error_code);
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/x86_32/traps.c Tue Mar 28 08:54:58 2006 -0700
@@ -27,8 +27,7 @@ void show_registers(struct cpu_user_regs
if ( hvm_guest(current) && guest_mode(regs) )
{
context = "hvm";
- hvm_store_cpu_guest_regs(current, &fault_regs);
- hvm_store_cpu_guest_ctrl_regs(current, fault_crs);
+ hvm_store_cpu_guest_regs(current, &fault_regs, fault_crs);
}
else
{
@@ -71,38 +70,77 @@ void show_registers(struct cpu_user_regs
void show_page_walk(unsigned long addr)
{
+ unsigned long pfn, mfn = read_cr3() >> PAGE_SHIFT;
+#ifdef CONFIG_X86_PAE
+ l3_pgentry_t l3e, *l3t;
+#endif
+ l2_pgentry_t l2e, *l2t;
+ l1_pgentry_t l1e, *l1t;
+
+ printk("Pagetable walk from %08lx:\n", addr);
+
+#ifdef CONFIG_X86_PAE
+ l3t = map_domain_page(mfn);
+ l3e = l3t[l3_table_offset(addr)];
+ mfn = l3e_get_pfn(l3e);
+ pfn = get_gpfn_from_mfn(mfn);
+ printk(" L3 = %"PRIpte" %08lx\n", l3e_get_intpte(l3e), pfn);
+ unmap_domain_page(l3t);
+ if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) )
+ return;
+#endif
+
+ l2t = map_domain_page(mfn);
+ l2e = l2t[l2_table_offset(addr)];
+ mfn = l2e_get_pfn(l2e);
+ pfn = get_gpfn_from_mfn(mfn);
+ printk(" L2 = %"PRIpte" %08lx %s\n", l2e_get_intpte(l2e), pfn,
+ (l2e_get_flags(l2e) & _PAGE_PSE) ? "(PSE)" : "");
+ unmap_domain_page(l2t);
+ if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) ||
+ (l2e_get_flags(l2e) & _PAGE_PSE) )
+ return;
+
+ l1t = map_domain_page(mfn);
+ l1e = l1t[l1_table_offset(addr)];
+ mfn = l1e_get_pfn(l1e);
+ pfn = get_gpfn_from_mfn(mfn);
+ printk(" L1 = %"PRIpte" %08lx\n", l1e_get_intpte(l1e), pfn);
+ unmap_domain_page(l1t);
+}
+
+int __spurious_page_fault(unsigned long addr)
+{
unsigned long mfn = read_cr3() >> PAGE_SHIFT;
- intpte_t *ptab, ent;
- unsigned long pfn;
-
- printk("Pagetable walk from %08lx:\n", addr);
-
#ifdef CONFIG_X86_PAE
- ptab = map_domain_page(mfn);
- ent = ptab[l3_table_offset(addr)];
- pfn = get_gpfn_from_mfn((u32)(ent >> PAGE_SHIFT));
- printk(" L3 = %"PRIpte" %08lx\n", ent, pfn);
- unmap_domain_page(ptab);
- if ( !(ent & _PAGE_PRESENT) )
- return;
- mfn = ent >> PAGE_SHIFT;
+ l3_pgentry_t l3e, *l3t;
#endif
-
- ptab = map_domain_page(mfn);
- ent = ptab[l2_table_offset(addr)];
- pfn = get_gpfn_from_mfn((u32)(ent >> PAGE_SHIFT));
- printk(" L2 = %"PRIpte" %08lx %s\n", ent, pfn,
- (ent & _PAGE_PSE) ? "(PSE)" : "");
- unmap_domain_page(ptab);
- if ( !(ent & _PAGE_PRESENT) || (ent & _PAGE_PSE) )
- return;
- mfn = ent >> PAGE_SHIFT;
-
- ptab = map_domain_page(ent >> PAGE_SHIFT);
- ent = ptab[l1_table_offset(addr)];
- pfn = get_gpfn_from_mfn((u32)(ent >> PAGE_SHIFT));
- printk(" L1 = %"PRIpte" %08lx\n", ent, pfn);
- unmap_domain_page(ptab);
+ l2_pgentry_t l2e, *l2t;
+ l1_pgentry_t l1e, *l1t;
+
+#ifdef CONFIG_X86_PAE
+ l3t = map_domain_page(mfn);
+ l3e = l3t[l3_table_offset(addr)];
+ mfn = l3e_get_pfn(l3e);
+ unmap_domain_page(l3t);
+ if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) )
+ return 0;
+#endif
+
+ l2t = map_domain_page(mfn);
+ l2e = l2t[l2_table_offset(addr)];
+ mfn = l2e_get_pfn(l2e);
+ unmap_domain_page(l2t);
+ if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) )
+ return 0;
+ if ( l2e_get_flags(l2e) & _PAGE_PSE )
+ return 1;
+
+ l1t = map_domain_page(mfn);
+ l1e = l1t[l1_table_offset(addr)];
+ mfn = l1e_get_pfn(l1e);
+ unmap_domain_page(l1t);
+ return !!(l1e_get_flags(l1e) & _PAGE_PRESENT);
}
#define DOUBLEFAULT_STACK_SIZE 1024
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/arch/x86/x86_64/traps.c
--- a/xen/arch/x86/x86_64/traps.c Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/arch/x86/x86_64/traps.c Tue Mar 28 08:54:58 2006 -0700
@@ -27,8 +27,7 @@ void show_registers(struct cpu_user_regs
if ( hvm_guest(current) && guest_mode(regs) )
{
context = "hvm";
- hvm_store_cpu_guest_regs(current, &fault_regs);
- hvm_store_cpu_guest_ctrl_regs(current, fault_crs);
+ hvm_store_cpu_guest_regs(current, &fault_regs, fault_crs);
}
else
{
@@ -71,31 +70,79 @@ void show_registers(struct cpu_user_regs
void show_page_walk(unsigned long addr)
{
- unsigned long page = read_cr3();
-
+ unsigned long pfn, mfn = read_cr3() >> PAGE_SHIFT;
+ l4_pgentry_t l4e, *l4t;
+ l3_pgentry_t l3e, *l3t;
+ l2_pgentry_t l2e, *l2t;
+ l1_pgentry_t l1e, *l1t;
+
printk("Pagetable walk from %016lx:\n", addr);
- page &= PAGE_MASK;
- page = ((unsigned long *) __va(page))[l4_table_offset(addr)];
- printk(" L4 = %016lx\n", page);
- if ( !(page & _PAGE_PRESENT) )
+ l4t = mfn_to_virt(mfn);
+ l4e = l4t[l4_table_offset(addr)];
+ mfn = l4e_get_pfn(l4e);
+ pfn = get_gpfn_from_mfn(mfn);
+ printk(" L4 = %"PRIpte" %016lx\n", l4e_get_intpte(l4e), pfn);
+ if ( !(l4e_get_flags(l4e) & _PAGE_PRESENT) )
return;
- page &= PAGE_MASK;
- page = ((unsigned long *) __va(page))[l3_table_offset(addr)];
- printk(" L3 = %016lx\n", page);
- if ( !(page & _PAGE_PRESENT) )
+ l3t = mfn_to_virt(mfn);
+ l3e = l3t[l3_table_offset(addr)];
+ mfn = l3e_get_pfn(l3e);
+ pfn = get_gpfn_from_mfn(mfn);
+ printk(" L3 = %"PRIpte" %016lx\n", l3e_get_intpte(l3e), pfn);
+ if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) )
return;
- page &= PAGE_MASK;
- page = ((unsigned long *) __va(page))[l2_table_offset(addr)];
- printk(" L2 = %016lx %s\n", page, (page & _PAGE_PSE) ? "(2MB)" : "");
- if ( !(page & _PAGE_PRESENT) || (page & _PAGE_PSE) )
+ l2t = mfn_to_virt(mfn);
+ l2e = l2t[l2_table_offset(addr)];
+ mfn = l2e_get_pfn(l2e);
+ pfn = get_gpfn_from_mfn(mfn);
+ printk(" L2 = %"PRIpte" %016lx %s\n", l2e_get_intpte(l2e), pfn,
+ (l2e_get_flags(l2e) & _PAGE_PSE) ? "(PSE)" : "");
+ if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) ||
+ (l2e_get_flags(l2e) & _PAGE_PSE) )
return;
- page &= PAGE_MASK;
- page = ((unsigned long *) __va(page))[l1_table_offset(addr)];
- printk(" L1 = %016lx\n", page);
+ l1t = mfn_to_virt(mfn);
+ l1e = l1t[l1_table_offset(addr)];
+ mfn = l1e_get_pfn(l1e);
+ pfn = get_gpfn_from_mfn(mfn);
+ printk(" L1 = %"PRIpte" %016lx\n", l1e_get_intpte(l1e), pfn);
+}
+
+int __spurious_page_fault(unsigned long addr)
+{
+ unsigned long mfn = read_cr3() >> PAGE_SHIFT;
+ l4_pgentry_t l4e, *l4t;
+ l3_pgentry_t l3e, *l3t;
+ l2_pgentry_t l2e, *l2t;
+ l1_pgentry_t l1e, *l1t;
+
+ l4t = mfn_to_virt(mfn);
+ l4e = l4t[l4_table_offset(addr)];
+ mfn = l4e_get_pfn(l4e);
+ if ( !(l4e_get_flags(l4e) & _PAGE_PRESENT) )
+ return 0;
+
+ l3t = mfn_to_virt(mfn);
+ l3e = l3t[l3_table_offset(addr)];
+ mfn = l3e_get_pfn(l3e);
+ if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) )
+ return 0;
+
+ l2t = mfn_to_virt(mfn);
+ l2e = l2t[l2_table_offset(addr)];
+ mfn = l2e_get_pfn(l2e);
+ if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) )
+ return 0;
+ if ( l2e_get_flags(l2e) & _PAGE_PSE )
+ return 1;
+
+ l1t = mfn_to_virt(mfn);
+ l1e = l1t[l1_table_offset(addr)];
+ mfn = l1e_get_pfn(l1e);
+ return !!(l1e_get_flags(l1e) & _PAGE_PRESENT);
}
asmlinkage void double_fault(void);
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/common/gdbstub.c
--- a/xen/common/gdbstub.c Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/common/gdbstub.c Tue Mar 28 08:54:58 2006 -0700
@@ -562,6 +562,7 @@ initialise_gdb(void)
gdb_ctx->serhnd = serial_parse_handle(opt_gdb);
if ( gdb_ctx->serhnd != -1 )
printk("GDB stub initialised.\n");
+ serial_start_sync(gdb_ctx->serhnd);
}
/*
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/common/page_alloc.c
--- a/xen/common/page_alloc.c Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/common/page_alloc.c Tue Mar 28 08:54:58 2006 -0700
@@ -219,8 +219,6 @@ unsigned long alloc_boot_pages(unsigned
#define pfn_dom_zone_type(_pfn) \
(((_pfn) <= MAX_DMADOM_PFN) ? MEMZONE_DMADOM : MEMZONE_DOM)
-/* Up to 2^20 pages can be allocated at once. */
-#define MAX_ORDER 20
static struct list_head heap[NR_ZONES][MAX_ORDER+1];
static unsigned long avail[NR_ZONES];
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/drivers/char/ns16550.c
--- a/xen/drivers/char/ns16550.c Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/drivers/char/ns16550.c Tue Mar 28 08:54:58 2006 -0700
@@ -121,8 +121,11 @@ static void ns16550_interrupt(
while ( !(ns_read_reg(uart, IIR) & IIR_NOINT) )
{
- serial_tx_interrupt(port, regs);
- serial_rx_interrupt(port, regs);
+ char lsr = ns_read_reg(uart, LSR);
+ if ( lsr & LSR_THRE )
+ serial_tx_interrupt(port, regs);
+ if ( lsr & LSR_DR )
+ serial_rx_interrupt(port, regs);
}
}
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/drivers/char/serial.c
--- a/xen/drivers/char/serial.c Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/drivers/char/serial.c Tue Mar 28 08:54:58 2006 -0700
@@ -7,6 +7,7 @@
*/
#include <xen/config.h>
+#include <xen/delay.h>
#include <xen/init.h>
#include <xen/irq.h>
#include <xen/keyhandler.h>
@@ -15,8 +16,8 @@
#include <xen/serial.h>
static struct serial_port com[2] = {
- { .lock = SPIN_LOCK_UNLOCKED },
- { .lock = SPIN_LOCK_UNLOCKED }
+ { .rx_lock = SPIN_LOCK_UNLOCKED, .tx_lock = SPIN_LOCK_UNLOCKED },
+ { .rx_lock = SPIN_LOCK_UNLOCKED, .tx_lock = SPIN_LOCK_UNLOCKED }
};
void serial_rx_interrupt(struct serial_port *port, struct cpu_user_regs *regs)
@@ -25,7 +26,7 @@ void serial_rx_interrupt(struct serial_p
serial_rx_fn fn = NULL;
unsigned long flags;
- spin_lock_irqsave(&port->lock, flags);
+ spin_lock_irqsave(&port->rx_lock, flags);
if ( port->driver->getc(port, &c) )
{
@@ -39,7 +40,7 @@ void serial_rx_interrupt(struct serial_p
port->rxbuf[MASK_SERIAL_RXBUF_IDX(port->rxbufp++)] = c;
}
- spin_unlock_irqrestore(&port->lock, flags);
+ spin_unlock_irqrestore(&port->rx_lock, flags);
if ( fn != NULL )
(*fn)(c & 0x7f, regs);
@@ -50,7 +51,19 @@ void serial_tx_interrupt(struct serial_p
int i;
unsigned long flags;
- spin_lock_irqsave(&port->lock, flags);
+ local_irq_save(flags);
+
+ /*
+ * Avoid spinning for a long time: if there is a long-term lock holder
+ * then we know that they'll be stuffing bytes into the transmitter which
+ * will therefore not be empty for long.
+ */
+ while ( !spin_trylock(&port->tx_lock) )
+ {
+ if ( !port->driver->tx_empty(port) )
+ return;
+ cpu_relax();
+ }
if ( port->driver->tx_empty(port) )
{
@@ -63,7 +76,7 @@ void serial_tx_interrupt(struct serial_p
}
}
- spin_unlock_irqrestore(&port->lock, flags);
+ spin_unlock_irqrestore(&port->tx_lock, flags);
}
static void __serial_putc(struct serial_port *port, char c)
@@ -117,7 +130,7 @@ void serial_putc(int handle, char c)
if ( (handle == -1) || !port->driver || !port->driver->putc )
return;
- spin_lock_irqsave(&port->lock, flags);
+ spin_lock_irqsave(&port->tx_lock, flags);
if ( (c == '\n') && (handle & SERHND_COOKED) )
__serial_putc(port, '\r');
@@ -129,7 +142,7 @@ void serial_putc(int handle, char c)
__serial_putc(port, c);
- spin_unlock_irqrestore(&port->lock, flags);
+ spin_unlock_irqrestore(&port->tx_lock, flags);
}
void serial_puts(int handle, const char *s)
@@ -141,7 +154,7 @@ void serial_puts(int handle, const char
if ( (handle == -1) || !port->driver || !port->driver->putc )
return;
- spin_lock_irqsave(&port->lock, flags);
+ spin_lock_irqsave(&port->tx_lock, flags);
while ( (c = *s++) != '\0' )
{
@@ -156,7 +169,7 @@ void serial_puts(int handle, const char
__serial_putc(port, c);
}
- spin_unlock_irqrestore(&port->lock, flags);
+ spin_unlock_irqrestore(&port->tx_lock, flags);
}
char serial_getc(int handle)
@@ -168,27 +181,28 @@ char serial_getc(int handle)
if ( (handle == -1) || !port->driver || !port->driver->getc )
return '\0';
- do {
+ do {
for ( ; ; )
{
- spin_lock_irqsave(&port->lock, flags);
+ spin_lock_irqsave(&port->rx_lock, flags);
if ( port->rxbufp != port->rxbufc )
{
c = port->rxbuf[MASK_SERIAL_RXBUF_IDX(port->rxbufc++)];
- spin_unlock_irqrestore(&port->lock, flags);
+ spin_unlock_irqrestore(&port->rx_lock, flags);
break;
}
if ( port->driver->getc(port, &c) )
{
- spin_unlock_irqrestore(&port->lock, flags);
+ spin_unlock_irqrestore(&port->rx_lock, flags);
break;
}
- spin_unlock_irqrestore(&port->lock, flags);
+ spin_unlock_irqrestore(&port->rx_lock, flags);
cpu_relax();
+ udelay(100);
}
} while ( ((handle & SERHND_LO) && (c & 0x80)) ||
((handle & SERHND_HI) && !(c & 0x80)) );
@@ -241,7 +255,7 @@ void serial_set_rx_handler(int handle, s
if ( handle == -1 )
return;
- spin_lock_irqsave(&port->lock, flags);
+ spin_lock_irqsave(&port->rx_lock, flags);
if ( port->rx != NULL )
goto fail;
@@ -265,11 +279,11 @@ void serial_set_rx_handler(int handle, s
port->rx = fn;
}
- spin_unlock_irqrestore(&port->lock, flags);
+ spin_unlock_irqrestore(&port->rx_lock, flags);
return;
fail:
- spin_unlock_irqrestore(&port->lock, flags);
+ spin_unlock_irqrestore(&port->rx_lock, flags);
printk("ERROR: Conflicting receive handlers for COM%d\n",
handle & SERHND_IDX);
}
@@ -277,8 +291,13 @@ void serial_force_unlock(int handle)
void serial_force_unlock(int handle)
{
struct serial_port *port = &com[handle & SERHND_IDX];
- if ( handle != -1 )
- port->lock = SPIN_LOCK_UNLOCKED;
+
+ if ( handle == -1 )
+ return;
+
+ port->rx_lock = SPIN_LOCK_UNLOCKED;
+ port->tx_lock = SPIN_LOCK_UNLOCKED;
+
serial_start_sync(handle);
}
@@ -290,7 +309,7 @@ void serial_start_sync(int handle)
if ( handle == -1 )
return;
- spin_lock_irqsave(&port->lock, flags);
+ spin_lock_irqsave(&port->tx_lock, flags);
if ( port->sync++ == 0 )
{
@@ -303,7 +322,7 @@ void serial_start_sync(int handle)
}
}
- spin_unlock_irqrestore(&port->lock, flags);
+ spin_unlock_irqrestore(&port->tx_lock, flags);
}
void serial_end_sync(int handle)
@@ -314,11 +333,11 @@ void serial_end_sync(int handle)
if ( handle == -1 )
return;
- spin_lock_irqsave(&port->lock, flags);
+ spin_lock_irqsave(&port->tx_lock, flags);
port->sync--;
- spin_unlock_irqrestore(&port->lock, flags);
+ spin_unlock_irqrestore(&port->tx_lock, flags);
}
int serial_tx_space(int handle)
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/include/asm-x86/hvm/hvm.h Tue Mar 28 08:54:58 2006 -0700
@@ -41,12 +41,12 @@ struct hvm_function_table {
/*
* Store and load guest state:
* 1) load/store guest register state,
- * 2) store guest control register state (used for panic dumps),
- * 3) modify guest state (e.g., set debug flags).
+ * 2) modify guest state (e.g., set debug flags).
*/
- void (*store_cpu_guest_regs)(struct vcpu *v, struct cpu_user_regs *r);
- void (*load_cpu_guest_regs)(struct vcpu *v, struct cpu_user_regs *r);
- void (*store_cpu_guest_ctrl_regs)(struct vcpu *v, unsigned long crs[8]);
+ void (*store_cpu_guest_regs)(
+ struct vcpu *v, struct cpu_user_regs *r, unsigned long *crs);
+ void (*load_cpu_guest_regs)(
+ struct vcpu *v, struct cpu_user_regs *r);
void (*modify_guest_state)(struct vcpu *v);
/*
@@ -93,21 +93,16 @@ hvm_relinquish_guest_resources(struct do
}
static inline void
-hvm_store_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *r)
+hvm_store_cpu_guest_regs(
+ struct vcpu *v, struct cpu_user_regs *r, unsigned long *crs)
{
- hvm_funcs.store_cpu_guest_regs(v, r);
+ hvm_funcs.store_cpu_guest_regs(v, r, crs);
}
static inline void
hvm_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *r)
{
hvm_funcs.load_cpu_guest_regs(v, r);
-}
-
-static inline void
-hvm_store_cpu_guest_ctrl_regs(struct vcpu *v, unsigned long crs[8])
-{
- hvm_funcs.store_cpu_guest_ctrl_regs(v, crs);
}
static inline void
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/include/asm-x86/hvm/svm/svm.h
--- a/xen/include/asm-x86/hvm/svm/svm.h Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/include/asm-x86/hvm/svm/svm.h Tue Mar 28 08:54:58 2006 -0700
@@ -48,6 +48,8 @@ extern void svm_stts(struct vcpu *v);
extern void svm_stts(struct vcpu *v);
extern void svm_do_launch(struct vcpu *v);
extern void svm_do_resume(struct vcpu *v);
+extern void svm_set_guest_time(struct vcpu *v, u64 gtime);
+extern u64 svm_get_guest_time(struct vcpu *v);
extern void arch_svm_do_resume(struct vcpu *v);
extern int load_vmcb(struct arch_svm_struct *arch_svm, u64 phys_hsa);
/* For debugging. Remove when no longer needed. */
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/include/asm-x86/processor.h
--- a/xen/include/asm-x86/processor.h Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/include/asm-x86/processor.h Tue Mar 28 08:54:58 2006 -0700
@@ -524,6 +524,7 @@ void show_stack(struct cpu_user_regs *re
void show_stack(struct cpu_user_regs *regs);
void show_registers(struct cpu_user_regs *regs);
void show_page_walk(unsigned long addr);
+int __spurious_page_fault(unsigned long addr);
asmlinkage void fatal_trap(int trapnr, struct cpu_user_regs *regs);
extern void mtrr_ap_init(void);
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/include/public/arch-x86_32.h
--- a/xen/include/public/arch-x86_32.h Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/include/public/arch-x86_32.h Tue Mar 28 08:54:58 2006 -0700
@@ -170,6 +170,18 @@ typedef struct {
#endif /* !__ASSEMBLY__ */
+/*
+ * Prefix forces emulation of some non-trapping instructions.
+ * Currently only CPUID.
+ */
+#ifdef __ASSEMBLY__
+#define XEN_EMULATE_PREFIX .byte 0x0f,0x0b,0x78,0x65,0x6e ;
+#define XEN_CPUID XEN_EMULATE_PREFIX cpuid
+#else
+#define XEN_EMULATE_PREFIX ".byte 0x0f,0x0b,0x78,0x65,0x6e ; "
+#define XEN_CPUID XEN_EMULATE_PREFIX "cpuid"
+#endif
+
#endif
/*
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/include/public/arch-x86_64.h
--- a/xen/include/public/arch-x86_64.h Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/include/public/arch-x86_64.h Tue Mar 28 08:54:58 2006 -0700
@@ -246,6 +246,18 @@ typedef struct {
#endif /* !__ASSEMBLY__ */
+/*
+ * Prefix forces emulation of some non-trapping instructions.
+ * Currently only CPUID.
+ */
+#ifdef __ASSEMBLY__
+#define XEN_EMULATE_PREFIX .byte 0x0f,0x0b,0x78,0x65,0x6e ;
+#define XEN_CPUID XEN_EMULATE_PREFIX cpuid
+#else
+#define XEN_EMULATE_PREFIX ".byte 0x0f,0x0b,0x78,0x65,0x6e ; "
+#define XEN_CPUID XEN_EMULATE_PREFIX "cpuid"
+#endif
+
#endif
/*
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/include/public/io/netif.h
--- a/xen/include/public/io/netif.h Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/include/public/io/netif.h Tue Mar 28 08:54:58 2006 -0700
@@ -20,8 +20,12 @@
*/
/* Protocol checksum field is blank in the packet (hardware offload)? */
-#define _NETTXF_csum_blank (0)
-#define NETTXF_csum_blank (1U<<_NETTXF_csum_blank)
+#define _NETTXF_csum_blank (0)
+#define NETTXF_csum_blank (1U<<_NETTXF_csum_blank)
+
+/* Packet data has been validated against protocol checksum. */
+#define _NETTXF_data_validated (1)
+#define NETTXF_data_validated (1U<<_NETTXF_data_validated)
typedef struct netif_tx_request {
grant_ref_t gref; /* Reference to buffer page */
@@ -41,9 +45,13 @@ typedef struct {
grant_ref_t gref; /* Reference to incoming granted frame */
} netif_rx_request_t;
-/* Protocol checksum already validated (e.g., performed by hardware)? */
-#define _NETRXF_csum_valid (0)
-#define NETRXF_csum_valid (1U<<_NETRXF_csum_valid)
+/* Packet data has been validated against protocol checksum. */
+#define _NETRXF_data_validated (0)
+#define NETRXF_data_validated (1U<<_NETRXF_data_validated)
+
+/* Protocol checksum field is blank in the packet (hardware offload)? */
+#define _NETRXF_csum_blank (1)
+#define NETRXF_csum_blank (1U<<_NETRXF_csum_blank)
typedef struct {
uint16_t id;
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/include/public/trace.h
--- a/xen/include/public/trace.h Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/include/public/trace.h Tue Mar 28 08:54:58 2006 -0700
@@ -24,7 +24,6 @@
#define TRC_VMXTIMER 0x00082000 /* VMX timer trace */
#define TRC_VMXINT 0x00084000 /* VMX interrupt trace */
#define TRC_VMXIO 0x00088000 /* VMX io emulation trace */
-#define TRC_VMEXIT_HANDLER 0x00090000 /* VMX handler trace */
/* Trace events per class */
@@ -50,14 +49,11 @@
/* trace events per subclass */
#define TRC_VMX_VMEXIT (TRC_VMXEXIT + 1)
-#define TRC_VMX_VECTOR (TRC_VMXEXIT + 2)
+#define TRC_VMX_VMENTRY (TRC_VMXEXIT + 2)
#define TRC_VMX_TIMER_INTR (TRC_VMXTIMER + 1)
#define TRC_VMX_INT (TRC_VMXINT + 1)
-
-#define TRC_VMEXIT (TRC_VMEXIT_HANDLER + 1)
-#define TRC_VMENTRY (TRC_VMEXIT_HANDLER + 2)
/* This structure represents a single trace buffer record. */
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/include/xen/lib.h
--- a/xen/include/xen/lib.h Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/include/xen/lib.h Tue Mar 28 08:54:58 2006 -0700
@@ -47,7 +47,8 @@ extern void debugtrace_printk(const char
#define printk(_f , _a...) printf( _f , ## _a )
extern void printf(const char *format, ...)
__attribute__ ((format (printf, 1, 2)));
-extern void panic(const char *format, ...);
+extern void panic(const char *format, ...)
+ __attribute__ ((format (printf, 1, 2)));
extern long vm_assist(struct domain *, unsigned int, unsigned int);
/* vsprintf.c */
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/include/xen/mm.h
--- a/xen/include/xen/mm.h Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/include/xen/mm.h Tue Mar 28 08:54:58 2006 -0700
@@ -68,6 +68,9 @@ unsigned long avail_domheap_pages(void);
#define ALLOC_DOM_DMA 1
+/* Up to 2^20 pages can be allocated at once. */
+#define MAX_ORDER 20
+
/* Automatic page scrubbing for dead domains. */
extern struct list_head page_scrub_list;
#define page_scrub_schedule_work() \
diff -r 7e3cbc409676 -r d75a6cc5e68a xen/include/xen/serial.h
--- a/xen/include/xen/serial.h Mon Mar 27 15:36:47 2006 -0700
+++ b/xen/include/xen/serial.h Tue Mar 28 08:54:58 2006 -0700
@@ -42,7 +42,7 @@ struct serial_port {
char rxbuf[SERIAL_RXBUFSZ];
unsigned int rxbufp, rxbufc;
/* Serial I/O is concurrency-safe. */
- spinlock_t lock;
+ spinlock_t rx_lock, tx_lock;
};
struct uart_driver {
diff -r 7e3cbc409676 -r d75a6cc5e68a buildconfigs/linux-defconfig_xen_ia64
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/buildconfigs/linux-defconfig_xen_ia64 Tue Mar 28 08:54:58 2006 -0700
@@ -0,0 +1,1523 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.16-xen
+# Mon Mar 27 14:36:21 2006
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# Processor type and features
+#
+CONFIG_IA64=y
+CONFIG_64BIT=y
+CONFIG_MMU=y
+CONFIG_SWIOTLB=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_TIME_INTERPOLATION=y
+CONFIG_EFI=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_XEN=y
+CONFIG_ARCH_XEN=y
+CONFIG_XEN_PRIVILEGED_GUEST=y
+CONFIG_XEN_BLKDEV_GRANT=y
+CONFIG_XEN_BLKDEV_FRONTEND=y
+CONFIG_XEN_BLKDEV_BACKEND=y
+CONFIG_XEN_SYSFS=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_DMA_IS_DMA32=y
+# CONFIG_IA64_GENERIC is not set
+CONFIG_IA64_DIG=y
+# CONFIG_IA64_HP_ZX1 is not set
+# CONFIG_IA64_HP_ZX1_SWIOTLB is not set
+# CONFIG_IA64_SGI_SN2 is not set
+# CONFIG_IA64_HP_SIM is not set
+# CONFIG_ITANIUM is not set
+CONFIG_MCKINLEY=y
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+# CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_PGTABLE_3=y
+# CONFIG_PGTABLE_4 is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+CONFIG_IA64_L1_CACHE_SHIFT=7
+CONFIG_IA64_CYCLONE=y
+CONFIG_IOSAPIC=y
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4
+CONFIG_HOTPLUG_CPU=y
+# CONFIG_SCHED_SMT is not set
+# CONFIG_PREEMPT is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+# CONFIG_VIRTUAL_MEM_MAP is not set
+# CONFIG_IA32_SUPPORT is not set
+CONFIG_IA64_MCA_RECOVERY=y
+CONFIG_PERFMON=y
+CONFIG_IA64_PALINFO=y
+
+#
+# Firmware Drivers
+#
+CONFIG_EFI_VARS=y
+CONFIG_EFI_PCDP=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management and ACPI
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+
+#
+# ACPI (Advanced Configuration and Power Interface) Support
+#
+CONFIG_ACPI=y
+CONFIG_ACPI_BUTTON=y
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_HOTPLUG_CPU=y
+CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_BLACKLIST_YEAR=0
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_ACPI_CONTAINER=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Bus options (PCI, PCMCIA)
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCI Hotplug Support
+#
+CONFIG_HOTPLUG_PCI=y
+# CONFIG_HOTPLUG_PCI_FAKE is not set
+CONFIG_HOTPLUG_PCI_ACPI=y
+# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_ARPD=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+# CONFIG_BRIDGE_NF_EBTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+CONFIG_BRIDGE=y
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=y
+CONFIG_BLK_DEV_NBD=y
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=y
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_IDE_GENERIC is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+CONFIG_BLK_DEV_CMD64X=y
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_CHR_DEV_OSST=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=y
+CONFIG_SCSI_FC_ATTRS=y
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+CONFIG_SCSI_SAS_ATTRS=y
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_IPR is not set
+CONFIG_SCSI_QLOGIC_FC=y
+# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
+CONFIG_SCSI_QLOGIC_1280=y
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_BLK_DEV_DM is not set
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=y
+# CONFIG_FUSION_FC is not set
+CONFIG_FUSION_SAS=y
+CONFIG_FUSION_MAX_SGE=128
+# CONFIG_FUSION_CTL is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=y
+
+#
+# ARCnet devices
+#
+CONFIG_ARCNET=y
+# CONFIG_ARCNET_1201 is not set
+# CONFIG_ARCNET_1051 is not set
+# CONFIG_ARCNET_RAW is not set
+# CONFIG_ARCNET_CAP is not set
+# CONFIG_ARCNET_COM90xx is not set
+# CONFIG_ARCNET_COM90xxIO is not set
+# CONFIG_ARCNET_RIM_I is not set
+# CONFIG_ARCNET_COM20020 is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+# CONFIG_DE2104X is not set
+CONFIG_TULIP=y
+CONFIG_TULIP_MWI=y
+CONFIG_TULIP_MMIO=y
+CONFIG_TULIP_NAPI=y
+CONFIG_TULIP_NAPI_HW_MITIGATION=y
+# CONFIG_DE4X5 is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_DM9102 is not set
+# CONFIG_ULI526X is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+CONFIG_EEPRO100=y
+CONFIG_E100=y
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_VIA_RHINE is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+# CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+CONFIG_TIGON3=y
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+CONFIG_NETCONSOLE=y
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+
+#
+# ISDN subsystem
+#
+CONFIG_ISDN=m
+
+#
+# Old ISDN4Linux
+#
+# CONFIG_ISDN_I4L is not set
+
+#
+# CAPI subsystem
+#
+# CONFIG_ISDN_CAPI is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_JOYDEV=y
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+CONFIG_GAMEPORT=y
+# CONFIG_GAMEPORT_NS558 is not set
+# CONFIG_GAMEPORT_L4 is not set
+# CONFIG_GAMEPORT_EMU10K1 is not set
+# CONFIG_GAMEPORT_FM801 is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINKMP is not set
+# CONFIG_SYNCLINK_GT is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_ACPI=y
+CONFIG_SERIAL_8250_NR_UARTS=6
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_EFI_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+CONFIG_AGP=y
+CONFIG_AGP_I460=y
+CONFIG_DRM=y
+# CONFIG_DRM_TDFX is not set
+# CONFIG_DRM_R128 is not set
+# CONFIG_DRM_RADEON is not set
+# CONFIG_DRM_MGA is not set
+# CONFIG_DRM_SIS is not set
+# CONFIG_DRM_VIA is not set
+# CONFIG_DRM_SAVAGE is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_HPET is not set
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_ALGOPCF=y
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_RTC_X1205_I2C is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=y
+
+#
+# Video For Linux
+#
+
+#
+# Video Adapters
+#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_BT848 is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+# CONFIG_VIDEO_STRADIS is not set
+# CONFIG_VIDEO_ZORAN is not set
+# CONFIG_VIDEO_SAA7134 is not set
+# CONFIG_VIDEO_MXB is not set
+# CONFIG_VIDEO_DPC is not set
+# CONFIG_VIDEO_HEXIUM_ORION is not set
+# CONFIG_VIDEO_HEXIUM_GEMINI is not set
+# CONFIG_VIDEO_CX88 is not set
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_OVCAMCHIP is not set
+# CONFIG_VIDEO_AUDIO_DECODER is not set
+# CONFIG_VIDEO_DECODER is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_GEMTEK_PCI is not set
+# CONFIG_RADIO_MAXIRADIO is not set
+# CONFIG_RADIO_MAESTRO is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON_OLD is not set
+CONFIG_FB_RADEON=y
+CONFIG_FB_RADEON_I2C=y
+CONFIG_FB_RADEON_DEBUG=y
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_HWDEP=y
+CONFIG_SND_RAWMIDI=y
+CONFIG_SND_SEQUENCER=y
+CONFIG_SND_SEQ_DUMMY=y
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_MPU401_UART=y
+CONFIG_SND_OPL3_LIB=y
+CONFIG_SND_AC97_CODEC=y
+CONFIG_SND_AC97_BUS=y
+CONFIG_SND_DUMMY=y
+CONFIG_SND_VIRMIDI=y
+CONFIG_SND_MTPAV=y
+CONFIG_SND_SERIAL_U16550=y
+CONFIG_SND_MPU401=y
+
+#
+# PCI devices
+#
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALI5451 is not set
+CONFIG_SND_ATIIXP=y
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+CONFIG_SND_FM801=y
+CONFIG_SND_FM801_TEA575X=y
+# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_TRIDENT is not set
+# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
+# CONFIG_SND_VX222 is not set
+# CONFIG_SND_YMFPCI is not set
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+
+#
+# Open Sound System
+#
+CONFIG_SOUND_PRIME=y
+# CONFIG_OBSOLETE_OSS_DRIVER is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_BANDWIDTH=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=y
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+CONFIG_USB_HIDDEV=y
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_ET61X251 is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_PWC is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=y
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=y
+CONFIG_XFS_EXPORT=y
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_SECURITY is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=y
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=y
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMB_NLS_REMOTE="cp437"
+CONFIG_CIFS=y
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=y
+CONFIG_NLS_CODEPAGE_775=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_CODEPAGE_857=y
+CONFIG_NLS_CODEPAGE_860=y
+CONFIG_NLS_CODEPAGE_861=y
+CONFIG_NLS_CODEPAGE_862=y
+CONFIG_NLS_CODEPAGE_863=y
+CONFIG_NLS_CODEPAGE_864=y
+CONFIG_NLS_CODEPAGE_865=y
+CONFIG_NLS_CODEPAGE_866=y
+CONFIG_NLS_CODEPAGE_869=y
+CONFIG_NLS_CODEPAGE_936=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+CONFIG_NLS_CODEPAGE_949=y
+CONFIG_NLS_CODEPAGE_874=y
+CONFIG_NLS_ISO8859_8=y
+# CONFIG_NLS_CODEPAGE_1250 is not set
+CONFIG_NLS_CODEPAGE_1251=y
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_ISO8859_3=y
+CONFIG_NLS_ISO8859_4=y
+CONFIG_NLS_ISO8859_5=y
+CONFIG_NLS_ISO8859_6=y
+CONFIG_NLS_ISO8859_7=y
+CONFIG_NLS_ISO8859_9=y
+CONFIG_NLS_ISO8859_13=y
+CONFIG_NLS_ISO8859_14=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_KOI8_R=y
+CONFIG_NLS_KOI8_U=y
+CONFIG_NLS_UTF8=y
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_PENDING_IRQ=y
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+# CONFIG_KPROBES is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=20
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_IA64_GRANULE_16MB=y
+# CONFIG_IA64_GRANULE_64MB is not set
+CONFIG_IA64_PRINT_HAZARDS=y
+# CONFIG_DISABLE_VHPT is not set
+# CONFIG_IA64_DEBUG_CMPXCHG is not set
+# CONFIG_IA64_DEBUG_IRQ is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/include/console.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/include/console.h Tue Mar 28 08:54:58 2006 -0700
@@ -0,0 +1,49 @@
+/*
+ ****************************************************************************
+ * (C) 2006 - Grzegorz Milos - Cambridge University
+ ****************************************************************************
+ *
+ * File: console.h
+ * Author: Grzegorz Milos
+ * Changes:
+ *
+ * Date: Mar 2006
+ *
+ * Environment: Xen Minimal OS
+ * Description: Console interface.
+ *
+ * Handles console I/O. Defines printk.
+ *
+ ****************************************************************************
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (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 _LIB_CONSOLE_H_
+#define _LIB_CONSOLE_H_
+
+#include<traps.h>
+
+void printk(const char *fmt, ...);
+void xprintk(const char *fmt, ...);
+
+void xencons_rx(char *buf, unsigned len, struct pt_regs *regs);
+void xencons_tx(void);
+
+void init_console(void);
+
+#endif /* _LIB_CONSOLE_H_ */
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/xenbus/xenbus.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/xenbus/xenbus.c Tue Mar 28 08:54:58 2006 -0700
@@ -0,0 +1,387 @@
+/*
+ ****************************************************************************
+ * (C) 2006 - Cambridge University
+ ****************************************************************************
+ *
+ * File: mm.c
+ * Author: Steven Smith (sos22@xxxxxxxxx)
+ * Changes: Grzegorz Milos (gm281@xxxxxxxxx)
+ *
+ * Date: Mar 2006, chages Aug 2005
+ *
+ * Environment: Xen Minimal OS
+ * Description: Minimal implementation of xenbus
+ *
+ ****************************************************************************
+ **/
+#include <os.h>
+#include <mm.h>
+#include <traps.h>
+#include <lib.h>
+#include <xenbus.h>
+#include <events.h>
+#include <errno.h>
+#include <sched.h>
+#include <wait.h>
+#include <xen/io/xs_wire.h>
+#include <spinlock.h>
+#include <xmalloc.h>
+
+#define BUG_ON(x) do { \
+ if (x) {printk("BUG at %s:%d\n", __FILE__, __LINE__); BUG(); } \
+} while (0)
+
+#define min(x,y) ({ \
+ typeof(x) tmpx = (x); \
+ typeof(y) tmpy = (y); \
+ tmpx < tmpy ? tmpx : tmpy; \
+ })
+
+#ifdef XENBUS_DEBUG
+#define DEBUG(_f, _a...) \
+ printk("MINI_OS(file=xenbus.c, line=%d) " _f , __LINE__, ## _a)
+#else
+#define DEBUG(_f, _a...) ((void)0)
+#endif
+
+
+static struct xenstore_domain_interface *xenstore_buf;
+static DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
+struct xenbus_req_info
+{
+ int in_use:1;
+ struct wait_queue_head waitq;
+ void *reply;
+};
+
+#define NR_REQS 32
+static struct xenbus_req_info req_info[NR_REQS];
+
+static void memcpy_from_ring(const void *Ring,
+ void *Dest,
+ int off,
+ int len)
+{
+ int c1, c2;
+ const char *ring = Ring;
+ char *dest = Dest;
+ c1 = min(len, XENSTORE_RING_SIZE - off);
+ c2 = len - c1;
+ memcpy(dest, ring + off, c1);
+ memcpy(dest + c1, ring, c2);
+}
+
+static void xenbus_thread_func(void *ign)
+{
+ struct xsd_sockmsg msg;
+ unsigned prod;
+
+ for (;;)
+ {
+ wait_event(xb_waitq, prod != xenstore_buf->rsp_prod);
+ while (1)
+ {
+ prod = xenstore_buf->rsp_prod;
+ DEBUG("Rsp_cons %d, rsp_prod %d.\n", xenstore_buf->rsp_cons,
+ xenstore_buf->rsp_prod);
+ if (xenstore_buf->rsp_prod - xenstore_buf->rsp_cons < sizeof(msg))
+ break;
+ rmb();
+ memcpy_from_ring(xenstore_buf->rsp,
+ &msg,
+ MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
+ sizeof(msg));
+ DEBUG("Msg len %d, %d avail, id %d.\n",
+ msg.len + sizeof(msg),
+ xenstore_buf->rsp_prod - xenstore_buf->rsp_cons,
+ msg.req_id);
+ if (xenstore_buf->rsp_prod - xenstore_buf->rsp_cons <
+ sizeof(msg) + msg.len)
+ break;
+
+ DEBUG("Message is good.\n");
+ req_info[msg.req_id].reply = malloc(sizeof(msg) + msg.len);
+ memcpy_from_ring(xenstore_buf->rsp,
+ req_info[msg.req_id].reply,
+ MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
+ msg.len + sizeof(msg));
+ wake_up(&req_info[msg.req_id].waitq);
+ xenstore_buf->rsp_cons += msg.len + sizeof(msg);
+ }
+ }
+}
+
+static void xenbus_evtchn_handler(int port, struct pt_regs *regs)
+{
+ wake_up(&xb_waitq);
+}
+
+static int nr_live_reqs;
+static spinlock_t req_lock = SPIN_LOCK_UNLOCKED;
+static DECLARE_WAIT_QUEUE_HEAD(req_wq);
+
+/* Release a xenbus identifier */
+static void release_xenbus_id(int id)
+{
+ BUG_ON(!req_info[id].in_use);
+ spin_lock(&req_lock);
+ nr_live_reqs--;
+ if (nr_live_reqs == NR_REQS - 1)
+ wake_up(&req_wq);
+ spin_unlock(&req_lock);
+}
+
+/* Allocate an identifier for a xenbus request. Blocks if none are
+ available. */
+static int allocate_xenbus_id(void)
+{
+ static int probe;
+ int o_probe;
+
+ while (1)
+ {
+ spin_lock(&req_lock);
+ if (nr_live_reqs < NR_REQS)
+ break;
+ spin_unlock(&req_lock);
+ wait_event(req_wq, (nr_live_reqs < NR_REQS));
+ }
+
+ o_probe = probe;
+ for (;;)
+ {
+ if (!req_info[o_probe].in_use)
+ break;
+ o_probe = (o_probe + 1) % NR_REQS;
+ BUG_ON(o_probe == probe);
+ }
+ nr_live_reqs++;
+ req_info[o_probe].in_use = 1;
+ probe = o_probe + 1;
+ spin_unlock(&req_lock);
+ init_waitqueue_head(&req_info[o_probe].waitq);
+ return o_probe;
+}
+
+/* Initialise xenbus. */
+void init_xenbus(void)
+{
+ int err;
+ DEBUG("init_xenbus called.\n");
+ xenstore_buf = mfn_to_virt(start_info.store_mfn);
+ create_thread("xenstore", xenbus_thread_func, NULL);
+ DEBUG("buf at %p.\n", xenstore_buf);
+ err = bind_evtchn(start_info.store_evtchn,
+ xenbus_evtchn_handler);
+ DEBUG("xenbus on irq %d\n", err);
+}
+
+struct write_req {
+ const void *data;
+ unsigned len;
+};
+
+/* Send data to xenbus. This can block. All of the requests are seen
+ by xenbus as if sent atomically. The header is added
+ automatically, using type %type, req_id %req_id, and trans_id
+ %trans_id. */
+static void xb_write(int type, int req_id, int trans_id,
+ const struct write_req *req, int nr_reqs)
+{
+ XENSTORE_RING_IDX prod;
+ int r;
+ int len = 0;
+ const struct write_req *cur_req;
+ int req_off;
+ int total_off;
+ int this_chunk;
+ struct xsd_sockmsg m = {.type = type, .req_id = req_id,
+ .tx_id = trans_id };
+ struct write_req header_req = { &m, sizeof(m) };
+
+ for (r = 0; r < nr_reqs; r++)
+ len += req[r].len;
+ m.len = len;
+ len += sizeof(m);
+
+ cur_req = &header_req;
+
+ BUG_ON(len > XENSTORE_RING_SIZE);
+ /* Wait for the ring to drain to the point where we can send the
+ message. */
+ prod = xenstore_buf->req_prod;
+ if (prod + len - xenstore_buf->req_cons > XENSTORE_RING_SIZE)
+ {
+ /* Wait for there to be space on the ring */
+ DEBUG("prod %d, len %d, cons %d, size %d; waiting.\n",
+ prod, len, xenstore_buf->req_cons, XENSTORE_RING_SIZE);
+ wait_event(xb_waitq,
+ xenstore_buf->req_prod + len - xenstore_buf->req_cons <=
+ XENSTORE_RING_SIZE);
+ DEBUG("Back from wait.\n");
+ prod = xenstore_buf->req_prod;
+ }
+
+ /* We're now guaranteed to be able to send the message without
+ overflowing the ring. Do so. */
+ total_off = 0;
+ req_off = 0;
+ while (total_off < len)
+ {
+ this_chunk = min(cur_req->len - req_off,
+ XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod));
+ memcpy((char *)xenstore_buf->req + MASK_XENSTORE_IDX(prod),
+ (char *)cur_req->data + req_off, this_chunk);
+ prod += this_chunk;
+ req_off += this_chunk;
+ total_off += this_chunk;
+ if (req_off == cur_req->len)
+ {
+ req_off = 0;
+ if (cur_req == &header_req)
+ cur_req = req;
+ else
+ cur_req++;
+ }
+ }
+
+ DEBUG("Complete main loop of xb_write.\n");
+ BUG_ON(req_off != 0);
+ BUG_ON(total_off != len);
+ BUG_ON(prod > xenstore_buf->req_cons + XENSTORE_RING_SIZE);
+
+ /* Remote must see entire message before updating indexes */
+ wmb();
+
+ xenstore_buf->req_prod += len;
+
+ /* Send evtchn to notify remote */
+ notify_remote_via_evtchn(start_info.store_evtchn);
+}
+
+/* Send a mesasge to xenbus, in the same fashion as xb_write, and
+ block waiting for a reply. The reply is malloced and should be
+ freed by the caller. */
+static void *xenbus_msg_reply(int type,
+ int trans,
+ struct write_req *io,
+ int nr_reqs)
+{
+ int id;
+ DEFINE_WAIT(w);
+ void *rep;
+ struct xsd_sockmsg *repmsg;
+
+ id = allocate_xenbus_id();
+ add_waiter(w, req_info[id].waitq);
+
+ xb_write(type, id, trans, io, nr_reqs);
+
+ schedule();
+ wake(current);
+
+ rep = req_info[id].reply;
+ repmsg = rep;
+ BUG_ON(repmsg->req_id != id);
+ release_xenbus_id(id);
+
+ return rep;
+}
+
+/* Send a debug message to xenbus. Can block. */
+static void xenbus_debug_msg(const char *msg)
+{
+ int len = strlen(msg);
+ struct write_req req[] = {
+ { "print", sizeof("print") },
+ { msg, len },
+ { "", 1 }};
+ void *reply;
+ struct xsd_sockmsg *repmsg;
+
+ reply = xenbus_msg_reply(XS_DEBUG, 0, req, 3);
+ repmsg = reply;
+ DEBUG("Got a reply, type %d, id %d, len %d.\n",
+ repmsg->type, repmsg->req_id, repmsg->len);
+}
+
+/* List the contents of a directory. Returns a malloc()ed array of
+ pointers to malloc()ed strings. The array is NULL terminated. May
+ block. */
+static char **xenbus_ls(const char *pre)
+{
+ void *reply;
+ struct xsd_sockmsg *repmsg;
+ struct write_req req[] = { { pre, strlen(pre)+1 } };
+ int nr_elems, x, i;
+ char **res;
+
+ repmsg = xenbus_msg_reply(XS_DIRECTORY, 0, req, 1);
+ reply = repmsg + 1;
+ for (x = nr_elems = 0; x < repmsg->len; x++)
+ nr_elems += (((char *)reply)[x] == 0);
+ res = malloc(sizeof(res[0]) * (nr_elems + 1));
+ for (x = i = 0; i < nr_elems; i++) {
+ int l = strlen((char *)reply + x);
+ res[i] = malloc(l + 1);
+ memcpy(res[i], (char *)reply + x, l + 1);
+ x += l + 1;
+ }
+ res[i] = NULL;
+ free(repmsg);
+ return res;
+}
+
+static char *xenbus_read(const char *path)
+{
+ struct write_req req[] = { {path, strlen(path) + 1}};
+ struct xsd_sockmsg *rep;
+ char *res;
+ rep = xenbus_msg_reply(XS_READ, 0, req, 1);
+ res = malloc(rep->len + 1);
+ memcpy(res, rep + 1, rep->len);
+ res[rep->len] = 0;
+ free(rep);
+ return res;
+}
+
+static void do_ls_test(const char *pre)
+{
+ char **dirs;
+ int x;
+
+ DEBUG("ls %s...\n", pre);
+ dirs = xenbus_ls(pre);
+ for (x = 0; dirs[x]; x++)
+ {
+ DEBUG("ls %s[%d] -> %s\n", pre, x, dirs[x]);
+ free(dirs[x]);
+ }
+ free(dirs);
+}
+
+static void do_read_test(const char *path)
+{
+ char *res;
+ DEBUG("Read %s...\n", path);
+ res = xenbus_read(path);
+ DEBUG("Read %s -> %s.\n", path, res);
+ free(res);
+}
+
+/* Simple testing thing */
+void test_xenbus(void)
+{
+ DEBUG("Doing xenbus test.\n");
+ xenbus_debug_msg("Testing xenbus...\n");
+
+ DEBUG("Doing ls test.\n");
+ do_ls_test("device");
+ do_ls_test("device/vif");
+ do_ls_test("device/vif/0");
+
+ DEBUG("Doing read test.\n");
+ do_read_test("device/vif/0/mac");
+ do_read_test("device/vif/0/backend");
+ printk("Xenbus initialised.\n");
+}
diff -r 7e3cbc409676 -r d75a6cc5e68a
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/msr.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/msr.h Tue Mar
28 08:54:58 2006 -0700
@@ -0,0 +1,399 @@
+#ifndef X86_64_MSR_H
+#define X86_64_MSR_H 1
+
+#ifndef __ASSEMBLY__
+/*
+ * Access to machine-specific registers (available on 586 and better only)
+ * Note: the rd* operations modify the parameters directly (without using
+ * pointer indirection), this allows gcc to optimize better
+ */
+
+#define rdmsr(msr,val1,val2) \
+ __asm__ __volatile__("rdmsr" \
+ : "=a" (val1), "=d" (val2) \
+ : "c" (msr))
+
+
+#define rdmsrl(msr,val) do { unsigned long a__,b__; \
+ __asm__ __volatile__("rdmsr" \
+ : "=a" (a__), "=d" (b__) \
+ : "c" (msr)); \
+ val = a__ | (b__<<32); \
+} while(0)
+
+#define wrmsr(msr,val1,val2) \
+ __asm__ __volatile__("wrmsr" \
+ : /* no outputs */ \
+ : "c" (msr), "a" (val1), "d" (val2))
+
+#define wrmsrl(msr,val) wrmsr(msr,(__u32)((__u64)(val)),((__u64)(val))>>32)
+
+/* wrmsr with exception handling */
+#define wrmsr_safe(msr,a,b) ({ int ret__; \
+ asm volatile("2: wrmsr ; xorl %0,%0\n" \
+ "1:\n\t" \
+ ".section .fixup,\"ax\"\n\t" \
+ "3: movl %4,%0 ; jmp 1b\n\t" \
+ ".previous\n\t" \
+ ".section __ex_table,\"a\"\n" \
+ " .align 8\n\t" \
+ " .quad 2b,3b\n\t" \
+ ".previous" \
+ : "=a" (ret__) \
+ : "c" (msr), "0" (a), "d" (b), "i" (-EFAULT)); \
+ ret__; })
+
+#define checking_wrmsrl(msr,val) wrmsr_safe(msr,(u32)(val),(u32)((val)>>32))
+
+#define rdmsr_safe(msr,a,b) \
+ ({ int ret__; \
+ asm volatile ("1: rdmsr\n" \
+ "2:\n" \
+ ".section .fixup,\"ax\"\n" \
+ "3: movl %4,%0\n" \
+ " jmp 2b\n" \
+ ".previous\n" \
+ ".section __ex_table,\"a\"\n" \
+ " .align 8\n" \
+ " .quad 1b,3b\n" \
+ ".previous":"=&bDS" (ret__), "=a"(*(a)), "=d"(*(b))\
+ :"c"(msr), "i"(-EIO), "0"(0)); \
+ ret__; })
+
+#define rdtsc(low,high) \
+ __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
+
+#define rdtscl(low) \
+ __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx")
+
+#define rdtscll(val) do { \
+ unsigned int __a,__d; \
+ asm volatile("rdtsc" : "=a" (__a), "=d" (__d)); \
+ (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \
+} while(0)
+
+#define write_tsc(val1,val2) wrmsr(0x10, val1, val2)
+
+#define rdpmc(counter,low,high) \
+ __asm__ __volatile__("rdpmc" \
+ : "=a" (low), "=d" (high) \
+ : "c" (counter))
+
+static inline void cpuid(int op, unsigned int *eax, unsigned int *ebx,
+ unsigned int *ecx, unsigned int *edx)
+{
+ __asm__(XEN_CPUID
+ : "=a" (*eax),
+ "=b" (*ebx),
+ "=c" (*ecx),
+ "=d" (*edx)
+ : "0" (op));
+}
+
+/* Some CPUID calls want 'count' to be placed in ecx */
+static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx,
+ int *edx)
+{
+ __asm__(XEN_CPUID
+ : "=a" (*eax),
+ "=b" (*ebx),
+ "=c" (*ecx),
+ "=d" (*edx)
+ : "0" (op), "c" (count));
+}
+
+/*
+ * CPUID functions returning a single datum
+ */
+static inline unsigned int cpuid_eax(unsigned int op)
+{
+ unsigned int eax;
+
+ __asm__(XEN_CPUID
+ : "=a" (eax)
+ : "0" (op)
+ : "bx", "cx", "dx");
+ return eax;
+}
+static inline unsigned int cpuid_ebx(unsigned int op)
+{
+ unsigned int eax, ebx;
+
+ __asm__(XEN_CPUID
+ : "=a" (eax), "=b" (ebx)
+ : "0" (op)
+ : "cx", "dx" );
+ return ebx;
+}
+static inline unsigned int cpuid_ecx(unsigned int op)
+{
+ unsigned int eax, ecx;
+
+ __asm__(XEN_CPUID
+ : "=a" (eax), "=c" (ecx)
+ : "0" (op)
+ : "bx", "dx" );
+ return ecx;
+}
+static inline unsigned int cpuid_edx(unsigned int op)
+{
+ unsigned int eax, edx;
+
+ __asm__(XEN_CPUID
+ : "=a" (eax), "=d" (edx)
+ : "0" (op)
+ : "bx", "cx");
+ return edx;
+}
+
+#define MSR_IA32_UCODE_WRITE 0x79
+#define MSR_IA32_UCODE_REV 0x8b
+
+
+#endif
+
+/* AMD/K8 specific MSRs */
+#define MSR_EFER 0xc0000080 /* extended feature register */
+#define MSR_STAR 0xc0000081 /* legacy mode SYSCALL target */
+#define MSR_LSTAR 0xc0000082 /* long mode SYSCALL target */
+#define MSR_CSTAR 0xc0000083 /* compatibility mode SYSCALL target */
+#define MSR_SYSCALL_MASK 0xc0000084 /* EFLAGS mask for syscall */
+#define MSR_FS_BASE 0xc0000100 /* 64bit GS base */
+#define MSR_GS_BASE 0xc0000101 /* 64bit FS base */
+#define MSR_KERNEL_GS_BASE 0xc0000102 /* SwapGS GS shadow (or USER_GS from
kernel) */
+/* EFER bits: */
+#define _EFER_SCE 0 /* SYSCALL/SYSRET */
+#define _EFER_LME 8 /* Long mode enable */
+#define _EFER_LMA 10 /* Long mode active (read-only) */
+#define _EFER_NX 11 /* No execute enable */
+
+#define EFER_SCE (1<<_EFER_SCE)
+#define EFER_LME (1<<_EFER_LME)
+#define EFER_LMA (1<<_EFER_LMA)
+#define EFER_NX (1<<_EFER_NX)
+
+/* Intel MSRs. Some also available on other CPUs */
+#define MSR_IA32_TSC 0x10
+#define MSR_IA32_PLATFORM_ID 0x17
+
+#define MSR_IA32_PERFCTR0 0xc1
+#define MSR_IA32_PERFCTR1 0xc2
+
+#define MSR_MTRRcap 0x0fe
+#define MSR_IA32_BBL_CR_CTL 0x119
+
+#define MSR_IA32_SYSENTER_CS 0x174
+#define MSR_IA32_SYSENTER_ESP 0x175
+#define MSR_IA32_SYSENTER_EIP 0x176
+
+#define MSR_IA32_MCG_CAP 0x179
+#define MSR_IA32_MCG_STATUS 0x17a
+#define MSR_IA32_MCG_CTL 0x17b
+
+#define MSR_IA32_EVNTSEL0 0x186
+#define MSR_IA32_EVNTSEL1 0x187
+
+#define MSR_IA32_DEBUGCTLMSR 0x1d9
+#define MSR_IA32_LASTBRANCHFROMIP 0x1db
+#define MSR_IA32_LASTBRANCHTOIP 0x1dc
+#define MSR_IA32_LASTINTFROMIP 0x1dd
+#define MSR_IA32_LASTINTTOIP 0x1de
+
+#define MSR_MTRRfix64K_00000 0x250
+#define MSR_MTRRfix16K_80000 0x258
+#define MSR_MTRRfix16K_A0000 0x259
+#define MSR_MTRRfix4K_C0000 0x268
+#define MSR_MTRRfix4K_C8000 0x269
+#define MSR_MTRRfix4K_D0000 0x26a
+#define MSR_MTRRfix4K_D8000 0x26b
+#define MSR_MTRRfix4K_E0000 0x26c
+#define MSR_MTRRfix4K_E8000 0x26d
+#define MSR_MTRRfix4K_F0000 0x26e
+#define MSR_MTRRfix4K_F8000 0x26f
+#define MSR_MTRRdefType 0x2ff
+
+#define MSR_IA32_MC0_CTL 0x400
+#define MSR_IA32_MC0_STATUS 0x401
+#define MSR_IA32_MC0_ADDR 0x402
+#define MSR_IA32_MC0_MISC 0x403
+
+#define MSR_P6_PERFCTR0 0xc1
+#define MSR_P6_PERFCTR1 0xc2
+#define MSR_P6_EVNTSEL0 0x186
+#define MSR_P6_EVNTSEL1 0x187
+
+/* K7/K8 MSRs. Not complete. See the architecture manual for a more complete
list. */
+#define MSR_K7_EVNTSEL0 0xC0010000
+#define MSR_K7_PERFCTR0 0xC0010004
+#define MSR_K7_EVNTSEL1 0xC0010001
+#define MSR_K7_PERFCTR1 0xC0010005
+#define MSR_K7_EVNTSEL2 0xC0010002
+#define MSR_K7_PERFCTR2 0xC0010006
+#define MSR_K7_EVNTSEL3 0xC0010003
+#define MSR_K7_PERFCTR3 0xC0010007
+#define MSR_K8_TOP_MEM1 0xC001001A
+#define MSR_K8_TOP_MEM2 0xC001001D
+#define MSR_K8_SYSCFG 0xC0010010
+#define MSR_K8_HWCR 0xC0010015
+
+/* K6 MSRs */
+#define MSR_K6_EFER 0xC0000080
+#define MSR_K6_STAR 0xC0000081
+#define MSR_K6_WHCR 0xC0000082
+#define MSR_K6_UWCCR 0xC0000085
+#define MSR_K6_PSOR 0xC0000087
+#define MSR_K6_PFIR 0xC0000088
+
+/* Centaur-Hauls/IDT defined MSRs. */
+#define MSR_IDT_FCR1 0x107
+#define MSR_IDT_FCR2 0x108
+#define MSR_IDT_FCR3 0x109
+#define MSR_IDT_FCR4 0x10a
+
+#define MSR_IDT_MCR0 0x110
+#define MSR_IDT_MCR1 0x111
+#define MSR_IDT_MCR2 0x112
+#define MSR_IDT_MCR3 0x113
+#define MSR_IDT_MCR4 0x114
+#define MSR_IDT_MCR5 0x115
+#define MSR_IDT_MCR6 0x116
+#define MSR_IDT_MCR7 0x117
+#define MSR_IDT_MCR_CTRL 0x120
+
+/* VIA Cyrix defined MSRs*/
+#define MSR_VIA_FCR 0x1107
+#define MSR_VIA_LONGHAUL 0x110a
+#define MSR_VIA_RNG 0x110b
+#define MSR_VIA_BCR2 0x1147
+
+/* Intel defined MSRs. */
+#define MSR_IA32_P5_MC_ADDR 0
+#define MSR_IA32_P5_MC_TYPE 1
+#define MSR_IA32_PLATFORM_ID 0x17
+#define MSR_IA32_EBL_CR_POWERON 0x2a
+
+#define MSR_IA32_APICBASE 0x1b
+#define MSR_IA32_APICBASE_BSP (1<<8)
+#define MSR_IA32_APICBASE_ENABLE (1<<11)
+#define MSR_IA32_APICBASE_BASE (0xfffff<<12)
+
+/* P4/Xeon+ specific */
+#define MSR_IA32_MCG_EAX 0x180
+#define MSR_IA32_MCG_EBX 0x181
+#define MSR_IA32_MCG_ECX 0x182
+#define MSR_IA32_MCG_EDX 0x183
+#define MSR_IA32_MCG_ESI 0x184
+#define MSR_IA32_MCG_EDI 0x185
+#define MSR_IA32_MCG_EBP 0x186
+#define MSR_IA32_MCG_ESP 0x187
+#define MSR_IA32_MCG_EFLAGS 0x188
+#define MSR_IA32_MCG_EIP 0x189
+#define MSR_IA32_MCG_RESERVED 0x18A
+
+#define MSR_P6_EVNTSEL0 0x186
+#define MSR_P6_EVNTSEL1 0x187
+
+#define MSR_IA32_PERF_STATUS 0x198
+#define MSR_IA32_PERF_CTL 0x199
+
+#define MSR_IA32_THERM_CONTROL 0x19a
+#define MSR_IA32_THERM_INTERRUPT 0x19b
+#define MSR_IA32_THERM_STATUS 0x19c
+#define MSR_IA32_MISC_ENABLE 0x1a0
+
+#define MSR_IA32_DEBUGCTLMSR 0x1d9
+#define MSR_IA32_LASTBRANCHFROMIP 0x1db
+#define MSR_IA32_LASTBRANCHTOIP 0x1dc
+#define MSR_IA32_LASTINTFROMIP 0x1dd
+#define MSR_IA32_LASTINTTOIP 0x1de
+
+#define MSR_IA32_MC0_CTL 0x400
+#define MSR_IA32_MC0_STATUS 0x401
+#define MSR_IA32_MC0_ADDR 0x402
+#define MSR_IA32_MC0_MISC 0x403
+
+/* Pentium IV performance counter MSRs */
+#define MSR_P4_BPU_PERFCTR0 0x300
+#define MSR_P4_BPU_PERFCTR1 0x301
+#define MSR_P4_BPU_PERFCTR2 0x302
+#define MSR_P4_BPU_PERFCTR3 0x303
+#define MSR_P4_MS_PERFCTR0 0x304
+#define MSR_P4_MS_PERFCTR1 0x305
+#define MSR_P4_MS_PERFCTR2 0x306
+#define MSR_P4_MS_PERFCTR3 0x307
+#define MSR_P4_FLAME_PERFCTR0 0x308
+#define MSR_P4_FLAME_PERFCTR1 0x309
+#define MSR_P4_FLAME_PERFCTR2 0x30a
+#define MSR_P4_FLAME_PERFCTR3 0x30b
+#define MSR_P4_IQ_PERFCTR0 0x30c
+#define MSR_P4_IQ_PERFCTR1 0x30d
+#define MSR_P4_IQ_PERFCTR2 0x30e
+#define MSR_P4_IQ_PERFCTR3 0x30f
+#define MSR_P4_IQ_PERFCTR4 0x310
+#define MSR_P4_IQ_PERFCTR5 0x311
+#define MSR_P4_BPU_CCCR0 0x360
+#define MSR_P4_BPU_CCCR1 0x361
+#define MSR_P4_BPU_CCCR2 0x362
+#define MSR_P4_BPU_CCCR3 0x363
+#define MSR_P4_MS_CCCR0 0x364
+#define MSR_P4_MS_CCCR1 0x365
+#define MSR_P4_MS_CCCR2 0x366
+#define MSR_P4_MS_CCCR3 0x367
+#define MSR_P4_FLAME_CCCR0 0x368
+#define MSR_P4_FLAME_CCCR1 0x369
+#define MSR_P4_FLAME_CCCR2 0x36a
+#define MSR_P4_FLAME_CCCR3 0x36b
+#define MSR_P4_IQ_CCCR0 0x36c
+#define MSR_P4_IQ_CCCR1 0x36d
+#define MSR_P4_IQ_CCCR2 0x36e
+#define MSR_P4_IQ_CCCR3 0x36f
+#define MSR_P4_IQ_CCCR4 0x370
+#define MSR_P4_IQ_CCCR5 0x371
+#define MSR_P4_ALF_ESCR0 0x3ca
+#define MSR_P4_ALF_ESCR1 0x3cb
+#define MSR_P4_BPU_ESCR0 0x3b2
+#define MSR_P4_BPU_ESCR1 0x3b3
+#define MSR_P4_BSU_ESCR0 0x3a0
+#define MSR_P4_BSU_ESCR1 0x3a1
+#define MSR_P4_CRU_ESCR0 0x3b8
+#define MSR_P4_CRU_ESCR1 0x3b9
+#define MSR_P4_CRU_ESCR2 0x3cc
+#define MSR_P4_CRU_ESCR3 0x3cd
+#define MSR_P4_CRU_ESCR4 0x3e0
+#define MSR_P4_CRU_ESCR5 0x3e1
+#define MSR_P4_DAC_ESCR0 0x3a8
+#define MSR_P4_DAC_ESCR1 0x3a9
+#define MSR_P4_FIRM_ESCR0 0x3a4
+#define MSR_P4_FIRM_ESCR1 0x3a5
+#define MSR_P4_FLAME_ESCR0 0x3a6
+#define MSR_P4_FLAME_ESCR1 0x3a7
+#define MSR_P4_FSB_ESCR0 0x3a2
+#define MSR_P4_FSB_ESCR1 0x3a3
+#define MSR_P4_IQ_ESCR0 0x3ba
+#define MSR_P4_IQ_ESCR1 0x3bb
+#define MSR_P4_IS_ESCR0 0x3b4
+#define MSR_P4_IS_ESCR1 0x3b5
+#define MSR_P4_ITLB_ESCR0 0x3b6
+#define MSR_P4_ITLB_ESCR1 0x3b7
+#define MSR_P4_IX_ESCR0 0x3c8
+#define MSR_P4_IX_ESCR1 0x3c9
+#define MSR_P4_MOB_ESCR0 0x3aa
+#define MSR_P4_MOB_ESCR1 0x3ab
+#define MSR_P4_MS_ESCR0 0x3c0
+#define MSR_P4_MS_ESCR1 0x3c1
+#define MSR_P4_PMH_ESCR0 0x3ac
+#define MSR_P4_PMH_ESCR1 0x3ad
+#define MSR_P4_RAT_ESCR0 0x3bc
+#define MSR_P4_RAT_ESCR1 0x3bd
+#define MSR_P4_SAAT_ESCR0 0x3ae
+#define MSR_P4_SAAT_ESCR1 0x3af
+#define MSR_P4_SSU_ESCR0 0x3be
+#define MSR_P4_SSU_ESCR1 0x3bf /* guess: not defined in
manual */
+#define MSR_P4_TBPU_ESCR0 0x3c2
+#define MSR_P4_TBPU_ESCR1 0x3c3
+#define MSR_P4_TC_ESCR0 0x3c4
+#define MSR_P4_TC_ESCR1 0x3c5
+#define MSR_P4_U2L_ESCR0 0x3b0
+#define MSR_P4_U2L_ESCR1 0x3b1
+
+#endif
diff -r 7e3cbc409676 -r d75a6cc5e68a patches/linux-2.6.16/device_bind.patch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.16/device_bind.patch Tue Mar 28 08:54:58 2006 -0700
@@ -0,0 +1,14 @@
+--- linux-2.6.16/drivers/base/bus.c 2006-03-16 10:50:20.000000000 -0500
++++ linux-2.6.16/drivers/base/bus.c 2006-03-16 11:02:08.000000000 -0500
+@@ -188,6 +188,11 @@ static ssize_t driver_bind(struct device
+ up(&dev->sem);
+ if (dev->parent)
+ up(&dev->parent->sem);
++
++ if (err > 0) /* success */
++ err = count;
++ else if (err == 0) /* driver didn't accept device */
++ err = -ENODEV;
+ }
+ put_device(dev);
+ put_bus(bus);
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/python/xen/util/xmlrpclib2.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/util/xmlrpclib2.py Tue Mar 28 08:54:58 2006 -0700
@@ -0,0 +1,111 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# 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
+#============================================================================
+# Copyright (C) 2006 Anthony Liguori <aliguori@xxxxxxxxxx>
+# Copyright (C) 2006 XenSource Ltd.
+#============================================================================
+
+"""
+An enhanced XML-RPC client/server interface for Python.
+"""
+
+from httplib import HTTPConnection, HTTP
+from xmlrpclib import Transport
+from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
+import xmlrpclib, socket, os, traceback
+import SocketServer
+
+# A new ServerProxy that also supports httpu urls. An http URL comes in the
+# form:
+#
+# httpu:///absolute/path/to/socket.sock
+#
+# It assumes that the RPC handler is /RPC2. This probably needs to be improved
+
+class HTTPUnixConnection(HTTPConnection):
+ def connect(self):
+ self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ self.sock.connect(self.host)
+
+class HTTPUnix(HTTP):
+ _connection_class = HTTPUnixConnection
+
+class UnixTransport(Transport):
+ def request(self, host, handler, request_body, verbose=0):
+ self.__handler = handler
+ return Transport.request(self, host, '/RPC2', request_body, verbose)
+ def make_connection(self, host):
+ return HTTPUnix(self.__handler)
+
+class ServerProxy(xmlrpclib.ServerProxy):
+ def __init__(self, uri, transport=None, encoding=None, verbose=0,
+ allow_none=1):
+ if transport == None:
+ (protocol, rest) = uri.split(':', 1)
+ if protocol == 'httpu':
+ uri = 'http:' + rest
+ transport = UnixTransport()
+ xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
+ verbose, allow_none)
+
+# This is a base XML-RPC server for TCP. It sets allow_reuse_address to
+# true, and has an improved marshaller that serializes unknown exceptions
+# with full traceback information.
+
+class TCPXMLRPCServer(SocketServer.ThreadingMixIn, SimpleXMLRPCServer):
+ allow_reuse_address = True
+
+ def _marshaled_dispatch(self, data, dispatch_method = None):
+ params, method = xmlrpclib.loads(data)
+ try:
+ if dispatch_method is not None:
+ response = dispatch_method(method, params)
+ else:
+ response = self._dispatch(method, params)
+
+ response = (response,)
+ response = xmlrpclib.dumps(response,
+ methodresponse=1,
+ allow_none=1)
+ except xmlrpclib.Fault, fault:
+ response = xmlrpclib.dumps(fault)
+ except:
+ response = xmlrpclib.dumps(
+ xmlrpclib.Fault(1, traceback.format_exc())
+ )
+
+ return response
+
+# This is a XML-RPC server that sits on a Unix domain socket.
+# It implements proper support for allow_reuse_address by
+# unlink()'ing an existing socket.
+
+class UnixXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
+ def address_string(self):
+ try:
+ return SimpleXMLRPCRequestHandler.address_string(self)
+ except ValueError, e:
+ return self.client_address[:2]
+
+class UnixXMLRPCServer(TCPXMLRPCServer):
+ address_family = socket.AF_UNIX
+
+ def __init__(self, addr, logRequests):
+ if self.allow_reuse_address:
+ try:
+ os.unlink(addr)
+ except OSError, exc:
+ pass
+ TCPXMLRPCServer.__init__(self, addr, UnixXMLRPCRequestHandler,
+ logRequests)
diff -r 7e3cbc409676 -r d75a6cc5e68a
tools/python/xen/xend/server/XMLRPCServer.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/server/XMLRPCServer.py Tue Mar 28 08:54:58
2006 -0700
@@ -0,0 +1,113 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# 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
+#============================================================================
+# Copyright (C) 2006 Anthony Liguori <aliguori@xxxxxxxxxx>
+# Copyright (C) 2006 XenSource Ltd.
+#============================================================================
+
+import xmlrpclib
+
+from xen.xend import XendDomain, XendDomainInfo, XendNode, \
+ XendLogging, XendDmesg
+from xen.util.xmlrpclib2 import UnixXMLRPCServer, TCPXMLRPCServer
+
+from xen.xend.XendClient import XML_RPC_SOCKET, ERROR_INVALID_DOMAIN
+from xen.xend.XendError import *
+
+def lookup(domid):
+ info = XendDomain.instance().domain_lookup_by_name_or_id(domid)
+ if not info:
+ raise XendInvalidDomain(str(domid))
+ return info
+
+def dispatch(domid, fn, args):
+ info = lookup(domid)
+ return getattr(info, fn)(*args)
+
+def domain(domid):
+ info = lookup(domid)
+ return info.sxpr()
+
+def domains(detail=1):
+ if detail < 1:
+ return XendDomain.instance().list_names()
+ else:
+ domains = XendDomain.instance().list_sorted()
+ return map(lambda dom: dom.sxpr(), domains)
+
+def domain_create(config):
+ info = XendDomain.instance().domain_create(config)
+ return info.sxpr()
+
+def domain_restore(src):
+ info = XendDomain.instance().domain_restore(src)
+ return info.sxpr()
+
+def get_log():
+ f = open(XendLogging.getLogFilename(), 'r')
+ try:
+ return f.read()
+ finally:
+ f.close()
+
+methods = ['device_create', 'destroyDevice', 'getDeviceSxprs',
+ 'setMemoryTarget', 'setName', 'setVCpuCount', 'shutdown',
+ 'send_sysrq', 'getVCPUInfo', 'waitForDevices']
+
+exclude = ['domain_create', 'domain_restore']
+
+class XMLRPCServer:
+ def __init__(self, use_tcp=False):
+ self.ready = False
+ self.use_tcp = use_tcp
+
+ def run(self):
+ if self.use_tcp:
+ # bind to something fixed for now as we may eliminate
+ # tcp support completely.
+ self.server = TCPXMLRPCServer(("localhost", 8005),
logRequests=False)
+ else:
+ self.server = UnixXMLRPCServer(XML_RPC_SOCKET, False)
+
+ # Functions in XendDomainInfo
+ for name in methods:
+ fn = eval("lambda domid, *args: dispatch(domid, '%s', args)"%name)
+ self.server.register_function(fn, "xend.domain.%s" % name)
+
+ # Functions in XendDomain
+ inst = XendDomain.instance()
+ for name in dir(inst):
+ fn = getattr(inst, name)
+ if name.startswith("domain_") and callable(fn):
+ if name not in exclude:
+ self.server.register_function(fn, "xend.domain.%s" %
name[7:])
+
+ # Functions in XendNode and XendDmesg
+ for type, lst, n in [(XendNode, ['info', 'cpu_bvt_slice_set'], 'node'),
+ (XendDmesg, ['info', 'clear'], 'node.dmesg')]:
+ inst = type.instance()
+ for name in lst:
+ self.server.register_function(getattr(inst, name),
+ "xend.%s.%s" % (n, name))
+
+ # A few special cases
+ self.server.register_function(domain, 'xend.domain')
+ self.server.register_function(domains, 'xend.domains')
+ self.server.register_function(get_log, 'xend.node.log')
+ self.server.register_function(domain_create, 'xend.domain.create')
+ self.server.register_function(domain_restore, 'xend.domain.restore')
+
+ self.server.register_introspection_functions()
+ self.ready = True
+ self.server.serve_forever()
diff -r 7e3cbc409676 -r d75a6cc5e68a tools/xenstore/README
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xenstore/README Tue Mar 28 08:54:58 2006 -0700
@@ -0,0 +1,5 @@
+The following files are imported from the Samba project. We use the versions
+from Samba 3, the current stable branch.
+
+talloc.c: samba-trunk/source/lib/talloc.c r14291 2006-03-13 04:27:47 +0000
+talloc.h: samba-trunk/source/include/talloc.h r11986 2005-12-01 00:43:36 +0000
diff -r 7e3cbc409676 -r d75a6cc5e68a
tools/xm-test/ramdisk/README-XenSource-initrd-0.7-img
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xm-test/ramdisk/README-XenSource-initrd-0.7-img Tue Mar 28
08:54:58 2006 -0700
@@ -0,0 +1,42 @@
+XenSource xm-test 0.7 initrd.img
+================================
+
+http://xm-test.xensource.com/ramdisks/initrd-0.7.img is an initrd suitable for
+use with Xen's xm-test regression testing suite. It has been built and
+provided by XenSource, for the convenience of Xen users. xm-test initrds may
+be mixed across minor xm-test versions, but not across major versions; this
+initrd is suitable for all 0.7.x versions of xm-test (as shipped with Xen
+3.0.x).
+
+In order to use this initrd, run "./autogen; ./configure; make existing"
+inside the xm-test directory, and the initrd will be downloaded automatically.
+Alternatively, if you have already downloaded this file, place it into the
+xm-test/ramdisk directory and run the same command. In either case,
+runtest.sh can then be used as normal. See xm-test/README for more details.
+
+This initrd was built using the infrastructure provided by xm-test. It is a
+full guest operating system and filesystem, and as such includes a large
+number of pieces of software. The source code for the majority of these are
+included in full inside the file
+http://xm-test.xensource.com/ramdisks/initrd.0.7.img-buildroot.tar.bz2, or
+alongside this file. Copyright statements and licences are contained therein.
+The remaining source code is included in the Xen distribution, at
+http://www.xensource.com/xen/downloads/archives.html. The configurations used
+for BusyBox, uClibc, and Buildroot are available as
+http://xm-test.xensource.com/ramdisks/initrd-0.7-busybox-config,
+http://xm-test.xensource.com/ramdisks/initrd-0.7-uClibc-config, and
+http://xm-test.xensource.com/ramdisks/initrd-0.7-buildroot-config
+respectively, or alongside this file.
+
+XenSource and the Xen contributors are grateful to the authors of these
+software packages for their contributions to free and open-source software.
+
+
+Buildroot and BusyBox are Copyright (c) Erik Andersen <andersen@xxxxxxxxxxxx>.
+BusyBox is licensed under the GNU General Public License (GPL). A copy of
+this license is available in the file GPL-2,
+http://xm-test.xensource.com/ramdisks/GPL-2, or alongside this file.
+
+uClibc is licensed under the GNU Lesser General Public License (LGPL). A copy
+of this license is available in the file
+http://xm-test.xensource.com/ramdisks/LGPL-2, or alongside this file.
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/xenbus/Makefile
--- a/extras/mini-os/xenbus/Makefile Mon Mar 27 15:36:47 2006 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-all: xenstore.h xenbus_comms.o xenbus_xs.o xenbus_probe.o
-
-xenstore.h:
- [ -e xenstored.h ] || ln -sf ../../../tools/xenstore/xenstored.h
xenstored.h
-
-clean:
- #Taken care of by main Makefile
- #rm xenstored.h
- #rm *.o
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/xenbus/xenbus_comms.c
--- a/extras/mini-os/xenbus/xenbus_comms.c Mon Mar 27 15:36:47 2006 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,184 +0,0 @@
-/******************************************************************************
- * xenbus_comms.c
- *
- * Low level code to talks to Xen Store: ringbuffer and event channel.
- *
- * 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:
- *
- * 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.
- */
-#include <types.h>
-#include <wait.h>
-#include <mm.h>
-#include <hypervisor.h>
-#include <events.h>
-#include <os.h>
-#include <lib.h>
-#include <xenbus.h>
-#include "xenbus_comms.h"
-
-static int xenbus_irq;
-
-extern void xenbus_probe(void *);
-extern int xenstored_ready;
-
-DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
-
-static inline struct xenstore_domain_interface *xenstore_domain_interface(void)
-{
- return mfn_to_virt(start_info.store_mfn);
-}
-
-static void wake_waiting(int port, struct pt_regs *regs)
-{
- wake_up(&xb_waitq);
-}
-
-static int check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod)
-{
- return ((prod - cons) <= XENSTORE_RING_SIZE);
-}
-
-static void *get_output_chunk(XENSTORE_RING_IDX cons,
- XENSTORE_RING_IDX prod,
- char *buf, uint32_t *len)
-{
- *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod);
- if ((XENSTORE_RING_SIZE - (prod - cons)) < *len)
- *len = XENSTORE_RING_SIZE - (prod - cons);
- return buf + MASK_XENSTORE_IDX(prod);
-}
-
-static const void *get_input_chunk(XENSTORE_RING_IDX cons,
- XENSTORE_RING_IDX prod,
- const char *buf, uint32_t *len)
-{
- *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(cons);
- if ((prod - cons) < *len)
- *len = prod - cons;
- return buf + MASK_XENSTORE_IDX(cons);
-}
-
-int xb_write(const void *data, unsigned len)
-{
- struct xenstore_domain_interface *intf = xenstore_domain_interface();
- XENSTORE_RING_IDX cons, prod;
-
- while (len != 0) {
- void *dst;
- unsigned int avail;
-
- wait_event(xb_waitq, (intf->req_prod - intf->req_cons) !=
- XENSTORE_RING_SIZE);
-
- /* Read indexes, then verify. */
- cons = intf->req_cons;
- prod = intf->req_prod;
- mb();
- if (!check_indexes(cons, prod))
- return -EIO;
-
- dst = get_output_chunk(cons, prod, intf->req, &avail);
- if (avail == 0)
- continue;
- if (avail > len)
- avail = len;
-
- memcpy(dst, data, avail);
- data = (void*) ( (unsigned long)data + avail );
- len -= avail;
-
- /* Other side must not see new header until data is there. */
- wmb();
- intf->req_prod += avail;
-
- /* This implies mb() before other side sees interrupt. */
- notify_remote_via_evtchn(start_info.store_evtchn);
- }
-
- return 0;
-}
-
-int xb_read(void *data, unsigned len)
-{
- struct xenstore_domain_interface *intf = xenstore_domain_interface();
- XENSTORE_RING_IDX cons, prod;
-
- while (len != 0) {
- unsigned int avail;
- const char *src;
-
- wait_event(xb_waitq,
- intf->rsp_cons != intf->rsp_prod);
-
- /* Read indexes, then verify. */
- cons = intf->rsp_cons;
- prod = intf->rsp_prod;
- mb();
- if (!check_indexes(cons, prod))
- return -EIO;
-
- src = get_input_chunk(cons, prod, intf->rsp, &avail);
- if (avail == 0)
- continue;
- if (avail > len)
- avail = len;
-
- /* We must read header before we read data. */
- rmb();
-
- memcpy(data, src, avail);
- data = (void*) ( (unsigned long)data + avail );
- len -= avail;
-
- /* Other side must not see free space until we've copied out */
- mb();
- intf->rsp_cons += avail;
-
- printk("Finished read of %i bytes (%i to go)\n", avail, len);
-
- /* Implies mb(): they will see new header. */
- notify_remote_via_evtchn(start_info.store_evtchn);
- }
-
- return 0;
-}
-
-/* Set up interrupt handler off store event channel. */
-int xb_init_comms(void)
-{
- int err;
-
- if (xenbus_irq)
- unbind_evtchn(xenbus_irq);
-
- err = bind_evtchn(
- start_info.store_evtchn, wake_waiting);
- if (err <= 0) {
- printk("XENBUS request irq failed %i\n", err);
- return err;
- }
-
- xenbus_irq = err;
-
- return 0;
-}
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/xenbus/xenbus_comms.h
--- a/extras/mini-os/xenbus/xenbus_comms.h Mon Mar 27 15:36:47 2006 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Private include for xenbus communications.
- *
- * 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:
- *
- * 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_COMMS_H
-#define _XENBUS_COMMS_H
-
-int xs_init(void);
-int xb_init_comms(void);
-
-/* Low level routines. */
-int xb_write(const void *data, unsigned len);
-int xb_read(void *data, unsigned len);
-int xs_input_avail(void);
-extern struct wait_queue_head xb_waitq;
-
-#endif /* _XENBUS_COMMS_H */
diff -r 7e3cbc409676 -r d75a6cc5e68a extras/mini-os/xenbus/xenbus_xs.c
--- a/extras/mini-os/xenbus/xenbus_xs.c Mon Mar 27 15:36:47 2006 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,796 +0,0 @@
-/******************************************************************************
- * xenbus_xs.c
- *
- * This is the kernel equivalent of the "xs" library. We don't need everything
- * and we use xenbus_comms for communication.
- *
- * 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:
- *
- * 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.
- */
-#include <errno.h>
-#include <types.h>
-#include <list.h>
-#include <lib.h>
-#include <err.h>
-#include <os.h>
-#include <xmalloc.h>
-#include <fcntl.h>
-#include <xenbus.h>
-#include <wait.h>
-#include <sched.h>
-#include <semaphore.h>
-#include <spinlock.h>
-#include <xen/io/xs_wire.h>
-#include "xenbus_comms.h"
-
-#define streq(a, b) (strcmp((a), (b)) == 0)
-
-struct xs_stored_msg {
- struct list_head list;
-
- struct xsd_sockmsg hdr;
-
- union {
- /* Queued replies. */
- struct {
- char *body;
- } reply;
-
- /* Queued watch events. */
- struct {
- struct xenbus_watch *handle;
- char **vec;
- unsigned int vec_size;
- } watch;
- } u;
-};
-
-struct xs_handle {
- /* A list of replies. Currently only one will ever be outstanding. */
- struct list_head reply_list;
- spinlock_t reply_lock;
- struct wait_queue_head reply_waitq;
-
- /* One request at a time. */
- struct semaphore request_mutex;
-
- /* Protect transactions against save/restore. */
- struct rw_semaphore suspend_mutex;
-};
-
-static struct xs_handle xs_state;
-
-/* List of registered watches, and a lock to protect it. */
-static LIST_HEAD(watches);
-static DEFINE_SPINLOCK(watches_lock);
-
-/* List of pending watch callback events, and a lock to protect it. */
-static LIST_HEAD(watch_events);
-static DEFINE_SPINLOCK(watch_events_lock);
-
-/*
- * Details of the xenwatch callback kernel thread. The thread waits on the
- * watch_events_waitq for work to do (queued on watch_events list). When it
- * wakes up it acquires the xenwatch_mutex before reading the list and
- * carrying out work.
- */
-/* static */ DECLARE_MUTEX(xenwatch_mutex);
-static DECLARE_WAIT_QUEUE_HEAD(watch_events_waitq);
-
-static int get_error(const char *errorstring)
-{
- unsigned int i;
-
- for (i = 0; !streq(errorstring, xsd_errors[i].errstring); i++) {
- if (i == ARRAY_SIZE(xsd_errors) - 1) {
- printk("XENBUS xen store gave: unknown error %s",
- errorstring);
- return EINVAL;
- }
- }
- return xsd_errors[i].errnum;
-}
-
-static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len)
-{
- struct xs_stored_msg *msg;
- char *body;
-
- spin_lock(&xs_state.reply_lock);
-
- while (list_empty(&xs_state.reply_list)) {
- spin_unlock(&xs_state.reply_lock);
- wait_event(xs_state.reply_waitq,
- !list_empty(&xs_state.reply_list));
- spin_lock(&xs_state.reply_lock);
- }
-
- msg = list_entry(xs_state.reply_list.next,
- struct xs_stored_msg, list);
- list_del(&msg->list);
-
- spin_unlock(&xs_state.reply_lock);
-
- *type = msg->hdr.type;
- if (len)
- *len = msg->hdr.len;
- body = msg->u.reply.body;
-
- free(msg);
-
- return body;
-}
-
-/* Emergency write. */
-void xenbus_debug_write(const char *str, unsigned int count)
-{
- struct xsd_sockmsg msg = { 0 };
-
- msg.type = XS_DEBUG;
- msg.len = sizeof("print") + count + 1;
-
- down(&xs_state.request_mutex);
- xb_write(&msg, sizeof(msg));
- xb_write("print", sizeof("print"));
- xb_write(str, count);
- xb_write("", 1);
- up(&xs_state.request_mutex);
-}
-
-void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg)
-{
- void *ret;
- struct xsd_sockmsg req_msg = *msg;
- int err;
-
- if (req_msg.type == XS_TRANSACTION_START)
- down_read(&xs_state.suspend_mutex);
-
- down(&xs_state.request_mutex);
-
- err = xb_write(msg, sizeof(*msg) + msg->len);
- if (err) {
- msg->type = XS_ERROR;
- ret = ERR_PTR(err);
- } else {
- ret = read_reply(&msg->type, &msg->len);
- }
-
- up(&xs_state.request_mutex);
-
- if ((msg->type == XS_TRANSACTION_END) ||
- ((req_msg.type == XS_TRANSACTION_START) &&
- (msg->type == XS_ERROR)))
- up_read(&xs_state.suspend_mutex);
-
- return ret;
-}
-
-/* Send message to xs, get kmalloc'ed reply. ERR_PTR() on error. */
-static void *xs_talkv(struct xenbus_transaction *t,
- enum xsd_sockmsg_type type,
- const struct kvec *iovec,
- unsigned int num_vecs,
- unsigned int *len)
-{
- struct xsd_sockmsg msg;
- void *ret = NULL;
- unsigned int i;
- int err;
-
- msg.tx_id = (u32)(unsigned long)t;
- msg.req_id = 0;
- msg.type = type;
- msg.len = 0;
- for (i = 0; i < num_vecs; i++)
- msg.len += iovec[i].iov_len;
-
- down(&xs_state.request_mutex);
-
- err = xb_write(&msg, sizeof(msg));
- if (err) {
- up(&xs_state.request_mutex);
- return ERR_PTR(err);
- }
-
- for (i = 0; i < num_vecs; i++) {
- err = xb_write(iovec[i].iov_base, iovec[i].iov_len);;
- if (err) {
- up(&xs_state.request_mutex);
- return ERR_PTR(err);
- }
- }
-
- ret = read_reply(&msg.type, len);
-
- up(&xs_state.request_mutex);
-
- if (IS_ERR(ret))
- return ret;
-
- if (msg.type == XS_ERROR) {
- err = get_error(ret);
- free(ret);
- return ERR_PTR(-err);
- }
-
- // BUG_ON(msg.type != type);
- return ret;
-}
-
-/* Simplified version of xs_talkv: single message. */
-static void *xs_single(struct xenbus_transaction *t,
- enum xsd_sockmsg_type type,
- const char *string,
- unsigned int *len)
-{
- struct kvec iovec;
-
- iovec.iov_base = (void *)string;
- iovec.iov_len = strlen(string) + 1;
- return xs_talkv(t, type, &iovec, 1, len);
-}
-
-/* Many commands only need an ack, don't care what it says. */
-static int xs_error(char *reply)
-{
- if (IS_ERR(reply))
- return PTR_ERR(reply);
- free(reply);
- return 0;
-}
-
-static unsigned int count_strings(const char *strings, unsigned int len)
-{
- unsigned int num;
- const char *p;
-
- for (p = strings, num = 0; p < strings + len; p += strlen(p) + 1)
- num++;
-
- return num;
-}
-
-/* Return the path to dir with /name appended. Buffer must be kfree()'ed. */
-static char *join(const char *dir, const char *name)
-{
- char *buffer;
-
- buffer = malloc(strlen(dir) + strlen("/") + strlen(name) + 1);
- if (buffer == NULL)
- return ERR_PTR(-ENOMEM);
-
- strcpy(buffer, dir);
- if (!streq(name, "")) {
- strcat(buffer, "/");
- strcat(buffer, name);
- }
-
- return buffer;
-}
-
-static char **split(char *strings, unsigned int len, unsigned int *num)
-{
- char *p, **ret;
-
- /* Count the strings. */
- *num = count_strings(strings, len);
-
- /* Transfer to one big alloc for easy freeing. */
- ret = malloc(*num * sizeof(char *) + len);
- if (!ret) {
- free(strings);
- return ERR_PTR(-ENOMEM);
- }
- memcpy(&ret[*num], strings, len);
- free(strings);
-
- strings = (char *)&ret[*num];
- for (p = strings, *num = 0; p < strings + len; p += strlen(p) + 1)
- ret[(*num)++] = p;
-
- return ret;
-}
-
-char **xenbus_directory(struct xenbus_transaction *t,
- const char *dir, const char *node, unsigned int *num)
-{
- char *strings, *path;
- unsigned int len;
-
- path = join(dir, node);
- if (IS_ERR(path))
- return (char **)path;
-
- strings = xs_single(t, XS_DIRECTORY, path, &len);
- free(path);
- if (IS_ERR(strings))
- return (char **)strings;
-
- return split(strings, len, num);
-}
-
-/* Check if a path exists. Return 1 if it does. */
-int xenbus_exists(struct xenbus_transaction *t,
- const char *dir, const char *node)
-{
- char **d;
- int dir_n;
-
- d = xenbus_directory(t, dir, node, &dir_n);
- if (IS_ERR(d))
- return 0;
- free(d);
- return 1;
-}
-
-/* Get the value of a single file.
- * Returns a kmalloced value: call free() on it after use.
- * len indicates length in bytes.
- */
-void *xenbus_read(struct xenbus_transaction *t,
- const char *dir, const char *node, unsigned int *len)
-{
- char *path;
- void *ret;
-
- path = join(dir, node);
- if (IS_ERR(path))
- return (void *)path;
-
- ret = xs_single(t, XS_READ, path, len);
- free(path);
- return ret;
-}
-
-/* Write the value of a single file.
- * Returns -err on failure.
- */
-int xenbus_write(struct xenbus_transaction *t,
- const char *dir, const char *node, const char *string)
-{
- const char *path;
- struct kvec iovec[2];
- int ret;
-
- path = join(dir, node);
- if (IS_ERR(path))
- return PTR_ERR(path);
-
- iovec[0].iov_base = (void *)path;
- iovec[0].iov_len = strlen(path) + 1;
- iovec[1].iov_base = (void *)string;
- iovec[1].iov_len = strlen(string);
-
- ret = xs_error(xs_talkv(t, XS_WRITE, iovec, ARRAY_SIZE(iovec), NULL));
- free(path);
- return ret;
-}
-
-/* Create a new directory. */
-int xenbus_mkdir(struct xenbus_transaction *t,
- const char *dir, const char *node)
-{
- char *path;
- int ret;
-
- path = join(dir, node);
- if (IS_ERR(path))
- return PTR_ERR(path);
-
- ret = xs_error(xs_single(t, XS_MKDIR, path, NULL));
- free(path);
- return ret;
-}
-
-/* Destroy a file or directory (directories must be empty). */
-int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node)
-{
- char *path;
- int ret;
-
- path = join(dir, node);
- if (IS_ERR(path))
- return PTR_ERR(path);
-
- ret = xs_error(xs_single(t, XS_RM, path, NULL));
- free(path);
- return ret;
-}
-
-/* Start a transaction: changes by others will not be seen during this
- * transaction, and changes will not be visible to others until end.
- */
-struct xenbus_transaction *xenbus_transaction_start(void)
-{
- char *id_str;
- unsigned long id;
-
- down_read(&xs_state.suspend_mutex);
-
- id_str = xs_single(NULL, XS_TRANSACTION_START, "", NULL);
- if (IS_ERR(id_str)) {
- up_read(&xs_state.suspend_mutex);
- return (struct xenbus_transaction *)id_str;
- }
-
- id = simple_strtoul(id_str, NULL, 0);
- free(id_str);
-
- return (struct xenbus_transaction *)id;
-}
-
-/* End a transaction.
- * If abandon is true, transaction is discarded instead of committed.
- */
-int xenbus_transaction_end(struct xenbus_transaction *t, int abort)
-{
- char abortstr[2];
- int err;
-
- if (abort)
- strcpy(abortstr, "F");
- else
- strcpy(abortstr, "T");
-
- err = xs_error(xs_single(t, XS_TRANSACTION_END, abortstr, NULL));
-
- up_read(&xs_state.suspend_mutex);
-
- return err;
-}
-
-/* Single read and scanf: returns -errno or num scanned. */
-int xenbus_scanf(struct xenbus_transaction *t,
- const char *dir, const char *node, const char *fmt, ...)
-{
- va_list ap;
- int ret;
- char *val;
-
- val = xenbus_read(t, dir, node, NULL);
- if (IS_ERR(val))
- return PTR_ERR(val);
-
- va_start(ap, fmt);
- ret = vsscanf(val, fmt, ap);
- va_end(ap);
- free(val);
- /* Distinctive errno. */
- if (ret == 0)
- return -ERANGE;
- return ret;
-}
-
-/* Single printf and write: returns -errno or 0. */
-int xenbus_printf(struct xenbus_transaction *t,
- const char *dir, const char *node, const char *fmt, ...)
-{
- va_list ap;
- int ret;
-#define PRINTF_BUFFER_SIZE 4096
- char *printf_buffer;
-
- printf_buffer = malloc(PRINTF_BUFFER_SIZE);
- if (printf_buffer == NULL)
- return -ENOMEM;
-
- va_start(ap, fmt);
- ret = vsnprintf(printf_buffer, PRINTF_BUFFER_SIZE, fmt, ap);
- va_end(ap);
-
- // BUG_ON(ret > PRINTF_BUFFER_SIZE-1);
- ret = xenbus_write(t, dir, node, printf_buffer);
-
- free(printf_buffer);
-
- return ret;
-}
-
-/* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
-int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...)
-{
- va_list ap;
- const char *name;
- int ret = 0;
-
- va_start(ap, dir);
- while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
- const char *fmt = va_arg(ap, char *);
- void *result = va_arg(ap, void *);
- char *p;
-
- p = xenbus_read(t, dir, name, NULL);
- if (IS_ERR(p)) {
- ret = PTR_ERR(p);
- break;
- }
- if (fmt) {
- if (sscanf(p, fmt, result) == 0)
- ret = -EINVAL;
- free(p);
- } else
- *(char **)result = p;
- }
- va_end(ap);
- return ret;
-}
-
-static int xs_watch(const char *path, const char *token)
-{
- struct kvec iov[2];
-
- iov[0].iov_base = (void *)path;
- iov[0].iov_len = strlen(path) + 1;
- iov[1].iov_base = (void *)token;
- iov[1].iov_len = strlen(token) + 1;
-
- return xs_error(xs_talkv(NULL, XS_WATCH, iov,
- ARRAY_SIZE(iov), NULL));
-}
-
-static int xs_unwatch(const char *path, const char *token)
-{
- struct kvec iov[2];
-
- iov[0].iov_base = (char *)path;
- iov[0].iov_len = strlen(path) + 1;
- iov[1].iov_base = (char *)token;
- iov[1].iov_len = strlen(token) + 1;
-
- return xs_error(xs_talkv(NULL, XS_UNWATCH, iov,
- ARRAY_SIZE(iov), NULL));
-}
-
-static struct xenbus_watch *find_watch(const char *token)
-{
- struct xenbus_watch *i, *cmp;
-
- cmp = (void *)simple_strtoul(token, NULL, 16);
-
- list_for_each_entry(i, &watches, list)
- if (i == cmp)
- return i;
-
- return NULL;
-}
-
-/* Register callback to watch this node. */
-int register_xenbus_watch(struct xenbus_watch *watch)
-{
- /* Pointer in ascii is the token. */
- char token[sizeof(watch) * 2 + 1];
- int err;
-
- sprintf(token, "%lX", (long)watch);
-
- down_read(&xs_state.suspend_mutex);
-
- spin_lock(&watches_lock);
- // BUG_ON(find_watch(token));
- list_add(&watch->list, &watches);
- spin_unlock(&watches_lock);
-
- err = xs_watch(watch->node, token);
-
- /* Ignore errors due to multiple registration. */
- if ((err != 0) && (err != -EEXIST)) {
- spin_lock(&watches_lock);
- list_del(&watch->list);
- spin_unlock(&watches_lock);
- }
-
- up_read(&xs_state.suspend_mutex);
-
- return err;
-}
-
-void unregister_xenbus_watch(struct xenbus_watch *watch)
-{
- struct xs_stored_msg *msg, *tmp;
- char token[sizeof(watch) * 2 + 1];
- int err;
-
- sprintf(token, "%lX", (long)watch);
-
- down_read(&xs_state.suspend_mutex);
-
- spin_lock(&watches_lock);
- // BUG_ON(!find_watch(token));
- list_del(&watch->list);
- spin_unlock(&watches_lock);
-
- err = xs_unwatch(watch->node, token);
- if (err)
- printk("XENBUS Failed to release watch %s: %i\n",
- watch->node, err);
-
- up_read(&xs_state.suspend_mutex);
-
- /* Cancel pending watch events. */
- spin_lock(&watch_events_lock);
- list_for_each_entry_safe(msg, tmp, &watch_events, list) {
- if (msg->u.watch.handle != watch)
- continue;
- list_del(&msg->list);
- free(msg->u.watch.vec);
- free(msg);
- }
- spin_unlock(&watch_events_lock);
-}
-
-void xs_suspend(void)
-{
- down_write(&xs_state.suspend_mutex);
- down(&xs_state.request_mutex);
-}
-
-void xs_resume(void)
-{
- struct xenbus_watch *watch;
- char token[sizeof(watch) * 2 + 1];
-
- up(&xs_state.request_mutex);
-
- /* No need for watches_lock: the suspend_mutex is sufficient. */
- list_for_each_entry(watch, &watches, list) {
- sprintf(token, "%lX", (long)watch);
- xs_watch(watch->node, token);
- }
-
- up_write(&xs_state.suspend_mutex);
-}
-
-static void xenwatch_thread(void *unused)
-{
- struct list_head *ent;
- struct xs_stored_msg *msg;
-
- for (;;) {
- wait_event(watch_events_waitq,
- !list_empty(&watch_events));
-
- down(&xenwatch_mutex);
-
- spin_lock(&watch_events_lock);
- ent = watch_events.next;
- if (ent != &watch_events)
- list_del(ent);
- spin_unlock(&watch_events_lock);
-
- if (ent != &watch_events) {
- msg = list_entry(ent, struct xs_stored_msg, list);
- msg->u.watch.handle->callback(
- msg->u.watch.handle,
- (const char **)msg->u.watch.vec,
- msg->u.watch.vec_size);
- free(msg->u.watch.vec);
- free(msg);
- }
-
- up(&xenwatch_mutex);
- }
-}
-
-static int process_msg(void)
-{
- struct xs_stored_msg *msg;
- char *body;
- int err;
-
- msg = malloc(sizeof(*msg));
- if (msg == NULL)
- return -ENOMEM;
-
- err = xb_read(&msg->hdr, sizeof(msg->hdr));
- if (err) {
- free(msg);
- return err;
- }
-
- body = malloc(msg->hdr.len + 1);
- if (body == NULL) {
- free(msg);
- return -ENOMEM;
- }
-
- err = xb_read(body, msg->hdr.len);
- if (err) {
- free(body);
- free(msg);
- return err;
- }
- body[msg->hdr.len] = '\0';
-
- if (msg->hdr.type == XS_WATCH_EVENT) {
- msg->u.watch.vec = split(body, msg->hdr.len,
- &msg->u.watch.vec_size);
- if (IS_ERR(msg->u.watch.vec)) {
- free(msg);
- return PTR_ERR(msg->u.watch.vec);
- }
-
- spin_lock(&watches_lock);
- msg->u.watch.handle = find_watch(
- msg->u.watch.vec[XS_WATCH_TOKEN]);
- if (msg->u.watch.handle != NULL) {
- spin_lock(&watch_events_lock);
- list_add_tail(&msg->list, &watch_events);
- wake_up(&watch_events_waitq);
- spin_unlock(&watch_events_lock);
- } else {
- free(msg->u.watch.vec);
- free(msg);
- }
- spin_unlock(&watches_lock);
- } else {
- msg->u.reply.body = body;
- spin_lock(&xs_state.reply_lock);
- list_add_tail(&msg->list, &xs_state.reply_list);
- spin_unlock(&xs_state.reply_lock);
- wake_up(&xs_state.reply_waitq);
- }
-
- return 0;
-}
-
-static void xenbus_thread(void *unused)
-{
- int err;
-
- for (;;) {
- err = process_msg();
- if (err)
- printk("XENBUS error %d while reading "
- "message\n", err);
- }
-}
-
-int xs_init(void)
-{
- int err;
- struct thread *kxwatcher_thread;
- struct thread *kxenbus_thread;
-
- INIT_LIST_HEAD(&xs_state.reply_list);
- spin_lock_init(&xs_state.reply_lock);
- init_waitqueue_head(&xs_state.reply_waitq);
-
- init_MUTEX(&xs_state.request_mutex);
- init_rwsem(&xs_state.suspend_mutex);
-
- /* Initialize the shared memory rings to talk to xenstored */
- err = xb_init_comms();
- if (err)
- return err;
-
- kxwatcher_thread = create_thread("kxwatch", xenwatch_thread, NULL);
- if (IS_ERR(kxwatcher_thread))
- return PTR_ERR(kxwatcher_thread);
-
- kxenbus_thread = create_thread("kxenbus", xenbus_thread, NULL);
- if (IS_ERR(kxenbus_thread))
- return PTR_ERR(kxenbus_thread);
-
- return 0;
-}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|