aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcl349@arcadians.cl.cam.ac.uk <cl349@arcadians.cl.cam.ac.uk>2004-12-26 10:00:51 +0000
committercl349@arcadians.cl.cam.ac.uk <cl349@arcadians.cl.cam.ac.uk>2004-12-26 10:00:51 +0000
commit7ada6cd67ff7153ce85d48d00c1c56af1dd2055c (patch)
treef0d0e41780b7ea059fb09bffadfe38591196577a
parent66ac336c5978db71606b1f1160ba16445ae81c91 (diff)
parent5dc6acb5fd57658377eb0e081ba7df8bfa35b558 (diff)
downloadxen-7ada6cd67ff7153ce85d48d00c1c56af1dd2055c.tar.gz
xen-7ada6cd67ff7153ce85d48d00c1c56af1dd2055c.tar.bz2
xen-7ada6cd67ff7153ce85d48d00c1c56af1dd2055c.zip
bitkeeper revision 1.1159.170.64 (41ce8bd3sGsiOUiBHp1KyOcLPmYBgQ)
sync w/ head.
-rw-r--r--.rootkeys9
-rw-r--r--linux-2.4.28-xen-sparse/arch/xen/kernel/time.c28
-rw-r--r--linux-2.4.28-xen-sparse/arch/xen/mm/init.c4
-rw-r--r--linux-2.6.10-rc3-xen-sparse/arch/xen/configs/xen0_defconfig10
-rw-r--r--linux-2.6.10-rc3-xen-sparse/arch/xen/configs/xenU_defconfig10
-rw-r--r--linux-2.6.10-rc3-xen-sparse/arch/xen/i386/Kconfig166
-rw-r--r--linux-2.6.10-rc3-xen-sparse/arch/xen/i386/kernel/traps.c1
-rw-r--r--linux-2.6.10-rc3-xen-sparse/arch/xen/kernel/reboot.c19
-rw-r--r--linux-2.6.10-rc3-xen-sparse/drivers/xen/netback/interface.c10
-rw-r--r--tools/libxc/Makefile1
-rwxr-xr-xtools/libxc/plan9a.out.h28
-rw-r--r--tools/libxc/xc.h25
-rw-r--r--tools/libxc/xc_linux_save.c7
-rwxr-xr-xtools/libxc/xc_plan9_build.c744
-rwxr-xr-xtools/misc/xencons26
-rw-r--r--tools/python/xen/lowlevel/xc/xc.c35
-rw-r--r--tools/python/xen/util/console_client.py26
-rw-r--r--tools/python/xen/xend/XendClient.py5
-rw-r--r--tools/python/xen/xend/XendDomain.py4
-rw-r--r--tools/python/xen/xend/XendDomainInfo.py29
-rw-r--r--tools/python/xen/xend/encode.py4
-rw-r--r--tools/python/xen/xend/server/SrvDaemon.py4
-rw-r--r--tools/python/xen/xend/server/SrvDomain.py3
-rw-r--r--tools/python/xen/xend/server/domain.py12
-rw-r--r--tools/python/xen/xend/server/messages.py5
-rw-r--r--tools/python/xen/xend/sxp.py3
-rw-r--r--tools/python/xen/xm/main.py15
-rw-r--r--tools/python/xen/xm/sysrq.py39
-rw-r--r--xen/arch/x86/Rules.mk17
-rw-r--r--xen/arch/x86/boot/x86_32.S6
-rw-r--r--xen/arch/x86/boot/x86_64.S20
-rw-r--r--xen/arch/x86/domain.c93
-rw-r--r--xen/arch/x86/setup.c2
-rw-r--r--xen/arch/x86/shadow.c6
-rw-r--r--xen/arch/x86/smpboot.c4
-rw-r--r--xen/arch/x86/traps.c6
-rw-r--r--xen/arch/x86/x86_32/entry.S6
-rw-r--r--xen/arch/x86/x86_32/mm.c13
-rw-r--r--xen/arch/x86/x86_64/asm-offsets.c71
-rw-r--r--xen/arch/x86/x86_64/mm.c455
-rw-r--r--xen/arch/x86/x86_64/xen.lds5
-rw-r--r--xen/common/domain.c27
-rw-r--r--xen/common/physdev.c3
-rw-r--r--xen/include/asm-x86/asm_defns.h18
-rw-r--r--xen/include/asm-x86/irq.h2
-rw-r--r--xen/include/asm-x86/multicall.h10
-rw-r--r--xen/include/asm-x86/processor.h18
-rw-r--r--xen/include/asm-x86/system.h7
-rw-r--r--xen/include/asm-x86/uaccess.h26
-rw-r--r--xen/include/asm-x86/x86_32/asm_defns.h13
-rw-r--r--xen/include/asm-x86/x86_32/current.h11
-rw-r--r--xen/include/asm-x86/x86_32/uaccess.h21
-rw-r--r--xen/include/asm-x86/x86_64/asm_defns.h6
-rw-r--r--xen/include/asm-x86/x86_64/current.h11
-rw-r--r--xen/include/asm-x86/x86_64/uaccess.h24
-rw-r--r--xen/include/public/arch-x86_32.h2
-rw-r--r--xen/include/public/arch-x86_64.h2
-rw-r--r--xen/include/public/io/domain_controller.h1
-rw-r--r--xen/include/public/trace.h2
-rw-r--r--xen/include/xen/domain.h (renamed from xen/include/asm-x86/domain.h)12
-rw-r--r--xen/include/xen/sched.h5
61 files changed, 1876 insertions, 321 deletions
diff --git a/.rootkeys b/.rootkeys
index 42e784ee12..7c617a02c2 100644
--- a/.rootkeys
+++ b/.rootkeys
@@ -318,6 +318,7 @@
41090ec8Pj_bkgCBpg2W7WfmNkumEA tools/examples/xmexample1
40cf2937oKlROYOJTN8GWwWM5AmjBg tools/examples/xmexample2
3fbba6dbDfYvJSsw9500b4SZyUhxjQ tools/libxc/Makefile
+41cc934abX-QLXJXW_clV_wRjM0zYg tools/libxc/plan9a.out.h
3fbba6dc1uU7U3IFeF6A-XEOYF2MkQ tools/libxc/rpm.spec
3fbba6dcrNxtygEcgJYAJJ1gCQqfsA tools/libxc/xc.h
40589968oCfoUlXd460CjVAkBE8IBA tools/libxc/xc_atropos.c
@@ -332,6 +333,7 @@
3fbba6db7li3FJiABYtCmuGxOJxEGw tools/libxc/xc_linux_save.c
3fbba6db7WnnJr0KFrIFrqNlSKvFYg tools/libxc/xc_misc.c
4051bce6CHAsYh8P5t2OHDtRWOP9og tools/libxc/xc_physdev.c
+41cc934aO1m6NxEh_8eDr9bJIMoLFA tools/libxc/xc_plan9_build.c
3fbba6dctWRWlFJkYb6hdix2X4WMuw tools/libxc/xc_private.c
3fbba6dcbVrG2hPzEzwdeV_UC8kydQ tools/libxc/xc_private.h
40589968UQFnJeOMn8UIFLbXBuwXjw tools/libxc/xc_rrobin.c
@@ -519,6 +521,7 @@
411b2c1ehdEGO_CwG0tvn85Q-Tfh5g tools/python/xen/xm/migrate.py
40cf2937PSslwBliN1g7ofDy2H_RhA tools/python/xen/xm/opts.py
40cf2937Z8WCNOnO2FcWdubvEAF9QQ tools/python/xen/xm/shutdown.py
+41b88ba6_C4---jeA895Efg9YFZgKA tools/python/xen/xm/sysrq.py
40fcefb2K1xqVVT4D-p7nL2GzS4scg tools/sv/Main.rpy
40ffbcb66Dj5F-1kCK9BcgSqCWkt1w tools/sv/Makefile
4120b0e5L_nW-u0MWRfIdXg4ng4OjA tools/sv/images/destroy.png
@@ -690,7 +693,9 @@
40f92331jfOlE7MfKwpdkEb1CEf23g xen/arch/x86/x86_32/seg_fixup.c
3ddb79bc4nTpGQOe6_-MbyZzkhlhFQ xen/arch/x86/x86_32/usercopy.c
3ddb79bcOMCu9-5mKpjIh5d0qqBDPg xen/arch/x86/x86_32/xen.lds
+41bf1717Ty3hwN3E9swdu8QfnvGqww xen/arch/x86/x86_64/asm-offsets.c
40e96d3aLDI-nViMuYneD7VKYlZrVg xen/arch/x86/x86_64/entry.S
+41bf1717XhPz_dNT5OKSjgmbFuWBuA xen/arch/x86/x86_64/mm.c
40e96d3ahBTZqbTViInnq0lM03vs7A xen/arch/x86/x86_64/usercopy.c
40e96d3akN3Hu_J5Bk-WXD8OGscrYQ xen/arch/x86/x86_64/xen.lds
3ddb79bdff-gj-jFGKjOejeHLqL8Lg xen/common/Makefile
@@ -778,6 +783,7 @@
40715b2dWe0tDhx9LkLXzTQkvD49RA xen/include/asm-x86/acpi.h
3ddb79c3l4IiQtf6MS2jIzcd-hJS8g xen/include/asm-x86/apic.h
3ddb79c3QJYWr8LLGdonLbWmNb9pQQ xen/include/asm-x86/apicdef.h
+41bf17171g_hhz2k4B-fN9LQlODDjQ xen/include/asm-x86/asm_defns.h
3ddb79c3OiG9eTsi9Dy3F_OkuRAzKA xen/include/asm-x86/atomic.h
3ddb79c3rM-Ote0Xn6Ytg8Y6YqAG-A xen/include/asm-x86/bitops.h
3ddb79c3KhTI0F_Iw_hRL9QEyOVK-g xen/include/asm-x86/cache.h
@@ -789,7 +795,6 @@
3ddb79c3r9-31dIsewPV3P3i8HALsQ xen/include/asm-x86/delay.h
3ddb79c34BFiXjBJ_cCKB0aCsV1IDw xen/include/asm-x86/desc.h
40715b2dTokMLYGSuD58BnxOqyWVew xen/include/asm-x86/div64.h
-40f2b4a2hC3HtChu-ArD8LyojxWMjg xen/include/asm-x86/domain.h
3e20b82fl1jmQiKdLy7fxMcutfpjWA xen/include/asm-x86/domain_page.h
3ddb79c3NU8Zy40OTrq3D-i30Y3t4A xen/include/asm-x86/fixmap.h
3e2d29944GI24gf7vOP_7x8EyuqxeA xen/include/asm-x86/flushtlb.h
@@ -825,6 +830,7 @@
3ddb79c3mbqEM7QQr3zVq7NiBNhouA xen/include/asm-x86/x86_32/regs.h
3e7f358aG11EvMI9VJ4_9hD4LUO7rQ xen/include/asm-x86/x86_32/string.h
3ddb79c3M2n1ROZH6xk3HbyN4CPDqg xen/include/asm-x86/x86_32/uaccess.h
+41bf1717bML6GxpclTWJabiaO5W5vg xen/include/asm-x86/x86_64/asm_defns.h
404f1b9ceJeGVaPNIENm2FkK0AgEOQ xen/include/asm-x86/x86_64/current.h
404f1b9fl6AQ_a-T1TDK3fuwTPXmHw xen/include/asm-x86/x86_64/desc.h
404f1badfXZJZ2sU8sh9PS2EZvd19Q xen/include/asm-x86/x86_64/ldt.h
@@ -852,6 +858,7 @@
3eb165e0eawr3R-p2ZQtSdLWtLRN_A xen/include/xen/console.h
3ddb79c1V44RD26YqCUm-kqIupM37A xen/include/xen/ctype.h
3ddb79c05DdHQ0UxX_jKsXdR4QlMCA xen/include/xen/delay.h
+40f2b4a2hC3HtChu-ArD8LyojxWMjg xen/include/xen/domain.h
3ddb79c2O729EttZTYu1c8LcsUO_GQ xen/include/xen/elf.h
3ddb79c0HIghfBF8zFUdmXhOU8i6hA xen/include/xen/errno.h
3ddb79c1W0lQca8gRV7sN6j3iY4Luw xen/include/xen/event.h
diff --git a/linux-2.4.28-xen-sparse/arch/xen/kernel/time.c b/linux-2.4.28-xen-sparse/arch/xen/kernel/time.c
index 0a04c6c3b6..9b3d40a08c 100644
--- a/linux-2.4.28-xen-sparse/arch/xen/kernel/time.c
+++ b/linux-2.4.28-xen-sparse/arch/xen/kernel/time.c
@@ -99,6 +99,10 @@ static u64 processed_system_time; /* System time (ns) at last processing. */
#define NS_PER_TICK (1000000000ULL/HZ)
+#ifndef NSEC_PER_SEC
+#define NSEC_PER_SEC (1000000000L)
+#endif
+
#define HANDLE_USEC_UNDERFLOW(_tv) \
do { \
while ( (_tv).tv_usec < 0 ) \
@@ -115,6 +119,17 @@ static u64 processed_system_time; /* System time (ns) at last processing. */
(_tv).tv_sec++; \
} \
} while ( 0 )
+static inline void __normalize_time(time_t *sec, s64 *nsec)
+{
+ while (*nsec >= NSEC_PER_SEC) {
+ (*nsec) -= NSEC_PER_SEC;
+ (*sec)++;
+ }
+ while (*nsec < 0) {
+ (*nsec) += NSEC_PER_SEC;
+ (*sec)--;
+ }
+}
/* Dynamically-mapped IRQs. */
static int time_irq, debug_irq;
@@ -256,6 +271,7 @@ void do_gettimeofday(struct timeval *tv)
{
unsigned long flags, lost;
struct timeval _tv;
+ s64 nsec;
again:
read_lock_irqsave(&xtime_lock, flags);
@@ -266,6 +282,10 @@ void do_gettimeofday(struct timeval *tv)
_tv.tv_sec = xtime.tv_sec;
_tv.tv_usec += xtime.tv_usec;
+ nsec = shadow_system_time - processed_system_time;
+ __normalize_time(&_tv.tv_sec, &nsec);
+ _tv.tv_usec += (long)nsec / 1000L;
+
if ( unlikely(!TIME_VALUES_UP_TO_DATE) )
{
/*
@@ -301,7 +321,8 @@ void do_gettimeofday(struct timeval *tv)
void do_settimeofday(struct timeval *tv)
{
struct timeval newtv;
- suseconds_t usec;
+ s64 nsec;
+ suseconds_t usec;
if ( !INDEPENDENT_WALLCLOCK() )
return;
@@ -315,6 +336,11 @@ void do_settimeofday(struct timeval *tv)
*/
again:
usec = tv->tv_usec - __get_time_delta_usecs();
+
+ nsec = shadow_system_time - processed_system_time;
+ __normalize_time(&tv->tv_sec, &nsec);
+ usec -= (long)nsec / 1000L;
+
if ( unlikely(!TIME_VALUES_UP_TO_DATE) )
{
__get_time_values_from_xen();
diff --git a/linux-2.4.28-xen-sparse/arch/xen/mm/init.c b/linux-2.4.28-xen-sparse/arch/xen/mm/init.c
index dd622aebda..980983fd03 100644
--- a/linux-2.4.28-xen-sparse/arch/xen/mm/init.c
+++ b/linux-2.4.28-xen-sparse/arch/xen/mm/init.c
@@ -36,6 +36,10 @@
#include <asm/apic.h>
#include <asm/tlb.h>
+/* XEN: We *cannot* use mmx_clear_page() this early. Force dumb memset(). */
+#undef clear_page
+#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
+
mmu_gather_t mmu_gathers[NR_CPUS];
unsigned long highstart_pfn, highend_pfn;
static unsigned long totalram_pages;
diff --git a/linux-2.6.10-rc3-xen-sparse/arch/xen/configs/xen0_defconfig b/linux-2.6.10-rc3-xen-sparse/arch/xen/configs/xen0_defconfig
index 98cbd2fdbf..d3ff092e5e 100644
--- a/linux-2.6.10-rc3-xen-sparse/arch/xen/configs/xen0_defconfig
+++ b/linux-2.6.10-rc3-xen-sparse/arch/xen/configs/xen0_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.10-rc2-xen0
-# Wed Dec 1 09:22:49 2004
+# Thu Dec 23 14:01:43 2004
#
CONFIG_XEN=y
CONFIG_ARCH_XEN=y
@@ -79,6 +79,11 @@ CONFIG_MMU=y
CONFIG_UID16=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_IOMAP=y
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+# CONFIG_M586 is not set
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
# CONFIG_M686 is not set
# CONFIG_MPENTIUMII is not set
# CONFIG_MPENTIUMIII is not set
@@ -88,6 +93,9 @@ CONFIG_MPENTIUM4=y
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
# CONFIG_MCRUSOE is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
# CONFIG_X86_GENERIC is not set
diff --git a/linux-2.6.10-rc3-xen-sparse/arch/xen/configs/xenU_defconfig b/linux-2.6.10-rc3-xen-sparse/arch/xen/configs/xenU_defconfig
index 2512c79cb1..0e7dc0a3b3 100644
--- a/linux-2.6.10-rc3-xen-sparse/arch/xen/configs/xenU_defconfig
+++ b/linux-2.6.10-rc3-xen-sparse/arch/xen/configs/xenU_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.10-rc2-xenU
-# Wed Dec 1 09:22:09 2004
+# Thu Dec 23 14:02:24 2004
#
CONFIG_XEN=y
CONFIG_ARCH_XEN=y
@@ -78,6 +78,11 @@ CONFIG_MMU=y
CONFIG_UID16=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_IOMAP=y
+# CONFIG_M386 is not set
+# CONFIG_M486 is not set
+# CONFIG_M586 is not set
+# CONFIG_M586TSC is not set
+# CONFIG_M586MMX is not set
# CONFIG_M686 is not set
# CONFIG_MPENTIUMII is not set
# CONFIG_MPENTIUMIII is not set
@@ -87,6 +92,9 @@ CONFIG_MPENTIUM4=y
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
# CONFIG_MCRUSOE is not set
+# CONFIG_MWINCHIPC6 is not set
+# CONFIG_MWINCHIP2 is not set
+# CONFIG_MWINCHIP3D is not set
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
# CONFIG_X86_GENERIC is not set
diff --git a/linux-2.6.10-rc3-xen-sparse/arch/xen/i386/Kconfig b/linux-2.6.10-rc3-xen-sparse/arch/xen/i386/Kconfig
index d58f91fbd3..f34d271ff6 100644
--- a/linux-2.6.10-rc3-xen-sparse/arch/xen/i386/Kconfig
+++ b/linux-2.6.10-rc3-xen-sparse/arch/xen/i386/Kconfig
@@ -32,70 +32,70 @@ choice
prompt "Processor family"
default M686
-#config M386
-# bool "386"
-# ---help---
-# This is the processor type of your CPU. This information is used for
-# optimizing purposes. In order to compile a kernel that can run on
-# all x86 CPU types (albeit not optimally fast), you can specify
-# "386" here.
-#
-# The kernel will not necessarily run on earlier architectures than
-# the one you have chosen, e.g. a Pentium optimized kernel will run on
-# a PPro, but not necessarily on a i486.
-#
-# Here are the settings recommended for greatest speed:
-# - "386" for the AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI
-# 486DLC/DLC2, UMC 486SX-S and NexGen Nx586. Only "386" kernels
-# will run on a 386 class machine.
-# - "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or
-# SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S.
-# - "586" for generic Pentium CPUs lacking the TSC
-# (time stamp counter) register.
-# - "Pentium-Classic" for the Intel Pentium.
-# - "Pentium-MMX" for the Intel Pentium MMX.
-# - "Pentium-Pro" for the Intel Pentium Pro.
-# - "Pentium-II" for the Intel Pentium II or pre-Coppermine Celeron.
-# - "Pentium-III" for the Intel Pentium III or Coppermine Celeron.
-# - "Pentium-4" for the Intel Pentium 4 or P4-based Celeron.
-# - "K6" for the AMD K6, K6-II and K6-III (aka K6-3D).
-# - "Athlon" for the AMD K7 family (Athlon/Duron/Thunderbird).
-# - "Crusoe" for the Transmeta Crusoe series.
+config M386
+ bool "386"
+ ---help---
+ This is the processor type of your CPU. This information is used for
+ optimizing purposes. In order to compile a kernel that can run on
+ all x86 CPU types (albeit not optimally fast), you can specify
+ "386" here.
+
+ The kernel will not necessarily run on earlier architectures than
+ the one you have chosen, e.g. a Pentium optimized kernel will run on
+ a PPro, but not necessarily on a i486.
+
+ Here are the settings recommended for greatest speed:
+ - "386" for the AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI
+ 486DLC/DLC2, UMC 486SX-S and NexGen Nx586. Only "386" kernels
+ will run on a 386 class machine.
+ - "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or
+ SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S.
+ - "586" for generic Pentium CPUs lacking the TSC
+ (time stamp counter) register.
+ - "Pentium-Classic" for the Intel Pentium.
+ - "Pentium-MMX" for the Intel Pentium MMX.
+ - "Pentium-Pro" for the Intel Pentium Pro.
+ - "Pentium-II" for the Intel Pentium II or pre-Coppermine Celeron.
+ - "Pentium-III" for the Intel Pentium III or Coppermine Celeron.
+ - "Pentium-4" for the Intel Pentium 4 or P4-based Celeron.
+ - "K6" for the AMD K6, K6-II and K6-III (aka K6-3D).
+ - "Athlon" for the AMD K7 family (Athlon/Duron/Thunderbird).
+ - "Crusoe" for the Transmeta Crusoe series.
# - "Efficeon" for the Transmeta Efficeon series.
-# - "Winchip-C6" for original IDT Winchip.
-# - "Winchip-2" for IDT Winchip 2.
-# - "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
-# - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
-# - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above).
-#
-# If you don't know what to do, choose "386".
+ - "Winchip-C6" for original IDT Winchip.
+ - "Winchip-2" for IDT Winchip 2.
+ - "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
+ - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
+ - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above).
-#config M486
-# bool "486"
-# help
-# Select this for a 486 series processor, either Intel or one of the
-# compatible processors from AMD, Cyrix, IBM, or Intel. Includes DX,
-# DX2, and DX4 variants; also SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or
-# U5S.
+ If you don't know what to do, choose "386".
-#config M586
-# bool "586/K5/5x86/6x86/6x86MX"
-# help
-# Select this for an 586 or 686 series processor such as the AMD K5,
-# the Intel 5x86 or 6x86, or the Intel 6x86MX. This choice does not
-# assume the RDTSC (Read Time Stamp Counter) instruction.
+config M486
+ bool "486"
+ help
+ Select this for a 486 series processor, either Intel or one of the
+ compatible processors from AMD, Cyrix, IBM, or Intel. Includes DX,
+ DX2, and DX4 variants; also SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or
+ U5S.
-#config M586TSC
-# bool "Pentium-Classic"
-# help
-# Select this for a Pentium Classic processor with the RDTSC (Read
-# Time Stamp Counter) instruction for benchmarking.
+config M586
+ bool "586/K5/5x86/6x86/6x86MX"
+ help
+ Select this for an 586 or 686 series processor such as the AMD K5,
+ the Intel 5x86 or 6x86, or the Intel 6x86MX. This choice does not
+ assume the RDTSC (Read Time Stamp Counter) instruction.
-#config M586MMX
-# bool "Pentium-MMX"
-# help
-# Select this for a Pentium with the MMX graphics/multimedia
-# extended instructions.
+config M586TSC
+ bool "Pentium-Classic"
+ help
+ Select this for a Pentium Classic processor with the RDTSC (Read
+ Time Stamp Counter) instruction for benchmarking.
+
+config M586MMX
+ bool "Pentium-MMX"
+ help
+ Select this for a Pentium with the MMX graphics/multimedia
+ extended instructions.
config M686
bool "Pentium-Pro"
@@ -164,33 +164,33 @@ config MCRUSOE
like a 586 with TSC, and sets some GCC optimization flags (like a
Pentium Pro with no alignment requirements).
-#config MEFFICEON
-# bool "Efficeon"
-# help
-# Select this for a Transmeta Efficeon processor.
+config MEFFICEON
+ bool "Efficeon"
+ help
+ Select this for a Transmeta Efficeon processor.
-#config MWINCHIPC6
-# bool "Winchip-C6"
-# help
-# Select this for an IDT Winchip C6 chip. Linux and GCC
-# treat this chip as a 586TSC with some extended instructions
-# and alignment requirements.
+config MWINCHIPC6
+ bool "Winchip-C6"
+ help
+ Select this for an IDT Winchip C6 chip. Linux and GCC
+ treat this chip as a 586TSC with some extended instructions
+ and alignment requirements.
-#config MWINCHIP2
-# bool "Winchip-2"
-# help
-# Select this for an IDT Winchip-2. Linux and GCC
-# treat this chip as a 586TSC with some extended instructions
-# and alignment requirements.
+config MWINCHIP2
+ bool "Winchip-2"
+ help
+ Select this for an IDT Winchip-2. Linux and GCC
+ treat this chip as a 586TSC with some extended instructions
+ and alignment requirements.
-#config MWINCHIP3D
-# bool "Winchip-2A/Winchip-3"
-# help
-# Select this for an IDT Winchip-2A or 3. Linux and GCC
-# treat this chip as a 586TSC with some extended instructions
-# and alignment reqirements. Also enable out of order memory
-# stores for this CPU, which can increase performance of some
-# operations.
+config MWINCHIP3D
+ bool "Winchip-2A/Winchip-3"
+ help
+ Select this for an IDT Winchip-2A or 3. Linux and GCC
+ treat this chip as a 586TSC with some extended instructions
+ and alignment reqirements. Also enable out of order memory
+ stores for this CPU, which can increase performance of some
+ operations.
config MCYRIXIII
bool "CyrixIII/VIA-C3"
diff --git a/linux-2.6.10-rc3-xen-sparse/arch/xen/i386/kernel/traps.c b/linux-2.6.10-rc3-xen-sparse/arch/xen/i386/kernel/traps.c
index c837f935b4..1936d96c37 100644
--- a/linux-2.6.10-rc3-xen-sparse/arch/xen/i386/kernel/traps.c
+++ b/linux-2.6.10-rc3-xen-sparse/arch/xen/i386/kernel/traps.c
@@ -979,7 +979,6 @@ void __init trap_init(void)
* default LDT is a single-entry callgate to lcall7 for iBCS
* and a callgate to lcall27 for Solaris/x86 binaries
*/
- clear_page(&default_ldt[0]);
make_lowmem_page_readonly(&default_ldt[0]);
xen_flush_page_update_queue();
diff --git a/linux-2.6.10-rc3-xen-sparse/arch/xen/kernel/reboot.c b/linux-2.6.10-rc3-xen-sparse/arch/xen/kernel/reboot.c
index 1f7303efd2..78c46675f5 100644
--- a/linux-2.6.10-rc3-xen-sparse/arch/xen/kernel/reboot.c
+++ b/linux-2.6.10-rc3-xen-sparse/arch/xen/kernel/reboot.c
@@ -8,6 +8,7 @@ static int errno;
#include <linux/unistd.h>
#include <linux/module.h>
#include <linux/reboot.h>
+#include <linux/sysrq.h>
#include <asm/irq.h>
#include <asm/mmu_context.h>
#include <asm-xen/ctrl_if.h>
@@ -49,10 +50,9 @@ EXPORT_SYMBOL(machine_power_off);
* Stop/pickle callback handling.
*/
-//#include <asm/suspend.h>
-
/* Ignore multiple shutdown requests. */
static int shutting_down = -1;
+static int pending_sysrq = -1;
static void __do_suspend(void)
{
@@ -214,9 +214,18 @@ static void __shutdown_handler(void *unused)
}
}
+static void __sysrq_handler(void *unused)
+{
+#ifdef CONFIG_MAGIC_SYSRQ
+ handle_sysrq(pending_sysrq, NULL, NULL);
+#endif
+ pending_sysrq = -1;
+}
+
static void shutdown_handler(ctrl_msg_t *msg, unsigned long id)
{
static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL);
+ static DECLARE_WORK(sysrq_work, __sysrq_handler, NULL);
if ( (shutting_down == -1) &&
((msg->subtype == CMSG_SHUTDOWN_POWEROFF) ||
@@ -226,6 +235,12 @@ static void shutdown_handler(ctrl_msg_t *msg, unsigned long id)
shutting_down = msg->subtype;
schedule_work(&shutdown_work);
}
+ else if ( (pending_sysrq == -1) &&
+ (msg->subtype == CMSG_SHUTDOWN_SYSRQ) )
+ {
+ pending_sysrq = msg->msg[0];
+ schedule_work(&sysrq_work);
+ }
else
{
printk("Ignore spurious shutdown request\n");
diff --git a/linux-2.6.10-rc3-xen-sparse/drivers/xen/netback/interface.c b/linux-2.6.10-rc3-xen-sparse/drivers/xen/netback/interface.c
index baa50ace22..8de03f644b 100644
--- a/linux-2.6.10-rc3-xen-sparse/drivers/xen/netback/interface.c
+++ b/linux-2.6.10-rc3-xen-sparse/drivers/xen/netback/interface.c
@@ -124,13 +124,17 @@ void netif_create(netif_be_create_t *create)
dev->hard_start_xmit = netif_be_start_xmit;
dev->get_stats = netif_be_get_stats;
- memcpy(dev->dev_addr, create->mac, ETH_ALEN);
/* Disable queuing. */
dev->tx_queue_len = 0;
- /* Force a different MAC from remote end. */
- dev->dev_addr[2] ^= 1;
+ /*
+ * Initialise a dummy MAC address. We choose the numerically largest
+ * non-broadcast address to prevent the address getting stolen by an
+ * Ethernet bridge for STP purposes. (FE:FF:FF:FF:FF:FF)
+ */
+ memset(dev->dev_addr, 0xFF, ETH_ALEN);
+ dev->dev_addr[0] &= ~0x01;
if ( (err = register_netdev(dev)) != 0 )
{
diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
index 9065bb1bd6..6ee078644c 100644
--- a/tools/libxc/Makefile
+++ b/tools/libxc/Makefile
@@ -18,6 +18,7 @@ SRCS += xc_domain.c
SRCS += xc_evtchn.c
SRCS += xc_io.c
SRCS += xc_linux_build.c
+SRCS += xc_plan9_build.c
SRCS += xc_linux_restore.c
SRCS += xc_linux_save.c
SRCS += xc_misc.c
diff --git a/tools/libxc/plan9a.out.h b/tools/libxc/plan9a.out.h
new file mode 100755
index 0000000000..d53f636517
--- /dev/null
+++ b/tools/libxc/plan9a.out.h
@@ -0,0 +1,28 @@
+
+typedef struct Exec
+{
+ long magic; /* magic number */
+ long text; /* size of text segment */
+ long data; /* size of initialized data */
+ long bss; /* size of uninitialized data */
+ long syms; /* size of symbol table */
+ long entry; /* entry point */
+ long spsz; /* size of pc/sp offset table */
+ long pcsz; /* size of pc/line number table */
+} Exec;
+
+#define _MAGIC(b) ((((4*b)+0)*b)+7)
+#define A_MAGIC _MAGIC(8) /* 68020 */
+#define I_MAGIC _MAGIC(11) /* intel 386 */
+#define J_MAGIC _MAGIC(12) /* intel 960 */
+#define K_MAGIC _MAGIC(13) /* sparc */
+#define V_MAGIC _MAGIC(16) /* mips 3000 */
+#define X_MAGIC _MAGIC(17) /* att dsp 3210 */
+#define M_MAGIC _MAGIC(18) /* mips 4000 */
+#define D_MAGIC _MAGIC(19) /* amd 29000 */
+#define E_MAGIC _MAGIC(20) /* arm 7-something */
+#define Q_MAGIC _MAGIC(21) /* powerpc */
+#define N_MAGIC _MAGIC(22) /* mips 4000 LE */
+#define L_MAGIC _MAGIC(23) /* dec alpha */
+#define P_MAGIC _MAGIC(24) /* mips 3000 LE */
+
diff --git a/tools/libxc/xc.h b/tools/libxc/xc.h
index 18665e9178..72dfd3c4e6 100644
--- a/tools/libxc/xc.h
+++ b/tools/libxc/xc.h
@@ -9,14 +9,15 @@
#ifndef __XC_H__
#define __XC_H__
-typedef unsigned char u8;
-typedef unsigned short u16;
-typedef unsigned long u32;
-typedef unsigned long long u64;
-typedef signed char s8;
-typedef signed short s16;
-typedef signed long s32;
-typedef signed long long s64;
+#include <stdint.h>
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef int8_t s8;
+typedef int16_t s16;
+typedef int32_t s32;
+typedef int64_t s64;
#include <xen/xen.h>
#include <xen/dom0_ops.h>
@@ -96,6 +97,14 @@ int xc_linux_build(int xc_handle,
unsigned int control_evtchn,
unsigned long flags);
+int
+xc_plan9_build (int xc_handle,
+ u32 domid,
+ const char *image_name,
+ const char *cmdline,
+ unsigned int control_evtchn,
+ unsigned long flags);
+
int xc_bvtsched_global_set(int xc_handle,
unsigned long ctx_allow);
diff --git a/tools/libxc/xc_linux_save.c b/tools/libxc/xc_linux_save.c
index 9ff85a241b..6d877c84f0 100644
--- a/tools/libxc/xc_linux_save.c
+++ b/tools/libxc/xc_linux_save.c
@@ -6,6 +6,7 @@
* Copyright (c) 2003, K A Fraser.
*/
+#include <inttypes.h>
#include <sys/time.h>
#include "xc_private.h"
#include <xen/linux/suspend.h>
@@ -245,7 +246,7 @@ static int print_stats( int xc_handle, u32 domid,
if ( print )
printf("delta %lldms, dom0 %d%%, target %d%%, sent %dMb/s, "
- "dirtied %dMb/s %ld pages\n",
+ "dirtied %dMb/s %" PRId32 " pages\n",
wall_delta,
(int)((d0_cpu_delta*100)/wall_delta),
(int)((d1_cpu_delta*100)/wall_delta),
@@ -307,8 +308,8 @@ static int analysis_phase( int xc_handle, u32 domid,
DOM0_SHADOW_CONTROL_OP_PEEK,
NULL, 0, &stats);
- printf("now= %lld faults= %ld dirty= %ld dirty_net= %ld "
- "dirty_block= %ld\n",
+ printf("now= %lld faults= %" PRId32 " dirty= %" PRId32
+ " dirty_net= %" PRId32 " dirty_block= %" PRId32"\n",
((now-start)+500)/1000,
stats.fault_count, stats.dirty_count,
stats.dirty_net_count, stats.dirty_block_count);
diff --git a/tools/libxc/xc_plan9_build.c b/tools/libxc/xc_plan9_build.c
new file mode 100755
index 0000000000..33c9a54914
--- /dev/null
+++ b/tools/libxc/xc_plan9_build.c
@@ -0,0 +1,744 @@
+/******************************************************************************
+ * xc_plan9_build.c
+ * derived from xc_linux_build.c
+ */
+
+#include "xc_private.h"
+
+#include <zlib.h>
+
+#define DEBUG 1
+#ifdef DEBUG
+#define DPRINTF(x) printf x; fflush(stdout);
+#else
+#define DPRINTF(x)
+#endif
+
+#include "plan9a.out.h"
+
+/* really TOS which means stack starts at 0x2000, and uses page 1*/
+#define STACKPAGE 2
+struct Exec header, origheader;
+
+typedef struct page {
+ char data[PAGE_SIZE];
+} PAGE;
+
+
+int
+memcpy_toguest(int xc_handle, u32 dom, void *v, int size,
+ unsigned long *page_array, unsigned int to_page)
+{
+ int ret;
+ unsigned char *cp = v;
+ unsigned int whichpage;
+ unsigned char *vaddr;
+
+// DPRINTF(("memcpy_to_guest: to_page 0x%x, count %d\n", to_page, size));
+ for (ret = 0, whichpage = to_page; size > 0;
+ whichpage++, size -= PAGE_SIZE, cp += PAGE_SIZE) {
+
+ // DPRINTF (("map_pfn_writeable(%p, 0x%lx)\n", pm_handle,
+// page_array[whichpage]));
+ vaddr = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+ PROT_READ | PROT_WRITE,
+ page_array[whichpage]);
+ // DPRINTF (("vaddr is %p\n", vaddr));
+ if (vaddr == NULL) {
+ ret = -1;
+ ERROR("Couldn't map guest memory");
+ goto out;
+ }
+ // DPRINTF (("copy %p to %p, count 0x%x\n", cp, vaddr, 4096));
+ memcpy(vaddr, cp, 4096);
+ munmap(vaddr, PAGE_SIZE);
+ // DPRINTF (("Did %ud'th pages\n", whichpage));
+ }
+ out:
+ return ret;
+}
+
+/* this is a function which can go away. It dumps a hunk of
+ * guest pages to a file (/tmp/dumpit); handy for debugging
+ * your image builder.
+ * Xen guys, nuke this if you wish.
+ */
+void
+dumpit(int xc_handle, u32 dom,
+ int start_page, int tot, unsigned long *page_array)
+{
+ int i, ofd;
+ unsigned char *vaddr;
+
+ ofd = open("/tmp/dumpit", O_RDWR);
+ for (i = start_page; i < tot; i++) {
+ vaddr = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+ PROT_READ | PROT_WRITE,
+ page_array[i]);
+ if (!vaddr) {
+ fprintf(stderr, "Page %d\n", i);
+ perror("shit");
+ read(0, &i, 1);
+ return;
+ }
+ write(ofd, vaddr, 4096);
+ munmap(vaddr, PAGE_SIZE);
+ }
+}
+int
+blah(char *b)
+{
+ fprintf(stderr, "Error in xc_plan9_build!\n");
+ perror(b);
+ return errno;
+}
+
+/* swap bytes. For plan 9 headers */
+void
+swabby(unsigned long *s, char *name)
+{
+ unsigned long it;
+ it = ((*s & 0xff000000) >> 24) | ((*s & 0xff0000) >> 8) |
+ ((*s & 0xff00) << 8) | ((*s & 0xff) << 24);
+ DPRINTF(("Item %s is 0x%lx\n", name, it));
+ *s = it;
+}
+
+void
+plan9header(Exec * header)
+{
+ /* header is big-endian */
+ swabby(&header->magic, "magic");
+ swabby(&header->text, "text");
+ swabby(&header->data, "data");
+ swabby(&header->bss, "bss");
+ swabby(&header->syms, "syms");
+ swabby(&header->entry, "entry");
+ swabby(&header->spsz, "spsz");
+ swabby(&header->pcsz, "pcsz");
+
+}
+
+static int
+ loadp9image(gzFile kernel_gfd, int xc_handle, u32 dom,
+ unsigned long *page_array,
+ unsigned long tot_pages, unsigned long *virt_load_addr,
+ unsigned long *ksize, unsigned long *symtab_addr,
+ unsigned long *symtab_len,
+ unsigned long *first_data_page, unsigned long *pdb_page);
+
+#define P9ROUND (P9SIZE / 8)
+
+#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
+#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
+
+static long
+get_tot_pages(int xc_handle, u32 domid)
+{
+ dom0_op_t op;
+ op.cmd = DOM0_GETDOMAININFO;
+ op.u.getdomaininfo.domain = (domid_t) domid;
+ op.u.getdomaininfo.ctxt = NULL;
+ return (do_dom0_op(xc_handle, &op) < 0) ?
+ -1 : op.u.getdomaininfo.tot_pages;
+}
+
+static int
+get_pfn_list(int xc_handle,
+ u32 domid, unsigned long *pfn_buf, unsigned long max_pfns)
+{
+ dom0_op_t op;
+ int ret;
+ op.cmd = DOM0_GETMEMLIST;
+ op.u.getmemlist.domain = (domid_t) domid;
+ op.u.getmemlist.max_pfns = max_pfns;
+ op.u.getmemlist.buffer = pfn_buf;
+
+ if (mlock(pfn_buf, max_pfns * sizeof (unsigned long)) != 0)
+ return -1;
+
+ ret = do_dom0_op(xc_handle, &op);
+
+ (void) munlock(pfn_buf, max_pfns * sizeof (unsigned long));
+
+#if 0
+#ifdef DEBUG
+ DPRINTF(("Ret for get_pfn_list is %d\n", ret));
+ if (ret >= 0) {
+ int i, j;
+ for (i = 0; i < op.u.getmemlist.num_pfns; i += 16) {
+ fprintf(stderr, "0x%x: ", i);
+ for (j = 0; j < 16; j++)
+ fprintf(stderr, "0x%lx ", pfn_buf[i + j]);
+ fprintf(stderr, "\n");
+ }
+ }
+#endif
+#endif
+ return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
+}
+
+static int
+setup_guestos(int xc_handle,
+ u32 dom,
+ gzFile kernel_gfd,
+ unsigned long tot_pages,
+ unsigned long *virt_startinfo_addr,
+ unsigned long *virt_load_addr,
+ full_execution_context_t * ctxt,
+ const char *cmdline,
+ unsigned long shared_info_frame,
+ unsigned int control_evtchn,
+ int flags)
+{
+ l1_pgentry_t *vl1e = NULL;
+ l2_pgentry_t *vl2tab = NULL, *vl2e = NULL;
+ unsigned long *cpage_array = NULL;
+ unsigned long *pte_array = NULL;
+ unsigned long l2tab;
+ unsigned long l1tab;
+ unsigned long count;
+ unsigned long symtab_addr = 0, symtab_len = 0;
+ start_info_t *start_info;
+ shared_info_t *shared_info;
+ unsigned long ksize;
+ mmu_t *mmu = NULL;
+ int i;
+ unsigned long first_page_after_kernel,
+ first_data_page,
+ page_array_page;
+ unsigned long cpu0pdb, cpu0pte, cpu0ptelast;
+ unsigned long /*last_pfn, */ tot_pte_pages;
+
+ DPRINTF(("tot pages is %ld\n", tot_pages));
+ if ((cpage_array = malloc(tot_pages * sizeof (unsigned long))) == NULL) {
+ PERROR("Could not allocate cpage array");
+ goto error_out;
+ }
+
+ if (get_pfn_list(xc_handle, dom, cpage_array, tot_pages) != tot_pages) {
+ PERROR("Could not get the page frame list");
+ goto error_out;
+ }
+
+ for (i = 0; i < 64; i++)
+ DPRINTF(("First %d page is 0x%lx\n", i, cpage_array[i]));
+
+ tot_pte_pages = tot_pages >> 10;
+ DPRINTF(("Page range is 0 to 0x%lx, which requires 0x%lx pte pages\n",
+ tot_pte_pages, tot_pte_pages));
+
+ if (loadp9image(kernel_gfd, xc_handle, dom, cpage_array, tot_pages,
+ virt_load_addr, &ksize, &symtab_addr, &symtab_len,
+ &first_data_page, &first_page_after_kernel))
+ goto error_out;
+ DPRINTF(("First data page is 0x%lx\n", first_data_page));
+ DPRINTF(("First page after kernel is 0x%lx\n",
+ first_page_after_kernel));
+
+ /*
+ NEED TO INCREMENT first page after kernel by:
+ + 1 (pdb)
+ + tot_pte_pages (pte)
+ + tot_pte_pages (page_array)
+ */
+ /* SO, have to copy the first kernel pages pfns right into the
+ * page_array, then do identity maps for the rest.
+ */
+ DPRINTF(("mapped kernel pages\n"));
+
+ /* now loop over all ptes and store into the page_array, so as
+ * to get the identity map.
+ */
+ if ((pte_array =
+ malloc(tot_pte_pages * 1024 * sizeof (unsigned long))) == NULL) {
+ PERROR("Could not allocate pte array");
+ goto error_out;
+ }
+
+ /* plan 9 on startup expects a "l2" (xen parlance) at 0x2000,
+ * this "l2" should have one PTE pointer for a va of 0x80000000.
+ * and an l1 (PTEs to you) at 0x3000. (physical).
+ * the PTEs should map the first 4M of memory.
+ */
+ /* get a physical address for the L2. This means take the PFN and
+ * shift left.
+ */
+ /* this terminology is plan 9 terminology.
+ * pdb is essentially the Xen L2. 'Page Directory Block'?
+ * I need to ask JMK.
+ * cpupte is the pte array.
+ * Plan 9 counts on these being set up for cpu0.
+ * SO: cpu0pdb (Xen L2)
+ * and cpupte (Xen L1)
+ */
+ /* cpu0pdb is right after kernel */
+ cpu0pdb = first_page_after_kernel;
+ /* cpu0pte comes right after cpu0pdb */
+ cpu0pte = cpu0pdb + 1;
+ /* number of the past cpu0pte page */
+ cpu0ptelast = cpu0pte + tot_pte_pages - 1;
+ /* first page of the page array (mfn) */
+ page_array_page = cpu0ptelast + 1;
+
+ DPRINTF(("cpu0pdb 0x%lx, cpu0pte 0x%lx cpu0ptelast 0x%lx\n", cpu0pdb,
+ cpu0pte, cpu0ptelast));
+ l2tab = cpage_array[cpu0pdb] << PAGE_SHIFT;
+ DPRINTF(("l2tab 0x%lx\n", l2tab));
+ ctxt->pt_base = l2tab;
+
+ /* get a physical address for the L1. This means take the PFN and
+ * shift left.
+ */
+ l1tab = cpage_array[cpu0pte] << PAGE_SHIFT;
+ DPRINTF(("l1tab 0x%lx\n", l1tab));
+ if ((mmu = init_mmu_updates(xc_handle, dom)) == NULL)
+ goto error_out;
+ DPRINTF(("now map in l2tab\n"));
+
+ /* Initialise the page tables. */
+ /* mmap in the l2tab */
+ if ((vl2tab = xc_map_foreign_range(xc_handle, dom,
+ PAGE_SIZE, PROT_READ | PROT_WRITE,
+ l2tab >> PAGE_SHIFT)) == NULL)
+ goto error_out;
+ DPRINTF(("vl2tab 0x%p\n", vl2tab));
+ /* now we have the cpu0pdb for the kernel, starting at 0x2000,
+ * so we can plug in the physical pointer to the 0x3000 pte
+ */
+ /* zero it */
+ memset(vl2tab, 0, PAGE_SIZE);
+ /* get a pointer in the l2tab for the virt_load_addr */
+ DPRINTF(("&vl2tab[l2_table_offset(*virt_load_addr)] is 0x%p[0x%lx]\n",
+ &vl2tab[l2_table_offset(*virt_load_addr)],
+ l2_table_offset(*virt_load_addr)));
+
+ vl2e = &vl2tab[l2_table_offset(*virt_load_addr)];
+
+ /* OK, for all the available PTE, set the PTE pointer up */
+ DPRINTF(("For i = %ld to %ld ...\n", cpu0pte, cpu0ptelast));
+ for (i = cpu0pte; i <= cpu0ptelast; i++) {
+ DPRINTF(("Index %d Set %p to 0x%lx\n", i, vl2e,
+ (cpage_array[i] << PAGE_SHIFT) | L2_PROT));
+ *vl2e++ = (cpage_array[i] << PAGE_SHIFT) | L2_PROT;
+ }
+
+ /* unmap it ... */
+ munmap(vl2tab, PAGE_SIZE);
+
+ /* for the pages from virt_load_pointer to the end of this
+ * set of PTEs, map in the PFN for that VA
+ */
+ for (vl1e = (l1_pgentry_t *) pte_array, count = 0;
+ count < tot_pte_pages * 1024; count++, vl1e++) {
+
+ *vl1e = cpage_array[count];
+ if (!cpage_array[count])
+ continue;
+ /* set in the PFN for this entry */
+ *vl1e = (cpage_array[count] << PAGE_SHIFT) | L1_PROT;
+/*
+ DPRINTF (("vl1e # %d 0x%lx gets 0x%lx\n",
+ count, vl1e, *vl1e));
+*/
+ if ((count >= cpu0pdb) && (count <= cpu0ptelast)) {
+ //DPRINTF((" Fix up page %d as it is in pte ville: ", count));
+ *vl1e &= ~_PAGE_RW;
+ DPRINTF(("0x%lx\n", *vl1e));
+ }
+ if ((count >= (0x100000 >> 12))
+ && (count < (first_data_page >> 12))) {
+ //DPRINTF((" Fix up page %d as it is in text ", count));
+ *vl1e &= ~_PAGE_RW;
+ //DPRINTF (("0x%lx\n", *vl1e));
+ }
+ }
+ /* special thing. Pre-map the shared info page */
+ vl1e = &pte_array[2];
+ *vl1e = (shared_info_frame << PAGE_SHIFT) | L1_PROT;
+ DPRINTF(("v1l1 %p, has value 0x%lx\n", vl1e, *(unsigned long *) vl1e));
+ /* another special thing. VA 80005000 has to point to 80006000 */
+ /* this is a Plan 9 thing -- the 'mach' pointer */
+ /* 80005000 is the mach pointer per-cpu, and the actual
+ * mach pointers are 80006000, 80007000 etc.
+ */
+ vl1e = &pte_array[5];
+ *vl1e = (cpage_array[6] << PAGE_SHIFT) | L1_PROT;
+
+ /* OK, it's all set up, copy it in */
+ memcpy_toguest(xc_handle, dom, pte_array,
+ (tot_pte_pages * 1024 * sizeof (unsigned long) /**/),
+ cpage_array, cpu0pte);
+
+ /* We really need to have the vl1tab unmapped or the add_mmu_update
+ * below will fail bigtime.
+ */
+ /* Xen guys: remember my errors on domain exit? Something I'm doing
+ * wrong in here? We never did find out ...
+ */
+ /* get rid of the entries we can not use ... */
+ memcpy_toguest(xc_handle, dom, cpage_array,
+ (tot_pte_pages * 1024 * sizeof (unsigned long) /**/),
+ cpage_array, page_array_page);
+ /* last chance to dump all of memory */
+ // dumpit(xc_handle, dom, 0 /*0x100000>>12*/, tot_pages, cpage_array) ;
+ /*
+ * Pin down l2tab addr as page dir page - causes hypervisor to provide
+ * correct protection for the page
+ */
+ if (add_mmu_update(xc_handle, mmu,
+ l2tab | MMU_EXTENDED_COMMAND, MMUEXT_PIN_L2_TABLE))
+ goto error_out;
+
+ for (count = 0; count < tot_pages; count++) {
+/*
+ DPRINTF (("add_mmu_update(0x%x, 0x%x, 0x%x, %d)\n", xc_handle, mmu,
+ (cpage_array[count]
+ << PAGE_SHIFT) |
+ MMU_MACHPHYS_UPDATE,
+ count));
+*/
+ if (add_mmu_update(xc_handle, mmu,
+ (cpage_array[count] << PAGE_SHIFT) |
+ MMU_MACHPHYS_UPDATE, count))
+ goto error_out;
+ //DPRINTF(("Do the next one\n"));
+ }
+/*
+ */
+
+ //dumpit(pm_handle, 3, 4, page_array);
+ /* put the virt_startinfo_addr at KZERO */
+ /* just hard-code for now */
+ *virt_startinfo_addr = 0x80000000;
+
+ DPRINTF(("virt_startinfo_addr = 0x%lx\n", *virt_startinfo_addr));
+ start_info = xc_map_foreign_range(xc_handle, dom,
+ PAGE_SIZE, PROT_READ | PROT_WRITE,
+ cpage_array[0]);
+ DPRINTF(("startinfo = 0x%p\n", start_info));
+ DPRINTF(("shared_info_frame is %lx\n", shared_info_frame));
+ memset(start_info, 0, sizeof (*start_info));
+ start_info->pt_base = 0x80000000 | cpu0pdb << PAGE_SHIFT;
+ start_info->mfn_list = 0x80000000 | (page_array_page) << PAGE_SHIFT;
+ DPRINTF(("mfn_list 0x%lx\n", start_info->mfn_list));
+ start_info->mod_start = 0;
+ start_info->mod_len = 0;
+ start_info->nr_pages = tot_pte_pages * 1024;
+ start_info->nr_pt_frames = tot_pte_pages + 1;
+ start_info->shared_info = shared_info_frame;
+ start_info->flags = 0;
+ DPRINTF((" control event channel is %d\n", control_evtchn));
+ start_info->domain_controller_evtchn = control_evtchn;
+ strncpy(start_info->cmd_line, cmdline, MAX_CMDLINE);
+ start_info->cmd_line[MAX_CMDLINE - 1] = '\0';
+ munmap(start_info, PAGE_SIZE);
+
+ DPRINTF(("done setting up start_info\n"));
+ DPRINTF(("shared_info_frame = 0x%lx\n", shared_info_frame));
+ /* shared_info page starts its life empty. */
+
+ shared_info = xc_map_foreign_range(xc_handle, dom,
+ PAGE_SIZE, PROT_READ | PROT_WRITE,
+ shared_info_frame);
+ memset(shared_info, 0, PAGE_SIZE);
+ /* Mask all upcalls... */
+ DPRINTF(("mask all upcalls\n"));
+ for (i = 0; i < MAX_VIRT_CPUS; i++)
+ shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
+ munmap(shared_info, PAGE_SIZE);
+
+ /* Send the page update requests down to the hypervisor. */
+ DPRINTF(("send page update reqs down.\n"));
+ if (finish_mmu_updates(xc_handle, mmu))
+ goto error_out;
+
+ //DPRINTF (("call dumpit.\n"));
+ //dumpit(pm_handle, 0x100000>>12, tot_pages, page_array) ;
+ //dumpit (pm_handle, 2, 0x100, page_array);
+ free(mmu);
+
+ /* we don't bother freeing anything at this point --
+ * we're exiting and it is pointless
+ */
+ return 0;
+
+ error_out:
+ /* oh well we still free some things -- I oughtta nuke this */
+ if (mmu != NULL)
+ free(mmu);
+ ;
+ return -1;
+}
+
+int
+xc_plan9_build(int xc_handle,
+ u32 domid,
+ const char *image_name,
+ const char *cmdline,
+ unsigned int control_evtchn, unsigned long flags)
+{
+ dom0_op_t launch_op, op;
+ unsigned long load_addr;
+ long tot_pages;
+ int kernel_fd = -1;
+ gzFile kernel_gfd = NULL;
+ int rc, i;
+ full_execution_context_t st_ctxt, *ctxt = &st_ctxt;
+ unsigned long virt_startinfo_addr;
+
+ if ((tot_pages = get_tot_pages(xc_handle, domid)) < 0) {
+ PERROR("Could not find total pages for domain");
+ return 1;
+ }
+ DPRINTF(("get_tot_pages returns %ld pages\n", tot_pages));
+
+ kernel_fd = open(image_name, O_RDONLY);
+ if (kernel_fd < 0) {
+ PERROR("Could not open kernel image");
+ return 1;
+ }
+
+ if ((kernel_gfd = gzdopen(kernel_fd, "rb")) == NULL) {
+ PERROR("Could not allocate decompression state for state file");
+ close(kernel_fd);
+ return 1;
+ }
+
+ DPRINTF(("get_tot_pages returns %ld pages\n", tot_pages));
+ if (mlock(&st_ctxt, sizeof (st_ctxt))) {
+ PERROR("Unable to mlock ctxt");
+ return 1;
+ }
+
+ op.cmd = DOM0_GETDOMAININFO;
+ op.u.getdomaininfo.domain = (domid_t) domid;
+ op.u.getdomaininfo.ctxt = ctxt;
+ if ((do_dom0_op(xc_handle, &op) < 0) ||
+ ((u32) op.u.getdomaininfo.domain != domid)) {
+ PERROR("Could not get info on domain");
+ goto error_out;
+ }
+ DPRINTF(("get_tot_pages returns %ld pages\n", tot_pages));
+
+ if (!(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED)
+ || (op.u.getdomaininfo.ctxt->pt_base != 0)) {
+ ERROR("Domain is already constructed");
+ goto error_out;
+ }
+
+ DPRINTF(("get_tot_pages returns %ld pages\n", tot_pages));
+ if (setup_guestos(xc_handle, domid, kernel_gfd, tot_pages,
+ &virt_startinfo_addr,
+ &load_addr, &st_ctxt, cmdline,
+ op.u.getdomaininfo.shared_info_frame,
+ control_evtchn, flags) < 0) {
+ ERROR("Error constructing guest OS");
+ goto error_out;
+ }
+
+ /* leave the leak in here for now
+ if ( kernel_fd >= 0 )
+ close(kernel_fd);
+ if( kernel_gfd )
+ gzclose(kernel_gfd);
+ */
+ ctxt->flags = 0;
+
+ /*
+ * Initial register values:
+ * DS,ES,FS,GS = FLAT_GUESTOS_DS
+ * CS:EIP = FLAT_GUESTOS_CS:start_pc
+ * SS:ESP = FLAT_GUESTOS_DS:start_stack
+ * ESI = start_info
+ * [EAX,EBX,ECX,EDX,EDI,EBP are zero]
+ * EFLAGS = IF | 2 (bit 1 is reserved and should always be 1)
+ */
+ ctxt->cpu_ctxt.ds = FLAT_GUESTOS_DS;
+ ctxt->cpu_ctxt.es = FLAT_GUESTOS_DS;
+ ctxt->cpu_ctxt.fs = FLAT_GUESTOS_DS;
+ ctxt->cpu_ctxt.gs = FLAT_GUESTOS_DS;
+ ctxt->cpu_ctxt.ss = FLAT_GUESTOS_DS;
+ ctxt->cpu_ctxt.cs = FLAT_GUESTOS_CS;
+ ctxt->cpu_ctxt.eip = load_addr;
+ ctxt->cpu_ctxt.eip = 0x80100020;
+ /* put stack at top of second page */
+ ctxt->cpu_ctxt.esp = 0x80000000 + (STACKPAGE << PAGE_SHIFT);
+
+ /* why is this set? */
+ ctxt->cpu_ctxt.esi = ctxt->cpu_ctxt.esp;
+ ctxt->cpu_ctxt.eflags = (1 << 9) | (1 << 2);
+
+ /* FPU is set up to default initial state. */
+ memset(ctxt->fpu_ctxt, 0, sizeof (ctxt->fpu_ctxt));
+
+ /* Virtual IDT is empty at start-of-day. */
+ for (i = 0; i < 256; i++) {
+ ctxt->trap_ctxt[i].vector = i;
+ ctxt->trap_ctxt[i].cs = FLAT_GUESTOS_CS;
+ }
+ ctxt->fast_trap_idx = 0;
+
+ /* No LDT. */
+ ctxt->ldt_ents = 0;
+
+ /* Use the default Xen-provided GDT. */
+ ctxt->gdt_ents = 0;
+
+ /* Ring 1 stack is the initial stack. */
+ /* put stack at top of second page */
+ ctxt->guestos_ss = FLAT_GUESTOS_DS;
+ ctxt->guestos_esp = ctxt->cpu_ctxt.esp;
+
+ /* No debugging. */
+ memset(ctxt->debugreg, 0, sizeof (ctxt->debugreg));
+
+ /* No callback handlers. */
+ ctxt->event_callback_cs = FLAT_GUESTOS_CS;
+ ctxt->event_callback_eip = 0;
+ ctxt->failsafe_callback_cs = FLAT_GUESTOS_CS;
+ ctxt->failsafe_callback_eip = 0;
+
+ memset(&launch_op, 0, sizeof (launch_op));
+
+ launch_op.u.builddomain.domain = (domid_t) domid;
+ // launch_op.u.builddomain.num_vifs = 1;
+ launch_op.u.builddomain.ctxt = ctxt;
+ launch_op.cmd = DOM0_BUILDDOMAIN;
+ rc = do_dom0_op(xc_handle, &launch_op);
+
+ fprintf(stderr, "RC is %d\n", rc);
+ return rc;
+
+ error_out:
+ if (kernel_fd >= 0)
+ close(kernel_fd);
+ if (kernel_gfd)
+ gzclose(kernel_gfd);
+
+ return -1;
+}
+
+/*
+ * Plan 9 memory layout (initial)
+ * ----------------
+ * | info from xen| @0
+ * ----------------
+ * | stack |
+ * ----------------<--- page 2
+ * | empty |
+ * ---------------<---- page 5 MACHADDR (always points to machp[cpuno]
+ * | aliased |
+ * ---------------<----- page 6 CPU0MACH
+ * | CPU0MACH |
+ * ----------------
+ * | empty |
+ * ---------------- *virt_load_addr = ehdr.e_entry (0x80100000)
+ * | kernel |
+ * | |
+ * ---------------- <----- page aligned boundary.
+ * | data |
+ * | |
+ * ----------------
+ * | bss |
+ * ----------------<--- end of kernel (page aligned)
+ * | PMD cpu0pdb |
+ * ----------------<--- page +1
+ * | PTE cpu0pte |
+ * ----------------<--- page (tot_pte_pages)/1024
+ * | page_array |
+ * ---------------- <--- page (tot_pte_pages)/1024
+ * | empty to TOM |
+ * ----------------
+ */
+
+static int
+loadp9image(gzFile kernel_gfd, int xc_handle, u32 dom,
+ unsigned long *page_array,
+ unsigned long tot_pages, unsigned long *virt_load_addr,
+ unsigned long *ksize, unsigned long *symtab_addr,
+ unsigned long *symtab_len,
+ unsigned long *first_data_page, unsigned long *pdb_page)
+{
+ unsigned long datapage;
+ Exec ehdr;
+
+ char *p;
+ unsigned long maxva;
+ int curpos, ret;
+ PAGE *image = 0;
+ unsigned long image_tot_pages = 0;
+ unsigned long textround;
+
+ ret = -1;
+
+ p = NULL;
+ maxva = 0;
+
+ if (gzread(kernel_gfd, &ehdr, sizeof (Exec)) != sizeof (Exec)) {
+ PERROR("Error reading kernel image P9 header.");
+ goto out;
+ }
+
+ plan9header(&ehdr);
+ curpos = sizeof (Exec);
+
+ if (ehdr.magic != I_MAGIC) {
+ PERROR("Image does not have an P9 header.");
+ goto out;
+ }
+
+ textround = ((ehdr.text + 0x20 + 4095) >> 12) << 12;
+ *first_data_page = 0x100000 + textround;
+ DPRINTF(("ehrd.text is 0x%lx, textround is 0x%lx\n",
+ ehdr.text, textround));
+
+ image_tot_pages =
+ (textround + ehdr.data + ehdr.bss + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ DPRINTF(("tot pages is %ld\n", image_tot_pages));
+
+ *virt_load_addr = 0x80100000;
+
+ if ((*virt_load_addr & (PAGE_SIZE - 1)) != 0) {
+ ERROR("We can only deal with page-aligned load addresses");
+ goto out;
+ }
+
+ if ((*virt_load_addr + (image_tot_pages << PAGE_SHIFT)) >
+ HYPERVISOR_VIRT_START) {
+ ERROR("Cannot map all domain memory without hitting Xen space");
+ goto out;
+ }
+
+ /* just malloc an image that is image_tot_pages in size. Then read in
+ * the image -- text, data, -- to page-rounded alignments.
+ * then copy into xen .
+ * this gets BSS zeroed for free
+ */
+ DPRINTF(("Allocate %ld bytes\n", image_tot_pages * sizeof (*image)));
+ image = calloc(image_tot_pages, sizeof (*image));
+ if (!image)
+ return blah("alloc data");
+ /* text starts at 0x20, after the header, just like Unix long ago */
+ if (gzread(kernel_gfd, &image[0].data[sizeof (Exec)], ehdr.text) <
+ ehdr.text)
+ return blah("read text");
+ DPRINTF(("READ TEXT %ld bytes\n", ehdr.text));
+ datapage = ((ehdr.text + sizeof (Exec)) / PAGE_SIZE) + 1;
+ if (gzread(kernel_gfd, image[datapage].data, ehdr.data) < ehdr.data)
+ return blah("read data");
+ DPRINTF(("READ DATA %ld bytes\n", ehdr.data));
+
+ /* nice contig stuff */
+ /* oops need to start at 0x100000 */
+
+ ret = memcpy_toguest(xc_handle, dom,
+ image, image_tot_pages * 4096, page_array, 0x100);
+ DPRINTF(("done copying kernel to guest memory\n"));
+
+ out:
+ if (image)
+ free(image);
+ *pdb_page = image_tot_pages + (0x100000 >> PAGE_SHIFT);
+ return ret;
+}
diff --git a/tools/misc/xencons b/tools/misc/xencons
index 7ac63aeb75..8bd3178eab 100755
--- a/tools/misc/xencons
+++ b/tools/misc/xencons
@@ -27,24 +27,34 @@ def __recv_from_sock(sock):
while not stop:
try:
data = sock.recv(1024)
- os.write(1, data)
except socket.error, error:
if error[0] != errno.EINTR:
raise
+ else:
+ try:
+ os.write(1, data)
+ except os.error, error:
+ if error[0] != errno.EINTR:
+ raise
os.wait()
def __send_to_sock(sock):
while 1:
- data = os.read(0,1024)
- if ord(data[0]) == ord(']')-64:
- break
try:
- sock.send(data)
- except socket.error, error:
- if error[0] == errno.EPIPE:
- sys.exit(0)
+ data = os.read(0,1024)
+ except os.error, error:
if error[0] != errno.EINTR:
raise
+ else:
+ if ord(data[0]) == ord(']')-64:
+ break
+ try:
+ sock.send(data)
+ except socket.error, error:
+ if error[0] == errno.EPIPE:
+ sys.exit(0)
+ if error[0] != errno.EINTR:
+ raise
sys.exit(0)
def connect(host,port):
diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c
index 2dd8680b4f..d2b7da0eba 100644
--- a/tools/python/xen/lowlevel/xc/xc.c
+++ b/tools/python/xen/lowlevel/xc/xc.c
@@ -366,6 +366,33 @@ static PyObject *pyxc_linux_build(PyObject *self,
return zero;
}
+static PyObject *pyxc_plan9_build(PyObject *self,
+ PyObject *args,
+ PyObject *kwds)
+{
+ XcObject *xc = (XcObject *)self;
+
+ u32 dom;
+ char *image, *ramdisk = NULL, *cmdline = "";
+ int control_evtchn, flags = 0;
+
+ static char *kwd_list[] = { "dom", "control_evtchn",
+ "image", "ramdisk", "cmdline", "flags",
+ NULL };
+
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|ssi", kwd_list,
+ &dom, &control_evtchn,
+ &image, &ramdisk, &cmdline, &flags) )
+ return NULL;
+
+ if ( xc_plan9_build(xc->xc_handle, dom, image,
+ cmdline, control_evtchn, flags) != 0 )
+ return PyErr_SetFromErrno(xc_error);
+
+ Py_INCREF(zero);
+ return zero;
+}
+
static PyObject *pyxc_bvtsched_global_set(PyObject *self,
PyObject *args,
PyObject *kwds)
@@ -889,6 +916,14 @@ static PyMethodDef pyxc_methods[] = {
" state_file [str]: Name of state file. Must not currently exist.\n"
" progress [int, 1]: Bool - display a running progress indication?\n\n"
"Returns: [int] 0 on success; -1 on error.\n" },
+ { "plan9_build",
+ (PyCFunction)pyxc_plan9_build,
+ METH_VARARGS | METH_KEYWORDS, "\n"
+ "Build a new Plan 9 guest OS.\n"
+ " dom [long]: Identifier of domain to build into.\n"
+ " image [str]: Name of kernel image file. May be gzipped.\n"
+ " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
+ "Returns: [int] 0 on success; -1 on error.\n" },
{ "linux_restore",
(PyCFunction)pyxc_linux_restore,
diff --git a/tools/python/xen/util/console_client.py b/tools/python/xen/util/console_client.py
index 7ac63aeb75..8bd3178eab 100644
--- a/tools/python/xen/util/console_client.py
+++ b/tools/python/xen/util/console_client.py
@@ -27,24 +27,34 @@ def __recv_from_sock(sock):
while not stop:
try:
data = sock.recv(1024)
- os.write(1, data)
except socket.error, error:
if error[0] != errno.EINTR:
raise
+ else:
+ try:
+ os.write(1, data)
+ except os.error, error:
+ if error[0] != errno.EINTR:
+ raise
os.wait()
def __send_to_sock(sock):
while 1:
- data = os.read(0,1024)
- if ord(data[0]) == ord(']')-64:
- break
try:
- sock.send(data)
- except socket.error, error:
- if error[0] == errno.EPIPE:
- sys.exit(0)
+ data = os.read(0,1024)
+ except os.error, error:
if error[0] != errno.EINTR:
raise
+ else:
+ if ord(data[0]) == ord(']')-64:
+ break
+ try:
+ sock.send(data)
+ except socket.error, error:
+ if error[0] == errno.EPIPE:
+ sys.exit(0)
+ if error[0] != errno.EINTR:
+ raise
sys.exit(0)
def connect(host,port):
diff --git a/tools/python/xen/xend/XendClient.py b/tools/python/xen/xend/XendClient.py
index 8290165412..4e733b7fde 100644
--- a/tools/python/xen/xend/XendClient.py
+++ b/tools/python/xen/xend/XendClient.py
@@ -228,10 +228,11 @@ class Xend:
return self.xendPost(self.domainurl(id),
{'op' : 'pause' })
- def xend_domain_shutdown(self, id, reason):
+ def xend_domain_shutdown(self, id, reason, key=0):
return self.xendPost(self.domainurl(id),
{'op' : 'shutdown',
- 'reason' : reason })
+ 'reason' : reason,
+ 'key' : key })
def xend_domain_destroy(self, id, reason):
return self.xendPost(self.domainurl(id),
diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py
index fc53b4de03..1b01b43cfa 100644
--- a/tools/python/xen/xend/XendDomain.py
+++ b/tools/python/xen/xend/XendDomain.py
@@ -455,7 +455,7 @@ class XendDomain:
except Exception, ex:
raise XendError(str(ex))
- def domain_shutdown(self, id, reason='poweroff'):
+ def domain_shutdown(self, id, reason='poweroff', key=0):
"""Shutdown domain (nicely).
- poweroff: restart according to exit code and restart mode
- reboot: restart on exit
@@ -474,7 +474,7 @@ class XendDomain:
eserver.inject('xend.domain.shutdown', [dominfo.name, dominfo.id, reason])
if reason == 'halt':
reason = 'poweroff'
- val = xend.domain_shutdown(dominfo.id, reason)
+ val = xend.domain_shutdown(dominfo.id, reason, key)
self.refresh_schedule()
return val
diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py
index 335da5e486..1a229a5599 100644
--- a/tools/python/xen/xend/XendDomainInfo.py
+++ b/tools/python/xen/xend/XendDomainInfo.py
@@ -1065,6 +1065,34 @@ def vm_image_linux(vm, image):
vm.create_domain("linux", kernel, ramdisk, cmdline)
return vm
+def vm_image_plan9(vm, image):
+ """Create a VM for a Plan 9 image.
+
+ name vm name
+ memory vm memory
+ image image config
+
+ returns vm
+ """
+ #todo: Same as for linux. Is that right? If so can unify them.
+ kernel = sxp.child_value(image, "kernel")
+ cmdline = ""
+ ip = sxp.child_value(image, "ip", "dhcp")
+ if ip:
+ cmdline += "ip=" + ip
+ root = sxp.child_value(image, "root")
+ if root:
+ cmdline += "root=" + root
+ args = sxp.child_value(image, "args")
+ if args:
+ cmdline += " " + args
+ ramdisk = sxp.child_value(image, "ramdisk", '')
+ vifs = vm.config_devices("vif")
+ vm.create_domain("plan9", kernel, ramdisk, cmdline)
+ return vm
+
+
+
def vm_dev_vif(vm, val, index, change=0):
"""Create a virtual network interface (vif).
@@ -1186,6 +1214,7 @@ def vm_field_maxmem(vm, config, val, index):
# Register image handlers.
add_image_handler('linux', vm_image_linux)
+add_image_handler('plan9', vm_image_plan9)
# Register device handlers.
add_device_handler('vif', vm_dev_vif)
diff --git a/tools/python/xen/xend/encode.py b/tools/python/xen/xend/encode.py
index 38c9351db7..48815defa9 100644
--- a/tools/python/xen/xend/encode.py
+++ b/tools/python/xen/xend/encode.py
@@ -14,6 +14,8 @@ import httplib
import random
import md5
+from xen.util.ip import _readline, _readlines
+
# Extract from HTML4 spec.
## The following example illustrates "multipart/form-data"
## encoding. Suppose we have the following form:
@@ -122,7 +124,7 @@ def encode_multipart(d):
out.write('"\r\n')
out.write('Content-Type: application/octet-stream\r\n')
out.write('\r\n')
- for l in v.readlines():
+ for l in _readlines(v):
out.write(l)
else:
out.write('Content-Disposition: form-data; name="')
diff --git a/tools/python/xen/xend/server/SrvDaemon.py b/tools/python/xen/xend/server/SrvDaemon.py
index 05a0f27201..338d6e4d4a 100644
--- a/tools/python/xen/xend/server/SrvDaemon.py
+++ b/tools/python/xen/xend/server/SrvDaemon.py
@@ -711,14 +711,14 @@ class Daemon:
raise XendError('Invalid console id')
console.disconnect()
- def domain_shutdown(self, dom, reason):
+ def domain_shutdown(self, dom, reason, key=0):
"""Shutdown a domain.
"""
dom = int(dom)
ctrl = self.domainCF.getController(dom)
if not ctrl:
raise XendError('No domain controller: %s' % dom)
- ctrl.shutdown(reason)
+ ctrl.shutdown(reason, key)
return 0
def domain_mem_target_set(self, dom, target):
diff --git a/tools/python/xen/xend/server/SrvDomain.py b/tools/python/xen/xend/server/SrvDomain.py
index c06b260ce1..d73a39bff5 100644
--- a/tools/python/xen/xend/server/SrvDomain.py
+++ b/tools/python/xen/xend/server/SrvDomain.py
@@ -47,7 +47,8 @@ class SrvDomain(SrvDir):
def op_shutdown(self, op, req):
fn = FormFn(self.xd.domain_shutdown,
[['dom', 'str'],
- ['reason', 'str']])
+ ['reason', 'str'],
+ ['key', 'int']])
val = fn(req.args, {'dom': self.dom.id})
req.setResponseCode(http.ACCEPTED)
req.setHeader("Location", "%s/.." % req.prePathURL())
diff --git a/tools/python/xen/xend/server/domain.py b/tools/python/xen/xend/server/domain.py
index 4e1baf64de..eb0dbcf48b 100644
--- a/tools/python/xen/xend/server/domain.py
+++ b/tools/python/xen/xend/server/domain.py
@@ -28,7 +28,8 @@ class DomainController(controller.Controller):
"""
reasons = {'poweroff' : 'shutdown_poweroff_t',
'reboot' : 'shutdown_reboot_t',
- 'suspend' : 'shutdown_suspend_t' }
+ 'suspend' : 'shutdown_suspend_t',
+ 'sysrq' : 'shutdown_sysrq_t' }
def __init__(self, factory, dom):
controller.Controller.__init__(self, factory, dom)
@@ -36,16 +37,19 @@ class DomainController(controller.Controller):
self.addMethod(CMSG_MEM_REQUEST, 0, None)
self.registerChannel()
- def shutdown(self, reason):
+ def shutdown(self, reason, key=0):
"""Shutdown a domain.
reason shutdown reason
+ key sysrq key (only if reason is 'sysrq')
"""
msgtype = self.reasons.get(reason)
if not msgtype:
raise XendError('invalid reason:' + reason)
- msg = packMsg(msgtype, {})
- self.writeRequest(msg)
+ extra = {}
+ if reason == 'sysrq': extra['key'] = key
+ print extra
+ self.writeRequest(packMsg(msgtype, extra))
def mem_target_set(self, target):
"""Set domain memory target in pages.
diff --git a/tools/python/xen/xend/server/messages.py b/tools/python/xen/xend/server/messages.py
index 081dd9ce32..35f9db986e 100644
--- a/tools/python/xen/xend/server/messages.py
+++ b/tools/python/xen/xend/server/messages.py
@@ -197,10 +197,12 @@ CMSG_SHUTDOWN = 6
CMSG_SHUTDOWN_POWEROFF = 0
CMSG_SHUTDOWN_REBOOT = 1
CMSG_SHUTDOWN_SUSPEND = 2
+CMSG_SHUTDOWN_SYSRQ = 3
STOPCODE_shutdown = 0
STOPCODE_reboot = 1
STOPCODE_suspend = 2
+STOPCODE_sysrq = 3
shutdown_formats = {
'shutdown_poweroff_t':
@@ -211,6 +213,9 @@ shutdown_formats = {
'shutdown_suspend_t':
(CMSG_SHUTDOWN, CMSG_SHUTDOWN_SUSPEND),
+
+ 'shutdown_sysrq_t':
+ (CMSG_SHUTDOWN, CMSG_SHUTDOWN_SYSRQ)
}
msg_formats.update(shutdown_formats)
diff --git a/tools/python/xen/xend/sxp.py b/tools/python/xen/xend/sxp.py
index 98cc303416..35b24aa8aa 100644
--- a/tools/python/xen/xend/sxp.py
+++ b/tools/python/xen/xend/sxp.py
@@ -17,6 +17,7 @@ import types
import errno
import string
from StringIO import StringIO
+from xen.util.ip import _readline, _readlines
__all__ = [
"mime_type",
@@ -713,7 +714,7 @@ def parse(io):
"""
pin = Parser()
while 1:
- buf = io.readline()
+ buf = _readline(io)
pin.input(buf)
if len(buf) == 0:
break
diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py
index e7454e507a..411da44106 100644
--- a/tools/python/xen/xm/main.py
+++ b/tools/python/xen/xm/main.py
@@ -11,7 +11,7 @@ from xen.xend import PrettyPrint
from xen.xend import sxp
from xen.xend.XendClient import XendError, server
from xen.xend.XendClient import main as xend_client_main
-from xen.xm import create, destroy, migrate, shutdown
+from xen.xm import create, destroy, migrate, shutdown, sysrq
from xen.xm.opts import *
class Group:
@@ -401,6 +401,19 @@ class ProgShutdown(Prog):
xm.prog(ProgShutdown)
+class ProgSysrq(Prog):
+ group = 'domain'
+ name = "sysrq"
+ info = """Send a sysrq to a domain."""
+
+ def help(self, args):
+ sysrq.main([args[0], '-h'])
+
+ def main(self, args):
+ sysrq.main(args)
+
+xm.prog(ProgSysrq)
+
class ProgPause(Prog):
group = 'domain'
name = "pause"
diff --git a/tools/python/xen/xm/sysrq.py b/tools/python/xen/xm/sysrq.py
new file mode 100644
index 0000000000..44827af094
--- /dev/null
+++ b/tools/python/xen/xm/sysrq.py
@@ -0,0 +1,39 @@
+# (C) Matthew Bloch <matthew@bytemark.co.uk> 2004
+
+"""Domain shutdown.
+"""
+import string
+import sys
+import time
+
+from xen.xend.XendClient import server
+from xen.xm.opts import *
+
+DOM0_NAME = 'Domain-0'
+DOM0_ID = '0'
+
+gopts = Opts(use="""[DOM] [letter]
+
+Sends a Linux sysrq to a domain.
+""")
+
+gopts.opt('help', short='h',
+ fn=set_true, default=0,
+ use="Print this help.")
+
+def sysrq(dom, req):
+ server.xend_domain_shutdown(dom, 'sysrq', req)
+
+def main(argv):
+ opts = gopts
+ args = opts.parse(argv)
+ if opts.vals.help:
+ opts.usage()
+ return
+
+ # no options for the moment
+ if len(args) < 1: opts.err('Missing domain')
+ if len(args) < 2: opts.err('Missing sysrq character')
+ dom = args[0]
+ req = ord(args[1][0])
+ sysrq(dom, req)
diff --git a/xen/arch/x86/Rules.mk b/xen/arch/x86/Rules.mk
index bceb1982f4..d569a435c5 100644
--- a/xen/arch/x86/Rules.mk
+++ b/xen/arch/x86/Rules.mk
@@ -32,3 +32,20 @@ CFLAGS += -m64 -mno-red-zone -fpic -fno-reorder-blocks
CFLAGS += -fno-asynchronous-unwind-tables
LDFLAGS := --oformat elf64-x86-64
endif
+
+# Test for at least GCC v3.2.x.
+gcc-ver = $(shell $(CC) -dumpversion | sed -e 's/^\(.\)\.\(.\)\.\(.\)/\$(1)/')
+ifeq ($(call gcc-ver,1),1)
+$(error gcc-1.x.x unsupported - upgrade to at least gcc-3.2.x)
+endif
+ifeq ($(call gcc-ver,1),2)
+$(error gcc-2.x.x unsupported - upgrade to at least gcc-3.2.x)
+endif
+ifeq ($(call gcc-ver,1),3)
+ifeq ($(call gcc-ver,2),0)
+$(error gcc-3.0.x unsupported - upgrade to at least gcc-3.2.x)
+endif
+ifeq ($(call gcc-ver,2),1)
+$(error gcc-3.1.x unsupported - upgrade to at least gcc-3.2.x)
+endif
+endif
diff --git a/xen/arch/x86/boot/x86_32.S b/xen/arch/x86/boot/x86_32.S
index 305c279c5e..ef568efd3a 100644
--- a/xen/arch/x86/boot/x86_32.S
+++ b/xen/arch/x86/boot/x86_32.S
@@ -102,15 +102,15 @@ __start:
/* Initialize low and high mappings of all memory with 4MB pages */
mov $idle_pg_table-__PAGE_OFFSET,%edi
- mov $0x1e3,%eax /* PRESENT+RW+A+D+4MB+GLOBAL */
+ mov $0xe3,%eax /* PRESENT+RW+A+D+4MB */
1: mov %eax,__PAGE_OFFSET>>20(%edi) /* high mapping */
stosl /* low mapping */
add $(1<<L2_PAGETABLE_SHIFT),%eax
- cmp $DIRECTMAP_PHYS_END+0x1e3,%eax
+ cmp $DIRECTMAP_PHYS_END+0xe3,%eax
jne 1b
1: stosl /* low mappings cover as much physmem as possible */
add $(1<<L2_PAGETABLE_SHIFT),%eax
- cmp $__HYPERVISOR_VIRT_START+0x1e3,%eax
+ cmp $__HYPERVISOR_VIRT_START+0xe3,%eax
jne 1b
/* Initialise IDT with simple error defaults. */
diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S
index 98289c7ab6..a8253a4ce1 100644
--- a/xen/arch/x86/boot/x86_64.S
+++ b/xen/arch/x86/boot/x86_64.S
@@ -257,30 +257,22 @@ copy_to_user:
set_intr_gate:
die:
machine_to_phys_mapping:
-.globl copy_from_user, show_registers, __set_fixmap, do_iopl, check_descriptor
+.globl copy_from_user, show_registers, do_iopl
copy_from_user:
show_registers:
-__set_fixmap:
do_iopl:
-check_descriptor:
-.globl set_gdt, idt_table, copy_user_generic, memcmp, idt_tables, new_thread
-set_gdt:
+.globl idt_table, copy_user_generic, memcmp, idt_tables, new_thread
idt_table:
copy_user_generic:
memcmp:
idt_tables:
new_thread:
-.globl switch_to, continue_nonidle_task, __get_user_1, paging_init, trap_init
+.globl switch_to, __get_user_1, __get_user_4, __get_user_8, trap_init
switch_to:
-continue_nonidle_task:
__get_user_1:
-paging_init:
-trap_init:
-.globl __get_user_8, zap_low_mappings, set_debugreg,synchronise_pagetables
+__get_user_4:
__get_user_8:
-zap_low_mappings:
+trap_init:
+.globl set_debugreg
set_debugreg:
-synchronise_pagetables:
-.globl destroy_gdt
-destroy_gdt:
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 4a01d86351..95dc9779a6 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -48,35 +48,16 @@
#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
#define round_pgdown(_p) ((_p)&PAGE_MASK)
-int hlt_counter;
-
-void disable_hlt(void)
-{
- hlt_counter++;
-}
-
-void enable_hlt(void)
-{
- hlt_counter--;
-}
-
-/*
- * We use this if we don't have any better
- * idle routine..
- */
static void default_idle(void)
{
- if ( hlt_counter == 0 )
- {
- __cli();
- if ( !softirq_pending(smp_processor_id()) )
- safe_halt();
- else
- __sti();
- }
+ __cli();
+ if ( !softirq_pending(smp_processor_id()) )
+ safe_halt();
+ else
+ __sti();
}
-void continue_cpu_idle_loop(void)
+static __attribute_used__ void idle_loop(void)
{
int cpu = smp_processor_id();
for ( ; ; )
@@ -102,7 +83,7 @@ void startup_cpu_idle_loop(void)
smp_mb();
init_idle();
- continue_cpu_idle_loop();
+ idle_loop();
}
static long no_idt[2];
@@ -216,20 +197,43 @@ void free_perdomain_pt(struct domain *d)
free_xenheap_page((unsigned long)d->mm.perdomain_pt);
}
+static void continue_idle_task(struct domain *d)
+{
+ reset_stack_and_jump(idle_loop);
+}
+
+static void continue_nonidle_task(struct domain *d)
+{
+ reset_stack_and_jump(ret_from_intr);
+}
+
void arch_do_createdomain(struct domain *d)
{
- d->shared_info = (void *)alloc_xenheap_page();
- memset(d->shared_info, 0, PAGE_SIZE);
- d->shared_info->arch.mfn_to_pfn_start =
- virt_to_phys(&machine_to_phys_mapping[0])>>PAGE_SHIFT;
- SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
- machine_to_phys_mapping[virt_to_phys(d->shared_info) >>
- PAGE_SHIFT] = INVALID_P2M_ENTRY;
-
- d->mm.perdomain_pt = (l1_pgentry_t *)alloc_xenheap_page();
- memset(d->mm.perdomain_pt, 0, PAGE_SIZE);
- machine_to_phys_mapping[virt_to_phys(d->mm.perdomain_pt) >>
- PAGE_SHIFT] = INVALID_P2M_ENTRY;
+#ifdef ARCH_HAS_FAST_TRAP
+ SET_DEFAULT_FAST_TRAP(&d->thread);
+#endif
+
+ if ( d->id == IDLE_DOMAIN_ID )
+ {
+ d->thread.schedule_tail = continue_idle_task;
+ }
+ else
+ {
+ d->thread.schedule_tail = continue_nonidle_task;
+
+ d->shared_info = (void *)alloc_xenheap_page();
+ memset(d->shared_info, 0, PAGE_SIZE);
+ d->shared_info->arch.mfn_to_pfn_start =
+ virt_to_phys(&machine_to_phys_mapping[0])>>PAGE_SHIFT;
+ SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
+ machine_to_phys_mapping[virt_to_phys(d->shared_info) >>
+ PAGE_SHIFT] = INVALID_P2M_ENTRY;
+
+ d->mm.perdomain_pt = (l1_pgentry_t *)alloc_xenheap_page();
+ memset(d->mm.perdomain_pt, 0, PAGE_SIZE);
+ machine_to_phys_mapping[virt_to_phys(d->mm.perdomain_pt) >>
+ PAGE_SHIFT] = INVALID_P2M_ENTRY;
+ }
}
int arch_final_setup_guestos(struct domain *d, full_execution_context_t *c)
@@ -263,7 +267,6 @@ int arch_final_setup_guestos(struct domain *d, full_execution_context_t *c)
sizeof(d->thread.traps));
#ifdef ARCH_HAS_FAST_TRAP
- SET_DEFAULT_FAST_TRAP(&d->thread);
if ( (rc = (int)set_fast_trap(d, c->fast_trap_idx)) != 0 )
return rc;
#endif
@@ -328,9 +331,6 @@ void new_thread(struct domain *d,
__save_flags(ec->eflags);
ec->eflags |= X86_EFLAGS_IF;
-
- /* No fast trap at start of day. */
- SET_DEFAULT_FAST_TRAP(&d->thread);
}
@@ -427,6 +427,8 @@ long do_iopl(domid_t domain, unsigned int new_io_pl)
return 0;
}
+#endif
+
unsigned long hypercall_create_continuation(
unsigned int op, unsigned int nr_args, ...)
{
@@ -448,11 +450,15 @@ unsigned long hypercall_create_continuation(
else
{
ec = get_execution_context();
+#if defined(__i386__)
ec->eax = op;
ec->eip -= 2; /* re-execute 'int 0x82' */
for ( i = 0, preg = &ec->ebx; i < nr_args; i++, preg++ )
*preg = va_arg(args, unsigned long);
+#else
+ preg = NULL; /* XXX x86/64 */
+#endif
}
va_end(args);
@@ -460,9 +466,6 @@ unsigned long hypercall_create_continuation(
return op;
}
-#endif
-
-
static void relinquish_list(struct domain *d, struct list_head *list)
{
struct list_head *ent;
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index cf6f7980e1..d2109f4fb8 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -328,6 +328,8 @@ void __init start_of_day(void)
sort_exception_tables();
+ arch_do_createdomain(current);
+
/* Tell the PCI layer not to allocate too close to the RAM area.. */
low_mem_size = ((max_page << PAGE_SHIFT) + 0xfffff) & ~0xfffff;
if ( low_mem_size > pci_mem_start ) pci_mem_start = low_mem_size;
diff --git a/xen/arch/x86/shadow.c b/xen/arch/x86/shadow.c
index 77b09551d9..aa4afc3cda 100644
--- a/xen/arch/x86/shadow.c
+++ b/xen/arch/x86/shadow.c
@@ -517,10 +517,10 @@ static void shadow_map_l1_into_current_l2(unsigned long va)
mk_l2_pgentry(spde);
gpl1e = (unsigned long *) &(linear_pg_table[
- (va>>PAGE_SHIFT) & ~(ENTRIES_PER_L1_PAGETABLE-1)]);
+ (va>>L1_PAGETABLE_SHIFT) & (ENTRIES_PER_L1_PAGETABLE-1)]);
- spl1e = (unsigned long *) &shadow_linear_pg_table[
- (va>>PAGE_SHIFT) & ~(ENTRIES_PER_L1_PAGETABLE-1)];
+ spl1e = (unsigned long *) &(shadow_linear_pg_table[
+ (va>>L1_PAGETABLE_SHIFT) & (ENTRIES_PER_L1_PAGETABLE-1)]);
for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ )
l1pte_propagate_from_guest(m, &gpl1e[i], &spl1e[i]);
diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c
index 05d49a27d0..991b5c577a 100644
--- a/xen/arch/x86/smpboot.c
+++ b/xen/arch/x86/smpboot.c
@@ -662,10 +662,6 @@ static void __init do_boot_cpu (int apicid)
map_cpu_to_boot_apicid(cpu, apicid);
-#if defined(__i386__)
- SET_DEFAULT_FAST_TRAP(&idle->thread);
-#endif
-
idle_task[cpu] = idle;
/* start_eip had better be page-aligned! */
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 842de24582..6837a143d3 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -981,4 +981,10 @@ unsigned long do_get_debugreg(int reg)
return current->thread.debugreg[reg];
}
+#else
+
+asmlinkage void fatal_trap(int trapnr, struct xen_regs *regs)
+{
+}
+
#endif /* __i386__ */
diff --git a/xen/arch/x86/x86_32/entry.S b/xen/arch/x86/x86_32/entry.S
index c85d84c649..d3df231fbb 100644
--- a/xen/arch/x86/x86_32/entry.S
+++ b/xen/arch/x86/x86_32/entry.S
@@ -56,7 +56,7 @@
#include <xen/config.h>
#include <xen/errno.h>
#include <xen/softirq.h>
-#include <asm/x86_32/asm_defns.h>
+#include <asm/asm_defns.h>
#include <public/xen.h>
#define GET_CURRENT(reg) \
@@ -65,10 +65,6 @@
andl $~3,reg; \
movl (reg),reg;
-ENTRY(continue_nonidle_task)
- GET_CURRENT(%ebx)
- jmp test_all_events
-
ALIGN
restore_all_guest:
testb $TF_failsafe_return,DOMAIN_thread_flags(%ebx)
diff --git a/xen/arch/x86/x86_32/mm.c b/xen/arch/x86/x86_32/mm.c
index ed95ca77e9..c22d527ac7 100644
--- a/xen/arch/x86/x86_32/mm.c
+++ b/xen/arch/x86/x86_32/mm.c
@@ -59,11 +59,13 @@ void __init paging_init(void)
void *ioremap_pt;
int i;
- /* Idle page table 1:1 maps the first part of physical memory. */
- for ( i = 0; i < DOMAIN_ENTRIES_PER_L2_PAGETABLE; i++ )
- idle_pg_table[i] =
- mk_l2_pgentry((i << L2_PAGETABLE_SHIFT) |
- __PAGE_HYPERVISOR | _PAGE_PSE);
+ /* Xen heap mappings can be GLOBAL. */
+ if ( cpu_has_pge )
+ {
+ for ( i = 0; i < DIRECTMAP_PHYS_END; i += (1 << L2_PAGETABLE_SHIFT) )
+ ((unsigned long *)idle_pg_table)
+ [(i + PAGE_OFFSET) >> L2_PAGETABLE_SHIFT] |= _PAGE_GLOBAL;
+ }
/* Create page table for ioremap(). */
ioremap_pt = (void *)alloc_xenheap_page();
@@ -86,7 +88,6 @@ void __init paging_init(void)
/* Set up linear page table mapping. */
idle_pg_table[LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT] =
mk_l2_pgentry(__pa(idle_pg_table) | __PAGE_HYPERVISOR);
-
}
void __init zap_low_mappings(void)
diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c
new file mode 100644
index 0000000000..2e6c3b396e
--- /dev/null
+++ b/xen/arch/x86/x86_64/asm-offsets.c
@@ -0,0 +1,71 @@
+/*
+ * Generate definitions needed by assembly language modules.
+ * This code generates raw asm output which is post-processed
+ * to extract and format the required data.
+ */
+
+#include <xen/sched.h>
+
+#define DEFINE(_sym, _val) \
+ __asm__ __volatile__ ( "\n->" #_sym " %0 " #_val : : "i" (_val) )
+#define BLANK() \
+ __asm__ __volatile__ ( "\n->" : : )
+#define OFFSET(_sym, _str, _mem) \
+ DEFINE(_sym, offsetof(_str, _mem));
+
+void __dummy__(void)
+{
+ OFFSET(XREGS_r15, struct xen_regs, r15);
+ OFFSET(XREGS_r14, struct xen_regs, r14);
+ OFFSET(XREGS_r13, struct xen_regs, r13);
+ OFFSET(XREGS_r12, struct xen_regs, r12);
+ OFFSET(XREGS_rbp, struct xen_regs, rbp);
+ OFFSET(XREGS_rbx, struct xen_regs, rbx);
+ OFFSET(XREGS_r11, struct xen_regs, r11);
+ OFFSET(XREGS_r10, struct xen_regs, r10);
+ OFFSET(XREGS_r9, struct xen_regs, r9);
+ OFFSET(XREGS_r8, struct xen_regs, r8);
+ OFFSET(XREGS_rax, struct xen_regs, rax);
+ OFFSET(XREGS_rcx, struct xen_regs, rcx);
+ OFFSET(XREGS_rdx, struct xen_regs, rdx);
+ OFFSET(XREGS_rsi, struct xen_regs, rsi);
+ OFFSET(XREGS_rdi, struct xen_regs, rdi);
+ OFFSET(XREGS_orig_rax, struct xen_regs, orig_rax);
+ OFFSET(XREGS_rip, struct xen_regs, rip);
+ OFFSET(XREGS_cs, struct xen_regs, cs);
+ OFFSET(XREGS_eflags, struct xen_regs, eflags);
+ OFFSET(XREGS_rsp, struct xen_regs, rsp);
+ OFFSET(XREGS_ss, struct xen_regs, ss);
+ BLANK();
+
+ OFFSET(DOMAIN_processor, struct domain, processor);
+ OFFSET(DOMAIN_shared_info, struct domain, shared_info);
+ OFFSET(DOMAIN_event_sel, struct domain, thread.event_selector);
+ OFFSET(DOMAIN_event_addr, struct domain, thread.event_address);
+ OFFSET(DOMAIN_failsafe_sel, struct domain, thread.failsafe_selector);
+ OFFSET(DOMAIN_failsafe_addr, struct domain, thread.failsafe_address);
+ OFFSET(DOMAIN_trap_bounce, struct domain, thread.trap_bounce);
+ OFFSET(DOMAIN_thread_flags, struct domain, thread.flags);
+ BLANK();
+
+ OFFSET(SHINFO_upcall_pending, shared_info_t,
+ vcpu_data[0].evtchn_upcall_pending);
+ OFFSET(SHINFO_upcall_mask, shared_info_t,
+ vcpu_data[0].evtchn_upcall_mask);
+ BLANK();
+
+ OFFSET(TRAPBOUNCE_error_code, struct trap_bounce, error_code);
+ OFFSET(TRAPBOUNCE_cr2, struct trap_bounce, cr2);
+ OFFSET(TRAPBOUNCE_flags, struct trap_bounce, flags);
+ OFFSET(TRAPBOUNCE_cs, struct trap_bounce, cs);
+ OFFSET(TRAPBOUNCE_eip, struct trap_bounce, eip);
+ BLANK();
+
+ OFFSET(MULTICALL_op, multicall_entry_t, op);
+ OFFSET(MULTICALL_arg0, multicall_entry_t, args[0]);
+ OFFSET(MULTICALL_arg1, multicall_entry_t, args[1]);
+ OFFSET(MULTICALL_arg2, multicall_entry_t, args[2]);
+ OFFSET(MULTICALL_arg3, multicall_entry_t, args[3]);
+ OFFSET(MULTICALL_arg4, multicall_entry_t, args[4]);
+ OFFSET(MULTICALL_result, multicall_entry_t, args[5]);
+}
diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c
new file mode 100644
index 0000000000..c7bcb17805
--- /dev/null
+++ b/xen/arch/x86/x86_64/mm.c
@@ -0,0 +1,455 @@
+/******************************************************************************
+ * arch/x86/x86_64/mm.c
+ *
+ * Modifications to Linux original are copyright (c) 2004, K A Fraser
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <xen/config.h>
+#include <xen/lib.h>
+#include <xen/init.h>
+#include <xen/mm.h>
+#include <asm/page.h>
+#include <asm/flushtlb.h>
+#include <asm/fixmap.h>
+#include <asm/domain_page.h>
+
+static inline void set_pte_phys(unsigned long vaddr,
+ l1_pgentry_t entry)
+{
+ l4_pgentry_t *l4ent;
+ l3_pgentry_t *l3ent;
+ l2_pgentry_t *l2ent;
+ l1_pgentry_t *l1ent;
+
+ l4ent = &idle_pg_table[l4_table_offset(vaddr)];
+ l3ent = l4_pgentry_to_l3(*l4ent) + l3_table_offset(vaddr);
+ l2ent = l3_pgentry_to_l2(*l3ent) + l2_table_offset(vaddr);
+ l1ent = l2_pgentry_to_l1(*l2ent) + l1_table_offset(vaddr);
+ *l1ent = entry;
+
+ /* It's enough to flush this one mapping. */
+ __flush_tlb_one(vaddr);
+}
+
+
+void __set_fixmap(enum fixed_addresses idx,
+ l1_pgentry_t entry)
+{
+ unsigned long address = fix_to_virt(idx);
+
+ if ( likely(idx < __end_of_fixed_addresses) )
+ set_pte_phys(address, entry);
+ else
+ printk("Invalid __set_fixmap\n");
+}
+
+
+void __init paging_init(void)
+{
+ void *ioremap_pt;
+ int i;
+
+ /* Create page table for ioremap(). */
+ ioremap_pt = (void *)alloc_xenheap_page();
+ clear_page(ioremap_pt);
+ idle_pg_table[IOREMAP_VIRT_START >> L2_PAGETABLE_SHIFT] =
+ mk_l2_pgentry(__pa(ioremap_pt) | __PAGE_HYPERVISOR);
+
+ /* Create read-only mapping of MPT for guest-OS use. */
+ idle_pg_table[RO_MPT_VIRT_START >> L2_PAGETABLE_SHIFT] =
+ mk_l2_pgentry(l2_pgentry_val(
+ idle_pg_table[RDWR_MPT_VIRT_START >> L2_PAGETABLE_SHIFT]) &
+ ~_PAGE_RW);
+
+ /* Set up mapping cache for domain pages. */
+ mapcache = (unsigned long *)alloc_xenheap_page();
+ clear_page(mapcache);
+ idle_pg_table[MAPCACHE_VIRT_START >> L2_PAGETABLE_SHIFT] =
+ mk_l2_pgentry(__pa(mapcache) | __PAGE_HYPERVISOR);
+
+ /* Set up linear page table mapping. */
+ idle_pg_table[LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT] =
+ mk_l2_pgentry(__pa(idle_pg_table) | __PAGE_HYPERVISOR);
+
+}
+
+void __init zap_low_mappings(void)
+{
+ idle_pg_table[0] = 0;
+}
+
+
+/*
+ * Allows shooting down of borrowed page-table use on specific CPUs.
+ * Specifically, we borrow page tables when running the idle domain.
+ */
+static void __synchronise_pagetables(void *mask)
+{
+ struct domain *d = current;
+ if ( ((unsigned long)mask & (1<<d->processor)) && is_idle_task(d) )
+ write_ptbase(&d->mm);
+}
+void synchronise_pagetables(unsigned long cpu_mask)
+{
+ __synchronise_pagetables((void *)cpu_mask);
+ smp_call_function(__synchronise_pagetables, (void *)cpu_mask, 1, 1);
+}
+
+long do_stack_switch(unsigned long ss, unsigned long esp)
+{
+ int nr = smp_processor_id();
+ struct tss_struct *t = &init_tss[nr];
+
+ /* We need to do this check as we load and use SS on guest's behalf. */
+ if ( (ss & 3) == 0 )
+ return -EPERM;
+
+ current->thread.guestos_ss = ss;
+ current->thread.guestos_sp = esp;
+ t->ss1 = ss;
+ t->esp1 = esp;
+
+ return 0;
+}
+
+
+/* Returns TRUE if given descriptor is valid for GDT or LDT. */
+int check_descriptor(unsigned long *d)
+{
+ unsigned long base, limit, a = d[0], b = d[1];
+
+ /* A not-present descriptor will always fault, so is safe. */
+ if ( !(b & _SEGMENT_P) )
+ goto good;
+
+ /*
+ * We don't allow a DPL of zero. There is no legitimate reason for
+ * specifying DPL==0, and it gets rather dangerous if we also accept call
+ * gates (consider a call gate pointing at another guestos descriptor with
+ * DPL 0 -- this would get the OS ring-0 privileges).
+ */
+ if ( (b & _SEGMENT_DPL) == 0 )
+ goto bad;
+
+ if ( !(b & _SEGMENT_S) )
+ {
+ /*
+ * System segment:
+ * 1. Don't allow interrupt or trap gates as they belong in the IDT.
+ * 2. Don't allow TSS descriptors or task gates as we don't
+ * virtualise x86 tasks.
+ * 3. Don't allow LDT descriptors because they're unnecessary and
+ * I'm uneasy about allowing an LDT page to contain LDT
+ * descriptors. In any case, Xen automatically creates the
+ * required descriptor when reloading the LDT register.
+ * 4. We allow call gates but they must not jump to a private segment.
+ */
+
+ /* Disallow everything but call gates. */
+ if ( (b & _SEGMENT_TYPE) != 0xc00 )
+ goto bad;
+
+ /* Can't allow far jump to a Xen-private segment. */
+ if ( !VALID_CODESEL(a>>16) )
+ goto bad;
+
+ /* Reserved bits must be zero. */
+ if ( (b & 0xe0) != 0 )
+ goto bad;
+
+ /* No base/limit check is needed for a call gate. */
+ goto good;
+ }
+
+ /* Check that base is at least a page away from Xen-private area. */
+ base = (b&(0xff<<24)) | ((b&0xff)<<16) | (a>>16);
+ if ( base >= (PAGE_OFFSET - PAGE_SIZE) )
+ goto bad;
+
+ /* Check and truncate the limit if necessary. */
+ limit = (b&0xf0000) | (a&0xffff);
+ limit++; /* We add one because limit is inclusive. */
+ if ( (b & _SEGMENT_G) )
+ limit <<= 12;
+
+ if ( (b & (_SEGMENT_CODE | _SEGMENT_EC)) == _SEGMENT_EC )
+ {
+ /*
+ * Grows-down limit check.
+ * NB. limit == 0xFFFFF provides no access (if G=1).
+ * limit == 0x00000 provides 4GB-4kB access (if G=1).
+ */
+ if ( (base + limit) > base )
+ {
+ limit = -(base & PAGE_MASK);
+ goto truncate;
+ }
+ }
+ else
+ {
+ /*
+ * Grows-up limit check.
+ * NB. limit == 0xFFFFF provides 4GB access (if G=1).
+ * limit == 0x00000 provides 4kB access (if G=1).
+ */
+ if ( ((base + limit) <= base) ||
+ ((base + limit) > PAGE_OFFSET) )
+ {
+ limit = PAGE_OFFSET - base;
+ truncate:
+ if ( !(b & _SEGMENT_G) )
+ goto bad; /* too dangerous; too hard to work out... */
+ limit = (limit >> 12) - 1;
+ d[0] &= ~0x0ffff; d[0] |= limit & 0x0ffff;
+ d[1] &= ~0xf0000; d[1] |= limit & 0xf0000;
+ }
+ }
+
+ good:
+ return 1;
+ bad:
+ return 0;
+}
+
+
+void destroy_gdt(struct domain *d)
+{
+ int i;
+ unsigned long pfn;
+
+ for ( i = 0; i < 16; i++ )
+ {
+ if ( (pfn = l1_pgentry_to_pagenr(d->mm.perdomain_pt[i])) != 0 )
+ put_page_and_type(&frame_table[pfn]);
+ d->mm.perdomain_pt[i] = mk_l1_pgentry(0);
+ }
+}
+
+
+long set_gdt(struct domain *d,
+ unsigned long *frames,
+ unsigned int entries)
+{
+ /* NB. There are 512 8-byte entries per GDT page. */
+ int i = 0, nr_pages = (entries + 511) / 512;
+ struct desc_struct *vgdt;
+ unsigned long pfn;
+
+ /* Check the first page in the new GDT. */
+ if ( (pfn = frames[0]) >= max_page )
+ goto fail;
+
+ /* The first page is special because Xen owns a range of entries in it. */
+ if ( !get_page_and_type(&frame_table[pfn], d, PGT_gdt_page) )
+ {
+ /* GDT checks failed: try zapping the Xen reserved entries. */
+ if ( !get_page_and_type(&frame_table[pfn], d, PGT_writable_page) )
+ goto fail;
+ vgdt = map_domain_mem(pfn << PAGE_SHIFT);
+ memset(vgdt + FIRST_RESERVED_GDT_ENTRY, 0,
+ NR_RESERVED_GDT_ENTRIES*8);
+ unmap_domain_mem(vgdt);
+ put_page_and_type(&frame_table[pfn]);
+
+ /* Okay, we zapped the entries. Now try the GDT checks again. */
+ if ( !get_page_and_type(&frame_table[pfn], d, PGT_gdt_page) )
+ goto fail;
+ }
+
+ /* Check the remaining pages in the new GDT. */
+ for ( i = 1; i < nr_pages; i++ )
+ if ( ((pfn = frames[i]) >= max_page) ||
+ !get_page_and_type(&frame_table[pfn], d, PGT_gdt_page) )
+ goto fail;
+
+ /* Copy reserved GDT entries to the new GDT. */
+ vgdt = map_domain_mem(frames[0] << PAGE_SHIFT);
+ memcpy(vgdt + FIRST_RESERVED_GDT_ENTRY,
+ gdt_table + FIRST_RESERVED_GDT_ENTRY,
+ NR_RESERVED_GDT_ENTRIES*8);
+ unmap_domain_mem(vgdt);
+
+ /* Tear down the old GDT. */
+ destroy_gdt(d);
+
+ /* Install the new GDT. */
+ for ( i = 0; i < nr_pages; i++ )
+ d->mm.perdomain_pt[i] =
+ mk_l1_pgentry((frames[i] << PAGE_SHIFT) | __PAGE_HYPERVISOR);
+
+ SET_GDT_ADDRESS(d, GDT_VIRT_START);
+ SET_GDT_ENTRIES(d, entries);
+
+ return 0;
+
+ fail:
+ while ( i-- > 0 )
+ put_page_and_type(&frame_table[frames[i]]);
+ return -EINVAL;
+}
+
+
+long do_set_gdt(unsigned long *frame_list, unsigned int entries)
+{
+ int nr_pages = (entries + 511) / 512;
+ unsigned long frames[16];
+ long ret;
+
+ if ( (entries <= LAST_RESERVED_GDT_ENTRY) || (entries > 8192) )
+ return -EINVAL;
+
+ if ( copy_from_user(frames, frame_list, nr_pages * sizeof(unsigned long)) )
+ return -EFAULT;
+
+ if ( (ret = set_gdt(current, frames, entries)) == 0 )
+ {
+ local_flush_tlb();
+ __asm__ __volatile__ ("lgdt %0" : "=m" (*current->mm.gdt));
+ }
+
+ return ret;
+}
+
+
+long do_update_descriptor(
+ unsigned long pa, unsigned long word1, unsigned long word2)
+{
+ unsigned long *gdt_pent, pfn = pa >> PAGE_SHIFT, d[2];
+ struct pfn_info *page;
+ long ret = -EINVAL;
+
+ d[0] = word1;
+ d[1] = word2;
+
+ if ( (pa & 7) || (pfn >= max_page) || !check_descriptor(d) )
+ return -EINVAL;
+
+ page = &frame_table[pfn];
+ if ( unlikely(!get_page(page, current)) )
+ return -EINVAL;
+
+ /* Check if the given frame is in use in an unsafe context. */
+ switch ( page->u.inuse.type_info & PGT_type_mask )
+ {
+ case PGT_gdt_page:
+ /* Disallow updates of Xen-reserved descriptors in the current GDT. */
+ if ( (l1_pgentry_to_pagenr(current->mm.perdomain_pt[0]) == pfn) &&
+ (((pa&(PAGE_SIZE-1))>>3) >= FIRST_RESERVED_GDT_ENTRY) &&
+ (((pa&(PAGE_SIZE-1))>>3) <= LAST_RESERVED_GDT_ENTRY) )
+ goto out;
+ if ( unlikely(!get_page_type(page, PGT_gdt_page)) )
+ goto out;
+ break;
+ case PGT_ldt_page:
+ if ( unlikely(!get_page_type(page, PGT_ldt_page)) )
+ goto out;
+ break;
+ default:
+ if ( unlikely(!get_page_type(page, PGT_writable_page)) )
+ goto out;
+ break;
+ }
+
+ /* All is good so make the update. */
+ gdt_pent = map_domain_mem(pa);
+ memcpy(gdt_pent, d, 8);
+ unmap_domain_mem(gdt_pent);
+
+ put_page_type(page);
+
+ ret = 0; /* success */
+
+ out:
+ put_page(page);
+ return ret;
+}
+
+#ifdef MEMORY_GUARD
+
+void *memguard_init(void *heap_start)
+{
+ l1_pgentry_t *l1;
+ int i, j;
+
+ /* Round the allocation pointer up to a page boundary. */
+ heap_start = (void *)(((unsigned long)heap_start + (PAGE_SIZE-1)) &
+ PAGE_MASK);
+
+ /* Memory guarding is incompatible with super pages. */
+ for ( i = 0; i < (xenheap_phys_end >> L2_PAGETABLE_SHIFT); i++ )
+ {
+ l1 = (l1_pgentry_t *)heap_start;
+ heap_start = (void *)((unsigned long)heap_start + PAGE_SIZE);
+ for ( j = 0; j < ENTRIES_PER_L1_PAGETABLE; j++ )
+ l1[j] = mk_l1_pgentry((i << L2_PAGETABLE_SHIFT) |
+ (j << L1_PAGETABLE_SHIFT) |
+ __PAGE_HYPERVISOR);
+ idle_pg_table[i] = idle_pg_table[i + l2_table_offset(PAGE_OFFSET)] =
+ mk_l2_pgentry(virt_to_phys(l1) | __PAGE_HYPERVISOR);
+ }
+
+ return heap_start;
+}
+
+static void __memguard_change_range(void *p, unsigned long l, int guard)
+{
+ l1_pgentry_t *l1;
+ l2_pgentry_t *l2;
+ unsigned long _p = (unsigned long)p;
+ unsigned long _l = (unsigned long)l;
+
+ /* Ensure we are dealing with a page-aligned whole number of pages. */
+ ASSERT((_p&PAGE_MASK) != 0);
+ ASSERT((_l&PAGE_MASK) != 0);
+ ASSERT((_p&~PAGE_MASK) == 0);
+ ASSERT((_l&~PAGE_MASK) == 0);
+
+ while ( _l != 0 )
+ {
+ l2 = &idle_pg_table[l2_table_offset(_p)];
+ l1 = l2_pgentry_to_l1(*l2) + l1_table_offset(_p);
+ if ( guard )
+ *l1 = mk_l1_pgentry(l1_pgentry_val(*l1) & ~_PAGE_PRESENT);
+ else
+ *l1 = mk_l1_pgentry(l1_pgentry_val(*l1) | _PAGE_PRESENT);
+ _p += PAGE_SIZE;
+ _l -= PAGE_SIZE;
+ }
+}
+
+void memguard_guard_range(void *p, unsigned long l)
+{
+ __memguard_change_range(p, l, 1);
+ local_flush_tlb();
+}
+
+void memguard_unguard_range(void *p, unsigned long l)
+{
+ __memguard_change_range(p, l, 0);
+}
+
+int memguard_is_guarded(void *p)
+{
+ l1_pgentry_t *l1;
+ l2_pgentry_t *l2;
+ unsigned long _p = (unsigned long)p;
+ l2 = &idle_pg_table[l2_table_offset(_p)];
+ l1 = l2_pgentry_to_l1(*l2) + l1_table_offset(_p);
+ return !(l1_pgentry_val(*l1) & _PAGE_PRESENT);
+}
+
+#endif
diff --git a/xen/arch/x86/x86_64/xen.lds b/xen/arch/x86/x86_64/xen.lds
index 4763fdf55a..8a6b3a27ac 100644
--- a/xen/arch/x86/x86_64/xen.lds
+++ b/xen/arch/x86/x86_64/xen.lds
@@ -28,6 +28,11 @@ SECTIONS
__ex_table : { *(__ex_table) } :text
__stop___ex_table = .;
+ . = ALIGN(16); /* Pre-exception table */
+ __start___pre_ex_table = .;
+ __pre_ex_table : { *(__pre_ex_table) } :text
+ __stop___pre_ex_table = .;
+
__start___ksymtab = .; /* Kernel symbol table */
__ksymtab : { *(__ksymtab) } :text
__stop___ksymtab = .;
diff --git a/xen/common/domain.c b/xen/common/domain.c
index d4a97d307a..ed18817cec 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -47,20 +47,21 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu)
/* Per-domain PCI-device list. */
spin_lock_init(&d->pcidev_lock);
INIT_LIST_HEAD(&d->pcidev_list);
+
+ if ( (d->id != IDLE_DOMAIN_ID) &&
+ ((init_event_channels(d) != 0) || (grant_table_create(d) != 0)) )
+ {
+ destroy_event_channels(d);
+ free_domain_struct(d);
+ return NULL;
+ }
+
+ arch_do_createdomain(d);
+
+ sched_add_domain(d);
if ( d->id != IDLE_DOMAIN_ID )
{
- if ( (init_event_channels(d) != 0) || (grant_table_create(d) != 0) )
- {
- destroy_event_channels(d);
- free_domain_struct(d);
- return NULL;
- }
-
- arch_do_createdomain(d);
-
- sched_add_domain(d);
-
write_lock(&domlist_lock);
pd = &domain_list; /* NB. domain_list maintained in order of dom_id. */
for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_list )
@@ -72,10 +73,6 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu)
domain_hash[DOMAIN_HASH(dom_id)] = d;
write_unlock(&domlist_lock);
}
- else
- {
- sched_add_domain(d);
- }
return d;
}
diff --git a/xen/common/physdev.c b/xen/common/physdev.c
index 728a8fe07f..a2559e5223 100644
--- a/xen/common/physdev.c
+++ b/xen/common/physdev.c
@@ -742,7 +742,8 @@ void physdev_init_dom0(struct domain *p)
*
* In Linux2.6 we set pcibios_scan_all_fns().
*/
- if ( dev->hdr_type != PCI_HEADER_TYPE_NORMAL )
+ if ( (dev->hdr_type != PCI_HEADER_TYPE_NORMAL) &&
+ (dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) )
continue;
pdev = xmalloc(sizeof(phys_dev_t));
pdev->dev = dev;
diff --git a/xen/include/asm-x86/asm_defns.h b/xen/include/asm-x86/asm_defns.h
new file mode 100644
index 0000000000..0fb3e44727
--- /dev/null
+++ b/xen/include/asm-x86/asm_defns.h
@@ -0,0 +1,18 @@
+
+#ifndef __X86_ASM_DEFNS_H__
+#define __X86_ASM_DEFNS_H__
+
+/* NB. Auto-generated from arch/.../asm-offsets.c */
+#include <asm/asm-offsets.h>
+#include <asm/processor.h>
+
+#define __STR(x) #x
+#define STR(x) __STR(x)
+
+#ifdef __x86_64__
+#include <asm/x86_64/asm_defns.h>
+#else
+#include <asm/x86_32/asm_defns.h>
+#endif
+
+#endif /* __X86_ASM_DEFNS_H__ */
diff --git a/xen/include/asm-x86/irq.h b/xen/include/asm-x86/irq.h
index b07fef7809..2779282659 100644
--- a/xen/include/asm-x86/irq.h
+++ b/xen/include/asm-x86/irq.h
@@ -5,7 +5,7 @@
#include <xen/config.h>
#include <asm/atomic.h>
-#include <asm/x86_32/asm_defns.h>
+#include <asm/asm_defns.h>
extern void disable_irq(unsigned int);
extern void disable_irq_nosync(unsigned int);
diff --git a/xen/include/asm-x86/multicall.h b/xen/include/asm-x86/multicall.h
index e1a7770354..d03ac9ffb1 100644
--- a/xen/include/asm-x86/multicall.h
+++ b/xen/include/asm-x86/multicall.h
@@ -5,7 +5,13 @@
#ifndef __ASM_X86_MULTICALL_H__
#define __ASM_X86_MULTICALL_H__
-#include <asm-x86/x86_32/asm_defns.h>
+#include <asm/asm_defns.h>
+
+#ifdef __x86_64__
+
+#define do_multicall_call(_call) BUG()
+
+#else
#define do_multicall_call(_call) \
do { \
@@ -23,4 +29,6 @@
: : "b" (_call) : "eax", "ecx", "edx" ); \
} while ( 0 )
+#endif
+
#endif /* __ASM_X86_MULTICALL_H__ */
diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h
index c5ccb59fa3..ae5b13b7d1 100644
--- a/xen/include/asm-x86/processor.h
+++ b/xen/include/asm-x86/processor.h
@@ -254,18 +254,18 @@ static inline unsigned int cpuid_edx(unsigned int op)
})
#define write_cr0(x) \
- __asm__("mov"__OS" %0,%%cr0": :"r" (x));
+ __asm__("mov"__OS" %0,%%cr0": :"r" ((unsigned long)x));
#define read_cr4() ({ \
- unsigned int __dummy; \
+ unsigned long __dummy; \
__asm__( \
- "movl %%cr4,%0\n\t" \
+ "mov"__OS" %%cr4,%0\n\t" \
:"=r" (__dummy)); \
__dummy; \
})
#define write_cr4(x) \
- __asm__("movl %0,%%cr4": :"r" (x));
+ __asm__("mov"__OS" %0,%%cr4": :"r" ((unsigned long)x));
/*
* Save the cr4 feature set we're using (ie
@@ -290,7 +290,7 @@ static inline void clear_in_cr4 (unsigned long mask)
mmu_cr4_features &= ~mask;
__asm__("mov"__OS" %%cr4,%%"__OP"ax\n\t"
"and"__OS" %0,%%"__OP"ax\n\t"
- "movl"__OS" %%"__OP"ax,%%cr4\n"
+ "mov"__OS" %%"__OP"ax,%%cr4\n"
: : "irg" (~mask)
:"ax");
}
@@ -399,6 +399,8 @@ struct thread_struct {
/* general user-visible register state */
execution_context_t user_ctxt;
+ void (*schedule_tail) (struct domain *);
+
/*
* Return vectors pushed to us by guest OS.
* The stack frame for events is exactly that of an x86 hardware interrupt.
@@ -456,14 +458,10 @@ extern struct desc_struct *idt_tables[];
long set_fast_trap(struct domain *p, int idx);
-#define INIT_THREAD { fast_trap_idx: 0x20 }
-
-#elif defined(__x86_64__)
+#endif
#define INIT_THREAD { 0 }
-#endif /* __x86_64__ */
-
extern int gpf_emulate_4gb(struct xen_regs *regs);
struct mm_struct {
diff --git a/xen/include/asm-x86/system.h b/xen/include/asm-x86/system.h
index e2c961e360..18854edc3f 100644
--- a/xen/include/asm-x86/system.h
+++ b/xen/include/asm-x86/system.h
@@ -271,13 +271,6 @@ static inline int local_irq_is_enabled(void)
return !!(flags & (1<<9)); /* EFLAGS_IF */
}
-/*
- * disable hlt during certain critical i/o operations
- */
-#define HAVE_DISABLE_HLT
-void disable_hlt(void);
-void enable_hlt(void);
-
#define BROKEN_ACPI_Sx 0x0001
#define BROKEN_INIT_AFTER_S1 0x0002
diff --git a/xen/include/asm-x86/uaccess.h b/xen/include/asm-x86/uaccess.h
index 52a8b25c56..46c02ecef4 100644
--- a/xen/include/asm-x86/uaccess.h
+++ b/xen/include/asm-x86/uaccess.h
@@ -1,6 +1,32 @@
+#ifndef __X86_UACCESS_H__
+#define __X86_UACCESS_H__
+
#ifdef __x86_64__
#include <asm/x86_64/uaccess.h>
#else
#include <asm/x86_32/uaccess.h>
#endif
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue. No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path. This means when everything is well,
+ * we don't even have to jump over them. Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry
+{
+ unsigned long insn, fixup;
+};
+
+extern unsigned long search_exception_table(unsigned long);
+extern void sort_exception_tables(void);
+
+#endif /* __X86_UACCESS_H__ */
diff --git a/xen/include/asm-x86/x86_32/asm_defns.h b/xen/include/asm-x86/x86_32/asm_defns.h
index 8231bb2dec..e11ea34964 100644
--- a/xen/include/asm-x86/x86_32/asm_defns.h
+++ b/xen/include/asm-x86/x86_32/asm_defns.h
@@ -1,12 +1,5 @@
-#ifndef __ASM_DEFNS_H__
-#define __ASM_DEFNS_H__
-
-/* NB. Auto-generated from arch/.../asm-offsets.c */
-#include <asm/asm-offsets.h>
-#include <asm/processor.h>
-
-#define __STR(x) #x
-#define STR(x) __STR(x)
+#ifndef __X86_32_ASM_DEFNS_H__
+#define __X86_32_ASM_DEFNS_H__
/* Maybe auto-generate the following two cases (quoted vs. unquoted). */
#ifndef __ASSEMBLY__
@@ -85,4 +78,4 @@
#endif
-#endif /* __ASM_DEFNS_H__ */
+#endif /* __X86_32_ASM_DEFNS_H__ */
diff --git a/xen/include/asm-x86/x86_32/current.h b/xen/include/asm-x86/x86_32/current.h
index 3450cd02cc..2c76a133aa 100644
--- a/xen/include/asm-x86/x86_32/current.h
+++ b/xen/include/asm-x86/x86_32/current.h
@@ -45,14 +45,11 @@ static inline unsigned long get_stack_top(void)
return p;
}
-#define schedule_tail(_p) \
+#define reset_stack_and_jump(__fn) \
__asm__ __volatile__ ( \
- "andl %%esp,%0; addl %2,%0; movl %0,%%esp; jmp *%1" \
- : : "r" (~(STACK_SIZE-1)), \
- "r" (unlikely(is_idle_task((_p))) ? \
- continue_cpu_idle_loop : \
- continue_nonidle_task), \
- "i" (STACK_SIZE-STACK_RESERVED) )
+ "movl %0,%%esp; jmp "STR(__fn) \
+ : : "r" (get_execution_context()) )
+#define schedule_tail(_d) ((_d)->thread.schedule_tail)(_d)
#endif /* _X86_CURRENT_H */
diff --git a/xen/include/asm-x86/x86_32/uaccess.h b/xen/include/asm-x86/x86_32/uaccess.h
index 650492d59e..b202a1a12b 100644
--- a/xen/include/asm-x86/x86_32/uaccess.h
+++ b/xen/include/asm-x86/x86_32/uaccess.h
@@ -69,27 +69,6 @@ extern struct movsl_mask {
#define array_access_ok(type,addr,count,size) \
(likely(count < (~0UL/size)) && access_ok(type,addr,count*size))
-/*
- * The exception table consists of pairs of addresses: the first is the
- * address of an instruction that is allowed to fault, and the second is
- * the address at which the program should continue. No registers are
- * modified, so it is entirely up to the continuation code to figure out
- * what to do.
- *
- * All the routines below use bits of fixup code that are out of line
- * with the main instruction path. This means when everything is well,
- * we don't even have to jump over them. Further, they do not intrude
- * on our cache or tlb entries.
- */
-
-struct exception_table_entry
-{
- unsigned long insn, fixup;
-};
-
-extern unsigned long search_exception_table(unsigned long);
-extern void sort_exception_tables(void);
-
/**
* get_user: - Get a simple variable from user space.
* @x: Variable to store result.
diff --git a/xen/include/asm-x86/x86_64/asm_defns.h b/xen/include/asm-x86/x86_64/asm_defns.h
new file mode 100644
index 0000000000..fa0b978304
--- /dev/null
+++ b/xen/include/asm-x86/x86_64/asm_defns.h
@@ -0,0 +1,6 @@
+#ifndef __X86_64_ASM_DEFNS_H__
+#define __X86_64_ASM_DEFNS_H__
+
+#define SAVE_ALL(_r) ""
+
+#endif /* __X86_64_ASM_DEFNS_H__ */
diff --git a/xen/include/asm-x86/x86_64/current.h b/xen/include/asm-x86/x86_64/current.h
index 2f3a6e5665..2ee550643b 100644
--- a/xen/include/asm-x86/x86_64/current.h
+++ b/xen/include/asm-x86/x86_64/current.h
@@ -40,15 +40,12 @@ static inline unsigned long get_stack_top(void)
return p;
}
-#define schedule_tail(_p) \
+#define reset_stack_and_jump(__fn) \
__asm__ __volatile__ ( \
- "andq %%rsp,%0; addq %2,%0; movq %0,%%rsp; jmp *%1" \
- : : "r" (~(STACK_SIZE-1)), \
- "r" (unlikely(is_idle_task((_p))) ? \
- continue_cpu_idle_loop : \
- continue_nonidle_task), \
- "i" (STACK_SIZE-STACK_RESERVED) )
+ "movq %0,%%rsp; jmp "STR(__fn) \
+ : : "r" (get_execution_context()) )
+#define schedule_tail(_d) ((_d)->thread.schedule_tail)(_d)
#else
diff --git a/xen/include/asm-x86/x86_64/uaccess.h b/xen/include/asm-x86/x86_64/uaccess.h
index be49ff870b..f965c87d32 100644
--- a/xen/include/asm-x86/x86_64/uaccess.h
+++ b/xen/include/asm-x86/x86_64/uaccess.h
@@ -35,31 +35,15 @@
#define access_ok(type, addr, size) (__range_not_ok(addr,size) == 0)
+#define array_access_ok(type,addr,count,size) \
+ (likely(sizeof(count) <= 4) /* disallow 64-bit counts */ && \
+ access_ok(type,addr,count*size))
+
extern inline int verify_area(int type, const void __user * addr, unsigned long size)
{
return access_ok(type,addr,size) ? 0 : -EFAULT;
}
-
-/*
- * The exception table consists of pairs of addresses: the first is the
- * address of an instruction that is allowed to fault, and the second is
- * the address at which the program should continue. No registers are
- * modified, so it is entirely up to the continuation code to figure out
- * what to do.
- *
- * All the routines below use bits of fixup code that are out of line
- * with the main instruction path. This means when everything is well,
- * we don't even have to jump over them. Further, they do not intrude
- * on our cache or tlb entries.
- */
-
-struct exception_table_entry
-{
- unsigned long insn, fixup;
-};
-
-
/*
* These are the main single-value transfer routines. They automatically
* use the right size if we just have the right pointer type.
diff --git a/xen/include/public/arch-x86_32.h b/xen/include/public/arch-x86_32.h
index dee8b783ef..b7210fc1b5 100644
--- a/xen/include/public/arch-x86_32.h
+++ b/xen/include/public/arch-x86_32.h
@@ -2,6 +2,8 @@
* arch-x86_32.h
*
* Guest OS interface to x86 32-bit Xen.
+ *
+ * Copyright (c) 2004, K A Fraser
*/
#ifndef __XEN_PUBLIC_ARCH_X86_32_H__
diff --git a/xen/include/public/arch-x86_64.h b/xen/include/public/arch-x86_64.h
index 856b5070a8..2144b0d63b 100644
--- a/xen/include/public/arch-x86_64.h
+++ b/xen/include/public/arch-x86_64.h
@@ -2,6 +2,8 @@
* arch-x86_64.h
*
* Guest OS interface to x86 64-bit Xen.
+ *
+ * Copyright (c) 2004, K A Fraser
*/
#ifndef __XEN_PUBLIC_ARCH_X86_64_H__
diff --git a/xen/include/public/io/domain_controller.h b/xen/include/public/io/domain_controller.h
index 5a4056cd4d..c248f21419 100644
--- a/xen/include/public/io/domain_controller.h
+++ b/xen/include/public/io/domain_controller.h
@@ -555,6 +555,7 @@ typedef struct {
#define CMSG_SHUTDOWN_REBOOT 1 /* Clean shutdown (SHUTDOWN_reboot). */
#define CMSG_SHUTDOWN_SUSPEND 2 /* Create suspend info, then */
/* SHUTDOWN_suspend. */
+#define CMSG_SHUTDOWN_SYSRQ 3
/******************************************************************************
diff --git a/xen/include/public/trace.h b/xen/include/public/trace.h
index 5e7904d52a..e4ee78b975 100644
--- a/xen/include/public/trace.h
+++ b/xen/include/public/trace.h
@@ -1,5 +1,7 @@
/******************************************************************************
* trace.h
+ *
+ * Mark Williamson, (C) 2004 Intel Research Cambridge
*/
#ifndef __XEN_PUBLIC_TRACE_H__
diff --git a/xen/include/asm-x86/domain.h b/xen/include/xen/domain.h
index 7dde4efa6d..5ff5ed62ad 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/xen/domain.h
@@ -1,6 +1,12 @@
-#ifndef __ASM_X86_DOMAIN_H__
-#define __ASM_X86_DOMAIN_H__
+#ifndef __XEN_DOMAIN_H__
+#define __XEN_DOMAIN_H__
+
+
+
+/*
+ * Arch-specifics.
+ */
extern void arch_do_createdomain(struct domain *d);
@@ -11,4 +17,4 @@ extern void free_perdomain_pt(struct domain *d);
extern void domain_relinquish_memory(struct domain *d);
-#endif /* __ASM_X86_DOMAIN_H__ */
+#endif /* __XEN_DOMAIN_H__ */
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index c8781f0440..d7e6f0be26 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -214,9 +214,6 @@ void domain_init(void);
int idle_cpu(int cpu); /* Is CPU 'cpu' idle right now? */
void startup_cpu_idle_loop(void);
-void continue_cpu_idle_loop(void);
-
-void continue_nonidle_task(void);
unsigned long hypercall_create_continuation(
unsigned int op, unsigned int nr_args, ...);
@@ -295,6 +292,6 @@ static inline void domain_unpause_by_systemcontroller(struct domain *d)
#define VM_ASSIST(_d,_t) (test_bit((_t), &(_d)->vm_assist))
#include <xen/slab.h>
-#include <asm/domain.h>
+#include <xen/domain.h>
#endif /* __SCHED_H__ */