[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Merge with xenppc-unstable.hg
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |