[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
# HG changeset patch # User awilliam@xxxxxxxxxxx # Node ID e74c47d073ee9f9392540576e53508f9c5b16a65 # Parent b8f6089cbce30c79809d5e00888b92007f3a9153 # Parent 912588576817fddae490a9bea71c58d2f8ea9802 merge with xen-unstable.hg --- linux-2.6-xen-sparse/arch/ia64/xen/drivers/Makefile | 21 linux-2.6-xen-sparse/arch/ia64/xen/drivers/README | 2 linux-2.6-xen-sparse/arch/ia64/xen/drivers/coreMakefile | 19 linux-2.6-xen-sparse/drivers/xen/blktap/Makefile | 3 linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c | 900 ---------- linux-2.6-xen-sparse/drivers/xen/blktap/common.h | 100 - linux-2.6-xen-sparse/drivers/xen/blktap/interface.c | 134 - linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c | 223 -- buildconfigs/linux-defconfig_xen0_ia64 | 2 buildconfigs/linux-defconfig_xen0_x86_32 | 2 buildconfigs/linux-defconfig_xen0_x86_64 | 2 buildconfigs/linux-defconfig_xen_ia64 | 2 buildconfigs/linux-defconfig_xen_x86_32 | 2 buildconfigs/linux-defconfig_xen_x86_64 | 2 linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S | 2 linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c | 16 linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c | 35 linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c | 11 linux-2.6-xen-sparse/arch/i386/kernel/vm86.c | 4 linux-2.6-xen-sparse/arch/i386/mm/init-xen.c | 14 linux-2.6-xen-sparse/arch/ia64/Kconfig | 36 linux-2.6-xen-sparse/arch/ia64/xen-mkbuildtree-pre | 5 linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c | 6 linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c | 58 linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c | 32 linux-2.6-xen-sparse/arch/x86_64/kernel/smp-xen.c | 2 linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c | 50 linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c | 16 linux-2.6-xen-sparse/drivers/xen/Kconfig | 53 linux-2.6-xen-sparse/drivers/xen/Makefile | 10 linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c | 22 linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c | 18 linux-2.6-xen-sparse/drivers/xen/blkback/common.h | 9 linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c | 20 linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c | 43 linux-2.6-xen-sparse/drivers/xen/blkfront/block.h | 11 linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c | 1 linux-2.6-xen-sparse/drivers/xen/char/mem.c | 8 linux-2.6-xen-sparse/drivers/xen/console/console.c | 2 linux-2.6-xen-sparse/drivers/xen/core/Makefile | 16 linux-2.6-xen-sparse/drivers/xen/core/cpu_hotplug.c | 2 linux-2.6-xen-sparse/drivers/xen/core/evtchn.c | 63 linux-2.6-xen-sparse/drivers/xen/core/gnttab.c | 202 -- linux-2.6-xen-sparse/drivers/xen/core/reboot.c | 8 linux-2.6-xen-sparse/drivers/xen/core/smpboot.c | 9 linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c | 6 linux-2.6-xen-sparse/drivers/xen/netback/common.h | 13 linux-2.6-xen-sparse/drivers/xen/netback/interface.c | 2 linux-2.6-xen-sparse/drivers/xen/netback/loopback.c | 2 linux-2.6-xen-sparse/drivers/xen/netback/netback.c | 324 ++- linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c | 46 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c | 263 +- linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c | 22 linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c | 16 linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c | 18 linux-2.6-xen-sparse/drivers/xen/tpmback/common.h | 16 linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c | 56 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c | 8 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c | 6 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c | 53 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c | 36 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hw_irq.h | 6 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h | 2 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h | 6 linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h | 7 linux-2.6-xen-sparse/include/asm-ia64/hw_irq.h | 11 linux-2.6-xen-sparse/include/asm-ia64/page.h | 10 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hw_irq.h | 6 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h | 2 linux-2.6-xen-sparse/include/linux/interrupt.h | 301 +++ linux-2.6-xen-sparse/include/xen/public/privcmd.h | 16 linux-2.6-xen-sparse/include/xen/xenbus.h | 35 linux-2.6-xen-sparse/kernel/irq/spurious.c | 206 ++ linux-2.6-xen-sparse/mm/memory.c | 2 patches/linux-2.6.16.13/rcu_needs_cpu.patch | 16 tools/debugger/libxendebug/xendebug.c | 7 tools/examples/network-bridge | 1 tools/firmware/hvmloader/Makefile | 4 tools/firmware/rombios/Makefile | 4 tools/firmware/vgabios/clext.c | 46 tools/firmware/vmxassist/vm86.c | 65 tools/ioemu/hw/cirrus_vga.c | 28 tools/ioemu/hw/pc.c | 11 tools/ioemu/hw/pckbd.c | 183 -- tools/ioemu/hw/usb-hid.c | 537 +++++ tools/ioemu/hw/usb-hub.c | 549 ++++++ tools/ioemu/hw/usb-uhci.c | 680 +++++++ tools/ioemu/hw/usb.c | 193 ++ tools/ioemu/hw/usb.h | 166 + tools/ioemu/hw/vga.c | 2 tools/ioemu/monitor.c | 8 tools/ioemu/sdl.c | 46 tools/ioemu/target-i386-dm/Makefile | 3 tools/ioemu/usb-linux.c | 488 +++++ tools/ioemu/vl.c | 203 ++ tools/ioemu/vl.h | 23 tools/ioemu/vnc.c | 58 tools/libxc/xc_core.c | 12 tools/libxc/xc_domain.c | 18 tools/libxc/xc_hvm_build.c | 10 tools/libxc/xc_ia64_stubs.c | 14 tools/libxc/xc_linux.c | 2 tools/libxc/xc_linux_build.c | 171 + tools/libxc/xc_linux_restore.c | 216 ++ tools/libxc/xc_linux_save.c | 69 tools/libxc/xc_load_aout9.c | 4 tools/libxc/xc_load_bin.c | 4 tools/libxc/xc_load_elf.c | 19 tools/libxc/xc_pagetab.c | 22 tools/libxc/xc_private.c | 68 tools/libxc/xc_private.h | 51 tools/libxc/xc_ptrace.c | 29 tools/libxc/xc_ptrace.h | 1 tools/libxc/xc_ptrace_core.c | 23 tools/libxc/xenctrl.h | 19 tools/libxc/xg_private.h | 25 tools/libxc/xg_save_restore.h | 34 tools/python/xen/lowlevel/acm/acm.c | 14 tools/python/xen/lowlevel/xs/xs.c | 68 tools/python/xen/util/security.py | 9 tools/python/xen/xend/image.py | 5 tools/python/xen/xm/create.py | 23 tools/tests/test_x86_emulator.c | 131 - tools/xm-test/configure.ac | 3 tools/xm-test/grouptest/default | 1 tools/xm-test/ramdisk/Makefile.am | 2 tools/xm-test/ramdisk/README-XenSource-initrd-0.8-img | 42 tools/xm-test/ramdisk/configs/busybox | 4 tools/xm-test/tests/Makefile.am | 1 tools/xm-test/tests/block-integrity/02_block_device_write_verify.py | 63 tools/xm-test/tests/block-integrity/Makefile.am | 3 tools/xm-test/tests/enforce_dom0_cpus/01_enforce_dom0_cpus_basic_pos.py | 21 tools/xm-test/tests/sched-credit/01_sched_credit_weight_cap_pos.py | 65 tools/xm-test/tests/sched-credit/Makefile.am | 20 xen/acm/acm_core.c | 2 xen/acm/acm_policy.c | 23 xen/acm/acm_simple_type_enforcement_hooks.c | 14 xen/arch/ia64/linux-xen/smpboot.c | 3 xen/arch/ia64/vmx/vmx_init.c | 3 xen/arch/ia64/xen/domain.c | 1 xen/arch/ia64/xen/xensetup.c | 2 xen/arch/x86/audit.c | 4 xen/arch/x86/cpu/mtrr/main.c | 2 xen/arch/x86/dom0_ops.c | 2 xen/arch/x86/domain.c | 48 xen/arch/x86/domain_build.c | 9 xen/arch/x86/hvm/intercept.c | 14 xen/arch/x86/hvm/io.c | 7 xen/arch/x86/hvm/platform.c | 94 - xen/arch/x86/hvm/svm/svm.c | 80 xen/arch/x86/hvm/vmx/vmcs.c | 177 + xen/arch/x86/hvm/vmx/vmx.c | 220 +- xen/arch/x86/hvm/vmx/x86_32/exits.S | 109 - xen/arch/x86/hvm/vmx/x86_64/exits.S | 146 - xen/arch/x86/i8259.c | 2 xen/arch/x86/irq.c | 22 xen/arch/x86/microcode.c | 2 xen/arch/x86/mm.c | 137 - xen/arch/x86/physdev.c | 9 xen/arch/x86/setup.c | 2 xen/arch/x86/shadow.c | 9 xen/arch/x86/shadow32.c | 14 xen/arch/x86/shadow_public.c | 14 xen/arch/x86/smp.c | 2 xen/arch/x86/smpboot.c | 17 xen/arch/x86/time.c | 6 xen/arch/x86/traps.c | 13 xen/arch/x86/x86_32/asm-offsets.c | 5 xen/arch/x86/x86_32/domain_page.c | 2 xen/arch/x86/x86_32/entry.S | 12 xen/arch/x86/x86_32/mm.c | 3 xen/arch/x86/x86_32/traps.c | 8 xen/arch/x86/x86_64/asm-offsets.c | 6 xen/arch/x86/x86_64/entry.S | 20 xen/arch/x86/x86_64/mm.c | 3 xen/arch/x86/x86_64/traps.c | 14 xen/arch/x86/x86_emulate.c | 19 xen/common/acm_ops.c | 12 xen/common/dom0_ops.c | 2 xen/common/domain.c | 134 + xen/common/event_channel.c | 23 xen/common/kernel.c | 5 xen/common/keyhandler.c | 5 xen/common/memory.c | 20 xen/common/page_alloc.c | 4 xen/common/perfc.c | 2 xen/common/sched_bvt.c | 36 xen/common/sched_credit.c | 30 xen/common/sched_sedf.c | 39 xen/common/schedule.c | 129 - xen/common/trace.c | 12 xen/common/xmalloc.c | 2 xen/drivers/char/console.c | 13 xen/include/acm/acm_core.h | 13 xen/include/asm-ia64/config.h | 5 xen/include/asm-ia64/event.h | 20 xen/include/asm-ia64/vmx_vcpu.h | 2 xen/include/asm-ia64/vmx_vpd.h | 3 xen/include/asm-ia64/xenpage.h | 4 xen/include/asm-x86/config.h | 5 xen/include/asm-x86/event.h | 26 xen/include/asm-x86/hvm/io.h | 7 xen/include/asm-x86/hvm/vmx/cpu.h | 17 xen/include/asm-x86/hvm/vmx/vmcs.h | 56 xen/include/asm-x86/hvm/vmx/vmx.h | 84 xen/include/asm-x86/irq.h | 3 xen/include/asm-x86/multicall.h | 79 xen/include/asm-x86/page.h | 11 xen/include/asm-x86/shadow.h | 37 xen/include/public/acm.h | 3 xen/include/public/acm_ops.h | 23 xen/include/public/arch-ia64.h | 3 xen/include/public/arch-x86_32.h | 27 xen/include/public/arch-x86_64.h | 24 xen/include/public/callback.h | 15 xen/include/public/dom0_ops.h | 56 xen/include/public/grant_table.h | 2 xen/include/public/io/netif.h | 4 xen/include/public/io/ring.h | 16 xen/include/public/memory.h | 10 xen/include/public/physdev.h | 7 xen/include/public/xen.h | 22 xen/include/xen/console.h | 2 xen/include/xen/domain.h | 23 xen/include/xen/event.h | 3 xen/include/xen/mm.h | 7 xen/include/xen/sched-if.h | 11 xen/include/xen/sched.h | 22 228 files changed, 6942 insertions(+), 3781 deletions(-) diff -r b8f6089cbce3 -r e74c47d073ee buildconfigs/linux-defconfig_xen0_ia64 --- a/buildconfigs/linux-defconfig_xen0_ia64 Tue Jun 13 09:00:32 2006 -0600 +++ b/buildconfigs/linux-defconfig_xen0_ia64 Tue Jun 13 12:12:24 2006 -0600 @@ -1529,14 +1529,12 @@ CONFIG_XEN_BACKEND=y CONFIG_XEN_BACKEND=y # CONFIG_XEN_PCIDEV_BACKEND is not set CONFIG_XEN_BLKDEV_BACKEND=y -# CONFIG_XEN_BLKDEV_TAP_BE is not set CONFIG_XEN_NETDEV_BACKEND=y # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set CONFIG_XEN_NETDEV_LOOPBACK=y # CONFIG_XEN_TPMDEV_BACKEND is not set CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y -# CONFIG_XEN_BLKDEV_TAP is not set # CONFIG_XEN_SCRUB_PAGES is not set # CONFIG_XEN_DISABLE_SERIAL is not set CONFIG_XEN_SYSFS=y diff -r b8f6089cbce3 -r e74c47d073ee buildconfigs/linux-defconfig_xen0_x86_32 --- a/buildconfigs/linux-defconfig_xen0_x86_32 Tue Jun 13 09:00:32 2006 -0600 +++ b/buildconfigs/linux-defconfig_xen0_x86_32 Tue Jun 13 12:12:24 2006 -0600 @@ -1322,14 +1322,12 @@ CONFIG_XEN_PCIDEV_BACKEND_PASS=y CONFIG_XEN_PCIDEV_BACKEND_PASS=y # CONFIG_XEN_PCIDEV_BE_DEBUG is not set CONFIG_XEN_BLKDEV_BACKEND=y -# CONFIG_XEN_BLKDEV_TAP_BE is not set CONFIG_XEN_NETDEV_BACKEND=y # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set CONFIG_XEN_NETDEV_LOOPBACK=y # CONFIG_XEN_TPMDEV_BACKEND is not set CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y -# CONFIG_XEN_BLKDEV_TAP is not set CONFIG_XEN_SCRUB_PAGES=y CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_SYSFS=y diff -r b8f6089cbce3 -r e74c47d073ee buildconfigs/linux-defconfig_xen0_x86_64 --- a/buildconfigs/linux-defconfig_xen0_x86_64 Tue Jun 13 09:00:32 2006 -0600 +++ b/buildconfigs/linux-defconfig_xen0_x86_64 Tue Jun 13 12:12:24 2006 -0600 @@ -1263,14 +1263,12 @@ CONFIG_XEN_PCIDEV_BACKEND_PASS=y CONFIG_XEN_PCIDEV_BACKEND_PASS=y # CONFIG_XEN_PCIDEV_BE_DEBUG is not set CONFIG_XEN_BLKDEV_BACKEND=y -# CONFIG_XEN_BLKDEV_TAP_BE is not set CONFIG_XEN_NETDEV_BACKEND=y # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set CONFIG_XEN_NETDEV_LOOPBACK=y # CONFIG_XEN_TPMDEV_BACKEND is not set CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y -# CONFIG_XEN_BLKDEV_TAP is not set CONFIG_XEN_SCRUB_PAGES=y CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_SYSFS=y diff -r b8f6089cbce3 -r e74c47d073ee buildconfigs/linux-defconfig_xen_ia64 --- a/buildconfigs/linux-defconfig_xen_ia64 Tue Jun 13 09:00:32 2006 -0600 +++ b/buildconfigs/linux-defconfig_xen_ia64 Tue Jun 13 12:12:24 2006 -0600 @@ -1535,14 +1535,12 @@ CONFIG_XEN_BACKEND=y CONFIG_XEN_BACKEND=y # CONFIG_XEN_PCIDEV_BACKEND is not set CONFIG_XEN_BLKDEV_BACKEND=y -# CONFIG_XEN_BLKDEV_TAP_BE is not set CONFIG_XEN_NETDEV_BACKEND=y # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set CONFIG_XEN_NETDEV_LOOPBACK=y # CONFIG_XEN_TPMDEV_BACKEND is not set CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y -# CONFIG_XEN_BLKDEV_TAP is not set # CONFIG_XEN_SCRUB_PAGES is not set # CONFIG_XEN_DISABLE_SERIAL is not set CONFIG_XEN_SYSFS=y diff -r b8f6089cbce3 -r e74c47d073ee buildconfigs/linux-defconfig_xen_x86_32 --- a/buildconfigs/linux-defconfig_xen_x86_32 Tue Jun 13 09:00:32 2006 -0600 +++ b/buildconfigs/linux-defconfig_xen_x86_32 Tue Jun 13 12:12:24 2006 -0600 @@ -3022,14 +3022,12 @@ CONFIG_XEN_PCIDEV_BACKEND_VPCI=y # CONFIG_XEN_PCIDEV_BACKEND_PASS is not set # CONFIG_XEN_PCIDEV_BE_DEBUG is not set CONFIG_XEN_BLKDEV_BACKEND=y -# CONFIG_XEN_BLKDEV_TAP_BE is not set CONFIG_XEN_NETDEV_BACKEND=y # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set CONFIG_XEN_NETDEV_LOOPBACK=y # CONFIG_XEN_TPMDEV_BACKEND is not set CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y -# CONFIG_XEN_BLKDEV_TAP is not set CONFIG_XEN_SCRUB_PAGES=y CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_SYSFS=y diff -r b8f6089cbce3 -r e74c47d073ee buildconfigs/linux-defconfig_xen_x86_64 --- a/buildconfigs/linux-defconfig_xen_x86_64 Tue Jun 13 09:00:32 2006 -0600 +++ b/buildconfigs/linux-defconfig_xen_x86_64 Tue Jun 13 12:12:24 2006 -0600 @@ -2854,7 +2854,6 @@ CONFIG_XEN_PCIDEV_BACKEND_PASS=y CONFIG_XEN_PCIDEV_BACKEND_PASS=y # CONFIG_XEN_PCIDEV_BE_DEBUG is not set CONFIG_XEN_BLKDEV_BACKEND=y -# CONFIG_XEN_BLKDEV_TAP_BE is not set CONFIG_XEN_NETDEV_BACKEND=y # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set CONFIG_XEN_NETDEV_LOOPBACK=y @@ -2862,7 +2861,6 @@ CONFIG_XEN_TPMDEV_BACKEND=m # CONFIG_XEN_TPMDEV_CLOSE_IF_VTPM_FAILS is not set CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y -# CONFIG_XEN_BLKDEV_TAP is not set CONFIG_XEN_SCRUB_PAGES=y CONFIG_XEN_DISABLE_SERIAL=y CONFIG_XEN_SYSFS=y diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S --- a/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S Tue Jun 13 12:12:24 2006 -0600 @@ -173,7 +173,7 @@ ENTRY(cpu_gdt_table) .ascii "|pae_pgdir_above_4gb" .ascii "|supervisor_mode_kernel" #ifdef CONFIG_X86_PAE - .ascii ",PAE=yes" + .ascii ",PAE=yes[extended-cr3]" #else .ascii ",PAE=no" #endif diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Tue Jun 13 12:12:24 2006 -0600 @@ -1378,7 +1378,6 @@ legacy_init_iomem_resources(struct e820e res->end = res->start + e820[i].size - 1; res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; request_resource(&iomem_resource, res); -#ifndef CONFIG_XEN if (e820[i].type == E820_RAM) { /* * We don't know which RAM region contains kernel data, @@ -1391,7 +1390,6 @@ legacy_init_iomem_resources(struct e820e request_resource(res, &crashk_res); #endif } -#endif } } @@ -1460,8 +1458,11 @@ static void __init register_memory(void) int i; /* Nothing to do if not running in dom0. */ - if (!(xen_start_info->flags & SIF_INITDOMAIN)) + if (!(xen_start_info->flags & SIF_INITDOMAIN)) { + legacy_init_iomem_resources(e820.map, e820.nr_map, + &code_resource, &data_resource); return; + } #ifdef CONFIG_XEN machine_e820 = alloc_bootmem_low_pages(PAGE_SIZE); @@ -1698,11 +1699,10 @@ void __init setup_arch(char **cmdline_p) init_mm.brk = (PFN_UP(__pa(xen_start_info->pt_base)) + xen_start_info->nr_pt_frames) << PAGE_SHIFT; - /* XEN: This is nonsense: kernel may not even be contiguous in RAM. */ - /*code_resource.start = virt_to_phys(_text);*/ - /*code_resource.end = virt_to_phys(_etext)-1;*/ - /*data_resource.start = virt_to_phys(_etext);*/ - /*data_resource.end = virt_to_phys(_edata)-1;*/ + code_resource.start = virt_to_phys(_text); + code_resource.end = virt_to_phys(_etext)-1; + data_resource.start = virt_to_phys(_etext); + data_resource.end = virt_to_phys(_edata)-1; parse_cmdline_early(cmdline_p); diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c Tue Jun 13 12:12:24 2006 -0600 @@ -47,6 +47,9 @@ EXPORT_SYMBOL(swiotlb); */ #define IO_TLB_SHIFT 11 +/* Width of DMA addresses in the IO TLB. 31 bits is an aacraid limitation. */ +#define IO_TLB_DMA_BITS 31 + static int swiotlb_force; static char *iotlb_virt_start; static unsigned long iotlb_nslabs; @@ -56,10 +59,16 @@ static unsigned long iotlb_nslabs; * swiotlb_sync_single_*, to see if the memory was in fact allocated by this * API. */ -static dma_addr_t iotlb_bus_start, iotlb_bus_end, iotlb_bus_mask; +static unsigned long iotlb_pfn_start, iotlb_pfn_end; /* Does the given dma address reside within the swiotlb aperture? */ -#define in_swiotlb_aperture(a) (!(((a) ^ iotlb_bus_start) & iotlb_bus_mask)) +static inline int in_swiotlb_aperture(dma_addr_t dev_addr) +{ + unsigned long pfn = mfn_to_local_pfn(dev_addr >> PAGE_SHIFT); + return (pfn_valid(pfn) + && (pfn >= iotlb_pfn_start) + && (pfn < iotlb_pfn_end)); +} /* * When the IOMMU overflows we return a fallback buffer. This sets the size. @@ -125,7 +134,6 @@ swiotlb_init_with_default_size (size_t d swiotlb_init_with_default_size (size_t default_size) { unsigned long i, bytes; - int rc; if (!iotlb_nslabs) { iotlb_nslabs = (default_size >> IO_TLB_SHIFT); @@ -146,10 +154,13 @@ swiotlb_init_with_default_size (size_t d "Use dom0_mem Xen boot parameter to reserve\n" "some DMA memory (e.g., dom0_mem=-128M).\n"); - /* Hardcode 31 address bits for now: aacraid limitation. */ - rc = xen_create_contiguous_region( - (unsigned long)iotlb_virt_start, get_order(bytes), 31); - BUG_ON(rc); + for (i = 0; i < iotlb_nslabs; i += IO_TLB_SEGSIZE) { + int rc = xen_create_contiguous_region( + (unsigned long)iotlb_virt_start + (i << IO_TLB_SHIFT), + get_order(IO_TLB_SEGSIZE << IO_TLB_SHIFT), + IO_TLB_DMA_BITS); + BUG_ON(rc); + } /* * Allocate and initialize the free list array. This array is used @@ -167,17 +178,13 @@ swiotlb_init_with_default_size (size_t d */ io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow); - iotlb_bus_start = virt_to_bus(iotlb_virt_start); - iotlb_bus_end = iotlb_bus_start + bytes; - iotlb_bus_mask = ~(dma_addr_t)(bytes - 1); + iotlb_pfn_start = __pa(iotlb_virt_start) >> PAGE_SHIFT; + iotlb_pfn_end = iotlb_pfn_start + (bytes >> PAGE_SHIFT); printk(KERN_INFO "Software IO TLB enabled: \n" " Aperture: %lu megabytes\n" - " Bus range: 0x%016lx - 0x%016lx\n" " Kernel range: 0x%016lx - 0x%016lx\n", bytes >> 20, - (unsigned long)iotlb_bus_start, - (unsigned long)iotlb_bus_end, (unsigned long)iotlb_virt_start, (unsigned long)iotlb_virt_start + bytes); } @@ -647,7 +654,7 @@ int int swiotlb_dma_supported (struct device *hwdev, u64 mask) { - return (mask >= (iotlb_bus_end - 1)); + return (mask >= ((1UL << IO_TLB_DMA_BITS) - 1)); } EXPORT_SYMBOL(swiotlb_init); diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c Tue Jun 13 12:12:24 2006 -0600 @@ -978,12 +978,19 @@ static void stop_hz_timer(void) unsigned int cpu = smp_processor_id(); unsigned long j; - /* We must do this /before/ checking rcu_pending(). */ cpu_set(cpu, nohz_cpu_mask); + + /* See matching smp_mb in rcu_start_batch in rcupdate.c. These mbs */ + /* ensure that if __rcu_pending (nested in rcu_needs_cpu) fetches a */ + /* value of rcp->cur that matches rdp->quiescbatch and allows us to */ + /* stop the hz timer then the cpumasks created for subsequent values */ + /* of cur in rcu_start_batch are guaranteed to pick up the updated */ + /* nohz_cpu_mask and so will not depend on this cpu. */ + smp_mb(); /* Leave ourselves in 'tick mode' if rcu or softirq pending. */ - if (rcu_pending(cpu) || local_softirq_pending()) { + if (rcu_needs_cpu(cpu) || local_softirq_pending()) { cpu_clear(cpu, nohz_cpu_mask); j = jiffies + 1; } else { diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/arch/i386/kernel/vm86.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/vm86.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/vm86.c Tue Jun 13 12:12:24 2006 -0600 @@ -132,7 +132,9 @@ struct pt_regs * fastcall save_v86_state current->thread.sysenter_cs = __KERNEL_CS; load_esp0(tss, ¤t->thread); current->thread.saved_esp0 = 0; +#ifndef CONFIG_X86_NO_TSS put_cpu(); +#endif loadsegment(fs, current->thread.saved_fs); loadsegment(gs, current->thread.saved_gs); @@ -310,7 +312,9 @@ static void do_sys_vm86(struct kernel_vm if (cpu_has_sep) tsk->thread.sysenter_cs = 0; load_esp0(tss, &tsk->thread); +#ifndef CONFIG_X86_NO_TSS put_cpu(); +#endif tsk->thread.screen_bitmap = info->screen_bitmap; if (info->flags & VM86_SCREEN_BITMAP) diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/arch/i386/mm/init-xen.c --- a/linux-2.6-xen-sparse/arch/i386/mm/init-xen.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/i386/mm/init-xen.c Tue Jun 13 12:12:24 2006 -0600 @@ -558,15 +558,11 @@ void __init paging_init(void) kmap_init(); - if (!xen_feature(XENFEAT_auto_translated_physmap) || - xen_start_info->shared_info >= xen_start_info->nr_pages) { - /* Switch to the real shared_info page, and clear the - * dummy page. */ - set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info); - HYPERVISOR_shared_info = - (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); - memset(empty_zero_page, 0, sizeof(empty_zero_page)); - } + /* Switch to the real shared_info page, and clear the + * dummy page. */ + set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info); + HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); + memset(empty_zero_page, 0, sizeof(empty_zero_page)); /* Setup mapping of lower 1st MB */ for (i = 0; i < NR_FIX_ISAMAPS; i++) diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/arch/ia64/Kconfig --- a/linux-2.6-xen-sparse/arch/ia64/Kconfig Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig Tue Jun 13 12:12:24 2006 -0600 @@ -66,7 +66,7 @@ config XEN_IA64_DOM0_VP config XEN_IA64_DOM0_NON_VP bool - depends on !(XEN && XEN_IA64_DOM0_VP) + depends on XEN && !XEN_IA64_DOM0_VP default y help dom0 P=M model @@ -489,15 +489,39 @@ source "security/Kconfig" source "crypto/Kconfig" +# # override default values of drivers/xen/Kconfig -if !XEN_IA64_DOM0_VP +# +if XEN +config XEN_UTIL + default n if XEN_IA64_DOM0_VP + config HAVE_ARCH_ALLOC_SKB - bool - default n + default n if !XEN_IA64_DOM0_VP config HAVE_ARCH_DEV_ALLOC_SKB - bool - default n + default n if !XEN_IA64_DOM0_VP + +config XEN_BALLOON + default n if !XEN_IA64_DOM0_VP + +config XEN_SKBUFF + default n if !XEN_IA64_DOM0_VP + +config XEN_NETDEV_BACKEND + default n if !XEN_IA64_DOM0_VP + +config XEN_NETDEV_FRONTEND + default n if !XEN_IA64_DOM0_VP + +config XEN_DEVMEM + default n + +config XEN_REBOOT + default n + +config XEN_SMPBOOT + default n endif source "drivers/xen/Kconfig" diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/arch/ia64/xen-mkbuildtree-pre --- a/linux-2.6-xen-sparse/arch/ia64/xen-mkbuildtree-pre Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/ia64/xen-mkbuildtree-pre Tue Jun 13 12:12:24 2006 -0600 @@ -10,8 +10,3 @@ #eventually asm-xsi-offsets needs to be part of hypervisor.h/hypercall.h ln -sf ../../../../xen/include/asm-ia64/asm-xsi-offsets.h include/asm-ia64/xen/ -#ia64 drivers/xen isn't fully functional yet, workaround... -#also ignore core/evtchn.c which uses a different irq mechanism than ia64 -#(warning: there be dragons here if these files diverge) -ln -sf ../../arch/ia64/xen/drivers/Makefile drivers/xen/Makefile -ln -sf ../../../arch/ia64/xen/drivers/coreMakefile drivers/xen/core/Makefile diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c Tue Jun 13 12:12:24 2006 -0600 @@ -44,9 +44,7 @@ unsigned long end_pfn_map; */ unsigned long end_user_pfn = MAXMEM>>PAGE_SHIFT; -#ifndef CONFIG_XEN extern struct resource code_resource, data_resource; -#endif /* Check for some hardcoded bad areas that early boot is not allowed to touch */ static inline int bad_addr(unsigned long *addrp, unsigned long size) @@ -251,8 +249,7 @@ void __init e820_reserve_resources(struc res->end = res->start + e820[i].size - 1; res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; request_resource(&iomem_resource, res); -#ifndef CONFIG_XEN - if (e820.map[i].type == E820_RAM) { + if (e820[i].type == E820_RAM) { /* * We don't know which RAM region contains kernel data, * so we try it repeatedly and let the resource manager @@ -264,7 +261,6 @@ void __init e820_reserve_resources(struc request_resource(res, &crashk_res); #endif } -#endif } } diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c Tue Jun 13 12:12:24 2006 -0600 @@ -18,6 +18,56 @@ #include <linux/slab.h> #include <linux/thread_info.h> #include <xen/interface/physdev.h> + +/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */ +static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value) +{ + int i; + + if (new_value) + for (i = base; i < base + extent; i++) + __set_bit(i, bitmap); + else + for (i = base; i < base + extent; i++) + clear_bit(i, bitmap); +} + +/* + * this changes the io permissions bitmap in the current task. + */ +asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) +{ + struct thread_struct * t = ¤t->thread; + unsigned long *bitmap; + struct physdev_set_iobitmap set_iobitmap; + + if ((from + num <= from) || (from + num > IO_BITMAP_BITS)) + return -EINVAL; + if (turn_on && !capable(CAP_SYS_RAWIO)) + return -EPERM; + + /* + * If it's the first ioperm() call in this thread's lifetime, set the + * IO bitmap up. ioperm() is much less timing critical than clone(), + * this is why we delay this operation until now: + */ + if (!t->io_bitmap_ptr) { + bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); + if (!bitmap) + return -ENOMEM; + + memset(bitmap, 0xff, IO_BITMAP_BYTES); + t->io_bitmap_ptr = bitmap; + + set_iobitmap.bitmap = (char *)bitmap; + set_iobitmap.nr_ports = IO_BITMAP_BITS; + HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap); + } + + set_bitmap(t->io_bitmap_ptr, from, num, !turn_on); + + return 0; +} /* * sys_iopl has to be used when you want to access the IO ports @@ -47,11 +97,3 @@ asmlinkage long sys_iopl(unsigned int ne return 0; } - -/* - * this changes the io permissions bitmap in the current task. - */ -asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) -{ - return turn_on ? sys_iopl(3, NULL) : 0; -} diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Tue Jun 13 12:12:24 2006 -0600 @@ -665,13 +665,6 @@ void __init setup_arch(char **cmdline_p) setup_xen_features(); - if (xen_feature(XENFEAT_auto_translated_physmap) && - xen_start_info->shared_info < xen_start_info->nr_pages) { - HYPERVISOR_shared_info = - (shared_info_t *)__va(xen_start_info->shared_info); - memset(empty_zero_page, 0, sizeof(empty_zero_page)); - } - HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_writable_pagetables); @@ -699,12 +692,10 @@ void __init setup_arch(char **cmdline_p) init_mm.end_data = (unsigned long) &_edata; init_mm.brk = (unsigned long) &_end; -#ifndef CONFIG_XEN code_resource.start = virt_to_phys(&_text); code_resource.end = virt_to_phys(&_etext)-1; data_resource.start = virt_to_phys(&_etext); data_resource.end = virt_to_phys(&_edata)-1; -#endif parse_cmdline_early(cmdline_p); @@ -826,14 +817,6 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_XEN { int i, j, k, fpp; - unsigned long va; - - /* 'Initial mapping' of initrd must be destroyed. */ - for (va = xen_start_info->mod_start; - va < (xen_start_info->mod_start+xen_start_info->mod_len); - va += PAGE_SIZE) { - HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0); - } if (!xen_feature(XENFEAT_auto_translated_physmap)) { /* Make sure we have a large enough P->M table. */ @@ -848,14 +831,6 @@ void __init setup_arch(char **cmdline_p) __pa(xen_start_info->mfn_list), PFN_PHYS(PFN_UP(xen_start_info->nr_pages * sizeof(unsigned long)))); - - /* Destroyed 'initial mapping' of old p2m table. */ - for (va = xen_start_info->mfn_list; - va < (xen_start_info->mfn_list + - (xen_start_info->nr_pages*sizeof(unsigned long))); - va += PAGE_SIZE) { - HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0); - } /* * Initialise the list of the frames that specify the @@ -944,8 +919,11 @@ void __init setup_arch(char **cmdline_p) BUG_ON(HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap)); e820_reserve_resources(machine_e820, memmap.nr_entries); - } -#elif !defined(CONFIG_XEN) + } else if (!(xen_start_info->flags & SIF_INITDOMAIN)) + e820_reserve_resources(e820.map, e820.nr_map); +#elif defined(CONFIG_XEN) + e820_reserve_resources(e820.map, e820.nr_map); +#else probe_roms(); e820_reserve_resources(e820.map, e820.nr_map); #endif diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/arch/x86_64/kernel/smp-xen.c --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/smp-xen.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/smp-xen.c Tue Jun 13 12:12:24 2006 -0600 @@ -488,7 +488,7 @@ static void smp_really_stop_cpu(void *du { smp_stop_cpu(); for (;;) - asm("hlt"); + halt(); } void smp_send_stop(void) diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c --- a/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c Tue Jun 13 12:12:24 2006 -0600 @@ -666,7 +666,34 @@ void __meminit init_memory_mapping(unsig set_pgd(pgd_offset_k(start), mk_kernel_pgd(pud_phys)); } - BUG_ON(!after_bootmem && start_pfn != table_end); + if (!after_bootmem) { + BUG_ON(start_pfn != table_end); + + /* Re-vector virtual addresses pointing into the initial + mapping to the just-established permanent ones. */ + xen_start_info = __va(__pa(xen_start_info)); + xen_start_info->pt_base = (unsigned long) + __va(__pa(xen_start_info->pt_base)); + if (!xen_feature(XENFEAT_auto_translated_physmap)) { + phys_to_machine_mapping = + __va(__pa(xen_start_info->mfn_list)); + xen_start_info->mfn_list = (unsigned long) + phys_to_machine_mapping; + } + if (xen_start_info->mod_start) + xen_start_info->mod_start = (unsigned long) + __va(__pa(xen_start_info->mod_start)); + + /* Destroy the Xen-created mappings beyond the kernel image as + * well as the temporary mappings created above. Prevents + * overlap with modules area (if init mapping is very big). + */ + start = PAGE_ALIGN((unsigned long)_end); + end = __START_KERNEL_map + (table_end << PAGE_SHIFT); + for (; start < end; start += PAGE_SIZE) + WARN_ON(HYPERVISOR_update_va_mapping( + start, __pte_ma(0), 0)); + } __flush_tlb_all(); } @@ -752,15 +779,11 @@ void __init paging_init(void) free_area_init_node(0, NODE_DATA(0), zones, __pa(PAGE_OFFSET) >> PAGE_SHIFT, holes); - if (!xen_feature(XENFEAT_auto_translated_physmap) || - xen_start_info->shared_info >= xen_start_info->nr_pages) { - /* Switch to the real shared_info page, and clear the - * dummy page. */ - set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info); - HYPERVISOR_shared_info = - (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); - memset(empty_zero_page, 0, sizeof(empty_zero_page)); - } + /* Switch to the real shared_info page, and clear the + * dummy page. */ + set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info); + HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); + memset(empty_zero_page, 0, sizeof(empty_zero_page)); init_mm.context.pinned = 1; @@ -859,6 +882,7 @@ void __init mem_init(void) void __init mem_init(void) { long codesize, reservedpages, datasize, initsize; + unsigned long pfn; contiguous_bitmap = alloc_bootmem_low_pages( (end_pfn + 2*BITS_PER_LONG) >> 3); @@ -887,6 +911,12 @@ void __init mem_init(void) #else totalram_pages = free_all_bootmem(); #endif + /* XEN: init and count pages outside initial allocation. */ + for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) { + ClearPageReserved(&mem_map[pfn]); + set_page_count(&mem_map[pfn], 1); + totalram_pages++; + } reservedpages = end_pfn - totalram_pages - e820_hole_size(0, end_pfn); after_bootmem = 1; diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c Tue Jun 13 12:12:24 2006 -0600 @@ -274,7 +274,7 @@ static int talk_to_backend(struct xenbus { const char *message = NULL; int err; - xenbus_transaction_t xbt; + struct xenbus_transaction xbt; err = setup_tpmring(dev, tp); if (err) { @@ -331,7 +331,7 @@ static void backend_changed(struct xenbu static void backend_changed(struct xenbus_device *dev, enum xenbus_state backend_state) { - struct tpm_private *tp = dev->data; + struct tpm_private *tp = dev->dev.driver_data; DPRINTK("\n"); switch (backend_state) { @@ -369,7 +369,7 @@ static int tpmfront_probe(struct xenbus_ if (!tp) return -ENOMEM; - err = xenbus_scanf(XBT_NULL, dev->nodename, + err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%i", &handle); if (XENBUS_EXIST_ERR(err)) return err; @@ -380,12 +380,12 @@ static int tpmfront_probe(struct xenbus_ } tp->dev = dev; - dev->data = tp; + dev->dev.driver_data = tp; err = talk_to_backend(dev, tp); if (err) { tpm_private_put(); - dev->data = NULL; + dev->dev.driver_data = NULL; return err; } return 0; @@ -394,14 +394,14 @@ static int tpmfront_probe(struct xenbus_ static int tpmfront_remove(struct xenbus_device *dev) { - struct tpm_private *tp = (struct tpm_private *)dev->data; + struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data; destroy_tpmring(tp); return 0; } static int tpmfront_suspend(struct xenbus_device *dev) { - struct tpm_private *tp = (struct tpm_private *)dev->data; + struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data; u32 ctr; /* lock, so no app can send */ @@ -431,7 +431,7 @@ static int tpmfront_suspend(struct xenbu static int tpmfront_resume(struct xenbus_device *dev) { - struct tpm_private *tp = (struct tpm_private *)dev->data; + struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data; destroy_tpmring(tp); return talk_to_backend(dev, tp); } diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/Kconfig --- a/linux-2.6-xen-sparse/drivers/xen/Kconfig Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/Kconfig Tue Jun 13 12:12:24 2006 -0600 @@ -84,19 +84,6 @@ config XEN_BLKDEV_BACKEND block devices to other guests via a high-performance shared-memory interface. -config XEN_BLKDEV_TAP_BE - tristate "Block Tap support for backend driver (DANGEROUS)" - depends on XEN_BLKDEV_BACKEND - default n - help - If you intend to use the block tap driver, the backend domain will - not know the domain id of the real frontend, and so will not be able - to map its data pages. This modifies the backend to attempt to map - from both the tap domain and the real frontend. This presents a - security risk, and so should ONLY be used for development - with the blktap. This option will be removed as the block drivers are - modified to use grant tables. - config XEN_NETDEV_BACKEND tristate "Network-device backend driver" depends on XEN_BACKEND && NET @@ -163,16 +150,6 @@ config XEN_NETDEV_FRONTEND dedicated device-driver domain, or your master control domain (domain 0), then you almost certainly want to say Y here. -config XEN_BLKDEV_TAP - tristate "Block device tap driver" - depends on XEN_BACKEND - default n - help - This driver allows a VM to interact on block device channels - to other VMs. Block messages may be passed through or redirected - to a character device, allowing device prototyping in application - space. Odds are that you want to say N here. - config XEN_SCRUB_PAGES bool "Scrub memory before freeing it to Xen" default y @@ -224,8 +201,38 @@ config HAVE_ARCH_DEV_ALLOC_SKB bool default y +config HAVE_IRQ_IGNORE_UNHANDLED + bool + default y + config NO_IDLE_HZ bool default y +config XEN_UTIL + bool + default y + +config XEN_BALLOON + bool + default y + +config XEN_DEVMEM + bool + default y + +config XEN_SKBUFF + bool + default y + depends on NET + +config XEN_REBOOT + bool + default y + +config XEN_SMPBOOT + bool + default y + depends on SMP + endif diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/Makefile --- a/linux-2.6-xen-sparse/drivers/xen/Makefile Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/Makefile Tue Jun 13 12:12:24 2006 -0600 @@ -1,20 +1,16 @@ - -obj-y += util.o - obj-y += core/ -obj-y += char/ obj-y += console/ obj-y += evtchn/ -obj-y += balloon/ obj-y += privcmd/ obj-y += xenbus/ +obj-$(CONFIG_XEN_UTIL) += util.o +obj-$(CONFIG_XEN_BALLOON) += balloon/ +obj-$(CONFIG_XEN_DEVMEM) += char/ obj-$(CONFIG_XEN_BLKDEV_BACKEND) += blkback/ obj-$(CONFIG_XEN_NETDEV_BACKEND) += netback/ obj-$(CONFIG_XEN_TPMDEV_BACKEND) += tpmback/ obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += blkfront/ obj-$(CONFIG_XEN_NETDEV_FRONTEND) += netfront/ -obj-$(CONFIG_XEN_BLKDEV_TAP) += blktap/ obj-$(CONFIG_XEN_PCIDEV_BACKEND) += pciback/ obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += pcifront/ - diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Tue Jun 13 12:12:24 2006 -0600 @@ -222,7 +222,7 @@ static int increase_reservation(unsigned /* Update P->M and M->P tables. */ set_phys_to_machine(pfn, frame_list[i]); xen_machphys_update(frame_list[i], pfn); - + /* Link back into the page tables if not highmem. */ if (pfn < max_low_pfn) { int ret; @@ -378,22 +378,21 @@ static void watch_target(struct xenbus_w unsigned long long new_target; int err; - err = xenbus_scanf(XBT_NULL, "memory", "target", "%llu", &new_target); + err = xenbus_scanf(XBT_NIL, "memory", "target", "%llu", &new_target); if (err != 1) { /* This is ok (for domain0 at least) - so just return */ return; - } - + } + /* The given memory/target value is in KiB, so it needs converting to - pages. PAGE_SHIFT converts bytes to pages, hence PAGE_SHIFT - 10. - */ + * pages. PAGE_SHIFT converts bytes to pages, hence PAGE_SHIFT - 10. + */ set_new_target(new_target >> (PAGE_SHIFT - 10)); - } static int balloon_init_watcher(struct notifier_block *notifier, - unsigned long event, - void *data) + unsigned long event, + void *data) { int err; @@ -402,11 +401,10 @@ static int balloon_init_watcher(struct n printk(KERN_ERR "Failed to set balloon watcher\n"); return NOTIFY_DONE; - } static int balloon_write(struct file *file, const char __user *buffer, - unsigned long count, void *data) + unsigned long count, void *data) { char memstring[64], *endchar; unsigned long long target_bytes; @@ -430,7 +428,7 @@ static int balloon_write(struct file *fi } static int balloon_read(char *page, char **start, off_t off, - int count, int *eof, void *data) + int count, int *eof, void *data) { int len; diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Tue Jun 13 12:12:24 2006 -0600 @@ -105,24 +105,12 @@ static inline unsigned long vaddr(pendin (pending_grant_handles[vaddr_pagenr(_req, _seg)]) -#ifdef CONFIG_XEN_BLKDEV_TAP_BE -/* - * If the tap driver is used, we may get pages belonging to either the tap - * or (more likely) the real frontend. The backend must specify which domain - * a given page belongs to in update_va_mapping though. For the moment, - * the tap rewrites the ID field of the request to contain the request index - * and the id of the real front end domain. - */ -#define BLKTAP_COOKIE 0xbeadfeed -static inline domid_t ID_TO_DOM(unsigned long id) { return (id >> 16); } -#endif - static int do_block_io_op(blkif_t *blkif); static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req, pending_req_t *pending_req); static void make_response(blkif_t *blkif, unsigned long id, - unsigned short op, int st); + unsigned short op, int st); /****************************************************************** * misc small helpers @@ -446,7 +434,7 @@ static void dispatch_rw_block_io(blkif_t bio = biolist[nbio++] = bio_alloc(GFP_KERNEL, nseg-i); if (unlikely(bio == NULL)) goto fail_put_bio; - + bio->bi_bdev = preq.bdev; bio->bi_private = pending_req; bio->bi_end_io = end_block_io_op; @@ -483,7 +471,7 @@ static void dispatch_rw_block_io(blkif_t static void make_response(blkif_t *blkif, unsigned long id, - unsigned short op, int st) + unsigned short op, int st) { blkif_response_t *resp; unsigned long flags; diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/blkback/common.h --- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Tue Jun 13 12:12:24 2006 -0600 @@ -45,8 +45,9 @@ #include <xen/gnttab.h> #include <xen/driver_util.h> -#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \ - __FILE__ , __LINE__ , ## _a ) +#define DPRINTK(_f, _a...) \ + pr_debug("(file=%s, line=%d) " _f, \ + __FILE__ , __LINE__ , ## _a ) struct vbd { blkif_vdev_t handle; /* what the domain refers to this vbd as */ @@ -73,10 +74,6 @@ typedef struct blkif_st { /* Back pointer to the backend_info. */ struct backend_info *be; /* Private fields. */ -#ifdef CONFIG_XEN_BLKDEV_TAP_BE - /* Is this a blktap frontend */ - unsigned int is_blktap; -#endif spinlock_t blk_ring_lock; atomic_t refcnt; diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Tue Jun 13 12:12:24 2006 -0600 @@ -77,7 +77,7 @@ static ssize_t show_physical_device(stru struct device_attribute *attr, char *buf) { struct xenbus_device *dev = to_xenbus_device(_dev); - struct backend_info *be = dev->data; + struct backend_info *be = dev->dev.driver_data; return sprintf(buf, "%x:%x\n", be->major, be->minor); } DEVICE_ATTR(physical_device, S_IRUSR | S_IRGRP | S_IROTH, @@ -88,7 +88,7 @@ static ssize_t show_mode(struct device * char *buf) { struct xenbus_device *dev = to_xenbus_device(_dev); - struct backend_info *be = dev->data; + struct backend_info *be = dev->dev.driver_data; return sprintf(buf, "%s\n", be->mode); } DEVICE_ATTR(mode, S_IRUSR | S_IRGRP | S_IROTH, show_mode, NULL); @@ -96,7 +96,7 @@ DEVICE_ATTR(mode, S_IRUSR | S_IRGRP | S_ static int blkback_remove(struct xenbus_device *dev) { - struct backend_info *be = dev->data; + struct backend_info *be = dev->dev.driver_data; DPRINTK(""); @@ -116,7 +116,7 @@ static int blkback_remove(struct xenbus_ device_remove_file(&dev->dev, &dev_attr_mode); kfree(be); - dev->data = NULL; + dev->dev.driver_data = NULL; return 0; } @@ -138,7 +138,7 @@ static int blkback_probe(struct xenbus_d return -ENOMEM; } be->dev = dev; - dev->data = be; + dev->dev.driver_data = be; be->blkif = blkif_alloc(dev->otherend_id); if (IS_ERR(be->blkif)) { @@ -186,7 +186,7 @@ static void backend_changed(struct xenbu DPRINTK(""); - err = xenbus_scanf(XBT_NULL, dev->nodename, "physical-device", "%x:%x", + err = xenbus_scanf(XBT_NIL, dev->nodename, "physical-device", "%x:%x", &major, &minor); if (XENBUS_EXIST_ERR(err)) { /* Since this watch will fire once immediately after it is @@ -208,7 +208,7 @@ static void backend_changed(struct xenbu return; } - be->mode = xenbus_read(XBT_NULL, dev->nodename, "mode", NULL); + be->mode = xenbus_read(XBT_NIL, dev->nodename, "mode", NULL); if (IS_ERR(be->mode)) { err = PTR_ERR(be->mode); be->mode = NULL; @@ -249,7 +249,7 @@ static void frontend_changed(struct xenb static void frontend_changed(struct xenbus_device *dev, enum xenbus_state frontend_state) { - struct backend_info *be = dev->data; + struct backend_info *be = dev->dev.driver_data; int err; DPRINTK(""); @@ -299,7 +299,7 @@ static void frontend_changed(struct xenb */ static void connect(struct backend_info *be) { - xenbus_transaction_t xbt; + struct xenbus_transaction xbt; int err; struct xenbus_device *dev = be->dev; @@ -364,7 +364,7 @@ static int connect_ring(struct backend_i DPRINTK("%s", dev->otherend); - err = xenbus_gather(XBT_NULL, dev->otherend, "ring-ref", "%lu", &ring_ref, + err = xenbus_gather(XBT_NIL, dev->otherend, "ring-ref", "%lu", &ring_ref, "event-channel", "%u", &evtchn, NULL); if (err) { xenbus_dev_fatal(dev, err, diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Tue Jun 13 12:12:24 2006 -0600 @@ -83,7 +83,7 @@ static int blkfront_probe(struct xenbus_ struct blkfront_info *info; /* FIXME: Use dynamic device id if this is not set. */ - err = xenbus_scanf(XBT_NULL, dev->nodename, + err = xenbus_scanf(XBT_NIL, dev->nodename, "virtual-device", "%i", &vdevice); if (err != 1) { xenbus_dev_fatal(dev, err, "reading virtual-device"); @@ -107,12 +107,12 @@ static int blkfront_probe(struct xenbus_ /* Front end dir is a number, which is used as the id. */ info->handle = simple_strtoul(strrchr(dev->nodename,'/')+1, NULL, 0); - dev->data = info; + dev->dev.driver_data = info; err = talk_to_backend(dev, info); if (err) { kfree(info); - dev->data = NULL; + dev->dev.driver_data = NULL; return err; } @@ -128,7 +128,7 @@ static int blkfront_probe(struct xenbus_ */ static int blkfront_resume(struct xenbus_device *dev) { - struct blkfront_info *info = dev->data; + struct blkfront_info *info = dev->dev.driver_data; int err; DPRINTK("blkfront_resume: %s\n", dev->nodename); @@ -148,7 +148,7 @@ static int talk_to_backend(struct xenbus struct blkfront_info *info) { const char *message = NULL; - xenbus_transaction_t xbt; + struct xenbus_transaction xbt; int err; /* Create shared ring, alloc event channel. */ @@ -249,7 +249,7 @@ static void backend_changed(struct xenbu static void backend_changed(struct xenbus_device *dev, enum xenbus_state backend_state) { - struct blkfront_info *info = dev->data; + struct blkfront_info *info = dev->dev.driver_data; struct block_device *bd; DPRINTK("blkfront:backend_changed.\n"); @@ -303,7 +303,7 @@ static void connect(struct blkfront_info DPRINTK("blkfront.c:connect:%s.\n", info->xbdev->otherend); - err = xenbus_gather(XBT_NULL, info->xbdev->otherend, + err = xenbus_gather(XBT_NIL, info->xbdev->otherend, "sectors", "%lu", §ors, "info", "%u", &binfo, "sector-size", "%lu", §or_size, @@ -318,7 +318,7 @@ static void connect(struct blkfront_info err = xlvbd_add(sectors, info->vdevice, binfo, sector_size, info); if (err) { xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s", - info->xbdev->otherend); + info->xbdev->otherend); return; } @@ -341,7 +341,7 @@ static void connect(struct blkfront_info */ static void blkfront_closing(struct xenbus_device *dev) { - struct blkfront_info *info = dev->data; + struct blkfront_info *info = dev->dev.driver_data; DPRINTK("blkfront_closing: %s removed\n", dev->nodename); @@ -353,7 +353,7 @@ static void blkfront_closing(struct xenb static int blkfront_remove(struct xenbus_device *dev) { - struct blkfront_info *info = dev->data; + struct blkfront_info *info = dev->dev.driver_data; DPRINTK("blkfront_remove: %s removed\n", dev->nodename); @@ -444,7 +444,7 @@ int blkif_release(struct inode *inode, s int blkif_ioctl(struct inode *inode, struct file *filep, - unsigned command, unsigned long argument) + unsigned command, unsigned long argument) { int i; @@ -452,10 +452,6 @@ int blkif_ioctl(struct inode *inode, str command, (long)argument, inode->i_rdev); switch (command) { - case HDIO_GETGEO: - /* return ENOSYS to use defaults */ - return -ENOSYS; - case CDROMMULTISESSION: DPRINTK("FIXME: support multisession CDs later\n"); for (i = 0; i < sizeof(struct cdrom_multisession); i++) @@ -469,6 +465,23 @@ int blkif_ioctl(struct inode *inode, str return -EINVAL; /* same return as native Linux */ } + return 0; +} + + +int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg) +{ + /* We don't have real geometry info, but let's at least return + values consistent with the size of the device */ + sector_t nsect = get_capacity(bd->bd_disk); + sector_t cylinders = nsect; + + hg->heads = 0xff; + hg->sectors = 0x3f; + sector_div(cylinders, hg->heads * hg->sectors); + hg->cylinders = cylinders; + if ((sector_t)(hg->cylinders + 1) * hg->heads * hg->sectors < nsect) + hg->cylinders = 0xffff; return 0; } diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/blkfront/block.h --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Tue Jun 13 12:12:24 2006 -0600 @@ -59,15 +59,15 @@ #include <asm/uaccess.h> #if 1 -#define IPRINTK(fmt, args...) \ - printk(KERN_INFO "xen_blk: " fmt, ##args) +#define IPRINTK(fmt, args...) \ + printk(KERN_INFO "xen_blk: " fmt, ##args) #else #define IPRINTK(fmt, args...) ((void)0) #endif #if 1 -#define WPRINTK(fmt, args...) \ - printk(KERN_WARNING "xen_blk: " fmt, ##args) +#define WPRINTK(fmt, args...) \ + printk(KERN_WARNING "xen_blk: " fmt, ##args) #else #define WPRINTK(fmt, args...) ((void)0) #endif @@ -139,7 +139,8 @@ extern int blkif_open(struct inode *inod extern int blkif_open(struct inode *inode, struct file *filep); extern int blkif_release(struct inode *inode, struct file *filep); extern int blkif_ioctl(struct inode *inode, struct file *filep, - unsigned command, unsigned long argument); + unsigned command, unsigned long argument); +extern int blkif_getgeo(struct block_device *, struct hd_geometry *); extern int blkif_check(dev_t dev); extern int blkif_revalidate(dev_t dev); extern void do_blkif_request (request_queue_t *rq); diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c Tue Jun 13 12:12:24 2006 -0600 @@ -91,6 +91,7 @@ static struct block_device_operations xl .open = blkif_open, .release = blkif_release, .ioctl = blkif_ioctl, + .getgeo = blkif_getgeo }; DEFINE_SPINLOCK(blkif_io_lock); diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/char/mem.c --- a/linux-2.6-xen-sparse/drivers/xen/char/mem.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/char/mem.c Tue Jun 13 12:12:24 2006 -0600 @@ -30,10 +30,10 @@ static inline int uncached_access(struct file *file) { - if (file->f_flags & O_SYNC) - return 1; - /* Xen sets correct MTRR type on non-RAM for us. */ - return 0; + if (file->f_flags & O_SYNC) + return 1; + /* Xen sets correct MTRR type on non-RAM for us. */ + return 0; } /* diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/console/console.c --- a/linux-2.6-xen-sparse/drivers/xen/console/console.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c Tue Jun 13 12:12:24 2006 -0600 @@ -364,7 +364,7 @@ void xencons_tx(void) /* Privileged receive callback and transmit kicker. */ static irqreturn_t xencons_priv_interrupt(int irq, void *dev_id, - struct pt_regs *regs) + struct pt_regs *regs) { static char rbuf[16]; int l; diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/core/Makefile --- a/linux-2.6-xen-sparse/drivers/xen/core/Makefile Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/core/Makefile Tue Jun 13 12:12:24 2006 -0600 @@ -2,11 +2,13 @@ # Makefile for the linux kernel. # -obj-y := evtchn.o reboot.o gnttab.o features.o +obj-y := evtchn.o gnttab.o features.o -obj-$(CONFIG_PROC_FS) += xen_proc.o -obj-$(CONFIG_NET) += skbuff.o -obj-$(CONFIG_SMP) += smpboot.o -obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o -obj-$(CONFIG_SYSFS) += hypervisor_sysfs.o -obj-$(CONFIG_XEN_SYSFS) += xen_sysfs.o +obj-$(CONFIG_PROC_FS) += xen_proc.o +obj-$(CONFIG_SYSFS) += hypervisor_sysfs.o +obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o +obj-$(CONFIG_XEN_SYSFS) += xen_sysfs.o +obj-$(CONFIG_IA64) += xenia64_init.o +obj-$(CONFIG_XEN_SKBUFF) += skbuff.o +obj-$(CONFIG_XEN_REBOOT) += reboot.o +obj-$(CONFIG_XEN_SMPBOOT) += smpboot.o diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/core/cpu_hotplug.c --- a/linux-2.6-xen-sparse/drivers/xen/core/cpu_hotplug.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/core/cpu_hotplug.c Tue Jun 13 12:12:24 2006 -0600 @@ -34,7 +34,7 @@ static void vcpu_hotplug(unsigned int cp return; sprintf(dir, "cpu/%d", cpu); - err = xenbus_scanf(XBT_NULL, dir, "availability", "%s", state); + err = xenbus_scanf(XBT_NIL, dir, "availability", "%s", state); if (err != 1) { printk(KERN_ERR "XENBUS: Unable to read cpu state\n"); return; diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/core/evtchn.c --- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c Tue Jun 13 12:12:24 2006 -0600 @@ -54,7 +54,8 @@ static DEFINE_SPINLOCK(irq_mapping_updat static DEFINE_SPINLOCK(irq_mapping_update_lock); /* IRQ <-> event-channel mappings. */ -static int evtchn_to_irq[NR_EVENT_CHANNELS] = {[0 ... NR_EVENT_CHANNELS-1] = -1}; +static int evtchn_to_irq[NR_EVENT_CHANNELS] = { + [0 ... NR_EVENT_CHANNELS-1] = -1 }; /* Packed IRQ information: binding type, sub-type index, and event channel. */ static u32 irq_info[NR_IRQS]; @@ -120,6 +121,11 @@ static inline unsigned long active_evtch static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) { + int irq = evtchn_to_irq[chn]; + + BUG_ON(irq == -1); + set_native_irq_info(irq, cpumask_of_cpu(cpu)); + clear_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu_evtchn[chn]]); set_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu]); cpu_evtchn[chn] = cpu; @@ -127,7 +133,12 @@ static void bind_evtchn_to_cpu(unsigned static void init_evtchn_cpu_bindings(void) { + int i; + /* By default all event channels notify CPU#0. */ + for (i = 0; i < NR_IRQS; i++) + set_native_irq_info(i, cpumask_of_cpu(0)); + memset(cpu_evtchn, 0, sizeof(cpu_evtchn)); memset(cpu_evtchn_mask[0], ~0, sizeof(cpu_evtchn_mask[0])); } @@ -430,25 +441,14 @@ void unbind_from_irqhandler(unsigned int } EXPORT_SYMBOL_GPL(unbind_from_irqhandler); -#ifdef CONFIG_SMP -static void do_nothing_function(void *ign) -{ -} -#endif - /* Rebind an evtchn so that it gets delivered to a specific cpu */ static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu) { struct evtchn_bind_vcpu bind_vcpu; - int evtchn; - - spin_lock(&irq_mapping_update_lock); - - evtchn = evtchn_from_irq(irq); - if (!VALID_EVTCHN(evtchn)) { - spin_unlock(&irq_mapping_update_lock); + int evtchn = evtchn_from_irq(irq); + + if (!VALID_EVTCHN(evtchn)) return; - } /* Send future instances of this interrupt to other vcpu. */ bind_vcpu.port = evtchn; @@ -461,21 +461,6 @@ static void rebind_irq_to_cpu(unsigned i */ if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0) bind_evtchn_to_cpu(evtchn, tcpu); - - spin_unlock(&irq_mapping_update_lock); - - /* - * Now send the new target processor a NOP IPI. When this returns, it - * will check for any pending interrupts, and so service any that got - * delivered to the wrong processor by mistake. - * - * XXX: The only time this is called with interrupts disabled is from - * the hotplug/hotunplug path. In that case, all cpus are stopped with - * interrupts disabled, and the missed interrupts will be picked up - * when they start again. This is kind of a hack. - */ - if (!irqs_disabled()) - smp_call_function(do_nothing_function, NULL, 0, 0); } @@ -597,8 +582,8 @@ static unsigned int startup_pirq(unsigne pirq_query_unmask(irq_to_pirq(irq)); + evtchn_to_irq[evtchn] = irq; bind_evtchn_to_cpu(evtchn, 0); - evtchn_to_irq[evtchn] = irq; irq_info[irq] = mk_irq_info(IRQT_PIRQ, irq, evtchn); out: @@ -678,7 +663,14 @@ static struct hw_interrupt_type pirq_typ set_affinity_irq }; -void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) +int irq_ignore_unhandled(unsigned int irq) +{ + struct physdev_irq_status_query irq_status = { .irq = irq }; + (void)HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status); + return !!(irq_status.flags & XENIRQSTAT_shared); +} + +void resend_irq_on_evtchn(struct hw_interrupt_type *h, unsigned int i) { int evtchn = evtchn_from_irq(i); shared_info_t *s = HYPERVISOR_shared_info; @@ -709,6 +701,8 @@ void unmask_evtchn(int port) shared_info_t *s = HYPERVISOR_shared_info; unsigned int cpu = smp_processor_id(); vcpu_info_t *vcpu_info = &s->vcpu_info[cpu]; + + BUG_ON(!irqs_disabled()); /* Slow path (hypercall) if this is a non-local port. */ if (unlikely(cpu != cpu_from_evtchn(port))) { @@ -726,11 +720,8 @@ void unmask_evtchn(int port) */ if (synch_test_bit(port, &s->evtchn_pending[0]) && !synch_test_and_set_bit(port / BITS_PER_LONG, - &vcpu_info->evtchn_pending_sel)) { + &vcpu_info->evtchn_pending_sel)) vcpu_info->evtchn_upcall_pending = 1; - if (!vcpu_info->evtchn_upcall_mask) - force_evtchn_callback(); - } } EXPORT_SYMBOL_GPL(unmask_evtchn); diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/core/gnttab.c --- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c Tue Jun 13 12:12:24 2006 -0600 @@ -1,27 +1,27 @@ /****************************************************************************** * gnttab.c - * + * * Granting foreign access to our memory reservation. - * + * * Copyright (c) 2005, Christopher Clark * Copyright (c) 2004-2005, K A Fraser - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation; or, when distributed * separately from the Linux kernel or incorporated into other * software packages, subject to the following license: - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this source file (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -36,45 +36,17 @@ #include <linux/sched.h> #include <linux/mm.h> #include <linux/vmalloc.h> +#include <xen/interface/xen.h> +#include <xen/gnttab.h> #include <asm/pgtable.h> -#include <xen/interface/xen.h> #include <asm/uaccess.h> -#include <xen/gnttab.h> #include <asm/synch_bitops.h> - -#if 1 -#define ASSERT(_p) \ - if (!(_p)) { printk(KERN_ALERT"Assertion '%s': line %d, file %s\n", \ - #_p , __LINE__, __FILE__); *(int*)0=0; } -#else -#define ASSERT(_p) ((void)0) -#endif - -#define WPRINTK(fmt, args...) \ - printk(KERN_WARNING "xen_grant: " fmt, ##args) - - -EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access); -EXPORT_SYMBOL_GPL(gnttab_end_foreign_access_ref); -EXPORT_SYMBOL_GPL(gnttab_end_foreign_access); -EXPORT_SYMBOL_GPL(gnttab_query_foreign_access); -EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer); -EXPORT_SYMBOL_GPL(gnttab_end_foreign_transfer_ref); -EXPORT_SYMBOL_GPL(gnttab_end_foreign_transfer); -EXPORT_SYMBOL_GPL(gnttab_alloc_grant_references); -EXPORT_SYMBOL_GPL(gnttab_free_grant_references); -EXPORT_SYMBOL_GPL(gnttab_free_grant_reference); -EXPORT_SYMBOL_GPL(gnttab_empty_grant_references); -EXPORT_SYMBOL_GPL(gnttab_claim_grant_reference); -EXPORT_SYMBOL_GPL(gnttab_release_grant_reference); -EXPORT_SYMBOL_GPL(gnttab_request_free_callback); -EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_ref); -EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer_ref); /* External tools reserve first few grant table entries. */ #define NR_RESERVED_ENTRIES 8 -#define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t)) +#define NR_GRANT_ENTRIES \ + (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(struct grant_entry)) #define GNTTAB_LIST_END (NR_GRANT_ENTRIES + 1) static grant_ref_t gnttab_list[NR_GRANT_ENTRIES]; @@ -82,12 +54,11 @@ static grant_ref_t gnttab_free_head; static grant_ref_t gnttab_free_head; static DEFINE_SPINLOCK(gnttab_list_lock); -static grant_entry_t *shared = NULL; - -static struct gnttab_free_callback *gnttab_free_callback_list = NULL; - -static int -get_free_entries(int count) +static struct grant_entry *shared; + +static struct gnttab_free_callback *gnttab_free_callback_list; + +static int get_free_entries(int count) { unsigned long flags; int ref; @@ -109,8 +80,7 @@ get_free_entries(int count) #define get_free_entry() get_free_entries(1) -static void -do_free_callbacks(void) +static void do_free_callbacks(void) { struct gnttab_free_callback *callback, *next; @@ -130,15 +100,13 @@ do_free_callbacks(void) } } -static inline void -check_free_callbacks(void) +static inline void check_free_callbacks(void) { if (unlikely(gnttab_free_callback_list)) do_free_callbacks(); } -static void -put_free_entry(grant_ref_t ref) +static void put_free_entry(grant_ref_t ref) { unsigned long flags; spin_lock_irqsave(&gnttab_list_lock, flags); @@ -153,8 +121,8 @@ put_free_entry(grant_ref_t ref) * Public grant-issuing interface functions */ -int -gnttab_grant_foreign_access(domid_t domid, unsigned long frame, int readonly) +int gnttab_grant_foreign_access(domid_t domid, unsigned long frame, + int readonly) { int ref; @@ -168,20 +136,20 @@ gnttab_grant_foreign_access(domid_t domi return ref; } - -void -gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid, - unsigned long frame, int readonly) +EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access); + +void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid, + unsigned long frame, int readonly) { shared[ref].frame = frame; shared[ref].domid = domid; wmb(); shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0); } - - -int -gnttab_query_foreign_access(grant_ref_t ref) +EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_ref); + + +int gnttab_query_foreign_access(grant_ref_t ref) { u16 nflags; @@ -189,9 +157,9 @@ gnttab_query_foreign_access(grant_ref_t return (nflags & (GTF_reading|GTF_writing)); } - -int -gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly) +EXPORT_SYMBOL_GPL(gnttab_query_foreign_access); + +int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly) { u16 flags, nflags; @@ -206,15 +174,15 @@ gnttab_end_foreign_access_ref(grant_ref_ return 1; } - -void -gnttab_end_foreign_access(grant_ref_t ref, int readonly, unsigned long page) +EXPORT_SYMBOL_GPL(gnttab_end_foreign_access_ref); + +void gnttab_end_foreign_access(grant_ref_t ref, int readonly, + unsigned long page) { if (gnttab_end_foreign_access_ref(ref, readonly)) { put_free_entry(ref); - if (page != 0) { + if (page != 0) free_page(page); - } } else { /* XXX This needs to be fixed so that the ref and page are placed on a list to be freed up later. */ @@ -222,9 +190,9 @@ gnttab_end_foreign_access(grant_ref_t re "WARNING: leaking g.e. and page still in use!\n"); } } - -int -gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn) +EXPORT_SYMBOL_GPL(gnttab_end_foreign_access); + +int gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn) { int ref; @@ -234,27 +202,27 @@ gnttab_grant_foreign_transfer(domid_t do return ref; } - -void -gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid, - unsigned long pfn) +EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer); + +void gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid, + unsigned long pfn) { shared[ref].frame = pfn; shared[ref].domid = domid; wmb(); shared[ref].flags = GTF_accept_transfer; } - -unsigned long -gnttab_end_foreign_transfer_ref(grant_ref_t ref) +EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer_ref); + +unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref) { unsigned long frame; u16 flags; /* - * If a transfer is not even yet started, try to reclaim the grant - * reference and return failure (== 0). - */ + * If a transfer is not even yet started, try to reclaim the grant + * reference and return failure (== 0). + */ while (!((flags = shared[ref].flags) & GTF_transfer_committed)) { if (synch_cmpxchg(&shared[ref].flags, flags, 0) == flags) return 0; @@ -274,24 +242,23 @@ gnttab_end_foreign_transfer_ref(grant_re return frame; } - -unsigned long -gnttab_end_foreign_transfer(grant_ref_t ref) +EXPORT_SYMBOL_GPL(gnttab_end_foreign_transfer_ref); + +unsigned long gnttab_end_foreign_transfer(grant_ref_t ref) { unsigned long frame = gnttab_end_foreign_transfer_ref(ref); put_free_entry(ref); return frame; } - -void -gnttab_free_grant_reference(grant_ref_t ref) -{ - +EXPORT_SYMBOL_GPL(gnttab_end_foreign_transfer); + +void gnttab_free_grant_reference(grant_ref_t ref) +{ put_free_entry(ref); } - -void -gnttab_free_grant_references(grant_ref_t head) +EXPORT_SYMBOL_GPL(gnttab_free_grant_reference); + +void gnttab_free_grant_references(grant_ref_t head) { grant_ref_t ref; unsigned long flags; @@ -310,9 +277,9 @@ gnttab_free_grant_references(grant_ref_t check_free_callbacks(); spin_unlock_irqrestore(&gnttab_list_lock, flags); } - -int -gnttab_alloc_grant_references(u16 count, grant_ref_t *head) +EXPORT_SYMBOL_GPL(gnttab_free_grant_references); + +int gnttab_alloc_grant_references(u16 count, grant_ref_t *head) { int h = get_free_entries(count); @@ -323,15 +290,15 @@ gnttab_alloc_grant_references(u16 count, return 0; } - -int -gnttab_empty_grant_references(const grant_ref_t *private_head) +EXPORT_SYMBOL_GPL(gnttab_alloc_grant_references); + +int gnttab_empty_grant_references(const grant_ref_t *private_head) { return (*private_head == GNTTAB_LIST_END); } - -int -gnttab_claim_grant_reference(grant_ref_t *private_head) +EXPORT_SYMBOL_GPL(gnttab_empty_grant_references); + +int gnttab_claim_grant_reference(grant_ref_t *private_head) { grant_ref_t g = *private_head; if (unlikely(g == GNTTAB_LIST_END)) @@ -339,17 +306,18 @@ gnttab_claim_grant_reference(grant_ref_t *private_head = gnttab_list[g]; return g; } - -void -gnttab_release_grant_reference(grant_ref_t *private_head, grant_ref_t release) +EXPORT_SYMBOL_GPL(gnttab_claim_grant_reference); + +void gnttab_release_grant_reference(grant_ref_t *private_head, + grant_ref_t release) { gnttab_list[release] = *private_head; *private_head = release; } - -void -gnttab_request_free_callback(struct gnttab_free_callback *callback, - void (*fn)(void *), void *arg, u16 count) +EXPORT_SYMBOL_GPL(gnttab_release_grant_reference); + +void gnttab_request_free_callback(struct gnttab_free_callback *callback, + void (*fn)(void *), void *arg, u16 count) { unsigned long flags; spin_lock_irqsave(&gnttab_list_lock, flags); @@ -361,9 +329,10 @@ gnttab_request_free_callback(struct gntt callback->next = gnttab_free_callback_list; gnttab_free_callback_list = callback; check_free_callbacks(); - out: +out: spin_unlock_irqrestore(&gnttab_list_lock, flags); } +EXPORT_SYMBOL_GPL(gnttab_request_free_callback); #ifndef __ia64__ static int map_pte_fn(pte_t *pte, struct page *pmd_page, @@ -377,7 +346,7 @@ static int map_pte_fn(pte_t *pte, struct } static int unmap_pte_fn(pte_t *pte, struct page *pmd_page, - unsigned long addr, void *data) + unsigned long addr, void *data) { set_pte_at(&init_mm, addr, pte, __pte(0)); @@ -385,10 +354,9 @@ static int unmap_pte_fn(pte_t *pte, stru } #endif -int -gnttab_resume(void) -{ - gnttab_setup_table_t setup; +int gnttab_resume(void) +{ + struct gnttab_setup_table setup; unsigned long frames[NR_GRANT_FRAMES]; int rc; #ifndef __ia64__ @@ -424,8 +392,7 @@ gnttab_resume(void) return 0; } -int -gnttab_suspend(void) +int gnttab_suspend(void) { #ifndef __ia64__ @@ -437,8 +404,7 @@ gnttab_suspend(void) return 0; } -static int __init -gnttab_init(void) +static int __init gnttab_init(void) { int i; diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/core/reboot.c --- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c Tue Jun 13 12:12:24 2006 -0600 @@ -250,7 +250,7 @@ static void shutdown_handler(struct xenb const char **vec, unsigned int len) { char *str; - xenbus_transaction_t xbt; + struct xenbus_transaction xbt; int err; if (shutting_down != SHUTDOWN_INVALID) @@ -298,7 +298,7 @@ static void sysrq_handler(struct xenbus_ unsigned int len) { char sysrq_key = '\0'; - xenbus_transaction_t xbt; + struct xenbus_transaction xbt; int err; again: @@ -336,8 +336,8 @@ static struct xenbus_watch sysrq_watch = }; static int setup_shutdown_watcher(struct notifier_block *notifier, - unsigned long event, - void *data) + unsigned long event, + void *data) { int err; diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/core/smpboot.c --- a/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c Tue Jun 13 12:12:24 2006 -0600 @@ -89,9 +89,8 @@ void __init prefill_possible_map(void) for (i = 0; i < NR_CPUS; i++) { rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL); - if (rc == -ENOENT) - break; - cpu_set(i, cpu_possible_map); + if (rc >= 0) + cpu_set(i, cpu_possible_map); } } @@ -209,7 +208,7 @@ void cpu_initialize_context(unsigned int ctxt.failsafe_callback_cs = __KERNEL_CS; ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback; - ctxt.ctrlreg[3] = virt_to_mfn(swapper_pg_dir) << PAGE_SHIFT; + ctxt.ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(swapper_pg_dir)); #else /* __x86_64__ */ ctxt.user_regs.cs = __KERNEL_CS; ctxt.user_regs.esp = idle->thread.rsp0 - sizeof(struct pt_regs); @@ -221,7 +220,7 @@ void cpu_initialize_context(unsigned int ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback; ctxt.syscall_callback_eip = (unsigned long)system_call; - ctxt.ctrlreg[3] = virt_to_mfn(init_level4_pgt) << PAGE_SHIFT; + ctxt.ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(init_level4_pgt)); ctxt.gs_base_kernel = (unsigned long)(cpu_pda(cpu)); #endif diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c --- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Tue Jun 13 12:12:24 2006 -0600 @@ -93,7 +93,7 @@ void evtchn_device_upcall(int port) } static ssize_t evtchn_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) + size_t count, loff_t *ppos) { int rc; unsigned int c, p, bytes1 = 0, bytes2 = 0; @@ -153,7 +153,7 @@ static ssize_t evtchn_read(struct file * } static ssize_t evtchn_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) + size_t count, loff_t *ppos) { int rc, i; evtchn_port_t *kbuf = (evtchn_port_t *)__get_free_page(GFP_KERNEL); @@ -201,7 +201,7 @@ static void evtchn_bind_to_user(struct p } static int evtchn_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { int rc; struct per_user_data *u = file->private_data; diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/netback/common.h --- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Tue Jun 13 12:12:24 2006 -0600 @@ -47,12 +47,13 @@ #include <xen/gnttab.h> #include <xen/driver_util.h> -#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \ - __FILE__ , __LINE__ , ## _a ) -#define IPRINTK(fmt, args...) \ - printk(KERN_INFO "xen_net: " fmt, ##args) -#define WPRINTK(fmt, args...) \ - printk(KERN_WARNING "xen_net: " fmt, ##args) +#define DPRINTK(_f, _a...) \ + pr_debug("(file=%s, line=%d) " _f, \ + __FILE__ , __LINE__ , ## _a ) +#define IPRINTK(fmt, args...) \ + printk(KERN_INFO "xen_net: " fmt, ##args) +#define WPRINTK(fmt, args...) \ + printk(KERN_WARNING "xen_net: " fmt, ##args) typedef struct netif_st { /* Unique identifier for this interface. */ diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/netback/interface.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Tue Jun 13 12:12:24 2006 -0600 @@ -124,7 +124,7 @@ netif_t *netif_alloc(domid_t domid, unsi * Initialise a dummy MAC address. We choose the numerically * largest non-broadcast address to prevent the address getting * stolen by an Ethernet bridge for STP purposes. - * (FE:FF:FF:FF:FF:FF) + * (FE:FF:FF:FF:FF:FF) */ memset(dev->dev_addr, 0xFF, ETH_ALEN); dev->dev_addr[0] &= ~0x01; diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/netback/loopback.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Tue Jun 13 12:12:24 2006 -0600 @@ -146,11 +146,13 @@ static void loopback_construct(struct ne dev->hard_start_xmit = loopback_start_xmit; dev->get_stats = loopback_get_stats; dev->set_multicast_list = loopback_set_multicast_list; + dev->change_mtu = NULL; /* allow arbitrary mtu */ dev->tx_queue_len = 0; dev->features = (NETIF_F_HIGHDMA | NETIF_F_LLTX | + NETIF_F_SG | NETIF_F_IP_CSUM); SET_ETHTOOL_OPS(dev, &network_ethtool_ops); diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/netback/netback.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Tue Jun 13 12:12:24 2006 -0600 @@ -43,14 +43,14 @@ static void netif_idx_release(u16 pendin static void netif_idx_release(u16 pending_idx); static void netif_page_release(struct page *page); static void make_tx_response(netif_t *netif, - u16 id, - s8 st); + u16 id, + s8 st); static int make_rx_response(netif_t *netif, - u16 id, - s8 st, - u16 offset, - u16 size, - u16 flags); + u16 id, + s8 st, + u16 offset, + u16 size, + u16 flags); static void net_tx_action(unsigned long unused); static DECLARE_TASKLET(net_tx_tasklet, net_tx_action, 0); @@ -329,9 +329,9 @@ static void net_rx_action(unsigned long DPRINTK("Bad status %d from grant transfer to DOM%u\n", gop->status, netif->domid); /* - * Page no longer belongs to us unless GNTST_bad_page, - * but that should be a fatal error anyway. - */ + * Page no longer belongs to us unless GNTST_bad_page, + * but that should be a fatal error anyway. + */ BUG_ON(gop->status == GNTST_bad_page); status = NETIF_RSP_ERROR; } @@ -458,6 +458,9 @@ inline static void net_tx_action_dealloc dc = dealloc_cons; dp = dealloc_prod; + /* Ensure we see all indexes enqueued by netif_idx_release(). */ + smp_rmb(); + /* * Free up any grants we have finished using */ @@ -480,10 +483,181 @@ inline static void net_tx_action_dealloc make_tx_response(netif, pending_tx_info[pending_idx].req.id, NETIF_RSP_OKAY); - + pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx; netif_put(netif); + } +} + +static void netbk_tx_err(netif_t *netif, RING_IDX end) +{ + RING_IDX cons = netif->tx.req_cons; + + do { + netif_tx_request_t *txp = RING_GET_REQUEST(&netif->tx, cons); + make_tx_response(netif, txp->id, NETIF_RSP_ERROR); + } while (++cons < end); + netif->tx.req_cons = cons; + netif_schedule_work(netif); + netif_put(netif); +} + +static int netbk_count_requests(netif_t *netif, netif_tx_request_t *txp, + int work_to_do) +{ + netif_tx_request_t *first = txp; + RING_IDX cons = netif->tx.req_cons; + int frags = 1; + + while (txp->flags & NETTXF_more_data) { + if (frags >= work_to_do) { + DPRINTK("Need more frags\n"); + return -frags; + } + + txp = RING_GET_REQUEST(&netif->tx, cons + frags); + if (txp->size > first->size) { + DPRINTK("Frags galore\n"); + return -frags; + } + + first->size -= txp->size; + frags++; + + if (unlikely((txp->offset + txp->size) > PAGE_SIZE)) { + DPRINTK("txp->offset: %x, size: %u\n", + txp->offset, txp->size); + return -frags; + } + } + + return frags; +} + +static gnttab_map_grant_ref_t *netbk_get_requests(netif_t *netif, + struct sk_buff *skb, + gnttab_map_grant_ref_t *mop) +{ + struct skb_shared_info *shinfo = skb_shinfo(skb); + skb_frag_t *frags = shinfo->frags; + netif_tx_request_t *txp; + unsigned long pending_idx = *((u16 *)skb->data); + RING_IDX cons = netif->tx.req_cons + 1; + int i, start; + + /* Skip first skb fragment if it is on same page as header fragment. */ + start = ((unsigned long)shinfo->frags[0].page == pending_idx); + + for (i = start; i < shinfo->nr_frags; i++) { + txp = RING_GET_REQUEST(&netif->tx, cons++); + pending_idx = pending_ring[MASK_PEND_IDX(pending_cons++)]; + + gnttab_set_map_op(mop++, MMAP_VADDR(pending_idx), + GNTMAP_host_map | GNTMAP_readonly, + txp->gref, netif->domid); + + memcpy(&pending_tx_info[pending_idx].req, txp, sizeof(*txp)); + netif_get(netif); + pending_tx_info[pending_idx].netif = netif; + frags[i].page = (void *)pending_idx; + } + + return mop; +} + +static int netbk_tx_check_mop(struct sk_buff *skb, + gnttab_map_grant_ref_t **mopp) +{ + gnttab_map_grant_ref_t *mop = *mopp; + int pending_idx = *((u16 *)skb->data); + netif_t *netif = pending_tx_info[pending_idx].netif; + netif_tx_request_t *txp; + struct skb_shared_info *shinfo = skb_shinfo(skb); + int nr_frags = shinfo->nr_frags; + int i, err, start; + + /* Check status of header. */ + err = mop->status; + if (unlikely(err)) { + txp = &pending_tx_info[pending_idx].req; + make_tx_response(netif, txp->id, NETIF_RSP_ERROR); + pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx; + netif_put(netif); + } else { + set_phys_to_machine( + __pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT, + FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT)); + grant_tx_handle[pending_idx] = mop->handle; + } + + /* Skip first skb fragment if it is on same page as header fragment. */ + start = ((unsigned long)shinfo->frags[0].page == pending_idx); + + for (i = start; i < nr_frags; i++) { + int j, newerr; + + pending_idx = (unsigned long)shinfo->frags[i].page; + + /* Check error status: if okay then remember grant handle. */ + newerr = (++mop)->status; + if (likely(!newerr)) { + set_phys_to_machine( + __pa(MMAP_VADDR(pending_idx))>>PAGE_SHIFT, + FOREIGN_FRAME(mop->dev_bus_addr>>PAGE_SHIFT)); + grant_tx_handle[pending_idx] = mop->handle; + /* Had a previous error? Invalidate this fragment. */ + if (unlikely(err)) + netif_idx_release(pending_idx); + continue; + } + + /* Error on this fragment: respond to client with an error. */ + txp = &pending_tx_info[pending_idx].req; + make_tx_response(netif, txp->id, NETIF_RSP_ERROR); + pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx; + netif_put(netif); + + /* Not the first error? Preceding frags already invalidated. */ + if (err) + continue; + + /* First error: invalidate header and preceding fragments. */ + pending_idx = *((u16 *)skb->data); + netif_idx_release(pending_idx); + for (j = start; j < i; j++) { + pending_idx = (unsigned long)shinfo->frags[i].page; + netif_idx_release(pending_idx); + } + + /* Remember the error: invalidate all subsequent fragments. */ + err = newerr; + } + + *mopp = mop + 1; + return err; +} + +static void netbk_fill_frags(struct sk_buff *skb) +{ + struct skb_shared_info *shinfo = skb_shinfo(skb); + int nr_frags = shinfo->nr_frags; + int i; + + for (i = 0; i < nr_frags; i++) { + skb_frag_t *frag = shinfo->frags + i; + netif_tx_request_t *txp; + unsigned long pending_idx; + + pending_idx = (unsigned long)frag->page; + txp = &pending_tx_info[pending_idx].req; + frag->page = virt_to_page(MMAP_VADDR(pending_idx)); + frag->size = txp->size; + frag->page_offset = txp->offset; + + skb->len += txp->size; + skb->data_len += txp->size; + skb->truesize += txp->size; } } @@ -504,7 +678,7 @@ static void net_tx_action(unsigned long net_tx_action_dealloc(); mop = tx_map_ops; - while ((NR_PENDING_REQS < MAX_PENDING_REQS) && + while (((NR_PENDING_REQS + MAX_SKB_FRAGS) < MAX_PENDING_REQS) && !list_empty(&net_schedule_list)) { /* Get a netif from the list with work to do. */ ent = net_schedule_list.next; @@ -552,38 +726,44 @@ static void net_tx_action(unsigned long } netif->remaining_credit -= txreq.size; - netif->tx.req_cons++; - - netif_schedule_work(netif); - - if (unlikely(txreq.size < ETH_HLEN) || - unlikely(txreq.size > ETH_FRAME_LEN)) { + ret = netbk_count_requests(netif, &txreq, work_to_do); + if (unlikely(ret < 0)) { + netbk_tx_err(netif, i - ret); + continue; + } + i += ret; + + if (unlikely(ret > MAX_SKB_FRAGS + 1)) { + DPRINTK("Too many frags\n"); + netbk_tx_err(netif, i); + continue; + } + + if (unlikely(txreq.size < ETH_HLEN)) { DPRINTK("Bad packet size: %d\n", txreq.size); - make_tx_response(netif, txreq.id, NETIF_RSP_ERROR); - netif_put(netif); + netbk_tx_err(netif, i); continue; } /* No crossing a page as the payload mustn't fragment. */ - if (unlikely((txreq.offset + txreq.size) >= PAGE_SIZE)) { + if (unlikely((txreq.offset + txreq.size) > PAGE_SIZE)) { DPRINTK("txreq.offset: %x, size: %u, end: %lu\n", txreq.offset, txreq.size, (txreq.offset &~PAGE_MASK) + txreq.size); - make_tx_response(netif, txreq.id, NETIF_RSP_ERROR); - netif_put(netif); + netbk_tx_err(netif, i); continue; } pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)]; - data_len = (txreq.size > PKT_PROT_LEN) ? + data_len = (txreq.size > PKT_PROT_LEN && + ret < MAX_SKB_FRAGS + 1) ? PKT_PROT_LEN : txreq.size; skb = alloc_skb(data_len+16, GFP_ATOMIC); if (unlikely(skb == NULL)) { DPRINTK("Can't allocate a skb in start_xmit.\n"); - make_tx_response(netif, txreq.id, NETIF_RSP_ERROR); - netif_put(netif); + netbk_tx_err(netif, i); break; } @@ -600,9 +780,23 @@ static void net_tx_action(unsigned long pending_tx_info[pending_idx].netif = netif; *((u16 *)skb->data) = pending_idx; + __skb_put(skb, data_len); + + skb_shinfo(skb)->nr_frags = ret - 1; + if (data_len < txreq.size) { + skb_shinfo(skb)->nr_frags++; + skb_shinfo(skb)->frags[0].page = + (void *)(unsigned long)pending_idx; + } + __skb_queue_tail(&tx_queue, skb); pending_cons++; + + mop = netbk_get_requests(netif, skb, mop); + + netif->tx.req_cons = i; + netif_schedule_work(netif); if ((mop - tx_map_ops) >= ARRAY_SIZE(tx_map_ops)) break; @@ -617,75 +811,56 @@ static void net_tx_action(unsigned long mop = tx_map_ops; while ((skb = __skb_dequeue(&tx_queue)) != NULL) { + netif_tx_request_t *txp; + pending_idx = *((u16 *)skb->data); netif = pending_tx_info[pending_idx].netif; - memcpy(&txreq, &pending_tx_info[pending_idx].req, - sizeof(txreq)); + txp = &pending_tx_info[pending_idx].req; /* Check the remap error code. */ - if (unlikely(mop->status)) { + if (unlikely(netbk_tx_check_mop(skb, &mop))) { printk(KERN_ALERT "#### netback grant fails\n"); - make_tx_response(netif, txreq.id, NETIF_RSP_ERROR); - netif_put(netif); + skb_shinfo(skb)->nr_frags = 0; kfree_skb(skb); - mop++; - pending_ring[MASK_PEND_IDX(pending_prod++)] = - pending_idx; continue; } - set_phys_to_machine( - __pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT, - FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT)); - grant_tx_handle[pending_idx] = mop->handle; - - data_len = (txreq.size > PKT_PROT_LEN) ? - PKT_PROT_LEN : txreq.size; - - __skb_put(skb, data_len); + + data_len = skb->len; memcpy(skb->data, - (void *)(MMAP_VADDR(pending_idx)|txreq.offset), + (void *)(MMAP_VADDR(pending_idx)|txp->offset), data_len); - if (data_len < txreq.size) { + if (data_len < txp->size) { /* Append the packet payload as a fragment. */ - skb_shinfo(skb)->frags[0].page = - virt_to_page(MMAP_VADDR(pending_idx)); - skb_shinfo(skb)->frags[0].size = - txreq.size - data_len; - skb_shinfo(skb)->frags[0].page_offset = - txreq.offset + data_len; - skb_shinfo(skb)->nr_frags = 1; + txp->offset += data_len; + txp->size -= data_len; } else { /* Schedule a response immediately. */ netif_idx_release(pending_idx); } - - skb->data_len = txreq.size - data_len; - skb->len += skb->data_len; - skb->truesize += skb->data_len; - - skb->dev = netif->dev; - skb->protocol = eth_type_trans(skb, skb->dev); /* * Old frontends do not assert data_validated but we * can infer it from csum_blank so test both flags. */ - if (txreq.flags & (NETTXF_data_validated|NETTXF_csum_blank)) { + if (txp->flags & (NETTXF_data_validated|NETTXF_csum_blank)) { skb->ip_summed = CHECKSUM_UNNECESSARY; skb->proto_data_valid = 1; } else { skb->ip_summed = CHECKSUM_NONE; skb->proto_data_valid = 0; } - skb->proto_csum_blank = !!(txreq.flags & NETTXF_csum_blank); - - netif->stats.rx_bytes += txreq.size; + skb->proto_csum_blank = !!(txp->flags & NETTXF_csum_blank); + + netbk_fill_frags(skb); + + skb->dev = netif->dev; + skb->protocol = eth_type_trans(skb, skb->dev); + + netif->stats.rx_bytes += skb->len; netif->stats.rx_packets++; netif_rx(skb); netif->dev->last_rx = jiffies; - - mop++; } } @@ -695,7 +870,10 @@ static void netif_idx_release(u16 pendin unsigned long flags; spin_lock_irqsave(&_lock, flags); - dealloc_ring[MASK_PEND_IDX(dealloc_prod++)] = pending_idx; + dealloc_ring[MASK_PEND_IDX(dealloc_prod)] = pending_idx; + /* Sync with net_tx_action_dealloc: insert idx /then/ incr producer. */ + smp_wmb(); + dealloc_prod++; spin_unlock_irqrestore(&_lock, flags); tasklet_schedule(&net_tx_tasklet); @@ -720,8 +898,8 @@ irqreturn_t netif_be_int(int irq, void * } static void make_tx_response(netif_t *netif, - u16 id, - s8 st) + u16 id, + s8 st) { RING_IDX i = netif->tx.rsp_prod_pvt; netif_tx_response_t *resp; @@ -747,11 +925,11 @@ static void make_tx_response(netif_t *ne } static int make_rx_response(netif_t *netif, - u16 id, - s8 st, - u16 offset, - u16 size, - u16 flags) + u16 id, + s8 st, + u16 offset, + u16 size, + u16 flags) { RING_IDX i = netif->rx.rsp_prod_pvt; netif_rx_response_t *resp; diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Tue Jun 13 12:12:24 2006 -0600 @@ -44,7 +44,7 @@ static void backend_changed(struct xenbu static int netback_remove(struct xenbus_device *dev) { - struct backend_info *be = dev->data; + struct backend_info *be = dev->dev.driver_data; if (be->backend_watch.node) { unregister_xenbus_watch(&be->backend_watch); @@ -56,7 +56,7 @@ static int netback_remove(struct xenbus_ be->netif = NULL; } kfree(be); - dev->data = NULL; + dev->dev.driver_data = NULL; return 0; } @@ -69,6 +69,8 @@ static int netback_probe(struct xenbus_d static int netback_probe(struct xenbus_device *dev, const struct xenbus_device_id *id) { + const char *message; + struct xenbus_transaction xbt; int err; struct backend_info *be = kzalloc(sizeof(struct backend_info), GFP_KERNEL); @@ -79,13 +81,34 @@ static int netback_probe(struct xenbus_d } be->dev = dev; - dev->data = be; + dev->dev.driver_data = be; err = xenbus_watch_path2(dev, dev->nodename, "handle", &be->backend_watch, backend_changed); if (err) goto fail; + do { + err = xenbus_transaction_start(&xbt); + if (err) { + xenbus_dev_fatal(dev, err, "starting transaction"); + goto fail; + } + + err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", 1); + if (err) { + message = "writing feature-sg"; + goto abort_transaction; + } + + err = xenbus_transaction_end(xbt, 0); + } while (err == -EAGAIN); + + if (err) { + xenbus_dev_fatal(dev, err, "completing transaction"); + goto fail; + } + err = xenbus_switch_state(dev, XenbusStateInitWait); if (err) { goto fail; @@ -93,6 +116,9 @@ static int netback_probe(struct xenbus_d return 0; +abort_transaction: + xenbus_transaction_end(xbt, 1); + xenbus_dev_fatal(dev, err, "%s", message); fail: DPRINTK("failed"); netback_remove(dev); @@ -108,14 +134,14 @@ static int netback_uevent(struct xenbus_ static int netback_uevent(struct xenbus_device *xdev, char **envp, int num_envp, char *buffer, int buffer_size) { - struct backend_info *be = xdev->data; + struct backend_info *be = xdev->dev.driver_data; netif_t *netif = be->netif; int i = 0, length = 0; char *val; DPRINTK("netback_uevent"); - val = xenbus_read(XBT_NULL, xdev->nodename, "script", NULL); + val = xenbus_read(XBT_NIL, xdev->nodename, "script", NULL); if (IS_ERR(val)) { int err = PTR_ERR(val); xenbus_dev_fatal(xdev, err, "reading script"); @@ -151,7 +177,7 @@ static void backend_changed(struct xenbu DPRINTK(""); - err = xenbus_scanf(XBT_NULL, dev->nodename, "handle", "%li", &handle); + err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%li", &handle); if (XENBUS_EXIST_ERR(err)) { /* Since this watch will fire once immediately after it is registered, we expect this. Ignore it, and wait for the @@ -187,7 +213,7 @@ static void frontend_changed(struct xenb static void frontend_changed(struct xenbus_device *dev, enum xenbus_state frontend_state) { - struct backend_info *be = dev->data; + struct backend_info *be = dev->dev.driver_data; DPRINTK(""); @@ -242,7 +268,7 @@ static void xen_net_read_rate(struct xen *bytes = ~0UL; *usec = 0; - ratestr = xenbus_read(XBT_NULL, dev->nodename, "rate", NULL); + ratestr = xenbus_read(XBT_NIL, dev->nodename, "rate", NULL); if (IS_ERR(ratestr)) return; @@ -272,7 +298,7 @@ static int xen_net_read_mac(struct xenbu char *s, *e, *macstr; int i; - macstr = s = xenbus_read(XBT_NULL, dev->nodename, "mac", NULL); + macstr = s = xenbus_read(XBT_NIL, dev->nodename, "mac", NULL); if (IS_ERR(macstr)) return PTR_ERR(macstr); @@ -321,7 +347,7 @@ static int connect_rings(struct backend_ DPRINTK(""); - err = xenbus_gather(XBT_NULL, dev->otherend, + err = xenbus_gather(XBT_NIL, dev->otherend, "tx-ring-ref", "%lu", &tx_ring_ref, "rx-ring-ref", "%lu", &rx_ring_ref, "event-channel", "%u", &evtchn, NULL); diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Tue Jun 13 12:12:24 2006 -0600 @@ -45,6 +45,7 @@ #include <linux/bitops.h> #include <linux/ethtool.h> #include <linux/in.h> +#include <linux/if_ether.h> #include <net/sock.h> #include <net/pkt_sched.h> #include <net/arp.h> @@ -137,14 +138,14 @@ static inline unsigned short get_id_from return id; } -#define DPRINTK(fmt, args...) pr_debug("netfront (%s:%d) " fmt, \ - __FUNCTION__, __LINE__, ##args) +#define DPRINTK(fmt, args...) \ + pr_debug("netfront (%s:%d) " fmt, \ + __FUNCTION__, __LINE__, ##args) #define IPRINTK(fmt, args...) \ printk(KERN_INFO "netfront: " fmt, ##args) #define WPRINTK(fmt, args...) \ printk(KERN_WARNING "netfront: " fmt, ##args) - static int talk_to_backend(struct xenbus_device *, struct netfront_info *); static int setup_device(struct xenbus_device *, struct netfront_info *); static struct net_device *create_netdev(int, struct xenbus_device *); @@ -155,8 +156,6 @@ static void netif_disconnect_backend(str static void netif_disconnect_backend(struct netfront_info *); static void close_netdev(struct netfront_info *); static void netif_free(struct netfront_info *); - -static void show_device(struct netfront_info *); static void network_connect(struct net_device *); static void network_tx_buf_gc(struct net_device *); @@ -172,6 +171,11 @@ static void xennet_sysfs_delif(struct ne #define xennet_sysfs_addif(dev) (0) #define xennet_sysfs_delif(dev) do { } while(0) #endif + +static inline int xennet_can_sg(struct net_device *dev) +{ + return dev->features & NETIF_F_SG; +} /** * Entry point to this code when a new device is created. Allocate the basic @@ -187,7 +191,7 @@ static int __devinit netfront_probe(stru struct netfront_info *info; unsigned int handle; - err = xenbus_scanf(XBT_NULL, dev->nodename, "handle", "%u", &handle); + err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%u", &handle); if (err != 1) { xenbus_dev_fatal(dev, err, "reading handle"); return err; @@ -201,14 +205,14 @@ static int __devinit netfront_probe(stru } info = netdev_priv(netdev); - dev->data = info; + dev->dev.driver_data = info; err = talk_to_backend(dev, info); if (err) { xennet_sysfs_delif(info->netdev); unregister_netdev(netdev); free_netdev(netdev); - dev->data = NULL; + dev->dev.driver_data = NULL; return err; } @@ -224,7 +228,7 @@ static int __devinit netfront_probe(stru */ static int netfront_resume(struct xenbus_device *dev) { - struct netfront_info *info = dev->data; + struct netfront_info *info = dev->dev.driver_data; DPRINTK("%s\n", dev->nodename); @@ -237,7 +241,7 @@ static int xen_net_read_mac(struct xenbu char *s, *e, *macstr; int i; - macstr = s = xenbus_read(XBT_NULL, dev->nodename, "mac", NULL); + macstr = s = xenbus_read(XBT_NIL, dev->nodename, "mac", NULL); if (IS_ERR(macstr)) return PTR_ERR(macstr); @@ -259,7 +263,7 @@ static int talk_to_backend(struct xenbus struct netfront_info *info) { const char *message; - xenbus_transaction_t xbt; + struct xenbus_transaction xbt; int err; err = xen_net_read_mac(dev, info->mac); @@ -306,8 +310,6 @@ again: xenbus_dev_fatal(dev, err, "completing transaction"); goto destroy_ring; } - - xenbus_switch_state(dev, XenbusStateConnected); return 0; @@ -334,35 +336,36 @@ static int setup_device(struct xenbus_de info->tx.sring = NULL; info->irq = 0; - txs = (struct netif_tx_sring *)__get_free_page(GFP_KERNEL); + txs = (struct netif_tx_sring *)get_zeroed_page(GFP_KERNEL); if (!txs) { err = -ENOMEM; xenbus_dev_fatal(dev, err, "allocating tx ring page"); goto fail; } - rxs = (struct netif_rx_sring *)__get_free_page(GFP_KERNEL); + SHARED_RING_INIT(txs); + FRONT_RING_INIT(&info->tx, txs, PAGE_SIZE); + + err = xenbus_grant_ring(dev, virt_to_mfn(txs)); + if (err < 0) { + free_page((unsigned long)txs); + goto fail; + } + info->tx_ring_ref = err; + + rxs = (struct netif_rx_sring *)get_zeroed_page(GFP_KERNEL); if (!rxs) { err = -ENOMEM; xenbus_dev_fatal(dev, err, "allocating rx ring page"); goto fail; } - memset(txs, 0, PAGE_SIZE); - memset(rxs, 0, PAGE_SIZE); - - SHARED_RING_INIT(txs); - FRONT_RING_INIT(&info->tx, txs, PAGE_SIZE); - SHARED_RING_INIT(rxs); FRONT_RING_INIT(&info->rx, rxs, PAGE_SIZE); - err = xenbus_grant_ring(dev, virt_to_mfn(txs)); - if (err < 0) + err = xenbus_grant_ring(dev, virt_to_mfn(rxs)); + if (err < 0) { + free_page((unsigned long)rxs); goto fail; - info->tx_ring_ref = err; - - err = xenbus_grant_ring(dev, virt_to_mfn(rxs)); - if (err < 0) - goto fail; + } info->rx_ring_ref = err; err = xenbus_alloc_evtchn(dev, &info->evtchn); @@ -370,13 +373,11 @@ static int setup_device(struct xenbus_de goto fail; memcpy(netdev->dev_addr, info->mac, ETH_ALEN); - network_connect(netdev); - info->irq = bind_evtchn_to_irqhandler( - info->evtchn, netif_int, SA_SAMPLE_RANDOM, netdev->name, - netdev); - (void)send_fake_arp(netdev); - show_device(info); - + err = bind_evtchn_to_irqhandler(info->evtchn, netif_int, + SA_SAMPLE_RANDOM, netdev->name, netdev); + if (err < 0) + goto fail; + info->irq = err; return 0; fail: @@ -391,15 +392,23 @@ static void backend_changed(struct xenbu static void backend_changed(struct xenbus_device *dev, enum xenbus_state backend_state) { + struct netfront_info *np = dev->dev.driver_data; + struct net_device *netdev = np->netdev; + DPRINTK("\n"); switch (backend_state) { case XenbusStateInitialising: - case XenbusStateInitWait: case XenbusStateInitialised: case XenbusStateConnected: case XenbusStateUnknown: case XenbusStateClosed: + break; + + case XenbusStateInitWait: + network_connect(netdev); + xenbus_switch_state(dev, XenbusStateConnected); + (void)send_fake_arp(netdev); break; case XenbusStateClosing: @@ -452,13 +461,17 @@ static int network_open(struct net_devic return 0; } +static inline int netfront_tx_slot_available(struct netfront_info *np) +{ + return RING_FREE_REQUESTS(&np->tx) >= MAX_SKB_FRAGS + 1; +} + static inline void network_maybe_wake_tx(struct net_device *dev) { struct netfront_info *np = netdev_priv(dev); if (unlikely(netif_queue_stopped(dev)) && - !RING_FULL(&np->tx) && - !gnttab_empty_grant_references(&np->gref_tx_head) && + netfront_tx_slot_available(np) && likely(netif_running(dev))) netif_wake_queue(dev); } @@ -485,7 +498,7 @@ static void network_tx_buf_gc(struct net printk(KERN_ALERT "network_tx_buf_gc: warning " "-- grant still in use by backend " "domain.\n"); - break; /* bail immediately */ + BUG(); } gnttab_end_foreign_access_ref( np->grant_tx_ref[id], GNTMAP_readonly); @@ -589,7 +602,7 @@ static void network_alloc_rx_buffers(str np->grant_rx_ref[id] = ref; gnttab_grant_foreign_transfer_ref(ref, np->xbdev->otherend_id, - __pa(skb->head) >> PAGE_SHIFT); + __pa(skb->head)>>PAGE_SHIFT); RING_GET_REQUEST(&np->rx, req_prod + i)->gref = ref; np->rx_pfn_array[i] = virt_to_mfn(skb->head); @@ -638,36 +651,95 @@ static void network_alloc_rx_buffers(str RING_PUSH_REQUESTS(&np->rx); } +static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev, + struct netif_tx_request *tx) +{ + struct netfront_info *np = netdev_priv(dev); + char *data = skb->data; + unsigned long mfn; + RING_IDX prod = np->tx.req_prod_pvt; + int frags = skb_shinfo(skb)->nr_frags; + unsigned int offset = offset_in_page(data); + unsigned int len = skb_headlen(skb); + unsigned int id; + grant_ref_t ref; + int i; + + while (len > PAGE_SIZE - offset) { + tx->size = PAGE_SIZE - offset; + tx->flags |= NETTXF_more_data; + len -= tx->size; + data += tx->size; + offset = 0; + + id = get_id_from_freelist(np->tx_skbs); + np->tx_skbs[id] = skb_get(skb); + tx = RING_GET_REQUEST(&np->tx, prod++); + tx->id = id; + ref = gnttab_claim_grant_reference(&np->gref_tx_head); + BUG_ON((signed short)ref < 0); + + mfn = virt_to_mfn(data); + gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id, + mfn, GNTMAP_readonly); + + tx->gref = np->grant_tx_ref[id] = ref; + tx->offset = offset; + tx->size = len; + tx->flags = 0; + } + + for (i = 0; i < frags; i++) { + skb_frag_t *frag = skb_shinfo(skb)->frags + i; + + tx->flags |= NETTXF_more_data; + + id = get_id_from_freelist(np->tx_skbs); + np->tx_skbs[id] = skb_get(skb); + tx = RING_GET_REQUEST(&np->tx, prod++); + tx->id = id; + ref = gnttab_claim_grant_reference(&np->gref_tx_head); + BUG_ON((signed short)ref < 0); + + mfn = pfn_to_mfn(page_to_pfn(frag->page)); + gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id, + mfn, GNTMAP_readonly); + + tx->gref = np->grant_tx_ref[id] = ref; + tx->offset = frag->page_offset; + tx->size = frag->size; + tx->flags = 0; + } + + np->tx.req_prod_pvt = prod; +} static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) { unsigned short id; struct netfront_info *np = netdev_priv(dev); struct netif_tx_request *tx; + char *data = skb->data; RING_IDX i; grant_ref_t ref; unsigned long mfn; int notify; - - if (unlikely((((unsigned long)skb->data & ~PAGE_MASK) + skb->len) >= - PAGE_SIZE)) { - struct sk_buff *nskb; - nskb = __dev_alloc_skb(skb->len, GFP_ATOMIC|__GFP_NOWARN); - if (unlikely(nskb == NULL)) - goto drop; - skb_put(nskb, skb->len); - memcpy(nskb->data, skb->data, skb->len); - /* Copy only the header fields we use in this driver. */ - nskb->dev = skb->dev; - nskb->ip_summed = skb->ip_summed; - nskb->proto_data_valid = skb->proto_data_valid; - dev_kfree_skb(skb); - skb = nskb; + int frags = skb_shinfo(skb)->nr_frags; + unsigned int offset = offset_in_page(data); + unsigned int len = skb_headlen(skb); + + frags += (offset + len + PAGE_SIZE - 1) / PAGE_SIZE; + if (unlikely(frags > MAX_SKB_FRAGS + 1)) { + printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n", + frags); + dump_stack(); + goto drop; } spin_lock_irq(&np->tx_lock); - if (unlikely(!netif_carrier_ok(dev))) { + if (unlikely(!netif_carrier_ok(dev) || + (frags > 1 && !xennet_can_sg(dev)))) { spin_unlock_irq(&np->tx_lock); goto drop; } @@ -682,12 +754,12 @@ static int network_start_xmit(struct sk_ tx->id = id; ref = gnttab_claim_grant_reference(&np->gref_tx_head); BUG_ON((signed short)ref < 0); - mfn = virt_to_mfn(skb->data); + mfn = virt_to_mfn(data); gnttab_grant_foreign_access_ref( ref, np->xbdev->otherend_id, mfn, GNTMAP_readonly); tx->gref = np->grant_tx_ref[id] = ref; - tx->offset = (unsigned long)skb->data & ~PAGE_MASK; - tx->size = skb->len; + tx->offset = offset; + tx->size = len; tx->flags = 0; if (skb->ip_summed == CHECKSUM_HW) /* local packet? */ @@ -696,14 +768,17 @@ static int network_start_xmit(struct sk_ tx->flags |= NETTXF_data_validated; np->tx.req_prod_pvt = i + 1; + + xennet_make_frags(skb, dev, tx); + tx->size = skb->len; + RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->tx, notify); if (notify) notify_remote_via_irq(np->irq); network_tx_buf_gc(dev); - if (RING_FULL(&np->tx) || - gnttab_empty_grant_references(&np->gref_tx_head)) + if (!netfront_tx_slot_available(np)) netif_stop_queue(dev); spin_unlock_irq(&np->tx_lock); @@ -771,10 +846,10 @@ static int netif_poll(struct net_device rx = RING_GET_RESPONSE(&np->rx, i); /* - * This definitely indicates a bug, either in this driver or - * in the backend driver. In future this should flag the bad - * situation to the system controller to reboot the backed. - */ + * This definitely indicates a bug, either in this driver or in + * the backend driver. In future this should flag the bad + * situation to the system controller to reboot the backed. + */ if ((ref = np->grant_rx_ref[rx->id]) == GRANT_INVALID_REF) { WPRINTK("Bad rx response id %d.\n", rx->id); work_done--; @@ -963,12 +1038,46 @@ static struct net_device_stats *network_ return &np->stats; } +static int xennet_change_mtu(struct net_device *dev, int mtu) +{ + int max = xennet_can_sg(dev) ? 65535 - ETH_HLEN : ETH_DATA_LEN; + + if (mtu > max) + return -EINVAL; + dev->mtu = mtu; + return 0; +} + +static int xennet_set_sg(struct net_device *dev, u32 data) +{ + if (data) { + struct netfront_info *np = netdev_priv(dev); + int val; + + if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-sg", + "%d", &val) < 0) + val = 0; + if (!val) + return -ENOSYS; + } else if (dev->mtu > ETH_DATA_LEN) + dev->mtu = ETH_DATA_LEN; + + return ethtool_op_set_sg(dev, data); +} + +static void xennet_set_features(struct net_device *dev) +{ + xennet_set_sg(dev, 1); +} + static void network_connect(struct net_device *dev) { struct netfront_info *np; int i, requeue_idx; struct netif_tx_request *tx; struct sk_buff *skb; + + xennet_set_features(dev); np = netdev_priv(dev); spin_lock_irq(&np->tx_lock); @@ -1054,22 +1163,6 @@ static void network_connect(struct net_d spin_unlock_irq(&np->tx_lock); } -static void show_device(struct netfront_info *np) -{ -#ifdef DEBUG - if (np) { - IPRINTK("<vif handle=%u %s(%s) evtchn=%u tx=%p rx=%p>\n", - np->handle, - netif_carrier_ok(np->netdev) ? "on" : "off", - netif_running(np->netdev) ? "open" : "closed", - np->evtchn, - np->tx, - np->rx); - } else - IPRINTK("<vif NULL>\n"); -#endif -} - static void netif_uninit(struct net_device *dev) { struct netfront_info *np = netdev_priv(dev); @@ -1081,6 +1174,8 @@ static struct ethtool_ops network_ethtoo { .get_tx_csum = ethtool_op_get_tx_csum, .set_tx_csum = ethtool_op_set_tx_csum, + .get_sg = ethtool_op_get_sg, + .set_sg = xennet_set_sg, }; #ifdef CONFIG_SYSFS @@ -1285,7 +1380,6 @@ static struct net_device * __devinit cre if (gnttab_alloc_grant_references(RX_MAX_TARGET, &np->gref_rx_head) < 0) { printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n"); - gnttab_free_grant_references(np->gref_tx_head); err = -ENOMEM; goto exit_free_tx; } @@ -1297,6 +1391,7 @@ static struct net_device * __devinit cre netdev->poll = netif_poll; netdev->set_multicast_list = network_set_multicast_list; netdev->uninit = netif_uninit; + netdev->change_mtu = xennet_change_mtu; netdev->weight = 64; netdev->features = NETIF_F_IP_CSUM; @@ -1361,7 +1456,7 @@ inetdev_notify(struct notifier_block *th */ static void netfront_closing(struct xenbus_device *dev) { - struct netfront_info *info = dev->data; + struct netfront_info *info = dev->dev.driver_data; DPRINTK("netfront_closing: %s removed\n", dev->nodename); @@ -1373,7 +1468,7 @@ static void netfront_closing(struct xenb static int __devexit netfront_remove(struct xenbus_device *dev) { - struct netfront_info *info = dev->data; + struct netfront_info *info = dev->dev.driver_data; DPRINTK("%s\n", dev->nodename); diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c --- a/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c Tue Jun 13 12:12:24 2006 -0600 @@ -23,7 +23,7 @@ static struct pciback_device *alloc_pdev dev_dbg(&xdev->dev, "allocated pdev @ 0x%p\n", pdev); pdev->xdev = xdev; - xdev->data = pdev; + xdev->dev.driver_data = pdev; spin_lock_init(&pdev->dev_lock); @@ -61,7 +61,7 @@ static void free_pdev(struct pciback_dev pciback_release_devices(pdev); - pdev->xdev->data = NULL; + pdev->xdev->dev.driver_data = NULL; pdev->xdev = NULL; kfree(pdev); @@ -125,7 +125,7 @@ static int pciback_attach(struct pciback dev_dbg(&pdev->xdev->dev, "Reading frontend config\n"); - err = xenbus_gather(XBT_NULL, pdev->xdev->otherend, + err = xenbus_gather(XBT_NIL, pdev->xdev->otherend, "pci-op-ref", "%u", &gnt_ref, "event-channel", "%u", &remote_evtchn, "magic", NULL, &magic, NULL); @@ -168,7 +168,7 @@ static void pciback_frontend_changed(str static void pciback_frontend_changed(struct xenbus_device *xdev, enum xenbus_state fe_state) { - struct pciback_device *pdev = xdev->data; + struct pciback_device *pdev = xdev->dev.driver_data; dev_dbg(&xdev->dev, "fe state changed %d\n", fe_state); @@ -200,7 +200,7 @@ static int pciback_publish_pci_root(stru dev_dbg(&pdev->xdev->dev, "Publishing pci roots\n"); - err = xenbus_scanf(XBT_NULL, pdev->xdev->nodename, + err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, "root_num", "%d", &root_num); if (err == 0 || err == -ENOENT) root_num = 0; @@ -215,7 +215,7 @@ static int pciback_publish_pci_root(stru goto out; } - err = xenbus_scanf(XBT_NULL, pdev->xdev->nodename, + err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, str, "%x:%x", &d, &b); if (err < 0) goto out; @@ -239,12 +239,12 @@ static int pciback_publish_pci_root(stru dev_dbg(&pdev->xdev->dev, "writing root %d at %04x:%02x\n", root_num, domain, bus); - err = xenbus_printf(XBT_NULL, pdev->xdev->nodename, str, + err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, str, "%04x:%02x", domain, bus); if (err) goto out; - err = xenbus_printf(XBT_NULL, pdev->xdev->nodename, + err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, "root_num", "%d", (root_num + 1)); out: @@ -306,7 +306,7 @@ static int pciback_setup_backend(struct dev_dbg(&pdev->xdev->dev, "getting be setup\n"); - err = xenbus_scanf(XBT_NULL, pdev->xdev->nodename, "num_devs", "%d", + err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, "num_devs", "%d", &num_devs); if (err != 1) { if (err >= 0) @@ -326,7 +326,7 @@ static int pciback_setup_backend(struct goto out; } - err = xenbus_scanf(XBT_NULL, pdev->xdev->nodename, dev_str, + err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, dev_str, "%x:%x:%x.%x", &domain, &bus, &slot, &func); if (err < 0) { xenbus_dev_fatal(pdev->xdev, err, @@ -421,7 +421,7 @@ static int pciback_xenbus_probe(struct x static int pciback_xenbus_remove(struct xenbus_device *dev) { - struct pciback_device *pdev = dev->data; + struct pciback_device *pdev = dev->dev.driver_data; if (pdev != NULL) free_pdev(pdev); diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c --- a/linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c Tue Jun 13 12:12:24 2006 -0600 @@ -29,7 +29,7 @@ static struct pcifront_device *alloc_pde } pdev->sh_info->flags = 0; - xdev->data = pdev; + xdev->dev.driver_data = pdev; pdev->xdev = xdev; INIT_LIST_HEAD(&pdev->root_buses); @@ -59,7 +59,7 @@ static void free_pdev(struct pcifront_de gnttab_end_foreign_access(pdev->gnt_ref, 0, (unsigned long)pdev->sh_info); - pdev->xdev->data = NULL; + pdev->xdev->dev.driver_data = NULL; kfree(pdev); } @@ -67,7 +67,7 @@ static int pcifront_publish_info(struct static int pcifront_publish_info(struct pcifront_device *pdev) { int err = 0; - xenbus_transaction_t trans; + struct xenbus_transaction trans; err = xenbus_grant_ring(pdev->xdev, virt_to_mfn(pdev->sh_info)); if (err < 0) @@ -143,7 +143,7 @@ static int pcifront_try_connect(struct p goto out; } - err = xenbus_scanf(XBT_NULL, pdev->xdev->otherend, + err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, "root_num", "%d", &num_roots); if (err == -ENOENT) { xenbus_dev_error(pdev->xdev, err, @@ -165,7 +165,7 @@ static int pcifront_try_connect(struct p goto out; } - err = xenbus_scanf(XBT_NULL, pdev->xdev->otherend, str, + err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str, "%x:%x", &domain, &bus); if (err != 2) { if (err >= 0) @@ -216,7 +216,7 @@ static void pcifront_backend_changed(str static void pcifront_backend_changed(struct xenbus_device *xdev, enum xenbus_state be_state) { - struct pcifront_device *pdev = xdev->data; + struct pcifront_device *pdev = xdev->dev.driver_data; switch (be_state) { case XenbusStateClosing: @@ -261,8 +261,8 @@ static int pcifront_xenbus_probe(struct static int pcifront_xenbus_remove(struct xenbus_device *xdev) { - if (xdev->data) - free_pdev(xdev->data); + if (xdev->dev.driver_data) + free_pdev(xdev->dev.driver_data); return 0; } diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Tue Jun 13 12:12:24 2006 -0600 @@ -39,7 +39,7 @@ static DECLARE_BITMAP(hypercall_permissi static DECLARE_BITMAP(hypercall_permission_map, NR_HYPERCALLS); static int privcmd_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long data) + unsigned int cmd, unsigned long data) { int ret = -ENOSYS; void __user *udata = (void __user *) data; @@ -61,11 +61,11 @@ static int privcmd_ioctl(struct inode *i __asm__ __volatile__ ( "pushl %%ebx; pushl %%ecx; pushl %%edx; " "pushl %%esi; pushl %%edi; " - "movl 4(%%eax),%%ebx ;" - "movl 8(%%eax),%%ecx ;" - "movl 12(%%eax),%%edx ;" - "movl 16(%%eax),%%esi ;" - "movl 20(%%eax),%%edi ;" + "movl 8(%%eax),%%ebx ;" + "movl 16(%%eax),%%ecx ;" + "movl 24(%%eax),%%edx ;" + "movl 32(%%eax),%%esi ;" + "movl 40(%%eax),%%edi ;" "movl (%%eax),%%eax ;" "shll $5,%%eax ;" "addl $hypercall_page,%%eax ;" @@ -161,7 +161,7 @@ static int privcmd_ioctl(struct inode *i case IOCTL_PRIVCMD_MMAPBATCH: { privcmd_mmapbatch_t m; struct vm_area_struct *vma = NULL; - unsigned long __user *p; + xen_pfn_t __user *p; unsigned long addr, mfn; int i; @@ -210,7 +210,7 @@ static int privcmd_ioctl(struct inode *i batch_err: printk("batch_err ret=%d vma=%p addr=%lx " "num=%d arr=%p %lx-%lx\n", - ret, vma, m.addr, m.num, m.arr, + ret, vma, (unsigned long)m.addr, m.num, m.arr, vma ? vma->vm_start : 0, vma ? vma->vm_end : 0); break; } @@ -241,7 +241,7 @@ static struct file_operations privcmd_fi }; static int capabilities_read(char *page, char **start, off_t off, - int count, int *eof, void *data) + int count, int *eof, void *data) { int len = 0; *page = 0; diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/tpmback/common.h --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Tue Jun 13 12:12:24 2006 -0600 @@ -17,8 +17,9 @@ #include <asm/io.h> #include <asm/pgalloc.h> -#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \ - __FILE__ , __LINE__ , ## _a ) +#define DPRINTK(_f, _a...) \ + pr_debug("(file=%s, line=%d) " _f, \ + __FILE__ , __LINE__ , ## _a ) typedef struct tpmif_st { struct list_head tpmif_list; @@ -68,12 +69,11 @@ int vtpm_release_packets(tpmif_t * tpmif int vtpm_release_packets(tpmif_t * tpmif, int send_msgs); #define tpmif_get(_b) (atomic_inc(&(_b)->refcnt)) -#define tpmif_put(_b) \ - do { \ - if ( atomic_dec_and_test(&(_b)->refcnt) ) \ - tpmif_disconnect_complete(_b); \ - } while (0) - +#define tpmif_put(_b) \ + do { \ + if (atomic_dec_and_test(&(_b)->refcnt)) \ + tpmif_disconnect_complete(_b); \ + } while (0) extern int num_frontends; diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Tue Jun 13 12:12:24 2006 -0600 @@ -41,13 +41,13 @@ static void connect(struct backend_info static void connect(struct backend_info *be); static int connect_ring(struct backend_info *be); static void backend_changed(struct xenbus_watch *watch, - const char **vec, unsigned int len); + const char **vec, unsigned int len); static void frontend_changed(struct xenbus_device *dev, - enum xenbus_state frontend_state); + enum xenbus_state frontend_state); static int tpmback_remove(struct xenbus_device *dev) { - struct backend_info *be = dev->data; + struct backend_info *be = dev->dev.driver_data; if (!be) return 0; @@ -62,30 +62,30 @@ static int tpmback_remove(struct xenbus_ be->tpmif = NULL; } kfree(be); - dev->data = NULL; + dev->dev.driver_data = NULL; return 0; } static int tpmback_probe(struct xenbus_device *dev, - const struct xenbus_device_id *id) + const struct xenbus_device_id *id) { int err; struct backend_info *be = kzalloc(sizeof(struct backend_info), - GFP_KERNEL); + GFP_KERNEL); if (!be) { xenbus_dev_fatal(dev, -ENOMEM, - "allocating backend structure"); + "allocating backend structure"); return -ENOMEM; } be->is_instance_set = 0; be->dev = dev; - dev->data = be; + dev->dev.driver_data = be; err = xenbus_watch_path2(dev, dev->nodename, - "instance", &be->backend_watch, - backend_changed); + "instance", &be->backend_watch, + backend_changed); if (err) { goto fail; } @@ -102,7 +102,7 @@ fail: static void backend_changed(struct xenbus_watch *watch, - const char **vec, unsigned int len) + const char **vec, unsigned int len) { int err; long instance; @@ -110,8 +110,8 @@ static void backend_changed(struct xenbu = container_of(watch, struct backend_info, backend_watch); struct xenbus_device *dev = be->dev; - err = xenbus_scanf(XBT_NULL, dev->nodename, - "instance","%li", &instance); + err = xenbus_scanf(XBT_NIL, dev->nodename, + "instance","%li", &instance); if (XENBUS_EXIST_ERR(err)) { return; } @@ -129,9 +129,9 @@ static void backend_changed(struct xenbu static void frontend_changed(struct xenbus_device *dev, - enum xenbus_state frontend_state) -{ - struct backend_info *be = dev->data; + enum xenbus_state frontend_state) +{ + struct backend_info *be = dev->dev.driver_data; int err; be->frontend_state = frontend_state; @@ -167,8 +167,8 @@ static void frontend_changed(struct xenb case XenbusStateInitWait: default: xenbus_dev_fatal(dev, -EINVAL, - "saw state %d at frontend", - frontend_state); + "saw state %d at frontend", + frontend_state); break; } } @@ -188,11 +188,11 @@ static void maybe_connect(struct backend * Notify the vTPM manager about a new front-end. */ err = tpmif_vtpm_open(be->tpmif, - be->frontend_id, - be->instance); + be->frontend_id, + be->instance); if (err) { xenbus_dev_error(be->dev, err, - "queueing vtpm open packet"); + "queueing vtpm open packet"); /* * Should close down this device and notify FE * about closure. @@ -204,7 +204,7 @@ static void maybe_connect(struct backend static void connect(struct backend_info *be) { - xenbus_transaction_t xbt; + struct xenbus_transaction xbt; int err; struct xenbus_device *dev = be->dev; unsigned long ready = 1; @@ -217,7 +217,7 @@ again: } err = xenbus_printf(xbt, be->dev->nodename, - "ready", "%lu", ready); + "ready", "%lu", ready); if (err) { xenbus_dev_fatal(be->dev, err, "writing 'ready'"); goto abort; @@ -245,8 +245,8 @@ static int connect_ring(struct backend_i unsigned int evtchn; int err; - err = xenbus_gather(XBT_NULL, dev->otherend, - "ring-ref", "%lu", &ring_ref, + err = xenbus_gather(XBT_NIL, dev->otherend, + "ring-ref", "%lu", &ring_ref, "event-channel", "%u", &evtchn, NULL); if (err) { xenbus_dev_error(dev, err, @@ -257,7 +257,7 @@ static int connect_ring(struct backend_i if (!be->tpmif) { be->tpmif = tpmif_find(dev->otherend_id, - be->instance); + be->instance); if (IS_ERR(be->tpmif)) { err = PTR_ERR(be->tpmif); be->tpmif = NULL; @@ -270,8 +270,8 @@ static int connect_ring(struct backend_i err = tpmif_map(be->tpmif, ring_ref, evtchn); if (err) { xenbus_dev_error(dev, err, - "mapping shared-frame %lu port %u", - ring_ref, evtchn); + "mapping shared-frame %lu port %u", + ring_ref, evtchn); return err; } } diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c Tue Jun 13 12:12:24 2006 -0600 @@ -106,12 +106,12 @@ int xenbus_switch_state(struct xenbus_de if (state == dev->state) return 0; - err = xenbus_scanf(XBT_NULL, dev->nodename, "state", "%d", + err = xenbus_scanf(XBT_NIL, dev->nodename, "state", "%d", ¤t_state); if (err != 1) return 0; - err = xenbus_printf(XBT_NULL, dev->nodename, "state", "%d", state); + err = xenbus_printf(XBT_NIL, dev->nodename, "state", "%d", state); if (err) { if (state != XenbusStateClosing) /* Avoid looping */ xenbus_dev_fatal(dev, err, "writing new state"); @@ -162,7 +162,7 @@ void _dev_error(struct xenbus_device *de goto fail; } - if (xenbus_write(XBT_NULL, path_buffer, "error", printf_buffer) != 0) { + if (xenbus_write(XBT_NIL, path_buffer, "error", printf_buffer) != 0) { printk("xenbus: failed to write error node for %s (%s)\n", dev->nodename, printf_buffer); goto fail; @@ -272,7 +272,7 @@ enum xenbus_state xenbus_read_driver_sta enum xenbus_state xenbus_read_driver_state(const char *path) { enum xenbus_state result; - int err = xenbus_gather(XBT_NULL, path, "state", "%d", &result, NULL); + int err = xenbus_gather(XBT_NIL, path, "state", "%d", &result, NULL); if (err) result = XenbusStateClosed; diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Tue Jun 13 12:12:24 2006 -0600 @@ -51,7 +51,7 @@ struct xenbus_dev_transaction { struct list_head list; - xenbus_transaction_t handle; + struct xenbus_transaction handle; }; struct xenbus_dev_data { @@ -154,11 +154,11 @@ static ssize_t xenbus_dev_write(struct f } if (msg_type == XS_TRANSACTION_START) { - trans->handle = simple_strtoul(reply, NULL, 0); + trans->handle.id = simple_strtoul(reply, NULL, 0); list_add(&trans->list, &u->transactions); } else if (msg_type == XS_TRANSACTION_END) { list_for_each_entry(trans, &u->transactions, list) - if (trans->handle == u->u.msg.tx_id) + if (trans->handle.id == u->u.msg.tx_id) break; BUG_ON(&trans->list == &u->transactions); list_del(&trans->list); diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Tue Jun 13 12:12:24 2006 -0600 @@ -30,8 +30,9 @@ * IN THE SOFTWARE. */ -#define DPRINTK(fmt, args...) \ - pr_debug("xenbus_probe (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args) +#define DPRINTK(fmt, args...) \ + pr_debug("xenbus_probe (%s:%d) " fmt ".\n", \ + __FUNCTION__, __LINE__, ##args) #include <linux/kernel.h> #include <linux/err.h> @@ -128,7 +129,7 @@ static int read_otherend_details(struct static int read_otherend_details(struct xenbus_device *xendev, char *id_node, char *path_node) { - int err = xenbus_gather(XBT_NULL, xendev->nodename, + int err = xenbus_gather(XBT_NIL, xendev->nodename, id_node, "%i", &xendev->otherend_id, path_node, NULL, &xendev->otherend, NULL); @@ -139,7 +140,7 @@ static int read_otherend_details(struct return err; } if (strlen(xendev->otherend) == 0 || - !xenbus_exists(XBT_NULL, xendev->otherend, "")) { + !xenbus_exists(XBT_NIL, xendev->otherend, "")) { xenbus_dev_fatal(xendev, -ENOENT, "missing other end from %s", xendev->nodename); free_otherend_details(xendev); @@ -195,14 +196,14 @@ static int backend_bus_id(char bus_id[BU devid = strrchr(nodename, '/') + 1; - err = xenbus_gather(XBT_NULL, nodename, "frontend-id", "%i", &domid, + err = xenbus_gather(XBT_NIL, nodename, "frontend-id", "%i", &domid, "frontend", NULL, &frontend, NULL); if (err) return err; if (strlen(frontend) == 0) err = -ERANGE; - if (!err && !xenbus_exists(XBT_NULL, frontend, "")) + if (!err && !xenbus_exists(XBT_NIL, frontend, "")) err = -ENOENT; kfree(frontend); @@ -634,7 +635,7 @@ static int xenbus_probe_backend(const ch if (!nodename) return -ENOMEM; - dir = xenbus_directory(XBT_NULL, nodename, "", &dir_n); + dir = xenbus_directory(XBT_NIL, nodename, "", &dir_n); if (IS_ERR(dir)) { kfree(nodename); return PTR_ERR(dir); @@ -657,7 +658,7 @@ static int xenbus_probe_device_type(stru unsigned int dir_n = 0; int i; - dir = xenbus_directory(XBT_NULL, bus->root, type, &dir_n); + dir = xenbus_directory(XBT_NIL, bus->root, type, &dir_n); if (IS_ERR(dir)) return PTR_ERR(dir); @@ -676,7 +677,7 @@ static int xenbus_probe_devices(struct x char **dir; unsigned int i, dir_n; - dir = xenbus_directory(XBT_NULL, bus->root, "", &dir_n); + dir = xenbus_directory(XBT_NIL, bus->root, "", &dir_n); if (IS_ERR(dir)) return PTR_ERR(dir); @@ -722,7 +723,7 @@ static void dev_changed(const char *node if (char_count(node, '/') < 2) return; - exists = xenbus_exists(XBT_NULL, node, ""); + exists = xenbus_exists(XBT_NIL, node, ""); if (!exists) { xenbus_cleanup_devices(node, &bus->bus); return; @@ -806,6 +807,7 @@ static int resume_dev(struct device *dev if (dev->driver == NULL) return 0; + drv = to_xenbus_driver(dev->driver); xdev = container_of(dev, struct xenbus_device, dev); @@ -817,6 +819,18 @@ static int resume_dev(struct device *dev return err; } + xdev->state = XenbusStateInitialising; + + if (drv->resume) { + err = drv->resume(xdev); + if (err) { + printk(KERN_WARNING + "xenbus: resume %s failed: %i\n", + dev->bus_id, err); + return err; + } + } + err = watch_otherend(xdev); if (err) { printk(KERN_WARNING @@ -825,14 +839,7 @@ static int resume_dev(struct device *dev return err; } - xdev->state = XenbusStateInitialising; - - if (drv->resume) - err = drv->resume(xdev); - if (err) - printk(KERN_WARNING - "xenbus: resume %s failed: %i\n", dev->bus_id, err); - return err; + return 0; } void xenbus_suspend(void) @@ -939,7 +946,7 @@ static int xsd_kva_mmap(struct file *fil } static int xsd_kva_read(char *page, char **start, off_t off, - int count, int *eof, void *data) + int count, int *eof, void *data) { int len; @@ -1038,10 +1045,10 @@ static int __init xenbus_probe_init(void free_page(page); /* - * Do not unregister the xenbus front/backend buses here. The - * buses must exist because front/backend drivers will use - * them when they are registered. - */ + * Do not unregister the xenbus front/backend buses here. The buses + * must exist because front/backend drivers will use them when they are + * registered. + */ return err; } diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Tue Jun 13 12:12:24 2006 -0600 @@ -192,7 +192,7 @@ void *xenbus_dev_request_and_reply(struc } /* Send message to xs, get kmalloc'ed reply. ERR_PTR() on error. */ -static void *xs_talkv(xenbus_transaction_t t, +static void *xs_talkv(struct xenbus_transaction t, enum xsd_sockmsg_type type, const struct kvec *iovec, unsigned int num_vecs, @@ -203,7 +203,7 @@ static void *xs_talkv(xenbus_transaction unsigned int i; int err; - msg.tx_id = t; + msg.tx_id = t.id; msg.req_id = 0; msg.type = type; msg.len = 0; @@ -251,7 +251,7 @@ static void *xs_talkv(xenbus_transaction } /* Simplified version of xs_talkv: single message. */ -static void *xs_single(xenbus_transaction_t t, +static void *xs_single(struct xenbus_transaction t, enum xsd_sockmsg_type type, const char *string, unsigned int *len) @@ -318,7 +318,7 @@ static char **split(char *strings, unsig return ret; } -char **xenbus_directory(xenbus_transaction_t t, +char **xenbus_directory(struct xenbus_transaction t, const char *dir, const char *node, unsigned int *num) { char *strings, *path; @@ -338,7 +338,7 @@ EXPORT_SYMBOL_GPL(xenbus_directory); EXPORT_SYMBOL_GPL(xenbus_directory); /* Check if a path exists. Return 1 if it does. */ -int xenbus_exists(xenbus_transaction_t t, +int xenbus_exists(struct xenbus_transaction t, const char *dir, const char *node) { char **d; @@ -356,7 +356,7 @@ EXPORT_SYMBOL_GPL(xenbus_exists); * Returns a kmalloced value: call free() on it after use. * len indicates length in bytes. */ -void *xenbus_read(xenbus_transaction_t t, +void *xenbus_read(struct xenbus_transaction t, const char *dir, const char *node, unsigned int *len) { char *path; @@ -375,7 +375,7 @@ EXPORT_SYMBOL_GPL(xenbus_read); /* Write the value of a single file. * Returns -err on failure. */ -int xenbus_write(xenbus_transaction_t t, +int xenbus_write(struct xenbus_transaction t, const char *dir, const char *node, const char *string) { const char *path; @@ -398,7 +398,7 @@ EXPORT_SYMBOL_GPL(xenbus_write); EXPORT_SYMBOL_GPL(xenbus_write); /* Create a new directory. */ -int xenbus_mkdir(xenbus_transaction_t t, +int xenbus_mkdir(struct xenbus_transaction t, const char *dir, const char *node) { char *path; @@ -415,7 +415,7 @@ EXPORT_SYMBOL_GPL(xenbus_mkdir); EXPORT_SYMBOL_GPL(xenbus_mkdir); /* Destroy a file or directory (directories must be empty). */ -int xenbus_rm(xenbus_transaction_t t, const char *dir, const char *node) +int xenbus_rm(struct xenbus_transaction t, const char *dir, const char *node) { char *path; int ret; @@ -433,19 +433,19 @@ EXPORT_SYMBOL_GPL(xenbus_rm); /* Start a transaction: changes by others will not be seen during this * transaction, and changes will not be visible to others until end. */ -int xenbus_transaction_start(xenbus_transaction_t *t) +int xenbus_transaction_start(struct xenbus_transaction *t) { char *id_str; down_read(&xs_state.suspend_mutex); - id_str = xs_single(XBT_NULL, XS_TRANSACTION_START, "", NULL); + id_str = xs_single(XBT_NIL, XS_TRANSACTION_START, "", NULL); if (IS_ERR(id_str)) { up_read(&xs_state.suspend_mutex); return PTR_ERR(id_str); } - *t = simple_strtoul(id_str, NULL, 0); + t->id = simple_strtoul(id_str, NULL, 0); kfree(id_str); return 0; } @@ -454,7 +454,7 @@ EXPORT_SYMBOL_GPL(xenbus_transaction_sta /* End a transaction. * If abandon is true, transaction is discarded instead of committed. */ -int xenbus_transaction_end(xenbus_transaction_t t, int abort) +int xenbus_transaction_end(struct xenbus_transaction t, int abort) { char abortstr[2]; int err; @@ -473,7 +473,7 @@ EXPORT_SYMBOL_GPL(xenbus_transaction_end EXPORT_SYMBOL_GPL(xenbus_transaction_end); /* Single read and scanf: returns -errno or num scanned. */ -int xenbus_scanf(xenbus_transaction_t t, +int xenbus_scanf(struct xenbus_transaction t, const char *dir, const char *node, const char *fmt, ...) { va_list ap; @@ -496,7 +496,7 @@ EXPORT_SYMBOL_GPL(xenbus_scanf); EXPORT_SYMBOL_GPL(xenbus_scanf); /* Single printf and write: returns -errno or 0. */ -int xenbus_printf(xenbus_transaction_t t, +int xenbus_printf(struct xenbus_transaction t, const char *dir, const char *node, const char *fmt, ...) { va_list ap; @@ -522,7 +522,7 @@ EXPORT_SYMBOL_GPL(xenbus_printf); EXPORT_SYMBOL_GPL(xenbus_printf); /* Takes tuples of names, scanf-style args, and void **, NULL terminated. */ -int xenbus_gather(xenbus_transaction_t t, const char *dir, ...) +int xenbus_gather(struct xenbus_transaction t, const char *dir, ...) { va_list ap; const char *name; @@ -560,7 +560,7 @@ static int xs_watch(const char *path, co iov[1].iov_base = (void *)token; iov[1].iov_len = strlen(token) + 1; - return xs_error(xs_talkv(XBT_NULL, XS_WATCH, iov, + return xs_error(xs_talkv(XBT_NIL, XS_WATCH, iov, ARRAY_SIZE(iov), NULL)); } @@ -573,7 +573,7 @@ static int xs_unwatch(const char *path, iov[1].iov_base = (char *)token; iov[1].iov_len = strlen(token) + 1; - return xs_error(xs_talkv(XBT_NULL, XS_UNWATCH, iov, + return xs_error(xs_talkv(XBT_NIL, XS_UNWATCH, iov, ARRAY_SIZE(iov), NULL)); } diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hw_irq.h --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hw_irq.h Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hw_irq.h Tue Jun 13 12:12:24 2006 -0600 @@ -68,6 +68,10 @@ extern atomic_t irq_mis_count; #define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs)) -extern void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i); +extern void resend_irq_on_evtchn(struct hw_interrupt_type *h, unsigned int i); +static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) +{ + resend_irq_on_evtchn(h, i); +} #endif /* _ASM_HW_IRQ_H */ diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Tue Jun 13 12:12:24 2006 -0600 @@ -255,6 +255,7 @@ HYPERVISOR_event_channel_op( op.cmd = cmd; memcpy(&op.u, arg, sizeof(op.u)); rc = _hypercall1(int, event_channel_op_compat, &op); + memcpy(arg, &op.u, sizeof(op.u)); } return rc; } @@ -290,6 +291,7 @@ HYPERVISOR_physdev_op( op.cmd = cmd; memcpy(&op.u, arg, sizeof(op.u)); rc = _hypercall1(int, physdev_op_compat, &op); + memcpy(arg, &op.u, sizeof(op.u)); } return rc; } diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h Tue Jun 13 12:12:24 2006 -0600 @@ -116,10 +116,12 @@ __asm__ __volatile__ ("movw %%dx,%1\n\t" __asm__ ( \ "movl %%cr3,%0\n\t" \ :"=r" (__dummy)); \ - machine_to_phys(__dummy); \ + __dummy = xen_cr3_to_pfn(__dummy); \ + mfn_to_pfn(__dummy) << PAGE_SHIFT; \ }) #define write_cr3(x) ({ \ - maddr_t __dummy = phys_to_machine(x); \ + unsigned int __dummy = pfn_to_mfn((x) >> PAGE_SHIFT); \ + __dummy = xen_pfn_to_cr3(__dummy); \ __asm__ __volatile__("movl %0,%%cr3": :"r" (__dummy)); \ }) diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Tue Jun 13 12:12:24 2006 -0600 @@ -61,13 +61,6 @@ static void __init machine_specific_arch .address = { __KERNEL_CS, (unsigned long)nmi }, }; - if (xen_feature(XENFEAT_auto_translated_physmap) && - xen_start_info->shared_info < xen_start_info->nr_pages) { - HYPERVISOR_shared_info = - (shared_info_t *)__va(xen_start_info->shared_info); - memset(empty_zero_page, 0, sizeof(empty_zero_page)); - } - ret = HYPERVISOR_callback_op(CALLBACKOP_register, &event); if (ret == 0) ret = HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe); diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/include/asm-ia64/hw_irq.h --- a/linux-2.6-xen-sparse/include/asm-ia64/hw_irq.h Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/include/asm-ia64/hw_irq.h Tue Jun 13 12:12:24 2006 -0600 @@ -90,15 +90,18 @@ extern void ia64_send_ipi (int cpu, int extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect); extern void register_percpu_irq (ia64_vector vec, struct irqaction *action); -#ifndef CONFIG_XEN static inline void hw_resend_irq (struct hw_interrupt_type *h, unsigned int vector) { +#ifdef CONFIG_XEN + extern void resend_irq_on_evtchn(struct hw_interrupt_type *h, + unsigned int i); + if (is_running_on_xen()) + resend_irq_on_evtchn(h, vector); + else +#endif /* CONFIG_XEN */ platform_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0); } -#else -extern void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i); -#endif /* CONFIG_XEN */ /* * Default implementations for the irq-descriptor API: diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/include/asm-ia64/page.h --- a/linux-2.6-xen-sparse/include/asm-ia64/page.h Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/include/asm-ia64/page.h Tue Jun 13 12:12:24 2006 -0600 @@ -327,6 +327,16 @@ machine_to_phys_for_dma(unsigned long ma #define virt_to_mfn(virt) (__pa(virt) >> PAGE_SHIFT) #define virt_to_machine(virt) __pa(virt) // for tpmfront.c +static inline unsigned long +mfn_to_local_pfn(unsigned long mfn) +{ + extern unsigned long max_mapnr; + unsigned long pfn = mfn_to_pfn(mfn); + if (!pfn_valid(pfn)) + return INVALID_P2M_ENTRY; + return pfn; +} + #endif /* CONFIG_XEN_IA64_DOM0_VP */ #endif /* CONFIG_XEN */ #endif /* __ASSEMBLY__ */ diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hw_irq.h --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hw_irq.h Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hw_irq.h Tue Jun 13 12:12:24 2006 -0600 @@ -132,7 +132,11 @@ __asm__( \ "push $" #nr "-256 ; " \ "jmp common_interrupt"); -extern void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i); +extern void resend_irq_on_evtchn(struct hw_interrupt_type *h, unsigned int i); +static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) +{ + resend_irq_on_evtchn(h, i); +} #define platform_legacy_irq(irq) ((irq) < 16) diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h Tue Jun 13 12:12:24 2006 -0600 @@ -253,6 +253,7 @@ HYPERVISOR_event_channel_op( op.cmd = cmd; memcpy(&op.u, arg, sizeof(op.u)); rc = _hypercall1(int, event_channel_op_compat, &op); + memcpy(arg, &op.u, sizeof(op.u)); } return rc; } @@ -288,6 +289,7 @@ HYPERVISOR_physdev_op( op.cmd = cmd; memcpy(&op.u, arg, sizeof(op.u)); rc = _hypercall1(int, physdev_op_compat, &op); + memcpy(arg, &op.u, sizeof(op.u)); } return rc; } diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/include/xen/public/privcmd.h --- a/linux-2.6-xen-sparse/include/xen/public/privcmd.h Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/include/xen/public/privcmd.h Tue Jun 13 12:12:24 2006 -0600 @@ -33,20 +33,22 @@ #ifndef __LINUX_PUBLIC_PRIVCMD_H__ #define __LINUX_PUBLIC_PRIVCMD_H__ +#include <linux/types.h> + #ifndef __user #define __user #endif typedef struct privcmd_hypercall { - unsigned long op; - unsigned long arg[5]; + __u64 op; + __u64 arg[5]; } privcmd_hypercall_t; typedef struct privcmd_mmap_entry { - unsigned long va; - unsigned long mfn; - unsigned long npages; + __u64 va; + __u64 mfn; + __u64 npages; } privcmd_mmap_entry_t; typedef struct privcmd_mmap { @@ -58,8 +60,8 @@ typedef struct privcmd_mmapbatch { typedef struct privcmd_mmapbatch { int num; /* number of pages to populate */ domid_t dom; /* target domain */ - unsigned long addr; /* virtual address */ - unsigned long __user *arr; /* array of mfns - top nibble set on err */ + __u64 addr; /* virtual address */ + xen_pfn_t __user *arr; /* array of mfns - top nibble set on err */ } privcmd_mmapbatch_t; /* diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/include/xen/xenbus.h --- a/linux-2.6-xen-sparse/include/xen/xenbus.h Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/include/xen/xenbus.h Tue Jun 13 12:12:24 2006 -0600 @@ -41,8 +41,6 @@ #include <xen/interface/grant_table.h> #include <xen/interface/io/xenbus.h> #include <xen/interface/io/xs_wire.h> - -#define XBT_NULL 0 /* Register callback to watch this node. */ struct xenbus_watch @@ -76,7 +74,6 @@ struct xenbus_device { struct xenbus_watch otherend_watch; struct device dev; enum xenbus_state state; - void *data; }; static inline struct xenbus_device *to_xenbus_device(struct device *dev) @@ -116,35 +113,41 @@ int xenbus_register_backend(struct xenbu int xenbus_register_backend(struct xenbus_driver *drv); void xenbus_unregister_driver(struct xenbus_driver *drv); -typedef u32 xenbus_transaction_t; - -char **xenbus_directory(xenbus_transaction_t t, +struct xenbus_transaction +{ + u32 id; +}; + +/* Nil transaction ID. */ +#define XBT_NIL ((struct xenbus_transaction) { 0 }) + +char **xenbus_directory(struct xenbus_transaction t, const char *dir, const char *node, unsigned int *num); -void *xenbus_read(xenbus_transaction_t t, +void *xenbus_read(struct xenbus_transaction t, const char *dir, const char *node, unsigned int *len); -int xenbus_write(xenbus_transaction_t t, +int xenbus_write(struct xenbus_transaction t, const char *dir, const char *node, const char *string); -int xenbus_mkdir(xenbus_transaction_t t, +int xenbus_mkdir(struct xenbus_transaction t, const char *dir, const char *node); -int xenbus_exists(xenbus_transaction_t t, +int xenbus_exists(struct xenbus_transaction t, const char *dir, const char *node); -int xenbus_rm(xenbus_transaction_t t, const char *dir, const char *node); -int xenbus_transaction_start(xenbus_transaction_t *t); -int xenbus_transaction_end(xenbus_transaction_t t, int abort); +int xenbus_rm(struct xenbus_transaction t, const char *dir, const char *node); +int xenbus_transaction_start(struct xenbus_transaction *t); +int xenbus_transaction_end(struct xenbus_transaction t, int abort); /* Single read and scanf: returns -errno or num scanned if > 0. */ -int xenbus_scanf(xenbus_transaction_t t, +int xenbus_scanf(struct xenbus_transaction t, const char *dir, const char *node, const char *fmt, ...) __attribute__((format(scanf, 4, 5))); /* Single printf and write: returns -errno or 0. */ -int xenbus_printf(xenbus_transaction_t t, +int xenbus_printf(struct xenbus_transaction t, const char *dir, const char *node, const char *fmt, ...) __attribute__((format(printf, 4, 5))); /* Generic read function: NULL-terminated triples of name, * sprintf-style type string, and pointer. Returns 0 or errno.*/ -int xenbus_gather(xenbus_transaction_t t, const char *dir, ...); +int xenbus_gather(struct xenbus_transaction t, const char *dir, ...); /* notifer routines for when the xenstore comes up */ int register_xenstore_notifier(struct notifier_block *nb); diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/mm/memory.c --- a/linux-2.6-xen-sparse/mm/memory.c Tue Jun 13 09:00:32 2006 -0600 +++ b/linux-2.6-xen-sparse/mm/memory.c Tue Jun 13 12:12:24 2006 -0600 @@ -968,7 +968,6 @@ int get_user_pages(struct task_struct *t { int i; unsigned int vm_flags; - int xenpage = 0; /* * Require read or write permissions. @@ -1026,7 +1025,6 @@ int get_user_pages(struct task_struct *t if (vma && (vma->vm_flags & VM_FOREIGN)) { struct page **map = vma->vm_private_data; int offset = (start - vma->vm_start) >> PAGE_SHIFT; - xenpage =1; if (map[offset] != NULL) { if (pages) { struct page *page = map[offset]; diff -r b8f6089cbce3 -r e74c47d073ee tools/debugger/libxendebug/xendebug.c --- a/tools/debugger/libxendebug/xendebug.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/debugger/libxendebug/xendebug.c Tue Jun 13 12:12:24 2006 -0600 @@ -57,7 +57,7 @@ typedef struct domain_context vcpu_guest_context_t context[MAX_VIRT_CPUS]; long total_pages; - unsigned long *page_array; + xen_pfn_t *page_array; unsigned long cr3_phys[MAX_VIRT_CPUS]; unsigned long *cr3_virt[MAX_VIRT_CPUS]; @@ -346,8 +346,9 @@ xendebug_memory_page (domain_context_p c ctxt->cr3_phys[vcpu] = vcpu_ctxt->ctrlreg[3]; if ( ctxt->cr3_virt[vcpu] ) munmap(ctxt->cr3_virt[vcpu], PAGE_SIZE); - ctxt->cr3_virt[vcpu] = xc_map_foreign_range(xc_handle, ctxt->domid, - PAGE_SIZE, PROT_READ, ctxt->cr3_phys[vcpu] >> PAGE_SHIFT); + ctxt->cr3_virt[vcpu] = xc_map_foreign_range( + xc_handle, ctxt->domid, PAGE_SIZE, PROT_READ, + xen_cr3_to_pfn(ctxt->cr3_phys[vcpu])); if ( ctxt->cr3_virt[vcpu] == NULL ) return 0; } diff -r b8f6089cbce3 -r e74c47d073ee tools/examples/network-bridge --- a/tools/examples/network-bridge Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/examples/network-bridge Tue Jun 13 12:12:24 2006 -0600 @@ -60,6 +60,7 @@ evalVariables "$@" evalVariables "$@" vifnum=${vifnum:-$(ip route list | awk '/^default / { print $NF }' | sed 's/^[^0-9]*//')} +vifnum=${vifnum:-0} bridge=${bridge:-xenbr${vifnum}} netdev=${netdev:-eth${vifnum}} antispoof=${antispoof:-no} diff -r b8f6089cbce3 -r e74c47d073ee tools/firmware/hvmloader/Makefile --- a/tools/firmware/hvmloader/Makefile Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/firmware/hvmloader/Makefile Tue Jun 13 12:12:24 2006 -0600 @@ -51,8 +51,8 @@ hvmloader: roms.h hvmloader.c acpi_madt. $(OBJCOPY) hvmloader.tmp hvmloader rm -f hvmloader.tmp -roms.h: ../rombios/BIOS-bochs-8-processors ../vgabios/VGABIOS-lgpl-latest.bin ../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin - sh ./mkhex rombios ../rombios/BIOS-bochs-8-processors > roms.h +roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin ../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin + sh ./mkhex rombios ../rombios/BIOS-bochs-latest > roms.h sh ./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h sh ./mkhex vgabios_cirrusvga ../vgabios/VGABIOS-lgpl-latest.cirrus.bin >> roms.h sh ./mkhex vmxassist ../vmxassist/vmxassist.bin >> roms.h diff -r b8f6089cbce3 -r e74c47d073ee tools/firmware/rombios/Makefile --- a/tools/firmware/rombios/Makefile Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/firmware/rombios/Makefile Tue Jun 13 12:12:24 2006 -0600 @@ -1,7 +1,7 @@ -#BIOS_BUILDS = BIOS-bochs-latest +BIOS_BUILDS = BIOS-bochs-latest #BIOS_BUILDS += BIOS-bochs-2-processors #BIOS_BUILDS += BIOS-bochs-4-processors -BIOS_BUILDS += BIOS-bochs-8-processors +#BIOS_BUILDS += BIOS-bochs-8-processors .PHONY: all all: bios diff -r b8f6089cbce3 -r e74c47d073ee tools/firmware/vgabios/clext.c --- a/tools/firmware/vgabios/clext.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/firmware/vgabios/clext.c Tue Jun 13 12:12:24 2006 -0600 @@ -525,6 +525,13 @@ cirrus_set_video_mode_extended: cirrus_set_video_mode_extended: call cirrus_switch_mode pop ax ;; mode + test al, #0x80 + jnz cirrus_set_video_mode_extended_1 + push ax + mov ax, #0xffff ; set to 0xff to keep win 2K happy + call cirrus_clear_vram + pop ax +cirrus_set_video_mode_extended_1: and al, #0x7f push ds @@ -992,6 +999,13 @@ cirrus_vesa_02h_1: jnz cirrus_vesa_02h_3 call cirrus_enable_16k_granularity cirrus_vesa_02h_3: + test bx, #0x8000 ;; no clear + jnz cirrus_vesa_02h_4 + push ax + xor ax,ax + call cirrus_clear_vram + pop ax +cirrus_vesa_02h_4: pop ax push ds #ifdef CIRRUS_VESA3_PMINFO @@ -1460,6 +1474,38 @@ cirrus_get_start_addr: pop bx ret +cirrus_clear_vram: + pusha + push es + mov si, ax + + call cirrus_enable_16k_granularity + call cirrus_extbios_85h + shl al, #2 + mov bl, al + xor ah,ah +cirrus_clear_vram_1: + mov al, #0x09 + mov dx, #0x3ce + out dx, ax + push ax + mov cx, #0xa000 + mov es, cx + xor di, di + mov ax, si + mov cx, #8192 + cld + rep + stosw + pop ax + inc ah + cmp ah, bl + jne cirrus_clear_vram_1 + + pop es + popa + ret + cirrus_extbios_handlers: ;; 80h dw cirrus_extbios_80h diff -r b8f6089cbce3 -r e74c47d073ee tools/firmware/vmxassist/vm86.c --- a/tools/firmware/vmxassist/vm86.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/firmware/vmxassist/vm86.c Tue Jun 13 12:12:24 2006 -0600 @@ -36,6 +36,8 @@ static unsigned prev_eip = 0; enum vm86_mode mode = 0; + +static struct regs saved_rm_regs; #ifdef DEBUG int traceset = 0; @@ -795,6 +797,8 @@ protected_mode(struct regs *regs) oldctx.esp = regs->uesp; oldctx.eflags = regs->eflags; + memset(&saved_rm_regs, 0, sizeof(struct regs)); + /* reload all segment registers */ if (!load_seg(regs->cs, &oldctx.cs_base, &oldctx.cs_limit, &oldctx.cs_arbytes)) @@ -808,6 +812,7 @@ protected_mode(struct regs *regs) load_seg(0, &oldctx.es_base, &oldctx.es_limit, &oldctx.es_arbytes); oldctx.es_sel = 0; + saved_rm_regs.ves = regs->ves; } if (load_seg(regs->uss, &oldctx.ss_base, @@ -817,6 +822,7 @@ protected_mode(struct regs *regs) load_seg(0, &oldctx.ss_base, &oldctx.ss_limit, &oldctx.ss_arbytes); oldctx.ss_sel = 0; + saved_rm_regs.uss = regs->uss; } if (load_seg(regs->vds, &oldctx.ds_base, @@ -826,6 +832,7 @@ protected_mode(struct regs *regs) load_seg(0, &oldctx.ds_base, &oldctx.ds_limit, &oldctx.ds_arbytes); oldctx.ds_sel = 0; + saved_rm_regs.vds = regs->vds; } if (load_seg(regs->vfs, &oldctx.fs_base, @@ -835,6 +842,7 @@ protected_mode(struct regs *regs) load_seg(0, &oldctx.fs_base, &oldctx.fs_limit, &oldctx.fs_arbytes); oldctx.fs_sel = 0; + saved_rm_regs.vfs = regs->vfs; } if (load_seg(regs->vgs, &oldctx.gs_base, @@ -844,6 +852,7 @@ protected_mode(struct regs *regs) load_seg(0, &oldctx.gs_base, &oldctx.gs_limit, &oldctx.gs_arbytes); oldctx.gs_sel = 0; + saved_rm_regs.vgs = regs->vgs; } /* initialize jump environment to warp back to protected mode */ @@ -880,16 +889,22 @@ real_mode(struct regs *regs) if (regs->uss >= HIGHMEM) panic("%%ss 0x%lx higher than 1MB", regs->uss); regs->uss = address(regs, regs->uss, 0) >> 4; + } else { + regs->uss = saved_rm_regs.uss; } if (regs->vds != 0) { if (regs->vds >= HIGHMEM) panic("%%ds 0x%lx higher than 1MB", regs->vds); regs->vds = address(regs, regs->vds, 0) >> 4; + } else { + regs->vds = saved_rm_regs.vds; } if (regs->ves != 0) { if (regs->ves >= HIGHMEM) panic("%%es 0x%lx higher than 1MB", regs->ves); regs->ves = address(regs, regs->ves, 0) >> 4; + } else { + regs->ves = saved_rm_regs.ves; } /* this should get us into 16-bit mode */ @@ -971,6 +986,39 @@ jmpl(struct regs *regs, int prefix) } else if (mode == VM86_PROTECTED_TO_REAL) { /* jump to real mode */ eip = (prefix & DATA32) ? fetch32(regs) : fetch16(regs); cs = fetch16(regs); + + TRACE((regs, (regs->eip - n) + 1, "jmpl 0x%x:0x%x", cs, eip)); + + regs->cs = cs; + regs->eip = eip; + set_mode(regs, VM86_REAL); + } else + panic("jmpl"); +} + +static void +jmpl_indirect(struct regs *regs, int prefix, unsigned modrm) +{ + unsigned n = regs->eip; + unsigned cs, eip; + unsigned addr; + + addr = operand(prefix, regs, modrm); + + if (mode == VM86_REAL_TO_PROTECTED) { /* jump to protected mode */ + eip = (prefix & DATA32) ? read32(addr) : read16(addr); + addr += (prefix & DATA32) ? 4 : 2; + cs = read16(addr); + + TRACE((regs, (regs->eip - n) + 1, "jmpl 0x%x:0x%x", cs, eip)); + + regs->cs = cs; + regs->eip = eip; + set_mode(regs, VM86_PROTECTED); + } else if (mode == VM86_PROTECTED_TO_REAL) { /* jump to real mode */ + eip = (prefix & DATA32) ? read32(addr) : read16(addr); + addr += (prefix & DATA32) ? 4 : 2; + cs = read16(addr); TRACE((regs, (regs->eip - n) + 1, "jmpl 0x%x:0x%x", cs, eip)); @@ -1306,6 +1354,23 @@ opcode(struct regs *regs) } goto invalid; + case 0xFF: /* jmpl (indirect) */ + if ((mode == VM86_REAL_TO_PROTECTED) || + (mode == VM86_PROTECTED_TO_REAL)) { + unsigned modrm = fetch8(regs); + + switch((modrm >> 3) & 7) { + case 5: + jmpl_indirect(regs, prefix, modrm); + return OPC_INVALID; + + default: + break; + } + + } + goto invalid; + case 0xEB: /* short jump */ if ((mode == VM86_REAL_TO_PROTECTED) || (mode == VM86_PROTECTED_TO_REAL)) { diff -r b8f6089cbce3 -r e74c47d073ee tools/ioemu/hw/cirrus_vga.c --- a/tools/ioemu/hw/cirrus_vga.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/ioemu/hw/cirrus_vga.c Tue Jun 13 12:12:24 2006 -0600 @@ -1191,17 +1191,6 @@ cirrus_hook_write_sr(CirrusVGAState * s, s->hw_cursor_y = (reg_value << 3) | (reg_index >> 5); break; case 0x07: // Extended Sequencer Mode - /* Win2K seems to assume that the VRAM is set to 0xff - * whenever VGA/SVGA mode changes - */ - if ((s->sr[0x07] ^ reg_value) & CIRRUS_SR7_BPP_SVGA) - memset(s->vram_ptr, 0xff, s->real_vram_size); - s->sr[0x07] = reg_value; -#ifdef DEBUG_CIRRUS - printf("cirrus: handled outport sr_index %02x, sr_value %02x\n", - reg_index, reg_value); -#endif - break; case 0x08: // EEPROM Control case 0x09: // Scratch Register 0 case 0x0a: // Scratch Register 1 @@ -2460,10 +2449,9 @@ static CPUWriteMemoryFunc *cirrus_linear }; extern FILE *logfile; -#if defined(__i386__) || defined (__x86_64__) static void * set_vram_mapping(unsigned long begin, unsigned long end) { - unsigned long * extent_start = NULL; + xen_pfn_t *extent_start = NULL; unsigned long nr_extents; void *vram_pointer = NULL; int i; @@ -2474,14 +2462,14 @@ static void * set_vram_mapping(unsigned end = (end + TARGET_PAGE_SIZE -1 ) & TARGET_PAGE_MASK; nr_extents = (end - begin) >> TARGET_PAGE_BITS; - extent_start = malloc(sizeof(unsigned long) * nr_extents ); + extent_start = malloc(sizeof(xen_pfn_t) * nr_extents ); if (extent_start == NULL) { fprintf(stderr, "Failed malloc on set_vram_mapping\n"); return NULL; } - memset(extent_start, 0, sizeof(unsigned long) * nr_extents); + memset(extent_start, 0, sizeof(xen_pfn_t) * nr_extents); for (i = 0; i < nr_extents; i++) { @@ -2509,7 +2497,7 @@ static void * set_vram_mapping(unsigned static int unset_vram_mapping(unsigned long begin, unsigned long end) { - unsigned long * extent_start = NULL; + xen_pfn_t *extent_start = NULL; unsigned long nr_extents; int i; @@ -2520,7 +2508,7 @@ static int unset_vram_mapping(unsigned l end = (end + TARGET_PAGE_SIZE -1 ) & TARGET_PAGE_MASK; nr_extents = (end - begin) >> TARGET_PAGE_BITS; - extent_start = malloc(sizeof(unsigned long) * nr_extents ); + extent_start = malloc(sizeof(xen_pfn_t) * nr_extents ); if (extent_start == NULL) { @@ -2528,7 +2516,7 @@ static int unset_vram_mapping(unsigned l return -1; } - memset(extent_start, 0, sizeof(unsigned long) * nr_extents); + memset(extent_start, 0, sizeof(xen_pfn_t) * nr_extents); for (i = 0; i < nr_extents; i++) extent_start[i] = (begin + (i * TARGET_PAGE_SIZE)) >> TARGET_PAGE_BITS; @@ -2540,10 +2528,6 @@ static int unset_vram_mapping(unsigned l return 0; } -#elif defined(__ia64__) -static void * set_vram_mapping(unsigned long addr, unsigned long end) {} -static int unset_vram_mapping(unsigned long addr, unsigned long end) {} -#endif extern int vga_accelerate; /* Compute the memory access functions */ diff -r b8f6089cbce3 -r e74c47d073ee tools/ioemu/hw/pc.c --- a/tools/ioemu/hw/pc.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/ioemu/hw/pc.c Tue Jun 13 12:12:24 2006 -0600 @@ -40,6 +40,7 @@ int dummy_refresh_clock; int dummy_refresh_clock; static fdctrl_t *floppy_controller; static RTCState *rtc_state; +static USBPort *usb_root_ports[2]; static void ioport80_write(void *opaque, uint32_t addr, uint32_t data) { @@ -537,8 +538,11 @@ void pc_init(uint64_t ram_size, int vga_ for(i = 0; i < MAX_SERIAL_PORTS; i++) { if (serial_hds[i]) { sp = serial_init(serial_io[i], serial_irq[i], serial_hds[i]); - if (i == SUMMA_PORT) + if (i == serial_summa_port) { summa_init(sp, serial_hds[i]); + fprintf(stderr, "Serial port %d (COM%d) initialized for Summagraphics\n", + i, i+1); + } } } @@ -581,6 +585,11 @@ void pc_init(uint64_t ram_size, int vga_ cmos_init(ram_size, boot_device, bs_table, timeoffset); acpi_init(0x8000); + if (pci_enabled && usb_enabled) { + usb_uhci_init(pci_bus, usb_root_ports); + usb_attach(usb_root_ports[0], vm_usb_hub); + } + /* must be done after all PCI devices are instanciated */ /* XXX: should be done in the Bochs BIOS */ if (pci_enabled) { diff -r b8f6089cbce3 -r e74c47d073ee tools/ioemu/hw/pckbd.c --- a/tools/ioemu/hw/pckbd.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/ioemu/hw/pckbd.c Tue Jun 13 12:12:24 2006 -0600 @@ -118,6 +118,9 @@ #define SUMMA_MAXX (16000 - 1) #define SUMMA_MAXY (16000 - 1) +#define MAX_ABSX 0x7fff +#define MAX_ABSY 0x7fff + typedef struct { uint8_t aux[KBD_QUEUE_SIZE]; uint8_t data[KBD_QUEUE_SIZE]; @@ -149,8 +152,6 @@ typedef struct KBDState { uint8_t mouse_wrap; uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */ uint8_t mouse_detect_state; - int mouse_x; /* absolute coordinates (for mousepad) */ - int mouse_y; int mouse_dx; /* current values, needed for 'poll' mode */ int mouse_dy; int mouse_dz; @@ -422,7 +423,7 @@ static void kbd_write_keyboard(KBDState int mouse_maxx, mouse_maxy; -static int kbd_mouse_send_packet(KBDState *s) +static void kbd_mouse_send_packet(KBDState *s) { unsigned int b; int dx1, dy1, dz1; @@ -430,100 +431,63 @@ static int kbd_mouse_send_packet(KBDStat dx1 = s->mouse_dx; dy1 = s->mouse_dy; dz1 = s->mouse_dz; + /* XXX: increase range to 8 bits ? */ + if (dx1 > 127) + dx1 = 127; + else if (dx1 < -127) + dx1 = -127; + if (dy1 > 127) + dy1 = 127; + else if (dy1 < -127) + dy1 = -127; + b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07); + kbd_queue(s, b, 1); + kbd_queue(s, dx1 & 0xff, 1); + kbd_queue(s, dy1 & 0xff, 1); + /* extra byte for IMPS/2 or IMEX */ switch(s->mouse_type) { - - case TABLET: /* Summagraphics pen tablet */ - if (SummaState.report_mode == MODE_STREAM) { - dx1 = s->mouse_x; - dy1 = s->mouse_y; - if (SummaState.origin == ORIGIN_LOWER_LEFT) - dy1 = mouse_maxy - dy1; - dx1 = ((dx1 * SUMMA_MAXX) / mouse_maxx) + SUMMA_BORDER; - dy1 = ((dy1 * SUMMA_MAXY) / mouse_maxy) + SUMMA_BORDER; - ser_queue(s->serial, 0x80 | (s->mouse_buttons & 7)); - ser_queue(s->serial, dx1 & 0x7f); - ser_queue(s->serial, dx1 >> 7); - ser_queue(s->serial, dy1 & 0x7f); - ser_queue(s->serial, dy1 >> 7); - } - s->mouse_dx = 0; - s->mouse_dy = 0; - s->mouse_dz = 0; - return 0; - - default: /* PS/2 style mice */ - /* XXX: increase range to 8 bits ? */ - if (dx1 > 127) - dx1 = 127; - else if (dx1 < -127) - dx1 = -127; - if (dy1 > 127) - dy1 = 127; - else if (dy1 < -127) - dy1 = -127; - b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07); - kbd_queue(s, b, 1); - kbd_queue(s, dx1 & 0xff, 1); - kbd_queue(s, dy1 & 0xff, 1); - /* extra byte for IMPS/2 or IMEX */ - switch(s->mouse_type) { - - default: - break; - - case IMPS2: - if (dz1 > 127) - dz1 = 127; - else if (dz1 < -127) - dz1 = -127; - kbd_queue(s, dz1 & 0xff, 1); - break; - - case IMEX: - if (dz1 > 7) - dz1 = 7; - else if (dz1 < -7) - dz1 = -7; - b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1); - kbd_queue(s, b, 1); - break; - } - - /* update deltas */ - s->mouse_dx -= dx1; - s->mouse_dy -= dy1; - s->mouse_dz -= dz1; - return s->mouse_dx || s->mouse_dy || s->mouse_dz; - - } -} - -static void pc_kbd_mouse_event(void *opaque, - int dx, int dy, int dz, int buttons_state, - int x, int y) + default: + break; + case IMPS2: + if (dz1 > 127) + dz1 = 127; + else if (dz1 < -127) + dz1 = -127; + kbd_queue(s, dz1 & 0xff, 1); + break; + case IMEX: + if (dz1 > 7) + dz1 = 7; + else if (dz1 < -7) + dz1 = -7; + b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1); + kbd_queue(s, b, 1); + break; + } + + /* update deltas */ + s->mouse_dx -= dx1; + s->mouse_dy -= dy1; + s->mouse_dz -= dz1; +} + +static void summa_mouse_event(void *opaque, int x, int y, int z, int buttons_state) { KBDState *s = opaque; - /* check if deltas are recorded when disabled */ - if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) - return; - - s->mouse_x = x; - s->mouse_y = y; - s->mouse_dx += dx; - s->mouse_dy -= dy; - s->mouse_dz += dz; - /* XXX: SDL sometimes generates nul events: we delete them */ - if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0 && - s->mouse_buttons == buttons_state) - return; - s->mouse_buttons = buttons_state; - - if (!(s->mouse_status & MOUSE_STATUS_REMOTE) && - (s->queue.count < (KBD_QUEUE_SIZE - 16))) { - while (kbd_mouse_send_packet(s)) - ; - } + if (SummaState.report_mode == MODE_STREAM) { + if (SummaState.origin == ORIGIN_LOWER_LEFT) + y = mouse_maxy - y; + x = ((x * SUMMA_MAXX) / MAX_ABSX) + SUMMA_BORDER; + y = ((y * SUMMA_MAXY) / MAX_ABSY) + SUMMA_BORDER; +fprintf(stderr, "summa_mouse_event: x, y - %d, %d\n", x, y); + ser_queue(s->serial, 0x80 | (buttons_state & 7)); + ser_queue(s->serial, x & 0x7f); + ser_queue(s->serial, x >> 7); + ser_queue(s->serial, y & 0x7f); + ser_queue(s->serial, y >> 7); + } + return; } static void summa(KBDState *s, uint8_t val) @@ -564,6 +528,7 @@ static void summa(KBDState *s, uint8_t v s->mouse_status |= MOUSE_STATUS_ENABLED; SummaState.origin = ORIGIN_LOWER_LEFT; SummaState.report_mode = (val == 'B') ? MODE_POINT : MODE_STREAM_SWITCH; + qemu_add_mouse_event_handler(summa_mouse_event, s, 1); break; case 'z': /* start of 2 byte command */ @@ -645,6 +610,36 @@ void summa_init(SerialState *serial, Cha chr->chr_write = summa_write; chr->opaque = (void *)&kbd_state; return; +} + +static void pc_kbd_mouse_event(void *opaque, + int dx, int dy, int dz, int buttons_state) +{ + KBDState *s = opaque; + + /* check if deltas are recorded when disabled */ + if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) + return; + + s->mouse_dx += dx; + s->mouse_dy -= dy; + s->mouse_dz += dz; + /* XXX: SDL sometimes generates nul events: we delete them */ + if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0 && + s->mouse_buttons == buttons_state) + return; + s->mouse_buttons = buttons_state; + + if (!(s->mouse_status & MOUSE_STATUS_REMOTE) && + (s->queue.count < (KBD_QUEUE_SIZE - 16))) { + for(;;) { + /* if not remote, send event. Multiple events are sent if + too big deltas */ + kbd_mouse_send_packet(s); + if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0) + break; + } + } } static void kbd_write_mouse(KBDState *s, int val) @@ -890,6 +885,6 @@ void kbd_init(void) register_ioport_write(0x64, 1, 1, kbd_write_command, s); qemu_add_kbd_event_handler(pc_kbd_put_keycode, s); - qemu_add_mouse_event_handler(pc_kbd_mouse_event, s); + qemu_add_mouse_event_handler(pc_kbd_mouse_event, s, 0); qemu_register_reset(kbd_reset, s); } diff -r b8f6089cbce3 -r e74c47d073ee tools/ioemu/hw/vga.c --- a/tools/ioemu/hw/vga.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/ioemu/hw/vga.c Tue Jun 13 12:12:24 2006 -0600 @@ -1995,6 +1995,7 @@ void vga_common_init(VGAState *s, Displa s->get_resolution = vga_get_resolution; /* XXX: currently needed for display */ vga_state = s; + vga_bios_init(s); } @@ -2082,7 +2083,6 @@ int vga_initialize(PCIBus *bus, DisplayS #endif } - vga_bios_init(s); return 0; } diff -r b8f6089cbce3 -r e74c47d073ee tools/ioemu/monitor.c --- a/tools/ioemu/monitor.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/ioemu/monitor.c Tue Jun 13 12:12:24 2006 -0600 @@ -492,6 +492,10 @@ static term_cmd_t term_cmds[] = { "", "quit the emulator" }, { "sendkey", "s", do_send_key, "keys", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1')" }, + { "usb_add", "s", do_usb_add, + "device", "add USB device (e.g. 'host:bus.addr' or 'host:vendor_id:product_id')" }, + { "usb_del", "s", do_usb_del, + "device", "remove USB device 'bus.addr'" }, { NULL, NULL, }, }; @@ -510,6 +514,10 @@ static term_cmd_t info_cmds[] = { "", "show i8259 (PIC) state", }, { "pci", "", pci_info, "", "show PCI info", }, + { "usb", "", usb_info, + "", "show guest USB devices", }, + { "usbhost", "", usb_host_info, + "", "show host USB devices", }, { "hvmiopage", "", sp_info, "", "show HVM device model shared page info", }, { NULL, NULL, }, diff -r b8f6089cbce3 -r e74c47d073ee tools/ioemu/sdl.c --- a/tools/ioemu/sdl.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/ioemu/sdl.c Tue Jun 13 12:12:24 2006 -0600 @@ -49,8 +49,12 @@ static int gui_fullscreen_initial_grab; static int gui_fullscreen_initial_grab; static int gui_grab_code = KMOD_LALT | KMOD_LCTRL; static uint8_t modifiers_state[256]; - -SDL_PixelFormat* sdl_get_format() { +static int width, height; +static SDL_Cursor *sdl_cursor_normal; +static SDL_Cursor *sdl_cursor_hidden; +static int absolute_enabled = 0; + +SDL_PixelFormat* sdl_get_format(void) { return screen->format; } @@ -69,6 +73,8 @@ static void sdl_resize(DisplayState *ds, flags |= SDL_RESIZABLE; if (gui_fullscreen) flags |= SDL_FULLSCREEN; + width = w; + height = h; screen = SDL_SetVideoMode(w, h, 0, flags); if (!screen) { fprintf(stderr, "Could not open SDL display\n"); @@ -368,9 +374,21 @@ static void sdl_update_caption(void) SDL_WM_SetCaption(buf, domain_name); } +static void sdl_hide_cursor(void) +{ + SDL_SetCursor(sdl_cursor_hidden); +} + +static void sdl_show_cursor(void) +{ + if (!kbd_mouse_is_absolute()) { + SDL_SetCursor(sdl_cursor_normal); + } +} + static void sdl_grab_start(void) { - SDL_ShowCursor(0); + sdl_hide_cursor(); SDL_WM_GrabInput(SDL_GRAB_ON); /* dummy read to avoid moving the mouse */ SDL_GetRelativeMouseState(NULL, NULL); @@ -381,6 +399,7 @@ static void sdl_grab_end(void) static void sdl_grab_end(void) { SDL_WM_GrabInput(SDL_GRAB_OFF); + sdl_show_cursor(); SDL_ShowCursor(1); gui_grab = 0; sdl_update_caption(); @@ -397,6 +416,21 @@ static void sdl_send_mouse_event(void) buttons |= MOUSE_EVENT_RBUTTON; if (state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) buttons |= MOUSE_EVENT_MBUTTON; + + if (kbd_mouse_is_absolute()) { + if (!absolute_enabled) { + sdl_hide_cursor(); + if (gui_grab) { + sdl_grab_end(); + } + absolute_enabled = 1; + } + + SDL_GetMouseState(&dx, &dy); + dx = dx * 0x7FFF / width; + dy = dy * 0x7FFF / height; + } + /* XXX: test wheel */ dz = 0; #ifdef SDL_BUTTON_WHEELUP @@ -405,7 +439,7 @@ static void sdl_send_mouse_event(void) if (state & SDL_BUTTON(SDL_BUTTON_WHEELDOWN)) dz++; #endif - kbd_mouse_event(dx, dy, dz, buttons, 0, 0); + kbd_mouse_event(dx, dy, dz, buttons); } static void toggle_full_screen(DisplayState *ds) @@ -571,6 +605,7 @@ void sdl_display_init(DisplayState *ds, void sdl_display_init(DisplayState *ds, int full_screen) { int flags; + uint8_t data = 0; if(keyboard_layout) kbd_layout=init_keyboard_layout(keyboard_layout); @@ -597,6 +632,9 @@ void sdl_display_init(DisplayState *ds, SDL_EnableUNICODE(1); gui_grab = 0; + sdl_cursor_hidden = SDL_CreateCursor(&data, &data, 8, 1, 0, 0); + sdl_cursor_normal = SDL_GetCursor(); + atexit(sdl_cleanup); if (full_screen) { gui_fullscreen = 1; diff -r b8f6089cbce3 -r e74c47d073ee tools/ioemu/target-i386-dm/Makefile --- a/tools/ioemu/target-i386-dm/Makefile Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/ioemu/target-i386-dm/Makefile Tue Jun 13 12:12:24 2006 -0600 @@ -274,6 +274,9 @@ audio.o fmodaudio.o: DEFINES := -I$(CONF audio.o fmodaudio.o: DEFINES := -I$(CONFIG_FMOD_INC) $(DEFINES) LIBS += $(CONFIG_FMOD_LIB) endif + +# USB layer +VL_OBJS+= usb.o usb-hub.o usb-uhci.o usb-linux.o usb-hid.o # Hardware support VL_OBJS+= ide.o ne2000.o pckbd.o vga.o dma.o diff -r b8f6089cbce3 -r e74c47d073ee tools/ioemu/vl.c --- a/tools/ioemu/vl.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/ioemu/vl.c Tue Jun 13 12:12:24 2006 -0600 @@ -144,8 +144,12 @@ int graphic_depth = 15; int graphic_depth = 15; int full_screen = 0; int repeat_key = 1; +int usb_enabled = 0; +USBPort *vm_usb_ports[MAX_VM_USB_PORTS]; +USBDevice *vm_usb_hub; TextConsole *vga_console; CharDriverState *serial_hds[MAX_SERIAL_PORTS]; +int serial_summa_port = -1; int xc_handle; time_t timeoffset = 0; @@ -437,6 +441,7 @@ static void *qemu_put_kbd_event_opaque; static void *qemu_put_kbd_event_opaque; static QEMUPutMouseEvent *qemu_put_mouse_event; static void *qemu_put_mouse_event_opaque; +static int qemu_put_mouse_event_absolute; void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque) { @@ -444,10 +449,11 @@ void qemu_add_kbd_event_handler(QEMUPutK qemu_put_kbd_event = func; } -void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque) +void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute) { qemu_put_mouse_event_opaque = opaque; qemu_put_mouse_event = func; + qemu_put_mouse_event_absolute = absolute; } void kbd_put_keycode(int keycode) @@ -457,12 +463,17 @@ void kbd_put_keycode(int keycode) } } -void kbd_mouse_event(int dx, int dy, int dz, int buttons_state, int x, int y) +void kbd_mouse_event(int dx, int dy, int dz, int buttons_state) { if (qemu_put_mouse_event) { qemu_put_mouse_event(qemu_put_mouse_event_opaque, - dx, dy, dz, buttons_state, x, y); - } + dx, dy, dz, buttons_state); + } +} + +int kbd_mouse_is_absolute(void) +{ + return qemu_put_mouse_event_absolute; } /***********************************************************/ @@ -1643,6 +1654,121 @@ static int net_fd_init(NetDriverState *n } #endif /* !_WIN32 */ + +/***********************************************************/ +/* USB devices */ + +static int usb_device_add(const char *devname) +{ + const char *p; + USBDevice *dev; + int i; + + if (!vm_usb_hub) + return -1; + for(i = 0;i < MAX_VM_USB_PORTS; i++) { + if (!vm_usb_ports[i]->dev) + break; + } + if (i == MAX_VM_USB_PORTS) + return -1; + + if (strstart(devname, "host:", &p)) { + dev = usb_host_device_open(p); + if (!dev) + return -1; + } else if (!strcmp(devname, "mouse")) { + dev = usb_mouse_init(); + if (!dev) + return -1; + } else if (!strcmp(devname, "tablet")) { + dev = usb_tablet_init(); + if (!dev) + return -1; + } else { + return -1; + } + usb_attach(vm_usb_ports[i], dev); + return 0; +} + +static int usb_device_del(const char *devname) +{ + USBDevice *dev; + int bus_num, addr, i; + const char *p; + + if (!vm_usb_hub) + return -1; + + p = strchr(devname, '.'); + if (!p) + return -1; + bus_num = strtoul(devname, NULL, 0); + addr = strtoul(p + 1, NULL, 0); + if (bus_num != 0) + return -1; + for(i = 0;i < MAX_VM_USB_PORTS; i++) { + dev = vm_usb_ports[i]->dev; + if (dev && dev->addr == addr) + break; + } + if (i == MAX_VM_USB_PORTS) + return -1; + usb_attach(vm_usb_ports[i], NULL); + return 0; +} + +void do_usb_add(const char *devname) +{ + int ret; + ret = usb_device_add(devname); + if (ret < 0) + term_printf("Could not add USB device '%s'\n", devname); +} + +void do_usb_del(const char *devname) +{ + int ret; + ret = usb_device_del(devname); + if (ret < 0) + term_printf("Could not remove USB device '%s'\n", devname); +} + +void usb_info(void) +{ + USBDevice *dev; + int i; + const char *speed_str; + + if (!vm_usb_hub) { + term_printf("USB support not enabled\n"); + return; + } + + for(i = 0; i < MAX_VM_USB_PORTS; i++) { + dev = vm_usb_ports[i]->dev; + if (dev) { + term_printf("Hub port %d:\n", i); + switch(dev->speed) { + case USB_SPEED_LOW: + speed_str = "1.5"; + break; + case USB_SPEED_FULL: + speed_str = "12"; + break; + case USB_SPEED_HIGH: + speed_str = "480"; + break; + default: + speed_str = "?"; + break; + } + term_printf(" Device %d.%d, speed %s Mb/s\n", + 0, dev->addr, speed_str); + } + } +} /***********************************************************/ /* dumb display */ @@ -2213,6 +2339,8 @@ void help(void) "-enable-audio enable audio support\n" "-localtime set the real time clock to local time [default=utc]\n" "-full-screen start in full screen\n" + "-usb enable the USB driver (will be the default soon)\n" + "-usbdevice name add the host or guest USB device 'name'\n" #ifdef TARGET_PPC "-prep Simulate a PREP system (default is PowerMAC)\n" "-g WxH[xDEPTH] Set the initial VGA graphic mode\n" @@ -2354,6 +2482,8 @@ enum { QEMU_OPTION_full_screen, QEMU_OPTION_vgaacc, QEMU_OPTION_repeatkey, + QEMU_OPTION_usb, + QEMU_OPTION_usbdevice, }; typedef struct QEMUOption { @@ -2427,8 +2557,10 @@ const QEMUOption qemu_options[] = { { "serial", 1, QEMU_OPTION_serial }, { "loadvm", HAS_ARG, QEMU_OPTION_loadvm }, { "full-screen", 0, QEMU_OPTION_full_screen }, + { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice }, /* temporary options */ + { "usb", 0, QEMU_OPTION_usb }, { "pci", 0, QEMU_OPTION_pci }, { "nic-ne2000", 0, QEMU_OPTION_nic_ne2000 }, { "cirrusvga", 0, QEMU_OPTION_cirrusvga }, @@ -2457,7 +2589,7 @@ int unset_mm_mapping(int xc_handle, uint32_t domid, unsigned long nr_pages, unsigned int address_bits, - unsigned long *extent_start) + xen_pfn_t *extent_start) { int err = 0; xc_dominfo_t info; @@ -2490,7 +2622,7 @@ int set_mm_mapping(int xc_handle, uint32_t domid, unsigned long nr_pages, unsigned int address_bits, - unsigned long *extent_start) + xen_pfn_t *extent_start) { xc_dominfo_t info; int err = 0; @@ -2498,7 +2630,7 @@ int set_mm_mapping(int xc_handle, xc_domain_getinfo(xc_handle, domid, 1, &info); if ( xc_domain_setmaxmem(xc_handle, domid, - (info.nr_pages + nr_pages) * PAGE_SIZE/1024) != 0) + info.max_memkb + nr_pages * PAGE_SIZE/1024) !=0) { fprintf(logfile, "set maxmem returned error %d\n", errno); return -1; @@ -2554,9 +2686,12 @@ int main(int argc, char **argv) char monitor_device[128]; char serial_devices[MAX_SERIAL_PORTS][128]; int serial_device_index; + char usb_devices[MAX_VM_USB_PORTS][128]; + int usb_devices_index; char qemu_dm_logfilename[64]; const char *loadvm = NULL; - unsigned long nr_pages, *page_array; + unsigned long nr_pages; + xen_pfn_t *page_array; extern void *shared_page; #if !defined(CONFIG_SOFTMMU) @@ -2588,11 +2723,12 @@ int main(int argc, char **argv) pstrcpy(monitor_device, sizeof(monitor_device), "vc"); pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc"); - pstrcpy(serial_devices[1], sizeof(serial_devices[1]), "null"); - for(i = 2; i < MAX_SERIAL_PORTS; i++) + serial_summa_port = -1; + for(i = 1; i < MAX_SERIAL_PORTS; i++) serial_devices[i][0] = '\0'; serial_device_index = 0; + usb_devices_index = 0; nb_tun_fds = 0; net_if_type = -1; nb_nics = 1; @@ -2937,6 +3073,20 @@ int main(int argc, char **argv) case QEMU_OPTION_full_screen: full_screen = 1; break; + case QEMU_OPTION_usb: + usb_enabled = 1; + break; + case QEMU_OPTION_usbdevice: + usb_enabled = 1; + if (usb_devices_index >= MAX_VM_USB_PORTS) { + fprintf(stderr, "Too many USB devices\n"); + exit(1); + } + pstrcpy(usb_devices[usb_devices_index], + sizeof(usb_devices[usb_devices_index]), + optarg); + usb_devices_index++; + break; case QEMU_OPTION_domainname: strncat(domain_name, optarg, sizeof(domain_name) - 20); break; @@ -3022,8 +3172,8 @@ int main(int argc, char **argv) xc_handle = xc_interface_open(); - if ( (page_array = (unsigned long *) - malloc(nr_pages * sizeof(unsigned long))) == NULL) + if ( (page_array = (xen_pfn_t *) + malloc(nr_pages * sizeof(xen_pfn_t))) == NULL) { fprintf(logfile, "malloc returned error %d\n", errno); exit(-1); @@ -3078,8 +3228,8 @@ int main(int argc, char **argv) page_array[0]); #endif - fprintf(logfile, "shared page at pfn:%lx, mfn: %lx\n", (nr_pages-1), - (page_array[nr_pages - 1])); + fprintf(logfile, "shared page at pfn:%lx, mfn: %"PRIx64"\n", (nr_pages-1), + (uint64_t)(page_array[nr_pages - 1])); /* we always create the cdrom drive, even if no disk is there */ bdrv_init(); @@ -3137,6 +3287,17 @@ int main(int argc, char **argv) } } + /* init USB devices */ + if (usb_enabled) { + vm_usb_hub = usb_hub_init(vm_usb_ports, MAX_VM_USB_PORTS); + for(i = 0; i < usb_devices_index; i++) { + if (usb_device_add(usb_devices[i]) < 0) { + fprintf(stderr, "Warning: could not add USB device %s\n", + usb_devices[i]); + } + } + } + /* init CPU state */ env = cpu_init(); global_env = env; @@ -3172,6 +3333,20 @@ int main(int argc, char **argv) exit(1); } monitor_init(monitor_hd, !nographic); + + /* Find which port should be the Summagraphics port */ + /* It's the first unspecified serial line. Note that COM1 is set */ + /* by default, so the Summagraphics port would be COM2 or higher */ + + for(i = 0; i < MAX_SERIAL_PORTS; i++) { + if (serial_devices[i][0] != '\0') + continue; + serial_summa_port = i; + pstrcpy(serial_devices[serial_summa_port], sizeof(serial_devices[0]), "null"); + break; + } + + /* Now, open the ports */ for(i = 0; i < MAX_SERIAL_PORTS; i++) { if (serial_devices[i][0] != '\0') { diff -r b8f6089cbce3 -r e74c47d073ee tools/ioemu/vl.h --- a/tools/ioemu/vl.h Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/ioemu/vl.h Tue Jun 13 12:12:24 2006 -0600 @@ -154,13 +154,14 @@ extern int graphic_depth; #define MOUSE_EVENT_MBUTTON 0x04 typedef void QEMUPutKBDEvent(void *opaque, int keycode); -typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state, int x, int y); +typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state); void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque); -void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque); +void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute); void kbd_put_keycode(int keycode); -void kbd_mouse_event(int dx, int dy, int dz, int buttons_state, int x, int y); +void kbd_mouse_event(int dx, int dy, int dz, int buttons_state); +int kbd_mouse_is_absolute(void); /* keysym is a unicode code except for special keys (see QEMU_KEY_xxx constants) */ @@ -238,9 +239,9 @@ void console_select(unsigned int index); /* serial ports */ #define MAX_SERIAL_PORTS 4 -#define SUMMA_PORT 1 extern CharDriverState *serial_hds[MAX_SERIAL_PORTS]; +extern int serial_summa_port; /* network redirectors support */ @@ -633,6 +634,7 @@ void kbd_init(void); void kbd_init(void); extern const char* keyboard_layout; extern int repeat_key; +extern int usb_enabled; /* mc146818rtc.c */ @@ -792,6 +794,19 @@ void adb_mouse_init(ADBBusState *bus); /* cuda.c */ +#include "hw/usb.h" + +/* usb ports of the VM */ + +#define MAX_VM_USB_PORTS 8 + +extern USBPort *vm_usb_ports[MAX_VM_USB_PORTS]; +extern USBDevice *vm_usb_hub; + +void do_usb_add(const char *devname); +void do_usb_del(const char *devname); +void usb_info(void); + extern ADBBusState adb_bus; int cuda_init(openpic_t *openpic, int irq); diff -r b8f6089cbce3 -r e74c47d073ee tools/ioemu/vnc.c --- a/tools/ioemu/vnc.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/ioemu/vnc.c Tue Jun 13 12:12:24 2006 -0600 @@ -138,9 +138,16 @@ static void init_mouse(int max_x,int max } static void mouse_refresh() { + static int last_x = -1; + static int last_y = -1; + static int last_z = -1; + static int last_b = -1; int dx=0,dy=0,dz=new_mouse_z; static int counter=1; + if (new_mouse_x == last_x && new_mouse_y == last_y && + new_mouse_z == last_z && new_mouse_buttons == last_b) + return; /* * Simulate lifting the mouse by pressing left <ctl><alt> together * e.g. don't send mouse events. @@ -148,27 +155,40 @@ static void mouse_refresh() { if (ctl_keys == 3) { mouse_x = new_mouse_x; mouse_y = new_mouse_y; + last_x = new_mouse_x; + last_y = new_mouse_y; + last_z = new_mouse_z; + last_b = new_mouse_buttons; return; } counter++; - if(!mouse_magic->calibration && counter>=2) { counter=0; return; } - - dx=new_mouse_x-mouse_x; - dy=new_mouse_y-mouse_y; - - if(mouse_magic->sonic_wall_is_orthogonal) { - if(abs(dx)>=mouse_magic->sonic_wall_x) { dx/=2; mouse_x+=dx; } - if(abs(dy)>=mouse_magic->sonic_wall_y) { dy/=2; mouse_y+=dy; } + //fprintf(stderr,"sending mouse event %d,%d\n",dx,dy); + if (kbd_mouse_is_absolute()) { + kbd_mouse_event(new_mouse_x * 0x7FFF / screen->width, + new_mouse_y * 0x7FFF / screen->height, dz, new_mouse_buttons); } else { - if(abs(dx)>=mouse_magic->sonic_wall_x || abs(dy)>=mouse_magic->sonic_wall_y) { - dx/=2; mouse_x+=dx; - dy/=2; mouse_y+=dy; - } - } - //fprintf(stderr,"sending mouse event %d,%d\n",dx,dy); - kbd_mouse_event(dx,dy,dz,new_mouse_buttons,new_mouse_x,new_mouse_y); - mouse_x+=dx; - mouse_y+=dy; + if(!mouse_magic->calibration && counter>=2) { counter=0; return; } + + dx=new_mouse_x-last_x; + dy=new_mouse_y-last_y; + + if(mouse_magic->sonic_wall_is_orthogonal) { + if(abs(dx)>=mouse_magic->sonic_wall_x) { dx/=2; mouse_x+=dx; } + if(abs(dy)>=mouse_magic->sonic_wall_y) { dy/=2; mouse_y+=dy; } + } else { + if(abs(dx)>=mouse_magic->sonic_wall_x || abs(dy)>=mouse_magic->sonic_wall_y) { + dx/=2; mouse_x+=dx; + dy/=2; mouse_y+=dy; + } + } + if (last_x != -1) + kbd_mouse_event(dx,dy,dz,new_mouse_buttons); + + } + last_x = new_mouse_x; + last_y = new_mouse_y; + last_z = new_mouse_z; + last_b = new_mouse_buttons; updates_since_mouse=0; } @@ -250,7 +270,7 @@ static void mouse_calibration_refresh() if(calibration_step==0) { x=0; y=1; - kbd_mouse_event(0,-1,0,0,x,y); + kbd_mouse_event(0,-1,0,0); calibration_step++; } else if(calibration_step==1) { // find out the initial position of the cursor @@ -282,7 +302,7 @@ static void mouse_calibration_refresh() } else { y++; move_calibrate: - kbd_mouse_event(-x,-y,0,0,x,y); + kbd_mouse_event(-x,-y,0,0); before_update=last_update; } } else if(calibration_step==3) { diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_core.c --- a/tools/libxc/xc_core.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/libxc/xc_core.c Tue Jun 13 12:12:24 2006 -0600 @@ -28,7 +28,7 @@ xc_domain_dumpcore_via_callback(int xc_h dumpcore_rtn_t dump_rtn) { unsigned long nr_pages; - unsigned long *page_array = NULL; + xen_pfn_t *page_array = NULL; xc_dominfo_t info; int i, nr_vcpus = 0; char *dump_mem, *dump_mem_start = NULL; @@ -70,7 +70,7 @@ xc_domain_dumpcore_via_callback(int xc_h sizeof(vcpu_guest_context_t)*nr_vcpus; dummy_len = (sizeof(struct xc_core_header) + (sizeof(vcpu_guest_context_t) * nr_vcpus) + - (nr_pages * sizeof(unsigned long))); + (nr_pages * sizeof(xen_pfn_t))); header.xch_pages_offset = round_pgup(dummy_len); sts = dump_rtn(args, (char *)&header, sizeof(struct xc_core_header)); @@ -81,17 +81,17 @@ xc_domain_dumpcore_via_callback(int xc_h if ( sts != 0 ) goto error_out; - if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL ) + if ( (page_array = malloc(nr_pages * sizeof(xen_pfn_t))) == NULL ) { - printf("Could not allocate memory\n"); + IPRINTF("Could not allocate memory\n"); goto error_out; } if ( xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages ) { - printf("Could not get the page frame list\n"); + IPRINTF("Could not get the page frame list\n"); goto error_out; } - sts = dump_rtn(args, (char *)page_array, nr_pages * sizeof(unsigned long)); + sts = dump_rtn(args, (char *)page_array, nr_pages * sizeof(xen_pfn_t)); if ( sts != 0 ) goto error_out; diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_domain.c --- a/tools/libxc/xc_domain.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/libxc/xc_domain.c Tue Jun 13 12:12:24 2006 -0600 @@ -291,7 +291,7 @@ int xc_domain_memory_increase_reservatio unsigned long nr_extents, unsigned int extent_order, unsigned int address_bits, - unsigned long *extent_start) + xen_pfn_t *extent_start) { int err; struct xen_memory_reservation reservation = { @@ -310,7 +310,7 @@ int xc_domain_memory_increase_reservatio if ( err > 0 ) { - fprintf(stderr, "Failed allocation for dom %d: " + DPRINTF("Failed allocation for dom %d: " "%ld pages order %d addr_bits %d\n", domid, nr_extents, extent_order, address_bits); errno = ENOMEM; @@ -324,7 +324,7 @@ int xc_domain_memory_decrease_reservatio uint32_t domid, unsigned long nr_extents, unsigned int extent_order, - unsigned long *extent_start) + xen_pfn_t *extent_start) { int err; struct xen_memory_reservation reservation = { @@ -338,7 +338,7 @@ int xc_domain_memory_decrease_reservatio if ( extent_start == NULL ) { - fprintf(stderr,"decrease_reservation extent_start is NULL!\n"); + DPRINTF("decrease_reservation extent_start is NULL!\n"); errno = EINVAL; return -1; } @@ -349,7 +349,7 @@ int xc_domain_memory_decrease_reservatio if ( err > 0 ) { - fprintf(stderr,"Failed deallocation for dom %d: %ld pages order %d\n", + DPRINTF("Failed deallocation for dom %d: %ld pages order %d\n", domid, nr_extents, extent_order); errno = EBUSY; err = -1; @@ -363,7 +363,7 @@ int xc_domain_memory_populate_physmap(in unsigned long nr_extents, unsigned int extent_order, unsigned int address_bits, - unsigned long *extent_start) + xen_pfn_t *extent_start) { int err; struct xen_memory_reservation reservation = { @@ -380,7 +380,7 @@ int xc_domain_memory_populate_physmap(in if ( err > 0 ) { - fprintf(stderr,"Failed deallocation for dom %d: %ld pages order %d\n", + DPRINTF("Failed deallocation for dom %d: %ld pages order %d\n", domid, nr_extents, extent_order); errno = EBUSY; err = -1; @@ -392,8 +392,8 @@ int xc_domain_translate_gpfn_list(int xc int xc_domain_translate_gpfn_list(int xc_handle, uint32_t domid, unsigned long nr_gpfns, - unsigned long *gpfn_list, - unsigned long *mfn_list) + xen_pfn_t *gpfn_list, + xen_pfn_t *mfn_list) { struct xen_translate_gpfn_list op = { .domid = domid, diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_hvm_build.c --- a/tools/libxc/xc_hvm_build.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/libxc/xc_hvm_build.c Tue Jun 13 12:12:24 2006 -0600 @@ -135,7 +135,7 @@ static void set_hvm_info_checksum(struct * hvmloader will use this info to set BIOS accordingly */ static int set_hvm_info(int xc_handle, uint32_t dom, - unsigned long *pfn_list, unsigned int vcpus, + xen_pfn_t *pfn_list, unsigned int vcpus, unsigned int pae, unsigned int acpi, unsigned int apic) { char *va_map; @@ -178,7 +178,7 @@ static int setup_guest(int xc_handle, unsigned int store_evtchn, unsigned long *store_mfn) { - unsigned long *page_array = NULL; + xen_pfn_t *page_array = NULL; unsigned long count, i; unsigned long long ptr; xc_mmu_t *mmu = NULL; @@ -207,12 +207,12 @@ static int setup_guest(int xc_handle, /* memsize is in megabytes */ v_end = (unsigned long long)memsize << 20; - printf("VIRTUAL MEMORY ARRANGEMENT:\n" + IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n" " Loaded HVM loader: %08lx->%08lx\n" " TOTAL: %08lx->%016llx\n", dsi.v_kernstart, dsi.v_kernend, dsi.v_start, v_end); - printf(" ENTRY ADDRESS: %08lx\n", dsi.v_kernentry); + IPRINTF(" ENTRY ADDRESS: %08lx\n", dsi.v_kernentry); if ( (v_end - dsi.v_start) > ((unsigned long long)nr_pages << PAGE_SHIFT) ) { @@ -223,7 +223,7 @@ static int setup_guest(int xc_handle, goto error_out; } - if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL ) + if ( (page_array = malloc(nr_pages * sizeof(xen_pfn_t))) == NULL ) { PERROR("Could not allocate memory.\n"); goto error_out; diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_ia64_stubs.c --- a/tools/libxc/xc_ia64_stubs.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/libxc/xc_ia64_stubs.c Tue Jun 13 12:12:24 2006 -0600 @@ -57,7 +57,7 @@ xc_plan9_build(int xc_handle, int xc_ia64_get_pfn_list(int xc_handle, uint32_t domid, - unsigned long *pfn_buf, + xen_pfn_t *pfn_buf, unsigned int start_page, unsigned int nr_pages) { @@ -65,7 +65,7 @@ int xc_ia64_get_pfn_list(int xc_handle, int num_pfns,ret; unsigned int __start_page, __nr_pages; unsigned long max_pfns; - unsigned long *__pfn_buf; + xen_pfn_t *__pfn_buf; __start_page = start_page; __nr_pages = nr_pages; @@ -80,7 +80,7 @@ int xc_ia64_get_pfn_list(int xc_handle, set_xen_guest_handle(op.u.getmemlist.buffer, __pfn_buf); if ( (max_pfns != -1UL) - && mlock(__pfn_buf, __nr_pages * sizeof(unsigned long)) != 0 ) + && mlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t)) != 0 ) { PERROR("Could not lock pfn list buffer"); return -1; @@ -89,7 +89,7 @@ int xc_ia64_get_pfn_list(int xc_handle, ret = do_dom0_op(xc_handle, &op); if (max_pfns != -1UL) - (void)munlock(__pfn_buf, __nr_pages * sizeof(unsigned long)); + (void)munlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t)); if (max_pfns == -1UL) return 0; @@ -122,10 +122,10 @@ int xc_ia64_copy_to_domain_pages(int xc_ { // N.B. gva should be page aligned - unsigned long *page_array = NULL; + xen_pfn_t *page_array = NULL; int i; - if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL ){ + if ( (page_array = malloc(nr_pages * sizeof(xen_pfn_t))) == NULL ){ PERROR("Could not allocate memory"); goto error_out; } @@ -669,7 +669,7 @@ static int setup_guest( int xc_handle, vp_eport = xc_evtchn_alloc_unbound(xc_handle, dom, 0); if (vp_eport < 0) { - fprintf(stderr, "Couldn't get unbound port from VMX guest.\n"); + DPRINTF("Couldn't get unbound port from VMX guest.\n"); goto error_out; } sp->vcpu_iodata[i].vp_eport = vp_eport; diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_linux.c --- a/tools/libxc/xc_linux.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/libxc/xc_linux.c Tue Jun 13 12:12:24 2006 -0600 @@ -28,7 +28,7 @@ int xc_interface_close(int xc_handle) } void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot, - unsigned long *arr, int num) + xen_pfn_t *arr, int num) { privcmd_mmapbatch_t ioctlx; void *addr; diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_linux_build.c --- a/tools/libxc/xc_linux_build.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/libxc/xc_linux_build.c Tue Jun 13 12:12:24 2006 -0600 @@ -10,6 +10,7 @@ #include "xc_aout9.h" #include <stdlib.h> #include <unistd.h> +#include <inttypes.h> #include <zlib.h> #if defined(__i386__) @@ -136,7 +137,7 @@ int load_initrd(int xc_handle, domid_t d int load_initrd(int xc_handle, domid_t dom, struct initrd_info *initrd, unsigned long physbase, - unsigned long *phys_to_mach) + xen_pfn_t *phys_to_mach) { char page[PAGE_SIZE]; unsigned long pfn_start, pfn, nr_pages; @@ -189,7 +190,7 @@ static int setup_pg_tables(int xc_handle vcpu_guest_context_t *ctxt, unsigned long dsi_v_start, unsigned long v_end, - unsigned long *page_array, + xen_pfn_t *page_array, unsigned long vpt_start, unsigned long vpt_end, unsigned shadow_mode_enabled) @@ -205,9 +206,9 @@ static int setup_pg_tables(int xc_handle alloc_pt(l2tab, vl2tab, pl2tab); vl2e = &vl2tab[l2_table_offset(dsi_v_start)]; if (shadow_mode_enabled) - ctxt->ctrlreg[3] = pl2tab; + ctxt->ctrlreg[3] = xen_pfn_to_cr3(pl2tab >> PAGE_SHIFT); else - ctxt->ctrlreg[3] = l2tab; + ctxt->ctrlreg[3] = xen_pfn_to_cr3(l2tab >> PAGE_SHIFT); for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++ ) { @@ -251,26 +252,42 @@ static int setup_pg_tables_pae(int xc_ha vcpu_guest_context_t *ctxt, unsigned long dsi_v_start, unsigned long v_end, - unsigned long *page_array, + xen_pfn_t *page_array, unsigned long vpt_start, unsigned long vpt_end, - unsigned shadow_mode_enabled) + unsigned shadow_mode_enabled, + unsigned pae_mode) { l1_pgentry_64_t *vl1tab = NULL, *vl1e = NULL; l2_pgentry_64_t *vl2tab = NULL, *vl2e = NULL; l3_pgentry_64_t *vl3tab = NULL, *vl3e = NULL; uint64_t l1tab, l2tab, l3tab, pl1tab, pl2tab, pl3tab; - unsigned long ppt_alloc, count; + unsigned long ppt_alloc, count, nmfn; /* First allocate page for page dir. */ ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT; + + if ( pae_mode == PAEKERN_extended_cr3 ) + { + ctxt->vm_assist |= (1UL << VMASST_TYPE_pae_extended_cr3); + } + else if ( page_array[ppt_alloc] > 0xfffff ) + { + nmfn = xc_make_page_below_4G(xc_handle, dom, page_array[ppt_alloc]); + if ( nmfn == 0 ) + { + DPRINTF("Couldn't get a page below 4GB :-(\n"); + goto error_out; + } + page_array[ppt_alloc] = nmfn; + } alloc_pt(l3tab, vl3tab, pl3tab); vl3e = &vl3tab[l3_table_offset_pae(dsi_v_start)]; if (shadow_mode_enabled) - ctxt->ctrlreg[3] = pl3tab; + ctxt->ctrlreg[3] = xen_pfn_to_cr3(pl3tab >> PAGE_SHIFT); else - ctxt->ctrlreg[3] = l3tab; + ctxt->ctrlreg[3] = xen_pfn_to_cr3(l3tab >> PAGE_SHIFT); for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++) { @@ -340,7 +357,7 @@ static int setup_pg_tables_64(int xc_han vcpu_guest_context_t *ctxt, unsigned long dsi_v_start, unsigned long v_end, - unsigned long *page_array, + xen_pfn_t *page_array, unsigned long vpt_start, unsigned long vpt_end, int shadow_mode_enabled) @@ -361,9 +378,9 @@ static int setup_pg_tables_64(int xc_han alloc_pt(l4tab, vl4tab, pl4tab); vl4e = &vl4tab[l4_table_offset(dsi_v_start)]; if (shadow_mode_enabled) - ctxt->ctrlreg[3] = pl4tab; + ctxt->ctrlreg[3] = xen_pfn_to_cr3(pl4tab >> PAGE_SHIFT); else - ctxt->ctrlreg[3] = l4tab; + ctxt->ctrlreg[3] = xen_pfn_to_cr3(l4tab >> PAGE_SHIFT); for ( count = 0; count < ((v_end-dsi_v_start)>>PAGE_SHIFT); count++) { @@ -451,7 +468,7 @@ static int setup_guest(int xc_handle, unsigned int console_evtchn, unsigned long *console_mfn, uint32_t required_features[XENFEAT_NR_SUBMAPS]) { - unsigned long *page_array = NULL; + xen_pfn_t *page_array = NULL; struct load_funcs load_funcs; struct domain_setup_info dsi; unsigned long vinitrd_start; @@ -478,7 +495,7 @@ static int setup_guest(int xc_handle, start_page = dsi.v_start >> PAGE_SHIFT; pgnr = (v_end - dsi.v_start) >> PAGE_SHIFT; - if ( (page_array = malloc(pgnr * sizeof(unsigned long))) == NULL ) + if ( (page_array = malloc(pgnr * sizeof(xen_pfn_t))) == NULL ) { PERROR("Could not allocate memory"); goto error_out; @@ -493,14 +510,14 @@ static int setup_guest(int xc_handle, #define _p(a) ((void *) (a)) - printf("VIRTUAL MEMORY ARRANGEMENT:\n" + IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n" " Loaded kernel: %p->%p\n" " Init. ramdisk: %p->%p\n" " TOTAL: %p->%p\n", _p(dsi.v_kernstart), _p(dsi.v_kernend), _p(vinitrd_start), _p(vinitrd_end), _p(dsi.v_start), _p(v_end)); - printf(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry)); + IPRINTF(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry)); (load_funcs.loadimage)(image, image_size, xc_handle, dom, page_array, &dsi); @@ -524,7 +541,7 @@ static int setup_guest(int xc_handle, *store_mfn = page_array[1]; *console_mfn = page_array[2]; - printf("start_info: 0x%lx at 0x%lx, " + IPRINTF("start_info: 0x%lx at 0x%lx, " "store_mfn: 0x%lx at 0x%lx, " "console_mfn: 0x%lx at 0x%lx\n", page_array[0], nr_pages, @@ -579,11 +596,11 @@ static int compat_check(int xc_handle, s } if (strstr(xen_caps, "xen-3.0-x86_32p")) { - if (!dsi->pae_kernel) { + if (dsi->pae_kernel == PAEKERN_no) { ERROR("Non PAE-kernel on PAE host."); return 0; } - } else if (dsi->pae_kernel) { + } else if (dsi->pae_kernel != PAEKERN_no) { ERROR("PAE-kernel on non-PAE host."); return 0; } @@ -591,6 +608,16 @@ static int compat_check(int xc_handle, s return 1; } +static inline int increment_ulong(unsigned long *pval, unsigned long inc) +{ + if ( inc >= -*pval ) + { + ERROR("Value wrapped to zero: image too large?"); + return 0; + } + *pval += inc; + return 1; +} static int setup_guest(int xc_handle, uint32_t dom, @@ -606,7 +633,7 @@ static int setup_guest(int xc_handle, unsigned int console_evtchn, unsigned long *console_mfn, uint32_t required_features[XENFEAT_NR_SUBMAPS]) { - unsigned long *page_array = NULL; + xen_pfn_t *page_array = NULL; unsigned long count, i, hypercall_pfn; start_info_t *start_info; shared_info_t *shared_info; @@ -617,7 +644,7 @@ static int setup_guest(int xc_handle, unsigned long nr_pt_pages; unsigned long physmap_pfn; - unsigned long *physmap, *physmap_e; + xen_pfn_t *physmap, *physmap_e; struct load_funcs load_funcs; struct domain_setup_info dsi; @@ -667,13 +694,14 @@ static int setup_guest(int xc_handle, goto error_out; } - printf("Supported features = { %08x }.\n", supported_features[0]); - printf("Required features = { %08x }.\n", required_features[0]); + IPRINTF("Supported features = { %08x }.\n", supported_features[0]); + IPRINTF("Required features = { %08x }.\n", required_features[0]); } for ( i = 0; i < XENFEAT_NR_SUBMAPS; i++ ) { - if ( (supported_features[i]&required_features[i]) != required_features[i] ) + if ( (supported_features[i] & required_features[i]) != + required_features[i] ) { ERROR("Guest kernel does not support a required feature."); goto error_out; @@ -691,35 +719,64 @@ static int setup_guest(int xc_handle, * which we solve by exhaustive search. */ v_end = round_pgup(dsi.v_end); + if ( v_end == 0 ) + { + ERROR("End of mapped kernel image too close to end of memory"); + goto error_out; + } vinitrd_start = v_end; - v_end += round_pgup(initrd->len); + if ( !increment_ulong(&v_end, round_pgup(initrd->len)) ) + goto error_out; vphysmap_start = v_end; - v_end += round_pgup(nr_pages * sizeof(unsigned long)); + if ( !increment_ulong(&v_end, round_pgup(nr_pages * sizeof(long))) ) + goto error_out; vstartinfo_start = v_end; - v_end += PAGE_SIZE; + if ( !increment_ulong(&v_end, PAGE_SIZE) ) + goto error_out; vstoreinfo_start = v_end; - v_end += PAGE_SIZE; + if ( !increment_ulong(&v_end, PAGE_SIZE) ) + goto error_out; vconsole_start = v_end; - v_end += PAGE_SIZE; + if ( !increment_ulong(&v_end, PAGE_SIZE) ) + goto error_out; if ( shadow_mode_enabled ) { vsharedinfo_start = v_end; - v_end += PAGE_SIZE; + if ( !increment_ulong(&v_end, PAGE_SIZE) ) + goto error_out; } vpt_start = v_end; for ( nr_pt_pages = 2; ; nr_pt_pages++ ) { - vpt_end = vpt_start + (nr_pt_pages * PAGE_SIZE); - vstack_start = vpt_end; - vstack_end = vstack_start + PAGE_SIZE; - v_end = (vstack_end + (1UL<<22)-1) & ~((1UL<<22)-1); + /* vpt_end = vpt_staret + (nr_pt_pages * PAGE_SIZE); */ + vpt_end = vpt_start; + if ( !increment_ulong(&vpt_end, nr_pt_pages * PAGE_SIZE) ) + goto error_out; + + vstack_start = vpt_end; + /* vstack_end = vstack_start + PAGE_SIZE; */ + vstack_end = vstack_start; + if ( !increment_ulong(&vstack_end, PAGE_SIZE) ) + goto error_out; + + /* v_end = (vstack_end + (1UL<<22)-1) & ~((1UL<<22)-1); */ + v_end = vstack_end; + if ( !increment_ulong(&v_end, (1UL<<22)-1) ) + goto error_out; + v_end &= ~((1UL<<22)-1); + if ( (v_end - vstack_end) < (512UL << 10) ) - v_end += 1UL << 22; /* Add extra 4MB to get >= 512kB padding. */ + { + /* Add extra 4MB to get >= 512kB padding. */ + if ( !increment_ulong(&v_end, 1UL << 22) ) + goto error_out; + } + #define NR(_l,_h,_s) \ (((((_h) + ((1UL<<(_s))-1)) & ~((1UL<<(_s))-1)) - \ ((_l) & ~((1UL<<(_s))-1))) >> (_s)) #if defined(__i386__) - if ( dsi.pae_kernel ) + if ( dsi.pae_kernel != PAEKERN_no ) { if ( (1 + /* # L3 */ NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT_PAE) + /* # L2 */ @@ -748,22 +805,22 @@ static int setup_guest(int xc_handle, #define _p(a) ((void *) (a)) - printf("VIRTUAL MEMORY ARRANGEMENT:\n"); - printf(" Loaded kernel: %p->%p\n", _p(dsi.v_kernstart), + IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"); + IPRINTF(" Loaded kernel: %p->%p\n", _p(dsi.v_kernstart), _p(dsi.v_kernend)); if ( initrd->len ) - printf(" Initial ramdisk: %p->%p\n", _p(vinitrd_start), + IPRINTF(" Initial ramdisk: %p->%p\n", _p(vinitrd_start), _p(vinitrd_start + initrd->len)); - printf(" Phys-Mach map: %p\n", _p(vphysmap_start)); - printf(" Start info: %p\n", _p(vstartinfo_start)); - printf(" Store page: %p\n", _p(vstoreinfo_start)); - printf(" Console page: %p\n", _p(vconsole_start)); + IPRINTF(" Phys-Mach map: %p\n", _p(vphysmap_start)); + IPRINTF(" Start info: %p\n", _p(vstartinfo_start)); + IPRINTF(" Store page: %p\n", _p(vstoreinfo_start)); + IPRINTF(" Console page: %p\n", _p(vconsole_start)); if ( shadow_mode_enabled ) - printf(" Shared Info page: %p\n", _p(vsharedinfo_start)); - printf(" Page tables: %p\n", _p(vpt_start)); - printf(" Boot stack: %p\n", _p(vstack_start)); - printf(" TOTAL: %p->%p\n", _p(dsi.v_start), _p(v_end)); - printf(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry)); + IPRINTF(" Shared Info page: %p\n", _p(vsharedinfo_start)); + IPRINTF(" Page tables: %p\n", _p(vpt_start)); + IPRINTF(" Boot stack: %p\n", _p(vstack_start)); + IPRINTF(" TOTAL: %p->%p\n", _p(dsi.v_start), _p(v_end)); + IPRINTF(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry)); if ( ((v_end - dsi.v_start)>>PAGE_SHIFT) > nr_pages ) { @@ -797,11 +854,11 @@ static int setup_guest(int xc_handle, /* setup page tables */ #if defined(__i386__) - if (dsi.pae_kernel) + if (dsi.pae_kernel != PAEKERN_no) rc = setup_pg_tables_pae(xc_handle, dom, ctxt, dsi.v_start, v_end, page_array, vpt_start, vpt_end, - shadow_mode_enabled); + shadow_mode_enabled, dsi.pae_kernel); else rc = setup_pg_tables(xc_handle, dom, ctxt, dsi.v_start, v_end, @@ -824,16 +881,16 @@ static int setup_guest(int xc_handle, */ if ( !shadow_mode_enabled ) { - if ( dsi.pae_kernel ) + if ( dsi.pae_kernel != PAEKERN_no ) { if ( pin_table(xc_handle, MMUEXT_PIN_L3_TABLE, - ctxt->ctrlreg[3] >> PAGE_SHIFT, dom) ) + xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) ) goto error_out; } else { if ( pin_table(xc_handle, MMUEXT_PIN_L2_TABLE, - ctxt->ctrlreg[3] >> PAGE_SHIFT, dom) ) + xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) ) goto error_out; } } @@ -845,7 +902,7 @@ static int setup_guest(int xc_handle, * correct protection for the page */ if ( pin_table(xc_handle, MMUEXT_PIN_L4_TABLE, - ctxt->ctrlreg[3] >> PAGE_SHIFT, dom) ) + xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) ) goto error_out; #endif @@ -865,8 +922,8 @@ static int setup_guest(int xc_handle, ((uint64_t)page_array[count] << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, count) ) { - fprintf(stderr,"m2p update failure p=%lx m=%lx\n", - count, page_array[count]); + DPRINTF("m2p update failure p=%lx m=%"PRIx64"\n", + count, (uint64_t)page_array[count]); munmap(physmap, PAGE_SIZE); goto error_out; } @@ -958,7 +1015,7 @@ static int setup_guest(int xc_handle, rc = xc_version(xc_handle, XENVER_version, NULL); sprintf(start_info->magic, "xen-%i.%i-x86_%d%s", rc >> 16, rc & (0xFFFF), (unsigned int)sizeof(long)*8, - dsi.pae_kernel ? "p" : ""); + (dsi.pae_kernel != PAEKERN_no) ? "p" : ""); start_info->nr_pages = nr_pages; start_info->shared_info = guest_shared_info_mfn << PAGE_SHIFT; start_info->flags = flags; diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_linux_restore.c --- a/tools/libxc/xc_linux_restore.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/libxc/xc_linux_restore.c Tue Jun 13 12:12:24 2006 -0600 @@ -25,10 +25,10 @@ static unsigned long max_pfn; static unsigned long max_pfn; /* Live mapping of the table mapping each PFN to its current MFN. */ -static unsigned long *live_p2m = NULL; +static xen_pfn_t *live_p2m = NULL; /* A table mapping each PFN to its new MFN. */ -static unsigned long *p2m = NULL; +static xen_pfn_t *p2m = NULL; static ssize_t @@ -108,7 +108,7 @@ int xc_linux_restore(int xc_handle, int unsigned int console_evtchn, unsigned long *console_mfn) { DECLARE_DOM0_OP; - int rc = 1, i, n; + int rc = 1, i, n, pae_extended_cr3 = 0; unsigned long mfn, pfn; unsigned int prev_pc, this_pc; int verify = 0; @@ -126,7 +126,7 @@ int xc_linux_restore(int xc_handle, int unsigned long *pfn_type = NULL; /* A table of MFNs to map in the current region */ - unsigned long *region_mfn = NULL; + xen_pfn_t *region_mfn = NULL; /* Types of the pfns in the current region */ unsigned long region_pfn_type[MAX_BATCH_SIZE]; @@ -135,7 +135,7 @@ int xc_linux_restore(int xc_handle, int unsigned long *page = NULL; /* A copy of the pfn-to-mfn table frame list. */ - unsigned long *p2m_frame_list = NULL; + xen_pfn_t *p2m_frame_list = NULL; /* A temporary mapping of the guest's start_info page. */ start_info_t *start_info; @@ -162,30 +162,88 @@ int xc_linux_restore(int xc_handle, int return 1; } - if (mlock(&ctxt, sizeof(ctxt))) { /* needed for build dom0 op, but might as well do early */ ERR("Unable to mlock ctxt"); return 1; } - - /* Read the saved P2M frame list */ - if(!(p2m_frame_list = malloc(P2M_FL_SIZE))) { + if (!(p2m_frame_list = malloc(P2M_FL_SIZE))) { ERR("Couldn't allocate p2m_frame_list array"); goto out; } - if (!read_exact(io_fd, p2m_frame_list, P2M_FL_SIZE)) { + /* Read first entry of P2M list, or extended-info signature (~0UL). */ + if (!read_exact(io_fd, p2m_frame_list, sizeof(long))) { + ERR("read extended-info signature failed"); + goto out; + } + + if (p2m_frame_list[0] == ~0UL) { + uint32_t tot_bytes; + + /* Next 4 bytes: total size of following extended info. */ + if (!read_exact(io_fd, &tot_bytes, sizeof(tot_bytes))) { + ERR("read extended-info size failed"); + goto out; + } + + while (tot_bytes) { + uint32_t chunk_bytes; + char chunk_sig[4]; + + /* 4-character chunk signature + 4-byte remaining chunk size. */ + if (!read_exact(io_fd, chunk_sig, sizeof(chunk_sig)) || + !read_exact(io_fd, &chunk_bytes, sizeof(chunk_bytes))) { + ERR("read extended-info chunk signature failed"); + goto out; + } + tot_bytes -= 8; + + /* VCPU context structure? */ + if (!strncmp(chunk_sig, "vcpu", 4)) { + if (!read_exact(io_fd, &ctxt, sizeof(ctxt))) { + ERR("read extended-info vcpu context failed"); + goto out; + } + tot_bytes -= sizeof(struct vcpu_guest_context); + chunk_bytes -= sizeof(struct vcpu_guest_context); + + if (ctxt.vm_assist & (1UL << VMASST_TYPE_pae_extended_cr3)) + pae_extended_cr3 = 1; + } + + /* Any remaining bytes of this chunk: read and discard. */ + while (chunk_bytes) { + unsigned long sz = chunk_bytes; + if ( sz > P2M_FL_SIZE ) + sz = P2M_FL_SIZE; + if (!read_exact(io_fd, p2m_frame_list, sz)) { + ERR("read-and-discard extended-info chunk bytes failed"); + goto out; + } + chunk_bytes -= sz; + tot_bytes -= sz; + } + } + + /* Now read the real first entry of P2M list. */ + if (!read_exact(io_fd, p2m_frame_list, sizeof(long))) { + ERR("read first entry of p2m_frame_list failed"); + goto out; + } + } + + /* First entry is already read into the p2m array. */ + if (!read_exact(io_fd, &p2m_frame_list[1], P2M_FL_SIZE - sizeof(long))) { ERR("read p2m_frame_list failed"); goto out; } - /* We want zeroed memory so use calloc rather than malloc. */ - p2m = calloc(max_pfn, sizeof(unsigned long)); + p2m = calloc(max_pfn, sizeof(xen_pfn_t)); pfn_type = calloc(max_pfn, sizeof(unsigned long)); - region_mfn = calloc(MAX_BATCH_SIZE, sizeof(unsigned long)); + region_mfn = calloc(MAX_BATCH_SIZE, sizeof(xen_pfn_t)); if ((p2m == NULL) || (pfn_type == NULL) || (region_mfn == NULL)) { ERR("memory alloc failed"); @@ -193,7 +251,7 @@ int xc_linux_restore(int xc_handle, int goto out; } - if (mlock(region_mfn, sizeof(unsigned long) * MAX_BATCH_SIZE)) { + if (mlock(region_mfn, sizeof(xen_pfn_t) * MAX_BATCH_SIZE)) { ERR("Could not mlock region_mfn"); goto out; } @@ -262,7 +320,7 @@ int xc_linux_restore(int xc_handle, int if (j == -1) { verify = 1; - fprintf(stderr, "Entering page verify mode\n"); + DPRINTF("Entering page verify mode\n"); continue; } @@ -331,17 +389,27 @@ int xc_linux_restore(int xc_handle, int ** A page table page - need to 'uncanonicalize' it, i.e. ** replace all the references to pfns with the corresponding ** mfns for the new domain. + ** + ** On PAE we need to ensure that PGDs are in MFNs < 4G, and + ** so we may need to update the p2m after the main loop. + ** Hence we defer canonicalization of L1s until then. */ - if(!uncanonicalize_pagetable(pagetype, page)) { - /* - ** Failing to uncanonicalize a page table can be ok - ** under live migration since the pages type may have - ** changed by now (and we'll get an update later). - */ - DPRINTF("PT L%ld race on pfn=%08lx mfn=%08lx\n", - pagetype >> 28, pfn, mfn); - nraces++; - continue; + if ((pt_levels != 3) || + pae_extended_cr3 || + (pagetype != L1TAB)) { + + if (!uncanonicalize_pagetable(pagetype, page)) { + /* + ** Failing to uncanonicalize a page table can be ok + ** under live migration since the pages type may have + ** changed by now (and we'll get an update later). + */ + DPRINTF("PT L%ld race on pfn=%08lx mfn=%08lx\n", + pagetype >> 28, pfn, mfn); + nraces++; + continue; + } + } } else if(pagetype != NOTAB) { @@ -389,6 +457,100 @@ int xc_linux_restore(int xc_handle, int } DPRINTF("Received all pages (%d races)\n", nraces); + + if ((pt_levels == 3) && !pae_extended_cr3) { + + /* + ** XXX SMH on PAE we need to ensure PGDs are in MFNs < 4G. This + ** is a little awkward and involves (a) finding all such PGDs and + ** replacing them with 'lowmem' versions; (b) upating the p2m[] + ** with the new info; and (c) canonicalizing all the L1s using the + ** (potentially updated) p2m[]. + ** + ** This is relatively slow (and currently involves two passes through + ** the pfn_type[] array), but at least seems to be correct. May wish + ** to consider more complex approaches to optimize this later. + */ + + int j, k; + + /* First pass: find all L3TABs current in > 4G mfns and get new mfns */ + for (i = 0; i < max_pfn; i++) { + + if (((pfn_type[i] & LTABTYPE_MASK)==L3TAB) && (p2m[i]>0xfffffUL)) { + + unsigned long new_mfn; + uint64_t l3ptes[4]; + uint64_t *l3tab; + + l3tab = (uint64_t *) + xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, + PROT_READ, p2m[i]); + + for(j = 0; j < 4; j++) + l3ptes[j] = l3tab[j]; + + munmap(l3tab, PAGE_SIZE); + + if (!(new_mfn=xc_make_page_below_4G(xc_handle, dom, p2m[i]))) { + ERR("Couldn't get a page below 4GB :-("); + goto out; + } + + p2m[i] = new_mfn; + if (xc_add_mmu_update(xc_handle, mmu, + (((unsigned long long)new_mfn) + << PAGE_SHIFT) | + MMU_MACHPHYS_UPDATE, i)) { + ERR("Couldn't m2p on PAE root pgdir"); + goto out; + } + + l3tab = (uint64_t *) + xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, + PROT_READ | PROT_WRITE, p2m[i]); + + for(j = 0; j < 4; j++) + l3tab[j] = l3ptes[j]; + + munmap(l3tab, PAGE_SIZE); + + } + } + + /* Second pass: find all L1TABs and uncanonicalize them */ + j = 0; + + for(i = 0; i < max_pfn; i++) { + + if (((pfn_type[i] & LTABTYPE_MASK)==L1TAB)) { + region_mfn[j] = p2m[i]; + j++; + } + + if(i == (max_pfn-1) || j == MAX_BATCH_SIZE) { + + if (!(region_base = xc_map_foreign_batch( + xc_handle, dom, PROT_READ | PROT_WRITE, + region_mfn, j))) { + ERR("map batch failed"); + goto out; + } + + for(k = 0; k < j; k++) { + if(!uncanonicalize_pagetable(L1TAB, + region_base + k*PAGE_SIZE)) { + ERR("failed uncanonicalize pt!"); + goto out; + } + } + + munmap(region_base, j*PAGE_SIZE); + j = 0; + } + } + + } if (xc_finish_mmu_updates(xc_handle, mmu)) { @@ -536,7 +698,7 @@ int xc_linux_restore(int xc_handle, int } /* Uncanonicalise the page table base pointer. */ - pfn = ctxt.ctrlreg[3] >> PAGE_SHIFT; + pfn = xen_cr3_to_pfn(ctxt.ctrlreg[3]); if (pfn >= max_pfn) { ERR("PT base is bad: pfn=%lu max_pfn=%lu type=%08lx", @@ -552,7 +714,7 @@ int xc_linux_restore(int xc_handle, int goto out; } - ctxt.ctrlreg[3] = p2m[pfn] << PAGE_SHIFT; + ctxt.ctrlreg[3] = xen_pfn_to_cr3(p2m[pfn]); /* clear any pending events and the selector */ memset(&(shared_info->evtchn_pending[0]), 0, diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_linux_save.c --- a/tools/libxc/xc_linux_save.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/libxc/xc_linux_save.c Tue Jun 13 12:12:24 2006 -0600 @@ -40,10 +40,10 @@ static unsigned long max_pfn; static unsigned long max_pfn; /* Live mapping of the table mapping each PFN to its current MFN. */ -static unsigned long *live_p2m = NULL; +static xen_pfn_t *live_p2m = NULL; /* Live mapping of system MFN to PFN table. */ -static unsigned long *live_m2p = NULL; +static xen_pfn_t *live_m2p = NULL; /* grep fodder: machine_to_phys */ @@ -288,7 +288,7 @@ static int print_stats(int xc_handle, ui d1_cpu_now = xc_domain_get_cpu_usage(xc_handle, domid, /* FIXME */ 0)/1000; if ( (d0_cpu_now == -1) || (d1_cpu_now == -1) ) - fprintf(stderr, "ARRHHH!!\n"); + DPRINTF("ARRHHH!!\n"); wall_delta = tv_delta(&wall_now,&wall_last)/1000; @@ -298,7 +298,7 @@ static int print_stats(int xc_handle, ui d1_cpu_delta = (d1_cpu_now - d1_cpu_last)/1000; if (print) - fprintf(stderr, + DPRINTF( "delta %lldms, dom0 %d%%, target %d%%, sent %dMb/s, " "dirtied %dMb/s %" PRId32 " pages\n", wall_delta, @@ -339,14 +339,14 @@ static int analysis_phase(int xc_handle, xc_shadow_control(xc_handle, domid, DOM0_SHADOW_CONTROL_OP_CLEAN, arr, max_pfn, NULL); - fprintf(stderr, "#Flush\n"); + DPRINTF("#Flush\n"); for ( i = 0; i < 40; i++ ) { usleep(50000); now = llgettimeofday(); xc_shadow_control(xc_handle, domid, DOM0_SHADOW_CONTROL_OP_PEEK, NULL, 0, &stats); - fprintf(stderr, "now= %lld faults= %" PRId32 " dirty= %" PRId32 + DPRINTF("now= %lld faults= %" PRId32 " dirty= %" PRId32 " dirty_net= %" PRId32 " dirty_block= %" PRId32"\n", ((now-start)+500)/1000, stats.fault_count, stats.dirty_count, @@ -501,22 +501,22 @@ void canonicalize_pagetable(unsigned lon -static unsigned long *xc_map_m2p(int xc_handle, +static xen_pfn_t *xc_map_m2p(int xc_handle, unsigned long max_mfn, int prot) { struct xen_machphys_mfn_list xmml; privcmd_mmap_entry_t *entries; unsigned long m2p_chunks, m2p_size; - unsigned long *m2p; - unsigned long *extent_start; + xen_pfn_t *m2p; + xen_pfn_t *extent_start; int i, rc; m2p_size = M2P_SIZE(max_mfn); m2p_chunks = M2P_CHUNKS(max_mfn); xmml.max_extents = m2p_chunks; - if (!(extent_start = malloc(m2p_chunks * sizeof(unsigned long)))) { + if (!(extent_start = malloc(m2p_chunks * sizeof(xen_pfn_t)))) { ERR("failed to allocate space for m2p mfns"); return NULL; } @@ -583,11 +583,11 @@ int xc_linux_save(int xc_handle, int io_ char page[PAGE_SIZE]; /* Double and single indirect references to the live P2M table */ - unsigned long *live_p2m_frame_list_list = NULL; - unsigned long *live_p2m_frame_list = NULL; + xen_pfn_t *live_p2m_frame_list_list = NULL; + xen_pfn_t *live_p2m_frame_list = NULL; /* A copy of the pfn-to-mfn table frame list. */ - unsigned long *p2m_frame_list = NULL; + xen_pfn_t *p2m_frame_list = NULL; /* Live mapping of shared info structure */ shared_info_t *live_shinfo = NULL; @@ -712,11 +712,11 @@ int xc_linux_save(int xc_handle, int io_ memcpy(p2m_frame_list, live_p2m_frame_list, P2M_FL_SIZE); /* Canonicalise the pfn-to-mfn table frame-number list. */ - for (i = 0; i < max_pfn; i += ulpp) { - if (!translate_mfn_to_pfn(&p2m_frame_list[i/ulpp])) { + for (i = 0; i < max_pfn; i += fpp) { + if (!translate_mfn_to_pfn(&p2m_frame_list[i/fpp])) { ERR("Frame# in pfn-to-mfn frame list is not in pseudophys"); - ERR("entry %d: p2m_frame_list[%ld] is 0x%lx", i, i/ulpp, - p2m_frame_list[i/ulpp]); + ERR("entry %d: p2m_frame_list[%ld] is 0x%"PRIx64, i, i/fpp, + (uint64_t)p2m_frame_list[i/fpp]); goto out; } } @@ -818,12 +818,33 @@ int xc_linux_save(int xc_handle, int io_ /* Start writing out the saved-domain record. */ - if(!write_exact(io_fd, &max_pfn, sizeof(unsigned long))) { + if (!write_exact(io_fd, &max_pfn, sizeof(unsigned long))) { ERR("write: max_pfn"); goto out; } - if(!write_exact(io_fd, p2m_frame_list, P2M_FL_SIZE)) { + /* + * Write an extended-info structure to inform the restore code that + * a PAE guest understands extended CR3 (PDPTs above 4GB). Turns off + * slow paths in the restore code. + */ + if ((pt_levels == 3) && + (ctxt.vm_assist & (1UL << VMASST_TYPE_pae_extended_cr3))) { + unsigned long signature = ~0UL; + uint32_t tot_sz = sizeof(struct vcpu_guest_context) + 8; + uint32_t chunk_sz = sizeof(struct vcpu_guest_context); + char chunk_sig[] = "vcpu"; + if (!write_exact(io_fd, &signature, sizeof(signature)) || + !write_exact(io_fd, &tot_sz, sizeof(tot_sz)) || + !write_exact(io_fd, &chunk_sig, 4) || + !write_exact(io_fd, &chunk_sz, sizeof(chunk_sz)) || + !write_exact(io_fd, &ctxt, sizeof(ctxt))) { + ERR("write: extended info"); + goto out; + } + } + + if (!write_exact(io_fd, p2m_frame_list, P2M_FL_SIZE)) { ERR("write: p2m_frame_list"); goto out; } @@ -940,7 +961,7 @@ int xc_linux_save(int xc_handle, int io_ } if (debug) - fprintf(stderr, "%d pfn= %08lx mfn= %08lx [mfn]= %08lx" + DPRINTF("%d pfn= %08lx mfn= %08lx [mfn]= %08lx" " sum= %08lx\n", iter, (pfn_type[j] & LTAB_MASK) | pfn_batch[j], @@ -1021,7 +1042,7 @@ int xc_linux_save(int xc_handle, int io_ int minusone = -1; memset(to_send, 0xff, BITMAP_SIZE); debug = 0; - fprintf(stderr, "Entering debug resend-all mode\n"); + DPRINTF("Entering debug resend-all mode\n"); /* send "-1" to put receiver into debug mode */ if(!write_exact(io_fd, &minusone, sizeof(int))) { @@ -1129,12 +1150,12 @@ int xc_linux_save(int xc_handle, int io_ } /* Canonicalise the page table base pointer. */ - if ( !MFN_IS_IN_PSEUDOPHYS_MAP(ctxt.ctrlreg[3] >> PAGE_SHIFT) ) { + if ( !MFN_IS_IN_PSEUDOPHYS_MAP(xen_cr3_to_pfn(ctxt.ctrlreg[3])) ) { ERR("PT base is not in range of pseudophys map"); goto out; } - ctxt.ctrlreg[3] = mfn_to_pfn(ctxt.ctrlreg[3] >> PAGE_SHIFT) << - PAGE_SHIFT; + ctxt.ctrlreg[3] = + xen_pfn_to_cr3(mfn_to_pfn(xen_cr3_to_pfn(ctxt.ctrlreg[3]))); if (!write_exact(io_fd, &ctxt, sizeof(ctxt)) || !write_exact(io_fd, live_shinfo, PAGE_SIZE)) { diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_load_aout9.c --- a/tools/libxc/xc_load_aout9.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/libxc/xc_load_aout9.c Tue Jun 13 12:12:24 2006 -0600 @@ -17,7 +17,7 @@ #define KOFFSET(_p) ((_p)&~KZERO) static int parseaout9image(const char *, unsigned long, struct domain_setup_info *); -static int loadaout9image(const char *, unsigned long, int, uint32_t, unsigned long *, struct domain_setup_info *); +static int loadaout9image(const char *, unsigned long, int, uint32_t, xen_pfn_t *, struct domain_setup_info *); static void copyout(int, uint32_t, unsigned long *, unsigned long, const char *, int); struct Exec *get_header(const char *, unsigned long, struct Exec *); @@ -79,7 +79,7 @@ loadaout9image( const char *image, unsigned long image_size, int xch, uint32_t dom, - unsigned long *parray, + xen_pfn_t *parray, struct domain_setup_info *dsi) { struct Exec ehdr; diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_load_bin.c --- a/tools/libxc/xc_load_bin.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/libxc/xc_load_bin.c Tue Jun 13 12:12:24 2006 -0600 @@ -107,7 +107,7 @@ static int static int loadbinimage( const char *image, unsigned long image_size, int xch, uint32_t dom, - unsigned long *parray, struct domain_setup_info *dsi); + xen_pfn_t *parray, struct domain_setup_info *dsi); int probe_bin(const char *image, unsigned long image_size, @@ -235,7 +235,7 @@ static int static int loadbinimage( const char *image, unsigned long image_size, int xch, uint32_t dom, - unsigned long *parray, struct domain_setup_info *dsi) + xen_pfn_t *parray, struct domain_setup_info *dsi) { unsigned long size; char *va; diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_load_elf.c --- a/tools/libxc/xc_load_elf.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/libxc/xc_load_elf.c Tue Jun 13 12:12:24 2006 -0600 @@ -16,10 +16,10 @@ static int static int loadelfimage( const char *image, unsigned long image_size, int xch, uint32_t dom, - unsigned long *parray, struct domain_setup_info *dsi); + xen_pfn_t *parray, struct domain_setup_info *dsi); static int loadelfsymtab( - const char *image, int xch, uint32_t dom, unsigned long *parray, + const char *image, int xch, uint32_t dom, xen_pfn_t *parray, struct domain_setup_info *dsi); int probe_elf(const char *image, @@ -122,8 +122,15 @@ static int parseelfimage(const char *ima ERROR("Actually saw: '%s'", guestinfo); return -EINVAL; } - if ( (strstr(guestinfo, "PAE=yes") != NULL) ) - dsi->pae_kernel = 1; + + dsi->pae_kernel = PAEKERN_no; + p = strstr(guestinfo, "PAE=yes"); + if ( p != NULL ) + { + dsi->pae_kernel = PAEKERN_yes; + if ( !strncmp(p+7, "[extended-cr3]", 14) ) + dsi->pae_kernel = PAEKERN_extended_cr3; + } break; } @@ -204,7 +211,7 @@ static int static int loadelfimage( const char *image, unsigned long elfsize, int xch, uint32_t dom, - unsigned long *parray, struct domain_setup_info *dsi) + xen_pfn_t *parray, struct domain_setup_info *dsi) { Elf_Ehdr *ehdr = (Elf_Ehdr *)image; Elf_Phdr *phdr; @@ -258,7 +265,7 @@ loadelfimage( static int loadelfsymtab( - const char *image, int xch, uint32_t dom, unsigned long *parray, + const char *image, int xch, uint32_t dom, xen_pfn_t *parray, struct domain_setup_info *dsi) { Elf_Ehdr *ehdr = (Elf_Ehdr *)image, *sym_ehdr; diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_pagetab.c --- a/tools/libxc/xc_pagetab.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/libxc/xc_pagetab.c Tue Jun 13 12:12:24 2006 -0600 @@ -75,10 +75,10 @@ unsigned long xc_translate_foreign_addre #endif if (xc_vcpu_getcontext(xc_handle, dom, vcpu, &ctx) != 0) { - fprintf(stderr, "failed to retreive vcpu context\n"); + DPRINTF("failed to retreive vcpu context\n"); goto out; } - cr3 = ctx.ctrlreg[3]; + cr3 = ((unsigned long long)xen_cr3_to_pfn(ctx.ctrlreg[3])) << PAGE_SHIFT; /* Page Map Level 4 */ @@ -87,12 +87,12 @@ unsigned long xc_translate_foreign_addre #elif defined(__x86_64__) pml = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ, cr3 >> PAGE_SHIFT); if (pml == NULL) { - fprintf(stderr, "failed to map PML4\n"); + DPRINTF("failed to map PML4\n"); goto out; } pmle = *(unsigned long long *)(pml + 8 * ((virt >> L4_PAGETABLE_SHIFT_PAE) & L4_PAGETABLE_MASK_PAE)); if((pmle & 1) == 0) { - fprintf(stderr, "page entry not present in PML4\n"); + DPRINTF("page entry not present in PML4\n"); goto out_unmap_pml; } #endif @@ -102,7 +102,7 @@ unsigned long xc_translate_foreign_addre if (pt_levels >= 3) { pdppage = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ, pmle >> PAGE_SHIFT); if (pdppage == NULL) { - fprintf(stderr, "failed to map PDP\n"); + DPRINTF("failed to map PDP\n"); goto out_unmap_pml; } if (pt_levels >= 4) @@ -114,7 +114,7 @@ unsigned long xc_translate_foreign_addre pdpe = *(unsigned long long *)(pdp + 8 * ((virt >> L3_PAGETABLE_SHIFT_PAE) & L3_PAGETABLE_MASK_PAE)); if((pdpe & 1) == 0) { - fprintf(stderr, "page entry not present in PDP\n"); + DPRINTF("page entry not present in PDP\n"); goto out_unmap_pdp; } } else { @@ -125,7 +125,7 @@ unsigned long xc_translate_foreign_addre pd = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ, pdpe >> PAGE_SHIFT); if (pd == NULL) { - fprintf(stderr, "failed to map PD\n"); + DPRINTF("failed to map PD\n"); goto out_unmap_pdp; } @@ -135,21 +135,21 @@ unsigned long xc_translate_foreign_addre pde = *(unsigned long long *)(pd + 4 * ((virt >> L2_PAGETABLE_SHIFT) & L2_PAGETABLE_MASK)); if ((pde & 1) == 0) { - fprintf(stderr, "page entry not present in PD\n"); + DPRINTF("page entry not present in PD\n"); goto out_unmap_pd; } /* Page Table */ if (pde & 0x00000008) { /* 4M page (or 2M in PAE mode) */ - fprintf(stderr, "Cannot currently cope with 2/4M pages\n"); + DPRINTF("Cannot currently cope with 2/4M pages\n"); exit(-1); } else { /* 4k page */ pt = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ, pde >> PAGE_SHIFT); if (pt == NULL) { - fprintf(stderr, "failed to map PT\n"); + DPRINTF("failed to map PT\n"); goto out_unmap_pd; } @@ -159,7 +159,7 @@ unsigned long xc_translate_foreign_addre pte = *(unsigned long long *)(pt + 4 * ((virt >> L1_PAGETABLE_SHIFT) & L1_PAGETABLE_MASK)); if ((pte & 0x00000001) == 0) { - fprintf(stderr, "page entry not present in PT\n"); + DPRINTF("page entry not present in PT\n"); goto out_unmap_pt; } diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_private.c --- a/tools/libxc/xc_private.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/libxc/xc_private.c Tue Jun 13 12:12:24 2006 -0600 @@ -4,6 +4,7 @@ * Helper functions for the rest of the library. */ +#include <inttypes.h> #include "xc_private.h" /* NB: arr must be mlock'ed */ @@ -134,9 +135,9 @@ int xc_memory_op(int xc_handle, struct xen_memory_reservation *reservation = arg; struct xen_machphys_mfn_list *xmml = arg; struct xen_translate_gpfn_list *trans = arg; - unsigned long *extent_start; - unsigned long *gpfn_list; - unsigned long *mfn_list; + xen_pfn_t *extent_start; + xen_pfn_t *gpfn_list; + xen_pfn_t *mfn_list; long ret = -EINVAL; hypercall.op = __HYPERVISOR_memory_op; @@ -156,7 +157,7 @@ int xc_memory_op(int xc_handle, get_xen_guest_handle(extent_start, reservation->extent_start); if ( (extent_start != NULL) && (mlock(extent_start, - reservation->nr_extents * sizeof(unsigned long)) != 0) ) + reservation->nr_extents * sizeof(xen_pfn_t)) != 0) ) { PERROR("Could not mlock"); safe_munlock(reservation, sizeof(*reservation)); @@ -171,7 +172,7 @@ int xc_memory_op(int xc_handle, } get_xen_guest_handle(extent_start, xmml->extent_start); if ( mlock(extent_start, - xmml->max_extents * sizeof(unsigned long)) != 0 ) + xmml->max_extents * sizeof(xen_pfn_t)) != 0 ) { PERROR("Could not mlock"); safe_munlock(xmml, sizeof(*xmml)); @@ -192,17 +193,17 @@ int xc_memory_op(int xc_handle, goto out1; } get_xen_guest_handle(gpfn_list, trans->gpfn_list); - if ( mlock(gpfn_list, trans->nr_gpfns * sizeof(long)) != 0 ) + if ( mlock(gpfn_list, trans->nr_gpfns * sizeof(xen_pfn_t)) != 0 ) { PERROR("Could not mlock"); safe_munlock(trans, sizeof(*trans)); goto out1; } get_xen_guest_handle(mfn_list, trans->mfn_list); - if ( mlock(mfn_list, trans->nr_gpfns * sizeof(long)) != 0 ) - { - PERROR("Could not mlock"); - safe_munlock(gpfn_list, trans->nr_gpfns * sizeof(long)); + if ( mlock(mfn_list, trans->nr_gpfns * sizeof(xen_pfn_t)) != 0 ) + { + PERROR("Could not mlock"); + safe_munlock(gpfn_list, trans->nr_gpfns * sizeof(xen_pfn_t)); safe_munlock(trans, sizeof(*trans)); goto out1; } @@ -220,22 +221,22 @@ int xc_memory_op(int xc_handle, get_xen_guest_handle(extent_start, reservation->extent_start); if ( extent_start != NULL ) safe_munlock(extent_start, - reservation->nr_extents * sizeof(unsigned long)); + reservation->nr_extents * sizeof(xen_pfn_t)); break; case XENMEM_machphys_mfn_list: safe_munlock(xmml, sizeof(*xmml)); get_xen_guest_handle(extent_start, xmml->extent_start); safe_munlock(extent_start, - xmml->max_extents * sizeof(unsigned long)); + xmml->max_extents * sizeof(xen_pfn_t)); break; case XENMEM_add_to_physmap: safe_munlock(arg, sizeof(struct xen_add_to_physmap)); break; case XENMEM_translate_gpfn_list: get_xen_guest_handle(mfn_list, trans->mfn_list); - safe_munlock(mfn_list, trans->nr_gpfns * sizeof(long)); + safe_munlock(mfn_list, trans->nr_gpfns * sizeof(xen_pfn_t)); get_xen_guest_handle(gpfn_list, trans->gpfn_list); - safe_munlock(gpfn_list, trans->nr_gpfns * sizeof(long)); + safe_munlock(gpfn_list, trans->nr_gpfns * sizeof(xen_pfn_t)); safe_munlock(trans, sizeof(*trans)); break; } @@ -263,7 +264,7 @@ long long xc_domain_get_cpu_usage( int x int xc_get_pfn_list(int xc_handle, uint32_t domid, - unsigned long *pfn_buf, + xen_pfn_t *pfn_buf, unsigned long max_pfns) { DECLARE_DOM0_OP; @@ -274,10 +275,10 @@ int xc_get_pfn_list(int xc_handle, set_xen_guest_handle(op.u.getmemlist.buffer, pfn_buf); #ifdef VALGRIND - memset(pfn_buf, 0, max_pfns * sizeof(unsigned long)); + memset(pfn_buf, 0, max_pfns * sizeof(xen_pfn_t)); #endif - if ( mlock(pfn_buf, max_pfns * sizeof(unsigned long)) != 0 ) + if ( mlock(pfn_buf, max_pfns * sizeof(xen_pfn_t)) != 0 ) { PERROR("xc_get_pfn_list: pfn_buf mlock failed"); return -1; @@ -285,7 +286,7 @@ int xc_get_pfn_list(int xc_handle, ret = do_dom0_op(xc_handle, &op); - safe_munlock(pfn_buf, max_pfns * sizeof(unsigned long)); + safe_munlock(pfn_buf, max_pfns * sizeof(xen_pfn_t)); #if 0 #ifdef DEBUG @@ -293,10 +294,10 @@ int xc_get_pfn_list(int xc_handle, if (ret >= 0) { int i, j; for (i = 0; i < op.u.getmemlist.num_pfns; i += 16) { - fprintf(stderr, "0x%x: ", i); + DPRINTF("0x%x: ", i); for (j = 0; j < 16; j++) - fprintf(stderr, "0x%lx ", pfn_buf[i + j]); - fprintf(stderr, "\n"); + DPRINTF("0x%lx ", pfn_buf[i + j]); + DPRINTF("\n"); } } #endif @@ -364,7 +365,7 @@ unsigned long xc_get_filesz(int fd) } void xc_map_memcpy(unsigned long dst, const char *src, unsigned long size, - int xch, uint32_t dom, unsigned long *parray, + int xch, uint32_t dom, xen_pfn_t *parray, unsigned long vstart) { char *va; @@ -428,6 +429,29 @@ int xc_version(int xc_handle, int cmd, v safe_munlock(arg, argsize); return rc; +} + +unsigned long xc_make_page_below_4G( + int xc_handle, uint32_t domid, unsigned long mfn) +{ + xen_pfn_t old_mfn = mfn; + xen_pfn_t new_mfn; + + if ( xc_domain_memory_decrease_reservation( + xc_handle, domid, 1, 0, &old_mfn) != 0 ) + { + DPRINTF("xc_make_page_below_4G decrease failed. mfn=%lx\n",mfn); + return 0; + } + + if ( xc_domain_memory_increase_reservation( + xc_handle, domid, 1, 0, 32, &new_mfn) != 0 ) + { + DPRINTF("xc_make_page_below_4G increase failed. mfn=%lx\n",mfn); + return 0; + } + + return new_mfn; } /* diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_private.h --- a/tools/libxc/xc_private.h Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/libxc/xc_private.h Tue Jun 13 12:12:24 2006 -0600 @@ -28,25 +28,50 @@ #define DECLARE_DOM0_OP dom0_op_t op #endif - #define PAGE_SHIFT XC_PAGE_SHIFT #define PAGE_SIZE (1UL << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) -#define ERROR(_m, _a...) \ +#define DEBUG 1 +#define INFO 1 +#define PROGRESS 0 + +#if INFO +#define IPRINTF(_f, _a...) printf(_f , ## _a) +#else +#define IPRINTF(_f, _a...) ((void)0) +#endif + +#if DEBUG +#define DPRINTF(_f, _a...) fprintf(stderr, _f , ## _a) +#else +#define DPRINTF(_f, _a...) ((void)0) +#endif + +#if PROGRESS +#define PPRINTF(_f, _a...) fprintf(stderr, _f , ## _a) +#else +#define PPRINTF(_f, _a...) +#endif + +#define ERR(_f, _a...) do { \ + DPRINTF(_f ": %d\n" , ## _a, errno); \ + fflush(stderr); } \ +while (0) + +#define ERROR(_m, _a...) \ +do { \ + int __saved_errno = errno; \ + DPRINTF("ERROR: " _m "\n" , ## _a ); \ + errno = __saved_errno; \ +} while (0) + +#define PERROR(_m, _a...) \ do { \ int __saved_errno = errno; \ - fprintf(stderr, "ERROR: " _m "\n" , ## _a ); \ + DPRINTF("ERROR: " _m " (%d = %s)\n" , ## _a , \ + __saved_errno, strerror(__saved_errno)); \ errno = __saved_errno; \ -} while (0) - - -#define PERROR(_m, _a...) \ -do { \ - int __saved_errno = errno; \ - fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a , \ - __saved_errno, strerror(__saved_errno)); \ - errno = __saved_errno; \ } while (0) static inline void safe_munlock(const void *addr, size_t len) @@ -88,7 +113,7 @@ static inline int do_dom0_op(int xc_hand if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 ) { if ( errno == EACCES ) - fprintf(stderr, "Dom0 operation failed -- need to" + DPRINTF("Dom0 operation failed -- need to" " rebuild the user-space tool set?\n"); } diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_ptrace.c --- a/tools/libxc/xc_ptrace.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/libxc/xc_ptrace.c Tue Jun 13 12:12:24 2006 -0600 @@ -143,7 +143,7 @@ online_vcpus_changed(cpumap_t cpumap) { if (handlers.td_create) handlers.td_create(index - 1); } else { - printf("thread death: %d\n", index - 1); + IPRINTF("thread death: %d\n", index - 1); if (handlers.td_death) handlers.td_death(index - 1); } changed_cpumap &= ~(1 << (index - 1)); @@ -190,7 +190,8 @@ map_domain_va_32( static void *v[MAX_VIRT_CPUS]; l2 = xc_map_foreign_range( - xc_handle, current_domid, PAGE_SIZE, PROT_READ, ctxt[cpu].ctrlreg[3] >> PAGE_SHIFT); + xc_handle, current_domid, PAGE_SIZE, PROT_READ, + xen_cr3_to_pfn(ctxt[cpu].ctrlreg[3])); if ( l2 == NULL ) return NULL; @@ -230,7 +231,8 @@ map_domain_va_pae( static void *v[MAX_VIRT_CPUS]; l3 = xc_map_foreign_range( - xc_handle, current_domid, PAGE_SIZE, PROT_READ, ctxt[cpu].ctrlreg[3] >> PAGE_SHIFT); + xc_handle, current_domid, PAGE_SIZE, PROT_READ, + xen_cr3_to_pfn(ctxt[cpu].ctrlreg[3])); if ( l3 == NULL ) return NULL; @@ -282,8 +284,9 @@ map_domain_va_64( if ((ctxt[cpu].ctrlreg[4] & 0x20) == 0 ) /* legacy ia32 mode */ return map_domain_va_32(xc_handle, cpu, guest_va, perm); - l4 = xc_map_foreign_range( xc_handle, current_domid, PAGE_SIZE, - PROT_READ, ctxt[cpu].ctrlreg[3] >> PAGE_SHIFT); + l4 = xc_map_foreign_range( + xc_handle, current_domid, PAGE_SIZE, PROT_READ, + xen_cr3_to_pfn(ctxt[cpu].ctrlreg[3])); if ( l4 == NULL ) return NULL; @@ -365,13 +368,13 @@ map_domain_va( nr_pages = npgs; if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL ) { - printf("Could not allocate memory\n"); + IPRINTF("Could not allocate memory\n"); return NULL; } if ( xc_get_pfn_list(xc_handle, current_domid, page_array, nr_pages) != nr_pages ) { - printf("Could not get the page frame list\n"); + IPRINTF("Could not get the page frame list\n"); return NULL; } } @@ -430,7 +433,7 @@ __xc_waitdomain( retval = do_dom0_op(xc_handle, &op); if ( retval || (op.u.getdomaininfo.domain != domain) ) { - printf("getdomaininfo failed\n"); + IPRINTF("getdomaininfo failed\n"); goto done; } *status = op.u.getdomaininfo.flags; @@ -451,7 +454,7 @@ __xc_waitdomain( } done: if (get_online_cpumap(xc_handle, &op.u.getdomaininfo, &cpumap)) - printf("get_online_cpumap failed\n"); + IPRINTF("get_online_cpumap failed\n"); if (online_cpumap != cpumap) online_vcpus_changed(cpumap); return retval; @@ -592,7 +595,7 @@ xc_ptrace( if ( retval || (op.u.getdomaininfo.domain != current_domid) ) goto out_error_dom0; if ( op.u.getdomaininfo.flags & DOMFLAGS_PAUSED ) - printf("domain currently paused\n"); + IPRINTF("domain currently paused\n"); else if ((retval = xc_domain_pause(xc_handle, current_domid))) goto out_error_dom0; op.cmd = DOM0_SETDEBUGGING; @@ -602,7 +605,7 @@ xc_ptrace( goto out_error_dom0; if (get_online_cpumap(xc_handle, &op.u.getdomaininfo, &cpumap)) - printf("get_online_cpumap failed\n"); + IPRINTF("get_online_cpumap failed\n"); if (online_cpumap != cpumap) online_vcpus_changed(cpumap); break; @@ -616,7 +619,7 @@ xc_ptrace( goto out_unsupported; /* XXX not yet supported */ case PTRACE_TRACEME: - printf("PTRACE_TRACEME is an invalid request under Xen\n"); + IPRINTF("PTRACE_TRACEME is an invalid request under Xen\n"); goto out_error; } @@ -630,7 +633,7 @@ xc_ptrace( out_unsupported: #ifdef DEBUG - printf("unsupported xc_ptrace request %s\n", ptrace_names[request]); + IPRINTF("unsupported xc_ptrace request %s\n", ptrace_names[request]); #endif errno = ENOSYS; return -1; diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_ptrace.h --- a/tools/libxc/xc_ptrace.h Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/libxc/xc_ptrace.h Tue Jun 13 12:12:24 2006 -0600 @@ -160,7 +160,6 @@ struct gdb_regs { } #endif -#define printval(x) printf("%s = %lx\n", #x, (long)x); #endif typedef void (*thr_ev_handler_t)(long); diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_ptrace_core.c --- a/tools/libxc/xc_ptrace_core.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/libxc/xc_ptrace_core.c Tue Jun 13 12:12:24 2006 -0600 @@ -12,8 +12,8 @@ static long nr_pages = 0; static long nr_pages = 0; static unsigned long *p2m_array = NULL; static unsigned long *m2p_array = NULL; -static unsigned long pages_offset; -static unsigned long cr3[MAX_VIRT_CPUS]; +static unsigned long pages_offset; +static unsigned long cr3[MAX_VIRT_CPUS]; /* --------------------- */ @@ -47,7 +47,7 @@ map_domain_va_core(unsigned long domfd, munmap(cr3_virt[cpu], PAGE_SIZE); v = mmap( NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd, - map_mtop_offset(cr3_phys[cpu])); + map_mtop_offset(xen_cr3_to_pfn(cr3_phys[cpu]))); if (v == MAP_FAILED) { perror("mmap failed"); @@ -85,7 +85,7 @@ map_domain_va_core(unsigned long domfd, map_mtop_offset(page_phys[cpu])); if (v == MAP_FAILED) { - printf("cr3 %lx pde %lx page %lx pti %lx\n", cr3[cpu], pde, page, l1_table_offset_i386(va)); + IPRINTF("cr3 %lx pde %lx page %lx pti %lx\n", cr3[cpu], pde, page, l1_table_offset_i386(va)); page_phys[cpu] = 0; return NULL; } @@ -113,7 +113,7 @@ xc_waitdomain_core( return -1; if (header.xch_magic != XC_CORE_MAGIC) { - printf("Magic number missmatch: 0x%08x (file) != " + IPRINTF("Magic number missmatch: 0x%08x (file) != " " 0x%08x (code)\n", header.xch_magic, XC_CORE_MAGIC); return -1; @@ -127,29 +127,28 @@ xc_waitdomain_core( sizeof(vcpu_guest_context_t)*nr_vcpus) return -1; - for (i = 0; i < nr_vcpus; i++) { + for (i = 0; i < nr_vcpus; i++) cr3[i] = ctxt[i].ctrlreg[3]; - } + if ((p2m_array = malloc(nr_pages * sizeof(unsigned long))) == NULL) { - printf("Could not allocate p2m_array\n"); + IPRINTF("Could not allocate p2m_array\n"); return -1; } + if (read(domfd, p2m_array, sizeof(unsigned long)*nr_pages) != sizeof(unsigned long)*nr_pages) return -1; if ((m2p_array = malloc((1<<20) * sizeof(unsigned long))) == NULL) { - printf("Could not allocate m2p array\n"); + IPRINTF("Could not allocate m2p array\n"); return -1; } bzero(m2p_array, sizeof(unsigned long)* 1 << 20); - for (i = 0; i < nr_pages; i++) { + for (i = 0; i < nr_pages; i++) m2p_array[p2m_array[i]] = i; - } - } return 0; } diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/libxc/xenctrl.h Tue Jun 13 12:12:24 2006 -0600 @@ -415,26 +415,26 @@ int xc_domain_memory_increase_reservatio unsigned long nr_extents, unsigned int extent_order, unsigned int address_bits, - unsigned long *extent_start); + xen_pfn_t *extent_start); int xc_domain_memory_decrease_reservation(int xc_handle, uint32_t domid, unsigned long nr_extents, unsigned int extent_order, - unsigned long *extent_start); + xen_pfn_t *extent_start); int xc_domain_memory_populate_physmap(int xc_handle, uint32_t domid, unsigned long nr_extents, unsigned int extent_order, unsigned int address_bits, - unsigned long *extent_start); + xen_pfn_t *extent_start); int xc_domain_translate_gpfn_list(int xc_handle, uint32_t domid, unsigned long nr_gpfns, - unsigned long *gpfn_list, - unsigned long *mfn_list); + xen_pfn_t *gpfn_list, + xen_pfn_t *mfn_list); int xc_domain_ioport_permission(int xc_handle, uint32_t domid, @@ -453,6 +453,9 @@ int xc_domain_iomem_permission(int xc_ha unsigned long nr_mfns, uint8_t allow_access); +unsigned long xc_make_page_below_4G(int xc_handle, uint32_t domid, + unsigned long mfn); + typedef dom0_perfc_desc_t xc_perfc_desc_t; /* IMPORTANT: The caller is responsible for mlock()'ing the @desc array. */ int xc_perfc_control(int xc_handle, @@ -484,7 +487,7 @@ void *xc_map_foreign_range(int xc_handle unsigned long mfn ); void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot, - unsigned long *arr, int num ); + xen_pfn_t *arr, int num ); /** * Translates a virtual address in the context of a given domain and @@ -499,11 +502,11 @@ unsigned long xc_translate_foreign_addre unsigned long xc_translate_foreign_address(int xc_handle, uint32_t dom, int vcpu, unsigned long long virt); -int xc_get_pfn_list(int xc_handle, uint32_t domid, unsigned long *pfn_buf, +int xc_get_pfn_list(int xc_handle, uint32_t domid, xen_pfn_t *pfn_buf, unsigned long max_pfns); int xc_ia64_get_pfn_list(int xc_handle, uint32_t domid, - unsigned long *pfn_buf, + xen_pfn_t *pfn_buf, unsigned int start_page, unsigned int nr_pages); int xc_copy_to_domain_page(int xc_handle, uint32_t domid, diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xg_private.h --- a/tools/libxc/xg_private.h Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/libxc/xg_private.h Tue Jun 13 12:12:24 2006 -0600 @@ -12,6 +12,7 @@ #include "xenctrl.h" #include "xenguest.h" +#include "xc_private.h" #include <xen/sys/privcmd.h> #include <xen/memory.h> @@ -129,23 +130,6 @@ typedef unsigned long l4_pgentry_t; (((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1)) #endif -#define ERROR(_m, _a...) \ -do { \ - int __saved_errno = errno; \ - fprintf(stderr, "ERROR: " _m "\n" , ## _a ); \ - errno = __saved_errno; \ -} while (0) - - -#define PERROR(_m, _a...) \ -do { \ - int __saved_errno = errno; \ - fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a , \ - __saved_errno, strerror(__saved_errno)); \ - errno = __saved_errno; \ -} while (0) - - struct domain_setup_info { unsigned long v_start; @@ -156,6 +140,9 @@ struct domain_setup_info unsigned long elf_paddr_offset; +#define PAEKERN_no 0 +#define PAEKERN_yes 1 +#define PAEKERN_extended_cr3 2 unsigned int pae_kernel; unsigned int load_symtab; @@ -170,7 +157,7 @@ typedef int (*parseimagefunc)(const char struct domain_setup_info *dsi); typedef int (*loadimagefunc)(const char *image, unsigned long image_size, int xch, - uint32_t dom, unsigned long *parray, + uint32_t dom, xen_pfn_t *parray, struct domain_setup_info *dsi); struct load_funcs @@ -198,7 +185,7 @@ unsigned long xc_get_filesz(int fd); unsigned long xc_get_filesz(int fd); void xc_map_memcpy(unsigned long dst, const char *src, unsigned long size, - int xch, uint32_t dom, unsigned long *parray, + int xch, uint32_t dom, xen_pfn_t *parray, unsigned long vstart); int pin_table(int xc_handle, unsigned int type, unsigned long mfn, diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xg_save_restore.h --- a/tools/libxc/xg_save_restore.h Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/libxc/xg_save_restore.h Tue Jun 13 12:12:24 2006 -0600 @@ -5,28 +5,6 @@ */ #include "xc_private.h" - -#define DEBUG 1 -#define PROGRESS 0 - -#define ERR(_f, _a...) do { \ - fprintf(stderr, _f ": %d\n" , ## _a, errno);\ - fflush(stderr); } \ -while (0) - -#if DEBUG -#define DPRINTF(_f, _a...) fprintf(stderr, _f , ## _a) -#else -#define DPRINTF(_f, _a...) ((void)0) -#endif - - -#if PROGRESS -#define PPRINTF(_f, _a...) fprintf(stderr, _f , ## _a) -#else -#define PPRINTF(_f, _a...) -#endif - /* ** We process save/restore/migrate in batches of pages; the below @@ -105,23 +83,23 @@ static int get_platform_info(int xc_hand */ #define M2P_SHIFT L2_PAGETABLE_SHIFT_PAE #define M2P_CHUNK_SIZE (1 << M2P_SHIFT) -#define M2P_SIZE(_m) ROUNDUP(((_m) * sizeof(unsigned long)), M2P_SHIFT) +#define M2P_SIZE(_m) ROUNDUP(((_m) * sizeof(xen_pfn_t)), M2P_SHIFT) #define M2P_CHUNKS(_m) (M2P_SIZE((_m)) >> M2P_SHIFT) /* Size in bytes of the P2M (rounded up to the nearest PAGE_SIZE bytes) */ -#define P2M_SIZE ROUNDUP((max_pfn * sizeof(unsigned long)), PAGE_SHIFT) +#define P2M_SIZE ROUNDUP((max_pfn * sizeof(xen_pfn_t)), PAGE_SHIFT) -/* Number of unsigned longs in a page */ -#define ulpp (PAGE_SIZE/sizeof(unsigned long)) +/* Number of xen_pfn_t in a page */ +#define fpp (PAGE_SIZE/sizeof(xen_pfn_t)) /* Number of entries in the pfn_to_mfn_frame_list */ -#define P2M_FL_ENTRIES (((max_pfn)+ulpp-1)/ulpp) +#define P2M_FL_ENTRIES (((max_pfn)+fpp-1)/fpp) /* Size in bytes of the pfn_to_mfn_frame_list */ #define P2M_FL_SIZE ((P2M_FL_ENTRIES)*sizeof(unsigned long)) /* Number of entries in the pfn_to_mfn_frame_list_list */ -#define P2M_FLL_ENTRIES (((max_pfn)+(ulpp*ulpp)-1)/(ulpp*ulpp)) +#define P2M_FLL_ENTRIES (((max_pfn)+(fpp*fpp)-1)/(fpp*fpp)) /* Current guests allow 8MB 'slack' in their P2M */ #define NR_SLACK_ENTRIES ((8 * 1024 * 1024) / PAGE_SIZE) diff -r b8f6089cbce3 -r e74c47d073ee tools/python/xen/lowlevel/acm/acm.c --- a/tools/python/xen/lowlevel/acm/acm.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/python/xen/lowlevel/acm/acm.c Tue Jun 13 12:12:24 2006 -0600 @@ -52,9 +52,9 @@ void * __getssid(int domid, uint32_t *bu } memset(buf, 0, SSID_BUFFER_SIZE); getssid.interface_version = ACM_INTERFACE_VERSION; - getssid.ssidbuf = buf; + set_xen_guest_handle(getssid.ssidbuf, buf); getssid.ssidbuf_size = SSID_BUFFER_SIZE; - getssid.get_ssid_by = DOMAINID; + getssid.get_ssid_by = ACM_GETBY_domainid; getssid.id.domainid = domid; if (xc_acm_op(xc_handle, ACMOP_getssid, &getssid, sizeof(getssid)) < 0) { @@ -163,19 +163,19 @@ static PyObject *getdecision(PyObject * return NULL; getdecision.interface_version = ACM_INTERFACE_VERSION; - getdecision.hook = SHARING; + getdecision.hook = ACMHOOK_sharing; if (!strcmp(arg1_name, "domid")) { - getdecision.get_decision_by1 = DOMAINID; + getdecision.get_decision_by1 = ACM_GETBY_domainid; getdecision.id1.domainid = atoi(arg1); } else { - getdecision.get_decision_by1 = SSIDREF; + getdecision.get_decision_by1 = ACM_GETBY_ssidref; getdecision.id1.ssidref = atol(arg1); } if (!strcmp(arg2_name, "domid")) { - getdecision.get_decision_by2 = DOMAINID; + getdecision.get_decision_by2 = ACM_GETBY_domainid; getdecision.id2.domainid = atoi(arg2); } else { - getdecision.get_decision_by2 = SSIDREF; + getdecision.get_decision_by2 = ACM_GETBY_ssidref; getdecision.id2.ssidref = atol(arg2); } diff -r b8f6089cbce3 -r e74c47d073ee tools/python/xen/lowlevel/xs/xs.c --- a/tools/python/xen/lowlevel/xs/xs.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/python/xen/lowlevel/xs/xs.c Tue Jun 13 12:12:24 2006 -0600 @@ -28,6 +28,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> +#include <errno.h> #include <xenctrl.h> #include "xs.h" @@ -43,6 +44,8 @@ #define PKG "xen.lowlevel.xs" #define CLS "xs" + +static PyObject *xs_error; /** Python wrapper round an xs handle. */ @@ -52,11 +55,17 @@ typedef struct XsHandle { PyObject *watches; } XsHandle; +static void xs_set_error(int value) +{ + errno = value; + PyErr_SetFromErrno(xs_error); +} + static inline struct xs_handle *xshandle(XsHandle *self) { struct xs_handle *xh = self->xh; if (!xh) - PyErr_SetString(PyExc_RuntimeError, "invalid xenstore daemon handle"); + xs_set_error(EINVAL); return xh; } @@ -77,7 +86,7 @@ static int parse_transaction_path(XsHand "\n" \ "Returns: [string] data read.\n" \ " None if key doesn't exist.\n" \ - "Raises RuntimeError on error.\n" \ + "Raises xen.lowlevel.xs.Error on error.\n" \ "\n" static PyObject *xspy_read(XsHandle *self, PyObject *args) @@ -113,7 +122,7 @@ static PyObject *xspy_read(XsHandle *sel " data [string] : data to write.\n" \ "\n" \ "Returns None on success.\n" \ - "Raises RuntimeError on error.\n" \ + "Raises xen.lowlevel.xs.Error on error.\n" \ "\n" static PyObject *xspy_write(XsHandle *self, PyObject *args) @@ -149,7 +158,7 @@ static PyObject *xspy_write(XsHandle *se "\n" \ "Returns: [string array] list of subdirectory names.\n" \ " None if key doesn't exist.\n" \ - "Raises RuntimeError on error.\n" \ + "Raises xen.lowlevel.xs.Error on error.\n" \ "\n" static PyObject *xspy_ls(XsHandle *self, PyObject *args) @@ -187,7 +196,7 @@ static PyObject *xspy_ls(XsHandle *self, " path [string]: path to directory to create.\n" \ "\n" \ "Returns None on success.\n" \ - "Raises RuntimeError on error.\n" \ + "Raises xen.lowlevel.xs.Error on error.\n" \ "\n" static PyObject *xspy_mkdir(XsHandle *self, PyObject *args) @@ -215,7 +224,7 @@ static PyObject *xspy_mkdir(XsHandle *se " path [string] : path to remove\n" \ "\n" \ "Returns None on success.\n" \ - "Raises RuntimeError on error.\n" \ + "Raises xen.lowlevel.xs.Error on error.\n" \ "\n" static PyObject *xspy_rm(XsHandle *self, PyObject *args) @@ -243,7 +252,7 @@ static PyObject *xspy_rm(XsHandle *self, " path [string]: xenstore path.\n" \ "\n" \ "Returns: permissions array.\n" \ - "Raises RuntimeError on error.\n" \ + "Raises xen.lowlevel.xs.Error on error.\n" \ "\n" static PyObject *xspy_get_permissions(XsHandle *self, PyObject *args) @@ -285,7 +294,7 @@ static PyObject *xspy_get_permissions(Xs return val; } else { - PyErr_SetFromErrno(PyExc_RuntimeError); + PyErr_SetFromErrno(xs_error); return NULL; } } @@ -297,7 +306,7 @@ static PyObject *xspy_get_permissions(Xs " perms : permissions.\n" \ "\n" \ "Returns None on success.\n" \ - "Raises RuntimeError on error.\n" \ + "Raises xen.lowlevel.xs.Error on error.\n" \ "\n" static PyObject *xspy_set_permissions(XsHandle *self, PyObject *args) @@ -324,13 +333,13 @@ static PyObject *xspy_set_permissions(Xs th = strtoul(thstr, NULL, 16); if (!PyList_Check(perms)) { - PyErr_SetString(PyExc_RuntimeError, "perms must be a list"); + xs_set_error(EINVAL); goto exit; } xsperms_n = PyList_Size(perms); xsperms = calloc(xsperms_n, sizeof(struct xs_permissions)); if (!xsperms) { - PyErr_SetString(PyExc_RuntimeError, "out of memory"); + xs_set_error(ENOMEM); goto exit; } tuple0 = PyTuple_New(0); @@ -352,7 +361,7 @@ static PyObject *xspy_set_permissions(Xs result = xs_set_permissions(xh, th, path, xsperms, xsperms_n); Py_END_ALLOW_THREADS if (!result) { - PyErr_SetFromErrno(PyExc_RuntimeError); + PyErr_SetFromErrno(xs_error); goto exit; } @@ -371,7 +380,7 @@ static PyObject *xspy_set_permissions(Xs " token [string] : returned in watch notification.\n" \ "\n" \ "Returns None on success.\n" \ - "Raises RuntimeError on error.\n" \ + "Raises xen.lowlevel.xs.Error on error.\n" \ "\n" /* Each 10 bits takes ~ 3 digits, plus one, plus one for nul terminator. */ @@ -421,7 +430,7 @@ static PyObject *xspy_watch(XsHandle *se "Read a watch notification.\n" \ "\n" \ "Returns: [tuple] (path, token).\n" \ - "Raises RuntimeError on error.\n" \ + "Raises xen.lowlevel.xs.Error on error.\n" \ "\n" static PyObject *xspy_read_watch(XsHandle *self, PyObject *args) @@ -441,11 +450,11 @@ again: xsval = xs_read_watch(xh, &num); Py_END_ALLOW_THREADS if (!xsval) { - PyErr_SetFromErrno(PyExc_RuntimeError); + PyErr_SetFromErrno(xs_error); goto exit; } if (sscanf(xsval[XS_WATCH_TOKEN], "%li", (unsigned long *)&token) != 1) { - PyErr_SetString(PyExc_RuntimeError, "invalid token"); + xs_set_error(EINVAL); goto exit; } for (i = 0; i < PyList_Size(self->watches); i++) { @@ -474,7 +483,7 @@ again: " token [string] : token from the watch.\n" \ "\n" \ "Returns None on success.\n" \ - "Raises RuntimeError on error.\n" \ + "Raises xen.lowlevel.xs.Error on error.\n" \ "\n" static PyObject *xspy_unwatch(XsHandle *self, PyObject *args) @@ -504,7 +513,7 @@ static PyObject *xspy_unwatch(XsHandle * "Start a transaction.\n" \ "\n" \ "Returns transaction handle on success.\n" \ - "Raises RuntimeError on error.\n" \ + "Raises xen.lowlevel.xs.Error on error.\n" \ "\n" static PyObject *xspy_transaction_start(XsHandle *self) @@ -521,7 +530,7 @@ static PyObject *xspy_transaction_start( Py_END_ALLOW_THREADS if (th == XBT_NULL) { - PyErr_SetFromErrno(PyExc_RuntimeError); + PyErr_SetFromErrno(xs_error); return NULL; } @@ -535,7 +544,7 @@ static PyObject *xspy_transaction_start( " abort [int]: abort flag (default 0).\n" \ "\n" \ "Returns True on success, False if you need to try again.\n" \ - "Raises RuntimeError on error.\n" \ + "Raises xen.lowlevel.xs.Error on error.\n" \ "\n" static PyObject *xspy_transaction_end(XsHandle *self, PyObject *args, @@ -572,7 +581,7 @@ static PyObject *xspy_transaction_end(Xs return Py_False; } else { - PyErr_SetFromErrno(PyExc_RuntimeError); + PyErr_SetFromErrno(xs_error); return NULL; } } @@ -585,7 +594,7 @@ static PyObject *xspy_transaction_end(Xs " port [int] : port the domain is using for xenstore\n" \ "\n" \ "Returns None on success.\n" \ - "Raises RuntimeError on error.\n" \ + "Raises xen.lowlevel.xs.Error on error.\n" \ "\n" static PyObject *xspy_introduce_domain(XsHandle *self, PyObject *args) @@ -616,7 +625,7 @@ static PyObject *xspy_introduce_domain(X " dom [int]: domain id\n" \ "\n" \ "Returns None on success.\n" \ - "Raises RuntimeError on error.\n" \ + "Raises xen.lowlevel.xs.Error on error.\n" \ "\n" static PyObject *xspy_release_domain(XsHandle *self, PyObject *args) @@ -643,7 +652,7 @@ static PyObject *xspy_release_domain(XsH "Close the connection to xenstore.\n" \ "\n" \ "Returns None on success.\n" \ - "Raises RuntimeError on error.\n" \ + "Raises xen.lowlevel.xs.Error on error.\n" \ "\n" static PyObject *xspy_close(XsHandle *self) @@ -672,7 +681,7 @@ static PyObject *xspy_close(XsHandle *se " domid [int]: domain id\n" \ "\n" \ "Returns: [string] domain store path.\n" \ - "Raises RuntimeError on error.\n" \ + "Raises xen.lowlevel.xs.Error on error.\n" \ "\n" static PyObject *xspy_get_domain_path(XsHandle *self, PyObject *args) @@ -754,7 +763,7 @@ static PyObject *none(bool result) return Py_None; } else { - PyErr_SetFromErrno(PyExc_RuntimeError); + PyErr_SetFromErrno(xs_error); return NULL; } } @@ -830,7 +839,7 @@ xshandle_init(XsHandle *self, PyObject * return 0; fail: - PyErr_SetFromErrno(PyExc_RuntimeError); + PyErr_SetFromErrno(xs_error); return -1; } @@ -902,8 +911,13 @@ PyMODINIT_FUNC initxs(void) if (m == NULL) return; + xs_error = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL); + Py_INCREF(&xshandle_type); PyModule_AddObject(m, CLS, (PyObject *)&xshandle_type); + + Py_INCREF(xs_error); + PyModule_AddObject(m, "Error", xs_error); } diff -r b8f6089cbce3 -r e74c47d073ee tools/python/xen/util/security.py --- a/tools/python/xen/util/security.py Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/python/xen/util/security.py Tue Jun 13 12:12:24 2006 -0600 @@ -426,6 +426,15 @@ def get_decision(arg1, arg2): err("Argument type not supported.") ssidref = label2ssidref(arg2[2][1], arg2[1][1]) arg2 = ['ssidref', str(ssidref)] + + # accept only int or string types for domid and ssidref + if isinstance(arg1[1], int): + arg1[1] = str(arg1[1]) + if isinstance(arg2[1], int): + arg2[1] = str(arg2[1]) + if not isinstance(arg1[1], str) or not isinstance(arg2[1], str): + err("Invalid id or ssidref type, string or int required") + try: decision = acm.getdecision(arg1[0], arg1[1], arg2[0], arg2[1]) except: diff -r b8f6089cbce3 -r e74c47d073ee tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/python/xen/xend/image.py Tue Jun 13 12:12:24 2006 -0600 @@ -249,7 +249,8 @@ class HVMImageHandler(ImageHandler): # xm config file def parseDeviceModelArgs(self, imageConfig, deviceConfig): dmargs = [ 'cdrom', 'boot', 'fda', 'fdb', 'ne2000', 'audio', - 'localtime', 'serial', 'stdvga', 'isa', 'vcpus'] + 'localtime', 'serial', 'stdvga', 'isa', 'vcpus', + 'usb', 'usbdevice'] ret = [] for a in dmargs: v = sxp.child_value(imageConfig, a) @@ -260,7 +261,7 @@ class HVMImageHandler(ImageHandler): if a == 'audio': a = 'enable-audio' # Handle booleans gracefully - if a in ['localtime', 'std-vga', 'isa', 'nic-ne2000', 'enable-audio']: + if a in ['localtime', 'std-vga', 'isa', 'nic-ne2000', 'enable-audio', 'usb']: if v != None: v = int(v) if v: ret.append("-%s" % a) else: diff -r b8f6089cbce3 -r e74c47d073ee tools/python/xen/xm/create.py --- a/tools/python/xen/xm/create.py Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/python/xen/xm/create.py Tue Jun 13 12:12:24 2006 -0600 @@ -264,7 +264,7 @@ gopts.var('irq', val='IRQ', For example 'irq=7'. This option may be repeated to add more than one IRQ.""") -gopts.var('usb', val='PATH', +gopts.var('usbport', val='PATH', fn=append_value, default=[], use="""Add a physical USB port to a domain, as specified by the path to that port. This option may be repeated to add more than one port.""") @@ -371,6 +371,14 @@ gopts.var('localtime', val='no|yes', gopts.var('localtime', val='no|yes', fn=set_bool, default=0, use="Is RTC set to localtime?") + +gopts.var('usb', val='no|yes', + fn=set_bool, default=0, + use="Emulate USB devices?") + +gopts.var('usbdevice', val='NAME', + fn=set_value, default='', + use="Name of USB device to add?") gopts.var('stdvga', val='no|yes', fn=set_bool, default=0, @@ -508,8 +516,8 @@ def configure_irq(config_devs, vals): config_devs.append(['device', config_irq]) def configure_usb(config_devs, vals): - for path in vals.usb: - config_usb = ['usb', ['path', path]] + for path in vals.usbport: + config_usb = ['usbport', ['path', path]] config_devs.append(['device', config_usb]) @@ -614,7 +622,7 @@ def configure_hvm(config_image, vals): args = [ 'device_model', 'pae', 'vcpus', 'cdrom', 'boot', 'fda', 'fdb', 'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'audio', 'vnc', 'vncviewer', 'sdl', 'display', 'ne2000', 'acpi', 'apic', - 'xauthority' ] + 'xauthority', 'usb', 'usbdevice' ] for a in args: if (vals.__dict__[a]): config_image.append([a, vals.__dict__[a]]) @@ -903,10 +911,15 @@ def make_domain(opts, config): else: err("%s" % ex.faultString) except Exception, ex: + # main.py has good error messages that let the user know what failed. + # unless the error is a create.py specific thing, it should be handled + # at main. The purpose of this general-case 'Exception' handler is to + # clean up create.py specific processes/data but since create.py does + # not know what to do with the error, it should pass it up. import signal if vncpid: os.kill(vncpid, signal.SIGKILL) - err(str(ex)) + raise ex dom = sxp.child_value(dominfo, 'name') diff -r b8f6089cbce3 -r e74c47d073ee tools/tests/test_x86_emulator.c --- a/tools/tests/test_x86_emulator.c Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/tests/test_x86_emulator.c Tue Jun 13 12:12:24 2006 -0600 @@ -13,6 +13,7 @@ typedef int64_t s64; typedef int64_t s64; #include <public/xen.h> #include <asm-x86/x86_emulate.h> +#include <sys/mman.h> static int read_any( unsigned long addr, @@ -85,23 +86,30 @@ int main(int argc, char **argv) struct x86_emulate_ctxt ctxt; struct cpu_user_regs regs; char instr[20] = { 0x01, 0x08 }; /* add %ecx,(%eax) */ - unsigned int res = 0x7FFFFFFF; - u32 cmpxchg8b_res[2] = { 0x12345678, 0x87654321 }; + unsigned int *res; int rc; ctxt.regs = ®s; ctxt.mode = X86EMUL_MODE_PROT32; + res = mmap((void *)0x100000, 0x1000, PROT_READ|PROT_WRITE, + MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); + if ( res == MAP_FAILED ) + { + fprintf(stderr, "mmap to low address failed\n"); + exit(1); + } + printf("%-40s", "Testing addl %%ecx,(%%eax)..."); instr[0] = 0x01; instr[1] = 0x08; regs.eflags = 0x200; regs.eip = (unsigned long)&instr[0]; regs.ecx = 0x12345678; - ctxt.cr2 = (unsigned long)&res; - res = 0x7FFFFFFF; - rc = x86_emulate_memop(&ctxt, &emulops); - if ( (rc != 0) || - (res != 0x92345677) || + ctxt.cr2 = (unsigned long)res; + *res = 0x7FFFFFFF; + rc = x86_emulate_memop(&ctxt, &emulops); + if ( (rc != 0) || + (*res != 0x92345677) || (regs.eflags != 0xa94) || (regs.eip != (unsigned long)&instr[2]) ) goto fail; @@ -116,11 +124,25 @@ int main(int argc, char **argv) #else regs.ecx = 0x12345678UL; #endif - ctxt.cr2 = (unsigned long)&res; - rc = x86_emulate_memop(&ctxt, &emulops); - if ( (rc != 0) || - (res != 0x92345677) || + ctxt.cr2 = (unsigned long)res; + rc = x86_emulate_memop(&ctxt, &emulops); + if ( (rc != 0) || + (*res != 0x92345677) || (regs.ecx != 0x8000000FUL) || + (regs.eip != (unsigned long)&instr[2]) ) + goto fail; + printf("okay\n"); + + printf("%-40s", "Testing movl (%%eax),%%ecx..."); + instr[0] = 0x8b; instr[1] = 0x08; + regs.eflags = 0x200; + regs.eip = (unsigned long)&instr[0]; + regs.ecx = ~0UL; + ctxt.cr2 = (unsigned long)res; + rc = x86_emulate_memop(&ctxt, &emulops); + if ( (rc != 0) || + (*res != 0x92345677) || + (regs.ecx != 0x92345677UL) || (regs.eip != (unsigned long)&instr[2]) ) goto fail; printf("okay\n"); @@ -131,10 +153,10 @@ int main(int argc, char **argv) regs.eip = (unsigned long)&instr[0]; regs.eax = 0x92345677UL; regs.ecx = 0xAA; - ctxt.cr2 = (unsigned long)&res; - rc = x86_emulate_memop(&ctxt, &emulops); - if ( (rc != 0) || - (res != 0x923456AA) || + ctxt.cr2 = (unsigned long)res; + rc = x86_emulate_memop(&ctxt, &emulops); + if ( (rc != 0) || + (*res != 0x923456AA) || (regs.eflags != 0x244) || (regs.eax != 0x92345677UL) || (regs.eip != (unsigned long)&instr[4]) ) @@ -147,10 +169,10 @@ int main(int argc, char **argv) regs.eip = (unsigned long)&instr[0]; regs.eax = 0xAABBCC77UL; regs.ecx = 0xFF; - ctxt.cr2 = (unsigned long)&res; - rc = x86_emulate_memop(&ctxt, &emulops); - if ( (rc != 0) || - (res != 0x923456AA) || + ctxt.cr2 = (unsigned long)res; + rc = x86_emulate_memop(&ctxt, &emulops); + if ( (rc != 0) || + (*res != 0x923456AA) || ((regs.eflags&0x240) != 0x200) || (regs.eax != 0xAABBCCAA) || (regs.ecx != 0xFF) || @@ -163,10 +185,10 @@ int main(int argc, char **argv) regs.eflags = 0x200; regs.eip = (unsigned long)&instr[0]; regs.ecx = 0x12345678; - ctxt.cr2 = (unsigned long)&res; - rc = x86_emulate_memop(&ctxt, &emulops); - if ( (rc != 0) || - (res != 0x12345678) || + ctxt.cr2 = (unsigned long)res; + rc = x86_emulate_memop(&ctxt, &emulops); + if ( (rc != 0) || + (*res != 0x12345678) || (regs.eflags != 0x200) || (regs.ecx != 0x923456AA) || (regs.eip != (unsigned long)&instr[2]) ) @@ -176,14 +198,14 @@ int main(int argc, char **argv) printf("%-40s", "Testing lock cmpxchgl %%ecx,(%%eax)..."); instr[0] = 0xf0; instr[1] = 0x0f; instr[2] = 0xb1; instr[3] = 0x08; regs.eflags = 0x200; - res = 0x923456AA; + *res = 0x923456AA; regs.eip = (unsigned long)&instr[0]; regs.eax = 0x923456AAUL; regs.ecx = 0xDDEEFF00L; - ctxt.cr2 = (unsigned long)&res; - rc = x86_emulate_memop(&ctxt, &emulops); - if ( (rc != 0) || - (res != 0xDDEEFF00) || + ctxt.cr2 = (unsigned long)res; + rc = x86_emulate_memop(&ctxt, &emulops); + if ( (rc != 0) || + (*res != 0xDDEEFF00) || (regs.eflags != 0x244) || (regs.eax != 0x923456AAUL) || (regs.eip != (unsigned long)&instr[4]) ) @@ -192,54 +214,57 @@ int main(int argc, char **argv) printf("%-40s", "Testing rep movsw..."); instr[0] = 0xf3; instr[1] = 0x66; instr[2] = 0xa5; - res = 0x22334455; + *res = 0x22334455; regs.eflags = 0x200; regs.ecx = 23; regs.eip = (unsigned long)&instr[0]; - regs.esi = (unsigned long)&res + 0; - regs.edi = (unsigned long)&res + 2; + regs.esi = (unsigned long)res + 0; + regs.edi = (unsigned long)res + 2; regs.error_code = 0; /* read fault */ ctxt.cr2 = regs.esi; rc = x86_emulate_memop(&ctxt, &emulops); if ( (rc != 0) || - (res != 0x44554455) || + (*res != 0x44554455) || (regs.eflags != 0x200) || (regs.ecx != 22) || - (regs.esi != ((unsigned long)&res + 2)) || - (regs.edi != ((unsigned long)&res + 4)) || + (regs.esi != ((unsigned long)res + 2)) || + (regs.edi != ((unsigned long)res + 4)) || (regs.eip != (unsigned long)&instr[0]) ) goto fail; printf("okay\n"); printf("%-40s", "Testing btrl $0x1,(%edi)..."); instr[0] = 0x0f; instr[1] = 0xba; instr[2] = 0x37; instr[3] = 0x01; - res = 0x2233445F; - regs.eflags = 0x200; - regs.eip = (unsigned long)&instr[0]; - regs.edi = (unsigned long)&res; + *res = 0x2233445F; + regs.eflags = 0x200; + regs.eip = (unsigned long)&instr[0]; + regs.edi = (unsigned long)res; ctxt.cr2 = regs.edi; rc = x86_emulate_memop(&ctxt, &emulops); if ( (rc != 0) || - (res != 0x2233445D) || + (*res != 0x2233445D) || ((regs.eflags&0x201) != 0x201) || (regs.eip != (unsigned long)&instr[4]) ) goto fail; printf("okay\n"); + + res[0] = 0x12345678; + res[1] = 0x87654321; printf("%-40s", "Testing cmpxchg8b (%edi) [succeeding]..."); instr[0] = 0x0f; instr[1] = 0xc7; instr[2] = 0x0f; regs.eflags = 0x200; - regs.eax = cmpxchg8b_res[0]; - regs.edx = cmpxchg8b_res[1]; + regs.eax = res[0]; + regs.edx = res[1]; regs.ebx = 0x9999AAAA; regs.ecx = 0xCCCCFFFF; regs.eip = (unsigned long)&instr[0]; - regs.edi = (unsigned long)cmpxchg8b_res; + regs.edi = (unsigned long)res; ctxt.cr2 = regs.edi; rc = x86_emulate_memop(&ctxt, &emulops); if ( (rc != 0) || - (cmpxchg8b_res[0] != 0x9999AAAA) || - (cmpxchg8b_res[1] != 0xCCCCFFFF) || + (res[0] != 0x9999AAAA) || + (res[1] != 0xCCCCFFFF) || ((regs.eflags&0x240) != 0x240) || (regs.eip != (unsigned long)&instr[3]) ) goto fail; @@ -248,12 +273,12 @@ int main(int argc, char **argv) printf("%-40s", "Testing cmpxchg8b (%edi) [failing]..."); instr[0] = 0x0f; instr[1] = 0xc7; instr[2] = 0x0f; regs.eip = (unsigned long)&instr[0]; - regs.edi = (unsigned long)cmpxchg8b_res; + regs.edi = (unsigned long)res; ctxt.cr2 = regs.edi; rc = x86_emulate_memop(&ctxt, &emulops); if ( (rc != 0) || - (cmpxchg8b_res[0] != 0x9999AAAA) || - (cmpxchg8b_res[1] != 0xCCCCFFFF) || + (res[0] != 0x9999AAAA) || + (res[1] != 0xCCCCFFFF) || (regs.eax != 0x9999AAAA) || (regs.edx != 0xCCCCFFFF) || ((regs.eflags&0x240) != 0x200) || @@ -265,11 +290,11 @@ int main(int argc, char **argv) instr[0] = 0x0f; instr[1] = 0xbe; instr[2] = 0x08; regs.eip = (unsigned long)&instr[0]; regs.ecx = 0x12345678; - ctxt.cr2 = (unsigned long)&res; - res = 0x82; + ctxt.cr2 = (unsigned long)res; + *res = 0x82; rc = x86_emulate_memop(&ctxt, &emulops); if ( (rc != 0) || - (res != 0x82) || + (*res != 0x82) || (regs.ecx != 0xFFFFFF82) || ((regs.eflags&0x240) != 0x200) || (regs.eip != (unsigned long)&instr[3]) ) @@ -280,11 +305,11 @@ int main(int argc, char **argv) instr[0] = 0x0f; instr[1] = 0xb7; instr[2] = 0x08; regs.eip = (unsigned long)&instr[0]; regs.ecx = 0x12345678; - ctxt.cr2 = (unsigned long)&res; - res = 0x1234aa82; + ctxt.cr2 = (unsigned long)res; + *res = 0x1234aa82; rc = x86_emulate_memop(&ctxt, &emulops); if ( (rc != 0) || - (res != 0x1234aa82) || + (*res != 0x1234aa82) || (regs.ecx != 0xaa82) || ((regs.eflags&0x240) != 0x200) || (regs.eip != (unsigned long)&instr[3]) ) diff -r b8f6089cbce3 -r e74c47d073ee tools/xm-test/configure.ac --- a/tools/xm-test/configure.ac Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/xm-test/configure.ac Tue Jun 13 12:12:24 2006 -0600 @@ -1,7 +1,7 @@ # xm-test configure.ac input script # Basic header information -AC_INIT([xm-test], [0.7.1]) +AC_INIT([xm-test], [0.8.0]) AM_INIT_AUTOMAKE([1.7 foreign]) # Check for dependencies @@ -118,6 +118,7 @@ AC_CONFIG_FILES([ tests/reboot/Makefile tests/restore/Makefile tests/save/Makefile + tests/sched-credit/Makefile tests/sedf/Makefile tests/shutdown/Makefile tests/sysrq/Makefile diff -r b8f6089cbce3 -r e74c47d073ee tools/xm-test/grouptest/default --- a/tools/xm-test/grouptest/default Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/xm-test/grouptest/default Tue Jun 13 12:12:24 2006 -0600 @@ -1,6 +1,7 @@ block-create block-create block-destroy block-list +block-integrity console create destroy diff -r b8f6089cbce3 -r e74c47d073ee tools/xm-test/ramdisk/Makefile.am --- a/tools/xm-test/ramdisk/Makefile.am Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/xm-test/ramdisk/Makefile.am Tue Jun 13 12:12:24 2006 -0600 @@ -2,7 +2,7 @@ INITRD ?= http://xm-test.xensource.com/r EXTRA_DIST = skel configs patches -BR_TAR = buildroot-20060427.tar.bz2 +BR_TAR = buildroot-20060606.tar.bz2 BR_URL = http://buildroot.uclibc.org/downloads/snapshots/$(BR_TAR) #BR_URL = http://buildroot.uclibc.org/downloads/snapshots/buildroot-snapshot.tar.bz2 BR_SRC = buildroot diff -r b8f6089cbce3 -r e74c47d073ee tools/xm-test/ramdisk/configs/busybox --- a/tools/xm-test/ramdisk/configs/busybox Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/xm-test/ramdisk/configs/busybox Tue Jun 13 12:12:24 2006 -0600 @@ -127,8 +127,8 @@ CONFIG_SYNC=y CONFIG_SYNC=y CONFIG_TAIL=y CONFIG_FEATURE_FANCY_TAIL=n -CONFIG_TEE=n -CONFIG_FEATURE_TEE_USE_BLOCK_IO=n +CONFIG_TEE=y +CONFIG_FEATURE_TEE_USE_BLOCK_IO=y CONFIG_TEST=y # diff -r b8f6089cbce3 -r e74c47d073ee tools/xm-test/tests/Makefile.am --- a/tools/xm-test/tests/Makefile.am Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/xm-test/tests/Makefile.am Tue Jun 13 12:12:24 2006 -0600 @@ -18,6 +18,7 @@ SUBDIRS = \ network-attach \ pause \ reboot \ + sched-credit \ sedf \ shutdown \ sysrq \ diff -r b8f6089cbce3 -r e74c47d073ee tools/xm-test/tests/block-integrity/Makefile.am --- a/tools/xm-test/tests/block-integrity/Makefile.am Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/xm-test/tests/block-integrity/Makefile.am Tue Jun 13 12:12:24 2006 -0600 @@ -1,7 +1,8 @@ SUBDIRS = -TESTS = 01_block_device_read_verify.test +TESTS = 01_block_device_read_verify.test \ + 02_block_device_write_verify.test XFAIL_TESTS = diff -r b8f6089cbce3 -r e74c47d073ee tools/xm-test/tests/enforce_dom0_cpus/01_enforce_dom0_cpus_basic_pos.py --- a/tools/xm-test/tests/enforce_dom0_cpus/01_enforce_dom0_cpus_basic_pos.py Tue Jun 13 09:00:32 2006 -0600 +++ b/tools/xm-test/tests/enforce_dom0_cpus/01_enforce_dom0_cpus_basic_pos.py Tue Jun 13 12:12:24 2006 -0600 @@ -28,6 +28,12 @@ check_status = 1 check_status = 1 max_tries = 10 +def reset_vcpu_count(): + status, output = traceCommand("xm vcpu-set 0 %s"%(dom0_online_vcpus)) + if status != 0: + print "WARNING!!! Unable to set vcpus back to %s, please set manually"\ + %(dom0_online_vcpus) + # 1) Make sure we have a multi cpu system and dom0 has at least 2 vcpus online. if smpConcurrencyLevel() <= 1: @@ -57,6 +63,7 @@ if check_status and status != 0: # 4) restart xend with new config os.putenv("XEND_CONFIG", "/tmp/xend-config.sxp") status = restartXend() +os.unsetenv("XEND_CONFIG") if check_status and status != 0: ns, no = restartXend() if ns != 0: @@ -75,7 +82,7 @@ while timeout + starttime > time.time(): cmd = "grep \"^processor\" /proc/cpuinfo | wc -l" status, output = traceCommand(cmd) if check_status and status != 0: - os.unsetenv("XEND_CONFIG") + reset_vcpu_count() restartXend() FAIL("\"%s\" returned invalid %i != 0" %(cmd,status)) # Has it succeeded? If so, we can leave the loop @@ -84,7 +91,7 @@ while timeout + starttime > time.time(): # Sleep for 1 second before trying again time.sleep(1) if output != str(enforce_dom0_cpus): - os.unsetenv("XEND_CONFIG") + reset_vcpu_count() restartXend() FAIL("/proc/cpuinfo says xend didn't enforce dom0_cpus (%s != %s)"%(output, enforce_dom0_cpus)) @@ -92,17 +99,13 @@ if output != str(enforce_dom0_cpus): # 6) count number of online cpus and see that it matches enforce value num_online = int(getDomInfo("Domain-0", "VCPUs")) if num_online != enforce_dom0_cpus: - os.unsetenv("XEND_CONFIG") + reset_vcpu_count() restartXend() FAIL("xm says xend didn't enforce dom0_cpus (%s != %s)" %(num_online, enforce_dom0_cpus)) # 7) restore dead processors -status, output = traceCommand("xm vcpu-set 0 %s"%(dom0_online_vcpus)) -if check_status and status != 0: - os.unsetenv("XEND_CONFIG") - restartXend() - FAIL("\"%s\" returned invalid %i != 0" %(cmd,status)) +reset_vcpu_count() # check restore worked # Since this also takes time, we will do it in a loop with a 20 second timeout. @@ -114,12 +117,10 @@ while timeout + starttime > time.time(): break time.sleep(1) if num_online != dom0_online_vcpus: - os.unsetenv("XEND_CONFIG") restartXend() FAIL("failed to restore dom0's VCPUs") # 8) Restart xend with default config -os.unsetenv("XEND_CONFIG") restartXend() diff -r b8f6089cbce3 -r e74c47d073ee xen/acm/acm_core.c --- a/xen/acm/acm_core.c Tue Jun 13 09:00:32 2006 -0600 +++ b/xen/acm/acm_core.c Tue Jun 13 12:12:24 2006 -0600 @@ -316,7 +316,7 @@ acm_init_domain_ssid(domid_t id, ssidref return ACM_INIT_SSID_ERROR; } - ssid->datatype = DOMAIN; + ssid->datatype = ACM_DATATYPE_domain; ssid->subject = subj; ssid->domainid = subj->domain_id; ssid->primary_ssid = NULL; diff -r b8f6089cbce3 -r e74c47d073ee xen/acm/acm_policy.c --- a/xen/acm/acm_policy.c Tue Jun 13 09:00:32 2006 -0600 +++ b/xen/acm/acm_policy.c Tue Jun 13 12:12:24 2006 -0600 @@ -32,7 +32,7 @@ #include <acm/acm_endian.h> int -acm_set_policy(void *buf, u32 buf_size, int isuserbuffer) +acm_set_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size, int isuserbuffer) { u8 *policy_buffer = NULL; struct acm_policy_buffer *pol; @@ -45,7 +45,7 @@ acm_set_policy(void *buf, u32 buf_size, return -ENOMEM; if (isuserbuffer) { - if (copy_from_user(policy_buffer, buf, buf_size)) + if (copy_from_guest(policy_buffer, buf, buf_size)) { printk("%s: Error copying!\n",__func__); goto error_free; @@ -116,7 +116,7 @@ acm_set_policy(void *buf, u32 buf_size, } int -acm_get_policy(void *buf, u32 buf_size) +acm_get_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size) { u8 *policy_buffer; int ret; @@ -162,7 +162,7 @@ acm_get_policy(void *buf, u32 buf_size) goto error_free_unlock; bin_pol->len = htonl(ntohl(bin_pol->len) + ret); - if (copy_to_user(buf, policy_buffer, ntohl(bin_pol->len))) + if (copy_to_guest(buf, policy_buffer, ntohl(bin_pol->len))) goto error_free_unlock; read_unlock(&acm_bin_pol_rwlock); @@ -177,7 +177,7 @@ acm_get_policy(void *buf, u32 buf_size) } int -acm_dump_statistics(void *buf, u16 buf_size) +acm_dump_statistics(XEN_GUEST_HANDLE(void) buf, u16 buf_size) { /* send stats to user space */ u8 *stats_buffer; @@ -208,7 +208,7 @@ acm_dump_statistics(void *buf, u16 buf_s memcpy(stats_buffer, &acm_stats, sizeof(struct acm_stats_buffer)); - if (copy_to_user(buf, stats_buffer, sizeof(struct acm_stats_buffer) + len1 + len2)) + if (copy_to_guest(buf, stats_buffer, sizeof(struct acm_stats_buffer) + len1 + len2)) goto error_lock_free; read_unlock(&acm_bin_pol_rwlock); @@ -223,7 +223,7 @@ acm_dump_statistics(void *buf, u16 buf_s int -acm_get_ssid(ssidref_t ssidref, u8 *buf, u16 buf_size) +acm_get_ssid(ssidref_t ssidref, XEN_GUEST_HANDLE(void) buf, u16 buf_size) { /* send stats to user space */ u8 *ssid_buffer; @@ -272,7 +272,7 @@ acm_get_ssid(ssidref_t ssidref, u8 *buf, acm_ssid->len += ret; acm_ssid->secondary_max_types = ret; - if (copy_to_user(buf, ssid_buffer, acm_ssid->len)) + if (copy_to_guest(buf, ssid_buffer, acm_ssid->len)) goto error_free_unlock; read_unlock(&acm_bin_pol_rwlock); @@ -287,14 +287,13 @@ acm_get_ssid(ssidref_t ssidref, u8 *buf, } int -acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2, - enum acm_hook_type hook) +acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2, u32 hook) { int ret = ACM_ACCESS_DENIED; switch (hook) { - case SHARING: - /* SHARING Hook restricts access in STE policy only */ + case ACMHOOK_sharing: + /* Sharing hook restricts access in STE policy only */ ret = acm_sharing(ssidref1, ssidref2); break; diff -r b8f6089cbce3 -r e74c47d073ee xen/acm/acm_simple_type_enforcement_hooks.c --- a/xen/acm/acm_simple_type_enforcement_hooks.c Tue Jun 13 09:00:32 2006 -0600 +++ b/xen/acm/acm_simple_type_enforcement_hooks.c Tue Jun 13 12:12:24 2006 -0600 @@ -117,7 +117,7 @@ ste_init_domain_ssid(void **ste_ssid, ss } /* clean ste cache */ for (i=0; i<ACM_TE_CACHE_SIZE; i++) - ste_ssidp->ste_cache[i].valid = FREE; + ste_ssidp->ste_cache[i].valid = ACM_STE_free; (*ste_ssid) = ste_ssidp; printkd("%s: determined ste_ssidref to %x.\n", @@ -329,7 +329,7 @@ ste_set_policy(u8 *buf, u32 buf_size) ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, (struct acm_ssid_domain *)(*pd)->ssid); for (i=0; i<ACM_TE_CACHE_SIZE; i++) - ste_ssid->ste_cache[i].valid = FREE; + ste_ssid->ste_cache[i].valid = ACM_STE_free; } read_unlock(&domlist_lock); return ACM_OK; @@ -397,7 +397,7 @@ check_cache(struct domain *dom, domid_t (struct acm_ssid_domain *)(dom->ssid)); for(i=0; i< ACM_TE_CACHE_SIZE; i++) { - if ((ste_ssid->ste_cache[i].valid == VALID) && + if ((ste_ssid->ste_cache[i].valid == ACM_STE_valid) && (ste_ssid->ste_cache[i].id == rdom)) { printkd("cache hit (entry %x, id= %x!\n", i, ste_ssid->ste_cache[i].id); return 1; @@ -418,10 +418,10 @@ cache_result(struct domain *subj, struct ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, (struct acm_ssid_domain *)(subj)->ssid); for(i=0; i< ACM_TE_CACHE_SIZE; i++) - if (ste_ssid->ste_cache[i].valid == FREE) + if (ste_ssid->ste_cache[i].valid == ACM_STE_free) break; if (i< ACM_TE_CACHE_SIZE) { - ste_ssid->ste_cache[i].valid = VALID; + ste_ssid->ste_cache[i].valid = ACM_STE_valid; ste_ssid->ste_cache[i].id = obj->domain_id; } else printk ("Cache of dom %x is full!\n", subj->domain_id); @@ -451,9 +451,9 @@ clean_id_from_cache(domid_t id) goto out; } for (i=0; i<ACM_TE_CACHE_SIZE; i++) - if ((ste_ssid->ste_cache[i].valid == VALID) && + if ((ste_ssid->ste_cache[i].valid == ACM_STE_valid) && (ste_ssid->ste_cache[i].id == id)) - ste_ssid->ste_cache[i].valid = FREE; + ste_ssid->ste_cache[i].valid = ACM_STE_free; } out: read_unlock(&domlist_lock); diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/ia64/linux-xen/smpboot.c --- a/xen/arch/ia64/linux-xen/smpboot.c Tue Jun 13 09:00:32 2006 -0600 +++ b/xen/arch/ia64/linux-xen/smpboot.c Tue Jun 13 12:12:24 2006 -0600 @@ -62,6 +62,7 @@ #include <asm/unistd.h> #ifdef XEN +#include <xen/domain.h> #include <asm/hw_irq.h> int ht_per_core = 1; #ifndef CONFIG_SMP @@ -487,7 +488,7 @@ do_rest: #else struct vcpu *v; - v = idle_vcpu[cpu] = alloc_vcpu(idle_vcpu[0]->domain, cpu, cpu); + v = alloc_idle_vcpu(cpu); BUG_ON(v == NULL); //printf ("do_boot_cpu: cpu=%d, domain=%p, vcpu=%p\n", cpu, idle, v); diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/ia64/vmx/vmx_init.c --- a/xen/arch/ia64/vmx/vmx_init.c Tue Jun 13 09:00:32 2006 -0600 +++ b/xen/arch/ia64/vmx/vmx_init.c Tue Jun 13 12:12:24 2006 -0600 @@ -288,9 +288,6 @@ vmx_final_setup_guest(struct vcpu *v) /* v->arch.schedule_tail = arch_vmx_do_launch; */ vmx_create_vp(v); - /* Set this ed to be vmx */ - set_bit(ARCH_VMX_VMCS_LOADED, &v->arch.arch_vmx.flags); - /* Physical mode emulation initialization, including * emulation ID allcation and related memory request */ diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/ia64/xen/domain.c --- a/xen/arch/ia64/xen/domain.c Tue Jun 13 09:00:32 2006 -0600 +++ b/xen/arch/ia64/xen/domain.c Tue Jun 13 12:12:24 2006 -0600 @@ -46,6 +46,7 @@ #include <asm/vcpu.h> /* for function declarations */ #include <public/arch-ia64.h> +#include <xen/domain.h> #include <asm/vmx.h> #include <asm/vmx_vcpu.h> #include <asm/vmx_vpd.h> diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/ia64/xen/xensetup.c --- a/xen/arch/ia64/xen/xensetup.c Tue Jun 13 09:00:32 2006 -0600 +++ b/xen/arch/ia64/xen/xensetup.c Tue Jun 13 12:12:24 2006 -0600 @@ -35,8 +35,6 @@ char saved_command_line[COMMAND_LINE_SIZ char saved_command_line[COMMAND_LINE_SIZE]; char dom0_command_line[COMMAND_LINE_SIZE]; -struct vcpu *idle_vcpu[NR_CPUS]; - cpumask_t cpu_present_map; extern unsigned long domain0_ready; diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/x86/audit.c --- a/xen/arch/x86/audit.c Tue Jun 13 09:00:32 2006 -0600 +++ b/xen/arch/x86/audit.c Tue Jun 13 12:12:24 2006 -0600 @@ -432,10 +432,10 @@ int audit_adjust_pgtables(struct domain for_each_vcpu(d, v) { - if ( pagetable_get_paddr(v->arch.guest_table) ) + if ( !pagetable_is_null(v->arch.guest_table) ) adjust(mfn_to_page(pagetable_get_pfn(v->arch.guest_table)), !shadow_mode_refcounts(d)); - if ( pagetable_get_paddr(v->arch.shadow_table) ) + if ( !pagetable_is_null(v->arch.shadow_table) ) adjust(mfn_to_page(pagetable_get_pfn(v->arch.shadow_table)), 0); if ( v->arch.monitor_shadow_ref ) diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/x86/cpu/mtrr/main.c --- a/xen/arch/x86/cpu/mtrr/main.c Tue Jun 13 09:00:32 2006 -0600 +++ b/xen/arch/x86/cpu/mtrr/main.c Tue Jun 13 12:12:24 2006 -0600 @@ -43,7 +43,7 @@ #include "mtrr.h" /* No blocking mutexes in Xen. Spin instead. */ -#define DECLARE_MUTEX(_m) spinlock_t _m = SPIN_LOCK_UNLOCKED +#define DECLARE_MUTEX(_m) DEFINE_SPINLOCK(_m) #define down(_m) spin_lock(_m) #define up(_m) spin_unlock(_m) #define lock_cpu_hotplug() ((void)0) diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/x86/dom0_ops.c --- a/xen/arch/x86/dom0_ops.c Tue Jun 13 09:00:32 2006 -0600 +++ b/xen/arch/x86/dom0_ops.c Tue Jun 13 12:12:24 2006 -0600 @@ -467,7 +467,7 @@ void arch_getdomaininfo_ctxt( if ( hvm_guest(v) ) c->flags |= VGCF_HVM_GUEST; - c->ctrlreg[3] = pagetable_get_paddr(v->arch.guest_table); + c->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); c->vm_assist = v->domain->vm_assist; } diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Tue Jun 13 09:00:32 2006 -0600 +++ b/xen/arch/x86/domain.c Tue Jun 13 12:12:24 2006 -0600 @@ -259,7 +259,7 @@ int arch_set_info_guest( struct vcpu *v, struct vcpu_guest_context *c) { struct domain *d = v->domain; - unsigned long phys_basetab = INVALID_MFN; + unsigned long cr3_pfn = INVALID_MFN; int i, rc; if ( !(c->flags & VGCF_HVM_GUEST) ) @@ -322,12 +322,8 @@ int arch_set_info_guest( if ( !(c->flags & VGCF_HVM_GUEST) ) { - phys_basetab = c->ctrlreg[3]; - phys_basetab = - (gmfn_to_mfn(d, phys_basetab >> PAGE_SHIFT) << PAGE_SHIFT) | - (phys_basetab & ~PAGE_MASK); - - v->arch.guest_table = mk_pagetable(phys_basetab); + cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c->ctrlreg[3])); + v->arch.guest_table = pagetable_from_pfn(cr3_pfn); } if ( (rc = (int)set_gdt(v, c->gdt_frames, c->gdt_ents)) != 0 ) @@ -335,14 +331,14 @@ int arch_set_info_guest( if ( c->flags & VGCF_HVM_GUEST ) { - v->arch.guest_table = mk_pagetable(0); + v->arch.guest_table = pagetable_null(); if ( !hvm_initialize_guest_resources(v) ) return -EINVAL; } else if ( shadow_mode_refcounts(d) ) { - if ( !get_page(mfn_to_page(phys_basetab>>PAGE_SHIFT), d) ) + if ( !get_page(mfn_to_page(cr3_pfn), d) ) { destroy_gdt(v); return -EINVAL; @@ -350,7 +346,7 @@ int arch_set_info_guest( } else { - if ( !get_page_and_type(mfn_to_page(phys_basetab>>PAGE_SHIFT), d, + if ( !get_page_and_type(mfn_to_page(cr3_pfn), d, PGT_base_page_table) ) { destroy_gdt(v); @@ -381,10 +377,6 @@ arch_do_vcpu_op( { struct vcpu_register_runstate_memory_area area; - rc = -EINVAL; - if ( v != current ) - break; - rc = -EFAULT; if ( copy_from_guest(&area, arg, 1) ) break; @@ -394,7 +386,10 @@ arch_do_vcpu_op( rc = 0; v->runstate_guest = area.addr.v; - __copy_to_user(v->runstate_guest, &v->runstate, sizeof(v->runstate)); + + if ( v == current ) + __copy_to_user(v->runstate_guest, &v->runstate, + sizeof(v->runstate)); break; } @@ -528,20 +523,29 @@ static void load_segments(struct vcpu *n if ( unlikely(!all_segs_okay) ) { struct cpu_user_regs *regs = guest_cpu_user_regs(); - unsigned long *rsp = + unsigned long *rsp = (n->arch.flags & TF_kernel_mode) ? (unsigned long *)regs->rsp : (unsigned long *)nctxt->kernel_sp; + unsigned long cs_and_mask, rflags; if ( !(n->arch.flags & TF_kernel_mode) ) toggle_guest_mode(n); else regs->cs &= ~3; + /* CS longword also contains full evtchn_upcall_mask. */ + cs_and_mask = (unsigned long)regs->cs | + ((unsigned long)n->vcpu_info->evtchn_upcall_mask << 32); + + /* Fold upcall mask into RFLAGS.IF. */ + rflags = regs->rflags & ~X86_EFLAGS_IF; + rflags |= !n->vcpu_info->evtchn_upcall_mask << 9; + if ( put_user(regs->ss, rsp- 1) | put_user(regs->rsp, rsp- 2) | - put_user(regs->rflags, rsp- 3) | - put_user(regs->cs, rsp- 4) | + put_user(rflags, rsp- 3) | + put_user(cs_and_mask, rsp- 4) | put_user(regs->rip, rsp- 5) | put_user(nctxt->user_regs.gs, rsp- 6) | put_user(nctxt->user_regs.fs, rsp- 7) | @@ -553,6 +557,10 @@ static void load_segments(struct vcpu *n DPRINTK("Error while creating failsafe callback frame.\n"); domain_crash(n->domain); } + + if ( test_bit(_VGCF_failsafe_disables_events, + &n->arch.guest_context.flags) ) + n->vcpu_info->evtchn_upcall_mask = 1; regs->entry_vector = TRAP_syscall; regs->rflags &= 0xFFFCBEFFUL; @@ -935,7 +943,7 @@ void domain_relinquish_resources(struct put_page_type(mfn_to_page(pfn)); put_page(mfn_to_page(pfn)); - v->arch.guest_table = mk_pagetable(0); + v->arch.guest_table = pagetable_null(); } if ( (pfn = pagetable_get_pfn(v->arch.guest_table_user)) != 0 ) @@ -944,7 +952,7 @@ void domain_relinquish_resources(struct put_page_type(mfn_to_page(pfn)); put_page(mfn_to_page(pfn)); - v->arch.guest_table_user = mk_pagetable(0); + v->arch.guest_table_user = pagetable_null(); } } diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/x86/domain_build.c --- a/xen/arch/x86/domain_build.c Tue Jun 13 09:00:32 2006 -0600 +++ b/xen/arch/x86/domain_build.c Tue Jun 13 12:12:24 2006 -0600 @@ -301,6 +301,9 @@ int construct_dom0(struct domain *d, xen_pae ? "yes" : "no", dom0_pae ? "yes" : "no"); return -EINVAL; } + + if ( xen_pae && !!strstr(dsi.xen_section_string, "PAE=yes[extended-cr3]") ) + set_bit(VMASST_TYPE_pae_extended_cr3, &d->vm_assist); if ( (p = strstr(dsi.xen_section_string, "FEATURES=")) != NULL ) { @@ -443,13 +446,13 @@ int construct_dom0(struct domain *d, l2tab[(LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT)+i] = l2e_from_paddr((u32)l2tab + i*PAGE_SIZE, __PAGE_HYPERVISOR); } - v->arch.guest_table = mk_pagetable((unsigned long)l3start); + v->arch.guest_table = pagetable_from_paddr((unsigned long)l3start); #else l2start = l2tab = (l2_pgentry_t *)mpt_alloc; mpt_alloc += PAGE_SIZE; memcpy(l2tab, idle_pg_table, PAGE_SIZE); l2tab[LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT] = l2e_from_paddr((unsigned long)l2start, __PAGE_HYPERVISOR); - v->arch.guest_table = mk_pagetable((unsigned long)l2start); + v->arch.guest_table = pagetable_from_paddr((unsigned long)l2start); #endif for ( i = 0; i < PDPT_L2_ENTRIES; i++ ) @@ -577,7 +580,7 @@ int construct_dom0(struct domain *d, l4e_from_paddr(__pa(l4start), __PAGE_HYPERVISOR); l4tab[l4_table_offset(PERDOMAIN_VIRT_START)] = l4e_from_paddr(__pa(d->arch.mm_perdomain_l3), __PAGE_HYPERVISOR); - v->arch.guest_table = mk_pagetable(__pa(l4start)); + v->arch.guest_table = pagetable_from_paddr(__pa(l4start)); l4tab += l4_table_offset(dsi.v_start); mfn = alloc_spfn; diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/x86/hvm/intercept.c --- a/xen/arch/x86/hvm/intercept.c Tue Jun 13 09:00:32 2006 -0600 +++ b/xen/arch/x86/hvm/intercept.c Tue Jun 13 12:12:24 2006 -0600 @@ -216,13 +216,14 @@ void hlt_timer_fn(void *data) static __inline__ void missed_ticks(struct periodic_time *pt) { - int missed_ticks; - - missed_ticks = (NOW() - pt->scheduled)/(s_time_t) pt->period; - if ( missed_ticks++ >= 0 ) { + s_time_t missed_ticks; + + missed_ticks = NOW() - pt->scheduled; + if ( missed_ticks > 0 ) { + missed_ticks = missed_ticks / (s_time_t) pt->period + 1; if ( missed_ticks > 1000 ) { /* TODO: Adjust guest time togther */ - pt->pending_intr_nr ++; + pt->pending_intr_nr++; } else { pt->pending_intr_nr += missed_ticks; @@ -236,6 +237,9 @@ void pt_timer_fn(void *data) { struct vcpu *v = data; struct periodic_time *pt = &(v->domain->arch.hvm_domain.pl_time.periodic_tm); + + pt->pending_intr_nr++; + pt->scheduled += pt->period; /* pick up missed timer tick */ missed_ticks(pt); diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/x86/hvm/io.c --- a/xen/arch/x86/hvm/io.c Tue Jun 13 09:00:32 2006 -0600 +++ b/xen/arch/x86/hvm/io.c Tue Jun 13 12:12:24 2006 -0600 @@ -507,6 +507,13 @@ static void hvm_mmio_assist(struct vcpu regs->ecx -= p->count; break; + case INSTR_LODS: + sign = p->df ? -1 : 1; + regs->esi += sign * p->count * p->size; + if (mmio_opp->flags & REPZ) + regs->ecx -= p->count; + break; + case INSTR_AND: if (src & REGISTER) { index = operand_index(src); diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/x86/hvm/platform.c --- a/xen/arch/x86/hvm/platform.c Tue Jun 13 09:00:32 2006 -0600 +++ b/xen/arch/x86/hvm/platform.c Tue Jun 13 12:12:24 2006 -0600 @@ -364,6 +364,12 @@ static int hvm_decode(int realmode, unsi } switch (*opcode) { + case 0x0A: /* or r8, m8 */ + instr->instr = INSTR_OR; + instr->op_size = BYTE; + GET_OP_SIZE_FOR_BYTE(size_reg); + return mem_reg(size_reg, opcode, instr, rex); + case 0x0B: /* or m32/16, r32/16 */ instr->instr = INSTR_OR; GET_OP_SIZE_FOR_NONEBYTE(instr->op_size); @@ -380,6 +386,12 @@ static int hvm_decode(int realmode, unsi GET_OP_SIZE_FOR_NONEBYTE(instr->op_size); return reg_mem(instr->op_size, opcode, instr, rex); + case 0x22: /* and m8, r8 */ + instr->instr = INSTR_AND; + instr->op_size = BYTE; + GET_OP_SIZE_FOR_BYTE(size_reg); + return mem_reg(size_reg, opcode, instr, rex); + case 0x23: /* and m32/16, r32/16 */ instr->instr = INSTR_AND; GET_OP_SIZE_FOR_NONEBYTE(instr->op_size); @@ -396,6 +408,12 @@ static int hvm_decode(int realmode, unsi GET_OP_SIZE_FOR_NONEBYTE(instr->op_size); return reg_mem(instr->op_size, opcode, instr, rex); + case 0x32: /* xor m8, r8*/ + instr->instr = INSTR_XOR; + instr->op_size = BYTE; + GET_OP_SIZE_FOR_BYTE(size_reg); + return mem_reg(size_reg, opcode, instr, rex); + case 0x39: /* cmp r32/16, m32/16 */ instr->instr = INSTR_CMP; GET_OP_SIZE_FOR_NONEBYTE(instr->op_size); @@ -408,19 +426,30 @@ static int hvm_decode(int realmode, unsi case 0x80: case 0x81: + case 0x83: { unsigned char ins_subtype = (opcode[1] >> 3) & 7; if (opcode[0] == 0x80) { GET_OP_SIZE_FOR_BYTE(size_reg); instr->op_size = BYTE; - } else { + } else if (opcode[0] == 0x81) { GET_OP_SIZE_FOR_NONEBYTE(instr->op_size); size_reg = instr->op_size; + } else if (opcode[0] == 0x83) { + GET_OP_SIZE_FOR_NONEBYTE(size_reg); + instr->op_size = size_reg; } + + /* opcode 0x83 always has a single byte operand */ + if (opcode[0] == 0x83) + instr->immediate = + (signed char)get_immediate(realmode, opcode+1, BYTE); + else + instr->immediate = + get_immediate(realmode, opcode+1, instr->op_size); instr->operand[0] = mk_operand(size_reg, 0, 0, IMMEDIATE); - instr->immediate = get_immediate(realmode, opcode+1, instr->op_size); instr->operand[1] = mk_operand(size_reg, 0, 0, MEMORY); switch (ins_subtype) { @@ -513,6 +542,16 @@ static int hvm_decode(int realmode, unsi case 0xAB: /* stosw/stosl */ instr->instr = INSTR_STOS; + GET_OP_SIZE_FOR_NONEBYTE(instr->op_size); + return DECODE_success; + + case 0xAC: /* lodsb */ + instr->instr = INSTR_LODS; + instr->op_size = BYTE; + return DECODE_success; + + case 0xAD: /* lodsw/lodsl */ + instr->instr = INSTR_LODS; GET_OP_SIZE_FOR_NONEBYTE(instr->op_size); return DECODE_success; @@ -906,6 +945,17 @@ void handle_mmio(unsigned long va, unsig GET_REPEAT_COUNT(), mmio_inst.op_size, regs->eax, IOREQ_WRITE, 0); break; + case INSTR_LODS: + /* + * Since the source is always in (contiguous) mmio space we don't + * need to break it up into pages. + */ + mmio_opp->flags = mmio_inst.flags; + mmio_opp->instr = mmio_inst.instr; + send_mmio_req(IOREQ_TYPE_COPY, gpa, + GET_REPEAT_COUNT(), mmio_inst.op_size, 0, IOREQ_READ, 0); + break; + case INSTR_OR: mmio_operands(IOREQ_TYPE_OR, gpa, &mmio_inst, mmio_opp, regs); break; @@ -954,26 +1004,26 @@ void handle_mmio(unsigned long va, unsig mmio_opp->instr = mmio_inst.instr; mmio_opp->operand[0] = mmio_inst.operand[0]; /* source */ mmio_opp->operand[1] = mmio_inst.operand[1]; /* destination */ - if (mmio_inst.operand[0] & REGISTER) { - long value; - unsigned long operand = mmio_inst.operand[0]; - value = get_reg_value(operand_size(operand), - operand_index(operand), 0, - mmio_opp->inst_decoder_regs); - /* send the request and wait for the value */ - send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1, - mmio_inst.op_size, value, IOREQ_WRITE, 0); - } else { - /* the destination is a register */ - long value; - unsigned long operand = mmio_inst.operand[1]; - value = get_reg_value(operand_size(operand), - operand_index(operand), 0, - mmio_opp->inst_decoder_regs); - /* send the request and wait for the value */ - send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1, - mmio_inst.op_size, value, IOREQ_WRITE, 0); - } + if ( mmio_inst.operand[0] & REGISTER ) { + long value; + unsigned long operand = mmio_inst.operand[0]; + value = get_reg_value(operand_size(operand), + operand_index(operand), 0, + mmio_opp->inst_decoder_regs); + /* send the request and wait for the value */ + send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1, + mmio_inst.op_size, value, IOREQ_WRITE, 0); + } else { + /* the destination is a register */ + long value; + unsigned long operand = mmio_inst.operand[1]; + value = get_reg_value(operand_size(operand), + operand_index(operand), 0, + mmio_opp->inst_decoder_regs); + /* send the request and wait for the value */ + send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1, + mmio_inst.op_size, value, IOREQ_WRITE, 0); + } break; default: diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Tue Jun 13 09:00:32 2006 -0600 +++ b/xen/arch/x86/hvm/svm/svm.c Tue Jun 13 12:12:24 2006 -0600 @@ -84,28 +84,26 @@ struct svm_percore_globals svm_globals[N /* * Initializes the POOL of ASID used by the guests per core. */ -void asidpool_init( int core ) +void asidpool_init(int core) { int i; - svm_globals[core].ASIDpool.asid_lock = SPIN_LOCK_UNLOCKED; - spin_lock(&svm_globals[core].ASIDpool.asid_lock); + + spin_lock_init(&svm_globals[core].ASIDpool.asid_lock); + /* Host ASID is always in use */ svm_globals[core].ASIDpool.asid[INITIAL_ASID] = ASID_INUSE; - for( i=1; i<ASID_MAX; i++ ) - { + for ( i = 1; i < ASID_MAX; i++ ) svm_globals[core].ASIDpool.asid[i] = ASID_AVAILABLE; - } - spin_unlock(&svm_globals[core].ASIDpool.asid_lock); } /* internal function to get the next available ASID */ -static int asidpool_fetch_next( struct vmcb_struct *vmcb, int core ) +static int asidpool_fetch_next(struct vmcb_struct *vmcb, int core) { int i; - for( i = 1; i < ASID_MAX; i++ ) - { - if( svm_globals[core].ASIDpool.asid[i] == ASID_AVAILABLE ) + for ( i = 1; i < ASID_MAX; i++ ) + { + if ( svm_globals[core].ASIDpool.asid[i] == ASID_AVAILABLE ) { vmcb->guest_asid = i; svm_globals[core].ASIDpool.asid[i] = ASID_INUSE; @@ -746,34 +744,34 @@ static void svm_ctxt_switch_to(struct vc void svm_final_setup_guest(struct vcpu *v) { + struct domain *d = v->domain; + struct vcpu *vc; + v->arch.schedule_tail = arch_svm_do_launch; v->arch.ctxt_switch_from = svm_ctxt_switch_from; v->arch.ctxt_switch_to = svm_ctxt_switch_to; - if (v == v->domain->vcpu[0]) - { - struct domain *d = v->domain; - struct vcpu *vc; - - /* Initialize monitor page table */ - for_each_vcpu(d, vc) - vc->arch.monitor_table = mk_pagetable(0); - - /* - * Required to do this once per domain - * TODO: add a seperate function to do these. - */ - memset(&d->shared_info->evtchn_mask[0], 0xff, - sizeof(d->shared_info->evtchn_mask)); - - /* - * Put the domain in shadow mode even though we're going to be using - * the shared 1:1 page table initially. It shouldn't hurt - */ - shadow_mode_enable(d, - SHM_enable|SHM_refcounts| - SHM_translate|SHM_external|SHM_wr_pt_pte); - } + if ( v != d->vcpu[0] ) + return; + + /* Initialize monitor page table */ + for_each_vcpu( d, vc ) + vc->arch.monitor_table = pagetable_null(); + + /* + * Required to do this once per domain + * TODO: add a seperate function to do these. + */ + memset(&d->shared_info->evtchn_mask[0], 0xff, + sizeof(d->shared_info->evtchn_mask)); + + /* + * Put the domain in shadow mode even though we're going to be using + * the shared 1:1 page table initially. It shouldn't hurt + */ + shadow_mode_enable(d, + SHM_enable|SHM_refcounts| + SHM_translate|SHM_external|SHM_wr_pt_pte); } @@ -870,7 +868,7 @@ static int svm_do_page_fault(unsigned lo /* Use 1:1 page table to identify MMIO address space */ if (mmio_space(gpa)) { - /* No support for APIC */ + /* No support for APIC */ if (!hvm_apic_support(v->domain) && gpa >= 0xFEC00000) { int inst_len; @@ -1570,7 +1568,7 @@ static int svm_set_cr0(unsigned long val } /* Now arch.guest_table points to machine physical. */ - v->arch.guest_table = mk_pagetable((u64)mfn << PAGE_SHIFT); + v->arch.guest_table = pagetable_from_pfn(mfn); update_pagetables(v); HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx", @@ -1590,7 +1588,7 @@ static int svm_set_cr0(unsigned long val if ( v->arch.hvm_svm.cpu_cr3 ) { put_page(mfn_to_page(get_mfn_from_gpfn( v->arch.hvm_svm.cpu_cr3 >> PAGE_SHIFT))); - v->arch.guest_table = mk_pagetable(0); + v->arch.guest_table = pagetable_null(); } /* @@ -1599,7 +1597,7 @@ static int svm_set_cr0(unsigned long val * created. */ if ((value & X86_CR0_PE) == 0) { - if (value & X86_CR0_PG) { + if (value & X86_CR0_PG) { svm_inject_exception(v, TRAP_gp_fault, 1, 0); return 0; } @@ -1740,7 +1738,7 @@ static int mov_to_cr(int gpreg, int cr, } old_base_mfn = pagetable_get_pfn(v->arch.guest_table); - v->arch.guest_table = mk_pagetable((u64)mfn << PAGE_SHIFT); + v->arch.guest_table = pagetable_from_pfn(mfn); if (old_base_mfn) put_page(mfn_to_page(old_base_mfn)); @@ -1797,7 +1795,7 @@ static int mov_to_cr(int gpreg, int cr, * Now arch.guest_table points to machine physical. */ - v->arch.guest_table = mk_pagetable((u64)mfn << PAGE_SHIFT); + v->arch.guest_table = pagetable_from_pfn(mfn); update_pagetables(v); HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx", diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/x86/hvm/vmx/vmcs.c --- a/xen/arch/x86/hvm/vmx/vmcs.c Tue Jun 13 09:00:32 2006 -0600 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Tue Jun 13 12:12:24 2006 -0600 @@ -42,7 +42,7 @@ int vmcs_size; -struct vmcs_struct *alloc_vmcs(void) +struct vmcs_struct *vmx_alloc_vmcs(void) { struct vmcs_struct *vmcs; u32 vmx_msr_low, vmx_msr_high; @@ -64,47 +64,63 @@ static void free_vmcs(struct vmcs_struct free_xenheap_pages(vmcs, order); } -static int load_vmcs(struct arch_vmx_struct *arch_vmx, u64 phys_ptr) -{ - int error; - - if ((error = __vmptrld(phys_ptr))) { - clear_bit(ARCH_VMX_VMCS_LOADED, &arch_vmx->flags); - return error; - } - set_bit(ARCH_VMX_VMCS_LOADED, &arch_vmx->flags); - return 0; -} - -static void vmx_smp_clear_vmcs(void *info) -{ - struct vcpu *v = (struct vcpu *)info; - - ASSERT(hvm_guest(v)); - - if (v->arch.hvm_vmx.launch_cpu == smp_processor_id()) - __vmpclear(virt_to_maddr(v->arch.hvm_vmx.vmcs)); -} - -void vmx_request_clear_vmcs(struct vcpu *v) -{ - ASSERT(hvm_guest(v)); - - if (v->arch.hvm_vmx.launch_cpu == smp_processor_id()) - __vmpclear(virt_to_maddr(v->arch.hvm_vmx.vmcs)); +static void __vmx_clear_vmcs(void *info) +{ + struct vcpu *v = info; + __vmpclear(virt_to_maddr(v->arch.hvm_vmx.vmcs)); + v->arch.hvm_vmx.active_cpu = -1; + v->arch.hvm_vmx.launched = 0; +} + +static void vmx_clear_vmcs(struct vcpu *v) +{ + unsigned int cpu = v->arch.hvm_vmx.active_cpu; + + if ( (cpu == -1) || (cpu == smp_processor_id()) ) + __vmx_clear_vmcs(v); else - smp_call_function(vmx_smp_clear_vmcs, v, 1, 1); -} - -#if 0 -static int store_vmcs(struct arch_vmx_struct *arch_vmx, u64 phys_ptr) -{ - /* take the current VMCS */ - __vmptrst(phys_ptr); - clear_bit(ARCH_VMX_VMCS_LOADED, &arch_vmx->flags); - return 0; -} -#endif + on_selected_cpus(cpumask_of_cpu(cpu), __vmx_clear_vmcs, v, 1, 1); +} + +static void vmx_load_vmcs(struct vcpu *v) +{ + __vmptrld(virt_to_maddr(v->arch.hvm_vmx.vmcs)); + v->arch.hvm_vmx.active_cpu = smp_processor_id(); +} + +void vmx_vmcs_enter(struct vcpu *v) +{ + /* + * NB. We must *always* run an HVM VCPU on its own VMCS, except for + * vmx_vmcs_enter/exit critical regions. This leads to some XXX TODOs XXX: + * 1. Move construct_vmcs() much earlier, to domain creation or + * context initialisation. + * 2. VMPTRLD as soon as we context-switch to a HVM VCPU. + * 3. VMCS destruction needs to happen later (from domain_destroy()). + */ + if ( v == current ) + return; + + vcpu_pause(v); + spin_lock(&v->arch.hvm_vmx.vmcs_lock); + + vmx_clear_vmcs(v); + vmx_load_vmcs(v); +} + +void vmx_vmcs_exit(struct vcpu *v) +{ + if ( v == current ) + return; + + /* Don't confuse arch_vmx_do_resume (for @v or @current!) */ + vmx_clear_vmcs(v); + if ( hvm_guest(current) ) + vmx_load_vmcs(current); + + spin_unlock(&v->arch.hvm_vmx.vmcs_lock); + vcpu_unpause(v); +} static inline int construct_vmcs_controls(struct arch_vmx_struct *arch_vmx) { @@ -247,7 +263,6 @@ static void vmx_do_launch(struct vcpu *v __vmwrite(HOST_CR3, pagetable_get_paddr(v->arch.monitor_table)); v->arch.schedule_tail = arch_vmx_do_resume; - v->arch.hvm_vmx.launch_cpu = smp_processor_id(); /* init guest tsc to start from 0 */ set_guest_time(v, 0); @@ -410,53 +425,49 @@ static inline int construct_vmcs_host(vo /* * Need to extend to support full virtualization. */ -static int construct_vmcs(struct arch_vmx_struct *arch_vmx, +static int construct_vmcs(struct vcpu *v, cpu_user_regs_t *regs) { + struct arch_vmx_struct *arch_vmx = &v->arch.hvm_vmx; int error; long rc; - u64 vmcs_phys_ptr; memset(arch_vmx, 0, sizeof(struct arch_vmx_struct)); + + spin_lock_init(&arch_vmx->vmcs_lock); + arch_vmx->active_cpu = -1; /* * Create a new VMCS */ - if (!(arch_vmx->vmcs = alloc_vmcs())) { + if (!(arch_vmx->vmcs = vmx_alloc_vmcs())) { printk("Failed to create a new VMCS\n"); - rc = -ENOMEM; - goto err_out; - } - vmcs_phys_ptr = (u64) virt_to_maddr(arch_vmx->vmcs); - - if ((error = __vmpclear(vmcs_phys_ptr))) { - printk("construct_vmcs: VMCLEAR failed\n"); - rc = -EINVAL; - goto err_out; - } - if ((error = load_vmcs(arch_vmx, vmcs_phys_ptr))) { - printk("construct_vmcs: load_vmcs failed: VMCS = %lx\n", - (unsigned long) vmcs_phys_ptr); - rc = -EINVAL; - goto err_out; - } + return -ENOMEM; + } + + vmx_clear_vmcs(v); + vmx_load_vmcs(v); + if ((error = construct_vmcs_controls(arch_vmx))) { printk("construct_vmcs: construct_vmcs_controls failed\n"); rc = -EINVAL; goto err_out; } + /* host selectors */ if ((error = construct_vmcs_host())) { printk("construct_vmcs: construct_vmcs_host failed\n"); rc = -EINVAL; goto err_out; } + /* guest selectors */ if ((error = construct_init_vmcs_guest(regs))) { printk("construct_vmcs: construct_vmcs_guest failed\n"); rc = -EINVAL; goto err_out; } + if ((error |= __vmwrite(EXCEPTION_BITMAP, MONITOR_DEFAULT_EXCEPTION_BITMAP))) { printk("construct_vmcs: setting Exception bitmap failed\n"); @@ -472,12 +483,16 @@ static int construct_vmcs(struct arch_vm return 0; err_out: - destroy_vmcs(arch_vmx); + vmx_destroy_vmcs(v); return rc; } -void destroy_vmcs(struct arch_vmx_struct *arch_vmx) -{ +void vmx_destroy_vmcs(struct vcpu *v) +{ + struct arch_vmx_struct *arch_vmx = &v->arch.hvm_vmx; + + vmx_clear_vmcs(v); + free_vmcs(arch_vmx->vmcs); arch_vmx->vmcs = NULL; @@ -506,22 +521,20 @@ void vm_resume_fail(unsigned long eflags void arch_vmx_do_resume(struct vcpu *v) { - if ( v->arch.hvm_vmx.launch_cpu == smp_processor_id() ) + if ( v->arch.hvm_vmx.active_cpu == smp_processor_id() ) { - load_vmcs(&v->arch.hvm_vmx, virt_to_maddr(v->arch.hvm_vmx.vmcs)); - vmx_do_resume(v); - reset_stack_and_jump(vmx_asm_do_resume); + vmx_load_vmcs(v); } else { - vmx_request_clear_vmcs(v); - load_vmcs(&v->arch.hvm_vmx, virt_to_maddr(v->arch.hvm_vmx.vmcs)); + vmx_clear_vmcs(v); + vmx_load_vmcs(v); vmx_migrate_timers(v); vmx_set_host_env(v); - vmx_do_resume(v); - v->arch.hvm_vmx.launch_cpu = smp_processor_id(); - reset_stack_and_jump(vmx_asm_do_relaunch); - } + } + + vmx_do_resume(v); + reset_stack_and_jump(vmx_asm_do_vmentry); } void arch_vmx_do_launch(struct vcpu *v) @@ -529,7 +542,7 @@ void arch_vmx_do_launch(struct vcpu *v) int error; cpu_user_regs_t *regs = ¤t->arch.guest_context.user_regs; - error = construct_vmcs(&v->arch.hvm_vmx, regs); + error = construct_vmcs(v, regs); if ( error < 0 ) { if (v->vcpu_id == 0) { @@ -540,7 +553,7 @@ void arch_vmx_do_launch(struct vcpu *v) domain_crash_synchronous(); } vmx_do_launch(v); - reset_stack_and_jump(vmx_asm_do_launch); + reset_stack_and_jump(vmx_asm_do_vmentry); } @@ -613,17 +626,9 @@ static void vmcs_dump(unsigned char ch) } printk("\tVCPU %d\n", v->vcpu_id); - if (v != current) { - vcpu_pause(v); - __vmptrld(virt_to_maddr(v->arch.hvm_vmx.vmcs)); - } - + vmx_vmcs_enter(v); vmcs_dump_vcpu(); - - if (v != current) { - __vmptrld(virt_to_maddr(current->arch.hvm_vmx.vmcs)); - vcpu_unpause(v); - } + vmx_vmcs_exit(v); } } diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Tue Jun 13 09:00:32 2006 -0600 +++ b/xen/arch/x86/hvm/vmx/vmx.c Tue Jun 13 12:12:24 2006 -0600 @@ -38,6 +38,7 @@ #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> #if CONFIG_PAGING_LEVELS >= 3 #include <asm/shadow_64.h> @@ -66,7 +67,7 @@ void vmx_final_setup_guest(struct vcpu * /* Initialize monitor page table */ for_each_vcpu(d, vc) - vc->arch.monitor_table = mk_pagetable(0); + vc->arch.monitor_table = pagetable_null(); /* * Required to do this once per domain @@ -91,8 +92,7 @@ static void vmx_relinquish_guest_resourc { if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) ) continue; - vmx_request_clear_vmcs(v); - destroy_vmcs(&v->arch.hvm_vmx); + vmx_destroy_vmcs(v); free_monitor_pagetable(v); kill_timer(&v->arch.hvm_vmx.hlt_timer); if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) ) @@ -402,54 +402,10 @@ void vmx_migrate_timers(struct vcpu *v) migrate_timer(&(VLAPIC(v)->vlapic_timer), v->processor); } -struct vmx_cpu_guest_regs_callback_info { - struct vcpu *v; - struct cpu_user_regs *regs; - unsigned long *crs; -}; - -static void vmx_store_cpu_guest_regs( - struct vcpu *v, struct cpu_user_regs *regs, unsigned long *crs); - -static void vmx_load_cpu_guest_regs( - struct vcpu *v, struct cpu_user_regs *regs); - -static void vmx_store_cpu_guest_regs_callback(void *data) -{ - struct vmx_cpu_guest_regs_callback_info *info = data; - vmx_store_cpu_guest_regs(info->v, info->regs, info->crs); -} - -static void vmx_load_cpu_guest_regs_callback(void *data) -{ - struct vmx_cpu_guest_regs_callback_info *info = data; - vmx_load_cpu_guest_regs(info->v, info->regs); -} - static void vmx_store_cpu_guest_regs( struct vcpu *v, struct cpu_user_regs *regs, unsigned long *crs) { - if ( v != current ) - { - /* Non-current VCPUs must be paused to get a register snapshot. */ - ASSERT(atomic_read(&v->pausecnt) != 0); - - if ( v->arch.hvm_vmx.launch_cpu != smp_processor_id() ) - { - /* Get register details from remote CPU. */ - struct vmx_cpu_guest_regs_callback_info info = { - .v = v, .regs = regs, .crs = crs }; - cpumask_t cpumask = cpumask_of_cpu(v->arch.hvm_vmx.launch_cpu); - on_selected_cpus(cpumask, vmx_store_cpu_guest_regs_callback, - &info, 1, 1); - return; - } - - /* Register details are on this CPU. Load the correct VMCS. */ - __vmptrld(virt_to_maddr(v->arch.hvm_vmx.vmcs)); - } - - ASSERT(v->arch.hvm_vmx.launch_cpu == smp_processor_id()); + vmx_vmcs_enter(v); if ( regs != NULL ) { @@ -471,9 +427,7 @@ static void vmx_store_cpu_guest_regs( __vmread(CR4_READ_SHADOW, &crs[4]); } - /* Reload current VCPU's VMCS if it was temporarily unloaded. */ - if ( (v != current) && hvm_guest(current) ) - __vmptrld(virt_to_maddr(current->arch.hvm_vmx.vmcs)); + vmx_vmcs_exit(v); } /* @@ -517,26 +471,7 @@ static void fixup_vm86_seg_bases(struct void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs) { - if ( v != current ) - { - /* Non-current VCPUs must be paused to set the register snapshot. */ - ASSERT(atomic_read(&v->pausecnt) != 0); - - if ( v->arch.hvm_vmx.launch_cpu != smp_processor_id() ) - { - struct vmx_cpu_guest_regs_callback_info info = { - .v = v, .regs = regs }; - cpumask_t cpumask = cpumask_of_cpu(v->arch.hvm_vmx.launch_cpu); - on_selected_cpus(cpumask, vmx_load_cpu_guest_regs_callback, - &info, 1, 1); - return; - } - - /* Register details are on this CPU. Load the correct VMCS. */ - __vmptrld(virt_to_maddr(v->arch.hvm_vmx.vmcs)); - } - - ASSERT(v->arch.hvm_vmx.launch_cpu == smp_processor_id()); + vmx_vmcs_enter(v); __vmwrite(GUEST_SS_SELECTOR, regs->ss); __vmwrite(GUEST_DS_SELECTOR, regs->ds); @@ -557,9 +492,7 @@ void vmx_load_cpu_guest_regs(struct vcpu __vmwrite(GUEST_CS_SELECTOR, regs->cs); __vmwrite(GUEST_RIP, regs->eip); - /* Reload current VCPU's VMCS if it was temporarily unloaded. */ - if ( (v != current) && hvm_guest(current) ) - __vmptrld(virt_to_maddr(current->arch.hvm_vmx.vmcs)); + vmx_vmcs_exit(v); } int vmx_realmode(struct vcpu *v) @@ -688,16 +621,19 @@ int start_vmx(void) set_in_cr4(X86_CR4_VMXE); /* Enable VMXE */ - if (!(vmcs = alloc_vmcs())) { + if (!(vmcs = vmx_alloc_vmcs())) { printk("Failed to allocate VMCS\n"); return 0; } phys_vmcs = (u64) virt_to_maddr(vmcs); - if (!(__vmxon(phys_vmcs))) { - printk("VMXON is done\n"); - } + if (__vmxon(phys_vmcs)) { + printk("VMXON failed\n"); + return 0; + } + + printk("VMXON is done\n"); vmx_save_init_msrs(); @@ -814,9 +750,7 @@ static void vmx_do_no_device_fault(void) } } -/* Reserved bits: [31:15], [12:11], [9], [6], [2:1] */ -#define VMX_VCPU_CPUID_L1_RESERVED 0xffff9a46 - +#define bitmaskof(idx) (1U << ((idx)&31)) static void vmx_vmexit_do_cpuid(struct cpu_user_regs *regs) { unsigned int input = (unsigned int)regs->eax; @@ -833,50 +767,74 @@ static void vmx_vmexit_do_cpuid(struct c (unsigned long)regs->ecx, (unsigned long)regs->edx, (unsigned long)regs->esi, (unsigned long)regs->edi); - if ( input == 4 ) + if ( input == CPUID_LEAF_0x4 ) + { cpuid_count(input, count, &eax, &ebx, &ecx, &edx); + eax &= NUM_CORES_RESET_MASK; + } else + { cpuid(input, &eax, &ebx, &ecx, &edx); - if ( input == 1 ) - { - if ( !hvm_apic_support(v->domain) || - !vlapic_global_enabled((VLAPIC(v))) ) + if ( input == CPUID_LEAF_0x1 ) { - clear_bit(X86_FEATURE_APIC, &edx); - /* Since the apic is disabled, avoid any confusion about SMP cpus being available */ - clear_bit(X86_FEATURE_HT, &edx); /* clear the hyperthread bit */ - ebx &= 0xFF00FFFF; /* set the logical processor count to 1 */ - ebx |= 0x00010000; - } - - + /* mask off reserved bits */ + ecx &= ~VMX_VCPU_CPUID_L1_ECX_RESERVED; + + if ( !hvm_apic_support(v->domain) || + !vlapic_global_enabled((VLAPIC(v))) ) + { + /* Since the apic is disabled, avoid any + confusion about SMP cpus being available */ + + clear_bit(X86_FEATURE_APIC, &edx); + } + #if CONFIG_PAGING_LEVELS < 3 - clear_bit(X86_FEATURE_PAE, &edx); - clear_bit(X86_FEATURE_PSE, &edx); - clear_bit(X86_FEATURE_PSE36, &edx); + edx &= ~(bitmaskof(X86_FEATURE_PAE) | + bitmaskof(X86_FEATURE_PSE) | + bitmaskof(X86_FEATURE_PSE36)); #else - if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 ) + if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 ) + { + if ( !v->domain->arch.hvm_domain.pae_enabled ) + clear_bit(X86_FEATURE_PAE, &edx); + clear_bit(X86_FEATURE_PSE, &edx); + clear_bit(X86_FEATURE_PSE36, &edx); + } +#endif + + ebx &= NUM_THREADS_RESET_MASK; + + /* Unsupportable for virtualised CPUs. */ + ecx &= ~(bitmaskof(X86_FEATURE_VMXE) | + bitmaskof(X86_FEATURE_EST) | + bitmaskof(X86_FEATURE_TM2) | + bitmaskof(X86_FEATURE_CID) | + bitmaskof(X86_FEATURE_MWAIT) ); + + edx &= ~( bitmaskof(X86_FEATURE_HT) | + bitmaskof(X86_FEATURE_MCA) | + bitmaskof(X86_FEATURE_MCE) | + bitmaskof(X86_FEATURE_ACPI) | + bitmaskof(X86_FEATURE_ACC) ); + } + else if ( ( input == CPUID_LEAF_0x6 ) + || ( input == CPUID_LEAF_0x9 ) + || ( input == CPUID_LEAF_0xA )) { - if ( !v->domain->arch.hvm_domain.pae_enabled ) - clear_bit(X86_FEATURE_PAE, &edx); - clear_bit(X86_FEATURE_PSE, &edx); - clear_bit(X86_FEATURE_PSE36, &edx); + eax = ebx = ecx = edx = 0x0; + } +#ifdef __i386__ + else if ( input == CPUID_LEAF_0x80000001 ) + { + clear_bit(X86_FEATURE_LAHF_LM & 31, &ecx); + + clear_bit(X86_FEATURE_LM & 31, &edx); + clear_bit(X86_FEATURE_SYSCALL & 31, &edx); } #endif - - /* Unsupportable for virtualised CPUs. */ - ecx &= ~VMX_VCPU_CPUID_L1_RESERVED; /* mask off reserved bits */ - clear_bit(X86_FEATURE_VMXE & 31, &ecx); - clear_bit(X86_FEATURE_MWAIT & 31, &ecx); - } -#ifdef __i386__ - else if ( input == 0x80000001 ) - { - /* Mask feature for Intel ia32e or AMD long mode. */ - clear_bit(X86_FEATURE_LM & 31, &edx); - } -#endif + } regs->eax = (unsigned long) eax; regs->ebx = (unsigned long) ebx; @@ -1223,7 +1181,7 @@ vmx_world_restore(struct vcpu *v, struct if(!get_page(mfn_to_page(mfn), v->domain)) return 0; old_base_mfn = pagetable_get_pfn(v->arch.guest_table); - v->arch.guest_table = mk_pagetable((u64)mfn << PAGE_SHIFT); + v->arch.guest_table = pagetable_from_pfn(mfn); if (old_base_mfn) put_page(mfn_to_page(old_base_mfn)); /* @@ -1459,7 +1417,7 @@ static int vmx_set_cr0(unsigned long val /* * Now arch.guest_table points to machine physical. */ - v->arch.guest_table = mk_pagetable((u64)mfn << PAGE_SHIFT); + v->arch.guest_table = pagetable_from_pfn(mfn); update_pagetables(v); HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx", @@ -1477,7 +1435,7 @@ static int vmx_set_cr0(unsigned long val if ( v->arch.hvm_vmx.cpu_cr3 ) { put_page(mfn_to_page(get_mfn_from_gpfn( v->arch.hvm_vmx.cpu_cr3 >> PAGE_SHIFT))); - v->arch.guest_table = mk_pagetable(0); + v->arch.guest_table = pagetable_null(); } /* @@ -1635,7 +1593,7 @@ static int mov_to_cr(int gp, int cr, str domain_crash_synchronous(); /* need to take a clean path */ } old_base_mfn = pagetable_get_pfn(v->arch.guest_table); - v->arch.guest_table = mk_pagetable((u64)mfn << PAGE_SHIFT); + v->arch.guest_table = pagetable_from_pfn(mfn); if (old_base_mfn) put_page(mfn_to_page(old_base_mfn)); /* @@ -1690,7 +1648,7 @@ static int mov_to_cr(int gp, int cr, str * Now arch.guest_table points to machine physical. */ - v->arch.guest_table = mk_pagetable((u64)mfn << PAGE_SHIFT); + v->arch.guest_table = pagetable_from_pfn(mfn); update_pagetables(v); HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx", @@ -1970,7 +1928,6 @@ static inline void vmx_vmexit_do_extint( __hvm_bug(regs); vector &= INTR_INFO_VECTOR_MASK; - local_irq_disable(); TRACE_VMEXIT(1,vector); switch(vector) { @@ -2065,30 +2022,33 @@ asmlinkage void vmx_vmexit_handler(struc struct vcpu *v = current; int error; - if ((error = __vmread(VM_EXIT_REASON, &exit_reason))) - __hvm_bug(®s); + error = __vmread(VM_EXIT_REASON, &exit_reason); + BUG_ON(error); perfc_incra(vmexits, exit_reason); - /* don't bother H/W interrutps */ - if (exit_reason != EXIT_REASON_EXTERNAL_INTERRUPT && - exit_reason != EXIT_REASON_VMCALL && - exit_reason != EXIT_REASON_IO_INSTRUCTION) + if ( (exit_reason != EXIT_REASON_EXTERNAL_INTERRUPT) && + (exit_reason != EXIT_REASON_VMCALL) && + (exit_reason != EXIT_REASON_IO_INSTRUCTION) ) HVM_DBG_LOG(DBG_LEVEL_0, "exit reason = %x", exit_reason); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |