# 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
|