# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1171479695 0
# Node ID 9af0c7e4ff513c02f9bd1548f21612e9cf59b022
# Parent aea80dbf6d96cbddbb652e7c4ef642778605ba76
# Parent 58e71ae679d5d2e602886297c134f12148540f47
Merge with xenppc-unstable.hg
---
linux-2.6-xen-sparse/include/asm-i386/a.out.h | 26
xen/include/asm-ia64/kexec.h | 25
xen/include/asm-ia64/linux/asm/percpu.h | 72
xen/include/asm-powerpc/kexec.h | 25
xen/include/asm-x86/kexec.h | 20
xen/include/asm-x86/x86_32/kexec.h | 39
xen/include/asm-x86/x86_64/kexec.h | 38
.hgignore | 2
buildconfigs/linux-defconfig_xen0_ia64 | 219 +-
buildconfigs/linux-defconfig_xenU_ia64 | 192 +
buildconfigs/linux-defconfig_xen_ia64 | 210 +-
extras/mini-os/gnttab.c | 5
extras/mini-os/netfront.c | 4
linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S | 22
linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c | 73
linux-2.6-xen-sparse/arch/ia64/kernel/setup.c | 11
linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c | 6
linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S | 16
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c | 5
linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c | 5
linux-2.6-xen-sparse/drivers/xen/core/evtchn.c | 6
linux-2.6-xen-sparse/drivers/xen/core/reboot.c | 3
linux-2.6-xen-sparse/drivers/xen/fbfront/xenkbd.c | 103 -
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c | 2
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c | 6
linux-2.6-xen-sparse/include/asm-ia64/hw_irq.h | 5
linux-2.6-xen-sparse/include/asm-ia64/maddr.h | 3
linux-2.6-xen-sparse/include/asm-ia64/page.h | 45
linux-2.6-xen-sparse/net/core/skbuff.c | 46
patches/linux-2.6.18/series | 1
patches/linux-2.6.18/softlockup-no-idle-hz.patch | 32
tools/examples/block | 8
tools/examples/vif-bridge | 7
tools/examples/xen-hotplug-common.sh | 5
tools/firmware/rombios/32bit/tcgbios/tcgbios.c | 14
tools/firmware/rombios/32bit/tcgbios/tpm_drivers.c | 52
tools/firmware/rombios/32bit/util.h | 15
tools/firmware/rombios/rombios.c | 13
tools/ioemu/hw/cirrus_vga.c | 4
tools/ioemu/hw/ide.c | 4
tools/ioemu/hw/rtl8139.c | 6
tools/ioemu/hw/tpm_tis.c | 13
tools/ioemu/xenstore.c | 60
tools/libxc/xc_domain.c | 8
tools/libxc/xc_hvm_restore.c | 61
tools/libxc/xc_hvm_save.c | 91
tools/libxc/xenguest.h | 5
tools/libxc/xg_private.c | 5
tools/misc/Makefile | 6
tools/misc/xen-detect.c | 108 +
tools/python/xen/xend/XendCheckpoint.py | 7
tools/python/xen/xend/XendConfig.py | 41
tools/python/xen/xend/XendDomain.py | 20
tools/python/xen/xend/XendDomainInfo.py | 58
tools/python/xen/xend/server/BlktapController.py | 62
tools/python/xen/xend/server/DevController.py | 52
tools/xcutils/xc_restore.c | 15
tools/xenfb/vncfb.c | 10
tools/xentrace/xentrace_format | 3
unmodified_drivers/linux-2.6/overrides.mk | 3
unmodified_drivers/linux-2.6/platform-pci/platform-compat.c | 6
unmodified_drivers/linux-2.6/platform-pci/platform-pci.c | 35
unmodified_drivers/linux-2.6/platform-pci/xen_support.c | 17
xen/arch/ia64/Rules.mk | 4
xen/arch/ia64/asm-offsets.c | 2
xen/arch/ia64/asm-xsi-offsets.c | 2
xen/arch/ia64/linux-xen/head.S | 16
xen/arch/ia64/linux-xen/mca.c | 80
xen/arch/ia64/vmx/optvfault.S | 75
xen/arch/ia64/vmx/vlsapic.c | 7
xen/arch/ia64/vmx/vmmu.c | 52
xen/arch/ia64/vmx/vmx_entry.S | 332 +--
xen/arch/ia64/vmx/vmx_init.c | 7
xen/arch/ia64/vmx/vmx_interrupt.c | 2
xen/arch/ia64/vmx/vmx_ivt.S | 295 ++
xen/arch/ia64/vmx/vmx_minstate.h | 1
xen/arch/ia64/vmx/vmx_phy_mode.c | 2
xen/arch/ia64/vmx/vmx_process.c | 90
xen/arch/ia64/vmx/vmx_vcpu.c | 20
xen/arch/ia64/vmx/vmx_virt.c | 4
xen/arch/ia64/vmx/vtlb.c | 12
xen/arch/ia64/xen/dom_fw.c | 12
xen/arch/ia64/xen/domain.c | 182 -
xen/arch/ia64/xen/faults.c | 20
xen/arch/ia64/xen/flushtlb.c | 42
xen/arch/ia64/xen/fw_emul.c | 11
xen/arch/ia64/xen/hyperprivop.S | 39
xen/arch/ia64/xen/mm.c | 27
xen/arch/ia64/xen/vcpu.c | 46
xen/arch/ia64/xen/vhpt.c | 8
xen/arch/ia64/xen/xensetup.c | 24
xen/arch/powerpc/machine_kexec.c | 5
xen/arch/x86/crash.c | 1
xen/arch/x86/domain.c | 52
xen/arch/x86/domain_build.c | 10
xen/arch/x86/domctl.c | 36
xen/arch/x86/hvm/Makefile | 1
xen/arch/x86/hvm/hpet.c | 2
xen/arch/x86/hvm/hvm.c | 47
xen/arch/x86/hvm/i8254.c | 2
xen/arch/x86/hvm/intercept.c | 176 -
xen/arch/x86/hvm/io.c | 2
xen/arch/x86/hvm/irq.c | 9
xen/arch/x86/hvm/platform.c | 65
xen/arch/x86/hvm/pmtimer.c | 75
xen/arch/x86/hvm/rtc.c | 2
xen/arch/x86/hvm/save.c | 229 ++
xen/arch/x86/hvm/svm/intr.c | 2
xen/arch/x86/hvm/svm/svm.c | 34
xen/arch/x86/hvm/svm/vmcb.c | 7
xen/arch/x86/hvm/vioapic.c | 2
xen/arch/x86/hvm/vlapic.c | 24
xen/arch/x86/hvm/vmx/vmcs.c | 18
xen/arch/x86/hvm/vmx/vmx.c | 34
xen/arch/x86/hvm/vpic.c | 2
xen/arch/x86/machine_kexec.c | 53
xen/arch/x86/mm.c | 107 -
xen/arch/x86/mm/Makefile | 3
xen/arch/x86/mm/p2m.c | 699 +++++++
xen/arch/x86/mm/paging.c | 143 +
xen/arch/x86/mm/shadow/common.c | 1197 +++---------
xen/arch/x86/mm/shadow/multi.c | 253 +-
xen/arch/x86/mm/shadow/multi.h | 2
xen/arch/x86/mm/shadow/page-guest32.h | 5
xen/arch/x86/mm/shadow/private.h | 107 -
xen/arch/x86/mm/shadow/types.h | 12
xen/arch/x86/setup.c | 2
xen/arch/x86/sysctl.c | 1
xen/arch/x86/traps.c | 10
xen/arch/x86/x86_32/domain_page.c | 1
xen/arch/x86/x86_32/entry.S | 107 -
xen/arch/x86/x86_64/Makefile | 4
xen/arch/x86/x86_64/compat/Makefile | 2
xen/arch/x86/x86_64/compat/entry.S | 91
xen/arch/x86/x86_64/compat_kexec.S | 126 +
xen/arch/x86/x86_64/entry.S | 56
xen/arch/x86/x86_64/traps.c | 1
xen/common/kexec.c | 1
xen/common/libelf/libelf-dominfo.c | 557 ++---
xen/common/libelf/libelf-loader.c | 127 -
xen/common/libelf/libelf-private.h | 26
xen/common/libelf/libelf-relocate.c | 375 +--
xen/common/libelf/libelf-tools.c | 153 -
xen/common/memory.c | 10
xen/drivers/char/console.c | 14
xen/include/asm-ia64/config.h | 4
xen/include/asm-ia64/domain.h | 5
xen/include/asm-ia64/flushtlb.h | 1
xen/include/asm-ia64/linux-xen/asm/README.origin | 1
xen/include/asm-ia64/linux-xen/asm/io.h | 2
xen/include/asm-ia64/linux-xen/asm/percpu.h | 77
xen/include/asm-ia64/linux-xen/linux/efi.h | 4
xen/include/asm-ia64/linux/asm/README.origin | 1
xen/include/asm-ia64/vcpu.h | 1
xen/include/asm-ia64/vmmu.h | 3
xen/include/asm-ia64/vmx.h | 2
xen/include/asm-ia64/vmx_mm_def.h | 4
xen/include/asm-ia64/vmx_vcpu.h | 21
xen/include/asm-ia64/vmx_vpd.h | 9
xen/include/asm-ia64/xenkregs.h | 4
xen/include/asm-x86/config.h | 4
xen/include/asm-x86/cpufeature.h | 1
xen/include/asm-x86/domain.h | 96
xen/include/asm-x86/hvm/hvm.h | 1
xen/include/asm-x86/hvm/support.h | 34
xen/include/asm-x86/hvm/vlapic.h | 2
xen/include/asm-x86/hvm/vpt.h | 14
xen/include/asm-x86/mm.h | 63
xen/include/asm-x86/p2m.h | 142 +
xen/include/asm-x86/page.h | 5
xen/include/asm-x86/paging.h | 376 +++
xen/include/asm-x86/shadow.h | 380 ---
xen/include/public/arch-ia64.h | 10
xen/include/public/domctl.h | 3
xen/include/public/hvm/save.h | 12
xen/include/xen/kexec.h | 1
176 files changed, 5986 insertions(+), 3874 deletions(-)
diff -r aea80dbf6d96 -r 9af0c7e4ff51 .hgignore
--- a/.hgignore Fri Feb 09 14:43:22 2007 -0600
+++ b/.hgignore Wed Feb 14 19:01:35 2007 +0000
@@ -107,6 +107,7 @@
^tools/firmware/rombios/BIOS-bochs-[^/]*$
^tools/firmware/rombios/_rombios[^/]*_\.c$
^tools/firmware/rombios/rombios[^/]*\.s$
+^tools/firmware/rombios/32bit/32bitbios_flat\.h$
^tools/firmware/vmxassist/gen$
^tools/firmware/vmxassist/offsets\.h$
^tools/firmware/vmxassist/vmxassist$
@@ -137,6 +138,7 @@
^tools/misc/miniterm/miniterm$
^tools/misc/xc_shadow$
^tools/misc/xen_cpuperf$
+^tools/misc/xen-detect$
^tools/misc/xenperf$
^tools/pygrub/build/.*$
^tools/python/build/.*$
diff -r aea80dbf6d96 -r 9af0c7e4ff51 buildconfigs/linux-defconfig_xen0_ia64
--- a/buildconfigs/linux-defconfig_xen0_ia64 Fri Feb 09 14:43:22 2007 -0600
+++ b/buildconfigs/linux-defconfig_xen0_ia64 Wed Feb 14 19:01:35 2007 +0000
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16.29-xen0
-# Tue Nov 14 10:39:09 2006
+# Linux kernel version: 2.6.18-xen0
+# Mon Jan 29 10:16:18 2007
#
#
@@ -21,14 +21,16 @@ CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
# CONFIG_CPUSETS is not set
+# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
CONFIG_KALLSYMS_EXTRA_PASS=y
@@ -40,11 +42,9 @@ CONFIG_FUTEX=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
@@ -55,7 +55,6 @@ CONFIG_MODULES=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_KMOD=y
@@ -64,6 +63,7 @@ CONFIG_STOP_MACHINE=y
#
# Block layer
#
+# CONFIG_BLK_DEV_IO_TRACE is not set
#
# IO Schedulers
@@ -86,8 +86,10 @@ CONFIG_MMU=y
CONFIG_MMU=y
CONFIG_SWIOTLB=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_TIME_INTERPOLATION=y
+CONFIG_DMI=y
CONFIG_EFI=y
CONFIG_GENERIC_IOMAP=y
CONFIG_XEN=y
@@ -96,6 +98,7 @@ CONFIG_XEN_IA64_EXPOSE_P2M_USE_DTR=y
CONFIG_XEN_IA64_EXPOSE_P2M_USE_DTR=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
CONFIG_DMA_IS_DMA32=y
+CONFIG_AUDIT_ARCH=y
# CONFIG_IA64_GENERIC is not set
CONFIG_IA64_DIG=y
# CONFIG_IA64_HP_ZX1 is not set
@@ -123,6 +126,7 @@ CONFIG_HOTPLUG_CPU=y
CONFIG_HOTPLUG_CPU=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
# CONFIG_SCHED_SMT is not set
+# CONFIG_PERMIT_BSP_REMOVE is not set
# CONFIG_PREEMPT is not set
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
@@ -132,6 +136,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
@@ -163,6 +168,7 @@ CONFIG_ACPI=y
CONFIG_ACPI=y
CONFIG_ACPI_BUTTON=y
CONFIG_ACPI_FAN=y
+# CONFIG_ACPI_DOCK is not set
CONFIG_ACPI_PROCESSOR=y
CONFIG_ACPI_HOTPLUG_CPU=y
CONFIG_ACPI_THERMAL=y
@@ -185,7 +191,7 @@ CONFIG_PCI_DOMAINS=y
CONFIG_PCI_DOMAINS=y
CONFIG_XEN_PCIDEV_FRONTEND=y
# CONFIG_XEN_PCIDEV_FE_DEBUG is not set
-CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCIEPORTBUS is not set
# CONFIG_PCI_DEBUG is not set
#
@@ -215,6 +221,8 @@ CONFIG_PACKET=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
@@ -229,7 +237,10 @@ CONFIG_SYN_COOKIES=y
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
@@ -240,6 +251,9 @@ CONFIG_TCP_CONG_BIC=y
#
# CONFIG_IP_VS is not set
# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_BRIDGE_NETFILTER=y
@@ -280,12 +294,12 @@ CONFIG_BRIDGE=y
CONFIG_BRIDGE=y
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
+CONFIG_LLC=y
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -314,6 +328,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
#
# Connector - unified userspace <-> kernelspace linker
@@ -352,6 +367,7 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
@@ -463,6 +479,7 @@ CONFIG_SCSI_SAS_ATTRS=y
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_IPS is not set
@@ -472,10 +489,8 @@ CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MOD
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+CONFIG_SCSI_SYM53C8XX_MMIO=y
# CONFIG_SCSI_IPR is not set
-CONFIG_SCSI_QLOGIC_FC=y
-# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
CONFIG_SCSI_QLOGIC_1280=y
# CONFIG_SCSI_QLA_FC is not set
# CONFIG_SCSI_LPFC is not set
@@ -488,7 +503,13 @@ CONFIG_SCSI_QLOGIC_1280=y
#
CONFIG_MD=y
# CONFIG_BLK_DEV_MD is not set
-# CONFIG_BLK_DEV_DM is not set
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
#
# Fusion MPT device support
@@ -607,6 +628,7 @@ CONFIG_TIGON3=y
# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
#
# Token Ring devices
@@ -709,6 +731,7 @@ CONFIG_VT=y
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_COMPUTONE is not set
# CONFIG_ROCKETPORT is not set
@@ -722,6 +745,7 @@ CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_N_HDLC is not set
# CONFIG_SPECIALIX is not set
# CONFIG_SX is not set
+# CONFIG_RIO is not set
# CONFIG_STALDRV is not set
#
@@ -755,6 +779,8 @@ CONFIG_EFI_RTC=y
# Ftape, the floppy tape device driver
#
CONFIG_AGP=y
+# CONFIG_AGP_SIS is not set
+# CONFIG_AGP_VIA is not set
CONFIG_AGP_I460=y
CONFIG_DRM=y
# CONFIG_DRM_TDFX is not set
@@ -799,10 +825,10 @@ CONFIG_I2C_ALGOPCF=y
# CONFIG_I2C_I810 is not set
# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_PROSAVAGE is not set
# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_SCx200_ACB is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
# CONFIG_I2C_SIS96X is not set
@@ -821,9 +847,7 @@ CONFIG_I2C_ALGOPCF=y
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
# CONFIG_SENSORS_MAX6875 is not set
-# CONFIG_RTC_X1205_I2C is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
@@ -838,13 +862,13 @@ CONFIG_I2C_ALGOPCF=y
#
# Dallas's 1-wire bus
#
-# CONFIG_W1 is not set
#
# Hardware Monitoring support
#
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
@@ -873,10 +897,12 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT8231 is not set
# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
# CONFIG_SENSORS_W83792D is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
@@ -888,24 +914,25 @@ CONFIG_HWMON=y
#
#
-# Multimedia Capabilities Port drivers
-#
-
-#
# Multimedia devices
#
CONFIG_VIDEO_DEV=y
-
-#
-# Video For Linux
-#
-
-#
-# Video Adapters
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
#
# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_VIVI is not set
# CONFIG_VIDEO_BT848 is not set
# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
# CONFIG_VIDEO_SAA5246A is not set
# CONFIG_VIDEO_SAA5249 is not set
# CONFIG_TUNER_3036 is not set
@@ -917,10 +944,40 @@ CONFIG_VIDEO_DEV=y
# CONFIG_VIDEO_HEXIUM_ORION is not set
# CONFIG_VIDEO_HEXIUM_GEMINI is not set
# CONFIG_VIDEO_CX88 is not set
+
+#
+# Encoders and Decoders
+#
+# CONFIG_VIDEO_MSP3400 is not set
+# CONFIG_VIDEO_CS53L32A is not set
+# CONFIG_VIDEO_TLV320AIC23B is not set
+# CONFIG_VIDEO_WM8775 is not set
+# CONFIG_VIDEO_WM8739 is not set
+# CONFIG_VIDEO_CX2341X is not set
+# CONFIG_VIDEO_CX25840 is not set
+# CONFIG_VIDEO_SAA711X is not set
+# CONFIG_VIDEO_SAA7127 is not set
+# CONFIG_VIDEO_UPD64031A is not set
+# CONFIG_VIDEO_UPD64083 is not set
+
+#
+# V4L USB devices
+#
+# CONFIG_VIDEO_PVRUSB2 is not set
# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
+# CONFIG_USB_QUICKCAM_MESSENGER is not set
+# CONFIG_USB_ET61X251 is not set
# CONFIG_VIDEO_OVCAMCHIP is not set
-# CONFIG_VIDEO_AUDIO_DECODER is not set
-# CONFIG_VIDEO_DECODER is not set
+# CONFIG_USB_W9968CF is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_ZC0301 is not set
+# CONFIG_USB_PWC is not set
#
# Radio Adapters
@@ -928,20 +985,24 @@ CONFIG_VIDEO_DEV=y
# CONFIG_RADIO_GEMTEK_PCI is not set
# CONFIG_RADIO_MAXIRADIO is not set
# CONFIG_RADIO_MAESTRO is not set
+# CONFIG_USB_DSBR is not set
#
# Digital Video Broadcasting Devices
#
# CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
CONFIG_FB=y
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_TILEBLITTING is not set
# CONFIG_FB_CIRRUS is not set
@@ -953,7 +1014,6 @@ CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
CONFIG_FB_RADEON=y
CONFIG_FB_RADEON_I2C=y
CONFIG_FB_RADEON_DEBUG=y
@@ -972,6 +1032,7 @@ CONFIG_FB_RADEON_DEBUG=y
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
CONFIG_DUMMY_CONSOLE=y
# CONFIG_FRAMEBUFFER_CONSOLE is not set
@@ -1002,9 +1063,11 @@ CONFIG_SND_OSSEMUL=y
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=y
CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
CONFIG_SND_SEQUENCER_OSS=y
# CONFIG_SND_DYNAMIC_MINORS is not set
CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set
@@ -1025,6 +1088,7 @@ CONFIG_SND_MPU401=y
# PCI devices
#
# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
# CONFIG_SND_ALI5451 is not set
CONFIG_SND_ATIIXP=y
# CONFIG_SND_ATIIXP_MODEM is not set
@@ -1037,6 +1101,18 @@ CONFIG_SND_ATIIXP=y
# CONFIG_SND_CMIPCI is not set
# CONFIG_SND_CS4281 is not set
# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# CONFIG_SND_INDIGO is not set
+# CONFIG_SND_INDIGOIO is not set
+# CONFIG_SND_INDIGODJ is not set
# CONFIG_SND_EMU10K1 is not set
# CONFIG_SND_EMU10K1X is not set
# CONFIG_SND_ENS1370 is not set
@@ -1057,6 +1133,7 @@ CONFIG_SND_FM801=y
# CONFIG_SND_MIXART is not set
# CONFIG_SND_NM256 is not set
# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
# CONFIG_SND_RME32 is not set
# CONFIG_SND_RME96 is not set
# CONFIG_SND_RME9652 is not set
@@ -1076,12 +1153,14 @@ CONFIG_SND_FM801=y
# Open Sound System
#
CONFIG_SOUND_PRIME=y
-# CONFIG_OBSOLETE_OSS_DRIVER is not set
-# CONFIG_SOUND_FUSION is not set
+# CONFIG_OSS_OBSOLETE_DRIVER is not set
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_ES1371 is not set
# CONFIG_SOUND_ICH is not set
# CONFIG_SOUND_TRIDENT is not set
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
# CONFIG_SOUND_TVMIXER is not set
#
@@ -1089,6 +1168,7 @@ CONFIG_SOUND_PRIME=y
#
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
@@ -1107,6 +1187,7 @@ CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_SPLIT_ISO is not set
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_BIG_ENDIAN is not set
@@ -1117,7 +1198,6 @@ CONFIG_USB_UHCI_HCD=y
#
# USB Device Class drivers
#
-# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
@@ -1154,9 +1234,7 @@ CONFIG_USB_HIDDEV=y
# CONFIG_USB_ACECAD is not set
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
-# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_TOUCHSCREEN is not set
# CONFIG_USB_YEALINK is not set
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
@@ -1169,21 +1247,6 @@ CONFIG_USB_HIDDEV=y
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_MICROTEK is not set
-
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-# CONFIG_USB_VICAM is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_ET61X251 is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_KONICAWC is not set
-# CONFIG_USB_OV511 is not set
-# CONFIG_USB_SE401 is not set
-# CONFIG_USB_SN9C102 is not set
-# CONFIG_USB_STV680 is not set
-# CONFIG_USB_PWC is not set
#
# USB Network Adapters
@@ -1214,10 +1277,12 @@ CONFIG_USB_MON=y
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
# CONFIG_USB_PHIDGETKIT is not set
# CONFIG_USB_PHIDGETSERVO is not set
# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_APPLEDISPLAY is not set
# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_LD is not set
# CONFIG_USB_TEST is not set
@@ -1237,12 +1302,43 @@ CONFIG_USB_MON=y
# CONFIG_MMC is not set
#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
# InfiniBand support
#
# CONFIG_INFINIBAND is not set
#
# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
#
#
@@ -1269,7 +1365,6 @@ CONFIG_REISERFS_FS_SECURITY=y
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=y
-CONFIG_XFS_EXPORT=y
# CONFIG_XFS_QUOTA is not set
# CONFIG_XFS_SECURITY is not set
# CONFIG_XFS_POSIX_ACL is not set
@@ -1278,6 +1373,7 @@ CONFIG_XFS_EXPORT=y
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
@@ -1312,7 +1408,6 @@ CONFIG_TMPFS=y
CONFIG_TMPFS=y
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
# CONFIG_CONFIGFS_FS is not set
#
@@ -1358,7 +1453,9 @@ CONFIG_SMB_NLS_REMOTE="cp437"
CONFIG_SMB_NLS_REMOTE="cp437"
CONFIG_CIFS=y
# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
# CONFIG_CIFS_EXPERIMENTAL is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
@@ -1437,9 +1534,11 @@ CONFIG_NLS_UTF8=y
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_IRQ_PER_CPU=y
#
# Instrumentation Support
@@ -1452,14 +1551,19 @@ CONFIG_GENERIC_PENDING_IRQ=y
#
# CONFIG_PRINTK_TIME is not set
CONFIG_MAGIC_SYSRQ=y
+CONFIG_UNUSED_SYMBOLS=y
CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=20
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_RWSEMS is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_FS is not set
@@ -1513,7 +1617,6 @@ CONFIG_CRYPTO_DES=y
#
# CONFIG_XEN_UTIL is not set
CONFIG_XEN_BALLOON=y
-# CONFIG_XEN_DEVMEM is not set
CONFIG_XEN_REBOOT=y
# CONFIG_XEN_SMPBOOT is not set
CONFIG_XEN_INTERFACE_VERSION=0x00030203
@@ -1539,6 +1642,7 @@ CONFIG_XEN_TPMDEV_BACKEND=m
CONFIG_XEN_TPMDEV_BACKEND=m
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
+# CONFIG_XEN_FRAMEBUFFER is not set
# CONFIG_XEN_SCRUB_PAGES is not set
CONFIG_XEN_DISABLE_SERIAL=y
CONFIG_XEN_SYSFS=y
@@ -1547,3 +1651,4 @@ CONFIG_XEN_COMPAT_030002=y
CONFIG_XEN_COMPAT_030002=y
CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
CONFIG_NO_IDLE_HZ=y
+CONFIG_XEN_DEVMEM=y
diff -r aea80dbf6d96 -r 9af0c7e4ff51 buildconfigs/linux-defconfig_xenU_ia64
--- a/buildconfigs/linux-defconfig_xenU_ia64 Fri Feb 09 14:43:22 2007 -0600
+++ b/buildconfigs/linux-defconfig_xenU_ia64 Wed Feb 14 19:01:35 2007 +0000
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16.29-xenU
-# Wed Oct 4 12:54:26 2006
+# Linux kernel version: 2.6.18-xenU
+# Mon Jan 29 10:26:51 2007
#
#
@@ -21,13 +21,15 @@ CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
# CONFIG_CPUSETS is not set
+# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -39,11 +41,9 @@ CONFIG_FUTEX=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
@@ -53,7 +53,6 @@ CONFIG_BASE_SMALL=0
#
CONFIG_MODULES=y
# CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
# CONFIG_KMOD is not set
@@ -61,6 +60,7 @@ CONFIG_OBSOLETE_MODPARM=y
#
# Block layer
#
+# CONFIG_BLK_DEV_IO_TRACE is not set
#
# IO Schedulers
@@ -83,8 +83,10 @@ CONFIG_MMU=y
CONFIG_MMU=y
CONFIG_SWIOTLB=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_TIME_INTERPOLATION=y
+CONFIG_DMI=y
CONFIG_EFI=y
CONFIG_GENERIC_IOMAP=y
CONFIG_XEN=y
@@ -93,6 +95,7 @@ CONFIG_XEN_IA64_EXPOSE_P2M_USE_DTR=y
CONFIG_XEN_IA64_EXPOSE_P2M_USE_DTR=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
CONFIG_DMA_IS_DMA32=y
+CONFIG_AUDIT_ARCH=y
# CONFIG_IA64_GENERIC is not set
CONFIG_IA64_DIG=y
# CONFIG_IA64_HP_ZX1 is not set
@@ -117,9 +120,10 @@ CONFIG_FORCE_MAX_ZONEORDER=11
CONFIG_FORCE_MAX_ZONEORDER=11
CONFIG_SMP=y
CONFIG_NR_CPUS=16
-# CONFIG_HOTPLUG_CPU is not set
+CONFIG_HOTPLUG_CPU=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
# CONFIG_SCHED_SMT is not set
+# CONFIG_PERMIT_BSP_REMOVE is not set
# CONFIG_PREEMPT is not set
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
@@ -129,6 +133,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
@@ -161,7 +166,9 @@ CONFIG_ACPI=y
CONFIG_ACPI=y
CONFIG_ACPI_BUTTON=y
CONFIG_ACPI_FAN=y
+# CONFIG_ACPI_DOCK is not set
CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_HOTPLUG_CPU=y
CONFIG_ACPI_THERMAL=y
CONFIG_ACPI_BLACKLIST_YEAR=0
# CONFIG_ACPI_DEBUG is not set
@@ -182,7 +189,7 @@ CONFIG_PCI_DOMAINS=y
CONFIG_PCI_DOMAINS=y
CONFIG_XEN_PCIDEV_FRONTEND=y
# CONFIG_XEN_PCIDEV_FE_DEBUG is not set
-CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCIEPORTBUS is not set
# CONFIG_PCI_DEBUG is not set
#
@@ -212,6 +219,8 @@ CONFIG_PACKET=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
@@ -226,7 +235,10 @@ CONFIG_IP_FIB_HASH=y
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
@@ -237,6 +249,9 @@ CONFIG_TCP_CONG_BIC=y
#
# CONFIG_IP_VS is not set
# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
@@ -276,7 +291,6 @@ CONFIG_NETFILTER=y
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -305,6 +319,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
#
# Connector - unified userspace <-> kernelspace linker
@@ -342,6 +357,7 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
@@ -399,6 +415,7 @@ CONFIG_SCSI_SAS_ATTRS=y
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_IPS is not set
@@ -408,9 +425,8 @@ CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MOD
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+CONFIG_SCSI_SYM53C8XX_MMIO=y
# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
CONFIG_SCSI_QLOGIC_1280=y
# CONFIG_SCSI_QLA_FC is not set
# CONFIG_SCSI_LPFC is not set
@@ -532,6 +548,7 @@ CONFIG_TIGON3=y
# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
#
# Token Ring devices
@@ -609,6 +626,7 @@ CONFIG_VT=y
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
# CONFIG_SERIAL_NONSTANDARD is not set
#
@@ -616,7 +634,7 @@ CONFIG_HW_CONSOLE=y
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_ACPI=y
+CONFIG_SERIAL_8250_PCI=y
CONFIG_SERIAL_8250_NR_UARTS=8
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
@@ -653,6 +671,8 @@ CONFIG_EFI_RTC=y
# Ftape, the floppy tape device driver
#
CONFIG_AGP=y
+# CONFIG_AGP_SIS is not set
+# CONFIG_AGP_VIA is not set
# CONFIG_AGP_I460 is not set
CONFIG_DRM=y
# CONFIG_DRM_TDFX is not set
@@ -697,10 +717,10 @@ CONFIG_I2C_ALGOPCF=y
# CONFIG_I2C_I810 is not set
# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_PROSAVAGE is not set
# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_SCx200_ACB is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
# CONFIG_I2C_SIS96X is not set
@@ -719,9 +739,7 @@ CONFIG_I2C_ALGOPCF=y
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
# CONFIG_SENSORS_MAX6875 is not set
-# CONFIG_RTC_X1205_I2C is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
@@ -736,13 +754,13 @@ CONFIG_I2C_ALGOPCF=y
#
# Dallas's 1-wire bus
#
-# CONFIG_W1 is not set
#
# Hardware Monitoring support
#
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
@@ -771,10 +789,12 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT8231 is not set
# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
# CONFIG_SENSORS_W83792D is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
@@ -786,24 +806,25 @@ CONFIG_HWMON=y
#
#
-# Multimedia Capabilities Port drivers
-#
-
-#
# Multimedia devices
#
CONFIG_VIDEO_DEV=y
-
-#
-# Video For Linux
-#
-
-#
-# Video Adapters
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
#
# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_VIVI is not set
# CONFIG_VIDEO_BT848 is not set
# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
# CONFIG_VIDEO_SAA5246A is not set
# CONFIG_VIDEO_SAA5249 is not set
# CONFIG_TUNER_3036 is not set
@@ -815,10 +836,40 @@ CONFIG_VIDEO_DEV=y
# CONFIG_VIDEO_HEXIUM_ORION is not set
# CONFIG_VIDEO_HEXIUM_GEMINI is not set
# CONFIG_VIDEO_CX88 is not set
+
+#
+# Encoders and Decoders
+#
+# CONFIG_VIDEO_MSP3400 is not set
+# CONFIG_VIDEO_CS53L32A is not set
+# CONFIG_VIDEO_TLV320AIC23B is not set
+# CONFIG_VIDEO_WM8775 is not set
+# CONFIG_VIDEO_WM8739 is not set
+# CONFIG_VIDEO_CX2341X is not set
+# CONFIG_VIDEO_CX25840 is not set
+# CONFIG_VIDEO_SAA711X is not set
+# CONFIG_VIDEO_SAA7127 is not set
+# CONFIG_VIDEO_UPD64031A is not set
+# CONFIG_VIDEO_UPD64083 is not set
+
+#
+# V4L USB devices
+#
+# CONFIG_VIDEO_PVRUSB2 is not set
# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
+# CONFIG_USB_QUICKCAM_MESSENGER is not set
+# CONFIG_USB_ET61X251 is not set
# CONFIG_VIDEO_OVCAMCHIP is not set
-# CONFIG_VIDEO_AUDIO_DECODER is not set
-# CONFIG_VIDEO_DECODER is not set
+# CONFIG_USB_W9968CF is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_ZC0301 is not set
+# CONFIG_USB_PWC is not set
#
# Radio Adapters
@@ -826,20 +877,24 @@ CONFIG_VIDEO_DEV=y
# CONFIG_RADIO_GEMTEK_PCI is not set
# CONFIG_RADIO_MAXIRADIO is not set
# CONFIG_RADIO_MAESTRO is not set
+# CONFIG_USB_DSBR is not set
#
# Digital Video Broadcasting Devices
#
# CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
CONFIG_FB=y
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_TILEBLITTING is not set
# CONFIG_FB_CIRRUS is not set
@@ -851,7 +906,6 @@ CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
CONFIG_FB_RADEON=y
CONFIG_FB_RADEON_I2C=y
CONFIG_FB_RADEON_DEBUG=y
@@ -870,6 +924,7 @@ CONFIG_FB_RADEON_DEBUG=y
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
CONFIG_DUMMY_CONSOLE=y
# CONFIG_FRAMEBUFFER_CONSOLE is not set
@@ -900,9 +955,11 @@ CONFIG_SND_OSSEMUL=y
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=y
CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
CONFIG_SND_SEQUENCER_OSS=y
# CONFIG_SND_DYNAMIC_MINORS is not set
CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set
@@ -923,6 +980,7 @@ CONFIG_SND_AC97_BUS=y
# PCI devices
#
# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
# CONFIG_SND_ALI5451 is not set
# CONFIG_SND_ATIIXP is not set
# CONFIG_SND_ATIIXP_MODEM is not set
@@ -980,6 +1038,7 @@ CONFIG_SND_FM801=y
#
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
@@ -998,6 +1057,7 @@ CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_SPLIT_ISO is not set
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_BIG_ENDIAN is not set
@@ -1008,7 +1068,6 @@ CONFIG_USB_UHCI_HCD=y
#
# USB Device Class drivers
#
-# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
@@ -1044,9 +1103,7 @@ CONFIG_USB_HIDDEV=y
# CONFIG_USB_ACECAD is not set
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
-# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_TOUCHSCREEN is not set
# CONFIG_USB_YEALINK is not set
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
@@ -1059,21 +1116,6 @@ CONFIG_USB_HIDDEV=y
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_MICROTEK is not set
-
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-# CONFIG_USB_VICAM is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_ET61X251 is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_KONICAWC is not set
-# CONFIG_USB_OV511 is not set
-# CONFIG_USB_SE401 is not set
-# CONFIG_USB_SN9C102 is not set
-# CONFIG_USB_STV680 is not set
-# CONFIG_USB_PWC is not set
#
# USB Network Adapters
@@ -1104,10 +1146,12 @@ CONFIG_USB_MON=y
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
# CONFIG_USB_PHIDGETKIT is not set
# CONFIG_USB_PHIDGETSERVO is not set
# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_APPLEDISPLAY is not set
# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_LD is not set
@@ -1126,12 +1170,43 @@ CONFIG_USB_MON=y
# CONFIG_MMC is not set
#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
# InfiniBand support
#
# CONFIG_INFINIBAND is not set
#
# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
#
#
@@ -1157,6 +1232,7 @@ CONFIG_FS_MBCACHE=y
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
@@ -1191,7 +1267,6 @@ CONFIG_TMPFS=y
CONFIG_TMPFS=y
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
# CONFIG_CONFIGFS_FS is not set
#
@@ -1311,9 +1386,11 @@ CONFIG_NLS_UTF8=y
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_IRQ_PER_CPU=y
#
# Instrumentation Support
@@ -1326,14 +1403,19 @@ CONFIG_GENERIC_PENDING_IRQ=y
#
# CONFIG_PRINTK_TIME is not set
CONFIG_MAGIC_SYSRQ=y
+CONFIG_UNUSED_SYMBOLS=y
CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=17
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_RWSEMS is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_FS is not set
@@ -1387,7 +1469,6 @@ CONFIG_CRYPTO_DES=y
#
# CONFIG_XEN_UTIL is not set
CONFIG_XEN_BALLOON=y
-# CONFIG_XEN_DEVMEM is not set
CONFIG_XEN_REBOOT=y
# CONFIG_XEN_SMPBOOT is not set
CONFIG_XEN_INTERFACE_VERSION=0x00030203
@@ -1402,6 +1483,8 @@ CONFIG_XEN_XENBUS_DEV=y
# CONFIG_XEN_BACKEND is not set
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
+CONFIG_XEN_FRAMEBUFFER=y
+CONFIG_XEN_KEYBOARD=y
# CONFIG_XEN_SCRUB_PAGES is not set
# CONFIG_XEN_DISABLE_SERIAL is not set
CONFIG_XEN_SYSFS=y
@@ -1410,3 +1493,4 @@ CONFIG_XEN_COMPAT_030002=y
CONFIG_XEN_COMPAT_030002=y
CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
CONFIG_NO_IDLE_HZ=y
+CONFIG_XEN_DEVMEM=y
diff -r aea80dbf6d96 -r 9af0c7e4ff51 buildconfigs/linux-defconfig_xen_ia64
--- a/buildconfigs/linux-defconfig_xen_ia64 Fri Feb 09 14:43:22 2007 -0600
+++ b/buildconfigs/linux-defconfig_xen_ia64 Wed Feb 14 19:01:35 2007 +0000
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16.29-xen
-# Tue Nov 14 10:38:50 2006
+# Linux kernel version: 2.6.18-xen
+# Mon Jan 29 10:01:13 2007
#
#
@@ -21,14 +21,16 @@ CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
# CONFIG_CPUSETS is not set
+# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
CONFIG_KALLSYMS_EXTRA_PASS=y
@@ -40,11 +42,9 @@ CONFIG_FUTEX=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
@@ -55,7 +55,6 @@ CONFIG_MODULES=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_KMOD=y
@@ -64,6 +63,7 @@ CONFIG_STOP_MACHINE=y
#
# Block layer
#
+# CONFIG_BLK_DEV_IO_TRACE is not set
#
# IO Schedulers
@@ -86,8 +86,10 @@ CONFIG_MMU=y
CONFIG_MMU=y
CONFIG_SWIOTLB=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_TIME_INTERPOLATION=y
+CONFIG_DMI=y
CONFIG_EFI=y
CONFIG_GENERIC_IOMAP=y
CONFIG_XEN=y
@@ -96,6 +98,7 @@ CONFIG_XEN_IA64_EXPOSE_P2M_USE_DTR=y
CONFIG_XEN_IA64_EXPOSE_P2M_USE_DTR=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
CONFIG_DMA_IS_DMA32=y
+CONFIG_AUDIT_ARCH=y
# CONFIG_IA64_GENERIC is not set
CONFIG_IA64_DIG=y
# CONFIG_IA64_HP_ZX1 is not set
@@ -123,6 +126,7 @@ CONFIG_HOTPLUG_CPU=y
CONFIG_HOTPLUG_CPU=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
# CONFIG_SCHED_SMT is not set
+# CONFIG_PERMIT_BSP_REMOVE is not set
# CONFIG_PREEMPT is not set
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
@@ -132,6 +136,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
@@ -163,6 +168,7 @@ CONFIG_ACPI=y
CONFIG_ACPI=y
CONFIG_ACPI_BUTTON=y
CONFIG_ACPI_FAN=y
+# CONFIG_ACPI_DOCK is not set
CONFIG_ACPI_PROCESSOR=y
CONFIG_ACPI_HOTPLUG_CPU=y
CONFIG_ACPI_THERMAL=y
@@ -185,7 +191,7 @@ CONFIG_PCI_DOMAINS=y
CONFIG_PCI_DOMAINS=y
CONFIG_XEN_PCIDEV_FRONTEND=y
# CONFIG_XEN_PCIDEV_FE_DEBUG is not set
-CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCIEPORTBUS is not set
# CONFIG_PCI_DEBUG is not set
#
@@ -215,6 +221,8 @@ CONFIG_PACKET=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
@@ -229,7 +237,10 @@ CONFIG_SYN_COOKIES=y
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
@@ -240,6 +251,9 @@ CONFIG_TCP_CONG_BIC=y
#
# CONFIG_IP_VS is not set
# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_BRIDGE_NETFILTER=y
@@ -280,12 +294,12 @@ CONFIG_BRIDGE=y
CONFIG_BRIDGE=y
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
+CONFIG_LLC=y
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -314,6 +328,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
#
# Connector - unified userspace <-> kernelspace linker
@@ -352,6 +367,7 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
@@ -463,6 +479,7 @@ CONFIG_SCSI_SAS_ATTRS=y
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_IPS is not set
@@ -472,10 +489,8 @@ CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MOD
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+CONFIG_SCSI_SYM53C8XX_MMIO=y
# CONFIG_SCSI_IPR is not set
-CONFIG_SCSI_QLOGIC_FC=y
-# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
CONFIG_SCSI_QLOGIC_1280=y
# CONFIG_SCSI_QLA_FC is not set
# CONFIG_SCSI_LPFC is not set
@@ -613,6 +628,7 @@ CONFIG_TIGON3=y
# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
#
# Token Ring devices
@@ -715,6 +731,7 @@ CONFIG_VT=y
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_COMPUTONE is not set
# CONFIG_ROCKETPORT is not set
@@ -728,6 +745,7 @@ CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_N_HDLC is not set
# CONFIG_SPECIALIX is not set
# CONFIG_SX is not set
+# CONFIG_RIO is not set
# CONFIG_STALDRV is not set
#
@@ -761,6 +779,8 @@ CONFIG_EFI_RTC=y
# Ftape, the floppy tape device driver
#
CONFIG_AGP=y
+# CONFIG_AGP_SIS is not set
+# CONFIG_AGP_VIA is not set
CONFIG_AGP_I460=y
CONFIG_DRM=y
# CONFIG_DRM_TDFX is not set
@@ -805,10 +825,10 @@ CONFIG_I2C_ALGOPCF=y
# CONFIG_I2C_I810 is not set
# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_PROSAVAGE is not set
# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_SCx200_ACB is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
# CONFIG_I2C_SIS96X is not set
@@ -827,9 +847,7 @@ CONFIG_I2C_ALGOPCF=y
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
# CONFIG_SENSORS_MAX6875 is not set
-# CONFIG_RTC_X1205_I2C is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
@@ -844,13 +862,13 @@ CONFIG_I2C_ALGOPCF=y
#
# Dallas's 1-wire bus
#
-# CONFIG_W1 is not set
#
# Hardware Monitoring support
#
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
@@ -879,10 +897,12 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT8231 is not set
# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
# CONFIG_SENSORS_W83792D is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
@@ -894,24 +914,25 @@ CONFIG_HWMON=y
#
#
-# Multimedia Capabilities Port drivers
-#
-
-#
# Multimedia devices
#
CONFIG_VIDEO_DEV=y
-
-#
-# Video For Linux
-#
-
-#
-# Video Adapters
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+
+#
+# Video Capture Adapters
+#
+
+#
+# Video Capture Adapters
#
# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_VIVI is not set
# CONFIG_VIDEO_BT848 is not set
# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
# CONFIG_VIDEO_SAA5246A is not set
# CONFIG_VIDEO_SAA5249 is not set
# CONFIG_TUNER_3036 is not set
@@ -923,10 +944,40 @@ CONFIG_VIDEO_DEV=y
# CONFIG_VIDEO_HEXIUM_ORION is not set
# CONFIG_VIDEO_HEXIUM_GEMINI is not set
# CONFIG_VIDEO_CX88 is not set
+
+#
+# Encoders and Decoders
+#
+# CONFIG_VIDEO_MSP3400 is not set
+# CONFIG_VIDEO_CS53L32A is not set
+# CONFIG_VIDEO_TLV320AIC23B is not set
+# CONFIG_VIDEO_WM8775 is not set
+# CONFIG_VIDEO_WM8739 is not set
+# CONFIG_VIDEO_CX2341X is not set
+# CONFIG_VIDEO_CX25840 is not set
+# CONFIG_VIDEO_SAA711X is not set
+# CONFIG_VIDEO_SAA7127 is not set
+# CONFIG_VIDEO_UPD64031A is not set
+# CONFIG_VIDEO_UPD64083 is not set
+
+#
+# V4L USB devices
+#
+# CONFIG_VIDEO_PVRUSB2 is not set
# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
+# CONFIG_USB_QUICKCAM_MESSENGER is not set
+# CONFIG_USB_ET61X251 is not set
# CONFIG_VIDEO_OVCAMCHIP is not set
-# CONFIG_VIDEO_AUDIO_DECODER is not set
-# CONFIG_VIDEO_DECODER is not set
+# CONFIG_USB_W9968CF is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_ZC0301 is not set
+# CONFIG_USB_PWC is not set
#
# Radio Adapters
@@ -934,20 +985,24 @@ CONFIG_VIDEO_DEV=y
# CONFIG_RADIO_GEMTEK_PCI is not set
# CONFIG_RADIO_MAXIRADIO is not set
# CONFIG_RADIO_MAESTRO is not set
+# CONFIG_USB_DSBR is not set
#
# Digital Video Broadcasting Devices
#
# CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
CONFIG_FB=y
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_TILEBLITTING is not set
# CONFIG_FB_CIRRUS is not set
@@ -959,7 +1014,6 @@ CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
CONFIG_FB_RADEON=y
CONFIG_FB_RADEON_I2C=y
CONFIG_FB_RADEON_DEBUG=y
@@ -978,6 +1032,7 @@ CONFIG_FB_RADEON_DEBUG=y
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
CONFIG_DUMMY_CONSOLE=y
# CONFIG_FRAMEBUFFER_CONSOLE is not set
@@ -1008,9 +1063,11 @@ CONFIG_SND_OSSEMUL=y
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=y
CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
CONFIG_SND_SEQUENCER_OSS=y
# CONFIG_SND_DYNAMIC_MINORS is not set
CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set
@@ -1031,6 +1088,7 @@ CONFIG_SND_MPU401=y
# PCI devices
#
# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
# CONFIG_SND_ALI5451 is not set
CONFIG_SND_ATIIXP=y
# CONFIG_SND_ATIIXP_MODEM is not set
@@ -1043,6 +1101,18 @@ CONFIG_SND_ATIIXP=y
# CONFIG_SND_CMIPCI is not set
# CONFIG_SND_CS4281 is not set
# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# CONFIG_SND_INDIGO is not set
+# CONFIG_SND_INDIGOIO is not set
+# CONFIG_SND_INDIGODJ is not set
# CONFIG_SND_EMU10K1 is not set
# CONFIG_SND_EMU10K1X is not set
# CONFIG_SND_ENS1370 is not set
@@ -1063,6 +1133,7 @@ CONFIG_SND_FM801=y
# CONFIG_SND_MIXART is not set
# CONFIG_SND_NM256 is not set
# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
# CONFIG_SND_RME32 is not set
# CONFIG_SND_RME96 is not set
# CONFIG_SND_RME9652 is not set
@@ -1082,12 +1153,14 @@ CONFIG_SND_FM801=y
# Open Sound System
#
CONFIG_SOUND_PRIME=y
-# CONFIG_OBSOLETE_OSS_DRIVER is not set
-# CONFIG_SOUND_FUSION is not set
+# CONFIG_OSS_OBSOLETE_DRIVER is not set
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_ES1371 is not set
# CONFIG_SOUND_ICH is not set
# CONFIG_SOUND_TRIDENT is not set
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
# CONFIG_SOUND_TVMIXER is not set
#
@@ -1095,6 +1168,7 @@ CONFIG_SOUND_PRIME=y
#
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
@@ -1113,6 +1187,7 @@ CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_SPLIT_ISO is not set
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_BIG_ENDIAN is not set
@@ -1123,7 +1198,6 @@ CONFIG_USB_UHCI_HCD=y
#
# USB Device Class drivers
#
-# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
@@ -1160,9 +1234,7 @@ CONFIG_USB_HIDDEV=y
# CONFIG_USB_ACECAD is not set
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
-# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_TOUCHSCREEN is not set
# CONFIG_USB_YEALINK is not set
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
@@ -1175,21 +1247,6 @@ CONFIG_USB_HIDDEV=y
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_MICROTEK is not set
-
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-# CONFIG_USB_VICAM is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_ET61X251 is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_KONICAWC is not set
-# CONFIG_USB_OV511 is not set
-# CONFIG_USB_SE401 is not set
-# CONFIG_USB_SN9C102 is not set
-# CONFIG_USB_STV680 is not set
-# CONFIG_USB_PWC is not set
#
# USB Network Adapters
@@ -1220,10 +1277,12 @@ CONFIG_USB_MON=y
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
# CONFIG_USB_PHIDGETKIT is not set
# CONFIG_USB_PHIDGETSERVO is not set
# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_APPLEDISPLAY is not set
# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_LD is not set
# CONFIG_USB_TEST is not set
@@ -1243,12 +1302,43 @@ CONFIG_USB_MON=y
# CONFIG_MMC is not set
#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
# InfiniBand support
#
# CONFIG_INFINIBAND is not set
#
# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
#
#
@@ -1275,7 +1365,6 @@ CONFIG_REISERFS_FS_SECURITY=y
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=y
-CONFIG_XFS_EXPORT=y
# CONFIG_XFS_QUOTA is not set
# CONFIG_XFS_SECURITY is not set
# CONFIG_XFS_POSIX_ACL is not set
@@ -1284,6 +1373,7 @@ CONFIG_XFS_EXPORT=y
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
@@ -1318,7 +1408,6 @@ CONFIG_TMPFS=y
CONFIG_TMPFS=y
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
# CONFIG_CONFIGFS_FS is not set
#
@@ -1364,7 +1453,9 @@ CONFIG_SMB_NLS_REMOTE="cp437"
CONFIG_SMB_NLS_REMOTE="cp437"
CONFIG_CIFS=y
# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
# CONFIG_CIFS_EXPERIMENTAL is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
@@ -1443,9 +1534,11 @@ CONFIG_NLS_UTF8=y
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_IRQ_PER_CPU=y
#
# Instrumentation Support
@@ -1458,14 +1551,19 @@ CONFIG_GENERIC_PENDING_IRQ=y
#
# CONFIG_PRINTK_TIME is not set
CONFIG_MAGIC_SYSRQ=y
+CONFIG_UNUSED_SYMBOLS=y
CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=20
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_RWSEMS is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_FS is not set
@@ -1519,7 +1617,6 @@ CONFIG_CRYPTO_DES=y
#
# CONFIG_XEN_UTIL is not set
CONFIG_XEN_BALLOON=y
-# CONFIG_XEN_DEVMEM is not set
CONFIG_XEN_REBOOT=y
# CONFIG_XEN_SMPBOOT is not set
CONFIG_XEN_INTERFACE_VERSION=0x00030203
@@ -1555,3 +1652,4 @@ CONFIG_XEN_COMPAT_030002=y
CONFIG_XEN_COMPAT_030002=y
CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
CONFIG_NO_IDLE_HZ=y
+CONFIG_XEN_DEVMEM=y
diff -r aea80dbf6d96 -r 9af0c7e4ff51 extras/mini-os/gnttab.c
--- a/extras/mini-os/gnttab.c Fri Feb 09 14:43:22 2007 -0600
+++ b/extras/mini-os/gnttab.c Wed Feb 14 19:01:35 2007 +0000
@@ -21,7 +21,12 @@
#define NR_RESERVED_ENTRIES 8
+/* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */
+#ifdef __ia64__
+#define NR_GRANT_FRAMES 1
+#else
#define NR_GRANT_FRAMES 4
+#endif
#define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
static grant_entry_t *gnttab_table;
diff -r aea80dbf6d96 -r 9af0c7e4ff51 extras/mini-os/netfront.c
--- a/extras/mini-os/netfront.c Fri Feb 09 14:43:22 2007 -0600
+++ b/extras/mini-os/netfront.c Wed Feb 14 19:01:35 2007 +0000
@@ -349,7 +349,9 @@ done:
init_rx_buffers();
unsigned char rawmac[6];
- sscanf(mac,"%x:%x:%x:%x:%x:%x",
+ /* Special conversion specifier 'hh' needed for __ia64__. Without
+ this mini-os panics with 'Unaligned reference'. */
+ sscanf(mac,"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
&rawmac[0],
&rawmac[1],
&rawmac[2],
diff -r aea80dbf6d96 -r 9af0c7e4ff51
linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S
--- a/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S Fri Feb 09 14:43:22
2007 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S Wed Feb 14 19:01:35
2007 +0000
@@ -747,7 +747,7 @@ ENTRY(hypervisor_callback)
jb 11f
cmpl $sysexit_ecrit,%eax
ja 11f
- addl $0x34,%esp # Remove cs...ebx from stack frame.
+ addl $OLDESP,%esp # Remove eflags...ebx from stack frame.
11: push %esp
call evtchn_do_upcall
add $4,%esp
@@ -777,18 +777,13 @@ ecrit: /**** END OF CRITICAL REGION ***
# provides the number of bytes which have already been popped from the
# interrupted stack frame.
critical_region_fixup:
- addl $critical_fixup_table-scrit,%eax
- movzbl (%eax),%eax # %eax contains num bytes popped
- cmpb $0xff,%al # 0xff => vcpu_info critical region
+ movzbl critical_fixup_table-scrit(%eax),%ecx # %eax contains num bytes
popped
+ cmpb $0xff,%cl # 0xff => vcpu_info critical region
jne 15f
- GET_THREAD_INFO(%ebp)
- xorl %eax,%eax
-15: mov %esp,%esi
- add %eax,%esi # %esi points at end of src region
- mov %esp,%edi
- add $0x34,%edi # %edi points at end of dst region
- mov %eax,%ecx
- shr $2,%ecx # convert words to bytes
+ xorl %ecx,%ecx
+15: leal (%esp,%ecx),%esi # %esi points at end of src region
+ leal OLDESP(%esp),%edi # %edi points at end of dst region
+ shrl $2,%ecx # convert words to bytes
je 17f # skip loop if nothing to copy
16: subl $4,%esi # pre-decrementing copy loop
subl $4,%edi
@@ -798,6 +793,7 @@ 17: movl %edi,%esp # final %edi is top
17: movl %edi,%esp # final %edi is top of merged stack
jmp 11b
+.section .rodata,"a"
critical_fixup_table:
.byte 0xff,0xff,0xff # testb $0xff,(%esi) = __TEST_PENDING
.byte 0xff,0xff # jnz 14f
@@ -814,6 +810,7 @@ critical_fixup_table:
.byte 0x28 # iret
.byte 0xff,0xff,0xff,0xff # movb $1,1(%esi)
.byte 0x00,0x00 # jmp 11b
+.previous
# Hypervisor uses this for application faults while it executes.
# We get here for two reasons:
@@ -1194,6 +1191,7 @@ ENTRY(fixup_4gb_segment)
jmp error_code
.section .rodata,"a"
+.align 4
#include "syscall_table.S"
syscall_table_size=(.-sys_call_table)
diff -r aea80dbf6d96 -r 9af0c7e4ff51
linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c
--- a/linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c Fri Feb 09 14:43:22
2007 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c Wed Feb 14 19:01:35
2007 +0000
@@ -319,81 +319,85 @@ static struct irqaction resched_irqactio
* required.
*/
static void
-xen_register_percpu_irq (unsigned int irq, struct irqaction *action, int save)
+xen_register_percpu_irq (unsigned int vec, struct irqaction *action, int save)
{
unsigned int cpu = smp_processor_id();
- int ret = 0;
+ irq_desc_t *desc;
+ int irq = 0;
if (xen_slab_ready) {
- switch (irq) {
+ switch (vec) {
case IA64_TIMER_VECTOR:
sprintf(timer_name[cpu], "%s%d", action->name, cpu);
- ret = bind_virq_to_irqhandler(VIRQ_ITC, cpu,
+ irq = bind_virq_to_irqhandler(VIRQ_ITC, cpu,
action->handler, action->flags,
timer_name[cpu], action->dev_id);
- per_cpu(timer_irq,cpu) = ret;
- printk(KERN_INFO "register VIRQ_ITC (%s) to xen irq
(%d)\n", timer_name[cpu], ret);
+ per_cpu(timer_irq,cpu) = irq;
break;
case IA64_IPI_RESCHEDULE:
sprintf(resched_name[cpu], "%s%d", action->name, cpu);
- ret = bind_ipi_to_irqhandler(RESCHEDULE_VECTOR, cpu,
+ irq = bind_ipi_to_irqhandler(RESCHEDULE_VECTOR, cpu,
action->handler, action->flags,
resched_name[cpu], action->dev_id);
- per_cpu(resched_irq,cpu) = ret;
- printk(KERN_INFO "register RESCHEDULE_VECTOR (%s) to
xen irq (%d)\n", resched_name[cpu], ret);
+ per_cpu(resched_irq,cpu) = irq;
break;
case IA64_IPI_VECTOR:
sprintf(ipi_name[cpu], "%s%d", action->name, cpu);
- ret = bind_ipi_to_irqhandler(IPI_VECTOR, cpu,
+ irq = bind_ipi_to_irqhandler(IPI_VECTOR, cpu,
action->handler, action->flags,
ipi_name[cpu], action->dev_id);
- per_cpu(ipi_irq,cpu) = ret;
- printk(KERN_INFO "register IPI_VECTOR (%s) to xen irq
(%d)\n", ipi_name[cpu], ret);
- break;
- case IA64_SPURIOUS_INT_VECTOR:
+ per_cpu(ipi_irq,cpu) = irq;
break;
case IA64_CMC_VECTOR:
sprintf(cmc_name[cpu], "%s%d", action->name, cpu);
- ret = bind_virq_to_irqhandler(VIRQ_MCA_CMC, cpu,
+ irq = bind_virq_to_irqhandler(VIRQ_MCA_CMC, cpu,
action->handler,
action->flags,
cmc_name[cpu],
action->dev_id);
- per_cpu(cmc_irq,cpu) = ret;
- printk(KERN_INFO "register VIRQ_MCA_CMC (%s) to xen "
- "irq (%d)\n", cmc_name[cpu], ret);
+ per_cpu(cmc_irq,cpu) = irq;
break;
case IA64_CMCP_VECTOR:
sprintf(cmcp_name[cpu], "%s%d", action->name, cpu);
- ret = bind_ipi_to_irqhandler(CMCP_VECTOR, cpu,
+ irq = bind_ipi_to_irqhandler(CMCP_VECTOR, cpu,
action->handler,
action->flags,
cmcp_name[cpu],
action->dev_id);
- per_cpu(cmcp_irq,cpu) = ret;
- printk(KERN_INFO "register CMCP_VECTOR (%s) to xen "
- "irq (%d)\n", cmcp_name[cpu], ret);
+ per_cpu(cmcp_irq,cpu) = irq;
break;
case IA64_CPEP_VECTOR:
sprintf(cpep_name[cpu], "%s%d", action->name, cpu);
- ret = bind_ipi_to_irqhandler(CPEP_VECTOR, cpu,
+ irq = bind_ipi_to_irqhandler(CPEP_VECTOR, cpu,
action->handler,
action->flags,
cpep_name[cpu],
action->dev_id);
- per_cpu(cpep_irq,cpu) = ret;
- printk(KERN_INFO "register CPEP_VECTOR (%s) to xen "
- "irq (%d)\n", cpep_name[cpu], ret);
+ per_cpu(cpep_irq,cpu) = irq;
break;
case IA64_CPE_VECTOR:
- printk(KERN_WARNING "register IA64_CPE_VECTOR "
- "IGNORED\n");
+ case IA64_MCA_RENDEZ_VECTOR:
+ case IA64_PERFMON_VECTOR:
+ case IA64_MCA_WAKEUP_VECTOR:
+ case IA64_SPURIOUS_INT_VECTOR:
+ /* No need to complain, these aren't supported. */
break;
default:
- printk(KERN_WARNING "Percpu irq %d is unsupported by
xen!\n", irq);
- break;
- }
- BUG_ON(ret < 0);
+ printk(KERN_WARNING "Percpu irq %d is unsupported "
+ "by xen!\n", vec);
+ break;
+ }
+ BUG_ON(irq < 0);
+
+ if (irq > 0) {
+ /*
+ * Mark percpu. Without this, migrate_irqs() will
+ * mark the interrupt for migrations and trigger it
+ * on cpu hotplug.
+ */
+ desc = irq_desc + irq;
+ desc->status |= IRQ_PER_CPU;
+ }
}
/* For BSP, we cache registered percpu irqs, and then re-walk
@@ -401,7 +405,7 @@ xen_register_percpu_irq (unsigned int ir
*/
if (!cpu && save) {
BUG_ON(saved_irq_cnt == MAX_LATE_IRQ);
- saved_percpu_irqs[saved_irq_cnt].irq = irq;
+ saved_percpu_irqs[saved_irq_cnt].irq = vec;
saved_percpu_irqs[saved_irq_cnt].action = action;
saved_irq_cnt++;
if (!xen_slab_ready)
@@ -588,7 +592,8 @@ ia64_send_ipi (int cpu, int vector, int
irq = per_cpu(ipi_to_irq, cpu)[CPEP_VECTOR];
break;
default:
- printk(KERN_WARNING"Unsupported IPI type 0x%x\n",
vector);
+ printk(KERN_WARNING "Unsupported IPI type 0x%x\n",
+ vector);
irq = 0;
break;
}
diff -r aea80dbf6d96 -r 9af0c7e4ff51
linux-2.6-xen-sparse/arch/ia64/kernel/setup.c
--- a/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c Fri Feb 09 14:43:22
2007 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c Wed Feb 14 19:01:35
2007 +0000
@@ -63,6 +63,7 @@
#ifdef CONFIG_XEN
#include <asm/hypervisor.h>
#include <asm/xen/xencomm.h>
+#include <xen/xencons.h>
#endif
#include <linux/dma-mapping.h>
@@ -95,6 +96,12 @@ static struct notifier_block xen_panic_b
static struct notifier_block xen_panic_block = {
xen_panic_event, NULL, 0 /* try to go last */
};
+
+void xen_pm_power_off(void)
+{
+ local_irq_disable();
+ HYPERVISOR_shutdown(SHUTDOWN_poweroff);
+}
#endif
extern void ia64_setup_printk_clock(void);
@@ -454,7 +461,9 @@ setup_arch (char **cmdline_p)
setup_xen_features();
/* Register a call for panic conditions. */
- notifier_chain_register(&panic_notifier_list, &xen_panic_block);
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &xen_panic_block);
+ pm_power_off = xen_pm_power_off;
}
#endif
diff -r aea80dbf6d96 -r 9af0c7e4ff51
linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c Fri Feb 09 14:43:22
2007 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c Wed Feb 14 19:01:35
2007 +0000
@@ -417,12 +417,6 @@ EXPORT_SYMBOL(HYPERVISOR_grant_table_op)
EXPORT_SYMBOL(HYPERVISOR_grant_table_op);
///////////////////////////////////////////////////////////////////////////
-// PageForeign(), SetPageForeign(), ClearPageForeign()
-
-struct address_space xen_ia64_foreign_dummy_mapping;
-EXPORT_SYMBOL(xen_ia64_foreign_dummy_mapping);
-
-///////////////////////////////////////////////////////////////////////////
// foreign mapping
#include <linux/efi.h>
#include <asm/meminit.h> // for IA64_GRANULE_SIZE, GRANULEROUND{UP,DOWN}()
diff -r aea80dbf6d96 -r 9af0c7e4ff51
linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S
--- a/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S Fri Feb 09 14:43:22
2007 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S Wed Feb 14 19:01:35
2007 +0000
@@ -124,6 +124,8 @@ GLOBAL_ENTRY(ia64_switch_to)
;;
itr.d dtr[r25]=r23 // wire in new mapping...
#ifdef CONFIG_XEN
+ ;;
+ srlz.d
mov r9=1
movl r8=XSI_PSR_IC
;;
@@ -875,9 +877,6 @@ skip_rbs_switch:
st8 [r2]=r8
st8 [r3]=r10
.work_pending:
- tbit.nz p6,p0=r31,TIF_SIGDELAYED // signal delayed from
MCA/INIT/NMI/PMI context?
-(p6) br.cond.sptk.few .sigdelayed
- ;;
tbit.z p6,p0=r31,TIF_NEED_RESCHED //
current_thread_info()->need_resched==0?
(p6) br.cond.sptk.few .notify
#ifdef CONFIG_PREEMPT
@@ -913,17 +912,6 @@ skip_rbs_switch:
(pLvSys)br.cond.sptk.few .work_pending_syscall_end
br.cond.sptk.many .work_processed_kernel // don't re-check
-// There is a delayed signal that was detected in MCA/INIT/NMI/PMI context
where
-// it could not be delivered. Deliver it now. The signal might be for us and
-// may set TIF_SIGPENDING, so redrive ia64_leave_* after processing the delayed
-// signal.
-
-.sigdelayed:
- br.call.sptk.many rp=do_sigdelayed
- cmp.eq p6,p0=r0,r0 // p6 <- 1, always
re-check
-(pLvSys)br.cond.sptk.few .work_pending_syscall_end
- br.cond.sptk.many .work_processed_kernel // re-check
-
.work_pending_syscall_end:
adds r2=PT(R8)+16,r12
adds r3=PT(R10)+16,r12
diff -r aea80dbf6d96 -r 9af0c7e4ff51
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Fri Feb 09 14:43:22
2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Wed Feb 14 19:01:35
2007 +0000
@@ -344,7 +344,7 @@ static void frontend_changed(struct xenb
switch (frontend_state) {
case XenbusStateInitialising:
if (dev->state == XenbusStateClosed) {
- printk("%s: %s: prepare for reconnect\n",
+ printk(KERN_INFO "%s: %s: prepare for reconnect\n",
__FUNCTION__, dev->nodename);
xenbus_switch_state(dev, XenbusStateInitWait);
}
@@ -488,7 +488,8 @@ static int connect_ring(struct backend_i
xenbus_dev_fatal(dev, err, "unknown fe protocol %s", protocol);
return -1;
}
- printk("blkback: ring-ref %ld, event-channel %d, protocol %d (%s)\n",
+ printk(KERN_INFO
+ "blkback: ring-ref %ld, event-channel %d, protocol %d (%s)\n",
ring_ref, evtchn, be->blkif->blk_protocol, protocol);
/* Map the shared frame, irq etc. */
diff -r aea80dbf6d96 -r 9af0c7e4ff51
linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c Fri Feb 09 14:43:22
2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c Wed Feb 14 19:01:35
2007 +0000
@@ -272,7 +272,7 @@ static void tap_frontend_changed(struct
switch (frontend_state) {
case XenbusStateInitialising:
if (dev->state == XenbusStateClosed) {
- printk("%s: %s: prepare for reconnect\n",
+ printk(KERN_INFO "%s: %s: prepare for reconnect\n",
__FUNCTION__, dev->nodename);
xenbus_switch_state(dev, XenbusStateInitWait);
}
@@ -369,7 +369,8 @@ static int connect_ring(struct backend_i
xenbus_dev_fatal(dev, err, "unknown fe protocol %s", protocol);
return -1;
}
- printk("blktap: ring-ref %ld, event-channel %d, protocol %d (%s)\n",
+ printk(KERN_INFO
+ "blktap: ring-ref %ld, event-channel %d, protocol %d (%s)\n",
ring_ref, evtchn, be->blkif->blk_protocol, protocol);
/* Map the shared frame, irq etc. */
diff -r aea80dbf6d96 -r 9af0c7e4ff51
linux-2.6-xen-sparse/drivers/xen/core/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c Fri Feb 09 14:43:22
2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c Wed Feb 14 19:01:35
2007 +0000
@@ -424,7 +424,7 @@ static void unbind_from_irq(unsigned int
static void unbind_from_irq(unsigned int irq)
{
struct evtchn_close close;
- int evtchn = evtchn_from_irq(irq);
+ int cpu, evtchn = evtchn_from_irq(irq);
spin_lock(&irq_mapping_update_lock);
@@ -452,6 +452,10 @@ static void unbind_from_irq(unsigned int
evtchn_to_irq[evtchn] = -1;
irq_info[irq] = IRQ_UNBOUND;
+
+ /* Zap stats across IRQ changes of use. */
+ for_each_possible_cpu(cpu)
+ kstat_cpu(cpu).irqs[irq] = 0;
}
spin_unlock(&irq_mapping_update_lock);
diff -r aea80dbf6d96 -r 9af0c7e4ff51
linux-2.6-xen-sparse/drivers/xen/core/reboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c Fri Feb 09 14:43:22
2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c Wed Feb 14 19:01:35
2007 +0000
@@ -100,6 +100,7 @@ static void shutdown_handler(struct xenb
static void shutdown_handler(struct xenbus_watch *watch,
const char **vec, unsigned int len)
{
+ extern void ctrl_alt_del(void);
char *str;
struct xenbus_transaction xbt;
int err;
@@ -129,7 +130,7 @@ static void shutdown_handler(struct xenb
if (strcmp(str, "poweroff") == 0)
shutting_down = SHUTDOWN_POWEROFF;
else if (strcmp(str, "reboot") == 0)
- kill_proc(1, SIGINT, 1); /* interrupt init */
+ ctrl_alt_del();
else if (strcmp(str, "suspend") == 0)
shutting_down = SHUTDOWN_SUSPEND;
else if (strcmp(str, "halt") == 0)
diff -r aea80dbf6d96 -r 9af0c7e4ff51
linux-2.6-xen-sparse/drivers/xen/fbfront/xenkbd.c
--- a/linux-2.6-xen-sparse/drivers/xen/fbfront/xenkbd.c Fri Feb 09 14:43:22
2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/fbfront/xenkbd.c Wed Feb 14 19:01:35
2007 +0000
@@ -29,10 +29,12 @@
struct xenkbd_info
{
- struct input_dev *dev;
+ struct input_dev *kbd;
+ struct input_dev *ptr;
struct xenkbd_page *page;
int irq;
struct xenbus_device *xbdev;
+ char phys[32];
};
static int xenkbd_remove(struct xenbus_device *);
@@ -56,23 +58,36 @@ static irqreturn_t input_handler(int rq,
rmb(); /* ensure we see ring contents up to prod */
for (cons = page->in_cons; cons != prod; cons++) {
union xenkbd_in_event *event;
+ struct input_dev *dev;
event = &XENKBD_IN_RING_REF(page, cons);
+ dev = info->ptr;
switch (event->type) {
case XENKBD_TYPE_MOTION:
- input_report_rel(info->dev, REL_X, event->motion.rel_x);
- input_report_rel(info->dev, REL_Y, event->motion.rel_y);
+ input_report_rel(dev, REL_X, event->motion.rel_x);
+ input_report_rel(dev, REL_Y, event->motion.rel_y);
break;
case XENKBD_TYPE_KEY:
- input_report_key(info->dev, event->key.keycode,
event->key.pressed);
+ dev = NULL;
+ if (test_bit(event->key.keycode, info->kbd->keybit))
+ dev = info->kbd;
+ if (test_bit(event->key.keycode, info->ptr->keybit))
+ dev = info->ptr;
+ if (dev)
+ input_report_key(dev, event->key.keycode,
+ event->key.pressed);
+ else
+ printk("xenkbd: unhandled keycode 0x%x\n",
+ event->key.keycode);
break;
case XENKBD_TYPE_POS:
- input_report_abs(info->dev, ABS_X, event->pos.abs_x);
- input_report_abs(info->dev, ABS_Y, event->pos.abs_y);
+ input_report_abs(dev, ABS_X, event->pos.abs_x);
+ input_report_abs(dev, ABS_Y, event->pos.abs_y);
break;
}
- }
- input_sync(info->dev);
+ if (dev)
+ input_sync(dev);
+ }
mb(); /* ensure we got ring contents */
page->in_cons = cons;
notify_remote_via_irq(info->irq);
@@ -85,7 +100,7 @@ int __devinit xenkbd_probe(struct xenbus
{
int ret, i;
struct xenkbd_info *info;
- struct input_dev *input_dev;
+ struct input_dev *kbd, *ptr;
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info) {
@@ -94,6 +109,7 @@ int __devinit xenkbd_probe(struct xenbus
}
dev->dev.driver_data = info;
info->xbdev = dev;
+ snprintf(info->phys, sizeof(info->phys), "xenbus/%s", dev->nodename);
info->page = (void *)__get_free_page(GFP_KERNEL);
if (!info->page)
@@ -101,32 +117,52 @@ int __devinit xenkbd_probe(struct xenbus
info->page->in_cons = info->page->in_prod = 0;
info->page->out_cons = info->page->out_prod = 0;
- input_dev = input_allocate_device();
- if (!input_dev)
+ /* keyboard */
+ kbd = input_allocate_device();
+ if (!kbd)
goto error_nomem;
-
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
- input_dev->keybit[LONG(BTN_MOUSE)]
- = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
- /* TODO additional buttons */
- input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
-
- /* FIXME not sure this is quite right */
- for (i = 0; i < 256; i++)
- set_bit(i, input_dev->keybit);
-
- input_dev->name = "Xen Virtual Keyboard/Mouse";
-
- input_set_abs_params(input_dev, ABS_X, 0, XENFB_WIDTH, 0, 0);
- input_set_abs_params(input_dev, ABS_Y, 0, XENFB_HEIGHT, 0, 0);
-
- ret = input_register_device(input_dev);
- if (ret) {
- input_free_device(input_dev);
- xenbus_dev_fatal(dev, ret, "input_register_device");
+ kbd->name = "Xen Virtual Keyboard";
+ kbd->phys = info->phys;
+ kbd->id.bustype = BUS_PCI;
+ kbd->id.vendor = 0x5853;
+ kbd->id.product = 0xffff;
+ kbd->evbit[0] = BIT(EV_KEY);
+ for (i = KEY_ESC; i < KEY_UNKNOWN; i++)
+ set_bit(i, kbd->keybit);
+ for (i = KEY_OK; i < KEY_MAX; i++)
+ set_bit(i, kbd->keybit);
+
+ ret = input_register_device(kbd);
+ if (ret) {
+ input_free_device(kbd);
+ xenbus_dev_fatal(dev, ret, "input_register_device(kbd)");
goto error;
}
- info->dev = input_dev;
+ info->kbd = kbd;
+
+ /* pointing device */
+ ptr = input_allocate_device();
+ if (!ptr)
+ goto error_nomem;
+ ptr->name = "Xen Virtual Pointer";
+ ptr->phys = info->phys;
+ ptr->id.bustype = BUS_PCI;
+ ptr->id.vendor = 0x5853;
+ ptr->id.product = 0xfffe;
+ ptr->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
+ for (i = BTN_LEFT; i <= BTN_TASK; i++)
+ set_bit(i, ptr->keybit);
+ ptr->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+ input_set_abs_params(ptr, ABS_X, 0, XENFB_WIDTH, 0, 0);
+ input_set_abs_params(ptr, ABS_Y, 0, XENFB_HEIGHT, 0, 0);
+
+ ret = input_register_device(ptr);
+ if (ret) {
+ input_free_device(ptr);
+ xenbus_dev_fatal(dev, ret, "input_register_device(ptr)");
+ goto error;
+ }
+ info->ptr = ptr;
ret = xenkbd_connect_backend(dev, info);
if (ret < 0)
@@ -155,7 +191,8 @@ static int xenkbd_remove(struct xenbus_d
struct xenkbd_info *info = dev->dev.driver_data;
xenkbd_disconnect_backend(info);
- input_unregister_device(info->dev);
+ input_unregister_device(info->kbd);
+ input_unregister_device(info->ptr);
free_page((unsigned long)info->page);
kfree(info);
return 0;
diff -r aea80dbf6d96 -r 9af0c7e4ff51
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Fri Feb 09 14:43:22
2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Wed Feb 14 19:01:35
2007 +0000
@@ -217,7 +217,7 @@ static void frontend_changed(struct xenb
switch (frontend_state) {
case XenbusStateInitialising:
if (dev->state == XenbusStateClosed) {
- printk("%s: %s: prepare for reconnect\n",
+ printk(KERN_INFO "%s: %s: prepare for reconnect\n",
__FUNCTION__, dev->nodename);
if (be->netif) {
netif_disconnect(be->netif);
diff -r aea80dbf6d96 -r 9af0c7e4ff51
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Fri Feb 09
14:43:22 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Wed Feb 14
19:01:35 2007 +0000
@@ -1505,7 +1505,7 @@ static void netif_release_rx_bufs(struct
int id, ref;
if (np->copying_receiver) {
- printk("%s: fix me for copying receiver.\n", __FUNCTION__);
+ WPRINTK("%s: fix me for copying receiver.\n", __FUNCTION__);
return;
}
@@ -1555,8 +1555,8 @@ static void netif_release_rx_bufs(struct
xfer++;
}
- printk("%s: %d xfer, %d noxfer, %d unused\n",
- __FUNCTION__, xfer, noxfer, unused);
+ IPRINTK("%s: %d xfer, %d noxfer, %d unused\n",
+ __FUNCTION__, xfer, noxfer, unused);
if (xfer) {
/* Some pages are no longer absent... */
diff -r aea80dbf6d96 -r 9af0c7e4ff51
linux-2.6-xen-sparse/include/asm-i386/a.out.h
--- a/linux-2.6-xen-sparse/include/asm-i386/a.out.h Fri Feb 09 14:43:22
2007 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-#ifndef __I386_A_OUT_H__
-#define __I386_A_OUT_H__
-
-struct exec
-{
- unsigned long a_info; /* Use macros N_MAGIC, etc for access */
- unsigned a_text; /* length of text, in bytes */
- unsigned a_data; /* length of data, in bytes */
- unsigned a_bss; /* length of uninitialized data area for file,
in bytes */
- unsigned a_syms; /* length of symbol table data in file, in
bytes */
- unsigned a_entry; /* start address */
- unsigned a_trsize; /* length of relocation info for text, in bytes
*/
- unsigned a_drsize; /* length of relocation info for data, in bytes
*/
-};
-
-#define N_TRSIZE(a) ((a).a_trsize)
-#define N_DRSIZE(a) ((a).a_drsize)
-#define N_SYMSIZE(a) ((a).a_syms)
-
-#ifdef __KERNEL__
-
-#define STACK_TOP (TASK_SIZE - 3*PAGE_SIZE)
-
-#endif
-
-#endif /* __A_OUT_GNU_H__ */
diff -r aea80dbf6d96 -r 9af0c7e4ff51
linux-2.6-xen-sparse/include/asm-ia64/hw_irq.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/hw_irq.h Fri Feb 09 14:43:22
2007 -0600
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hw_irq.h Wed Feb 14 19:01:35
2007 +0000
@@ -104,10 +104,9 @@ static inline void ia64_resend_irq(unsig
static inline void ia64_resend_irq(unsigned int vector)
{
#ifdef CONFIG_XEN
- extern void resend_irq_on_evtchn(struct hw_interrupt_type *h,
- unsigned int i);
+ extern int resend_irq_on_evtchn(unsigned int i);
if (is_running_on_xen())
- resend_irq_on_evtchn(h, vector);
+ resend_irq_on_evtchn(vector);
else
#endif /* CONFIG_XEN */
platform_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0);
diff -r aea80dbf6d96 -r 9af0c7e4ff51
linux-2.6-xen-sparse/include/asm-ia64/maddr.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/maddr.h Fri Feb 09 14:43:22
2007 -0600
+++ b/linux-2.6-xen-sparse/include/asm-ia64/maddr.h Wed Feb 14 19:01:35
2007 +0000
@@ -84,9 +84,6 @@ mfn_to_local_pfn(unsigned long mfn)
#endif /* !CONFIG_XEN */
-/* XXX to compile set_phys_to_machine(vaddr, FOREIGN_FRAME(m)) */
-#define FOREIGN_FRAME(m) (INVALID_P2M_ENTRY)
-
#define mfn_to_pfn(mfn) (mfn)
#define pfn_to_mfn(pfn) (pfn)
diff -r aea80dbf6d96 -r 9af0c7e4ff51
linux-2.6-xen-sparse/include/asm-ia64/page.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/page.h Fri Feb 09 14:43:22
2007 -0600
+++ b/linux-2.6-xen-sparse/include/asm-ia64/page.h Wed Feb 14 19:01:35
2007 +0000
@@ -236,46 +236,17 @@ get_order (unsigned long size)
#include <linux/kernel.h>
#include <asm/hypervisor.h>
#include <xen/features.h> // to compile netback, netfront
-
-/*
- * XXX hack!
- * Linux/IA64 uses PG_arch_1.
- * This hack will be removed once PG_foreign bit is taken.
- * #include <xen/foreign_page.h>
- */
-#ifdef __ASM_XEN_FOREIGN_PAGE_H__
-# error "don't include include/xen/foreign_page.h!"
-#endif
-
-extern struct address_space xen_ia64_foreign_dummy_mapping;
-#define PageForeign(page) \
- ((page)->mapping == &xen_ia64_foreign_dummy_mapping)
-
-#define SetPageForeign(page, dtor) do { \
- set_page_private((page), (unsigned long)(dtor)); \
- (page)->mapping = &xen_ia64_foreign_dummy_mapping; \
- smp_rmb(); \
-} while (0)
-
-#define ClearPageForeign(page) do { \
- (page)->mapping = NULL; \
- smp_rmb(); \
- set_page_private((page), 0); \
-} while (0)
-
-#define PageForeignDestructor(page) \
- ( (void (*) (struct page *)) page_private(page) )
-
-#define arch_free_page(_page,_order) \
-({ int foreign = PageForeign(_page); \
- if (foreign) \
- (PageForeignDestructor(_page))(_page); \
- foreign; \
+#include <asm/maddr.h>
+
+#define arch_free_page(_page, _order) \
+({ \
+ int foreign = PageForeign(_page); \
+ if (foreign) \
+ PageForeignDestructor(_page); \
+ foreign; \
})
#define HAVE_ARCH_FREE_PAGE
-#include <asm/maddr.h>
-
#endif /* CONFIG_XEN */
#endif /* __ASSEMBLY__ */
diff -r aea80dbf6d96 -r 9af0c7e4ff51 linux-2.6-xen-sparse/net/core/skbuff.c
--- a/linux-2.6-xen-sparse/net/core/skbuff.c Fri Feb 09 14:43:22 2007 -0600
+++ b/linux-2.6-xen-sparse/net/core/skbuff.c Wed Feb 14 19:01:35 2007 +0000
@@ -1897,6 +1897,29 @@ int skb_append_datato_frags(struct sock
}
/**
+ * skb_pull_rcsum - pull skb and update receive checksum
+ * @skb: buffer to update
+ * @start: start of data before pull
+ * @len: length of data pulled
+ *
+ * This function performs an skb_pull on the packet and updates
+ * update the CHECKSUM_HW checksum. It should be used on receive
+ * path processing instead of skb_pull unless you know that the
+ * checksum difference is zero (e.g., a valid IP header) or you
+ * are setting ip_summed to CHECKSUM_NONE.
+ */
+unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len)
+{
+ BUG_ON(len > skb->len);
+ skb->len -= len;
+ BUG_ON(skb->len < skb->data_len);
+ skb_postpull_rcsum(skb, skb->data, len);
+ return skb->data += len;
+}
+
+EXPORT_SYMBOL_GPL(skb_pull_rcsum);
+
+/**
* skb_segment - Perform protocol segmentation on skb.
* @skb: buffer to segment
* @features: features for the output path (see dev->features)
@@ -2021,29 +2044,6 @@ err:
}
EXPORT_SYMBOL_GPL(skb_segment);
-
-/**
- * skb_pull_rcsum - pull skb and update receive checksum
- * @skb: buffer to update
- * @start: start of data before pull
- * @len: length of data pulled
- *
- * This function performs an skb_pull on the packet and updates
- * update the CHECKSUM_HW checksum. It should be used on receive
- * path processing instead of skb_pull unless you know that the
- * checksum difference is zero (e.g., a valid IP header) or you
- * are setting ip_summed to CHECKSUM_NONE.
- */
-unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len)
-{
- BUG_ON(len > skb->len);
- skb->len -= len;
- BUG_ON(skb->len < skb->data_len);
- skb_postpull_rcsum(skb, skb->data, len);
- return skb->data += len;
-}
-
-EXPORT_SYMBOL_GPL(skb_pull_rcsum);
void __init skb_init(void)
{
diff -r aea80dbf6d96 -r 9af0c7e4ff51 patches/linux-2.6.18/series
--- a/patches/linux-2.6.18/series Fri Feb 09 14:43:22 2007 -0600
+++ b/patches/linux-2.6.18/series Wed Feb 14 19:01:35 2007 +0000
@@ -18,3 +18,4 @@ x86-elfnote-as-preprocessor-macro.patch
x86-elfnote-as-preprocessor-macro.patch
fixaddr-top.patch
git-c06cb8b1c4d25e5b4d7a2d7c2462619de1e0dbc4.patch
+softlockup-no-idle-hz.patch
diff -r aea80dbf6d96 -r 9af0c7e4ff51
patches/linux-2.6.18/softlockup-no-idle-hz.patch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.18/softlockup-no-idle-hz.patch Wed Feb 14 19:01:35
2007 +0000
@@ -0,0 +1,56 @@
+diff -pruN ../orig-linux-2.6.18/include/linux/sched.h ./include/linux/sched.h
+--- ../orig-linux-2.6.18/include/linux/sched.h 2006-09-20 04:42:06.000000000
+0100
++++ ./include/linux/sched.h 2007-02-07 01:10:24.000000000 +0000
+@@ -211,10 +211,15 @@ extern void update_process_times(int use
+ extern void scheduler_tick(void);
+
+ #ifdef CONFIG_DETECT_SOFTLOCKUP
++extern unsigned long softlockup_get_next_event(void);
+ extern void softlockup_tick(void);
+ extern void spawn_softlockup_task(void);
+ extern void touch_softlockup_watchdog(void);
+ #else
++static inline unsigned long softlockup_get_next_event(void)
++{
++ return MAX_JIFFY_OFFSET;
++}
+ static inline void softlockup_tick(void)
+ {
+ }
+diff -pruN ../orig-linux-2.6.18/kernel/softlockup.c ./kernel/softlockup.c
+--- ../orig-linux-2.6.18/kernel/softlockup.c 2006-09-20 04:42:06.000000000
+0100
++++ ./kernel/softlockup.c 2007-02-07 01:53:22.000000000 +0000
+@@ -40,6 +40,19 @@ void touch_softlockup_watchdog(void)
+ }
+ EXPORT_SYMBOL(touch_softlockup_watchdog);
+
++unsigned long softlockup_get_next_event(void)
++{
++ int this_cpu = smp_processor_id();
++ unsigned long touch_timestamp = per_cpu(touch_timestamp, this_cpu);
++
++ if (per_cpu(print_timestamp, this_cpu) == touch_timestamp ||
++ did_panic ||
++ !per_cpu(watchdog_task, this_cpu))
++ return MAX_JIFFY_OFFSET;
++
++ return min_t(long, 0, touch_timestamp + HZ - jiffies);
++}
++
+ /*
+ * This callback runs from the timer interrupt, and checks
+ * whether the watchdog thread has hung or not:
+diff -pruN ../orig-linux-2.6.18/kernel/timer.c ./kernel/timer.c
+--- ../orig-linux-2.6.18/kernel/timer.c 2006-09-20 04:42:06.000000000
+0100
++++ ./kernel/timer.c 2007-02-07 01:29:34.000000000 +0000
+@@ -485,7 +485,9 @@ unsigned long next_timer_interrupt(void)
+ if (hr_expires < 3)
+ return hr_expires + jiffies;
+ }
+- hr_expires += jiffies;
++ hr_expires = min_t(unsigned long,
++ softlockup_get_next_event(),
++ hr_expires) + jiffies;
+
+ base = __get_cpu_var(tvec_bases);
+ spin_lock(&base->lock);
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/examples/block
--- a/tools/examples/block Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/examples/block Wed Feb 14 19:01:35 2007 +0000
@@ -367,13 +367,7 @@ mount it read-write in a guest domain."
fatal 'Failed to find an unused loop device'
fi
- cmode=`canonicalise_mode $mode`
- if [ "$cmode" == 'r' ]
- then
- do_or_die losetup -r "$loopdev" "$file"
- else
- do_or_die losetup "$loopdev" "$file"
- fi
+ do_or_die losetup "$loopdev" "$file"
xenstore_write "$XENBUS_PATH/node" "$loopdev"
write_dev "$loopdev"
release_lock "block"
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/examples/vif-bridge
--- a/tools/examples/vif-bridge Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/examples/vif-bridge Wed Feb 14 19:01:35 2007 +0000
@@ -46,6 +46,13 @@ then
fi
fi
+RET=0
+ip link show $bridge 1>/dev/null 2>&1 || RET=1
+if [ "$RET" -eq 1 ]
+then
+ fatal "Could not find bridge device $bridge"
+fi
+
case "$command" in
online)
setup_bridge_port "$vif"
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/examples/xen-hotplug-common.sh
--- a/tools/examples/xen-hotplug-common.sh Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/examples/xen-hotplug-common.sh Wed Feb 14 19:01:35 2007 +0000
@@ -28,14 +28,15 @@ unset $(set | grep ^LC_ | cut -d= -f1)
unset $(set | grep ^LC_ | cut -d= -f1)
fatal() {
- xenstore_write "$XENBUS_PATH"/hotplug-status error
+ xenstore_write "$XENBUS_PATH/hotplug-error" "$*" \
+ "$XENBUS_PATH/hotplug-status" error
log err "$@"
exit 1
}
success() {
# Tell DevController that backend is "connected"
- xenstore_write "$XENBUS_PATH"/hotplug-status connected
+ xenstore_write "$XENBUS_PATH/hotplug-status" connected
}
do_or_die() {
diff -r aea80dbf6d96 -r 9af0c7e4ff51
tools/firmware/rombios/32bit/tcgbios/tcgbios.c
--- a/tools/firmware/rombios/32bit/tcgbios/tcgbios.c Fri Feb 09 14:43:22
2007 -0600
+++ b/tools/firmware/rombios/32bit/tcgbios/tcgbios.c Wed Feb 14 19:01:35
2007 +0000
@@ -146,7 +146,7 @@ static int tpm_driver_to_use = TPM_INVAL
static int tpm_driver_to_use = TPM_INVALID_DRIVER;
static
-uint32_t MA_IsTPMPresent()
+uint32_t MA_IsTPMPresent(void)
{
uint32_t rc = 0;
unsigned int i;
@@ -263,11 +263,11 @@ void tcpa_acpi_init(void)
{
struct acpi_20_rsdt *rsdt;
uint32_t length;
- struct acpi_20_tcpa *tcpa;
+ struct acpi_20_tcpa *tcpa = (void *)0;
uint16_t found = 0;
uint16_t rsdp_off;
uint16_t off;
- struct acpi_20_rsdp *rsdp;
+ struct acpi_20_rsdp *rsdp = (void *)0;
if (MA_IsTPMPresent() == 0) {
return;
@@ -732,8 +732,8 @@ void tcpa_measure_post(Bit32u from, Bit3
void tcpa_measure_post(Bit32u from, Bit32u to)
{
struct pcpes pcpes; /* PCClientPCREventStruc */
+ int len = to - from;
memset(&pcpes, 0x0, sizeof(pcpes));
- int len = to - from;
if (len > 0) {
sha1((unsigned char *)from,
@@ -986,7 +986,7 @@ uint32_t PassThroughToTPM32(struct pttti
{
uint32_t rc = 0;
uint8_t *cmd32;
- uint32_t resbuflen;
+ uint32_t resbuflen = 0;
if (TCG_IsShutdownPreBootInterface() != 0) {
rc = (TCG_PC_TPMERROR |
@@ -1277,9 +1277,7 @@ typedef struct _sha1_ctx {
} sha1_ctx;
-static inline uint32_t rol(val, rol)
- uint32_t val;
- uint16_t rol;
+static inline uint32_t rol(uint32_t val, uint16_t rol)
{
return (val << rol) | (val >> (32 - rol));
}
diff -r aea80dbf6d96 -r 9af0c7e4ff51
tools/firmware/rombios/32bit/tcgbios/tpm_drivers.c
--- a/tools/firmware/rombios/32bit/tcgbios/tpm_drivers.c Fri Feb 09
14:43:22 2007 -0600
+++ b/tools/firmware/rombios/32bit/tcgbios/tpm_drivers.c Wed Feb 14
19:01:35 2007 +0000
@@ -27,12 +27,27 @@
#include "tpm_drivers.h"
#include "tcgbios.h"
+#define STS_VALID (1 << 7) /* 0x80 */
+#define STS_COMMAND_READY (1 << 6) /* 0x40 */
+#define STS_TPM_GO (1 << 5) /* 0x20 */
+#define STS_DATA_AVAILABLE (1 << 4) /* 0x10 */
+#define STS_EXPECT (1 << 3) /* 0x08 */
+#define STS_RESPONSE_RETRY (1 << 1) /* 0x02 */
+
+#define ACCESS_TPM_REG_VALID_STS (1 << 7) /* 0x80 */
+#define ACCESS_ACTIVE_LOCALITY (1 << 5) /* 0x20 */
+#define ACCESS_BEEN_SEIZED (1 << 4) /* 0x10 */
+#define ACCESS_SEIZE (1 << 3) /* 0x08 */
+#define ACCESS_PENDING_REQUEST (1 << 2) /* 0x04 */
+#define ACCESS_REQUEST_USE (1 << 1) /* 0x02 */
+#define ACCESS_TPM_ESTABLISHMENT (1 << 0) /* 0x01 */
+
static uint32_t tis_wait_sts(uint8_t *addr, uint32_t time,
uint8_t mask, uint8_t expect)
{
uint32_t rc = 0;
while (time > 0) {
- uint8_t sts = addr[TPM_STS];
+ uint8_t sts = mmio_readb(&addr[TPM_STS]);
if ((sts & mask) == expect) {
rc = 1;
break;
@@ -45,16 +60,17 @@ static uint32_t tis_wait_sts(uint8_t *ad
static uint32_t tis_activate(uint32_t baseaddr)
{
- uint32_t rc = 0;
+ uint32_t rc = 1;
uint8_t *tis_addr = (uint8_t*)baseaddr;
uint8_t acc;
/* request access to locality */
- tis_addr[TPM_ACCESS] = 0x2;
+ tis_addr[TPM_ACCESS] = ACCESS_REQUEST_USE;
- acc = tis_addr[TPM_ACCESS];
- if ((acc & 0x20) != 0) {
- tis_addr[TPM_STS] = 0x40;
- rc = tis_wait_sts(tis_addr, 100, 0x40, 0x40);
+ acc = mmio_readb(&tis_addr[TPM_ACCESS]);
+ if ((acc & ACCESS_ACTIVE_LOCALITY) != 0) {
+ tis_addr[TPM_STS] = STS_COMMAND_READY;
+ rc = tis_wait_sts(tis_addr, 100,
+ STS_COMMAND_READY, STS_COMMAND_READY);
}
return rc;
}
@@ -64,8 +80,8 @@ uint32_t tis_ready(uint32_t baseaddr)
uint32_t rc = 0;
uint8_t *tis_addr = (uint8_t*)baseaddr;
- tis_addr[TPM_STS] = 0x40;
- rc = tis_wait_sts(tis_addr, 100, 0x40, 0x40);
+ tis_addr[TPM_STS] = STS_COMMAND_READY;
+ rc = tis_wait_sts(tis_addr, 100, STS_COMMAND_READY, STS_COMMAND_READY);
return rc;
}
@@ -81,8 +97,7 @@ uint32_t tis_senddata(uint32_t baseaddr,
uint16_t burst = 0;
uint32_t ctr = 0;
while (burst == 0 && ctr < 2000) {
- burst = (((uint16_t)tis_addr[TPM_STS+1]) ) +
- (((uint16_t)tis_addr[TPM_STS+2]) << 8);
+ burst = mmio_readw((uint16_t *)&tis_addr[TPM_STS+1]);
if (burst == 0) {
mssleep(1);
ctr++;
@@ -120,11 +135,11 @@ uint32_t tis_readresp(uint32_t baseaddr,
uint32_t sts;
while (offset < len) {
- buffer[offset] = tis_addr[TPM_DATA_FIFO];
+ buffer[offset] = mmio_readb(&tis_addr[TPM_DATA_FIFO]);
offset++;
- sts = tis_addr[TPM_STS];
+ sts = mmio_readb(&tis_addr[TPM_STS]);
/* data left ? */
- if ((sts & 0x10) == 0) {
+ if ((sts & STS_DATA_AVAILABLE) == 0) {
break;
}
}
@@ -136,7 +151,7 @@ uint32_t tis_waitdatavalid(uint32_t base
{
uint8_t *tis_addr = (uint8_t*)baseaddr;
uint32_t rc = 0;
- if (tis_wait_sts(tis_addr, 1000, 0x80, 0x80) == 0) {
+ if (tis_wait_sts(tis_addr, 1000, STS_VALID, STS_VALID) == 0) {
rc = TCG_NO_RESPONSE;
}
return rc;
@@ -146,8 +161,9 @@ uint32_t tis_waitrespready(uint32_t base
{
uint32_t rc = 0;
uint8_t *tis_addr = (uint8_t*)baseaddr;
- tis_addr[TPM_STS] = 0x20;
- if (tis_wait_sts(tis_addr, timeout, 0x10, 0x10) == 0) {
+ tis_addr[TPM_STS] = STS_TPM_GO;
+ if (tis_wait_sts(tis_addr, timeout,
+ STS_DATA_AVAILABLE, STS_DATA_AVAILABLE) == 0) {
rc = TCG_NO_RESPONSE;
}
return rc;
@@ -158,7 +174,7 @@ uint32_t tis_probe(uint32_t baseaddr)
{
uint32_t rc = 0;
uint8_t *tis_addr = (uint8_t*)baseaddr;
- uint32_t didvid = *(uint32_t*)&tis_addr[TPM_DID_VID];
+ uint32_t didvid = mmio_readl((uint32_t *)&tis_addr[TPM_DID_VID]);
if ((didvid != 0) && (didvid != 0xffffffff)) {
rc = 1;
}
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/firmware/rombios/32bit/util.h
--- a/tools/firmware/rombios/32bit/util.h Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/firmware/rombios/32bit/util.h Wed Feb 14 19:01:35 2007 +0000
@@ -24,5 +24,20 @@ void uuid_to_string(char *dest, uint8_t
void uuid_to_string(char *dest, uint8_t *uuid);
int printf(const char *fmt, ...);
+static inline uint8_t mmio_readb(uint8_t *addr)
+{
+ return *(volatile uint8_t *)addr;
+}
+
+static inline uint16_t mmio_readw(uint16_t *addr)
+{
+ return *(volatile uint16_t *)addr;
+}
+
+static inline uint32_t mmio_readl(uint32_t *addr)
+{
+ return *(volatile uint32_t *)addr;
+}
+
#endif
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/firmware/rombios/rombios.c
--- a/tools/firmware/rombios/rombios.c Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/firmware/rombios/rombios.c Wed Feb 14 19:01:35 2007 +0000
@@ -5722,9 +5722,6 @@ int13_cdemu(DS, ES, DI, SI, BP, SP, BX,
goto int13_fail;
}
-#if BX_TCGBIOS
- tcpa_ipl((Bit32u)bootseg); /* specs: 8.2.3 steps 4 and 5 */
-#endif
switch (GET_AH()) {
@@ -7741,6 +7738,10 @@ ASM_END
}
}
+#if BX_TCGBIOS
+ tcpa_add_bootdevice((Bit32u)0L, (Bit32u)bootdrv);
+#endif
+
/* Canonicalize bootseg:bootip */
bootip = (bootseg & 0x0fff) << 4;
bootseg &= 0xf000;
@@ -7760,6 +7761,9 @@ ASM_END
bootdrv = (Bit8u)(status>>8);
bootseg = read_word(ebda_seg,&EbdaData->cdemu.load_segment);
/* Canonicalize bootseg:bootip */
+#if BX_TCGBIOS
+ tcpa_add_bootdevice((Bit32u)1L, (Bit32u)0L);
+#endif
bootip = (bootseg & 0x0fff) << 4;
bootseg &= 0xf000;
break;
@@ -7773,6 +7777,9 @@ ASM_END
default: return;
}
+#if BX_TCGBIOS
+ tcpa_ipl((Bit32u)bootseg); /* specs: 8.2.3 steps 4 and 5 */
+#endif
/* Debugging info */
printf("Booting from %x:%x\n", bootseg, bootip);
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/ioemu/hw/cirrus_vga.c
--- a/tools/ioemu/hw/cirrus_vga.c Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/ioemu/hw/cirrus_vga.c Wed Feb 14 19:01:35 2007 +0000
@@ -3339,6 +3339,10 @@ void pci_cirrus_vga_init(PCIBus *bus, Di
pci_conf[0x0a] = PCI_CLASS_SUB_VGA;
pci_conf[0x0b] = PCI_CLASS_BASE_DISPLAY;
pci_conf[0x0e] = PCI_CLASS_HEADERTYPE_00h;
+ pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
+ pci_conf[0x2d] = 0x58;
+ pci_conf[0x2e] = 0x01; /* subsystem device */
+ pci_conf[0x2f] = 0x00;
/* setup VGA */
s = &d->cirrus_vga;
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/ioemu/hw/ide.c
--- a/tools/ioemu/hw/ide.c Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/ioemu/hw/ide.c Wed Feb 14 19:01:35 2007 +0000
@@ -2502,6 +2502,10 @@ void pci_piix3_ide_init(PCIBus *bus, Blo
pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
pci_conf[0x0e] = 0x00; // header_type
+ pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
+ pci_conf[0x2d] = 0x58;
+ pci_conf[0x2e] = 0x01; /* subsystem device */
+ pci_conf[0x2f] = 0x00;
pci_register_io_region((PCIDevice *)d, 4, 0x10,
PCI_ADDRESS_SPACE_IO, bmdma_map);
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/ioemu/hw/rtl8139.c
--- a/tools/ioemu/hw/rtl8139.c Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/ioemu/hw/rtl8139.c Wed Feb 14 19:01:35 2007 +0000
@@ -3423,8 +3423,10 @@ void pci_rtl8139_init(PCIBus *bus, NICIn
pci_conf[0x0e] = 0x00; /* header_type */
pci_conf[0x3d] = 1; /* interrupt pin 0 */
pci_conf[0x34] = 0xdc;
- pci_conf[0x2c] = pci_conf[0x00]; // same as Vendor ID
- pci_conf[0x2d] = pci_conf[0x01];
+ pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
+ pci_conf[0x2d] = 0x58;
+ pci_conf[0x2e] = 0x01; /* subsystem device */
+ pci_conf[0x2f] = 0x00;
s = &d->rtl8139;
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/ioemu/hw/tpm_tis.c
--- a/tools/ioemu/hw/tpm_tis.c Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/ioemu/hw/tpm_tis.c Wed Feb 14 19:01:35 2007 +0000
@@ -517,7 +517,7 @@ static uint32_t tis_mem_readl(void *opaq
#ifdef DEBUG_TPM
fprintf(logfile," read(%08x) = %08x\n",
- addr,
+ (int)addr,
val);
#endif
@@ -538,7 +538,7 @@ static void tis_mem_writel(void *opaque,
#ifdef DEBUG_TPM
fprintf(logfile,"write(%08x) = %08x\n",
- addr,
+ (int)addr,
val);
#endif
@@ -757,10 +757,11 @@ static void tpm_save(QEMUFile* f,void* o
static void tpm_save(QEMUFile* f,void* opaque)
{
tpmState* s=(tpmState*)opaque;
+ uint8_t locty = s->active_loc;
int c;
/* need to wait for outstanding requests to complete */
- if (IS_COMM_WITH_VTPM(s)) {
+ if (s->loc[locty].state == STATE_EXECUTION) {
int repeats = 30; /* 30 seconds; really should be infty */
while (repeats > 0 &&
!(s->loc[s->active_loc].sts & STS_DATA_AVAILABLE)) {
@@ -777,6 +778,10 @@ static void tpm_save(QEMUFile* f,void* o
}
}
+ if (IS_COMM_WITH_VTPM(s)) {
+ close_vtpm_channel(s, 1);
+ }
+
qemu_put_be32s(f,&s->offset);
qemu_put_buffer(f, s->buffer.buf, TPM_MAX_PKT);
qemu_put_8s(f, &s->active_loc);
@@ -993,7 +998,7 @@ static int TPM_Receive(tpmState *s, tpmB
uint32_t size = tpm_get_size_from_buffer(buffer->buf);
if (size + sizeof(buffer->instance) != off) {
fprintf(logfile,"TPM: Packet size is bad! %d != %d\n",
- size + sizeof(buffer->instance),
+ (int)(size + sizeof(buffer->instance)),
off);
} else {
uint32_t ret;
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/ioemu/xenstore.c
--- a/tools/ioemu/xenstore.c Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/ioemu/xenstore.c Wed Feb 14 19:01:35 2007 +0000
@@ -10,6 +10,7 @@
#include "vl.h"
#include "block_int.h"
+#include <unistd.h>
static struct xs_handle *xsh = NULL;
static char *hd_filename[MAX_DISKS];
@@ -52,11 +53,40 @@ void xenstore_check_new_media_present(in
qemu_mod_timer(insert_timer, qemu_get_clock(rt_clock) + timeout);
}
+static int waitForDevice(char *path, char *field, char *desired)
+{
+ char *buf = NULL, *stat = NULL;
+ unsigned int len;
+ int val = 1;
+
+ /* loop until we find a value in xenstore, return
+ * if it was what we wanted, or not
+ */
+ while (1) {
+ if (pasprintf(&buf, "%s/%s", path, field) == -1)
+ goto done;
+ free(stat);
+ stat = xs_read(xsh, XBT_NULL, buf, &len);
+ if (stat == NULL) {
+ usleep(100000); /* 1/10th second, no path found */
+ } else {
+ val = strcmp(stat, desired);
+ goto done;
+ }
+ }
+
+done:
+ free(stat);
+ free(buf);
+ return val;
+}
+
void xenstore_parse_domain_config(int domid)
{
char **e = NULL;
char *buf = NULL, *path;
- char *bpath = NULL, *dev = NULL, *params = NULL, *type = NULL;
+ char *fpath = NULL, *bpath = NULL,
+ *dev = NULL, *params = NULL, *type = NULL;
int i;
unsigned int len, num, hd_index;
@@ -120,7 +150,35 @@ void xenstore_parse_domain_config(int do
hd_filename[hd_index] = params; /* strdup() */
params = NULL; /* don't free params on re-use */
}
+ /*
+ * check if device has a phantom vbd; the phantom is hooked
+ * to the frontend device (for ease of cleanup), so lookup
+ * the frontend device, and see if there is a phantom_vbd
+ * if there is, we will use resolution as the filename
+ */
+ if (pasprintf(&buf, "%s/device/vbd/%s/phantom_vbd", path, e[i]) == -1)
+ continue;
+ free(fpath);
+ fpath = xs_read(xsh, XBT_NULL, buf, &len);
+ if (fpath != NULL) {
+
+ if (waitForDevice(fpath, "hotplug-status", "connected")) {
+ continue;
+ }
+
+ if (pasprintf(&buf, "%s/dev", fpath) == -1)
+ continue;
+ params = xs_read(xsh, XBT_NULL, buf , &len);
+ if (params != NULL) {
+ free(hd_filename[hd_index]);
+ hd_filename[hd_index] = params;
+ params = NULL; /* don't free params on re-use */
+ }
+ }
bs_table[hd_index] = bdrv_new(dev);
+ /* re-establish buf */
+ if (pasprintf(&buf, "%s/params", bpath) == -1)
+ continue;
/* check if it is a cdrom */
if (type && !strcmp(type, "cdrom")) {
bdrv_set_type_hint(bs_table[hd_index], BDRV_TYPE_CDROM);
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/libxc/xc_domain.c Wed Feb 14 19:01:35 2007 +0000
@@ -252,12 +252,14 @@ int xc_domain_hvm_getcontext(int xc_hand
domctl.u.hvmcontext.size = size;
set_xen_guest_handle(domctl.u.hvmcontext.buffer, ctxt_buf);
- if ( (ret = lock_pages(ctxt_buf, size)) != 0 )
- return ret;
+ if ( ctxt_buf )
+ if ( (ret = lock_pages(ctxt_buf, size)) != 0 )
+ return ret;
ret = do_domctl(xc_handle, &domctl);
- unlock_pages(ctxt_buf, size);
+ if ( ctxt_buf )
+ unlock_pages(ctxt_buf, size);
return (ret < 0 ? -1 : domctl.u.hvmcontext.size);
}
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/libxc/xc_hvm_restore.c
--- a/tools/libxc/xc_hvm_restore.c Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/libxc/xc_hvm_restore.c Wed Feb 14 19:01:35 2007 +0000
@@ -41,11 +41,8 @@ static unsigned long hvirt_start;
/* #levels of page tables used by the currrent guest */
static unsigned int pt_levels;
-/* total number of pages used by the current guest */
-static unsigned long max_pfn;
-
-/* A table mapping each PFN to its new MFN. */
-static xen_pfn_t *p2m = NULL;
+/* A list of PFNs that exist, used when allocating memory to the guest */
+static xen_pfn_t *pfns = NULL;
static ssize_t
read_exact(int fd, void *buf, size_t count)
@@ -67,9 +64,8 @@ read_exact(int fd, void *buf, size_t cou
}
int xc_hvm_restore(int xc_handle, int io_fd,
- uint32_t dom, unsigned long nr_pfns,
+ uint32_t dom, unsigned long max_pfn,
unsigned int store_evtchn, unsigned long *store_mfn,
- unsigned int console_evtchn, unsigned long *console_mfn,
unsigned int pae, unsigned int apic)
{
DECLARE_DOMCTL;
@@ -91,7 +87,7 @@ int xc_hvm_restore(int xc_handle, int io
unsigned long long v_end, memsize;
unsigned long shared_page_nr;
- unsigned long mfn, pfn;
+ unsigned long pfn;
unsigned int prev_pc, this_pc;
int verify = 0;
@@ -99,23 +95,27 @@ int xc_hvm_restore(int xc_handle, int io
unsigned long region_pfn_type[MAX_BATCH_SIZE];
struct xen_add_to_physmap xatp;
+
+ /* Number of pages of memory the guest has. *Not* the same as max_pfn. */
+ unsigned long nr_pages;
/* hvm guest mem size (Mb) */
memsize = (unsigned long long)*store_mfn;
v_end = memsize << 20;
-
- DPRINTF("xc_hvm_restore:dom=%d, nr_pfns=0x%lx, store_evtchn=%d,
*store_mfn=%ld, console_evtchn=%d, *console_mfn=%ld, pae=%u, apic=%u.\n",
- dom, nr_pfns, store_evtchn, *store_mfn, console_evtchn,
*console_mfn, pae, apic);
-
- max_pfn = nr_pfns;
-
+ nr_pages = (unsigned long) memsize << (20 - PAGE_SHIFT);
+
+ DPRINTF("xc_hvm_restore:dom=%d, nr_pages=0x%lx, store_evtchn=%d,
*store_mfn=%ld, pae=%u, apic=%u.\n",
+ dom, nr_pages, store_evtchn, *store_mfn, pae, apic);
+
+
if(!get_platform_info(xc_handle, dom,
&max_mfn, &hvirt_start, &pt_levels)) {
ERROR("Unable to get platform info.");
return 1;
}
- DPRINTF("xc_hvm_restore start: max_pfn = %lx, max_mfn = %lx,
hvirt_start=%lx, pt_levels=%d\n",
+ DPRINTF("xc_hvm_restore start: nr_pages = %lx, max_pfn = %lx, max_mfn =
%lx, hvirt_start=%lx, pt_levels=%d\n",
+ nr_pages,
max_pfn,
max_mfn,
hvirt_start,
@@ -128,30 +128,30 @@ int xc_hvm_restore(int xc_handle, int io
}
- p2m = malloc(max_pfn * sizeof(xen_pfn_t));
- if (p2m == NULL) {
+ pfns = malloc(max_pfn * sizeof(xen_pfn_t));
+ if (pfns == NULL) {
ERROR("memory alloc failed");
errno = ENOMEM;
goto out;
}
- if(xc_domain_setmaxmem(xc_handle, dom, PFN_TO_KB(max_pfn)) != 0) {
+ if(xc_domain_setmaxmem(xc_handle, dom, PFN_TO_KB(nr_pages)) != 0) {
errno = ENOMEM;
goto out;
}
for ( i = 0; i < max_pfn; i++ )
- p2m[i] = i;
+ pfns[i] = i;
for ( i = HVM_BELOW_4G_RAM_END >> PAGE_SHIFT; i < max_pfn; i++ )
- p2m[i] += HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT;
+ pfns[i] += HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT;
/* Allocate memory for HVM guest, skipping VGA hole 0xA0000-0xC0000. */
rc = xc_domain_memory_populate_physmap(
- xc_handle, dom, (max_pfn > 0xa0) ? 0xa0 : max_pfn,
- 0, 0, &p2m[0x00]);
- if ( (rc == 0) && (max_pfn > 0xc0) )
+ xc_handle, dom, (nr_pages > 0xa0) ? 0xa0 : nr_pages,
+ 0, 0, &pfns[0x00]);
+ if ( (rc == 0) && (nr_pages > 0xc0) )
rc = xc_domain_memory_populate_physmap(
- xc_handle, dom, max_pfn - 0xc0, 0, 0, &p2m[0xc0]);
+ xc_handle, dom, nr_pages - 0xc0, 0, 0, &pfns[0xc0]);
if ( rc != 0 )
{
PERROR("Could not allocate memory for HVM guest.\n");
@@ -172,9 +172,6 @@ int xc_hvm_restore(int xc_handle, int io
goto out;
}
- for ( i = 0; i < max_pfn; i++)
- p2m[i] = i;
-
prev_pc = 0;
n = 0;
@@ -182,7 +179,7 @@ int xc_hvm_restore(int xc_handle, int io
int j;
- this_pc = (n * 100) / max_pfn;
+ this_pc = (n * 100) / nr_pages;
if ( (this_pc - prev_pc) >= 5 )
{
PPRINTF("\b\b\b\b%3d%%", this_pc);
@@ -235,8 +232,6 @@ int xc_hvm_restore(int xc_handle, int io
}
- mfn = p2m[pfn];
-
/* In verify mode, we use a copy; otherwise we work in place */
page = verify ? (void *)buf : (region_base + i*PAGE_SIZE);
@@ -253,8 +248,8 @@ int xc_hvm_restore(int xc_handle, int io
int v;
- DPRINTF("************** pfn=%lx mfn=%lx gotcs=%08lx "
- "actualcs=%08lx\n", pfn, p2m[pfn],
+ DPRINTF("************** pfn=%lx gotcs=%08lx "
+ "actualcs=%08lx\n", pfn,
csum_page(region_base + i*PAGE_SIZE),
csum_page(buf));
@@ -362,7 +357,7 @@ int xc_hvm_restore(int xc_handle, int io
out:
if ( (rc != 0) && (dom != 0) )
xc_domain_destroy(xc_handle, dom);
- free(p2m);
+ free(pfns);
free(hvm_buf);
DPRINTF("Restore exit with rc=%d\n", rc);
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/libxc/xc_hvm_save.c
--- a/tools/libxc/xc_hvm_save.c Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/libxc/xc_hvm_save.c Wed Feb 14 19:01:35 2007 +0000
@@ -27,16 +27,11 @@
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
+#include <xen/hvm/e820.h>
#include "xc_private.h"
#include "xg_private.h"
#include "xg_save_restore.h"
-
-/*
- * Size of a buffer big enough to take the HVM state of a domain.
- * Ought to calculate this a bit more carefully, or maybe ask Xen.
- */
-#define HVM_CTXT_SIZE 8192
/*
** Default values for important tuning parameters. Can override by passing
@@ -281,11 +276,11 @@ int xc_hvm_save(int xc_handle, int io_fd
/* A copy of the CPU context of the guest. */
vcpu_guest_context_t ctxt;
- /* A table containg the type of each PFN (/not/ MFN!). */
- unsigned long *pfn_type = NULL;
- unsigned long *pfn_batch = NULL;
+ /* A table containg the PFNs (/not/ MFN!) to map. */
+ xen_pfn_t *pfn_batch = NULL;
/* A copy of hvm domain context buffer*/
+ uint32_t hvm_buf_size;
uint8_t *hvm_buf = NULL;
/* Live mapping of shared info structure */
@@ -295,7 +290,6 @@ int xc_hvm_save(int xc_handle, int io_fd
unsigned char *region_base = NULL;
uint32_t nr_pfns, rec_size, nr_vcpus;
- unsigned long *page_array = NULL;
/* power of 2 order of max_pfn */
int order_nr;
@@ -366,18 +360,12 @@ int xc_hvm_save(int xc_handle, int io_fd
goto out;
}
- max_pfn = live_shinfo->arch.max_pfn;
-
DPRINTF("saved hvm domain info:max_memkb=0x%lx, max_mfn=0x%lx,
nr_pages=0x%lx\n", info.max_memkb, max_mfn, info.nr_pages);
- /* nr_pfns: total pages excluding vga acc mem
- * max_pfn: nr_pfns + 0x20 vga hole(0xa0~0xc0)
- * getdomaininfo.tot_pages: all the allocated pages for this domain
- */
if (live) {
ERROR("hvm domain doesn't support live migration now.\n");
goto out;
-
+
if (xc_shadow_control(xc_handle, dom,
XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY,
NULL, 0, NULL, 0, NULL) < 0) {
@@ -386,6 +374,7 @@ int xc_hvm_save(int xc_handle, int io_fd
}
/* excludes vga acc mem */
+ /* XXX will need to check whether acceleration is enabled here! */
nr_pfns = info.nr_pages - 0x800;
last_iter = 0;
@@ -401,8 +390,8 @@ int xc_hvm_save(int xc_handle, int io_fd
ERROR("HVM Domain appears not to have suspended");
goto out;
}
- nr_pfns = info.nr_pages;
- DPRINTF("after suspend hvm domain nr_pages=0x%x.\n", nr_pfns);
+
+ nr_pfns = info.nr_pages;
}
DPRINTF("after 1st handle hvm domain nr_pfns=0x%x, nr_pages=0x%lx,
max_memkb=0x%lx, live=%d.\n",
@@ -411,10 +400,15 @@ int xc_hvm_save(int xc_handle, int io_fd
info.max_memkb,
live);
- nr_pfns = info.nr_pages;
-
- /*XXX: caculate the VGA hole*/
- max_pfn = nr_pfns + 0x20;
+ /* Calculate the highest PFN of "normal" memory:
+ * HVM memory is sequential except for the VGA and MMIO holes, and
+ * we have nr_pfns of it (which now excludes the cirrus video RAM) */
+ max_pfn = nr_pfns;
+ /* Skip the VGA hole from 0xa0000 to 0xc0000 */
+ max_pfn += 0x20;
+ /* Skip the MMIO hole: 256MB just below 4GB */
+ if ( max_pfn >= (HVM_BELOW_4G_MMIO_START >> PAGE_SHIFT) )
+ max_pfn += (HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT);
skip_this_iter = 0;/*XXX*/
/* pretend we sent all the pages last iteration */
@@ -429,11 +423,16 @@ int xc_hvm_save(int xc_handle, int io_fd
to_send = malloc(BITMAP_SIZE);
to_skip = malloc(BITMAP_SIZE);
- page_array = (unsigned long *) malloc( sizeof(unsigned long) * max_pfn);
-
- hvm_buf = malloc(HVM_CTXT_SIZE);
-
- if (!to_send ||!to_skip ||!page_array ||!hvm_buf ) {
+
+ hvm_buf_size = xc_domain_hvm_getcontext(xc_handle, dom, 0, 0);
+ if ( hvm_buf_size == -1 )
+ {
+ ERROR("Couldn't get HVM context size from Xen");
+ goto out;
+ }
+ hvm_buf = malloc(hvm_buf_size);
+
+ if (!to_send ||!to_skip ||!hvm_buf) {
ERROR("Couldn't allocate memory");
goto out;
}
@@ -453,23 +452,13 @@ int xc_hvm_save(int xc_handle, int io_fd
analysis_phase(xc_handle, dom, max_pfn, to_skip, 0);
- /* get all the HVM domain pfns */
- for ( i = 0; i < max_pfn; i++)
- page_array[i] = i;
-
/* We want zeroed memory so use calloc rather than malloc. */
- pfn_type = calloc(MAX_BATCH_SIZE, sizeof(*pfn_type));
pfn_batch = calloc(MAX_BATCH_SIZE, sizeof(*pfn_batch));
- if ((pfn_type == NULL) || (pfn_batch == NULL)) {
- ERROR("failed to alloc memory for pfn_type and/or pfn_batch arrays");
+ if (pfn_batch == NULL) {
+ ERROR("failed to alloc memory for pfn_batch array");
errno = ENOMEM;
- goto out;
- }
-
- if (lock_pages(pfn_type, MAX_BATCH_SIZE * sizeof(*pfn_type))) {
- ERROR("Unable to lock");
goto out;
}
@@ -510,16 +499,15 @@ int xc_hvm_save(int xc_handle, int io_fd
}
- /* load pfn_type[] with the mfn of all the pages we're doing in
+ /* load pfn_batch[] with the mfn of all the pages we're doing in
this batch. */
for (batch = 0; batch < MAX_BATCH_SIZE && N < max_pfn ; N++) {
int n = permute(N, max_pfn, order_nr);
if (debug) {
- DPRINTF("%d pfn= %08lx mfn= %08lx %d \n",
- iter, (unsigned long)n, page_array[n],
- test_bit(n, to_send));
+ DPRINTF("%d pfn= %08lx %d \n",
+ iter, (unsigned long)n, test_bit(n, to_send));
}
if (!last_iter && test_bit(n, to_send)&& test_bit(n, to_skip))
@@ -529,10 +517,12 @@ int xc_hvm_save(int xc_handle, int io_fd
(test_bit(n, to_send) && last_iter)))
continue;
- if (n >= 0xa0 && n < 0xc0) {
-/* DPRINTF("get a vga hole pfn= %x.\n", n);*/
+ /* Skip PFNs that aren't really there */
+ if ((n >= 0xa0 && n < 0xc0) /* VGA hole */
+ || (n >= (HVM_BELOW_4G_MMIO_START >> PAGE_SHIFT)
+ && n < (1ULL << 32) >> PAGE_SHIFT)) /* 4G MMIO hole */
continue;
- }
+
/*
** we get here if:
** 1. page is marked to_send & hasn't already been re-dirtied
@@ -540,7 +530,6 @@ int xc_hvm_save(int xc_handle, int io_fd
*/
pfn_batch[batch] = n;
- pfn_type[batch] = page_array[n];
batch++;
}
@@ -572,7 +561,6 @@ int xc_hvm_save(int xc_handle, int io_fd
goto out;
}
-
sent_this_iter += batch;
munmap(region_base, batch*PAGE_SIZE);
@@ -661,7 +649,7 @@ int xc_hvm_save(int xc_handle, int io_fd
}
if ( (rec_size = xc_domain_hvm_getcontext(xc_handle, dom, hvm_buf,
- HVM_CTXT_SIZE)) == -1) {
+ hvm_buf_size)) == -1) {
ERROR("HVM:Could not get hvm buffer");
goto out;
}
@@ -722,9 +710,6 @@ int xc_hvm_save(int xc_handle, int io_fd
}
free(hvm_buf);
- free(page_array);
-
- free(pfn_type);
free(pfn_batch);
free(to_send);
free(to_skip);
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/libxc/xenguest.h Wed Feb 14 19:01:35 2007 +0000
@@ -57,9 +57,8 @@ int xc_linux_restore(int xc_handle, int
* @return 0 on success, -1 on failure
*/
int xc_hvm_restore(int xc_handle, int io_fd, uint32_t dom,
- unsigned long nr_pfns, unsigned int store_evtchn,
- unsigned long *store_mfn, unsigned int console_evtchn,
- unsigned long *console_mfn,
+ unsigned long max_pfn, unsigned int store_evtchn,
+ unsigned long *store_mfn,
unsigned int pae, unsigned int apic);
/**
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/libxc/xg_private.c
--- a/tools/libxc/xg_private.c Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/libxc/xg_private.c Wed Feb 14 19:01:35 2007 +0000
@@ -209,9 +209,8 @@ int xc_hvm_save(int xc_handle, int io_fd
__attribute__((weak))
int xc_hvm_restore(int xc_handle, int io_fd, uint32_t dom,
- unsigned long nr_pfns, unsigned int store_evtchn,
- unsigned long *store_mfn, unsigned int console_evtchn,
- unsigned long *console_mfn,
+ unsigned long max_pfn, unsigned int store_evtchn,
+ unsigned long *store_mfn,
unsigned int pae, unsigned int apic)
{
errno = ENOSYS;
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/misc/Makefile
--- a/tools/misc/Makefile Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/misc/Makefile Wed Feb 14 19:01:35 2007 +0000
@@ -9,7 +9,9 @@ CFLAGS += $(INCLUDES)
HDRS = $(wildcard *.h)
-TARGETS = xenperf xc_shadow
+TARGETS-y := xenperf xc_shadow
+TARGETS-$(CONFIG_X86) += xen-detect
+TARGETS := $(TARGETS-y)
INSTALL_BIN = $(TARGETS) xencons
INSTALL_SBIN = netfix xm xen-bugtool xen-python-path xend xenperf
@@ -41,5 +43,5 @@ clean:
%.o: %.c $(HDRS) Makefile
$(CC) -c $(CFLAGS) -o $@ $<
-$(TARGETS): %: %.o Makefile
+xenperf xc_shadow: %: %.o Makefile
$(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxenctrl
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/misc/xen-detect.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/misc/xen-detect.c Wed Feb 14 19:01:35 2007 +0000
@@ -0,0 +1,108 @@
+/******************************************************************************
+ * xen_detect.c
+ *
+ * Simple GNU C / POSIX application to detect execution on Xen VMM platform.
+ *
+ * Copyright (c) 2007, XenSource Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+static int pv_context;
+
+static void cpuid(uint32_t idx,
+ uint32_t *eax,
+ uint32_t *ebx,
+ uint32_t *ecx,
+ uint32_t *edx)
+{
+ asm volatile (
+ "test %1,%1 ; jz 1f ; ud2a ; .ascii \"xen\" ; 1: cpuid"
+ : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
+ : "0" (idx), "1" (pv_context) );
+}
+
+static int check_for_xen(void)
+{
+ uint32_t eax, ebx, ecx, edx;
+ char signature[13];
+
+ cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
+ *(uint32_t *)(signature + 0) = ebx;
+ *(uint32_t *)(signature + 4) = ecx;
+ *(uint32_t *)(signature + 8) = edx;
+ signature[12] = '\0';
+
+ if ( strcmp("XenVMMXenVMM", signature) || (eax < 0x40000002) )
+ return 0;
+
+ cpuid(0x40000001, &eax, &ebx, &ecx, &edx);
+ printf("Running in %s context on Xen v%d.%d.\n",
+ pv_context ? "PV" : "HVM", (uint16_t)(eax >> 16), (uint16_t)eax);
+ return 1;
+}
+
+int main(void)
+{
+ pid_t pid;
+ int status;
+ uint32_t dummy;
+
+ /* Check for execution in HVM context. */
+ if ( check_for_xen() )
+ return 0;
+
+ /* Now we check for execution in PV context. */
+ pv_context = 1;
+
+ /*
+ * Fork a child to test the paravirtualised CPUID instruction.
+ * If executed outside Xen PV context, the extended opcode will fault.
+ */
+ pid = fork();
+ switch ( pid )
+ {
+ case 0:
+ /* Child: test paravirtualised CPUID opcode and then exit cleanly. */
+ cpuid(0x40000000, &dummy, &dummy, &dummy, &dummy);
+ exit(0);
+ case -1:
+ fprintf(stderr, "Fork failed.\n");
+ return 0;
+ }
+
+ /*
+ * Parent waits for child to terminate and checks for clean exit.
+ * Only if the exit is clean is it safe for us to try the extended CPUID.
+ */
+ waitpid(pid, &status, 0);
+ if ( WIFEXITED(status) && check_for_xen() )
+ return 0;
+
+ printf("Not running on Xen.\n");
+ return 0;
+}
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/python/xen/xend/XendCheckpoint.py Wed Feb 14 19:01:35 2007 +0000
@@ -239,8 +239,11 @@ def restore(xd, fd, dominfo = None, paus
forkHelper(cmd, fd, handler.handler, True)
- if handler.store_mfn is None or handler.console_mfn is None:
- raise XendError('Could not read store/console MFN')
+ if handler.store_mfn is None:
+ raise XendError('Could not read store MFN')
+
+ if not is_hvm and handler.console_mfn is None:
+ raise XendError('Could not read console MFN')
dominfo.waitForDevices() # Wait for backends to set up
if not paused:
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/python/xen/xend/XendConfig.py Wed Feb 14 19:01:35 2007 +0000
@@ -1148,6 +1148,47 @@ class XendConfig(dict):
# no valid device to add
return ''
+ def phantom_device_add(self, dev_type, cfg_xenapi = None,
+ target = None):
+ """Add a phantom tap device configuration in XenAPI struct format.
+ """
+
+ if target == None:
+ target = self
+
+ if dev_type not in XendDevices.valid_devices() and \
+ dev_type not in XendDevices.pseudo_devices():
+ raise XendConfigError("XendConfig: %s not a valid device type" %
+ dev_type)
+
+ if cfg_xenapi == None:
+ raise XendConfigError("XendConfig: device_add requires some "
+ "config.")
+
+ if cfg_xenapi:
+ log.debug("XendConfig.phantom_device_add: %s" % str(cfg_xenapi))
+
+ if cfg_xenapi:
+ dev_info = {}
+ if dev_type in ('vbd', 'tap'):
+ if dev_type == 'vbd':
+ dev_info['uname'] = cfg_xenapi.get('image', '')
+ dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
+ elif dev_type == 'tap':
+ if cfg_xenapi.get('image').find('tap:') == -1:
+ dev_info['uname'] = 'tap:qcow:%s' %
cfg_xenapi.get('image')
+ dev_info['dev'] = '/dev/%s' % cfg_xenapi.get('device')
+ dev_info['uname'] = cfg_xenapi.get('image')
+ dev_info['mode'] = cfg_xenapi.get('mode')
+ dev_info['backend'] = '0'
+ dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
+ dev_info['uuid'] = dev_uuid
+ self['devices'][dev_uuid] = (dev_type, dev_info)
+ self['vbd_refs'].append(dev_uuid)
+ return dev_uuid
+
+ return ''
+
def console_add(self, protocol, location, other_config = {}):
dev_uuid = uuid.createString()
if protocol == 'vt100':
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/python/xen/xend/XendDomain.py Wed Feb 14 19:01:35 2007 +0000
@@ -800,7 +800,10 @@ class XendDomain:
"support.")
path = self._managed_check_point_path(dom_uuid)
- fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
+ oflags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
+ if hasattr(os, "O_LARGEFILE"):
+ oflags |= os.O_LARGEFILE
+ fd = os.open(path, oflags)
try:
# For now we don't support 'live checkpoint'
XendCheckpoint.save(fd, dominfo, False, False, path)
@@ -840,8 +843,11 @@ class XendDomain:
# Restore that replaces the existing XendDomainInfo
try:
log.debug('Current DomainInfo state: %d' % dominfo.state)
+ oflags = os.O_RDONLY
+ if hasattr(os, "O_LARGEFILE"):
+ oflags |= os.O_LARGEFILE
XendCheckpoint.restore(self,
- os.open(chkpath, os.O_RDONLY),
+ os.open(chkpath, oflags),
dominfo,
paused = start_paused)
os.unlink(chkpath)
@@ -1009,7 +1015,10 @@ class XendDomain:
@raise XendError: Failure to restore domain
"""
try:
- fd = os.open(src, os.O_RDONLY)
+ oflags = os.O_RDONLY
+ if hasattr(os, "O_LARGEFILE"):
+ oflags |= os.O_LARGEFILE
+ fd = os.open(src, oflags)
try:
return self.domain_restore_fd(fd, paused=paused)
finally:
@@ -1193,7 +1202,10 @@ class XendDomain:
if dominfo.getDomid() == DOM0_ID:
raise XendError("Cannot save privileged domain %i" % domid)
- fd = os.open(dst, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
+ oflags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
+ if hasattr(os, "O_LARGEFILE"):
+ oflags |= os.O_LARGEFILE
+ fd = os.open(dst, oflags)
try:
# For now we don't support 'live checkpoint'
XendCheckpoint.save(fd, dominfo, False, False, dst)
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/python/xen/xend/XendDomainInfo.py Wed Feb 14 19:01:35 2007 +0000
@@ -1416,7 +1416,7 @@ class XendDomainInfo:
self.info['image'],
self.info['devices'])
- localtime = self.info.get('localtime', False)
+ localtime = self.info.get('platform_localtime', False)
if localtime:
xc.domain_set_time_offset(self.domid)
@@ -1565,18 +1565,53 @@ class XendDomainInfo:
# VM Destroy
#
+ def _prepare_phantom_paths(self):
+ # get associated devices to destroy
+ # build list of phantom devices to be removed after normal devices
+ plist = []
+ from xen.xend.xenstore.xstransact import xstransact
+ t = xstransact("%s/device/vbd" % GetDomainPath(self.domid))
+ for dev in t.list():
+ backend_phantom_vbd =
xstransact.Read("%s/device/vbd/%s/phantom_vbd" \
+ % (self.dompath, dev))
+ if backend_phantom_vbd is not None:
+ frontend_phantom_vbd = xstransact.Read("%s/frontend" \
+ % backend_phantom_vbd)
+ plist.append(backend_phantom_vbd)
+ plist.append(frontend_phantom_vbd)
+ return plist
+
+ def _cleanup_phantom_devs(self, plist):
+ # remove phantom devices
+ if not plist == []:
+ time.sleep(2)
+ for paths in plist:
+ if paths.find('backend') != -1:
+ from xen.xend.server import DevController
+ # Modify online status /before/ updating state (latter is
watched by
+ # drivers, so this ordering avoids a race).
+ xstransact.Write(paths, 'online', "0")
+ xstransact.Write(paths, 'state',
str(DevController.xenbusState['Closing']))
+ # force
+ xstransact.Remove(paths)
+
def destroy(self):
"""Cleanup VM and destroy domain. Nothrow guarantee."""
log.debug("XendDomainInfo.destroy: domid=%s", str(self.domid))
+
+ paths = self._prepare_phantom_paths()
self._cleanupVm()
if self.dompath is not None:
self.destroyDomain()
+ self._cleanup_phantom_devs(paths)
def destroyDomain(self):
log.debug("XendDomainInfo.destroyDomain(%s)", str(self.domid))
+
+ paths = self._prepare_phantom_paths()
try:
if self.domid is not None:
@@ -1591,7 +1626,7 @@ class XendDomainInfo:
XendDomain.instance().remove_domain(self)
self.cleanupDomain()
-
+ self._cleanup_phantom_devs(paths)
def resumeDomain(self):
log.debug("XendDomainInfo.resumeDomain(%s)", str(self.domid))
@@ -2211,6 +2246,25 @@ class XendDomainInfo:
return dev_uuid
+ def create_phantom_vbd_with_vdi(self, xenapi_vbd, vdi_image_path):
+ """Create a VBD using a VDI from XendStorageRepository.
+
+ @param xenapi_vbd: vbd struct from the Xen API
+ @param vdi_image_path: VDI UUID
+ @rtype: string
+ @return: uuid of the device
+ """
+ xenapi_vbd['image'] = vdi_image_path
+ dev_uuid = self.info.phantom_device_add('tap', cfg_xenapi = xenapi_vbd)
+ if not dev_uuid:
+ raise XendError('Failed to create device')
+
+ if self.state == XEN_API_VM_POWER_STATE_RUNNING:
+ _, config = self.info['devices'][dev_uuid]
+ config['devid'] =
self.getDeviceController('tap').createDevice(config)
+
+ return config['devid']
+
def create_vif(self, xenapi_vif):
"""Create VIF device from the passed struct in Xen API format.
diff -r aea80dbf6d96 -r 9af0c7e4ff51
tools/python/xen/xend/server/BlktapController.py
--- a/tools/python/xen/xend/server/BlktapController.py Fri Feb 09 14:43:22
2007 -0600
+++ b/tools/python/xen/xend/server/BlktapController.py Wed Feb 14 19:01:35
2007 +0000
@@ -2,7 +2,10 @@
from xen.xend.server.blkif import BlkifController
+from xen.xend.XendLogging import log
+phantomDev = 0;
+phantomId = 0;
class BlktapController(BlkifController):
def __init__(self, vm):
@@ -12,3 +15,62 @@ class BlktapController(BlkifController):
"""@see DevController#frontendRoot"""
return "%s/device/vbd" % self.vm.getDomainPath()
+
+ def getDeviceDetails(self, config):
+ (devid, back, front) = BlkifController.getDeviceDetails(self, config)
+
+ phantomDevid = 0
+ wrapped = False
+
+ try:
+ imagetype = self.vm.info['image']['type']
+ except:
+ imagetype = ""
+
+ if imagetype == 'hvm':
+ tdevname = back['dev']
+ index = ['c', 'd', 'e', 'f', 'g', 'h', 'i', \
+ 'j', 'l', 'm', 'n', 'o', 'p']
+ while True:
+ global phantomDev
+ global phantomId
+ import os, stat
+
+ phantomId = phantomId + 1
+ if phantomId == 16:
+ if index[phantomDev] == index[-1]:
+ if wrapped:
+ raise VmError(" No loopback block \
+ devices are available. ")
+ wrapped = True
+ phantomDev = 0
+ else:
+ phantomDev = phantomDev + 1
+ phantomId = 1
+ devname = 'xvd%s%d' % (index[phantomDev], phantomId)
+ try:
+ info = os.stat('/dev/%s' % devname)
+ except:
+ break
+
+ vbd = { 'mode': 'w', 'device': devname }
+ fn = 'tap:%s' % back['params']
+
+ # recurse ... by creating the vbd, then fallthrough
+ # and finish creating the original device
+
+ from xen.xend import XendDomain
+ dom0 = XendDomain.instance().privilegedDomain()
+ phantomDevid = dom0.create_phantom_vbd_with_vdi(vbd, fn)
+ # we need to wait for this device at a higher level
+ # the vbd that gets created will have a link to us
+ # and will let them do it there
+
+ # add a hook to point to the phantom device,
+ # root path is always the same (dom0 tap)
+ if phantomDevid != 0:
+ front['phantom_vbd'] = '/local/domain/0/backend/tap/0/%s' \
+ % str(phantomDevid)
+
+ return (devid, back, front)
+
diff -r aea80dbf6d96 -r 9af0c7e4ff51
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py Fri Feb 09 14:43:22
2007 -0600
+++ b/tools/python/xen/xend/server/DevController.py Wed Feb 14 19:01:35
2007 +0000
@@ -153,9 +153,9 @@ class DevController:
log.debug("Waiting for %s.", devid)
if not self.hotplug:
- return
-
- status = self.waitForBackend(devid)
+ return
+
+ (status, err) = self.waitForBackend(devid)
if status == Timeout:
self.destroyDevice(devid, False)
@@ -165,25 +165,22 @@ class DevController:
elif status == Error:
self.destroyDevice(devid, False)
- raise VmError("Device %s (%s) could not be connected. "
- "Backend device not found." %
- (devid, self.deviceClass))
-
+ if err is None:
+ raise VmError("Device %s (%s) could not be connected. "
+ "Backend device not found." %
+ (devid, self.deviceClass))
+ else:
+ raise VmError("Device %s (%s) could not be connected. "
+ "%s" % (devid, self.deviceClass, err))
elif status == Missing:
# Don't try to destroy the device; it's already gone away.
raise VmError("Device %s (%s) could not be connected. "
"Device not found." % (devid, self.deviceClass))
elif status == Busy:
- err = None
- frontpath = self.frontendPath(devid)
- backpath = xstransact.Read(frontpath, "backend")
- if backpath:
- err = xstransact.Read(backpath, HOTPLUG_ERROR_NODE)
- if not err:
+ self.destroyDevice(devid, False)
+ if err is None:
err = "Busy."
-
- self.destroyDevice(devid, False)
raise VmError("Device %s (%s) could not be connected.\n%s" %
(devid, self.deviceClass, err))
@@ -476,19 +473,36 @@ class DevController:
def waitForBackend(self, devid):
frontpath = self.frontendPath(devid)
+ # lookup a phantom
+ phantomPath = xstransact.Read(frontpath, 'phantom_vbd')
+ if phantomPath is not None:
+ log.debug("Waiting for %s's phantom %s.", devid, phantomPath)
+ statusPath = phantomPath + '/' + HOTPLUG_STATUS_NODE
+ ev = Event()
+ result = { 'status': Timeout }
+ xswatch(statusPath, hotplugStatusCallback, ev, result)
+ ev.wait(DEVICE_CREATE_TIMEOUT)
+ err = xstransact.Read(statusPath, HOTPLUG_ERROR_NODE)
+ if result['status'] != 'Connected':
+ return (result['status'], err)
+
backpath = xstransact.Read(frontpath, "backend")
+
if backpath:
statusPath = backpath + '/' + HOTPLUG_STATUS_NODE
ev = Event()
result = { 'status': Timeout }
-
+
xswatch(statusPath, hotplugStatusCallback, ev, result)
ev.wait(DEVICE_CREATE_TIMEOUT)
- return result['status']
- else:
- return Missing
+
+ err = xstransact.Read(backpath, HOTPLUG_ERROR_NODE)
+
+ return (result['status'], err)
+ else:
+ return (Missing, None)
def backendPath(self, backdom, devid):
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/xcutils/xc_restore.c
--- a/tools/xcutils/xc_restore.c Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/xcutils/xc_restore.c Wed Feb 14 19:01:35 2007 +0000
@@ -18,14 +18,14 @@ int
int
main(int argc, char **argv)
{
- unsigned int xc_fd, io_fd, domid, nr_pfns, store_evtchn, console_evtchn;
+ unsigned int xc_fd, io_fd, domid, max_pfn, store_evtchn, console_evtchn;
unsigned int hvm, pae, apic;
int ret;
unsigned long store_mfn, console_mfn;
if (argc != 9)
errx(1,
- "usage: %s iofd domid nr_pfns store_evtchn console_evtchn hvm pae
apic",
+ "usage: %s iofd domid max_pfn store_evtchn console_evtchn hvm pae
apic",
argv[0]);
xc_fd = xc_interface_open();
@@ -34,7 +34,7 @@ main(int argc, char **argv)
io_fd = atoi(argv[1]);
domid = atoi(argv[2]);
- nr_pfns = atoi(argv[3]);
+ max_pfn = atoi(argv[3]);
store_evtchn = atoi(argv[4]);
console_evtchn = atoi(argv[5]);
hvm = atoi(argv[6]);
@@ -44,15 +44,16 @@ main(int argc, char **argv)
if (hvm) {
/* pass the memsize to xc_hvm_restore to find the store_mfn */
store_mfn = hvm;
- ret = xc_hvm_restore(xc_fd, io_fd, domid, nr_pfns, store_evtchn,
- &store_mfn, console_evtchn, &console_mfn, pae, apic);
+ ret = xc_hvm_restore(xc_fd, io_fd, domid, max_pfn, store_evtchn,
+ &store_mfn, pae, apic);
} else
- ret = xc_linux_restore(xc_fd, io_fd, domid, nr_pfns, store_evtchn,
+ ret = xc_linux_restore(xc_fd, io_fd, domid, max_pfn, store_evtchn,
&store_mfn, console_evtchn, &console_mfn);
if (ret == 0) {
printf("store-mfn %li\n", store_mfn);
- printf("console-mfn %li\n", console_mfn);
+ if (!hvm)
+ printf("console-mfn %li\n", console_mfn);
fflush(stdout);
}
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/xenfb/vncfb.c
--- a/tools/xenfb/vncfb.c Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/xenfb/vncfb.c Wed Feb 14 19:01:35 2007 +0000
@@ -57,7 +57,8 @@ static void *kbd_layout;
static void *kbd_layout;
static int btnmap[] = {
- BTN_LEFT, BTN_MIDDLE, BTN_RIGHT, BTN_FORWARD, BTN_BACK
+ BTN_LEFT, BTN_MIDDLE, BTN_RIGHT, BTN_SIDE,
+ BTN_EXTRA, BTN_FORWARD, BTN_BACK, BTN_TASK
};
static void on_kbd_event(rfbBool down, rfbKeySym keycode, rfbClientPtr cl)
@@ -73,11 +74,12 @@ static void on_kbd_event(rfbBool down, r
*/
rfbScreenInfoPtr server = cl->screen;
struct xenfb *xenfb = server->screenData;
-
- if( keycode >= 'A' && keycode <= 'Z' )
+ int scancode;
+
+ if (keycode >= 'A' && keycode <= 'Z')
keycode += 'a' - 'A';
- int scancode = keycode_table[keysym2scancode(kbd_layout, keycode)];
+ scancode = keycode_table[keysym2scancode(kbd_layout, keycode)];
if (scancode == 0)
return;
if (xenfb_send_key(xenfb, down, scancode) < 0)
diff -r aea80dbf6d96 -r 9af0c7e4ff51 tools/xentrace/xentrace_format
--- a/tools/xentrace/xentrace_format Fri Feb 09 14:43:22 2007 -0600
+++ b/tools/xentrace/xentrace_format Wed Feb 14 19:01:35 2007 +0000
@@ -107,6 +107,9 @@ while not interrupted:
(tsc, event, d1, d2, d3, d4, d5) = struct.unpack(TRCREC, line)
+ # Event field is 'uint32_t', not 'long'.
+ event &= 0xffffffff
+
#tsc = (tscH<<32) | tscL
#print i, tsc
diff -r aea80dbf6d96 -r 9af0c7e4ff51 unmodified_drivers/linux-2.6/overrides.mk
--- a/unmodified_drivers/linux-2.6/overrides.mk Fri Feb 09 14:43:22 2007 -0600
+++ b/unmodified_drivers/linux-2.6/overrides.mk Wed Feb 14 19:01:35 2007 +0000
@@ -6,3 +6,6 @@
# a Xen kernel to find the right headers)
EXTRA_CFLAGS += -D__XEN_INTERFACE_VERSION__=0x00030202
EXTRA_CFLAGS += -I$(M)/include -I$(M)/compat-include
-DHAVE_XEN_PLATFORM_COMPAT_H
+ifeq ($(ARCH),ia64)
+ EXTRA_CFLAGS += -DCONFIG_VMX_GUEST
+endif
diff -r aea80dbf6d96 -r 9af0c7e4ff51
unmodified_drivers/linux-2.6/platform-pci/platform-compat.c
--- a/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c Fri Feb
09 14:43:22 2007 -0600
+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c Wed Feb
14 19:01:35 2007 +0000
@@ -12,6 +12,12 @@ static int system_state = 1;
static int system_state = 1;
EXPORT_SYMBOL(system_state);
#endif
+
+static inline void ctrl_alt_del(void)
+{
+ kill_proc(1, SIGINT, 1); /* interrupt init */
+}
+EXPORT_SYMBOL(ctrl_alt_del);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8)
size_t strcspn(const char *s, const char *reject)
diff -r aea80dbf6d96 -r 9af0c7e4ff51
unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
--- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c Fri Feb 09
14:43:22 2007 -0600
+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c Wed Feb 14
19:01:35 2007 +0000
@@ -118,14 +118,10 @@ unsigned long alloc_xen_mmio(unsigned lo
{
unsigned long addr;
- addr = 0;
- if (platform_mmio_alloc + len <= platform_mmiolen)
- {
- addr = platform_mmio + platform_mmio_alloc;
- platform_mmio_alloc += len;
- } else {
- panic("ran out of xen mmio space");
- }
+ addr = platform_mmio + platform_mmio_alloc;
+ platform_mmio_alloc += len;
+ BUG_ON(platform_mmio_alloc > platform_mmiolen);
+
return addr;
}
@@ -181,23 +177,19 @@ static int get_hypercall_stubs(void)
static uint64_t get_callback_via(struct pci_dev *pdev)
{
+ u8 pin;
+ int irq;
+
#ifdef __ia64__
- int irq, rid;
for (irq = 0; irq < 16; irq++) {
if (isa_irq_to_vector(irq) == pdev->irq)
- return irq;
- }
- /* use Requester-ID as callback_irq */
- /* RID: '<#bus(8)><#dev(5)><#func(3)>' (cf. PCI-Express spec) */
- rid = ((pdev->bus->number & 0xff) << 8) | pdev->devfn;
- printk(KERN_INFO DRV_NAME ":use Requester-ID(%04x) as callback irq\n",
- rid);
- return rid | IA64_CALLBACK_IRQ_RID;
+ return irq; /* ISA IRQ */
+ }
#else /* !__ia64__ */
- u8 pin;
-
- if (pdev->irq < 16)
- return pdev->irq; /* ISA IRQ */
+ irq = pdev->irq;
+ if (irq < 16)
+ return irq; /* ISA IRQ */
+#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
pin = pdev->pin;
@@ -211,7 +203,6 @@ static uint64_t get_callback_via(struct
((uint64_t)pdev->bus->number << 16) |
((uint64_t)(pdev->devfn & 0xff) << 8) |
((uint64_t)(pin - 1) & 3));
-#endif
}
/* Invalidate foreign mappings (e.g., in qemu-based device model). */
diff -r aea80dbf6d96 -r 9af0c7e4ff51
unmodified_drivers/linux-2.6/platform-pci/xen_support.c
--- a/unmodified_drivers/linux-2.6/platform-pci/xen_support.c Fri Feb 09
14:43:22 2007 -0600
+++ b/unmodified_drivers/linux-2.6/platform-pci/xen_support.c Wed Feb 14
19:01:35 2007 +0000
@@ -30,6 +30,23 @@
#include <xen/platform-compat.h>
#endif
+#if defined (__ia64__)
+unsigned long __hypercall(unsigned long a1, unsigned long a2,
+ unsigned long a3, unsigned long a4,
+ unsigned long a5, unsigned long cmd)
+{
+ unsigned long __res;
+ __asm__ __volatile__ (";;\n"
+ "mov r2=%1\n"
+ "break 0x1000 ;;\n"
+ "mov %0=r8 ;;\n"
+ : "=r"(__res) : "r"(cmd) : "r2", "r8", "memory");
+
+ return __res;
+}
+EXPORT_SYMBOL(__hypercall);
+#endif
+
void xen_machphys_update(unsigned long mfn, unsigned long pfn)
{
BUG();
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/Rules.mk
--- a/xen/arch/ia64/Rules.mk Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/Rules.mk Wed Feb 14 19:01:35 2007 +0000
@@ -4,7 +4,6 @@ HAS_ACPI := y
HAS_ACPI := y
HAS_VGA := y
xenoprof := y
-VALIDATE_VT ?= n
no_warns ?= n
xen_ia64_expose_p2m ?= y
xen_ia64_pervcpu_vhpt ?= y
@@ -37,9 +36,6 @@ CFLAGS += -ffixed-r13 -mfixed-range=f2-f
CFLAGS += -ffixed-r13 -mfixed-range=f2-f5,f12-f127
CFLAGS += -g
#CFLAGS += -DVTI_DEBUG
-ifeq ($(VALIDATE_VT),y)
-CFLAGS += -DVALIDATE_VT
-endif
ifeq ($(xen_ia64_expose_p2m),y)
CFLAGS += -DCONFIG_XEN_IA64_EXPOSE_P2M
endif
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/asm-offsets.c
--- a/xen/arch/ia64/asm-offsets.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/asm-offsets.c Wed Feb 14 19:01:35 2007 +0000
@@ -57,6 +57,7 @@ void foo(void)
DEFINE(IA64_VCPU_DOMAIN_OFFSET, offsetof (struct vcpu, domain));
DEFINE(IA64_VCPU_HYPERCALL_CONTINUATION_OFS, offsetof (struct vcpu,
arch.hypercall_continuation));
+ DEFINE(IA64_VCPU_FP_PSR_OFFSET, offsetof (struct vcpu, arch.fp_psr));
DEFINE(IA64_VCPU_META_RR0_OFFSET, offsetof (struct vcpu,
arch.metaphysical_rr0));
DEFINE(IA64_VCPU_META_SAVED_RR0_OFFSET, offsetof (struct vcpu,
arch.metaphysical_saved_rr0));
DEFINE(IA64_VCPU_BREAKIMM_OFFSET, offsetof (struct vcpu,
arch.breakimm));
@@ -199,6 +200,7 @@ void foo(void)
DEFINE(IA64_VPD_BASE_OFFSET, offsetof (struct vcpu, arch.privregs));
DEFINE(IA64_VPD_VIFS_OFFSET, offsetof (mapped_regs_t, ifs));
DEFINE(IA64_VLSAPIC_INSVC_BASE_OFFSET, offsetof (struct vcpu,
arch.insvc[0]));
+ DEFINE(IA64_VPD_VPTA_OFFSET, offsetof (struct mapped_regs, pta));
DEFINE(IA64_VPD_CR_VPTA_OFFSET, offsetof (cr_t, pta));
DEFINE(XXX_THASH_SIZE, sizeof (thash_data_t));
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/asm-xsi-offsets.c
--- a/xen/arch/ia64/asm-xsi-offsets.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/asm-xsi-offsets.c Wed Feb 14 19:01:35 2007 +0000
@@ -61,6 +61,8 @@ void foo(void)
DEFINE_MAPPED_REG_OFS(XSI_ITIR_OFS, itir);
DEFINE_MAPPED_REG_OFS(XSI_ITV_OFS, itv);
DEFINE_MAPPED_REG_OFS(XSI_PTA_OFS, pta);
+ DEFINE_MAPPED_REG_OFS(XSI_VPSR_DFH_OFS, vpsr_dfh);
+ DEFINE_MAPPED_REG_OFS(XSI_HPSR_DFH_OFS, hpsr_dfh);
DEFINE_MAPPED_REG_OFS(XSI_PSR_IC_OFS, interrupt_collection_enabled);
DEFINE_MAPPED_REG_OFS(XSI_VPSR_PP_OFS, vpsr_pp);
DEFINE_MAPPED_REG_OFS(XSI_METAPHYS_OFS, metaphysical_mode);
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/linux-xen/head.S
--- a/xen/arch/ia64/linux-xen/head.S Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/linux-xen/head.S Wed Feb 14 19:01:35 2007 +0000
@@ -267,13 +267,8 @@ start_ap:
/*
* Switch into virtual mode:
*/
-#if defined(XEN) && defined(VALIDATE_VT)
- movl r16=(IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH\
- |IA64_PSR_DI)
-#else
movl
r16=(IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN \
|IA64_PSR_DI)
-#endif
;;
mov cr.ipsr=r16
movl r17=1f
@@ -292,11 +287,7 @@ 1: // now we are in virtual mode
;;
// set IVT entry point---can't access I/O ports without it
-#if defined(XEN) && defined(VALIDATE_VT)
- movl r3=vmx_ia64_ivt
-#else
movl r3=ia64_ivt
-#endif
;;
mov cr.iva=r3
movl r2=FPSR_DEFAULT
@@ -368,15 +359,8 @@ 1: // now we are in virtual mode
.load_current:
// load the "current" pointer (r13) and ar.k6 with the current task
-#if defined(XEN) && defined(VALIDATE_VT)
- mov r21=r2
- ;;
- bsw.1
- ;;
-#else
mov IA64_KR(CURRENT)=r2 // virtual address
mov IA64_KR(CURRENT_STACK)=r16
-#endif
mov r13=r2
/*
* Reserve space at the top of the stack for "struct pt_regs". Kernel
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/linux-xen/mca.c
--- a/xen/arch/ia64/linux-xen/mca.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/linux-xen/mca.c Wed Feb 14 19:01:35 2007 +0000
@@ -84,6 +84,7 @@
#include <xen/event.h>
#include <xen/softirq.h>
#include <asm/xenmca.h>
+#include <linux/shutdown.h>
#endif
#if defined(IA64_MCA_DEBUG_INFO)
@@ -684,16 +685,8 @@ fetch_min_state (pal_min_state_area_t *m
#ifdef XEN
static spinlock_t init_dump_lock = SPIN_LOCK_UNLOCKED;
static spinlock_t show_stack_lock = SPIN_LOCK_UNLOCKED;
-
-static void
-save_ksp (struct unw_frame_info *info, void *arg)
-{
- current->arch._thread.ksp = (__u64)(info->sw) - 16;
- wmb();
-}
-
-/* FIXME */
-int try_crashdump(struct pt_regs *a) { return 0; }
+static atomic_t num_stopped_cpus = ATOMIC_INIT(0);
+extern void show_stack (struct task_struct *, unsigned long *);
#define CPU_FLUSH_RETRY_MAX 5
static void
@@ -716,6 +709,35 @@ init_cache_flush (void)
}
printk("\nPAL cache flush failed. status=%ld\n",rval);
}
+
+static void inline
+save_ksp (struct unw_frame_info *info)
+{
+ current->arch._thread.ksp = (__u64)(info->sw) - 16;
+ wmb();
+ init_cache_flush();
+}
+
+static void
+freeze_cpu_osinit (struct unw_frame_info *info, void *arg)
+{
+ save_ksp(info);
+ atomic_inc(&num_stopped_cpus);
+ printk("%s: CPU%d init handler done\n",
+ __FUNCTION__, smp_processor_id());
+ for (;;)
+ local_irq_disable();
+}
+
+/* FIXME */
+static void
+try_crashdump(struct unw_frame_info *info, void *arg)
+{
+ save_ksp(info);
+ printk("\nINIT dump complete. Please reboot now.\n");
+ for (;;)
+ local_irq_disable();
+}
#endif /* XEN */
static void
@@ -741,7 +763,8 @@ init_handler_platform (pal_min_state_are
show_min_state(ms);
#ifdef XEN
- printk("Backtrace of current vcpu (vcpu_id %d)\n", current->vcpu_id);
+ printk("Backtrace of current vcpu (vcpu_id %d of domid %d)\n",
+ current->vcpu_id, current->domain->domain_id);
#else
printk("Backtrace of current task (pid %d, %s)\n", current->pid,
current->comm);
fetch_min_state(ms, pt, sw);
@@ -749,20 +772,35 @@ init_handler_platform (pal_min_state_are
unw_init_from_interruption(&info, current, pt, sw);
ia64_do_show_stack(&info, NULL);
#ifdef XEN
- unw_init_running(save_ksp, NULL);
spin_unlock(&show_stack_lock);
- wmb();
- init_cache_flush();
if (spin_trylock(&init_dump_lock)) {
+ struct domain *d;
+ struct vcpu *v;
#ifdef CONFIG_SMP
- udelay(5*1000000);
-#endif
- if (try_crashdump(pt) == 0)
- printk("\nINIT dump complete. Please reboot now.\n");
- }
- printk("%s: CPU%d init handler done\n",
- __FUNCTION__, smp_processor_id());
+ int other_cpus = num_online_cpus() - 1;
+ int wait = 1000 * other_cpus;
+
+ while ((atomic_read(&num_stopped_cpus) != other_cpus) && wait--)
+ udelay(1000);
+ if (other_cpus && wait < 0)
+ printk("timeout %d\n", atomic_read(&num_stopped_cpus));
+#endif
+ if (opt_noreboot) {
+ /* this route is for dump routine */
+ unw_init_running(try_crashdump, pt);
+ } else {
+ for_each_domain(d) {
+ for_each_vcpu(d, v) {
+ printk("Backtrace of current vcpu "
+ "(vcpu_id %d of domid %d)\n",
+ v->vcpu_id, d->domain_id);
+ show_stack(v, NULL);
+ }
+ }
+ }
+ }
+ unw_init_running(freeze_cpu_osinit, NULL);
#else /* XEN */
#ifdef CONFIG_SMP
/* read_trylock() would be handy... */
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/vmx/optvfault.S
--- a/xen/arch/ia64/vmx/optvfault.S Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/vmx/optvfault.S Wed Feb 14 19:01:35 2007 +0000
@@ -15,6 +15,7 @@
#include <asm/vmx_vpd.h>
#include <asm/vmx_pal_vsa.h>
#include <asm/asm-offsets.h>
+#include <asm-ia64/vmx_mm_def.h>
#define ACCE_MOV_FROM_AR
#define ACCE_MOV_FROM_RR
@@ -22,6 +23,7 @@
#define ACCE_RSM
#define ACCE_SSM
#define ACCE_MOV_TO_PSR
+#define ACCE_THASH
//mov r1=ar3
GLOBAL_ENTRY(vmx_asm_mov_from_ar)
@@ -192,6 +194,13 @@ GLOBAL_ENTRY(vmx_asm_rsm)
;;
st8 [r17]=r19
and r20=r20,r28
+ adds r27=IA64_VCPU_FP_PSR_OFFSET,r21
+ ;;
+ ld8 r27=[r27]
+ ;;
+ tbit.nz p8,p0= r27,IA64_PSR_DFH_BIT
+ ;;
+ (p8) dep r20=-1,r20,IA64_PSR_DFH_BIT,1
;;
mov cr.ipsr=r20
tbit.nz p6,p0=r23,0
@@ -360,6 +369,14 @@ vmx_asm_mov_to_psr_1:
add r20=r19,r20
mov b0=r24
;;
+ adds r27=IA64_VCPU_FP_PSR_OFFSET,r21
+ ;;
+ ld8 r27=[r27]
+ ;;
+ tbit.nz p8,p0=r27,IA64_PSR_DFH_BIT
+ ;;
+ (p8) dep r20=-1,r20,IA64_PSR_DFH_BIT,1
+ ;;
mov cr.ipsr=r20
cmp.ne p6,p0=r0,r0
;;
@@ -403,6 +420,64 @@ ENTRY(vmx_asm_dispatch_vexirq)
br.many vmx_dispatch_vexirq
END(vmx_asm_dispatch_vexirq)
+// thash
+// TODO: add support when pta.vf = 1
+GLOBAL_ENTRY(vmx_asm_thash)
+#ifndef ACCE_THASH
+ br.many vmx_virtualization_fault_back
+#endif
+ extr.u r17=r25,20,7 // get r3 from opcode in r25
+ extr.u r18=r25,6,7 // get r1 from opcode in r25
+ movl r20=asm_mov_from_reg
+ ;;
+ adds r30=vmx_asm_thash_back1-asm_mov_from_reg,r20
+ shladd r17=r17,4,r20 // get addr of MOVE_FROM_REG(r17)
+ adds r16=IA64_VPD_BASE_OFFSET,r21 // get vcpu.arch.priveregs
+ ;;
+ mov r24=b0
+ ;;
+ ld8 r16=[r16] // get VPD addr
+ mov b0=r17
+ br.many b0 // r19 return value
+ ;;
+vmx_asm_thash_back1:
+ shr.u r23=r19,61 // get RR number
+ adds r25=VCPU_VRR0_OFS,r21 // get vcpu->arch.arch_vmx.vrr[0]'s addr
+ adds r16=IA64_VPD_VPTA_OFFSET,r16 // get vpta
+ ;;
+ shladd r27=r23,3,r25 // get vcpu->arch.arch_vmx.vrr[r23]'s addr
+ ld8 r17=[r16] // get PTA
+ mov r26=1
+ ;;
+ extr.u r29=r17,2,6 // get pta.size
+ ld8 r25=[r27] // get vcpu->arch.arch_vmx.vrr[r23]'s value
+ ;;
+ extr.u r25=r25,2,6 // get rr.ps
+ shl r22=r26,r29 // 1UL << pta.size
+ ;;
+ shr.u r23=r19,r25 // vaddr >> rr.ps
+ adds r26=3,r29 // pta.size + 3
+ shl r27=r17,3 // pta << 3
+ ;;
+ shl r23=r23,3 // (vaddr >> rr.ps) << 3
+ shr.u r27=r27,r26 // (pta << 3) >> (pta.size+3)
+ movl r16=VRN_MASK
+ ;;
+ adds r22=-1,r22 // (1UL << pta.size) - 1
+ shl r27=r27,r29 // ((pta<<3)>>(pta.size+3))<<pta.size
+ and r19=r19,r16 // vaddr & VRN_MASK
+ ;;
+ and r22=r22,r23 // vhpt_offset
+ or r19=r19,r27 // (vadr&VRN_MASK) |(((pta<<3)>>(pta.size +
3))<<pta.size)
+ adds r26=asm_mov_to_reg-asm_mov_from_reg,r20
+ ;;
+ or r19=r19,r22 // calc pval
+ shladd r17=r18,4,r26
+ adds r30=vmx_resume_to_guest-asm_mov_from_reg,r20
+ ;;
+ mov b0=r17
+ br.many b0
+END(vmx_asm_thash)
#define MOV_TO_REG0 \
{; \
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/vmx/vlsapic.c
--- a/xen/arch/ia64/vmx/vlsapic.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/vmx/vlsapic.c Wed Feb 14 19:01:35 2007 +0000
@@ -171,7 +171,12 @@ static void vtm_timer_fn(void *data)
} else
vtm->pending = 1;
- update_last_itc(vtm, VCPU(vcpu, itm)); // update vITC
+ /*
+ * "+ 1" is for fixing oops message at timer_interrupt() on VTI guest.
+ * If oops checking condition changed to timer_after_eq() on VTI guest,
+ * this parameter should be erased.
+ */
+ update_last_itc(vtm, VCPU(vcpu, itm) + 1); // update vITC
}
void vtm_init(VCPU *vcpu)
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/vmx/vmmu.c
--- a/xen/arch/ia64/vmx/vmmu.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/vmx/vmmu.c Wed Feb 14 19:01:35 2007 +0000
@@ -129,13 +129,15 @@ purge_machine_tc_by_domid(domid_t domid)
#endif
}
-static void init_domain_vhpt(struct vcpu *v)
+static int init_domain_vhpt(struct vcpu *v)
{
struct page_info *page;
void * vbase;
page = alloc_domheap_pages (NULL, VCPU_VHPT_ORDER, 0);
if ( page == NULL ) {
- panic_domain(vcpu_regs(v),"No enough contiguous memory for
init_domain_vhpt\n");
+ printk("No enough contiguous memory for init_domain_vhpt\n");
+
+ return -1;
}
vbase = page_to_virt(page);
memset(vbase, 0, VCPU_VHPT_SIZE);
@@ -147,18 +149,36 @@ static void init_domain_vhpt(struct vcpu
VHPT(v,cch_sz) = VCPU_VHPT_SIZE - VHPT(v,hash_sz);
thash_init(&(v->arch.vhpt),VCPU_VHPT_SHIFT-1);
v->arch.arch_vmx.mpta = v->arch.vhpt.pta.val;
-}
-
-
-
-void init_domain_tlb(struct vcpu *v)
+
+ return 0;
+}
+
+
+static void free_domain_vhpt(struct vcpu *v)
+{
+ struct page_info *page;
+
+ if (v->arch.vhpt.hash) {
+ page = virt_to_page(v->arch.vhpt.hash);
+ free_domheap_pages(page, VCPU_VHPT_ORDER);
+ }
+
+ return;
+}
+
+int init_domain_tlb(struct vcpu *v)
{
struct page_info *page;
void * vbase;
- init_domain_vhpt(v);
+
+ if (init_domain_vhpt(v) != 0)
+ return -1;
+
page = alloc_domheap_pages (NULL, VCPU_VTLB_ORDER, 0);
if ( page == NULL ) {
- panic_domain(vcpu_regs(v),"No enough contiguous memory for
init_domain_tlb\n");
+ printk("No enough contiguous memory for init_domain_tlb\n");
+ free_domain_vhpt(v);
+ return -1;
}
vbase = page_to_virt(page);
memset(vbase, 0, VCPU_VTLB_SIZE);
@@ -169,7 +189,10 @@ void init_domain_tlb(struct vcpu *v)
VTLB(v,cch_buf) = (void *)((u64)vbase + VTLB(v,hash_sz));
VTLB(v,cch_sz) = VCPU_VTLB_SIZE - VTLB(v,hash_sz);
thash_init(&(v->arch.vtlb),VCPU_VTLB_SHIFT-1);
-}
+
+ return 0;
+}
+
void free_domain_tlb(struct vcpu *v)
{
@@ -179,10 +202,8 @@ void free_domain_tlb(struct vcpu *v)
page = virt_to_page(v->arch.vtlb.hash);
free_domheap_pages(page, VCPU_VTLB_ORDER);
}
- if ( v->arch.vhpt.hash) {
- page = virt_to_page(v->arch.vhpt.hash);
- free_domheap_pages(page, VCPU_VHPT_ORDER);
- }
+
+ free_domain_vhpt(v);
}
/*
@@ -553,7 +574,8 @@ static void ptc_ga_remote_func (void *va
mpta = ia64_get_pta();
ia64_set_pta(v->arch.arch_vmx.mpta&(~1));
ia64_srlz_d();
- vmx_vcpu_ptc_l(v, REGION_OFFSET(vadr), args->ps);
+ vadr = PAGEALIGN(vadr, args->ps);
+ thash_purge_entries_remote(v, vadr, args->ps);
VMX(v, vrr[0]) = oldrid;
VMX(v, psbits[0]) = oldpsbits;
ia64_set_rr(0x0,moldrid);
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/vmx/vmx_entry.S
--- a/xen/arch/ia64/vmx/vmx_entry.S Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/vmx/vmx_entry.S Wed Feb 14 19:01:35 2007 +0000
@@ -190,12 +190,8 @@ GLOBAL_ENTRY(ia64_leave_hypervisor)
PT_REGS_UNWIND_INFO(0)
rsm psr.i
;;
- alloc loc0=ar.pfs,0,1,1,0
- ;;
- adds out0=16,r12
br.call.sptk.many b0=leave_hypervisor_tail
;;
- mov ar.pfs=loc0
adds r20=PT(PR)+16,r12
adds r8=PT(EML_UNAT)+16,r12
;;
@@ -302,11 +298,9 @@ GLOBAL_ENTRY(ia64_leave_hypervisor)
;;
mov ar.fpsr=r19
mov ar.ccv=r18
- ;;
-//rbs_switch
-
shr.u r18=r20,16
;;
+vmx_rbs_switch:
movl r19= THIS_CPU(ia64_phys_stacked_size_p8)
;;
ld4 r19=[r19]
@@ -368,7 +362,7 @@ vmx_rse_clear_invalid:
;;
mov cr.ipsr=r31
mov cr.iip=r30
- mov cr.ifs=r29
+(pNonSys) mov cr.ifs=r29
mov ar.pfs=r27
adds r18=IA64_VPD_BASE_OFFSET,r21
;;
@@ -425,148 +419,190 @@ END(ia64_vmm_entry)
END(ia64_vmm_entry)
-#ifdef XEN_DBL_MAPPING /* will be removed */
-
-#define VMX_PURGE_RR7 0
-#define VMX_INSERT_RR7 1
+
/*
- * in0: old rr7
- * in1: virtual address of xen image
- * in2: virtual address of vhpt table
+ * ia64_leave_syscall(): Same as ia64_leave_kernel, except that it doesn't
+ * need to switch to bank 0 and doesn't restore the scratch registers.
+ * To avoid leaking kernel bits, the scratch registers are set to
+ * the following known-to-be-safe values:
+ *
+ * r1: restored (global pointer)
+ * r2: cleared
+ * r3: 1 (when returning to user-level)
+ * r8-r11: restored (syscall return value(s))
+ * r12: restored (user-level stack pointer)
+ * r13: restored (user-level thread pointer)
+ * r14: set to __kernel_syscall_via_epc
+ * r15: restored (syscall #)
+ * r16-r17: cleared
+ * r18: user-level b6
+ * r19: cleared
+ * r20: user-level ar.fpsr
+ * r21: user-level b0
+ * r22: cleared
+ * r23: user-level ar.bspstore
+ * r24: user-level ar.rnat
+ * r25: user-level ar.unat
+ * r26: user-level ar.pfs
+ * r27: user-level ar.rsc
+ * r28: user-level ip
+ * r29: user-level psr
+ * r30: user-level cfm
+ * r31: user-level pr
+ * f6-f11: cleared
+ * pr: restored (user-level pr)
+ * b0: restored (user-level rp)
+ * b6: restored
+ * b7: set to __kernel_syscall_via_epc
+ * ar.unat: restored (user-level ar.unat)
+ * ar.pfs: restored (user-level ar.pfs)
+ * ar.rsc: restored (user-level ar.rsc)
+ * ar.rnat: restored (user-level ar.rnat)
+ * ar.bspstore: restored (user-level ar.bspstore)
+ * ar.fpsr: restored (user-level ar.fpsr)
+ * ar.ccv: cleared
+ * ar.csd: cleared
+ * ar.ssd: cleared
*/
-GLOBAL_ENTRY(vmx_purge_double_mapping)
- alloc loc1 = ar.pfs,5,9,0,0
- mov loc0 = rp
- movl r8 = 1f
- ;;
- movl loc4 = KERNEL_TR_PAGE_SHIFT
- movl loc5 = VCPU_TLB_SHIFT
- mov loc6 = psr
- movl loc7 = XEN_RR7_SWITCH_STUB
- mov loc8 = (1<<VMX_PURGE_RR7)
- ;;
- srlz.i
- ;;
- rsm psr.i | psr.ic
- ;;
- srlz.i
- ;;
- mov ar.rsc = 0
- mov b6 = loc7
- mov rp = r8
- ;;
- br.sptk b6
-1:
- mov ar.rsc = 3
- mov rp = loc0
- ;;
- mov psr.l = loc6
- ;;
- srlz.i
- ;;
- br.ret.sptk rp
-END(vmx_purge_double_mapping)
-
-/*
- * in0: new rr7
- * in1: virtual address of xen image
- * in2: virtual address of vhpt table
- * in3: pte entry of xen image
- * in4: pte entry of vhpt table
- */
-GLOBAL_ENTRY(vmx_insert_double_mapping)
- alloc loc1 = ar.pfs,5,9,0,0
- mov loc0 = rp
- movl loc2 = IA64_TR_XEN_IN_DOM // TR number for xen image
- ;;
- movl loc3 = IA64_TR_VHPT_IN_DOM // TR number for vhpt table
- movl r8 = 1f
- movl loc4 = KERNEL_TR_PAGE_SHIFT
- ;;
- movl loc5 = VCPU_TLB_SHIFT
- mov loc6 = psr
- movl loc7 = XEN_RR7_SWITCH_STUB
- ;;
- srlz.i
- ;;
- rsm psr.i | psr.ic
- mov loc8 = (1<<VMX_INSERT_RR7)
- ;;
- srlz.i
- ;;
- mov ar.rsc = 0
- mov b6 = loc7
- mov rp = r8
- ;;
- br.sptk b6
-1:
- mov ar.rsc = 3
- mov rp = loc0
- ;;
- mov psr.l = loc6
- ;;
- srlz.i
- ;;
- br.ret.sptk rp
-END(vmx_insert_double_mapping)
-
- .align PAGE_SIZE
-/*
- * Stub to add double mapping for new domain, which shouldn't
- * access any memory when active. Before reaching this point,
- * both psr.i/ic is cleared and rse is set in lazy mode.
- *
- * in0: new rr7
- * in1: virtual address of xen image
- * in2: virtual address of vhpt table
- * in3: pte entry of xen image
- * in4: pte entry of vhpt table
- * loc2: TR number for xen image
- * loc3: TR number for vhpt table
- * loc4: page size for xen image
- * loc5: page size of vhpt table
- * loc7: free to use
- * loc8: purge or insert
- * r8: will contain old rid value
- */
-GLOBAL_ENTRY(vmx_switch_rr7)
- movl loc7 = (7<<61)
- dep.z loc4 = loc4, 2, 6
- dep.z loc5 = loc5, 2, 6
- ;;
- tbit.nz p6,p7=loc8, VMX_INSERT_RR7
- mov r8 = rr[loc7]
- ;;
- mov rr[loc7] = in0
-(p6)mov cr.ifa = in1
-(p6)mov cr.itir = loc4
- ;;
- srlz.i
- ;;
-(p6)itr.i itr[loc2] = in3
-(p7)ptr.i in1, loc4
- ;;
-(p6)itr.d dtr[loc2] = in3
-(p7)ptr.d in1, loc4
- ;;
- srlz.i
- ;;
-(p6)mov cr.ifa = in2
-(p6)mov cr.itir = loc5
- ;;
-(p6)itr.d dtr[loc3] = in4
-(p7)ptr.d in2, loc5
- ;;
- srlz.i
- ;;
- mov rr[loc7] = r8
- ;;
- srlz.i
- br.sptk rp
-END(vmx_switch_rr7)
- .align PAGE_SIZE
-
+GLOBAL_ENTRY(ia64_leave_hypercall)
+ PT_REGS_UNWIND_INFO(0)
+ /*
+ * work.need_resched etc. mustn't get changed by this CPU before it
returns to
+ * user- or fsys-mode, hence we disable interrupts early on.
+ *
+ * p6 controls whether current_thread_info()->flags needs to be check for
+ * extra work. We always check for extra work when returning to
user-level.
+ * With CONFIG_PREEMPT, we also check for extra work when the preempt_count
+ * is 0. After extra work processing has been completed, execution
+ * resumes at .work_processed_syscall with p6 set to 1 if the
extra-work-check
+ * needs to be redone.
+ */
+(pUStk) rsm psr.i
+ cmp.eq pLvSys,p0=r0,r0 // pLvSys=1: leave from syscall
+(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk
+ ;;
+ br.call.sptk.many b0=leave_hypervisor_tail
+.work_processed_syscall:
+ //clean up bank 1 registers
+ mov r16=r0
+ mov r17=r0
+ mov r18=r0
+ mov r19=r0
+ mov r20=r0
+ mov r21=r0
+ mov r22=r0
+ mov r23=r0
+ mov r24=r0
+ mov r25=r0
+ mov r26=r0
+ mov r27=r0
+ mov r28=r0
+ mov r29=r0
+ mov r30=r0
+ mov r31=r0
+ bsw.0
+ ;;
+ adds r2=PT(LOADRS)+16,r12
+ adds r3=PT(AR_BSPSTORE)+16,r12
+#ifndef XEN
+ adds r18=TI_FLAGS+IA64_TASK_SIZE,r13
+ ;;
+(p6) ld4 r31=[r18] // load
current_thread_info()->flags
+#endif
+ ;;
+ ld8 r20=[r2],PT(B6)-PT(LOADRS) // load ar.rsc value for
"loadrs"
+ nop.i 0
+ ;;
+// mov r16=ar.bsp // M2 get existing backing
store pointer
+ ld8 r18=[r2],PT(R9)-PT(B6) // load b6
+#ifndef XEN
+(p6) and r15=TIF_WORK_MASK,r31 // any work other than
TIF_SYSCALL_TRACE?
+#endif
+ ;;
+ ld8 r24=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be
garbage)
+#ifndef XEN
+(p6) cmp4.ne.unc p6,p0=r15, r0 // any special work pending?
+(p6) br.cond.spnt .work_pending_syscall
+#endif
+ ;;
+ // start restoring the state saved on the kernel stack (struct pt_regs):
+ ld8 r9=[r2],PT(CR_IPSR)-PT(R9)
+ ld8 r11=[r3],PT(CR_IIP)-PT(R11)
+//(pNonSys) break 0 // bug check: we shouldn't be here if
pNonSys is TRUE!
+ ;;
+ invala // M0|1 invalidate ALAT
+ rsm psr.i | psr.ic // M2 turn off interrupts and interruption collection
+ cmp.eq p9,p0=r0,r0 // A set p9 to indicate that we should restore cr.ifs
+
+ ld8 r31=[r2],32 // M0|1 load cr.ipsr
+ ld8 r30=[r3],16 // M0|1 load cr.iip
+ ;;
+// ld8 r29=[r2],16 // M0|1 load cr.ifs
+ ld8 r28=[r3],16 // M0|1 load ar.unat
+//(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
+ ;;
+ ld8 r27=[r2],PT(B0)-PT(AR_PFS) // M0|1 load ar.pfs
+(pKStk) mov r22=psr // M2 read PSR now that interrupts
are disabled
+ nop 0
+ ;;
+ ld8 r22=[r2],PT(AR_RNAT)-PT(B0) // M0|1 load b0
+ ld8 r26=[r3],PT(PR)-PT(AR_RSC) // M0|1 load ar.rsc
+ mov f6=f0 // F clear f6
+ ;;
+ ld8 r25=[r2],PT(AR_FPSR)-PT(AR_RNAT) // M0|1 load ar.rnat (may be
garbage)
+ ld8 r23=[r3],PT(R1)-PT(PR) // M0|1 load predicates
+ mov f7=f0 // F clear f7
+ ;;
+ ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // M0|1 load ar.fpsr
+ ld8.fill r1=[r3],16 // M0|1 load r1
+//(pUStk) mov r17=1 // A
+ ;;
+//(pUStk) st1 [r14]=r17 // M2|3
+ ld8.fill r13=[r3],16 // M0|1
+ mov f8=f0 // F clear f8
+ ;;
+ ld8.fill r12=[r2] // M0|1 restore r12 (sp)
+#ifdef XEN
+ ld8.fill r2=[r3] // M0|1
+#else
+ ld8.fill r15=[r3] // M0|1 restore r15
+#endif
+ mov b6=r18 // I0 restore b6
+ mov ar.fpsr=r20
+// addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 // A
+ mov f9=f0 // F clear f9
+//(pKStk) br.cond.dpnt.many skip_rbs_switch // B
+
+// srlz.d // M0 ensure interruption collection
is off (for cover)
+// shr.u r18=r19,16 // I0|1 get byte size of existing "dirty"
partition
+ mov r3=r21
+ cover // B add current frame into dirty
partition & set cr.ifs
+ ;;
+//(pUStk) ld4 r17=[r17] // M0|1 r17 =
cpu_data->phys_stacked_size_p8
+ mov r19=ar.bsp // M2 get new backing store pointer
+ addl r18=IA64_RBS_OFFSET, r3
+ ;;
+ mov r3=r0
+ sub r18=r19,r18 // get byte size of existing "dirty" partition
+ ;;
+ shl r20=r18,16 // set rsc.load
+ mov f10=f0 // F clear f10
+#ifdef XEN
+ mov r14=r0
#else
+ movl r14=__kernel_syscall_via_epc // X
+#endif
+ ;;
+ mov.m ar.csd=r0 // M2 clear ar.csd
+ mov.m ar.ccv=r0 // M2 clear ar.ccv
+ mov b7=r14 // I0 clear b7 (hint with
__kernel_syscall_via_epc)
+
+ mov.m ar.ssd=r0 // M2 clear ar.ssd
+ mov f11=f0 // F clear f11
+ br.cond.sptk.many vmx_rbs_switch // B
+END(ia64_leave_hypercall)
+
+
/*
* in0: new rr7
* in1: virtual address of shared_info
@@ -707,5 +743,3 @@ 1:
srlz.d // seralize restoration of psr.l
br.ret.sptk.many rp
END(vmx_switch_rr7)
-#endif
-
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/vmx/vmx_init.c
--- a/xen/arch/ia64/vmx/vmx_init.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/vmx/vmx_init.c Wed Feb 14 19:01:35 2007 +0000
@@ -290,7 +290,7 @@ static void vmx_release_assist_channel(s
* Initialize VMX envirenment for guest. Only the 1st vp/vcpu
* is registered here.
*/
-void
+int
vmx_final_setup_guest(struct vcpu *v)
{
vpd_t *vpd;
@@ -305,7 +305,8 @@ vmx_final_setup_guest(struct vcpu *v)
* to this solution. Maybe it can be deferred until we know created
* one as vmx domain */
#ifndef HASH_VHPT
- init_domain_tlb(v);
+ if (init_domain_tlb(v) != 0)
+ return -1;
#endif
vmx_create_event_channels(v);
@@ -322,6 +323,8 @@ vmx_final_setup_guest(struct vcpu *v)
/* Set up guest 's indicator for VTi domain*/
set_bit(ARCH_VMX_DOMAIN, &v->arch.arch_vmx.flags);
+
+ return 0;
}
void
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/vmx/vmx_interrupt.c
--- a/xen/arch/ia64/vmx/vmx_interrupt.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/vmx/vmx_interrupt.c Wed Feb 14 19:01:35 2007 +0000
@@ -99,7 +99,7 @@ inject_guest_interruption(VCPU *vcpu, u6
pt_isr.ir = 0;
VMX(vcpu,cr_isr) = pt_isr.val;
collect_interruption(vcpu);
-
+ vmx_ia64_set_dcr(vcpu);
vmx_vcpu_get_iva(vcpu,&viva);
regs->cr_iip = viva + vec;
}
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/vmx/vmx_ivt.S
--- a/xen/arch/ia64/vmx/vmx_ivt.S Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/vmx/vmx_ivt.S Wed Feb 14 19:01:35 2007 +0000
@@ -59,6 +59,14 @@
#include <asm/unistd.h>
#include <asm/vhpt.h>
#include <asm/virt_event.h>
+#include <xen/errno.h>
+
+#if 1
+# define PSR_DEFAULT_BITS psr.ac
+#else
+# define PSR_DEFAULT_BITS 0
+#endif
+
#ifdef VTI_DEBUG
/*
@@ -431,17 +439,152 @@ ENTRY(vmx_break_fault)
VMX_DBG_FAULT(11)
mov r31=pr
mov r19=11
- mov r30=cr.iim
+ mov r17=cr.iim
;;
#ifdef VTI_DEBUG
// break 0 is already handled in vmx_ia64_handle_break.
- cmp.eq p6,p7=r30,r0
+ cmp.eq p6,p7=r17,r0
(p6) br.sptk vmx_fault_11
;;
#endif
- br.sptk.many vmx_dispatch_break_fault
- ;;
- VMX_FAULT(11);
+ mov r29=cr.ipsr
+ adds r22=IA64_VCPU_BREAKIMM_OFFSET, r21
+ ;;
+ ld4 r22=[r22]
+ extr.u r24=r29,IA64_PSR_CPL0_BIT,2
+ cmp.eq p0,p6=r0,r0
+ ;;
+ cmp.ne.or p6,p0=r22,r17
+ cmp.ne.or p6,p0=r0,r24
+(p6) br.sptk.many vmx_dispatch_break_fault
+ ;;
+ /*
+ * The streamlined system call entry/exit paths only save/restore the
initial part
+ * of pt_regs. This implies that the callers of system-calls must adhere
to the
+ * normal procedure calling conventions.
+ *
+ * Registers to be saved & restored:
+ * CR registers: cr.ipsr, cr.iip, cr.ifs
+ * AR registers: ar.unat, ar.pfs, ar.rsc, ar.rnat, ar.bspstore, ar.fpsr
+ * others: pr, b0, b6, loadrs, r1, r11, r12, r13, r15
+ * Registers to be restored only:
+ * r8-r11: output value from the system call.
+ *
+ * During system call exit, scratch registers (including r15) are
modified/cleared
+ * to prevent leaking bits from kernel to user level.
+ */
+
+// mov.m r16=IA64_KR(CURRENT) // M2 r16 <- current task (12 cyc)
+ mov r14=r21
+ bsw.1 // B (6 cyc) regs are saved,
switch to bank 1
+ ;;
+ mov r29=cr.ipsr // M2 (12 cyc)
+ mov r31=pr // I0 (2 cyc)
+ mov r16=r14
+ mov r15=r2
+
+ mov r17=cr.iim // M2 (2 cyc)
+ mov.m r27=ar.rsc // M2 (12 cyc)
+// mov r18=__IA64_BREAK_SYSCALL // A
+
+ mov.m ar.rsc=0 // M2
+ mov.m r21=ar.fpsr // M2 (12 cyc)
+ mov r19=b6 // I0 (2 cyc)
+ ;;
+ mov.m r23=ar.bspstore // M2 (12 cyc)
+ mov.m r24=ar.rnat // M2 (5 cyc)
+ mov.i r26=ar.pfs // I0 (2 cyc)
+
+ invala // M0|1
+ nop.m 0 // M
+ mov r20=r1 // A save r1
+
+ nop.m 0
+// movl r30=sys_call_table // X
+ movl r30=ia64_hypercall_table // X
+
+ mov r28=cr.iip // M2 (2 cyc)
+// cmp.eq p0,p7=r18,r17 // I0 is this a system call?
+//(p7) br.cond.spnt non_syscall // B no ->
+ //
+ // From this point on, we are definitely on the syscall-path
+ // and we can use (non-banked) scratch registers.
+ //
+///////////////////////////////////////////////////////////////////////
+ mov r1=r16 // A move task-pointer to
"addl"-addressable reg
+ mov r2=r16 // A setup r2 for ia64_syscall_setup
+// add r9=TI_FLAGS+IA64_TASK_SIZE,r16 // A r9 =
¤t_thread_info()->flags
+
+// adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16
+// adds r15=-1024,r15 // A subtract 1024 from syscall
number
+// mov r3=NR_syscalls - 1
+ mov r3=NR_hypercalls - 1
+ ;;
+// ld1.bias r17=[r16] // M0|1 r17 = current->thread.on_ustack
flag
+// ld4 r9=[r9] // M0|1 r9 =
current_thread_info()->flags
+ mov r9=r0 // force flags = 0
+ extr.u r8=r29,41,2 // I0 extract ei field from cr.ipsr
+
+ shladd r30=r15,3,r30 // A r30 = sys_call_table +
8*(syscall-1024)
+ addl r22=IA64_RBS_OFFSET,r1 // A compute base of RBS
+ cmp.leu p6,p7=r15,r3 // A syscall number in range?
+ ;;
+
+ lfetch.fault.excl.nt1 [r22] // M0|1 prefetch RBS
+(p6) ld8 r30=[r30] // M0|1 load address of syscall
entry point
+ tnat.nz.or p7,p0=r15 // I0 is syscall nr a NaT?
+
+ mov.m ar.bspstore=r22 // M2 switch to kernel RBS
+ cmp.eq p8,p9=2,r8 // A isr.ei==2?
+ ;;
+
+(p8) mov r8=0 // A clear ei to 0
+//(p7) movl r30=sys_ni_syscall // X
+(p7) movl r30=do_ni_hypercall // X
+
+(p8) adds r28=16,r28 // A switch cr.iip to next
bundle
+(p9) adds r8=1,r8 // A increment ei to next
slot
+ nop.i 0
+ ;;
+
+ mov.m r25=ar.unat // M2 (5 cyc)
+ dep r29=r8,r29,41,2 // I0 insert new ei into
cr.ipsr
+// adds r15=1024,r15 // A restore original syscall number
+ //
+ // If any of the above loads miss in L1D, we'll stall here until
+ // the data arrives.
+ //
+///////////////////////////////////////////////////////////////////////
+// st1 [r16]=r0 // M2|3 clear
current->thread.on_ustack flag
+ mov b6=r30 // I0 setup syscall handler branch
reg early
+ cmp.ne pKStk,pUStk=r0,r0 // A were we on kernel stacks
already?
+
+// and r9=_TIF_SYSCALL_TRACEAUDIT,r9 // A mask trace or audit
+ mov r18=ar.bsp // M2 (12 cyc)
+ ;;
+(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1 // A compute base of
memory stack
+// cmp.eq p14,p0=r9,r0 // A are syscalls being
traced/audited?
+// br.call.sptk.many b7=ia64_syscall_setup // B
+ br.call.sptk.many b7=ia64_hypercall_setup // B
+1:
+ mov ar.rsc=0x3 // M2 set eager mode, pl 0,
LE, loadrs=0
+// nop 0
+// bsw.1 // B (6 cyc) regs are saved,
switch to bank 1
+ ;;
+ ssm psr.ic | PSR_DEFAULT_BITS // M2 now it's safe to
re-enable intr.-collection
+// movl r3=ia64_ret_from_syscall // X
+ movl r3=ia64_leave_hypercall // X
+ ;;
+
+ srlz.i // M0 ensure interruption
collection is on
+ mov rp=r3 // I0 set the real return addr
+ //(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad
call-frame or r15 is a NaT
+ (p15) ssm psr.i // M2 restore psr.i
+ //(p14) br.call.sptk.many b6=b6 // B invoke
syscall-handker (ignore return addr)
+ br.call.sptk.many b6=b6 // B invoke syscall-handker
(ignore return addr)
+// br.cond.spnt.many ia64_trace_syscall // B do syscall-tracing
thingamagic
+ ;;
+ VMX_FAULT(11)
END(vmx_break_fault)
.org vmx_ia64_ivt+0x3000
@@ -613,6 +756,146 @@ END(vmx_virtual_exirq)
// 0x3800 Entry 14 (size 64 bundles) Reserved
VMX_DBG_FAULT(14)
VMX_FAULT(14)
+ // this code segment is from 2.6.16.13
+
+ /*
+ * There is no particular reason for this code to be here, other than that
+ * there happens to be space here that would go unused otherwise. If this
+ * fault ever gets "unreserved", simply moved the following code to a more
+ * suitable spot...
+ *
+ * ia64_syscall_setup() is a separate subroutine so that it can
+ * allocate stacked registers so it can safely demine any
+ * potential NaT values from the input registers.
+ *
+ * On entry:
+ * - executing on bank 0 or bank 1 register set (doesn't matter)
+ * - r1: stack pointer
+ * - r2: current task pointer
+ * - r3: preserved
+ * - r11: original contents (saved ar.pfs to be saved)
+ * - r12: original contents (sp to be saved)
+ * - r13: original contents (tp to be saved)
+ * - r15: original contents (syscall # to be saved)
+ * - r18: saved bsp (after switching to kernel stack)
+ * - r19: saved b6
+ * - r20: saved r1 (gp)
+ * - r21: saved ar.fpsr
+ * - r22: kernel's register backing store base (krbs_base)
+ * - r23: saved ar.bspstore
+ * - r24: saved ar.rnat
+ * - r25: saved ar.unat
+ * - r26: saved ar.pfs
+ * - r27: saved ar.rsc
+ * - r28: saved cr.iip
+ * - r29: saved cr.ipsr
+ * - r31: saved pr
+ * - b0: original contents (to be saved)
+ * On exit:
+ * - p10: TRUE if syscall is invoked with more than 8 out
+ * registers or r15's Nat is true
+ * - r1: kernel's gp
+ * - r3: preserved (same as on entry)
+ * - r8: -EINVAL if p10 is true
+ * - r12: points to kernel stack
+ * - r13: points to current task
+ * - r14: preserved (same as on entry)
+ * - p13: preserved
+ * - p15: TRUE if interrupts need to be re-enabled
+ * - ar.fpsr: set to kernel settings
+ * - b6: preserved (same as on entry)
+ */
+GLOBAL_ENTRY(ia64_hypercall_setup)
+#if PT(B6) != 0
+# error This code assumes that b6 is the first field in pt_regs.
+#endif
+ st8 [r1]=r19 // save b6
+ add r16=PT(CR_IPSR),r1 // initialize first base pointer
+ add r17=PT(R11),r1 // initialize second base pointer
+ ;;
+ alloc r19=ar.pfs,8,0,0,0 // ensure in0-in7 are writable
+ st8 [r16]=r29,PT(AR_PFS)-PT(CR_IPSR) // save cr.ipsr
+ tnat.nz p8,p0=in0
+
+ st8.spill [r17]=r11,PT(CR_IIP)-PT(R11) // save r11
+ tnat.nz p9,p0=in1
+(pKStk) mov r18=r0 // make sure r18 isn't NaT
+ ;;
+
+ st8 [r16]=r26,PT(CR_IFS)-PT(AR_PFS) // save ar.pfs
+ st8 [r17]=r28,PT(AR_UNAT)-PT(CR_IIP) // save cr.iip
+ mov r28=b0 // save b0 (2 cyc)
+ ;;
+
+ st8 [r17]=r25,PT(AR_RSC)-PT(AR_UNAT) // save ar.unat
+ dep r19=0,r19,38,26 // clear all bits but 0..37 [I0]
+(p8) mov in0=-1
+ ;;
+
+ st8 [r16]=r19,PT(AR_RNAT)-PT(CR_IFS) // store ar.pfs.pfm in cr.ifs
+ extr.u r11=r19,7,7 // I0 // get sol of ar.pfs
+ and r8=0x7f,r19 // A // get sof of ar.pfs
+
+ st8 [r17]=r27,PT(AR_BSPSTORE)-PT(AR_RSC)// save ar.rsc
+ tbit.nz p15,p0=r29,IA64_PSR_I_BIT // I0
+(p9) mov in1=-1
+ ;;
+
+(pUStk) sub r18=r18,r22 // r18=RSE.ndirty*8
+ tnat.nz p10,p0=in2
+ add r11=8,r11
+ ;;
+(pKStk) adds r16=PT(PR)-PT(AR_RNAT),r16 // skip over ar_rnat
field
+(pKStk) adds r17=PT(B0)-PT(AR_BSPSTORE),r17 // skip over ar_bspstore field
+ tnat.nz p11,p0=in3
+ ;;
+(p10) mov in2=-1
+ tnat.nz p12,p0=in4 // [I0]
+(p11) mov in3=-1
+ ;;
+(pUStk) st8 [r16]=r24,PT(PR)-PT(AR_RNAT) // save ar.rnat
+(pUStk) st8 [r17]=r23,PT(B0)-PT(AR_BSPSTORE) // save ar.bspstore
+ shl r18=r18,16 // compute ar.rsc to be used
for "loadrs"
+ ;;
+ st8 [r16]=r31,PT(LOADRS)-PT(PR) // save predicates
+ st8 [r17]=r28,PT(R1)-PT(B0) // save b0
+ tnat.nz p13,p0=in5 // [I0]
+ ;;
+ st8 [r16]=r18,PT(R12)-PT(LOADRS) // save ar.rsc value for "loadrs"
+ st8.spill [r17]=r20,PT(R13)-PT(R1) // save original r1
+(p12) mov in4=-1
+ ;;
+
+.mem.offset 0,0; st8.spill [r16]=r12,PT(AR_FPSR)-PT(R12) // save r12
+.mem.offset 8,0; st8.spill [r17]=r13,PT(R15)-PT(R13) // save r13
+(p13) mov in5=-1
+ ;;
+ st8 [r16]=r21,PT(R8)-PT(AR_FPSR) // save ar.fpsr
+ tnat.nz p13,p0=in6
+ cmp.lt p10,p9=r11,r8 // frame size can't be more than local+8
+ ;;
+ mov r8=1
+(p9) tnat.nz p10,p0=r15
+ adds r12=-16,r1 // switch to kernel memory stack (with 16 bytes
of scratch)
+
+ st8.spill [r17]=r15 // save r15
+ tnat.nz p8,p0=in7
+ nop.i 0
+
+ mov r13=r2 // establish `current'
+ movl r1=__gp // establish kernel global
pointer
+ ;;
+ st8 [r16]=r8 // ensure pt_regs.r8 != 0 (see
handle_syscall_error)
+(p13) mov in6=-1
+(p8) mov in7=-1
+
+ cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0
+ movl r17=FPSR_DEFAULT
+ ;;
+ mov.m ar.fpsr=r17 // set ar.fpsr to kernel default value
+(p10) mov r8=-EINVAL
+ br.ret.sptk.many b7
+END(ia64_hypercall_setup)
.org vmx_ia64_ivt+0x3c00
@@ -795,12 +1078,14 @@ ENTRY(vmx_virtualization_fault)
cmp.eq p9,p0=EVENT_RSM,r24
cmp.eq p10,p0=EVENT_SSM,r24
cmp.eq p11,p0=EVENT_MOV_TO_PSR,r24
+ cmp.eq p12,p0=EVENT_THASH,r24
(p6) br.dptk.many vmx_asm_mov_from_ar
(p7) br.dptk.many vmx_asm_mov_from_rr
(p8) br.dptk.many vmx_asm_mov_to_rr
(p9) br.dptk.many vmx_asm_rsm
(p10) br.dptk.many vmx_asm_ssm
(p11) br.dptk.many vmx_asm_mov_to_psr
+ (p12) br.dptk.many vmx_asm_thash
;;
vmx_virtualization_fault_back:
mov r19=37
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/vmx/vmx_minstate.h
--- a/xen/arch/ia64/vmx/vmx_minstate.h Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/vmx/vmx_minstate.h Wed Feb 14 19:01:35 2007 +0000
@@ -174,6 +174,7 @@
;; \
st8 [r16]=r29,16; /* save b0 */ \
st8 [r17]=r18,16; /* save ar.rsc value for "loadrs" */ \
+ cmp.eq pNonSys,pSys=r0,r0 /* initialize pSys=0, pNonSys=1 */ \
;; \
.mem.offset 0,0; st8.spill [r16]=r20,16; /* save original r1 */
\
.mem.offset 8,0; st8.spill [r17]=r12,16; \
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/vmx/vmx_phy_mode.c
--- a/xen/arch/ia64/vmx/vmx_phy_mode.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/vmx/vmx_phy_mode.c Wed Feb 14 19:01:35 2007 +0000
@@ -188,7 +188,7 @@ vmx_load_all_rr(VCPU *vcpu)
(void *)vcpu->arch.privregs,
(void *)vcpu->arch.vhpt.hash, pal_vaddr );
ia64_set_pta(VMX(vcpu, mpta));
- ia64_set_dcr(VMX(vcpu, mdcr));
+ vmx_ia64_set_dcr(vcpu);
ia64_srlz_d();
ia64_set_psr(psr);
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/vmx/vmx_process.c
--- a/xen/arch/ia64/vmx/vmx_process.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/vmx/vmx_process.c Wed Feb 14 19:01:35 2007 +0000
@@ -79,36 +79,56 @@ static u64 vec2off[68] = {0x0,0x400,0x80
void vmx_reflect_interruption(u64 ifa, u64 isr, u64 iim,
- u64 vector, REGS *regs)
-{
- u64 status;
+ u64 vec, REGS *regs)
+{
+ u64 status, vector;
VCPU *vcpu = current;
u64 vpsr = VCPU(vcpu, vpsr);
- vector=vec2off[vector];
+
+ vector = vec2off[vec];
if(!(vpsr&IA64_PSR_IC)&&(vector!=IA64_DATA_NESTED_TLB_VECTOR)){
panic_domain(regs, "Guest nested fault vector=%lx!\n", vector);
}
- else{ // handle fpswa emulation
+
+ switch (vec) {
+
+ case 25: // IA64_DISABLED_FPREG_VECTOR
+
+ if (FP_PSR(vcpu) & IA64_PSR_DFH) {
+ FP_PSR(vcpu) = IA64_PSR_MFH;
+ if (__ia64_per_cpu_var(fp_owner) != vcpu)
+ __ia64_load_fpu(vcpu->arch._thread.fph);
+ }
+ if (!(VCPU(vcpu, vpsr) & IA64_PSR_DFH)) {
+ regs->cr_ipsr &= ~IA64_PSR_DFH;
+ return;
+ }
+
+ break;
+
+ case 32: // IA64_FP_FAULT_VECTOR
+ // handle fpswa emulation
// fp fault
- if (vector == IA64_FP_FAULT_VECTOR) {
- status = handle_fpu_swa(1, regs, isr);
- if (!status) {
- vcpu_increment_iip(vcpu);
- return;
- } else if (IA64_RETRY == status)
- return;
- }
+ status = handle_fpu_swa(1, regs, isr);
+ if (!status) {
+ vcpu_increment_iip(vcpu);
+ return;
+ } else if (IA64_RETRY == status)
+ return;
+ break;
+
+ case 33: // IA64_FP_TRAP_VECTOR
//fp trap
- else if (vector == IA64_FP_TRAP_VECTOR) {
- status = handle_fpu_swa(0, regs, isr);
- if (!status)
- return;
- else if (IA64_RETRY == status) {
- vcpu_decrement_iip(vcpu);
- return;
- }
- }
- }
+ status = handle_fpu_swa(0, regs, isr);
+ if (!status)
+ return;
+ else if (IA64_RETRY == status) {
+ vcpu_decrement_iip(vcpu);
+ return;
+ }
+ break;
+
+ }
VCPU(vcpu,isr)=isr;
VCPU(vcpu,iipa) = regs->cr_iip;
if (vector == IA64_BREAK_VECTOR || vector == IA64_SPECULATION_VECTOR)
@@ -194,7 +214,7 @@ void save_banked_regs_to_vpd(VCPU *v, RE
// ONLY gets called from ia64_leave_kernel
// ONLY call with interrupts disabled?? (else might miss one?)
// NEVER successful if already reflecting a trap/fault because psr.i==0
-void leave_hypervisor_tail(struct pt_regs *regs)
+void leave_hypervisor_tail(void)
{
struct domain *d = current->domain;
struct vcpu *v = current;
@@ -207,17 +227,23 @@ void leave_hypervisor_tail(struct pt_reg
local_irq_disable();
if (v->vcpu_id == 0) {
- int callback_irq =
+ unsigned long callback_irq =
d->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ];
+ /*
+ * val[63:56] == 1: val[55:0] is a delivery PCI INTx line:
+ * Domain = val[47:32], Bus = val[31:16],
+ * DevFn = val[15: 8], IntX = val[ 1: 0]
+ * val[63:56] == 0: val[55:0] is a delivery as GSI
+ */
if (callback_irq != 0 && local_events_need_delivery()) {
/* change level for para-device callback irq */
/* use level irq to send discrete event */
- if (callback_irq & IA64_CALLBACK_IRQ_RID) {
- /* case of using Requester-ID as callback irq */
- /* RID: '<#bus(8)><#dev(5)><#func(3)>' */
- int dev = (callback_irq >> 3) & 0x1f;
- viosapic_set_pci_irq(d, dev, 0, 1);
- viosapic_set_pci_irq(d, dev, 0, 0);
+ if ((uint8_t)(callback_irq >> 56) == 1) {
+ /* case of using PCI INTx line as callback irq */
+ int pdev = (callback_irq >> 11) & 0x1f;
+ int pintx = callback_irq & 3;
+ viosapic_set_pci_irq(d, pdev, pintx, 1);
+ viosapic_set_pci_irq(d, pdev, pintx, 0);
} else {
/* case of using GSI as callback irq */
viosapic_set_irq(d, callback_irq, 1);
@@ -367,7 +393,7 @@ vmx_hpw_miss(u64 vadr , u64 vec, REGS* r
if (!vpsr.ic)
misr.ni = 1;
- if(!vhpt_enabled(v, vadr, misr.rs?RSE_REF:DATA_REF)){
+ if (!vhpt_enabled(v, vadr, INST_REF)) {
vcpu_set_isr(v, misr.val);
alt_itlb(v, vadr);
return IA64_FAULT;
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/vmx/vmx_vcpu.c
--- a/xen/arch/ia64/vmx/vmx_vcpu.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/vmx/vmx_vcpu.c Wed Feb 14 19:01:35 2007 +0000
@@ -78,6 +78,22 @@ unsigned long guest_psr_index = 0;
unsigned long guest_psr_index = 0;
#endif
+
+void
+vmx_ia64_set_dcr(VCPU *v)
+{
+ unsigned long dcr_bits = IA64_DEFAULT_DCR_BITS;
+
+ // if guest is runing on cpl > 0, set dcr.dm=1
+ // if geust is runing on cpl = 0, set dcr.dm=0
+ // because Guest OS may ld.s on tr mapped page.
+ if (!(VCPU(v, vpsr) & IA64_PSR_CPL))
+ dcr_bits &= ~IA64_DCR_DM;
+
+ ia64_set_dcr(dcr_bits);
+}
+
+
void
vmx_vcpu_set_psr(VCPU *vcpu, unsigned long value)
{
@@ -140,6 +156,9 @@ vmx_vcpu_set_psr(VCPU *vcpu, unsigned lo
IA64_PSR_VM;
regs->cr_ipsr = (regs->cr_ipsr & mask ) | ( value & (~mask) );
+
+ if (FP_PSR(vcpu) & IA64_PSR_DFH)
+ regs->cr_ipsr |= IA64_PSR_DFH;
check_mm_mode_switch(vcpu, old_psr, new_psr);
return ;
@@ -258,6 +277,7 @@ IA64FAULT vmx_vcpu_rfi(VCPU *vcpu)
else
vcpu_bsw0(vcpu);
vmx_vcpu_set_psr(vcpu,psr);
+ vmx_ia64_set_dcr(vcpu);
ifs=VCPU(vcpu,ifs);
if(ifs>>63)
regs->cr_ifs = ifs;
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/vmx/vmx_virt.c
--- a/xen/arch/ia64/vmx/vmx_virt.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/vmx/vmx_virt.c Wed Feb 14 19:01:35 2007 +0000
@@ -1234,7 +1234,7 @@ IA64FAULT vmx_emul_mov_to_cr(VCPU *vcpu,
#endif //CHECK_FAULT
r2 = cr_igfld_mask(inst.M32.cr3,r2);
switch (inst.M32.cr3) {
- case 0: return vmx_vcpu_set_dcr(vcpu,r2);
+ case 0: return vcpu_set_dcr(vcpu,r2);
case 1: return vmx_vcpu_set_itm(vcpu,r2);
case 2: return vmx_vcpu_set_iva(vcpu,r2);
case 8: return vmx_vcpu_set_pta(vcpu,r2);
@@ -1299,7 +1299,7 @@ IA64FAULT vmx_emul_mov_from_cr(VCPU *vcp
// from_cr_cnt[inst.M33.cr3]++;
switch (inst.M33.cr3) {
- case 0: return vmx_cr_get(dcr);
+ case 0: return cr_get(dcr);
case 1: return vmx_cr_get(itm);
case 2: return vmx_cr_get(iva);
case 8: return vmx_cr_get(pta);
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/vmx/vtlb.c
--- a/xen/arch/ia64/vmx/vtlb.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/vmx/vtlb.c Wed Feb 14 19:01:35 2007 +0000
@@ -248,6 +248,7 @@ u64 guest_vhpt_lookup(u64 iha, u64 *pte)
"tnat.nz p6,p7=r9;;"
"(p6) mov %0=1;"
"(p6) mov r9=r0;"
+ "(p7) extr.u r9=r9,0,53;;"
"(p7) mov %0=r0;"
"(p7) st8 [%2]=r9;;"
"ssm psr.ic;;"
@@ -261,7 +262,7 @@ u64 guest_vhpt_lookup(u64 iha, u64 *pte)
* purge software guest tlb
*/
-void vtlb_purge(VCPU *v, u64 va, u64 ps)
+static void vtlb_purge(VCPU *v, u64 va, u64 ps)
{
thash_data_t *cur;
u64 start, curadr, size, psbits, tag, rr_ps, num;
@@ -442,6 +443,15 @@ void thash_purge_entries(VCPU *v, u64 va
vhpt_purge(v, va, ps);
}
+void thash_purge_entries_remote(VCPU *v, u64 va, u64 ps)
+{
+ u64 old_va = va;
+ va = REGION_OFFSET(va);
+ if (vcpu_quick_region_check(v->arch.tc_regions, old_va))
+ vtlb_purge(v, va, ps);
+ vhpt_purge(v, va, ps);
+}
+
u64 translate_phy_pte(VCPU *v, u64 *pte, u64 itir, u64 va)
{
u64 ps, ps_mask, paddr, maddr;
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/xen/dom_fw.c
--- a/xen/arch/ia64/xen/dom_fw.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/xen/dom_fw.c Wed Feb 14 19:01:35 2007 +0000
@@ -599,7 +599,17 @@ complete_dom0_memmap(struct domain *d,
case EFI_UNUSABLE_MEMORY:
case EFI_PAL_CODE:
- /* Discard. */
+ /*
+ * We don't really need these, but holes in the
+ * memory map may cause Linux to assume there are
+ * uncacheable ranges within a granule.
+ */
+ dom_md->type = EFI_UNUSABLE_MEMORY;
+ dom_md->phys_addr = start;
+ dom_md->virt_addr = 0;
+ dom_md->num_pages = (end - start) >> EFI_PAGE_SHIFT;
+ dom_md->attribute = EFI_MEMORY_WB;
+ num_mds++;
break;
default:
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/xen/domain.c Wed Feb 14 19:01:35 2007 +0000
@@ -42,6 +42,7 @@
#include <asm/vmx_vpd.h>
#include <asm/vmx_phy_mode.h>
#include <asm/vhpt.h>
+#include <asm/vcpu.h>
#include <asm/tlbflush.h>
#include <asm/regionreg.h>
#include <asm/dom_fw.h>
@@ -67,6 +68,8 @@ static void init_switch_stack(struct vcp
This is a Xen virtual address. */
DEFINE_PER_CPU(uint8_t *, current_psr_i_addr);
DEFINE_PER_CPU(int *, current_psr_ic_addr);
+
+DEFINE_PER_CPU(struct vcpu *, fp_owner);
#include <xen/sched-if.h>
@@ -135,12 +138,44 @@ static void flush_vtlb_for_context_switc
}
}
+static void lazy_fp_switch(struct vcpu *prev, struct vcpu *next)
+{
+ /*
+ * Implement eager save, lazy restore
+ */
+ if (!is_idle_vcpu(prev)) {
+ if (VMX_DOMAIN(prev)) {
+ if (FP_PSR(prev) & IA64_PSR_MFH) {
+ __ia64_save_fpu(prev->arch._thread.fph);
+ __ia64_per_cpu_var(fp_owner) = prev;
+ }
+ } else {
+ if (PSCB(prev, hpsr_mfh)) {
+ __ia64_save_fpu(prev->arch._thread.fph);
+ __ia64_per_cpu_var(fp_owner) = prev;
+ }
+ }
+ }
+
+ if (!is_idle_vcpu(next)) {
+ if (VMX_DOMAIN(next)) {
+ FP_PSR(next) = IA64_PSR_DFH;
+ vcpu_regs(next)->cr_ipsr |= IA64_PSR_DFH;
+ } else {
+ PSCB(next, hpsr_dfh) = 1;
+ PSCB(next, hpsr_mfh) = 0;
+ vcpu_regs(next)->cr_ipsr |= IA64_PSR_DFH;
+ }
+ }
+}
+
void schedule_tail(struct vcpu *prev)
{
extern char ia64_ivt;
+
context_saved(prev);
-
ia64_disable_vhpt_walker();
+
if (VMX_DOMAIN(current)) {
vmx_do_launch(current);
migrate_timer(¤t->arch.arch_vmx.vtm.vtm_timer,
@@ -148,7 +183,7 @@ void schedule_tail(struct vcpu *prev)
} else {
ia64_set_iva(&ia64_ivt);
load_region_regs(current);
- ia64_set_pta(vcpu_pta(current));
+ ia64_set_pta(vcpu_pta(current));
vcpu_load_kernel_regs(current);
__ia64_per_cpu_var(current_psr_i_addr) = ¤t->domain->
shared_info->vcpu_info[current->vcpu_id].evtchn_upcall_mask;
@@ -165,64 +200,65 @@ void context_switch(struct vcpu *prev, s
local_irq_save(spsr);
- if (!is_idle_domain(prev->domain))
- __ia64_save_fpu(prev->arch._thread.fph);
- if (!is_idle_domain(next->domain))
- __ia64_load_fpu(next->arch._thread.fph);
-
if (VMX_DOMAIN(prev)) {
- vmx_save_state(prev);
- if (!VMX_DOMAIN(next)) {
- /* VMX domains can change the physical cr.dcr.
- * Restore default to prevent leakage. */
- ia64_setreg(_IA64_REG_CR_DCR, (IA64_DCR_DP | IA64_DCR_DK
- | IA64_DCR_DX | IA64_DCR_DR | IA64_DCR_PP
- | IA64_DCR_DA | IA64_DCR_DD | IA64_DCR_LC));
- }
+ vmx_save_state(prev);
+ if (!VMX_DOMAIN(next)) {
+ /* VMX domains can change the physical cr.dcr.
+ * Restore default to prevent leakage. */
+ ia64_setreg(_IA64_REG_CR_DCR, IA64_DEFAULT_DCR_BITS);
+ }
}
if (VMX_DOMAIN(next))
- vmx_load_state(next);
+ vmx_load_state(next);
ia64_disable_vhpt_walker();
- /*ia64_psr(ia64_task_regs(next))->dfh = !ia64_is_local_fpu_owner(next);*/
+ lazy_fp_switch(prev, current);
+
prev = ia64_switch_to(next);
/* Note: ia64_switch_to does not return here at vcpu initialization. */
- //cpu_set(smp_processor_id(), current->domain->domain_dirty_cpumask);
-
- if (VMX_DOMAIN(current)){
- vmx_load_all_rr(current);
- migrate_timer(¤t->arch.arch_vmx.vtm.vtm_timer,
- current->processor);
+ if (VMX_DOMAIN(current)) {
+ vmx_load_all_rr(current);
+ migrate_timer(¤t->arch.arch_vmx.vtm.vtm_timer,
+ current->processor);
} else {
- struct domain *nd;
- extern char ia64_ivt;
-
- ia64_set_iva(&ia64_ivt);
-
- nd = current->domain;
- if (!is_idle_domain(nd)) {
- load_region_regs(current);
- ia64_set_pta(vcpu_pta(current));
- vcpu_load_kernel_regs(current);
- vcpu_set_next_timer(current);
- if (vcpu_timer_expired(current))
- vcpu_pend_timer(current);
- __ia64_per_cpu_var(current_psr_i_addr) = &nd->shared_info->
- vcpu_info[current->vcpu_id].evtchn_upcall_mask;
- __ia64_per_cpu_var(current_psr_ic_addr) =
- (int *)(nd->arch.shared_info_va + XSI_PSR_IC_OFS);
- } else {
- /* When switching to idle domain, only need to disable vhpt
- * walker. Then all accesses happen within idle context will
- * be handled by TR mapping and identity mapping.
- */
- __ia64_per_cpu_var(current_psr_i_addr) = NULL;
- __ia64_per_cpu_var(current_psr_ic_addr) = NULL;
+ struct domain *nd;
+ extern char ia64_ivt;
+
+ ia64_set_iva(&ia64_ivt);
+
+ nd = current->domain;
+ if (!is_idle_domain(nd)) {
+ load_region_regs(current);
+ ia64_set_pta(vcpu_pta(current));
+ vcpu_load_kernel_regs(current);
+ vcpu_set_next_timer(current);
+ if (vcpu_timer_expired(current))
+ vcpu_pend_timer(current);
+ __ia64_per_cpu_var(current_psr_i_addr) = &nd->shared_info->
+ vcpu_info[current->vcpu_id].evtchn_upcall_mask;
+ __ia64_per_cpu_var(current_psr_ic_addr) =
+ (int *)(nd->arch.shared_info_va + XSI_PSR_IC_OFS);
+ } else {
+ /* When switching to idle domain, only need to disable vhpt
+ * walker. Then all accesses happen within idle context will
+ * be handled by TR mapping and identity mapping.
+ */
+ __ia64_per_cpu_var(current_psr_i_addr) = NULL;
+ __ia64_per_cpu_var(current_psr_ic_addr) = NULL;
}
}
local_irq_restore(spsr);
+
+ /* lazy fp */
+ if (current->processor != current->arch.last_processor) {
+ unsigned long *addr;
+ addr = (unsigned long *)per_cpu_addr(fp_owner,
+ current->arch.last_processor);
+ ia64_cmpxchg(acq, addr, current, 0, 8);
+ }
+
flush_vtlb_for_context_switch(prev, current);
context_saved(prev);
}
@@ -411,9 +447,6 @@ int vcpu_late_initialise(struct vcpu *v)
assign_domain_page(d, IA64_XMAPPEDREGS_PADDR(v->vcpu_id) + i,
virt_to_maddr(v->arch.privregs + i));
- tlbflush_update_time(&v->arch.tlbflush_timestamp,
- tlbflush_current_time());
-
return 0;
}
@@ -519,6 +552,12 @@ void arch_domain_destroy(struct domain *
deallocate_rid_range(d);
}
+int arch_vcpu_reset(struct vcpu *v)
+{
+ /* FIXME: Stub for now */
+ return 0;
+}
+
void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
{
int i;
@@ -542,7 +581,7 @@ void arch_get_info_guest(struct vcpu *v,
er->dtrs[i].rid = v->arch.dtrs[i].rid;
}
er->event_callback_ip = v->arch.event_callback_ip;
- er->dcr = v->arch.dcr;
+ er->dcr = PSCB(v,dcr);
er->iva = v->arch.iva;
}
@@ -578,16 +617,18 @@ int arch_set_info_guest(struct vcpu *v,
er->dtrs[i].rid);
}
v->arch.event_callback_ip = er->event_callback_ip;
- v->arch.dcr = er->dcr;
+ PSCB(v,dcr) = er->dcr;
v->arch.iva = er->iva;
}
if (test_bit(_VCPUF_initialised, &v->vcpu_flags))
return 0;
- if (d->arch.is_vti)
- vmx_final_setup_guest(v);
- else {
+ if (d->arch.is_vti) {
+ rc = vmx_final_setup_guest(v);
+ if (rc != 0)
+ return rc;
+ } else {
rc = vcpu_late_initialise(v);
if (rc != 0)
return rc;
@@ -982,12 +1023,6 @@ int construct_dom0(struct domain *d,
unsigned long bp_mpa;
struct ia64_boot_param *bp;
-#ifdef VALIDATE_VT
- unsigned int vmx_dom0 = 0;
- unsigned long mfn;
- struct page_info *page = NULL;
-#endif
-
//printk("construct_dom0: starting\n");
/* Sanity! */
@@ -1020,23 +1055,6 @@ int construct_dom0(struct domain *d,
printk("Incompatible kernel binary\n");
return -1;
}
-
-#ifdef VALIDATE_VT
- /* Temp workaround */
- if (running_on_sim)
- dsi.xen_section_string = (char *)1;
-
- /* Check whether dom0 is vti domain */
- if ((!vmx_enabled) && !dsi.xen_section_string) {
- printk("Lack of hardware support for unmodified vmx dom0\n");
- panic("");
- }
-
- if (vmx_enabled && !dsi.xen_section_string) {
- printk("Dom0 is vmx domain!\n");
- vmx_dom0 = 1;
- }
-#endif
p_start = parms.virt_base;
pkern_start = parms.virt_kstart;
@@ -1131,14 +1149,6 @@ int construct_dom0(struct domain *d,
printk("Dom0: 0x%lx\n", (u64)dom0);
-#ifdef VALIDATE_VT
- /* VMX specific construction for Dom0, if hardware supports VMX
- * and Dom0 is unmodified image
- */
- if (vmx_dom0)
- vmx_final_setup_guest(v);
-#endif
-
set_bit(_VCPUF_initialised, &v->vcpu_flags);
/* Build firmware.
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/xen/faults.c
--- a/xen/arch/ia64/xen/faults.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/xen/faults.c Wed Feb 14 19:01:35 2007 +0000
@@ -92,6 +92,9 @@ void reflect_interruption(unsigned long
regs->cr_iip = ((unsigned long)PSCBX(v, iva) + vector) & ~0xffUL;
regs->cr_ipsr = (regs->cr_ipsr & ~DELIVER_PSR_CLR) | DELIVER_PSR_SET;
+ if (PSCB(v, hpsr_dfh))
+ regs->cr_ipsr |= IA64_PSR_DFH;
+ PSCB(v, vpsr_dfh) = 0;
v->vcpu_info->evtchn_upcall_mask = 1;
PSCB(v, interrupt_collection_enabled) = 0;
@@ -152,6 +155,9 @@ void reflect_event(void)
regs->cr_iip = v->arch.event_callback_ip;
regs->cr_ipsr = (regs->cr_ipsr & ~DELIVER_PSR_CLR) | DELIVER_PSR_SET;
+ if (PSCB(v, hpsr_dfh))
+ regs->cr_ipsr |= IA64_PSR_DFH;
+ PSCB(v, vpsr_dfh) = 0;
v->vcpu_info->evtchn_upcall_mask = 1;
PSCB(v, interrupt_collection_enabled) = 0;
}
@@ -261,6 +267,10 @@ void ia64_do_page_fault(unsigned long ad
((unsigned long)PSCBX(current, iva) + fault) & ~0xffUL;
regs->cr_ipsr =
(regs->cr_ipsr & ~DELIVER_PSR_CLR) | DELIVER_PSR_SET;
+
+ if (PSCB(current, hpsr_dfh))
+ regs->cr_ipsr |= IA64_PSR_DFH;
+ PSCB(current, vpsr_dfh) = 0;
perfc_incra(slow_reflect, fault >> 8);
return;
}
@@ -608,6 +618,16 @@ ia64_handle_reflection(unsigned long ifa
vector = IA64_GENEX_VECTOR;
break;
case 25:
+ if (PSCB(v, hpsr_dfh)) {
+ PSCB(v, hpsr_dfh) = 0;
+ PSCB(v, hpsr_mfh) = 1;
+ if (__ia64_per_cpu_var(fp_owner) != v)
+ __ia64_load_fpu(v->arch._thread.fph);
+ }
+ if (!PSCB(v, vpsr_dfh)) {
+ regs->cr_ipsr &= ~IA64_PSR_DFH;
+ return;
+ }
vector = IA64_DISABLED_FPREG_VECTOR;
break;
case 26:
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/xen/flushtlb.c
--- a/xen/arch/ia64/xen/flushtlb.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/xen/flushtlb.c Wed Feb 14 19:01:35 2007 +0000
@@ -59,44 +59,18 @@ tlbflush_clock_inc_and_return(void)
return t2;
}
+static void
+tlbflush_clock_local_flush(void *unused)
+{
+ local_vhpt_flush();
+ local_flush_tlb_all();
+}
+
void
new_tlbflush_clock_period(void)
{
- /*
- *XXX TODO
- * If flushing all vcpu's vhpt takes too long, it can be done backgroundly.
- * In such case tlbflush time comparison is done using only 31bit
- * similar to linux jiffies comparison.
- * vhpt should be flushed gradually before wraping 31bits.
- *
- * Sample calculation.
- * Currently Xen/IA64 can create up to 64 domains at the same time.
- * Vhpt size is currently 64KB. (This might be changed later though)
- * Suppose each domains have 4 vcpus (or 16 vcpus).
- * then the memory size which must be flushed is 16MB (64MB).
- */
- struct domain* d;
- struct vcpu* v;
- /* flush all vhpt of vcpu of all existing domain. */
- read_lock(&domlist_lock);
- for_each_domain(d) {
- for_each_vcpu(d, v) {
- vcpu_purge_tr_entry(&PSCBX(v,dtlb));
- vcpu_purge_tr_entry(&PSCBX(v,itlb));
- }
- }
- smp_mb();
- for_each_domain(d) {
- for_each_vcpu(d, v) {
- if (HAS_PERVCPU_VHPT(v->domain))
- vcpu_vhpt_flush(v);
- }
- }
- read_unlock(&domlist_lock);
- /* unlock has release semantics */
-
/* flush all vhpt of physical cpu and mTLB */
- on_each_cpu((void (*)(void *))local_flush_tlb_all, NULL, 1, 1);
+ on_each_cpu(tlbflush_clock_local_flush, NULL, 1, 1);
/*
* if global TLB shootdown is finished, increment tlbflush_time
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/xen/fw_emul.c
--- a/xen/arch/ia64/xen/fw_emul.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/xen/fw_emul.c Wed Feb 14 19:01:35 2007 +0000
@@ -605,9 +605,11 @@ xen_pal_emulator(unsigned long index, u6
printk ("Domain0 halts the machine\n");
console_start_sync();
(*efi.reset_system)(EFI_RESET_SHUTDOWN,0,0,NULL);
- }
- else
- domain_shutdown(current->domain, SHUTDOWN_poweroff);
+ } else {
+ set_bit(_VCPUF_down, ¤t->vcpu_flags);
+ vcpu_sleep_nosync(current);
+ status = PAL_STATUS_SUCCESS;
+ }
break;
case PAL_HALT_LIGHT:
if (VMX_DOMAIN(current)) {
@@ -622,6 +624,9 @@ xen_pal_emulator(unsigned long index, u6
case PAL_PLATFORM_ADDR:
if (VMX_DOMAIN(current))
status = PAL_STATUS_SUCCESS;
+ break;
+ case PAL_LOGICAL_TO_PHYSICAL:
+ /* Optional, no need to complain about being unimplemented */
break;
default:
printk("xen_pal_emulator: UNIMPLEMENTED PAL CALL %lu!!!!\n",
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/xen/hyperprivop.S
--- a/xen/arch/ia64/xen/hyperprivop.S Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/xen/hyperprivop.S Wed Feb 14 19:01:35 2007 +0000
@@ -252,6 +252,10 @@ ENTRY(hyper_ssm_i)
movl r27=~DELIVER_PSR_CLR;;
or r29=r29,r28;;
and r29=r29,r27;;
+ // set hpsr_dfh to ipsr
+ adds r28=XSI_HPSR_DFH_OFS-XSI_PSR_IC_OFS,r18;;
+ ld1 r28=[r28];;
+ dep r29=r28,r29,IA64_PSR_DFH_BIT,1;;
mov cr.ipsr=r29;;
// set shared_mem ipsr (from ipsr in r30 with ipsr.ri already set)
extr.u r29=r30,IA64_PSR_CPL0_BIT,2;;
@@ -269,6 +273,12 @@ ENTRY(hyper_ssm_i)
movl r22=THIS_CPU(current_psr_i_addr)
adds r21=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18 ;;
ld8 r22=[r22]
+ ;;
+ adds r27=XSI_VPSR_DFH_OFS-XSI_PSR_IC_OFS,r18;;
+ ld1 r28=[r27];;
+ st1 [r27]=r0
+ dep r30=r28,r30,IA64_PSR_DFH_BIT,1
+ ;;
st8 [r21]=r30;;
// set shared_mem interrupt_delivery_enabled to 0
// set shared_mem interrupt_collection_enabled to 0
@@ -607,6 +617,10 @@ ENTRY(fast_reflect)
movl r27=~(DELIVER_PSR_CLR|IA64_PSR_CPL0);;
or r29=r29,r28;;
and r29=r29,r27;;
+ // set hpsr_dfh to ipsr
+ adds r28=XSI_HPSR_DFH_OFS-XSI_PSR_IC_OFS,r18;;
+ ld1 r28=[r28];;
+ dep r29=r28,r29,IA64_PSR_DFH_BIT,1;;
mov cr.ipsr=r29;;
// set shared_mem ipsr (from ipsr in r30 with ipsr.ri already set)
extr.u r29=r30,IA64_PSR_CPL0_BIT,2;;
@@ -629,7 +643,13 @@ ENTRY(fast_reflect)
(p6) dep r30=0,r30,IA64_PSR_I_BIT,1
(p7) dep r30=-1,r30,IA64_PSR_I_BIT,1 ;;
mov r22=1
- adds r21=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18 ;;
+ adds r21=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18
+ ;;
+ adds r27=XSI_VPSR_DFH_OFS-XSI_PSR_IC_OFS,r18;;
+ ld1 r28=[r27];;
+ st1 [r27]=r0
+ dep r30=r28,r30,IA64_PSR_DFH_BIT,1
+ ;;
st8 [r21]=r30 ;;
// set shared_mem interrupt_delivery_enabled to 0
// set shared_mem interrupt_collection_enabled to 0
@@ -1103,6 +1123,18 @@ just_do_rfi:
IA64_PSR_IT|IA64_PSR_BN)
;;
or r21=r21,r20
+ ;;
+ adds r20=XSI_VPSR_DFH_OFS-XSI_PSR_IC_OFS,r18;;
+ tbit.z p8,p9 = r21, IA64_PSR_DFH_BIT
+ ;;
+ (p9) mov r27=1;;
+ (p9) st1 [r20]=r27
+ ;;
+ (p8) st1 [r20]=r0
+ (p8) adds r20=XSI_HPSR_DFH_OFS-XSI_PSR_IC_OFS,r18;;
+ (p8) ld1 r27=[r20]
+ ;;
+ (p8) dep r21=r27,r21, IA64_PSR_DFH_BIT, 1
;;
mov cr.ipsr=r21
adds r20=XSI_BANKNUM_OFS-XSI_PSR_IC_OFS,r18 ;;
@@ -1488,6 +1520,11 @@ ENTRY(hyper_get_psr)
ld8 r20=[r20];;
ld1 r21=[r20];;
dep r8=r21,r8,IA64_PSR_I_BIT,1
+ ;;
+ // set vpsr.dfh
+ adds r20=XSI_VPSR_DFH_OFS-XSI_PSR_IC_OFS,r18;;
+ ld1 r21=[r20];;
+ dep r8=r21,r8,IA64_PSR_DFH_BIT,1
;;
mov r25=cr.iip
extr.u r26=r24,41,2 ;;
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/xen/mm.c
--- a/xen/arch/ia64/xen/mm.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/xen/mm.c Wed Feb 14 19:01:35 2007 +0000
@@ -525,7 +525,9 @@ u64 translate_domain_pte(u64 pteval, u64
This can happen when domU tries to touch i/o
port space. Also prevents possible address
aliasing issues. */
- printk("Warning: UC to WB for mpaddr=%lx\n", mpaddr);
+ if (!(mpaddr - IO_PORTS_PADDR < IO_PORTS_SIZE))
+ gdprintk(XENLOG_WARNING, "Warning: UC to WB "
+ "for mpaddr=%lx\n", mpaddr);
pteval = (pteval & ~_PAGE_MA_MASK) | _PAGE_MA_WB;
}
break;
@@ -690,7 +692,6 @@ unsigned long lookup_domain_mpa(struct d
if (pte != NULL) {
pte_t tmp_pte = *pte;// pte is volatile. copy the value.
if (pte_present(tmp_pte)) {
-//printk("lookup_domain_page: found mapping for %lx,
pte=%lx\n",mpaddr,pte_val(*pte));
if (entry != NULL)
p2m_entry_set(entry, pte, tmp_pte);
return pte_val(tmp_pte);
@@ -698,14 +699,20 @@ unsigned long lookup_domain_mpa(struct d
return GPFN_INV_MASK;
}
- printk("%s: d 0x%p id %d current 0x%p id %d\n",
- __func__, d, d->domain_id, current, current->vcpu_id);
- if (mpaddr < d->arch.convmem_end)
- printk("%s: non-allocated mpa 0x%lx (< 0x%lx)\n", __func__,
- mpaddr, d->arch.convmem_end);
- else
- printk("%s: bad mpa 0x%lx (=> 0x%lx)\n", __func__,
- mpaddr, d->arch.convmem_end);
+ if (mpaddr < d->arch.convmem_end) {
+ gdprintk(XENLOG_WARNING, "vcpu %d iip 0x%016lx: non-allocated mpa "
+ "0x%lx (< 0x%lx)\n", current->vcpu_id, PSCB(current, iip),
+ mpaddr, d->arch.convmem_end);
+ } else if (mpaddr - IO_PORTS_PADDR < IO_PORTS_SIZE) {
+ /* Log I/O port probing, but complain less loudly about it */
+ gdprintk(XENLOG_INFO, "vcpu %d iip 0x%016lx: bad I/O port access "
+ "0x%lx\n ", current->vcpu_id, PSCB(current, iip),
+ IO_SPACE_SPARSE_DECODING(mpaddr - IO_PORTS_PADDR));
+ } else {
+ gdprintk(XENLOG_WARNING, "vcpu %d iip 0x%016lx: bad mpa 0x%lx "
+ "(=> 0x%lx)\n", current->vcpu_id, PSCB(current, iip),
+ mpaddr, d->arch.convmem_end);
+ }
if (entry != NULL)
p2m_entry_set(entry, NULL, __pte(0));
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/xen/vcpu.c
--- a/xen/arch/ia64/xen/vcpu.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/xen/vcpu.c Wed Feb 14 19:01:35 2007 +0000
@@ -141,6 +141,9 @@ void vcpu_init_regs(struct vcpu *v)
/* dt/rt/it:1;i/ic:1, si:1, vm/bn:1, ac:1 */
/* Need to be expanded as macro */
regs->cr_ipsr = 0x501008826008;
+ /* lazy fp */
+ FP_PSR(v) = IA64_PSR_DFH;
+ regs->cr_ipsr |= IA64_PSR_DFH;
} else {
regs->cr_ipsr = ia64_getreg(_IA64_REG_PSR)
| IA64_PSR_BITS_TO_SET | IA64_PSR_BN;
@@ -148,6 +151,10 @@ void vcpu_init_regs(struct vcpu *v)
| IA64_PSR_RI | IA64_PSR_IS);
// domain runs at PL2
regs->cr_ipsr |= 2UL << IA64_PSR_CPL0_BIT;
+ // lazy fp
+ PSCB(v, hpsr_dfh) = 1;
+ PSCB(v, hpsr_mfh) = 0;
+ regs->cr_ipsr |= IA64_PSR_DFH;
}
regs->cr_ifs = 1UL << 63; /* or clear? */
regs->ar_fpsr = FPSR_DEFAULT;
@@ -265,8 +272,10 @@ IA64FAULT vcpu_reset_psr_sm(VCPU * vcpu,
IA64_PSR_I | IA64_PSR_IC | IA64_PSR_DT |
IA64_PSR_DFL | IA64_PSR_DFH))
return IA64_ILLOP_FAULT;
- if (imm.dfh)
- ipsr->dfh = 0;
+ if (imm.dfh) {
+ ipsr->dfh = PSCB(vcpu, hpsr_dfh);
+ PSCB(vcpu, vpsr_dfh) = 0;
+ }
if (imm.dfl)
ipsr->dfl = 0;
if (imm.pp) {
@@ -320,8 +329,10 @@ IA64FAULT vcpu_set_psr_sm(VCPU * vcpu, u
IA64_PSR_DT | IA64_PSR_DFL | IA64_PSR_DFH;
if (imm24 & ~mask)
return IA64_ILLOP_FAULT;
- if (imm.dfh)
+ if (imm.dfh) {
+ PSCB(vcpu, vpsr_dfh) = 1;
ipsr->dfh = 1;
+ }
if (imm.dfl)
ipsr->dfl = 1;
if (imm.pp) {
@@ -386,8 +397,13 @@ IA64FAULT vcpu_set_psr_l(VCPU * vcpu, u6
//if (val & ~(IA64_PSR_PP | IA64_PSR_UP | IA64_PSR_SP))
// return IA64_ILLOP_FAULT;
// however trying to set other bits can't be an error as it is in ssm
- if (newpsr.dfh)
+ if (newpsr.dfh) {
ipsr->dfh = 1;
+ PSCB(vcpu, vpsr_dfh) = 1;
+ } else {
+ ipsr->dfh = PSCB(vcpu, hpsr_dfh);
+ PSCB(vcpu, vpsr_dfh) = 0;
+ }
if (newpsr.dfl)
ipsr->dfl = 1;
if (newpsr.pp) {
@@ -466,6 +482,8 @@ IA64FAULT vcpu_get_psr(VCPU * vcpu, u64
newpsr.pp = 1;
else
newpsr.pp = 0;
+ newpsr.dfh = PSCB(vcpu, vpsr_dfh);
+
*pval = *(unsigned long *)&newpsr;
*pval &= (MASK(0, 32) | MASK(35, 2));
return IA64_NO_FAULT;
@@ -483,7 +501,7 @@ BOOLEAN vcpu_get_psr_i(VCPU * vcpu)
u64 vcpu_get_ipsr_int_state(VCPU * vcpu, u64 prevpsr)
{
- u64 dcr = PSCBX(vcpu, dcr);
+ u64 dcr = PSCB(vcpu, dcr);
PSR psr;
//printk("*** vcpu_get_ipsr_int_state (0x%016lx)...\n",prevpsr);
@@ -497,6 +515,7 @@ u64 vcpu_get_ipsr_int_state(VCPU * vcpu,
psr.ia64_psr.ic = PSCB(vcpu, interrupt_collection_enabled);
psr.ia64_psr.i = !vcpu->vcpu_info->evtchn_upcall_mask;
psr.ia64_psr.bn = PSCB(vcpu, banknum);
+ psr.ia64_psr.dfh = PSCB(vcpu, vpsr_dfh);
psr.ia64_psr.dt = 1;
psr.ia64_psr.it = 1;
psr.ia64_psr.rt = 1;
@@ -513,10 +532,7 @@ u64 vcpu_get_ipsr_int_state(VCPU * vcpu,
IA64FAULT vcpu_get_dcr(VCPU * vcpu, u64 * pval)
{
-//verbose("vcpu_get_dcr: called @%p\n",PSCB(vcpu,iip));
- // Reads of cr.dcr on Xen always have the sign bit set, so
- // a domain can differentiate whether it is running on SP or not
- *pval = PSCBX(vcpu, dcr) | 0x8000000000000000L;
+ *pval = PSCB(vcpu, dcr);
return IA64_NO_FAULT;
}
@@ -632,11 +648,7 @@ IA64FAULT vcpu_get_iha(VCPU * vcpu, u64
IA64FAULT vcpu_set_dcr(VCPU * vcpu, u64 val)
{
- // Reads of cr.dcr on SP always have the sign bit set, so
- // a domain can differentiate whether it is running on SP or not
- // Thus, writes of DCR should ignore the sign bit
-//verbose("vcpu_set_dcr: called\n");
- PSCBX(vcpu, dcr) = val & ~0x8000000000000000L;
+ PSCB(vcpu, dcr) = val;
return IA64_NO_FAULT;
}
@@ -1343,6 +1355,12 @@ IA64FAULT vcpu_rfi(VCPU * vcpu)
if (psr.ia64_psr.cpl < 3)
psr.ia64_psr.cpl = 2;
int_enable = psr.ia64_psr.i;
+ if (psr.ia64_psr.dfh) {
+ PSCB(vcpu, vpsr_dfh) = 1;
+ } else {
+ psr.ia64_psr.dfh = PSCB(vcpu, hpsr_dfh);
+ PSCB(vcpu, vpsr_dfh) = 0;
+ }
if (psr.ia64_psr.ic)
PSCB(vcpu, interrupt_collection_enabled) = 1;
if (psr.ia64_psr.dt && psr.ia64_psr.rt && psr.ia64_psr.it)
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/xen/vhpt.c
--- a/xen/arch/ia64/xen/vhpt.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/xen/vhpt.c Wed Feb 14 19:01:35 2007 +0000
@@ -54,11 +54,7 @@ void
void
vcpu_vhpt_flush(struct vcpu* v)
{
- /* increment flush clock before flush */
- u32 flush_time = tlbflush_clock_inc_and_return();
__vhpt_flush(vcpu_vhpt_maddr(v));
- /* this must be after flush */
- tlbflush_update_time(&v->arch.tlbflush_timestamp, flush_time);
perfc_incrc(vcpu_vhpt_flush);
}
@@ -177,7 +173,9 @@ void
void
pervcpu_vhpt_free(struct vcpu *v)
{
- free_domheap_pages(v->arch.vhpt_page, VHPT_SIZE_LOG2 - PAGE_SHIFT);
+ if (likely(v->arch.vhpt_page != NULL))
+ free_domheap_pages(v->arch.vhpt_page,
+ VHPT_SIZE_LOG2 - PAGE_SHIFT);
}
#endif
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/ia64/xen/xensetup.c
--- a/xen/arch/ia64/xen/xensetup.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/ia64/xen/xensetup.c Wed Feb 14 19:01:35 2007 +0000
@@ -26,6 +26,8 @@
#include <asm/vmx.h>
#include <linux/efi.h>
#include <asm/iosapic.h>
+#include <xen/softirq.h>
+#include <xen/rcupdate.h>
unsigned long xenheap_phys_end, total_pages;
@@ -265,13 +267,16 @@ void start_kernel(void)
early_setup_arch(&cmdline);
/* We initialise the serial devices very early so we can get debugging. */
- if (running_on_sim) hpsim_serial_init();
+ if (running_on_sim)
+ hpsim_serial_init();
else {
- ns16550_init(0, &ns16550_com1);
- /* Also init com2 for Tiger4. */
- ns16550_com2.io_base = 0x2f8;
- ns16550_com2.irq = 3;
- ns16550_init(1, &ns16550_com2);
+ ns16550_init(0, &ns16550_com1);
+ if (ns16550_com1.io_base == 0x3f8) {
+ /* Also init com2 for Tiger4. */
+ ns16550_com2.io_base = 0x2f8;
+ ns16550_com2.irq = 3;
+ ns16550_init(1, &ns16550_com2);
+ }
}
serial_init_preirq();
@@ -436,6 +441,12 @@ void start_kernel(void)
init_xen_time(); /* initialise the time */
timer_init();
+ rcu_init();
+
+#ifdef CONFIG_XEN_IA64_TLBFLUSH_CLOCK
+ open_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, new_tlbflush_clock_period);
+#endif
+
#ifdef CONFIG_SMP
if ( opt_nosmp )
{
@@ -464,6 +475,7 @@ printk("num_online_cpus=%d, max_cpus=%d\
if ( num_online_cpus() >= max_cpus )
break;
if ( !cpu_online(i) ) {
+ rcu_online_cpu(i);
__cpu_up(i);
}
}
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/powerpc/machine_kexec.c
--- a/xen/arch/powerpc/machine_kexec.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/powerpc/machine_kexec.c Wed Feb 14 19:01:35 2007 +0000
@@ -19,6 +19,11 @@ void machine_reboot_kexec(xen_kexec_imag
printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
}
+void machine_kexec(xen_kexec_image_t *image)
+{
+ printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+}
+
/*
* Local variables:
* mode: C
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/crash.c
--- a/xen/arch/x86/crash.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/crash.c Wed Feb 14 19:01:35 2007 +0000
@@ -11,7 +11,6 @@
#include <asm/atomic.h>
#include <asm/elf.h>
#include <asm/percpu.h>
-#include <asm/kexec.h>
#include <xen/types.h>
#include <xen/irq.h>
#include <asm/ipi.h>
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/domain.c Wed Feb 14 19:01:35 2007 +0000
@@ -37,7 +37,7 @@
#include <asm/i387.h>
#include <asm/mpspec.h>
#include <asm/ldt.h>
-#include <asm/shadow.h>
+#include <asm/paging.h>
#include <asm/hvm/hvm.h>
#include <asm/hvm/support.h>
#include <asm/msr.h>
@@ -331,6 +331,7 @@ int vcpu_initialise(struct vcpu *v)
pae_l3_cache_init(&v->arch.pae_l3_cache);
+ paging_vcpu_init(v);
if ( is_hvm_domain(d) )
{
@@ -424,7 +425,7 @@ int arch_domain_create(struct domain *d)
HYPERVISOR_COMPAT_VIRT_START(d) = __HYPERVISOR_COMPAT_VIRT_START;
#endif
- shadow_domain_init(d);
+ paging_domain_init(d);
if ( !is_idle_domain(d) )
{
@@ -464,7 +465,7 @@ void arch_domain_destroy(struct domain *
hvm_domain_destroy(d);
}
- shadow_final_teardown(d);
+ paging_final_teardown(d);
free_xenheap_pages(
d->arch.mm_perdomain_pt,
@@ -613,7 +614,7 @@ int arch_set_info_guest(
{
cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c.nat->ctrlreg[3]));
- if ( shadow_mode_refcounts(d)
+ if ( paging_mode_refcounts(d)
? !get_page(mfn_to_page(cr3_pfn), d)
: !get_page_and_type(mfn_to_page(cr3_pfn), d,
PGT_base_page_table) )
@@ -631,7 +632,7 @@ int arch_set_info_guest(
cr3_pfn = gmfn_to_mfn(d, compat_cr3_to_pfn(c.cmp->ctrlreg[3]));
- if ( shadow_mode_refcounts(d)
+ if ( paging_mode_refcounts(d)
? !get_page(mfn_to_page(cr3_pfn), d)
: !get_page_and_type(mfn_to_page(cr3_pfn), d,
PGT_l3_page_table) )
@@ -652,8 +653,8 @@ int arch_set_info_guest(
/* Don't redo final setup */
set_bit(_VCPUF_initialised, &v->vcpu_flags);
- if ( shadow_mode_enabled(d) )
- shadow_update_paging_modes(v);
+ if ( paging_mode_enabled(d) )
+ paging_update_paging_modes(v);
update_cr3(v);
@@ -1406,7 +1407,7 @@ static void vcpu_destroy_pagetables(stru
if ( pfn != 0 )
{
- if ( shadow_mode_refcounts(d) )
+ if ( paging_mode_refcounts(d) )
put_page(mfn_to_page(pfn));
else
put_page_and_type(mfn_to_page(pfn));
@@ -1427,7 +1428,7 @@ static void vcpu_destroy_pagetables(stru
pfn = pagetable_get_pfn(v->arch.guest_table);
if ( pfn != 0 )
{
- if ( shadow_mode_refcounts(d) )
+ if ( paging_mode_refcounts(d) )
put_page(mfn_to_page(pfn));
else
put_page_and_type(mfn_to_page(pfn));
@@ -1443,7 +1444,7 @@ static void vcpu_destroy_pagetables(stru
pfn = pagetable_get_pfn(v->arch.guest_table_user);
if ( pfn != 0 )
{
- if ( shadow_mode_refcounts(d) )
+ if ( paging_mode_refcounts(d) )
put_page(mfn_to_page(pfn));
else
put_page_and_type(mfn_to_page(pfn));
@@ -1464,8 +1465,8 @@ void domain_relinquish_resources(struct
for_each_vcpu ( d, v )
vcpu_destroy_pagetables(v);
- /* Tear down shadow mode stuff. */
- shadow_teardown(d);
+ /* Tear down paging-assistance stuff. */
+ paging_teardown(d);
/*
* Relinquish GDT mappings. No need for explicit unmapping of the LDT as
@@ -1484,35 +1485,12 @@ void domain_relinquish_resources(struct
void arch_dump_domain_info(struct domain *d)
{
- if ( shadow_mode_enabled(d) )
- {
- printk(" shadow mode: ");
- if ( d->arch.shadow.mode & SHM2_enable )
- printk("enabled ");
- if ( shadow_mode_refcounts(d) )
- printk("refcounts ");
- if ( shadow_mode_log_dirty(d) )
- printk("log_dirty ");
- if ( shadow_mode_translate(d) )
- printk("translate ");
- if ( shadow_mode_external(d) )
- printk("external ");
- printk("\n");
- }
+ paging_dump_domain_info(d);
}
void arch_dump_vcpu_info(struct vcpu *v)
{
- if ( shadow_mode_enabled(v->domain) )
- {
- if ( v->arch.shadow.mode )
- printk(" shadowed %u-on-%u, %stranslated\n",
- v->arch.shadow.mode->guest_levels,
- v->arch.shadow.mode->shadow_levels,
- shadow_vcpu_mode_translate(v) ? "" : "not ");
- else
- printk(" not shadowed\n");
- }
+ paging_dump_vcpu_info(v);
}
/*
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/domain_build.c Wed Feb 14 19:01:35 2007 +0000
@@ -25,7 +25,7 @@
#include <asm/processor.h>
#include <asm/desc.h>
#include <asm/i387.h>
-#include <asm/shadow.h>
+#include <asm/paging.h>
#include <public/version.h>
#include <public/libelf.h>
@@ -777,8 +777,8 @@ int construct_dom0(struct domain *d,
(void)alloc_vcpu(d, i, i);
/* Set up CR3 value for write_ptbase */
- if ( shadow_mode_enabled(v->domain) )
- shadow_update_paging_modes(v);
+ if ( paging_mode_enabled(v->domain) )
+ paging_update_paging_modes(v);
else
update_cr3(v);
@@ -918,8 +918,8 @@ int construct_dom0(struct domain *d,
regs->eflags = X86_EFLAGS_IF;
if ( opt_dom0_shadow )
- if ( shadow_enable(d, SHM2_enable) == 0 )
- shadow_update_paging_modes(v);
+ if ( paging_enable(d, PG_SH_enable) == 0 )
+ paging_update_paging_modes(v);
if ( supervisor_mode_kernel )
{
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/domctl.c Wed Feb 14 19:01:35 2007 +0000
@@ -19,7 +19,7 @@
#include <xen/trace.h>
#include <xen/console.h>
#include <xen/iocap.h>
-#include <asm/shadow.h>
+#include <asm/paging.h>
#include <asm/irq.h>
#include <asm/hvm/hvm.h>
#include <asm/hvm/support.h>
@@ -42,7 +42,7 @@ long arch_do_domctl(
d = get_domain_by_id(domctl->domain);
if ( d != NULL )
{
- ret = shadow_domctl(d,
+ ret = paging_domctl(d,
&domctl->u.shadow_op,
guest_handle_cast(u_domctl, void));
put_domain(d);
@@ -326,10 +326,6 @@ long arch_do_domctl(
struct hvm_domain_context c;
struct domain *d;
- c.cur = 0;
- c.size = domctl->u.hvmcontext.size;
- c.data = NULL;
-
ret = -ESRCH;
if ( (d = get_domain_by_id(domctl->domain)) == NULL )
break;
@@ -338,19 +334,38 @@ long arch_do_domctl(
if ( !is_hvm_domain(d) )
goto gethvmcontext_out;
+ c.cur = 0;
+ c.size = hvm_save_size(d);
+ c.data = NULL;
+
+ if ( guest_handle_is_null(domctl->u.hvmcontext.buffer) )
+ {
+ /* Client is querying for the correct buffer size */
+ domctl->u.hvmcontext.size = c.size;
+ ret = 0;
+ goto gethvmcontext_out;
+ }
+
+ /* Check that the client has a big enough buffer */
+ ret = -ENOSPC;
+ if ( domctl->u.hvmcontext.size < c.size )
+ goto gethvmcontext_out;
+
+ /* Allocate our own marshalling buffer */
ret = -ENOMEM;
if ( (c.data = xmalloc_bytes(c.size)) == NULL )
goto gethvmcontext_out;
ret = hvm_save(d, &c);
+ domctl->u.hvmcontext.size = c.cur;
if ( copy_to_guest(domctl->u.hvmcontext.buffer, c.data, c.size) != 0 )
ret = -EFAULT;
+ gethvmcontext_out:
if ( copy_to_guest(u_domctl, domctl, 1) )
ret = -EFAULT;
- gethvmcontext_out:
if ( c.data != NULL )
xfree(c.data);
@@ -383,6 +398,7 @@ long arch_do_domctl(
put_domain(d);
}
+ break;
case XEN_DOMCTL_get_address_size:
{
@@ -396,7 +412,11 @@ long arch_do_domctl(
ret = 0;
put_domain(d);
- }
+
+ if ( copy_to_guest(u_domctl, domctl, 1) )
+ ret = -EFAULT;
+ }
+ break;
default:
ret = -ENOSYS;
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/hvm/Makefile
--- a/xen/arch/x86/hvm/Makefile Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/hvm/Makefile Wed Feb 14 19:01:35 2007 +0000
@@ -15,3 +15,4 @@ obj-y += vioapic.o
obj-y += vioapic.o
obj-y += vlapic.o
obj-y += vpic.o
+obj-y += save.o
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/hvm/hpet.c
--- a/xen/arch/x86/hvm/hpet.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/hvm/hpet.c Wed Feb 14 19:01:35 2007 +0000
@@ -409,7 +409,7 @@ static int hpet_load(struct domain *d, h
return 0;
}
-HVM_REGISTER_SAVE_RESTORE(HPET, hpet_save, hpet_load);
+HVM_REGISTER_SAVE_RESTORE(HPET, hpet_save, hpet_load, 1, HVMSR_PER_DOM);
void hpet_init(struct vcpu *v)
{
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/hvm/hvm.c Wed Feb 14 19:01:35 2007 +0000
@@ -30,11 +30,10 @@
#include <xen/hypercall.h>
#include <xen/guest_access.h>
#include <xen/event.h>
-#include <xen/shadow.h>
#include <asm/current.h>
#include <asm/e820.h>
#include <asm/io.h>
-#include <asm/shadow.h>
+#include <asm/paging.h>
#include <asm/regs.h>
#include <asm/cpufeature.h>
#include <asm/processor.h>
@@ -106,7 +105,6 @@ void hvm_migrate_timers(struct vcpu *v)
pit_migrate_timers(v);
rtc_migrate_timers(v);
hpet_migrate_timers(v);
- pmtimer_migrate_timers(v);
if ( vcpu_vlapic(v)->pt.enabled )
migrate_timer(&vcpu_vlapic(v)->pt.timer, v->processor);
}
@@ -156,7 +154,7 @@ int hvm_domain_initialise(struct domain
spin_lock_init(&d->arch.hvm_domain.buffered_io_lock);
spin_lock_init(&d->arch.hvm_domain.irq_lock);
- rc = shadow_enable(d, SHM2_refcounts|SHM2_translate|SHM2_external);
+ rc = paging_enable(d, PG_SH_enable|PG_refcounts|PG_translate|PG_external);
if ( rc != 0 )
return rc;
@@ -170,7 +168,6 @@ void hvm_domain_destroy(struct domain *d
{
pit_deinit(d);
rtc_deinit(d);
- pmtimer_deinit(d);
hpet_deinit(d);
if ( d->arch.hvm_domain.shared_page_va )
@@ -227,7 +224,8 @@ static int hvm_load_cpu_ctxt(struct doma
return 0;
}
-HVM_REGISTER_SAVE_RESTORE(CPU, hvm_save_cpu_ctxt, hvm_load_cpu_ctxt);
+HVM_REGISTER_SAVE_RESTORE(CPU, hvm_save_cpu_ctxt, hvm_load_cpu_ctxt,
+ 1, HVMSR_PER_VCPU);
int hvm_vcpu_initialise(struct vcpu *v)
{
@@ -271,6 +269,24 @@ void hvm_vcpu_destroy(struct vcpu *v)
/* Event channel is already freed by evtchn_destroy(). */
/*free_xen_event_channel(v, v->arch.hvm_vcpu.xen_port);*/
+}
+
+
+void hvm_vcpu_reset(struct vcpu *v)
+{
+ vcpu_pause(v);
+
+ vlapic_reset(vcpu_vlapic(v));
+
+ hvm_funcs.vcpu_initialise(v);
+
+ set_bit(_VCPUF_down, &v->vcpu_flags);
+ clear_bit(_VCPUF_initialised, &v->vcpu_flags);
+ clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
+ clear_bit(_VCPUF_fpu_dirtied, &v->vcpu_flags);
+ clear_bit(_VCPUF_blocked, &v->vcpu_flags);
+
+ vcpu_unpause(v);
}
static void hvm_vcpu_down(void)
@@ -366,7 +382,7 @@ static int __hvm_copy(void *buf, paddr_t
count = min_t(int, PAGE_SIZE - (addr & ~PAGE_MASK), todo);
if ( virt )
- mfn = get_mfn_from_gpfn(shadow_gva_to_gfn(current, addr));
+ mfn = get_mfn_from_gpfn(paging_gva_to_gfn(current, addr));
else
mfn = get_mfn_from_gpfn(addr >> PAGE_SHIFT);
@@ -583,7 +599,7 @@ void hvm_do_hypercall(struct cpu_user_re
return;
}
- if ( current->arch.shadow.mode->guest_levels == 4 )
+ if ( current->arch.paging.mode->guest_levels == 4 )
{
pregs->rax = hvm_hypercall64_table[pregs->rax](pregs->rdi,
pregs->rsi,
@@ -624,19 +640,12 @@ void hvm_hypercall_page_initialise(struc
*/
int hvm_bringup_ap(int vcpuid, int trampoline_vector)
{
- struct vcpu *bsp = current, *v;
- struct domain *d = bsp->domain;
+ struct vcpu *v;
+ struct domain *d = current->domain;
struct vcpu_guest_context *ctxt;
int rc = 0;
BUG_ON(!is_hvm_domain(d));
-
- if ( bsp->vcpu_id != 0 )
- {
- gdprintk(XENLOG_ERR, "Not calling hvm_bringup_ap from BSP context.\n");
- domain_crash(bsp->domain);
- return -EINVAL;
- }
if ( (v = d->vcpu[vcpuid]) == NULL )
return -ENOENT;
@@ -668,8 +677,8 @@ int hvm_bringup_ap(int vcpuid, int tramp
goto out;
}
- if ( test_and_clear_bit(_VCPUF_down, &d->vcpu[vcpuid]->vcpu_flags) )
- vcpu_wake(d->vcpu[vcpuid]);
+ if ( test_and_clear_bit(_VCPUF_down, &v->vcpu_flags) )
+ vcpu_wake(v);
gdprintk(XENLOG_INFO, "AP %d bringup suceeded.\n", vcpuid);
out:
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/hvm/i8254.c
--- a/xen/arch/x86/hvm/i8254.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/hvm/i8254.c Wed Feb 14 19:01:35 2007 +0000
@@ -445,7 +445,7 @@ static int pit_load(struct domain *d, hv
return 0;
}
-HVM_REGISTER_SAVE_RESTORE(PIT, pit_save, pit_load);
+HVM_REGISTER_SAVE_RESTORE(PIT, pit_save, pit_load, 1, HVMSR_PER_DOM);
static void pit_reset(void *opaque)
{
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/hvm/intercept.c
--- a/xen/arch/x86/hvm/intercept.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/hvm/intercept.c Wed Feb 14 19:01:35 2007 +0000
@@ -29,8 +29,6 @@
#include <asm/current.h>
#include <io_ports.h>
#include <xen/event.h>
-#include <xen/compile.h>
-#include <public/version.h>
extern struct hvm_mmio_handler hpet_mmio_handler;
@@ -157,180 +155,6 @@ static inline void hvm_mmio_access(struc
}
}
-/* List of handlers for various HVM save and restore types */
-static struct {
- hvm_save_handler save;
- hvm_load_handler load;
- const char *name;
-} hvm_sr_handlers [HVM_SAVE_CODE_MAX + 1] = {{NULL, NULL, "<?>"},};
-
-/* Init-time function to add entries to that list */
-void hvm_register_savevm(uint16_t typecode,
- const char *name,
- hvm_save_handler save_state,
- hvm_load_handler load_state)
-{
- ASSERT(typecode <= HVM_SAVE_CODE_MAX);
- ASSERT(hvm_sr_handlers[typecode].save == NULL);
- ASSERT(hvm_sr_handlers[typecode].load == NULL);
- hvm_sr_handlers[typecode].save = save_state;
- hvm_sr_handlers[typecode].load = load_state;
- hvm_sr_handlers[typecode].name = name;
-}
-
-
-int hvm_save(struct domain *d, hvm_domain_context_t *h)
-{
- uint32_t eax, ebx, ecx, edx;
- char *c;
- struct hvm_save_header hdr;
- struct hvm_save_end end;
- hvm_save_handler handler;
- uint16_t i;
-
- hdr.magic = HVM_FILE_MAGIC;
- hdr.version = HVM_FILE_VERSION;
-
- /* Save some CPUID bits */
- cpuid(1, &eax, &ebx, &ecx, &edx);
- hdr.cpuid = eax;
-
- /* Save xen changeset */
- c = strrchr(XEN_CHANGESET, ':');
- if ( c )
- hdr.changeset = simple_strtoll(c, NULL, 16);
- else
- hdr.changeset = -1ULL; /* Unknown */
-
- if ( hvm_save_entry(HEADER, 0, h, &hdr) != 0 )
- {
- gdprintk(XENLOG_ERR, "HVM save: failed to write header\n");
- return -EFAULT;
- }
-
- /* Save all available kinds of state */
- for ( i = 0; i <= HVM_SAVE_CODE_MAX; i++ )
- {
- handler = hvm_sr_handlers[i].save;
- if ( handler != NULL )
- {
- gdprintk(XENLOG_INFO, "HVM save: %s\n", hvm_sr_handlers[i].name);
- if ( handler(d, h) != 0 )
- {
- gdprintk(XENLOG_ERR,
- "HVM save: failed to save type %"PRIu16"\n", i);
- return -EFAULT;
- }
- }
- }
-
- /* Save an end-of-file marker */
- if ( hvm_save_entry(END, 0, h, &end) != 0 )
- {
- /* Run out of data */
- gdprintk(XENLOG_ERR, "HVM save: no room for end marker.\n");
- return -EFAULT;
- }
-
- /* Save macros should not have let us overrun */
- ASSERT(h->cur <= h->size);
- return 0;
-}
-
-int hvm_load(struct domain *d, hvm_domain_context_t *h)
-{
- uint32_t eax, ebx, ecx, edx;
- char *c;
- uint64_t cset;
- struct hvm_save_header hdr;
- struct hvm_save_descriptor *desc;
- hvm_load_handler handler;
- struct vcpu *v;
-
- /* Read the save header, which must be first */
- if ( hvm_load_entry(HEADER, h, &hdr) != 0 )
- return -1;
-
- if (hdr.magic != HVM_FILE_MAGIC) {
- gdprintk(XENLOG_ERR,
- "HVM restore: bad magic number %#"PRIx32"\n", hdr.magic);
- return -1;
- }
-
- if (hdr.version != HVM_FILE_VERSION) {
- gdprintk(XENLOG_ERR,
- "HVM restore: unsupported version %u\n", hdr.version);
- return -1;
- }
-
- cpuid(1, &eax, &ebx, &ecx, &edx);
- /*TODO: need to define how big a difference is acceptable */
- if (hdr.cpuid != eax)
- gdprintk(XENLOG_WARNING, "HVM restore: saved CPUID (%#"PRIx32") "
- "does not match host (%#"PRIx32").\n", hdr.cpuid, eax);
-
-
- c = strrchr(XEN_CHANGESET, ':');
- if ( hdr.changeset == -1ULL )
- gdprintk(XENLOG_WARNING,
- "HVM restore: Xen changeset was not saved.\n");
- else if ( c == NULL )
- gdprintk(XENLOG_WARNING,
- "HVM restore: Xen changeset is not available.\n");
- else
- {
- cset = simple_strtoll(c, NULL, 16);
- if ( hdr.changeset != cset )
- gdprintk(XENLOG_WARNING, "HVM restore: saved Xen changeset (%#"PRIx64
- ") does not match host (%#"PRIx64").\n", hdr.changeset, cset);
- }
-
- /* Down all the vcpus: we only re-enable the ones that had state saved. */
- for_each_vcpu(d, v)
- if ( test_and_set_bit(_VCPUF_down, &v->vcpu_flags) )
- vcpu_sleep_nosync(v);
-
- while(1) {
-
- if ( h->size - h->cur < sizeof(struct hvm_save_descriptor) )
- {
- /* Run out of data */
- gdprintk(XENLOG_ERR,
- "HVM restore: save did not end with a null entry\n");
- return -1;
- }
-
- /* Read the typecode of the next entry and check for the end-marker */
- desc = (struct hvm_save_descriptor *)(&h->data[h->cur]);
- if ( desc->typecode == 0 )
- return 0;
-
- /* Find the handler for this entry */
- if ( desc->typecode > HVM_SAVE_CODE_MAX
- || (handler = hvm_sr_handlers[desc->typecode].load) == NULL )
- {
- gdprintk(XENLOG_ERR,
- "HVM restore: unknown entry typecode %u\n",
- desc->typecode);
- return -1;
- }
-
- /* Load the entry */
- gdprintk(XENLOG_INFO, "HVM restore: %s %"PRIu16"\n",
- hvm_sr_handlers[desc->typecode].name, desc->instance);
- if ( handler(d, h) != 0 )
- {
- gdprintk(XENLOG_ERR,
- "HVM restore: failed to load entry %u/%u\n",
- desc->typecode, desc->instance);
- return -1;
- }
- }
-
- /* Not reached */
-}
-
-
int hvm_buffered_io_intercept(ioreq_t *p)
{
struct vcpu *v = current;
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/hvm/io.c Wed Feb 14 19:01:35 2007 +0000
@@ -32,7 +32,7 @@
#include <asm/processor.h>
#include <asm/msr.h>
#include <asm/apic.h>
-#include <asm/shadow.h>
+#include <asm/paging.h>
#include <asm/hvm/hvm.h>
#include <asm/hvm/support.h>
#include <asm/hvm/vpt.h>
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/hvm/irq.c
--- a/xen/arch/x86/hvm/irq.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/hvm/irq.c Wed Feb 14 19:01:35 2007 +0000
@@ -480,6 +480,9 @@ static int irq_load_link(struct domain *
return 0;
}
-HVM_REGISTER_SAVE_RESTORE(PCI_IRQ, irq_save_pci, irq_load_pci);
-HVM_REGISTER_SAVE_RESTORE(ISA_IRQ, irq_save_isa, irq_load_isa);
-HVM_REGISTER_SAVE_RESTORE(PCI_LINK, irq_save_link, irq_load_link);
+HVM_REGISTER_SAVE_RESTORE(PCI_IRQ, irq_save_pci, irq_load_pci,
+ 1, HVMSR_PER_DOM);
+HVM_REGISTER_SAVE_RESTORE(ISA_IRQ, irq_save_isa, irq_load_isa,
+ 1, HVMSR_PER_DOM);
+HVM_REGISTER_SAVE_RESTORE(PCI_LINK, irq_save_link, irq_load_link,
+ 1, HVMSR_PER_DOM);
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/hvm/platform.c Wed Feb 14 19:01:35 2007 +0000
@@ -21,7 +21,6 @@
#include <xen/config.h>
#include <xen/types.h>
#include <xen/mm.h>
-#include <xen/shadow.h>
#include <xen/domain_page.h>
#include <asm/page.h>
#include <xen/event.h>
@@ -29,6 +28,7 @@
#include <xen/sched.h>
#include <asm/regs.h>
#include <asm/x86_emulate.h>
+#include <asm/paging.h>
#include <asm/hvm/hvm.h>
#include <asm/hvm/support.h>
#include <asm/hvm/io.h>
@@ -513,12 +513,28 @@ static int mmio_decode(int address_bytes
mmio_op->operand[1] = mk_operand(size_reg, 0, 0, MEMORY);
switch ( ins_subtype ) {
+ case 0: /* add $imm, m32/16 */
+ mmio_op->instr = INSTR_ADD;
+ return DECODE_success;
+
+ case 1: /* or $imm, m32/16 */
+ mmio_op->instr = INSTR_OR;
+ return DECODE_success;
+
+ case 4: /* and $imm, m32/16 */
+ mmio_op->instr = INSTR_AND;
+ return DECODE_success;
+
+ case 5: /* sub $imm, m32/16 */
+ mmio_op->instr = INSTR_SUB;
+ return DECODE_success;
+
+ case 6: /* xor $imm, m32/16 */
+ mmio_op->instr = INSTR_XOR;
+ return DECODE_success;
+
case 7: /* cmp $imm, m32/16 */
mmio_op->instr = INSTR_CMP;
- return DECODE_success;
-
- case 1: /* or $imm, m32/16 */
- mmio_op->instr = INSTR_OR;
return DECODE_success;
default:
@@ -673,6 +689,39 @@ static int mmio_decode(int address_bytes
return DECODE_success;
} else
return DECODE_failure;
+
+ case 0xFE:
+ case 0xFF:
+ {
+ unsigned char ins_subtype = (opcode[1] >> 3) & 7;
+
+ if ( opcode[0] == 0xFE ) {
+ *op_size = BYTE;
+ GET_OP_SIZE_FOR_BYTE(size_reg);
+ } else {
+ GET_OP_SIZE_FOR_NONEBYTE(*op_size);
+ size_reg = *op_size;
+ }
+
+ mmio_op->immediate = 1;
+ mmio_op->operand[0] = mk_operand(size_reg, 0, 0, IMMEDIATE);
+ mmio_op->operand[1] = mk_operand(size_reg, 0, 0, MEMORY);
+
+ switch ( ins_subtype ) {
+ case 0: /* inc */
+ mmio_op->instr = INSTR_ADD;
+ return DECODE_success;
+
+ case 1: /* dec */
+ mmio_op->instr = INSTR_SUB;
+ return DECODE_success;
+
+ default:
+ printk("%x/%x, This opcode isn't handled yet!\n",
+ *opcode, ins_subtype);
+ return DECODE_failure;
+ }
+ }
case 0x0F:
break;
@@ -793,7 +842,7 @@ void send_pio_req(unsigned long port, un
if ( value_is_ptr ) /* get physical address of data */
{
if ( hvm_paging_enabled(current) )
- p->data = shadow_gva_to_gpa(current, value);
+ p->data = paging_gva_to_gpa(current, value);
else
p->data = value; /* guest VA == guest PA */
}
@@ -849,7 +898,7 @@ static void send_mmio_req(unsigned char
if ( value_is_ptr )
{
if ( hvm_paging_enabled(v) )
- p->data = shadow_gva_to_gpa(v, value);
+ p->data = paging_gva_to_gpa(v, value);
else
p->data = value; /* guest VA == guest PA */
}
@@ -965,7 +1014,7 @@ void handle_mmio(unsigned long gpa)
if ( ad_size == WORD )
addr &= 0xFFFF;
addr += hvm_get_segment_base(v, x86_seg_es);
- if ( shadow_gva_to_gpa(v, addr) == gpa )
+ if ( paging_gva_to_gpa(v, addr) == gpa )
{
enum x86_segment seg;
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/hvm/pmtimer.c
--- a/xen/arch/x86/hvm/pmtimer.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/hvm/pmtimer.c Wed Feb 14 19:01:35 2007 +0000
@@ -1,17 +1,6 @@
#include <asm/hvm/vpt.h>
#include <asm/hvm/io.h>
#include <asm/hvm/support.h>
-
-#define TMR_STS (1 << 0)
-static void pmt_update_status(void *opaque)
-{
- PMTState *s = opaque;
- s->pm1_status |= TMR_STS;
-
- /* TODO: When TMR_EN == 1, generate a SCI event */
-
- set_timer(&s->timer, NOW() + (1000000000ULL << 31) / FREQUENCE_PMTIMER);
-}
static int handle_pmt_io(ioreq_t *p)
{
@@ -30,42 +19,62 @@ static int handle_pmt_io(ioreq_t *p)
/* PM_TMR_BLK is read-only */
return 1;
} else if (p->dir == 1) { /* read */
+ /* Set the correct value in the timer, accounting for time
+ * elapsed since the last time we did that. */
curr_gtime = hvm_get_guest_time(s->vcpu);
- s->pm1_timer += ((curr_gtime - s->last_gtime) * s->scale) >> 32;
- p->data = s->pm1_timer;
+ s->pm.timer += ((curr_gtime - s->last_gtime) * s->scale) >> 32;
+ p->data = s->pm.timer;
s->last_gtime = curr_gtime;
return 1;
}
return 0;
}
+static int pmtimer_save(struct domain *d, hvm_domain_context_t *h)
+{
+ PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
+ uint32_t x;
+
+ /* Update the counter to the guest's current time. We always save
+ * with the domain paused, so the saved time should be after the
+ * last_gtime, but just in case, make sure we only go forwards */
+ x = ((s->vcpu->arch.hvm_vcpu.guest_time - s->last_gtime) * s->scale) >> 32;
+ if ( x < 1UL<<31 )
+ s->pm.timer += x;
+ return hvm_save_entry(PMTIMER, 0, h, &s->pm);
+}
+
+static int pmtimer_load(struct domain *d, hvm_domain_context_t *h)
+{
+ PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
+
+ /* Reload the counter */
+ if ( hvm_load_entry(PMTIMER, h, &s->pm) )
+ return -EINVAL;
+
+ /* Calculate future counter values from now. */
+ s->last_gtime = hvm_get_guest_time(s->vcpu);
+
+ return 0;
+}
+
+HVM_REGISTER_SAVE_RESTORE(PMTIMER, pmtimer_save, pmtimer_load,
+ 1, HVMSR_PER_DOM);
+
+
void pmtimer_init(struct vcpu *v, int base)
{
PMTState *s = &v->domain->arch.hvm_domain.pl_time.vpmt;
- s->pm1_timer = 0;
- s->pm1_status = 0;
+ s->pm.timer = 0;
s->scale = ((uint64_t)FREQUENCE_PMTIMER << 32) / ticks_per_sec(v);
s->vcpu = v;
- init_timer(&s->timer, pmt_update_status, s, v->processor);
- /* ACPI supports a 32-bit power management timer */
- set_timer(&s->timer, NOW() + (1000000000ULL << 31) / FREQUENCE_PMTIMER);
-
+ /* Not implemented: we should set TMR_STS (bit 0 of PM1a_STS) every
+ * time the timer's top bit flips, and generate an SCI if TMR_EN
+ * (bit 0 of PM1a_EN) is set. For now, those registers are in
+ * qemu-dm, and we just calculate the timer's value on demand. */
+
register_portio_handler(v->domain, base, 4, handle_pmt_io);
}
-void pmtimer_migrate_timers(struct vcpu *v)
-{
- struct PMTState *vpmt = &v->domain->arch.hvm_domain.pl_time.vpmt;
-
- if (vpmt->vcpu == v)
- migrate_timer(&vpmt->timer, v->processor);
-}
-
-void pmtimer_deinit(struct domain *d)
-{
- PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
-
- kill_timer(&s->timer);
-}
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/hvm/rtc.c
--- a/xen/arch/x86/hvm/rtc.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/hvm/rtc.c Wed Feb 14 19:01:35 2007 +0000
@@ -417,7 +417,7 @@ static int rtc_load(struct domain *d, hv
return 0;
}
-HVM_REGISTER_SAVE_RESTORE(RTC, rtc_save, rtc_load);
+HVM_REGISTER_SAVE_RESTORE(RTC, rtc_save, rtc_load, 1, HVMSR_PER_DOM);
void rtc_init(struct vcpu *v, int base)
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/hvm/save.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/hvm/save.c Wed Feb 14 19:01:35 2007 +0000
@@ -0,0 +1,229 @@
+/*
+ * hvm/save.c: Save and restore HVM guest's emulated hardware state.
+ *
+ * Copyright (c) 2004, Intel Corporation.
+ * Copyright (c) 2007, XenSource Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/compile.h>
+#include <xen/lib.h>
+#include <public/version.h>
+#include <xen/sched.h>
+
+#include <asm/hvm/hvm.h>
+#include <asm/hvm/support.h>
+#include <asm/hvm/domain.h>
+#include <asm/current.h>
+
+
+/* List of handlers for various HVM save and restore types */
+static struct {
+ hvm_save_handler save;
+ hvm_load_handler load;
+ const char *name;
+ size_t size;
+ int kind;
+} hvm_sr_handlers [HVM_SAVE_CODE_MAX + 1] = {{NULL, NULL, "<?>"},};
+
+/* Init-time function to add entries to that list */
+void hvm_register_savevm(uint16_t typecode,
+ const char *name,
+ hvm_save_handler save_state,
+ hvm_load_handler load_state,
+ size_t size, int kind)
+{
+ ASSERT(typecode <= HVM_SAVE_CODE_MAX);
+ ASSERT(hvm_sr_handlers[typecode].save == NULL);
+ ASSERT(hvm_sr_handlers[typecode].load == NULL);
+ hvm_sr_handlers[typecode].save = save_state;
+ hvm_sr_handlers[typecode].load = load_state;
+ hvm_sr_handlers[typecode].name = name;
+ hvm_sr_handlers[typecode].size = size;
+ hvm_sr_handlers[typecode].kind = kind;
+}
+
+size_t hvm_save_size(struct domain *d)
+{
+ struct vcpu *v;
+ size_t sz;
+ int i;
+
+ /* Basic overhead for header and footer */
+ sz = (2 * sizeof (struct hvm_save_descriptor)) + HVM_SAVE_LENGTH(HEADER);
+
+ /* Plus space for each thing we will be saving */
+ for ( i = 0; i <= HVM_SAVE_CODE_MAX; i++ )
+ if ( hvm_sr_handlers[i].kind == HVMSR_PER_VCPU )
+ for_each_vcpu(d, v)
+ sz += hvm_sr_handlers[i].size;
+ else
+ sz += hvm_sr_handlers[i].size;
+
+ return sz;
+}
+
+
+int hvm_save(struct domain *d, hvm_domain_context_t *h)
+{
+ uint32_t eax, ebx, ecx, edx;
+ char *c;
+ struct hvm_save_header hdr;
+ struct hvm_save_end end;
+ hvm_save_handler handler;
+ uint16_t i;
+
+ hdr.magic = HVM_FILE_MAGIC;
+ hdr.version = HVM_FILE_VERSION;
+
+ /* Save some CPUID bits */
+ cpuid(1, &eax, &ebx, &ecx, &edx);
+ hdr.cpuid = eax;
+
+ /* Save xen changeset */
+ c = strrchr(XEN_CHANGESET, ':');
+ if ( c )
+ hdr.changeset = simple_strtoll(c, NULL, 16);
+ else
+ hdr.changeset = -1ULL; /* Unknown */
+
+ if ( hvm_save_entry(HEADER, 0, h, &hdr) != 0 )
+ {
+ gdprintk(XENLOG_ERR, "HVM save: failed to write header\n");
+ return -EFAULT;
+ }
+
+ /* Save all available kinds of state */
+ for ( i = 0; i <= HVM_SAVE_CODE_MAX; i++ )
+ {
+ handler = hvm_sr_handlers[i].save;
+ if ( handler != NULL )
+ {
+ gdprintk(XENLOG_INFO, "HVM save: %s\n", hvm_sr_handlers[i].name);
+ if ( handler(d, h) != 0 )
+ {
+ gdprintk(XENLOG_ERR,
+ "HVM save: failed to save type %"PRIu16"\n", i);
+ return -EFAULT;
+ }
+ }
+ }
+
+ /* Save an end-of-file marker */
+ if ( hvm_save_entry(END, 0, h, &end) != 0 )
+ {
+ /* Run out of data */
+ gdprintk(XENLOG_ERR, "HVM save: no room for end marker.\n");
+ return -EFAULT;
+ }
+
+ /* Save macros should not have let us overrun */
+ ASSERT(h->cur <= h->size);
+ return 0;
+}
+
+int hvm_load(struct domain *d, hvm_domain_context_t *h)
+{
+ uint32_t eax, ebx, ecx, edx;
+ char *c;
+ uint64_t cset;
+ struct hvm_save_header hdr;
+ struct hvm_save_descriptor *desc;
+ hvm_load_handler handler;
+ struct vcpu *v;
+
+ /* Read the save header, which must be first */
+ if ( hvm_load_entry(HEADER, h, &hdr) != 0 )
+ return -1;
+
+ if (hdr.magic != HVM_FILE_MAGIC) {
+ gdprintk(XENLOG_ERR,
+ "HVM restore: bad magic number %#"PRIx32"\n", hdr.magic);
+ return -1;
+ }
+
+ if (hdr.version != HVM_FILE_VERSION) {
+ gdprintk(XENLOG_ERR,
+ "HVM restore: unsupported version %u\n", hdr.version);
+ return -1;
+ }
+
+ cpuid(1, &eax, &ebx, &ecx, &edx);
+ /*TODO: need to define how big a difference is acceptable */
+ if (hdr.cpuid != eax)
+ gdprintk(XENLOG_WARNING, "HVM restore: saved CPUID (%#"PRIx32") "
+ "does not match host (%#"PRIx32").\n", hdr.cpuid, eax);
+
+
+ c = strrchr(XEN_CHANGESET, ':');
+ if ( hdr.changeset == -1ULL )
+ gdprintk(XENLOG_WARNING,
+ "HVM restore: Xen changeset was not saved.\n");
+ else if ( c == NULL )
+ gdprintk(XENLOG_WARNING,
+ "HVM restore: Xen changeset is not available.\n");
+ else
+ {
+ cset = simple_strtoll(c, NULL, 16);
+ if ( hdr.changeset != cset )
+ gdprintk(XENLOG_WARNING, "HVM restore: saved Xen changeset (%#"PRIx64
+ ") does not match host (%#"PRIx64").\n", hdr.changeset, cset);
+ }
+
+ /* Down all the vcpus: we only re-enable the ones that had state saved. */
+ for_each_vcpu(d, v)
+ if ( test_and_set_bit(_VCPUF_down, &v->vcpu_flags) )
+ vcpu_sleep_nosync(v);
+
+ while(1) {
+
+ if ( h->size - h->cur < sizeof(struct hvm_save_descriptor) )
+ {
+ /* Run out of data */
+ gdprintk(XENLOG_ERR,
+ "HVM restore: save did not end with a null entry\n");
+ return -1;
+ }
+
+ /* Read the typecode of the next entry and check for the end-marker */
+ desc = (struct hvm_save_descriptor *)(&h->data[h->cur]);
+ if ( desc->typecode == 0 )
+ return 0;
+
+ /* Find the handler for this entry */
+ if ( desc->typecode > HVM_SAVE_CODE_MAX
+ || (handler = hvm_sr_handlers[desc->typecode].load) == NULL )
+ {
+ gdprintk(XENLOG_ERR,
+ "HVM restore: unknown entry typecode %u\n",
+ desc->typecode);
+ return -1;
+ }
+
+ /* Load the entry */
+ gdprintk(XENLOG_INFO, "HVM restore: %s %"PRIu16"\n",
+ hvm_sr_handlers[desc->typecode].name, desc->instance);
+ if ( handler(d, h) != 0 )
+ {
+ gdprintk(XENLOG_ERR,
+ "HVM restore: failed to load entry %u/%u\n",
+ desc->typecode, desc->instance);
+ return -1;
+ }
+ }
+
+ /* Not reached */
+}
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/hvm/svm/intr.c Wed Feb 14 19:01:35 2007 +0000
@@ -24,10 +24,10 @@
#include <xen/lib.h>
#include <xen/trace.h>
#include <xen/errno.h>
-#include <xen/shadow.h>
#include <asm/cpufeature.h>
#include <asm/processor.h>
#include <asm/msr.h>
+#include <asm/paging.h>
#include <asm/hvm/hvm.h>
#include <asm/hvm/io.h>
#include <asm/hvm/support.h>
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/hvm/svm/svm.c Wed Feb 14 19:01:35 2007 +0000
@@ -29,7 +29,8 @@
#include <xen/domain_page.h>
#include <asm/current.h>
#include <asm/io.h>
-#include <asm/shadow.h>
+#include <asm/paging.h>
+#include <asm/p2m.h>
#include <asm/regs.h>
#include <asm/cpufeature.h>
#include <asm/processor.h>
@@ -491,9 +492,6 @@ int svm_vmcb_restore(struct vcpu *v, str
v->arch.guest_table = pagetable_from_pfn(mfn);
if (old_base_mfn)
put_page(mfn_to_page(old_base_mfn));
- /*
- * arch.shadow_table should now hold the next CR3 for shadow
- */
v->arch.hvm_svm.cpu_cr3 = c->cr3;
}
@@ -560,7 +558,7 @@ int svm_vmcb_restore(struct vcpu *v, str
vmcb->sysenter_esp = c->sysenter_esp;
vmcb->sysenter_eip = c->sysenter_eip;
- shadow_update_paging_modes(v);
+ paging_update_paging_modes(v);
return 0;
bad_cr3:
@@ -1095,7 +1093,7 @@ static int svm_do_page_fault(unsigned lo
"svm_do_page_fault = 0x%lx, eip = %lx, error_code = %lx",
va, (unsigned long)current->arch.hvm_svm.vmcb->rip,
(unsigned long)regs->error_code);
- return shadow_fault(va, regs);
+ return paging_fault(va, regs);
}
@@ -1199,6 +1197,8 @@ static void svm_vmexit_do_cpuid(struct v
/* So far, we do not support 3DNow for the guest. */
clear_bit(X86_FEATURE_3DNOW & 31, &edx);
clear_bit(X86_FEATURE_3DNOWEXT & 31, &edx);
+ /* no FFXSR instructions feature. */
+ clear_bit(X86_FEATURE_FFXSR & 31, &edx);
}
else if ( input == 0x80000007 || input == 0x8000000A )
{
@@ -1728,7 +1728,7 @@ static int svm_set_cr0(unsigned long val
v->arch.guest_table = pagetable_from_pfn(mfn);
if ( old_base_mfn )
put_page(mfn_to_page(old_base_mfn));
- shadow_update_paging_modes(v);
+ paging_update_paging_modes(v);
HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
(unsigned long) (mfn << PAGE_SHIFT));
@@ -1751,7 +1751,7 @@ static int svm_set_cr0(unsigned long val
svm_inject_exception(v, TRAP_gp_fault, 1, 0);
return 0;
}
- shadow_update_paging_modes(v);
+ paging_update_paging_modes(v);
}
else if ( (value & (X86_CR0_PE | X86_CR0_PG)) == X86_CR0_PE )
{
@@ -1761,7 +1761,7 @@ static int svm_set_cr0(unsigned long val
clear_bit(SVM_CPU_STATE_LMA_ENABLED, &v->arch.hvm_svm.cpu_state);
}
/* we should take care of this kind of situation */
- shadow_update_paging_modes(v);
+ paging_update_paging_modes(v);
}
return 1;
@@ -1864,7 +1864,7 @@ static int mov_to_cr(int gpreg, int cr,
mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
if (mfn != pagetable_get_pfn(v->arch.guest_table))
goto bad_cr3;
- shadow_update_cr3(v);
+ paging_update_cr3(v);
}
else
{
@@ -1915,7 +1915,7 @@ static int mov_to_cr(int gpreg, int cr,
v->arch.guest_table = pagetable_from_pfn(mfn);
if ( old_base_mfn )
put_page(mfn_to_page(old_base_mfn));
- shadow_update_paging_modes(v);
+ paging_update_paging_modes(v);
HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
(unsigned long) (mfn << PAGE_SHIFT));
@@ -1944,7 +1944,7 @@ static int mov_to_cr(int gpreg, int cr,
* all TLB entries except global entries.
*/
if ((old_cr ^ value) & (X86_CR4_PSE | X86_CR4_PGE | X86_CR4_PAE))
- shadow_update_paging_modes(v);
+ paging_update_paging_modes(v);
break;
case 8:
@@ -2287,7 +2287,7 @@ void svm_handle_invlpg(const short invlp
__update_guest_eip (vmcb, inst_len);
}
- shadow_invlpg(v, g_vaddr);
+ paging_invlpg(v, g_vaddr);
}
@@ -2658,7 +2658,7 @@ void walk_shadow_and_guest_pt(unsigned l
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
paddr_t gpa;
- gpa = shadow_gva_to_gpa(current, gva);
+ gpa = paging_gva_to_gpa(current, gva);
printk("gva = %lx, gpa=%"PRIpaddr", gCR3=%x\n", gva, gpa, (u32)vmcb->cr3);
if( !svm_paging_enabled(v) || mmio_space(gpa) )
return;
@@ -2679,7 +2679,7 @@ void walk_shadow_and_guest_pt(unsigned l
shadow_sync_va(v, gva);
gpte.l1 = 0;
- __copy_from_user(&gpte, &linear_pg_table[ l1_linear_offset(gva) ],
+ __copy_from_user(&gpte, &__linear_l1_table[ l1_linear_offset(gva) ],
sizeof(gpte) );
printk( "G-PTE = %x, flags=%x\n", gpte.l1, l1e_get_flags(gpte) );
@@ -2724,7 +2724,7 @@ asmlinkage void svm_vmexit_handler(struc
if (svm_dbg_on && exit_reason == VMEXIT_EXCEPTION_PF)
{
if (svm_paging_enabled(v) &&
- !mmio_space(shadow_gva_to_gpa(current, vmcb->exitinfo2)))
+ !mmio_space(paging_gva_to_gpa(current, vmcb->exitinfo2)))
{
printk("I%08ld,ExC=%s(%d),IP=%x:%"PRIx64","
"I1=%"PRIx64",I2=%"PRIx64",INT=%"PRIx64", "
@@ -2734,7 +2734,7 @@ asmlinkage void svm_vmexit_handler(struc
(u64)vmcb->exitinfo1,
(u64)vmcb->exitinfo2,
(u64)vmcb->exitintinfo.bytes,
- (u64)shadow_gva_to_gpa(current, vmcb->exitinfo2));
+ (u64)paging_gva_to_gpa(current, vmcb->exitinfo2));
}
else
{
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/hvm/svm/vmcb.c Wed Feb 14 19:01:35 2007 +0000
@@ -23,10 +23,10 @@
#include <xen/mm.h>
#include <xen/lib.h>
#include <xen/errno.h>
-#include <xen/shadow.h>
#include <asm/cpufeature.h>
#include <asm/processor.h>
#include <asm/msr.h>
+#include <asm/paging.h>
#include <asm/hvm/hvm.h>
#include <asm/hvm/io.h>
#include <asm/hvm/support.h>
@@ -196,7 +196,7 @@ static int construct_vmcb(struct vcpu *v
read_cr4() & ~(X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE);
vmcb->cr4 = arch_svm->cpu_shadow_cr4 | SVM_CR4_HOST_MASK;
- shadow_update_paging_modes(v);
+ paging_update_paging_modes(v);
vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3;
arch_svm->vmcb->exception_intercepts = MONITOR_DEFAULT_EXCEPTION_BITMAP;
@@ -209,7 +209,8 @@ int svm_create_vmcb(struct vcpu *v)
struct arch_svm_struct *arch_svm = &v->arch.hvm_svm;
int rc;
- if ( (arch_svm->vmcb = alloc_vmcb()) == NULL )
+ if ( (arch_svm->vmcb == NULL) &&
+ (arch_svm->vmcb = alloc_vmcb()) == NULL )
{
printk("Failed to create a new VMCB\n");
return -ENOMEM;
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/hvm/vioapic.c Wed Feb 14 19:01:35 2007 +0000
@@ -514,7 +514,7 @@ static int ioapic_load(struct domain *d,
return 0;
}
-HVM_REGISTER_SAVE_RESTORE(IOAPIC, ioapic_save, ioapic_load);
+HVM_REGISTER_SAVE_RESTORE(IOAPIC, ioapic_save, ioapic_load, 1, HVMSR_PER_DOM);
void vioapic_init(struct domain *d)
{
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/hvm/vlapic.c Wed Feb 14 19:01:35 2007 +0000
@@ -22,7 +22,6 @@
#include <xen/types.h>
#include <xen/mm.h>
#include <xen/xmalloc.h>
-#include <xen/shadow.h>
#include <xen/domain_page.h>
#include <asm/page.h>
#include <xen/event.h>
@@ -83,8 +82,6 @@ static unsigned int vlapic_lvt_mask[VLAP
#define vlapic_base_address(vlapic) \
(vlapic->hw.apic_base_msr & MSR_IA32_APICBASE_BASE)
-static int vlapic_reset(struct vlapic *vlapic);
-
/*
* Generic APIC bitmap vector update & search routines.
*/
@@ -293,8 +290,11 @@ static int vlapic_accept_irq(struct vcpu
break;
case APIC_DM_SMI:
+ gdprintk(XENLOG_WARNING, "Ignoring guest SMI\n");
+ break;
+
case APIC_DM_NMI:
- gdprintk(XENLOG_WARNING, "Ignoring guest SMI/NMI\n");
+ gdprintk(XENLOG_WARNING, "Ignoring guest NMI\n");
break;
case APIC_DM_INIT:
@@ -303,10 +303,7 @@ static int vlapic_accept_irq(struct vcpu
break;
/* FIXME How to check the situation after vcpu reset? */
if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
- {
- gdprintk(XENLOG_ERR, "Reset hvm vcpu not supported yet\n");
- goto exit_and_crash;
- }
+ hvm_vcpu_reset(v);
v->arch.hvm_vcpu.init_sipi_sipi_state =
HVM_VCPU_INIT_SIPI_SIPI_STATE_WAIT_SIPI;
result = 1;
@@ -764,7 +761,7 @@ int cpu_get_apic_interrupt(struct vcpu *
}
/* Reset the VLPAIC back to its power-on/reset state. */
-static int vlapic_reset(struct vlapic *vlapic)
+void vlapic_reset(struct vlapic *vlapic)
{
struct vcpu *v = vlapic_vcpu(vlapic);
int i;
@@ -793,8 +790,6 @@ static int vlapic_reset(struct vlapic *v
vlapic_set_reg(vlapic, APIC_SPIV, 0xff);
vlapic->hw.disabled |= VLAPIC_SW_DISABLED;
-
- return 1;
}
#ifdef HVM_DEBUG_SUSPEND
@@ -908,8 +903,10 @@ static int lapic_load_regs(struct domain
return 0;
}
-HVM_REGISTER_SAVE_RESTORE(LAPIC, lapic_save_hidden, lapic_load_hidden);
-HVM_REGISTER_SAVE_RESTORE(LAPIC_REGS, lapic_save_regs, lapic_load_regs);
+HVM_REGISTER_SAVE_RESTORE(LAPIC, lapic_save_hidden, lapic_load_hidden,
+ 1, HVMSR_PER_VCPU);
+HVM_REGISTER_SAVE_RESTORE(LAPIC_REGS, lapic_save_regs, lapic_load_regs,
+ 1, HVMSR_PER_VCPU);
int vlapic_init(struct vcpu *v)
{
@@ -922,7 +919,6 @@ int vlapic_init(struct vcpu *v)
{
dprintk(XENLOG_ERR, "malloc vlapic regs error for vcpu %x\n",
v->vcpu_id);
- xfree(vlapic);
return -ENOMEM;
}
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/hvm/vmx/vmcs.c Wed Feb 14 19:01:35 2007 +0000
@@ -295,6 +295,11 @@ static void construct_vmcs(struct vcpu *
vmx_vmcs_enter(v);
+ v->arch.hvm_vmx.cpu_cr2 = 0;
+ v->arch.hvm_vmx.cpu_cr3 = 0;
+ memset(&v->arch.hvm_vmx.msr_state, 0, sizeof(v->arch.hvm_vmx.msr_state));
+ v->arch.hvm_vmx.vmxassist_enabled = 0;
+
/* VMCS controls. */
__vmwrite(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_control);
__vmwrite(VM_EXIT_CONTROLS, vmx_vmexit_control);
@@ -443,15 +448,18 @@ static void construct_vmcs(struct vcpu *
vmx_vmcs_exit(v);
- shadow_update_paging_modes(v); /* will update HOST & GUEST_CR3 as reqd */
+ paging_update_paging_modes(v); /* will update HOST & GUEST_CR3 as reqd */
}
int vmx_create_vmcs(struct vcpu *v)
{
- if ( (v->arch.hvm_vmx.vmcs = vmx_alloc_vmcs()) == NULL )
- return -ENOMEM;
-
- __vmx_clear_vmcs(v);
+ if ( v->arch.hvm_vmx.vmcs == NULL )
+ {
+ if ( (v->arch.hvm_vmx.vmcs = vmx_alloc_vmcs()) == NULL )
+ return -ENOMEM;
+
+ __vmx_clear_vmcs(v);
+ }
construct_vmcs(v);
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/hvm/vmx/vmx.c Wed Feb 14 19:01:35 2007 +0000
@@ -35,12 +35,13 @@
#include <asm/types.h>
#include <asm/msr.h>
#include <asm/spinlock.h>
+#include <asm/paging.h>
+#include <asm/p2m.h>
#include <asm/hvm/hvm.h>
#include <asm/hvm/support.h>
#include <asm/hvm/vmx/vmx.h>
#include <asm/hvm/vmx/vmcs.h>
#include <asm/hvm/vmx/cpu.h>
-#include <asm/shadow.h>
#include <public/sched.h>
#include <public/hvm/ioreq.h>
#include <asm/hvm/vpic.h>
@@ -484,9 +485,6 @@ int vmx_vmcs_restore(struct vcpu *v, str
v->arch.guest_table = pagetable_from_pfn(mfn);
if (old_base_mfn)
put_page(mfn_to_page(old_base_mfn));
- /*
- * arch.shadow_table should now hold the next CR3 for shadow
- */
v->arch.hvm_vmx.cpu_cr3 = c->cr3;
}
@@ -556,7 +554,7 @@ int vmx_vmcs_restore(struct vcpu *v, str
vmx_vmcs_exit(v);
- shadow_update_paging_modes(v);
+ paging_update_paging_modes(v);
return 0;
bad_cr3:
@@ -1126,7 +1124,7 @@ static int vmx_do_page_fault(unsigned lo
}
#endif
- result = shadow_fault(va, regs);
+ result = paging_fault(va, regs);
TRACE_VMEXIT(2, result);
#if 0
@@ -1277,7 +1275,7 @@ static void vmx_do_invlpg(unsigned long
* We do the safest things first, then try to update the shadow
* copying from guest
*/
- shadow_invlpg(v, va);
+ paging_invlpg(v, va);
}
@@ -1691,9 +1689,6 @@ static int vmx_world_restore(struct vcpu
v->arch.guest_table = pagetable_from_pfn(mfn);
if (old_base_mfn)
put_page(mfn_to_page(old_base_mfn));
- /*
- * arch.shadow_table should now hold the next CR3 for shadow
- */
v->arch.hvm_vmx.cpu_cr3 = c->cr3;
}
@@ -1753,7 +1748,7 @@ static int vmx_world_restore(struct vcpu
__vmwrite(GUEST_LDTR_BASE, c->ldtr_base);
__vmwrite(GUEST_LDTR_AR_BYTES, c->ldtr_arbytes.bytes);
- shadow_update_paging_modes(v);
+ paging_update_paging_modes(v);
return 0;
bad_cr3:
@@ -1906,14 +1901,11 @@ static int vmx_set_cr0(unsigned long val
v->arch.guest_table = pagetable_from_pfn(mfn);
if (old_base_mfn)
put_page(mfn_to_page(old_base_mfn));
- shadow_update_paging_modes(v);
+ paging_update_paging_modes(v);
HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
(unsigned long) (mfn << PAGE_SHIFT));
- /*
- * arch->shadow_table should hold the next CR3 for shadow
- */
HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx, mfn = %lx",
v->arch.hvm_vmx.cpu_cr3, mfn);
}
@@ -1981,7 +1973,7 @@ static int vmx_set_cr0(unsigned long val
vm_entry_value &= ~VM_ENTRY_IA32E_MODE;
__vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
}
- shadow_update_paging_modes(v);
+ paging_update_paging_modes(v);
}
return 1;
@@ -2070,7 +2062,7 @@ static int mov_to_cr(int gp, int cr, str
mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
if (mfn != pagetable_get_pfn(v->arch.guest_table))
goto bad_cr3;
- shadow_update_cr3(v);
+ paging_update_cr3(v);
} else {
/*
* If different, make a shadow. Check if the PDBR is valid
@@ -2084,9 +2076,6 @@ static int mov_to_cr(int gp, int cr, str
v->arch.guest_table = pagetable_from_pfn(mfn);
if (old_base_mfn)
put_page(mfn_to_page(old_base_mfn));
- /*
- * arch.shadow_table should now hold the next CR3 for shadow
- */
v->arch.hvm_vmx.cpu_cr3 = value;
update_cr3(v);
HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx", value);
@@ -2120,9 +2109,6 @@ static int mov_to_cr(int gp, int cr, str
HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
(unsigned long) (mfn << PAGE_SHIFT));
- /*
- * arch->shadow_table should hold the next CR3 for shadow
- */
HVM_DBG_LOG(DBG_LEVEL_VMMU,
"Update CR3 value = %lx, mfn = %lx",
v->arch.hvm_vmx.cpu_cr3, mfn);
@@ -2148,7 +2134,7 @@ static int mov_to_cr(int gp, int cr, str
* all TLB entries except global entries.
*/
if ( (old_cr ^ value) & (X86_CR4_PSE | X86_CR4_PGE | X86_CR4_PAE) )
- shadow_update_paging_modes(v);
+ paging_update_paging_modes(v);
break;
case 8:
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/hvm/vpic.c
--- a/xen/arch/x86/hvm/vpic.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/hvm/vpic.c Wed Feb 14 19:01:35 2007 +0000
@@ -440,7 +440,7 @@ static int vpic_load(struct domain *d, h
return 0;
}
-HVM_REGISTER_SAVE_RESTORE(PIC, vpic_save, vpic_load);
+HVM_REGISTER_SAVE_RESTORE(PIC, vpic_save, vpic_load, 2, HVMSR_PER_DOM);
void vpic_init(struct domain *d)
{
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/machine_kexec.c
--- a/xen/arch/x86/machine_kexec.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/machine_kexec.c Wed Feb 14 19:01:35 2007 +0000
@@ -15,10 +15,14 @@
#include <xen/types.h>
#include <xen/console.h>
#include <xen/kexec.h>
-#include <asm/kexec.h>
#include <xen/domain_page.h>
#include <asm/fixmap.h>
#include <asm/hvm/hvm.h>
+
+typedef void (*relocate_new_kernel_t)(
+ unsigned long indirection_page,
+ unsigned long *page_list,
+ unsigned long start_address);
int machine_kexec_load(int type, int slot, xen_kexec_image_t *image)
{
@@ -40,8 +44,26 @@ int machine_kexec_load(int type, int slo
else
{
/* Odd pages: va for previous ma. */
- set_fixmap(fix_base + (k >> 1), prev_ma);
- image->page_list[k] = fix_to_virt(fix_base + (k >> 1));
+ if ( IS_COMPAT(dom0) )
+ {
+
+ /*
+ * The compatability bounce code sets up a page table
+ * with a 1-1 mapping of the first 1G of memory so
+ * VA==PA here.
+ *
+ * This Linux purgatory code still sets up separate
+ * high and low mappings on the control page (entries
+ * 0 and 1) but it is harmless if they are equal since
+ * that PT is not live at the time.
+ */
+ image->page_list[k] = prev_ma;
+ }
+ else
+ {
+ set_fixmap(fix_base + (k >> 1), prev_ma);
+ image->page_list[k] = fix_to_virt(fix_base + (k >> 1));
+ }
}
}
@@ -94,6 +116,31 @@ void machine_reboot_kexec(xen_kexec_imag
BUG();
}
+void machine_kexec(xen_kexec_image_t *image)
+{
+#ifdef CONFIG_COMPAT
+ if ( IS_COMPAT(dom0) )
+ {
+ extern void compat_machine_kexec(unsigned long rnk,
+ unsigned long indirection_page,
+ unsigned long *page_list,
+ unsigned long start_address);
+ compat_machine_kexec(image->page_list[1],
+ image->indirection_page,
+ image->page_list,
+ image->start_address);
+ }
+ else
+#endif
+ {
+ relocate_new_kernel_t rnk;
+
+ rnk = (relocate_new_kernel_t) image->page_list[1];
+ (*rnk)(image->indirection_page, image->page_list,
+ image->start_address);
+ }
+}
+
/*
* Local variables:
* mode: C
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/mm.c Wed Feb 14 19:01:35 2007 +0000
@@ -99,6 +99,7 @@
#include <xen/event.h>
#include <xen/iocap.h>
#include <xen/guest_access.h>
+#include <asm/paging.h>
#include <asm/shadow.h>
#include <asm/page.h>
#include <asm/flushtlb.h>
@@ -373,9 +374,6 @@ void write_ptbase(struct vcpu *v)
/* Should be called after CR3 is updated.
* Updates vcpu->arch.cr3 and, for HVM guests, vcpu->arch.hvm_vcpu.cpu_cr3.
*
- * Also updates other state derived from CR3 (vcpu->arch.guest_vtable,
- * shadow_vtable, etc).
- *
* Uses values found in vcpu->arch.(guest_table and guest_table_user), and
* for HVM guests, arch.monitor_table and hvm's guest CR3.
*
@@ -385,9 +383,9 @@ void update_cr3(struct vcpu *v)
{
unsigned long cr3_mfn=0;
- if ( shadow_mode_enabled(v->domain) )
- {
- shadow_update_cr3(v);
+ if ( paging_mode_enabled(v->domain) )
+ {
+ paging_update_cr3(v);
return;
}
@@ -615,7 +613,7 @@ get_page_from_l1e(
* qemu-dm helper process in dom0 to map the domain's memory without
* messing up the count of "real" writable mappings.) */
okay = (((l1e_get_flags(l1e) & _PAGE_RW) &&
- !(unlikely(shadow_mode_external(d) && (d != current->domain))))
+ !(unlikely(paging_mode_external(d) && (d != current->domain))))
? get_page_and_type(page, d, PGT_writable_page)
: get_page(page, d));
if ( !okay )
@@ -804,9 +802,9 @@ void put_page_from_l1e(l1_pgentry_t l1e,
}
/* Remember we didn't take a type-count of foreign writable mappings
- * to shadow external domains */
+ * to paging-external domains */
if ( (l1e_get_flags(l1e) & _PAGE_RW) &&
- !(unlikely((e != d) && shadow_mode_external(e))) )
+ !(unlikely((e != d) && paging_mode_external(e))) )
{
put_page_and_type(page);
}
@@ -976,6 +974,19 @@ static void pae_flush_pgd(
l3_pgentry_t *l3tab_ptr;
struct pae_l3_cache *cache;
+ if ( unlikely(shadow_mode_enabled(d)) )
+ {
+ cpumask_t m = CPU_MASK_NONE;
+ /* Re-shadow this l3 table on any vcpus that are using it */
+ for_each_vcpu ( d, v )
+ if ( pagetable_get_pfn(v->arch.guest_table) == mfn )
+ {
+ paging_update_cr3(v);
+ cpus_or(m, m, v->vcpu_dirty_cpumask);
+ }
+ flush_tlb_mask(m);
+ }
+
/* If below 4GB then the pgdir is not shadowed in low memory. */
if ( !l3tab_needs_shadow(mfn) )
return;
@@ -1259,20 +1270,13 @@ static inline int update_intpte(intpte_t
{
int rv = 1;
#ifndef PTE_UPDATE_WITH_CMPXCHG
- if ( unlikely(shadow_mode_enabled(v->domain)) )
- rv = shadow_write_guest_entry(v, p, new, _mfn(mfn));
- else
- rv = (!__copy_to_user(p, &new, sizeof(new)));
+ rv = paging_write_guest_entry(v, p, new, _mfn(mfn));
#else
{
intpte_t t = old;
for ( ; ; )
{
- if ( unlikely(shadow_mode_enabled(v->domain)) )
- rv = shadow_cmpxchg_guest_entry(v, p, &t, new, _mfn(mfn));
- else
- rv = (!cmpxchg_user(p, t, new));
-
+ rv = paging_cmpxchg_guest_entry(v, p, &t, new, _mfn(mfn));
if ( unlikely(rv == 0) )
{
MEM_LOG("Failed to update %" PRIpte " -> %" PRIpte
@@ -1310,7 +1314,7 @@ static int mod_l1_entry(l1_pgentry_t *pl
if ( unlikely(__copy_from_user(&ol1e, pl1e, sizeof(ol1e)) != 0) )
return 0;
- if ( unlikely(shadow_mode_refcounts(d)) )
+ if ( unlikely(paging_mode_refcounts(d)) )
return UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, current);
if ( l1e_get_flags(nl1e) & _PAGE_PRESENT )
@@ -1572,7 +1576,7 @@ void free_page_type(struct page_info *pa
*/
queue_deferred_ops(owner, DOP_FLUSH_ALL_TLBS);
- if ( unlikely(shadow_mode_enabled(owner)) )
+ if ( unlikely(paging_mode_enabled(owner)) )
{
/* A page table is dirtied when its type count becomes zero. */
mark_dirty(owner, page_to_mfn(page));
@@ -1771,7 +1775,7 @@ int new_guest_cr3(unsigned long mfn)
#ifdef CONFIG_COMPAT
if ( IS_COMPAT(d) )
{
- okay = shadow_mode_refcounts(d)
+ okay = paging_mode_refcounts(d)
? 0 /* Old code was broken, but what should it be? */
: mod_l4_entry(__va(pagetable_get_paddr(v->arch.guest_table)),
l4e_from_pfn(mfn, (_PAGE_PRESENT|_PAGE_RW|
@@ -1788,7 +1792,7 @@ int new_guest_cr3(unsigned long mfn)
return 1;
}
#endif
- okay = shadow_mode_refcounts(d)
+ okay = paging_mode_refcounts(d)
? get_page_from_pagenr(mfn, d)
: get_page_and_type_from_pagenr(mfn, PGT_root_page_table, d);
if ( unlikely(!okay) )
@@ -1808,7 +1812,7 @@ int new_guest_cr3(unsigned long mfn)
if ( likely(old_base_mfn != 0) )
{
- if ( shadow_mode_refcounts(d) )
+ if ( paging_mode_refcounts(d) )
put_page(mfn_to_page(old_base_mfn));
else
put_page_and_type(mfn_to_page(old_base_mfn));
@@ -1861,7 +1865,7 @@ static int set_foreigndom(domid_t domid)
d->domain_id);
okay = 0;
}
- else if ( unlikely(shadow_mode_translate(d)) )
+ else if ( unlikely(paging_mode_translate(d)) )
{
MEM_LOG("Cannot mix foreign mappings with translated domains");
okay = 0;
@@ -2007,7 +2011,7 @@ int do_mmuext_op(
if ( (op.cmd - MMUEXT_PIN_L1_TABLE) > (CONFIG_PAGING_LEVELS - 1) )
break;
- if ( shadow_mode_refcounts(FOREIGNDOM) )
+ if ( paging_mode_refcounts(FOREIGNDOM) )
break;
okay = get_page_and_type_from_pagenr(mfn, type, FOREIGNDOM);
@@ -2032,7 +2036,7 @@ int do_mmuext_op(
break;
case MMUEXT_UNPIN_TABLE:
- if ( shadow_mode_refcounts(d) )
+ if ( paging_mode_refcounts(d) )
break;
if ( unlikely(!(okay = get_page_from_pagenr(mfn, d))) )
@@ -2070,7 +2074,7 @@ int do_mmuext_op(
}
if (likely(mfn != 0))
{
- if ( shadow_mode_refcounts(d) )
+ if ( paging_mode_refcounts(d) )
okay = get_page_from_pagenr(mfn, d);
else
okay = get_page_and_type_from_pagenr(
@@ -2087,7 +2091,7 @@ int do_mmuext_op(
v->arch.guest_table_user = pagetable_from_pfn(mfn);
if ( old_mfn != 0 )
{
- if ( shadow_mode_refcounts(d) )
+ if ( paging_mode_refcounts(d) )
put_page(mfn_to_page(old_mfn));
else
put_page_and_type(mfn_to_page(old_mfn));
@@ -2101,8 +2105,8 @@ int do_mmuext_op(
break;
case MMUEXT_INVLPG_LOCAL:
- if ( !shadow_mode_enabled(d)
- || shadow_invlpg(v, op.arg1.linear_addr) != 0 )
+ if ( !paging_mode_enabled(d)
+ || paging_invlpg(v, op.arg1.linear_addr) != 0 )
local_flush_tlb_one(op.arg1.linear_addr);
break;
@@ -2149,7 +2153,7 @@ int do_mmuext_op(
unsigned long ptr = op.arg1.linear_addr;
unsigned long ents = op.arg2.nr_ents;
- if ( shadow_mode_external(d) )
+ if ( paging_mode_external(d) )
{
MEM_LOG("ignoring SET_LDT hypercall from external "
"domain %u", d->domain_id);
@@ -2298,9 +2302,9 @@ int do_mmu_update(
case PGT_l3_page_table:
case PGT_l4_page_table:
{
- if ( shadow_mode_refcounts(d) )
+ if ( paging_mode_refcounts(d) )
{
- MEM_LOG("mmu update on shadow-refcounted domain!");
+ MEM_LOG("mmu update on auto-refcounted domain!");
break;
}
@@ -2351,13 +2355,7 @@ int do_mmu_update(
if ( unlikely(!get_page_type(page, PGT_writable_page)) )
break;
- if ( unlikely(shadow_mode_enabled(d)) )
- okay = shadow_write_guest_entry(v, va, req.val, _mfn(mfn));
- else
- {
- *(intpte_t *)va = req.val;
- okay = 1;
- }
+ okay = paging_write_guest_entry(v, va, req.val, _mfn(mfn));
put_page_type(page);
}
@@ -2380,9 +2378,9 @@ int do_mmu_update(
break;
}
- if ( unlikely(shadow_mode_translate(FOREIGNDOM)) )
+ if ( unlikely(paging_mode_translate(FOREIGNDOM)) )
{
- MEM_LOG("Mach-phys update on shadow-translate guest");
+ MEM_LOG("Mach-phys update on auto-translate guest");
break;
}
@@ -2472,7 +2470,7 @@ static int create_grant_pte_mapping(
goto failed;
}
- if ( !shadow_mode_refcounts(d) )
+ if ( !paging_mode_refcounts(d) )
put_page_from_l1e(ol1e, d);
put_page_type(page);
@@ -2578,7 +2576,7 @@ static int create_grant_va_mapping(
if ( !okay )
return GNTST_general_error;
- if ( !shadow_mode_refcounts(d) )
+ if ( !paging_mode_refcounts(d) )
put_page_from_l1e(ol1e, d);
return GNTST_okay;
@@ -2704,7 +2702,7 @@ int do_update_va_mapping(unsigned long v
perfc_incrc(calls_to_update_va);
- if ( unlikely(!__addr_ok(va) && !shadow_mode_external(d)) )
+ if ( unlikely(!__addr_ok(va) && !paging_mode_external(d)) )
return -EINVAL;
LOCK_BIGLOCK(d);
@@ -2744,8 +2742,8 @@ int do_update_va_mapping(unsigned long v
switch ( (bmap_ptr = flags & ~UVMF_FLUSHTYPE_MASK) )
{
case UVMF_LOCAL:
- if ( !shadow_mode_enabled(d)
- || (shadow_invlpg(current, va) != 0) )
+ if ( !paging_mode_enabled(d)
+ || (paging_invlpg(current, va) != 0) )
local_flush_tlb_one(va);
break;
case UVMF_ALL:
@@ -2980,7 +2978,7 @@ long arch_memory_op(int op, XEN_GUEST_HA
break;
}
- if ( !shadow_mode_translate(d) || (mfn == 0) )
+ if ( !paging_mode_translate(d) || (mfn == 0) )
{
put_domain(d);
return -EINVAL;
@@ -3235,17 +3233,12 @@ static int ptwr_emulated_update(
if ( do_cmpxchg )
{
int okay;
+ intpte_t t = old;
ol1e = l1e_from_intpte(old);
- if ( shadow_mode_enabled(d) )
- {
- intpte_t t = old;
- okay = shadow_cmpxchg_guest_entry(v, (intpte_t *) pl1e,
- &t, val, _mfn(mfn));
- okay = (okay && t == old);
- }
- else
- okay = (cmpxchg((intpte_t *)pl1e, old, val) == old);
+ okay = paging_cmpxchg_guest_entry(v, (intpte_t *) pl1e,
+ &t, val, _mfn(mfn));
+ okay = (okay && t == old);
if ( !okay )
{
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/mm/Makefile
--- a/xen/arch/x86/mm/Makefile Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/mm/Makefile Wed Feb 14 19:01:35 2007 +0000
@@ -1,1 +1,4 @@ subdir-y += shadow
subdir-y += shadow
+
+obj-y += paging.o
+obj-y += p2m.o
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/mm/p2m.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/mm/p2m.c Wed Feb 14 19:01:35 2007 +0000
@@ -0,0 +1,699 @@
+/******************************************************************************
+ * arch/x86/mm/p2m.c
+ *
+ * physical-to-machine mappings for automatically-translated domains.
+ *
+ * Parts of this code are Copyright (c) 2007 by Advanced Micro Devices.
+ * Parts of this code are Copyright (c) 2006 by XenSource Inc.
+ * Parts of this code are Copyright (c) 2006 by Michael A Fetterman
+ * Parts based on earlier work by Michael A Fetterman, Ian Pratt et al.
+ *
+ * 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 <asm/domain.h>
+#include <asm/page.h>
+#include <asm/paging.h>
+#include <asm/p2m.h>
+
+/* Debugging and auditing of the P2M code? */
+#define P2M_AUDIT 0
+#define P2M_DEBUGGING 1
+
+/* The P2M lock. This protects all updates to the p2m table.
+ * Updates are expected to be safe against concurrent reads,
+ * which do *not* require the lock */
+
+#define p2m_lock_init(_d) \
+ do { \
+ spin_lock_init(&(_d)->arch.p2m.lock); \
+ (_d)->arch.p2m.locker = -1; \
+ (_d)->arch.p2m.locker_function = "nobody"; \
+ } while (0)
+
+#define p2m_lock(_d) \
+ do { \
+ if ( unlikely((_d)->arch.p2m.locker == current->processor) )\
+ { \
+ printk("Error: p2m lock held by %s\n", \
+ (_d)->arch.p2m.locker_function); \
+ BUG(); \
+ } \
+ spin_lock(&(_d)->arch.p2m.lock); \
+ ASSERT((_d)->arch.p2m.locker == -1); \
+ (_d)->arch.p2m.locker = current->processor; \
+ (_d)->arch.p2m.locker_function = __func__; \
+ } while (0)
+
+#define p2m_unlock(_d) \
+ do { \
+ ASSERT((_d)->arch.p2m.locker == current->processor); \
+ (_d)->arch.p2m.locker = -1; \
+ (_d)->arch.p2m.locker_function = "nobody"; \
+ spin_unlock(&(_d)->arch.p2m.lock); \
+ } while (0)
+
+
+
+/* Printouts */
+#define P2M_PRINTK(_f, _a...) \
+ debugtrace_printk("p2m: %s(): " _f, __func__, ##_a)
+#define P2M_ERROR(_f, _a...) \
+ printk("pg error: %s(): " _f, __func__, ##_a)
+#if P2M_DEBUGGING
+#define P2M_DEBUG(_f, _a...) \
+ debugtrace_printk("p2mdebug: %s(): " _f, __func__, ##_a)
+#else
+#define P2M_DEBUG(_f, _a...) do { (void)(_f); } while(0)
+#endif
+
+
+/* Override macros from asm/page.h to make them work with mfn_t */
+#undef mfn_to_page
+#define mfn_to_page(_m) (frame_table + mfn_x(_m))
+#undef mfn_valid
+#define mfn_valid(_mfn) (mfn_x(_mfn) < max_page)
+#undef page_to_mfn
+#define page_to_mfn(_pg) (_mfn((_pg) - frame_table))
+
+
+
+// Find the next level's P2M entry, checking for out-of-range gfn's...
+// Returns NULL on error.
+//
+static l1_pgentry_t *
+p2m_find_entry(void *table, unsigned long *gfn_remainder,
+ unsigned long gfn, u32 shift, u32 max)
+{
+ u32 index;
+
+ index = *gfn_remainder >> shift;
+ if ( index >= max )
+ {
+ P2M_DEBUG("gfn=0x%lx out of range "
+ "(gfn_remainder=0x%lx shift=%d index=0x%x max=0x%x)\n",
+ gfn, *gfn_remainder, shift, index, max);
+ return NULL;
+ }
+ *gfn_remainder &= (1 << shift) - 1;
+ return (l1_pgentry_t *)table + index;
+}
+
+// Walk one level of the P2M table, allocating a new table if required.
+// Returns 0 on error.
+//
+static int
+p2m_next_level(struct domain *d, mfn_t *table_mfn, void **table,
+ unsigned long *gfn_remainder, unsigned long gfn, u32 shift,
+ u32 max, unsigned long type)
+{
+ l1_pgentry_t *p2m_entry;
+ l1_pgentry_t new_entry;
+ void *next;
+ ASSERT(d->arch.p2m.alloc_page);
+
+ if ( !(p2m_entry = p2m_find_entry(*table, gfn_remainder, gfn,
+ shift, max)) )
+ return 0;
+
+ if ( !(l1e_get_flags(*p2m_entry) & _PAGE_PRESENT) )
+ {
+ struct page_info *pg = d->arch.p2m.alloc_page(d);
+ if ( pg == NULL )
+ return 0;
+ list_add_tail(&pg->list, &d->arch.p2m.pages);
+ pg->u.inuse.type_info = type | 1 | PGT_validated;
+ pg->count_info = 1;
+
+ new_entry = l1e_from_pfn(mfn_x(page_to_mfn(pg)),
+ __PAGE_HYPERVISOR|_PAGE_USER);
+
+ switch ( type ) {
+ case PGT_l3_page_table:
+ paging_write_p2m_entry(d, gfn, p2m_entry, new_entry, 4);
+ break;
+ case PGT_l2_page_table:
+ paging_write_p2m_entry(d, gfn, p2m_entry, new_entry, 3);
+ break;
+ case PGT_l1_page_table:
+ paging_write_p2m_entry(d, gfn, p2m_entry, new_entry, 2);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ }
+ *table_mfn = _mfn(l1e_get_pfn(*p2m_entry));
+ next = map_domain_page(mfn_x(*table_mfn));
+ unmap_domain_page(*table);
+ *table = next;
+
+ return 1;
+}
+
+// Returns 0 on error (out of memory)
+static int
+set_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn)
+{
+ // XXX -- this might be able to be faster iff current->domain == d
+ mfn_t table_mfn = pagetable_get_mfn(d->arch.phys_table);
+ void *table =map_domain_page(mfn_x(table_mfn));
+ unsigned long gfn_remainder = gfn;
+ l1_pgentry_t *p2m_entry;
+ l1_pgentry_t entry_content;
+ int rv=0;
+
+#if CONFIG_PAGING_LEVELS >= 4
+ if ( !p2m_next_level(d, &table_mfn, &table, &gfn_remainder, gfn,
+ L4_PAGETABLE_SHIFT - PAGE_SHIFT,
+ L4_PAGETABLE_ENTRIES, PGT_l3_page_table) )
+ goto out;
+#endif
+#if CONFIG_PAGING_LEVELS >= 3
+ // When using PAE Xen, we only allow 33 bits of pseudo-physical
+ // address in translated guests (i.e. 8 GBytes). This restriction
+ // comes from wanting to map the P2M table into the 16MB RO_MPT hole
+ // in Xen's address space for translated PV guests.
+ //
+ if ( !p2m_next_level(d, &table_mfn, &table, &gfn_remainder, gfn,
+ L3_PAGETABLE_SHIFT - PAGE_SHIFT,
+ (CONFIG_PAGING_LEVELS == 3
+ ? 8
+ : L3_PAGETABLE_ENTRIES),
+ PGT_l2_page_table) )
+ goto out;
+#endif
+ if ( !p2m_next_level(d, &table_mfn, &table, &gfn_remainder, gfn,
+ L2_PAGETABLE_SHIFT - PAGE_SHIFT,
+ L2_PAGETABLE_ENTRIES, PGT_l1_page_table) )
+ goto out;
+
+ p2m_entry = p2m_find_entry(table, &gfn_remainder, gfn,
+ 0, L1_PAGETABLE_ENTRIES);
+ ASSERT(p2m_entry);
+
+ /* Track the highest gfn for which we have ever had a valid mapping */
+ if ( mfn_valid(mfn) && (gfn > d->arch.p2m.max_mapped_pfn) )
+ d->arch.p2m.max_mapped_pfn = gfn;
+
+ if ( mfn_valid(mfn) )
+ entry_content = l1e_from_pfn(mfn_x(mfn), __PAGE_HYPERVISOR|_PAGE_USER);
+ else
+ entry_content = l1e_empty();
+
+ /* level 1 entry */
+ paging_write_p2m_entry(d, gfn, p2m_entry, entry_content, 1);
+
+ /* Success */
+ rv = 1;
+
+ out:
+ unmap_domain_page(table);
+ return rv;
+}
+
+
+/* Init the datastructures for later use by the p2m code */
+void p2m_init(struct domain *d)
+{
+ p2m_lock_init(d);
+ INIT_LIST_HEAD(&d->arch.p2m.pages);
+}
+
+
+// Allocate a new p2m table for a domain.
+//
+// The structure of the p2m table is that of a pagetable for xen (i.e. it is
+// controlled by CONFIG_PAGING_LEVELS).
+//
+// The alloc_page and free_page functions will be used to get memory to
+// build the p2m, and to release it again at the end of day.
+//
+// Returns 0 for success or -errno.
+//
+int p2m_alloc_table(struct domain *d,
+ struct page_info * (*alloc_page)(struct domain *d),
+ void (*free_page)(struct domain *d, struct page_info *pg))
+
+{
+ mfn_t mfn;
+ struct list_head *entry;
+ struct page_info *page, *p2m_top;
+ unsigned int page_count = 0;
+ unsigned long gfn;
+
+ p2m_lock(d);
+
+ if ( pagetable_get_pfn(d->arch.phys_table) != 0 )
+ {
+ P2M_ERROR("p2m already allocated for this domain\n");
+ p2m_unlock(d);
+ return -EINVAL;
+ }
+
+ P2M_PRINTK("allocating p2m table\n");
+
+ d->arch.p2m.alloc_page = alloc_page;
+ d->arch.p2m.free_page = free_page;
+
+ p2m_top = d->arch.p2m.alloc_page(d);
+ if ( p2m_top == NULL )
+ {
+ p2m_unlock(d);
+ return -ENOMEM;
+ }
+list_add_tail(&p2m_top->list, &d->arch.p2m.pages);
+
+ p2m_top->count_info = 1;
+ p2m_top->u.inuse.type_info =
+#if CONFIG_PAGING_LEVELS == 4
+ PGT_l4_page_table
+#elif CONFIG_PAGING_LEVELS == 3
+ PGT_l3_page_table
+#elif CONFIG_PAGING_LEVELS == 2
+ PGT_l2_page_table
+#endif
+ | 1 | PGT_validated;
+
+ d->arch.phys_table = pagetable_from_mfn(page_to_mfn(p2m_top));
+
+ P2M_PRINTK("populating p2m table\n");
+
+ /* Initialise physmap tables for slot zero. Other code assumes this. */
+ gfn = 0;
+mfn = _mfn(INVALID_MFN);
+ if ( !set_p2m_entry(d, gfn, mfn) )
+ goto error;
+
+ for ( entry = d->page_list.next;
+ entry != &d->page_list;
+ entry = entry->next )
+ {
+ page = list_entry(entry, struct page_info, list);
+ mfn = page_to_mfn(page);
+ gfn = get_gpfn_from_mfn(mfn_x(mfn));
+ page_count++;
+ if (
+#ifdef __x86_64__
+ (gfn != 0x5555555555555555L)
+#else
+ (gfn != 0x55555555L)
+#endif
+ && gfn != INVALID_M2P_ENTRY
+ && !set_p2m_entry(d, gfn, mfn) )
+ goto error;
+ }
+
+ P2M_PRINTK("p2m table initialised (%u pages)\n", page_count);
+ p2m_unlock(d);
+ return 0;
+
+ error:
+ P2M_PRINTK("failed to initialize p2m table, gfn=%05lx, mfn=%"
+ PRI_mfn "\n", gfn, mfn_x(mfn));
+ p2m_unlock(d);
+ return -ENOMEM;
+}
+
+void p2m_teardown(struct domain *d)
+/* Return all the p2m pages to Xen.
+ * We know we don't have any extra mappings to these pages */
+{
+ struct list_head *entry, *n;
+ struct page_info *pg;
+
+ p2m_lock(d);
+ d->arch.phys_table = pagetable_null();
+
+ list_for_each_safe(entry, n, &d->arch.p2m.pages)
+ {
+ pg = list_entry(entry, struct page_info, list);
+ list_del(entry);
+ d->arch.p2m.free_page(d, pg);
+ }
+ p2m_unlock(d);
+}
+
+mfn_t
+gfn_to_mfn_foreign(struct domain *d, unsigned long gpfn)
+/* Read another domain's p2m entries */
+{
+ mfn_t mfn;
+ paddr_t addr = ((paddr_t)gpfn) << PAGE_SHIFT;
+ l2_pgentry_t *l2e;
+ l1_pgentry_t *l1e;
+
+ ASSERT(paging_mode_translate(d));
+ mfn = pagetable_get_mfn(d->arch.phys_table);
+
+
+ if ( gpfn > d->arch.p2m.max_mapped_pfn )
+ /* This pfn is higher than the highest the p2m map currently holds */
+ return _mfn(INVALID_MFN);
+
+#if CONFIG_PAGING_LEVELS >= 4
+ {
+ l4_pgentry_t *l4e = map_domain_page(mfn_x(mfn));
+ l4e += l4_table_offset(addr);
+ if ( (l4e_get_flags(*l4e) & _PAGE_PRESENT) == 0 )
+ {
+ unmap_domain_page(l4e);
+ return _mfn(INVALID_MFN);
+ }
+ mfn = _mfn(l4e_get_pfn(*l4e));
+ unmap_domain_page(l4e);
+ }
+#endif
+#if CONFIG_PAGING_LEVELS >= 3
+ {
+ l3_pgentry_t *l3e = map_domain_page(mfn_x(mfn));
+#if CONFIG_PAGING_LEVELS == 3
+ /* On PAE hosts the p2m has eight l3 entries, not four (see
+ * shadow_set_p2m_entry()) so we can't use l3_table_offset.
+ * Instead, just count the number of l3es from zero. It's safe
+ * to do this because we already checked that the gfn is within
+ * the bounds of the p2m. */
+ l3e += (addr >> L3_PAGETABLE_SHIFT);
+#else
+ l3e += l3_table_offset(addr);
+#endif
+ if ( (l3e_get_flags(*l3e) & _PAGE_PRESENT) == 0 )
+ {
+ unmap_domain_page(l3e);
+ return _mfn(INVALID_MFN);
+ }
+ mfn = _mfn(l3e_get_pfn(*l3e));
+ unmap_domain_page(l3e);
+ }
+#endif
+
+ l2e = map_domain_page(mfn_x(mfn));
+ l2e += l2_table_offset(addr);
+ if ( (l2e_get_flags(*l2e) & _PAGE_PRESENT) == 0 )
+ {
+ unmap_domain_page(l2e);
+ return _mfn(INVALID_MFN);
+ }
+ mfn = _mfn(l2e_get_pfn(*l2e));
+ unmap_domain_page(l2e);
+
+ l1e = map_domain_page(mfn_x(mfn));
+ l1e += l1_table_offset(addr);
+ if ( (l1e_get_flags(*l1e) & _PAGE_PRESENT) == 0 )
+ {
+ unmap_domain_page(l1e);
+ return _mfn(INVALID_MFN);
+ }
+ mfn = _mfn(l1e_get_pfn(*l1e));
+ unmap_domain_page(l1e);
+
+ return mfn;
+}
+
+#if P2M_AUDIT
+static void audit_p2m(struct domain *d)
+{
+ struct list_head *entry;
+ struct page_info *page;
+ struct domain *od;
+ unsigned long mfn, gfn, m2pfn, lp2mfn = 0;
+ mfn_t p2mfn;
+ unsigned long orphans_d = 0, orphans_i = 0, mpbad = 0, pmbad = 0;
+ int test_linear;
+
+ if ( !paging_mode_translate(d) )
+ return;
+
+ //P2M_PRINTK("p2m audit starts\n");
+
+ test_linear = ( (d == current->domain)
+ && !pagetable_is_null(current->arch.monitor_table) );
+ if ( test_linear )
+ local_flush_tlb();
+
+ /* Audit part one: walk the domain's page allocation list, checking
+ * the m2p entries. */
+ for ( entry = d->page_list.next;
+ entry != &d->page_list;
+ entry = entry->next )
+ {
+ page = list_entry(entry, struct page_info, list);
+ mfn = mfn_x(page_to_mfn(page));
+
+ // P2M_PRINTK("auditing guest page, mfn=%#lx\n", mfn);
+
+ od = page_get_owner(page);
+
+ if ( od != d )
+ {
+ P2M_PRINTK("wrong owner %#lx -> %p(%u) != %p(%u)\n",
+ mfn, od, (od?od->domain_id:-1), d, d->domain_id);
+ continue;
+ }
+
+ gfn = get_gpfn_from_mfn(mfn);
+ if ( gfn == INVALID_M2P_ENTRY )
+ {
+ orphans_i++;
+ //P2M_PRINTK("orphaned guest page: mfn=%#lx has invalid gfn\n",
+ // mfn);
+ continue;
+ }
+
+ if ( gfn == 0x55555555 )
+ {
+ orphans_d++;
+ //P2M_PRINTK("orphaned guest page: mfn=%#lx has debug gfn\n",
+ // mfn);
+ continue;
+ }
+
+ p2mfn = gfn_to_mfn_foreign(d, gfn);
+ if ( mfn_x(p2mfn) != mfn )
+ {
+ mpbad++;
+ P2M_PRINTK("map mismatch mfn %#lx -> gfn %#lx -> mfn %#lx"
+ " (-> gfn %#lx)\n",
+ mfn, gfn, mfn_x(p2mfn),
+ (mfn_valid(p2mfn)
+ ? get_gpfn_from_mfn(mfn_x(p2mfn))
+ : -1u));
+ /* This m2p entry is stale: the domain has another frame in
+ * this physical slot. No great disaster, but for neatness,
+ * blow away the m2p entry. */
+ set_gpfn_from_mfn(mfn, INVALID_M2P_ENTRY);
+ }
+
+ if ( test_linear && (gfn <= d->arch.p2m.max_mapped_pfn) )
+ {
+ lp2mfn = mfn_x(gfn_to_mfn_current(gfn));
+ if ( lp2mfn != mfn_x(p2mfn) )
+ {
+ P2M_PRINTK("linear mismatch gfn %#lx -> mfn %#lx "
+ "(!= mfn %#lx)\n", gfn, lp2mfn, mfn_x(p2mfn));
+ }
+ }
+
+ // P2M_PRINTK("OK: mfn=%#lx, gfn=%#lx, p2mfn=%#lx, lp2mfn=%#lx\n",
+ // mfn, gfn, p2mfn, lp2mfn);
+ }
+
+ /* Audit part two: walk the domain's p2m table, checking the entries. */
+ if ( pagetable_get_pfn(d->arch.phys_table) != 0 )
+ {
+ l2_pgentry_t *l2e;
+ l1_pgentry_t *l1e;
+ int i1, i2;
+
+#if CONFIG_PAGING_LEVELS == 4
+ l4_pgentry_t *l4e;
+ l3_pgentry_t *l3e;
+ int i3, i4;
+ l4e = map_domain_page(mfn_x(pagetable_get_mfn(d->arch.phys_table)));
+#elif CONFIG_PAGING_LEVELS == 3
+ l3_pgentry_t *l3e;
+ int i3;
+ l3e = map_domain_page(mfn_x(pagetable_get_mfn(d->arch.phys_table)));
+#else /* CONFIG_PAGING_LEVELS == 2 */
+ l2e = map_domain_page(mfn_x(pagetable_get_mfn(d->arch.phys_table)));
+#endif
+
+ gfn = 0;
+#if CONFIG_PAGING_LEVELS >= 3
+#if CONFIG_PAGING_LEVELS >= 4
+ for ( i4 = 0; i4 < L4_PAGETABLE_ENTRIES; i4++ )
+ {
+ if ( !(l4e_get_flags(l4e[i4]) & _PAGE_PRESENT) )
+ {
+ gfn += 1 << (L4_PAGETABLE_SHIFT - PAGE_SHIFT);
+ continue;
+ }
+ l3e = map_domain_page(mfn_x(_mfn(l4e_get_pfn(l4e[i4]))));
+#endif /* now at levels 3 or 4... */
+ for ( i3 = 0;
+ i3 < ((CONFIG_PAGING_LEVELS==4) ? L3_PAGETABLE_ENTRIES : 8);
+ i3++ )
+ {
+ if ( !(l3e_get_flags(l3e[i3]) & _PAGE_PRESENT) )
+ {
+ gfn += 1 << (L3_PAGETABLE_SHIFT - PAGE_SHIFT);
+ continue;
+ }
+ l2e = map_domain_page(mfn_x(_mfn(l3e_get_pfn(l3e[i3]))));
+#endif /* all levels... */
+ for ( i2 = 0; i2 < L2_PAGETABLE_ENTRIES; i2++ )
+ {
+ if ( !(l2e_get_flags(l2e[i2]) & _PAGE_PRESENT) )
+ {
+ gfn += 1 << (L2_PAGETABLE_SHIFT - PAGE_SHIFT);
+ continue;
+ }
+ l1e = map_domain_page(mfn_x(_mfn(l2e_get_pfn(l2e[i2]))));
+
+ for ( i1 = 0; i1 < L1_PAGETABLE_ENTRIES; i1++, gfn++ )
+ {
+ if ( !(l1e_get_flags(l1e[i1]) & _PAGE_PRESENT) )
+ continue;
+ mfn = l1e_get_pfn(l1e[i1]);
+ ASSERT(mfn_valid(_mfn(mfn)));
+ m2pfn = get_gpfn_from_mfn(mfn);
+ if ( m2pfn != gfn )
+ {
+ pmbad++;
+ P2M_PRINTK("mismatch: gfn %#lx -> mfn %#lx"
+ " -> gfn %#lx\n", gfn, mfn, m2pfn);
+ BUG();
+ }
+ }
+ unmap_domain_page(l1e);
+ }
+#if CONFIG_PAGING_LEVELS >= 3
+ unmap_domain_page(l2e);
+ }
+#if CONFIG_PAGING_LEVELS >= 4
+ unmap_domain_page(l3e);
+ }
+#endif
+#endif
+
+#if CONFIG_PAGING_LEVELS == 4
+ unmap_domain_page(l4e);
+#elif CONFIG_PAGING_LEVELS == 3
+ unmap_domain_page(l3e);
+#else /* CONFIG_PAGING_LEVELS == 2 */
+ unmap_domain_page(l2e);
+#endif
+
+ }
+
+ //P2M_PRINTK("p2m audit complete\n");
+ //if ( orphans_i | orphans_d | mpbad | pmbad )
+ // P2M_PRINTK("p2m audit found %lu orphans (%lu inval %lu debug)\n",
+ // orphans_i + orphans_d, orphans_i, orphans_d,
+ if ( mpbad | pmbad )
+ P2M_PRINTK("p2m audit found %lu odd p2m, %lu bad m2p entries\n",
+ pmbad, mpbad);
+}
+#else
+#define audit_p2m(_d) do { (void)(_d); } while(0)
+#endif /* P2M_AUDIT */
+
+
+
+static void
+p2m_remove_page(struct domain *d, unsigned long gfn, unsigned long mfn)
+{
+ if ( !paging_mode_translate(d) )
+ return;
+ P2M_DEBUG("removing gfn=%#lx mfn=%#lx\n", gfn, mfn);
+
+ ASSERT(mfn_x(gfn_to_mfn(d, gfn)) == mfn);
+ //ASSERT(mfn_to_gfn(d, mfn) == gfn);
+
+ set_p2m_entry(d, gfn, _mfn(INVALID_MFN));
+ set_gpfn_from_mfn(mfn, INVALID_M2P_ENTRY);
+}
+
+void
+guest_physmap_remove_page(struct domain *d, unsigned long gfn,
+ unsigned long mfn)
+{
+ p2m_lock(d);
+ audit_p2m(d);
+ p2m_remove_page(d, gfn, mfn);
+ audit_p2m(d);
+ p2m_unlock(d);
+}
+
+void
+guest_physmap_add_page(struct domain *d, unsigned long gfn,
+ unsigned long mfn)
+{
+ unsigned long ogfn;
+ mfn_t omfn;
+
+ if ( !paging_mode_translate(d) )
+ return;
+
+ p2m_lock(d);
+ audit_p2m(d);
+
+ P2M_DEBUG("adding gfn=%#lx mfn=%#lx\n", gfn, mfn);
+
+ omfn = gfn_to_mfn(d, gfn);
+ if ( mfn_valid(omfn) )
+ {
+ set_p2m_entry(d, gfn, _mfn(INVALID_MFN));
+ set_gpfn_from_mfn(mfn_x(omfn), INVALID_M2P_ENTRY);
+ }
+
+ ogfn = mfn_to_gfn(d, _mfn(mfn));
+ if (
+#ifdef __x86_64__
+ (ogfn != 0x5555555555555555L)
+#else
+ (ogfn != 0x55555555L)
+#endif
+ && (ogfn != INVALID_M2P_ENTRY)
+ && (ogfn != gfn) )
+ {
+ /* This machine frame is already mapped at another physical address */
+ P2M_DEBUG("aliased! mfn=%#lx, old gfn=%#lx, new gfn=%#lx\n",
+ mfn, ogfn, gfn);
+ if ( mfn_valid(omfn = gfn_to_mfn(d, ogfn)) )
+ {
+ P2M_DEBUG("old gfn=%#lx -> mfn %#lx\n",
+ ogfn , mfn_x(omfn));
+ if ( mfn_x(omfn) == mfn )
+ p2m_remove_page(d, ogfn, mfn);
+ }
+ }
+
+ set_p2m_entry(d, gfn, _mfn(mfn));
+ set_gpfn_from_mfn(mfn, gfn);
+
+ audit_p2m(d);
+ p2m_unlock(d);
+}
+
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/mm/paging.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/mm/paging.c Wed Feb 14 19:01:35 2007 +0000
@@ -0,0 +1,143 @@
+/******************************************************************************
+ * arch/x86/paging.c
+ *
+ * x86 specific paging support
+ * Copyright (c) 2007 Advanced Micro Devices (Wei Huang)
+ * Copyright (c) 2007 XenSource Inc.
+ *
+ * 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/init.h>
+#include <asm/paging.h>
+#include <asm/shadow.h>
+#include <asm/p2m.h>
+
+/* Xen command-line option to enable hardware-assisted paging */
+int opt_hap_enabled = 0;
+boolean_param("hap", opt_hap_enabled);
+
+/* Printouts */
+#define PAGING_PRINTK(_f, _a...) \
+ debugtrace_printk("pg: %s(): " _f, __func__, ##_a)
+#define PAGING_ERROR(_f, _a...) \
+ printk("pg error: %s(): " _f, __func__, ##_a)
+#define PAGING_DEBUG(flag, _f, _a...) \
+ do { \
+ if (PAGING_DEBUG_ ## flag) \
+ debugtrace_printk("pgdebug: %s(): " _f, __func__, ##_a); \
+ } while (0)
+
+
+/* Domain paging struct initialization. */
+void paging_domain_init(struct domain *d)
+{
+ p2m_init(d);
+ shadow_domain_init(d);
+}
+
+/* vcpu paging struct initialization goes here */
+void paging_vcpu_init(struct vcpu *v)
+{
+ shadow_vcpu_init(v);
+}
+
+
+int paging_domctl(struct domain *d, xen_domctl_shadow_op_t *sc,
+ XEN_GUEST_HANDLE(void) u_domctl)
+{
+ /* Here, dispatch domctl to the appropriate paging code */
+ return shadow_domctl(d, sc, u_domctl);
+}
+
+/* Call when destroying a domain */
+void paging_teardown(struct domain *d)
+{
+ shadow_teardown(d);
+ /* Call other modes' teardown code here */
+}
+
+/* Call once all of the references to the domain have gone away */
+void paging_final_teardown(struct domain *d)
+{
+ shadow_teardown(d);
+ /* Call other modes' final teardown code here */
+}
+
+/* Enable an arbitrary paging-assistance mode. Call once at domain
+ * creation. */
+int paging_enable(struct domain *d, u32 mode)
+{
+ if ( mode & PG_SH_enable )
+ return shadow_enable(d, mode);
+ else
+ /* No other modes supported yet */
+ return -EINVAL;
+}
+
+/* Print paging-assistance info to the console */
+void paging_dump_domain_info(struct domain *d)
+{
+ if ( paging_mode_enabled(d) )
+ {
+ printk(" paging assistance: ");
+ if ( paging_mode_shadow(d) )
+ printk("shadow ");
+ if ( paging_mode_hap(d) )
+ printk("hap ");
+ if ( paging_mode_refcounts(d) )
+ printk("refcounts ");
+ if ( paging_mode_log_dirty(d) )
+ printk("log_dirty ");
+ if ( paging_mode_translate(d) )
+ printk("translate ");
+ if ( paging_mode_external(d) )
+ printk("external ");
+ printk("\n");
+ }
+}
+
+void paging_dump_vcpu_info(struct vcpu *v)
+{
+ if ( paging_mode_enabled(v->domain) )
+ {
+ printk(" paging assistance: ");
+ if ( paging_mode_shadow(v->domain) )
+ {
+ if ( v->arch.paging.mode )
+ printk("shadowed %u-on-%u, %stranslated\n",
+ v->arch.paging.mode->guest_levels,
+ v->arch.paging.mode->shadow.shadow_levels,
+ paging_vcpu_mode_translate(v) ? "" : "not ");
+ else
+ printk("not shadowed\n");
+ }
+ else if ( paging_mode_hap(v->domain) && v->arch.paging.mode )
+ printk("hap, %u levels\n",
+ v->arch.paging.mode->guest_levels);
+ else
+ printk("none\n");
+ }
+}
+
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r aea80dbf6d96 -r 9af0c7e4ff51 xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c Fri Feb 09 14:43:22 2007 -0600
+++ b/xen/arch/x86/mm/shadow/common.c Wed Feb 14 19:01:35 2007 +0000
@@ -47,12 +47,27 @@ void shadow_domain_init(struct domain *d
int i;
shadow_lock_init(d);
for ( i = 0; i <= SHADOW_MAX_ORDER; i++ )
- INIT_LIST_HEAD(&d->arch.shadow.freelists[i]);
- INIT_LIST_HEAD(&d->arch.shadow.p2m_freelist);
- INIT_LIST_HEAD(&d->arch.shadow.p2m_inuse);
- INIT_LIST_HEAD(&d->arch.shadow.pinned_shadows);
-}
-
+ INIT_LIST_HEAD(&d->arch.paging.shadow.freelists[i]);
+ INIT_LIST_HEAD(&d->arch.paging.shadow.p2m_freelist);
+ INIT_LIST_HEAD(&d->arch.paging.shadow.pinned_shadows);
+}
+
+/* Setup the shadow-specfic parts of a vcpu struct. Note: The most important
+ * job is to initialize the update_paging_modes() function pointer, which is
+ * used to initialized the rest of resources. Therefore, it really does not
+ * matter to have v->arch.paging.mode pointing to any mode, as long as it can
+ * be compiled.
+ */
+void shadow_vcpu_init(struct vcpu *v)
+{
+#if CONFIG_PAGING_LEVELS == 4
+ v->arch.paging.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,3,3);
+#elif CONFIG_PAGING_LEVELS == 3
+ v->arch.paging.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,3,3);
+#elif CONFIG_PAGING_LEVELS == 2
+ v->arch.paging.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,2,2);
+#endif
+}
#if SHADOW_AUDIT
int shadow_audit_enable = 0;
@@ -265,7 +280,7 @@ hvm_emulate_write(enum x86_segment seg,
if ( rc )
return rc;
- return v->arch.shadow.mode->x86_emulate_write(
+ return v->arch.paging.mode->shadow.x86_emulate_write(
v, addr, &val, bytes, sh_ctxt);
}
@@ -288,7 +303,7 @@ hvm_emulate_cmpxchg(enum x86_segment seg
if ( rc )
return rc;
- return v->arch.shadow.mode->x86_emulate_cmpxchg(
+ return v->arch.paging.mode->shadow.x86_emulate_cmpxchg(
v, addr, old, new, bytes, sh_ctxt);
}
@@ -312,7 +327,7 @@ hvm_emulate_cmpxchg8b(enum x86_segment s
if ( rc )
return rc;
- return v->arch.shadow.mode->x86_emulate_cmpxchg8b(
+ return v->arch.paging.mode->shadow.x86_emulate_cmpxchg8b(
v, addr, old_lo, old_hi, new_lo, new_hi, sh_ctxt);
}
@@ -353,7 +368,7 @@ pv_emulate_write(enum x86_segment seg,
struct sh_emulate_ctxt *sh_ctxt =
container_of(ctxt, struct sh_emulate_ctxt, ctxt);
struct vcpu *v = current;
- return v->arch.shadow.mode->x86_emulate_write(
+ return v->arch.paging.mode->shadow.x86_emulate_write(
v, offset, &val, bytes, sh_ctxt);
}
@@ -368,7 +383,7 @@ pv_emulate_cmpxchg(enum x86_segment seg,
struct sh_emulate_ctxt *sh_ctxt =
container_of(ctxt, struct sh_emulate_ctxt, ctxt);
struct vcpu *v = current;
- return v->arch.shadow.mode->x86_emulate_cmpxchg(
+ return v->arch.paging.mode->shadow.x86_emulate_cmpxchg(
v, offset, old, new, bytes, sh_ctxt);
}
@@ -384,7 +399,7 @@ pv_emulate_cmpxchg8b(enum x86_segment se
struct sh_emulate_ctxt *sh_ctxt =
container_of(ctxt, struct sh_emulate_ctxt, ctxt);
struct vcpu *v = current;
- return v->arch.shadow.mode->x86_emulate_cmpxchg8b(
+ return v->arch.paging.mode->shadow.x86_emulate_cmpxchg8b(
v, offset, old_lo, old_hi, new_lo, new_hi, sh_ctxt);
}
@@ -721,7 +736,7 @@ static inline int chunk_is_available(str
int i;
for ( i = order; i <= SHADOW_MAX_ORDER; i++ )
- if ( !list_empty(&d->arch.shadow.freelists[i]) )
+ if ( !list_empty(&d->arch.paging.shadow.freelists[i]) )
return 1;
return 0;
}
@@ -783,7 +798,7 @@ void shadow_prealloc(struct domain *d, u
/* Stage one: walk the list of pinned pages, unpinning them */
perfc_incrc(shadow_prealloc_1);
- list_for_each_backwards_safe(l, t, &d->arch.shadow.pinned_shadows)
+ list_for_each_backwards_safe(l, t, &d->arch.paging.shadow.pinned_shadows)
{
sp = list_entry(l, struct shadow_page_info, list);
smfn = shadow_page_to_mfn(sp);
@@ -823,9 +838,9 @@ void shadow_prealloc(struct domain *d, u
SHADOW_PRINTK("Can't pre-allocate %i shadow pages!\n"
" shadow pages total = %u, free = %u, p2m=%u\n",
1 << order,
- d->arch.shadow.total_pages,
- d->arch.shadow.free_pages,
- d->arch.shadow.p2m_pages);
+ d->arch.paging.shadow.total_pages,
+ d->arch.paging.shadow.free_pages,
+ d->arch.paging.shadow.p2m_pages);
BUG();
}
@@ -840,7 +855,7 @@ static void shadow_blow_tables(struct do
int i;
/* Pass one: unpin all pinned pages */
- list_for_each_backwards_safe(l,t, &d->arch.shadow.pinned_shadows)
+ list_for_each_backwards_safe(l,t, &d->arch.paging.shadow.pinned_shadows)
{
sp = list_entry(l, struct shadow_page_info, list);
smfn = shadow_page_to_mfn(sp);
@@ -905,9 +920,9 @@ mfn_t shadow_alloc(struct domain *d,
/* Find smallest order which can satisfy the request. */
for ( i = order; i <= SHADOW_MAX_ORDER; i++ )
- if ( !list_empty(&d->arch.shadow.freelists[i]) )
+ if ( !list_empty(&d->arch.paging.shadow.freelists[i]) )
{
- sp = list_entry(d->arch.shadow.freelists[i].next,
+ sp = list_entry(d->arch.paging.shadow.freelists[i].next,
struct shadow_page_info, list);
list_del(&sp->list);
@@ -916,10 +931,10 @@ mfn_t shadow_alloc(struct domain *d,
{
i--;
sp->order = i;
- list_add_tail(&sp->list, &d->arch.shadow.freelists[i]);
+ list_add_tail(&sp->list, &d->arch.paging.shadow.freelists[i]);
sp += 1 << i;
}
- d->arch.shadow.free_pages -= 1 << order;
+ d->arch.paging.shadow.free_pages -= 1 << order;
/* Init page info fields and clear the pages */
for ( i = 0; i < 1<<order ; i++ )
@@ -976,7 +991,7 @@ void shadow_free(struct domain *d, mfn_t
ASSERT(shadow_type != SH_type_p2m_table);
order = shadow_order(shadow_type);
- d->arch.shadow.free_pages += 1 << order;
+ d->arch.paging.shadow.free_pages += 1 << order;
for ( i = 0; i < 1<<order; i++ )
{
@@ -985,8 +1000,8 @@ void shadow_free(struct domain *d, mfn_t
for_each_vcpu(d, v)
{
/* No longer safe to look for a writeable mapping in this shadow */
- if ( v->arch.shadow.last_writeable_pte_smfn == mfn_x(smfn) + i )
- v->arch.shadow.last_writeable_pte_smfn = 0;
+ if ( v->arch.paging.shadow.last_writeable_pte_smfn == mfn_x(smfn)
+ i )
+ v->arch.paging.shadow.last_writeable_pte_smfn = 0;
}
#endif
/* Strip out the type: this is now a free shadow page */
@@ -1019,7 +1034,7 @@ void shadow_free(struct domain *d, mfn_t
}
sp->order = order;
- list_add_tail(&sp->list, &d->arch.shadow.freelists[order]);
+ list_add_tail(&sp->list, &d->arch.paging.shadow.freelists[order]);
}
/* Divert some memory from the pool to be used by the p2m mapping.
@@ -1033,19 +1048,19 @@ void shadow_free(struct domain *d, mfn_t
* returns non-zero on success.
*/
static int
-shadow_alloc_p2m_pages(struct domain *d)
+sh_alloc_p2m_pages(struct domain *d)
{
struct page_info *pg;
u32 i;
ASSERT(shadow_locked_by_me(d));
- if ( d->arch.shadow.total_pages
+ if ( d->arch.paging.shadow.total_pages
< (shadow_min_acceptable_pages(d) + (1<<SHADOW_MAX_ORDER)) )
return 0; /* Not enough shadow memory: need to increase it first */
pg = mfn_to_page(shadow_alloc(d, SH_type_p2m_table, 0));
- d->arch.shadow.p2m_pages += (1<<SHADOW_MAX_ORDER);
- d->arch.shadow.total_pages -= (1<<SHADOW_MAX_ORDER);
+ d->arch.paging.shadow.p2m_pages += (1<<SHADOW_MAX_ORDER);
+ d->arch.paging.shadow.total_pages -= (1<<SHADOW_MAX_ORDER);
for (i = 0; i < (1<<SHADOW_MAX_ORDER); i++)
{
/* Unlike shadow pages, mark p2m pages as owned by the domain.
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|