From d7002a96b99b95061bea2aab60b670d3a57fd1158a0c89d8076799b1aed8f7ef Mon Sep 17 00:00:00 2001 From: OBS User unknown Date: Sun, 11 Feb 2007 10:48:10 +0000 Subject: [PATCH] OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/xen?expand=0&rev=3 --- 32on64-acmop.patch | 147 + 32on64-base.patch | 1058 ++++ 32on64-call-gates.patch | 484 ++ 32on64-domctl.patch | 1336 +++++ 32on64-emul.patch | 647 +++ 32on64-fixes.patch | 110 + 32on64-gnttabop.patch | 281 + 32on64-hvm.patch | 184 + 32on64-hypercall.patch | 900 +++ 32on64-interface.patch | 616 +++ 32on64-kexec.patch | 226 + 32on64-m2p.patch | 1192 ++++ 32on64-memop.patch | 1196 ++++ 32on64-mmuop.patch | 292 + 32on64-multicall.patch | 168 + 32on64-per-domain-pa-bits.patch | 78 + 32on64-physdevop.patch | 316 ++ 32on64-pltop.patch | 108 + 32on64-schedop.patch | 167 + 32on64-settrap.patch | 123 + 32on64-shadow.patch | 199 + 32on64-shared.patch | 900 +++ 32on64-startup.patch | 584 ++ 32on64-sysctl.patch | 312 ++ 32on64-trace.patch | 142 + 32on64-vcpuop.patch | 379 ++ 32on64-xenoprof.patch | 326 ++ README.SuSE | 116 +- blktools-bimodal.diff | 71 + block-iscsi | 180 +- block-losetup-retry.diff | 8 +- block-nbd | 2 +- block-sync.diff | 6 +- bridge-hostonly.diff | 82 + bug.patch | 325 ++ cross-build-fix.diff | 45 + domUloader.py | 470 +- domheap-no-dma.patch | 168 + emul-privop-lock.patch | 76 + fbback-bimodal.diff | 158 + hide-asm-labels.patch | 505 ++ init.xend | 29 +- init.xendomains | 43 +- libelf-add-to-xenkernel.diff | 3100 +++++++++++ libelf-symlink-to-libxc.diff | 36 + libelf-use-hvm-build.diff | 300 + libelf-use-readnotes.diff | 360 ++ libelf-use-xen-dom0.diff | 722 +++ libxc-logging.diff | 111 + mem-zones.patch | 244 + microcode-xen-13079.diff | 61 + mk-xen-rescue-img.sh | 278 - non-flat-pm.patch | 461 -- npt-fpu-bug.patch | 28 + npt-windows-bug.patch | 302 + npt_part1.patch | 1096 ++++ npt_part2.patch | 13 + pae-guest-linear-pgtable.patch | 83 + protocol-bimodal.diff | 35 + pv-driver-build.patch | 101 + serial-split.patch | 8 +- suppress-rdtscp.patch | 28 + svm-update-v_tpr-on-mmio.patch | 116 + svm_cpuid_ffxsr_13743.patch | 25 + tools-add-errors.diff | 41 + tools-debug-oldbuilder.diff | 238 + tools-domain-builder-core.diff | 3066 +++++++++++ tools-domain-builder-header-libxc.diff | 165 + tools-domain-builder-linux.diff | 164 + tools-kboot.diff | 2171 ++++++++ tools-readnotes-gunzip.diff | 46 + tools-xc_kexec.diff | 5135 ++++++++++++++++++ vgacon-50-lines.patch | 44 + vgacon-keep.patch | 113 + x86-extra-trap-info.patch | 89 + x86-mm-simplify.patch | 56 + x86-ptwr_emulate.patch | 33 + x86_emulate.patch | 554 ++ xen-3.0.3-testing-src.tar.bz2 | 3 - xen-3.0.4-testing-src.tar.bz2 | 3 + xen-bonding.diff | 16 +- xen-bootloader-dryrun.diff | 22 + xen-bootloader-nohang.diff | 32 + xen-bootloader-tidy.diff | 13 + xen-changeset.diff | 19 +- xen-config.diff | 14 + xen-console.diff | 63 - xen-destdir.diff | 110 +- xen-docs.diff | 30 - xen-domUloader-pygrub.diff | 16 - xen-domUloader.diff | 197 +- xen-generate-foreign-headers.diff | 406 ++ xen-hvm-default-bridge.diff | 62 +- xen-hvm-default-pae.diff | 18 +- xen-hvm-netfront.diff | 8 +- xen-io-register-context.diff | 680 --- xen-ioapic-ack-default.diff | 10 +- xen-keymap.diff | 47 - xen-localtime.patch | 14 + xen-lost-mouse.diff | 24 +- xen-lowmem-emergency-pool.diff | 56 +- xen-man-permissions.patch | 6 +- xen-man-xm-bad-char.diff | 6 +- xen-max-free-mem.diff | 36 +- xen-messages.diff | 49 +- xen-network-bridge.diff | 12 +- xen-no-dummy-nfs-ip.diff | 8 +- xen-poweroff.diff | 57 - xen-pvfb-2.patch | 1122 ---- xen-pvfb-3.patch | 129 - xen-python25-warnings.diff | 152 - xen-rpmoptflags.diff | 68 +- xen-tightvnc-args.diff | 8 +- xen-vm-install.diff | 12 + xen-vm-install.tar.bz2 | 3 + xen-warnings.diff | 12 +- xen-xm-top-needs-root.diff | 8 +- xen-xmexample-nbd.diff | 2 +- xen-xmexample.diff | 61 +- xen.changes | 195 +- xen.spec | 655 ++- xend-config-devname.patch | 27 + xend-config-ramdisk.patch | 21 + xen-config-defaults.diff => xend-config.diff | 30 +- xend-xmlrpc-large-ints.diff | 26 +- xm-test-cleanup.diff | 14 + xmclone.sh | 579 ++ xmexample.rescue | 85 - xu-11841-svm-interrupt-delivery.diff | 75 - xu-11842-svm-interrupt-delivery.diff | 121 - xu-11843-svm-no-double-nmi.diff | 33 - xu-11847-pv-hvm.diff | 74 - xu-11888-pv-hvm.diff | 45 - xu-11896-pv-hvm.diff | 65 - xu-11897-pv-hvm.diff | 40 - xu-11898-pv-hvm.diff | 764 --- xu-11899-pv-hvm.diff | 39 - xu-11900-pv-hvm.diff | 34 - xu-11901-pv-hvm.diff | 26 - xu-11902-pv-hvm.diff | 40 - xu-11903-pv-hvm.diff | 55 - xu-11904-pv-hvm.diff | 26 - xu-11905-pv-hvm.diff | 230 - xu-11906-pv-hvm.diff | 25 - xu-11907-pv-hvm.diff | 48 - xu-11908-pv-hvm.diff | 47 - xu-11909-pv-hvm.diff | 42 - xu-11910-pv-hvm.diff | 22 - xu-11911-pv-hvm.diff | 26 - xu-11912-pv-hvm.diff | 39 - xu-11913-pv-hvm.diff | 48 - xu-11914-pv-hvm.diff | 67 - xu-11915-pv-hvm.diff | 34 - xu-11916-pv-hvm.diff | 39 - xu-11917-pv-hvm.diff | 54 - xu-11918-pv-hvm.diff | 24 - xu-11974-pv-hvm.diff | 72 - xu-12012-hvm-smp-timer.diff | 140 - xu-12013-hvm-ioapic.diff | 59 - xu-12030-pv-hvm.diff | 99 - xu-12031-pv-hvm.diff | 243 - xu-12032-pv-hvm.diff | 31 - xu-12040-pv-spurious-interrupt.diff | 44 - xu-12205-pv-hvm.diff | 23 - xu-12278-hvm-interrupt-race.diff | 57 - xxx_heap_pages-static.patch | 244 + 166 files changed, 35454 insertions(+), 7164 deletions(-) create mode 100644 32on64-acmop.patch create mode 100644 32on64-base.patch create mode 100644 32on64-call-gates.patch create mode 100644 32on64-domctl.patch create mode 100644 32on64-emul.patch create mode 100644 32on64-fixes.patch create mode 100644 32on64-gnttabop.patch create mode 100644 32on64-hvm.patch create mode 100644 32on64-hypercall.patch create mode 100644 32on64-interface.patch create mode 100644 32on64-kexec.patch create mode 100644 32on64-m2p.patch create mode 100644 32on64-memop.patch create mode 100644 32on64-mmuop.patch create mode 100644 32on64-multicall.patch create mode 100644 32on64-per-domain-pa-bits.patch create mode 100644 32on64-physdevop.patch create mode 100644 32on64-pltop.patch create mode 100644 32on64-schedop.patch create mode 100644 32on64-settrap.patch create mode 100644 32on64-shadow.patch create mode 100644 32on64-shared.patch create mode 100644 32on64-startup.patch create mode 100644 32on64-sysctl.patch create mode 100644 32on64-trace.patch create mode 100644 32on64-vcpuop.patch create mode 100644 32on64-xenoprof.patch create mode 100644 blktools-bimodal.diff create mode 100644 bridge-hostonly.diff create mode 100644 bug.patch create mode 100644 cross-build-fix.diff create mode 100644 domheap-no-dma.patch create mode 100644 emul-privop-lock.patch create mode 100644 fbback-bimodal.diff create mode 100644 hide-asm-labels.patch create mode 100644 libelf-add-to-xenkernel.diff create mode 100644 libelf-symlink-to-libxc.diff create mode 100644 libelf-use-hvm-build.diff create mode 100644 libelf-use-readnotes.diff create mode 100644 libelf-use-xen-dom0.diff create mode 100644 libxc-logging.diff create mode 100644 mem-zones.patch create mode 100644 microcode-xen-13079.diff delete mode 100644 mk-xen-rescue-img.sh delete mode 100644 non-flat-pm.patch create mode 100644 npt-fpu-bug.patch create mode 100644 npt-windows-bug.patch create mode 100644 npt_part1.patch create mode 100644 npt_part2.patch create mode 100644 pae-guest-linear-pgtable.patch create mode 100644 protocol-bimodal.diff create mode 100644 pv-driver-build.patch create mode 100644 suppress-rdtscp.patch create mode 100644 svm-update-v_tpr-on-mmio.patch create mode 100644 svm_cpuid_ffxsr_13743.patch create mode 100644 tools-add-errors.diff create mode 100644 tools-debug-oldbuilder.diff create mode 100644 tools-domain-builder-core.diff create mode 100644 tools-domain-builder-header-libxc.diff create mode 100644 tools-domain-builder-linux.diff create mode 100644 tools-kboot.diff create mode 100644 tools-readnotes-gunzip.diff create mode 100644 tools-xc_kexec.diff create mode 100644 vgacon-50-lines.patch create mode 100644 vgacon-keep.patch create mode 100644 x86-extra-trap-info.patch create mode 100644 x86-mm-simplify.patch create mode 100644 x86-ptwr_emulate.patch create mode 100644 x86_emulate.patch delete mode 100644 xen-3.0.3-testing-src.tar.bz2 create mode 100644 xen-3.0.4-testing-src.tar.bz2 create mode 100644 xen-bootloader-dryrun.diff create mode 100644 xen-bootloader-nohang.diff create mode 100644 xen-bootloader-tidy.diff create mode 100644 xen-config.diff delete mode 100644 xen-console.diff delete mode 100644 xen-docs.diff delete mode 100644 xen-domUloader-pygrub.diff create mode 100644 xen-generate-foreign-headers.diff delete mode 100644 xen-io-register-context.diff delete mode 100644 xen-keymap.diff create mode 100644 xen-localtime.patch delete mode 100644 xen-poweroff.diff delete mode 100644 xen-pvfb-2.patch delete mode 100644 xen-pvfb-3.patch delete mode 100644 xen-python25-warnings.diff create mode 100644 xen-vm-install.diff create mode 100644 xen-vm-install.tar.bz2 create mode 100644 xend-config-devname.patch create mode 100644 xend-config-ramdisk.patch rename xen-config-defaults.diff => xend-config.diff (52%) create mode 100644 xm-test-cleanup.diff create mode 100644 xmclone.sh delete mode 100644 xmexample.rescue delete mode 100644 xu-11841-svm-interrupt-delivery.diff delete mode 100644 xu-11842-svm-interrupt-delivery.diff delete mode 100644 xu-11843-svm-no-double-nmi.diff delete mode 100644 xu-11847-pv-hvm.diff delete mode 100644 xu-11888-pv-hvm.diff delete mode 100644 xu-11896-pv-hvm.diff delete mode 100644 xu-11897-pv-hvm.diff delete mode 100644 xu-11898-pv-hvm.diff delete mode 100644 xu-11899-pv-hvm.diff delete mode 100644 xu-11900-pv-hvm.diff delete mode 100644 xu-11901-pv-hvm.diff delete mode 100644 xu-11902-pv-hvm.diff delete mode 100644 xu-11903-pv-hvm.diff delete mode 100644 xu-11904-pv-hvm.diff delete mode 100644 xu-11905-pv-hvm.diff delete mode 100644 xu-11906-pv-hvm.diff delete mode 100644 xu-11907-pv-hvm.diff delete mode 100644 xu-11908-pv-hvm.diff delete mode 100644 xu-11909-pv-hvm.diff delete mode 100644 xu-11910-pv-hvm.diff delete mode 100644 xu-11911-pv-hvm.diff delete mode 100644 xu-11912-pv-hvm.diff delete mode 100644 xu-11913-pv-hvm.diff delete mode 100644 xu-11914-pv-hvm.diff delete mode 100644 xu-11915-pv-hvm.diff delete mode 100644 xu-11916-pv-hvm.diff delete mode 100644 xu-11917-pv-hvm.diff delete mode 100644 xu-11918-pv-hvm.diff delete mode 100644 xu-11974-pv-hvm.diff delete mode 100644 xu-12012-hvm-smp-timer.diff delete mode 100644 xu-12013-hvm-ioapic.diff delete mode 100644 xu-12030-pv-hvm.diff delete mode 100644 xu-12031-pv-hvm.diff delete mode 100644 xu-12032-pv-hvm.diff delete mode 100644 xu-12040-pv-spurious-interrupt.diff delete mode 100644 xu-12205-pv-hvm.diff delete mode 100644 xu-12278-hvm-interrupt-race.diff create mode 100644 xxx_heap_pages-static.patch diff --git a/32on64-acmop.patch b/32on64-acmop.patch new file mode 100644 index 0000000..ec496b2 --- /dev/null +++ b/32on64-acmop.patch @@ -0,0 +1,147 @@ +Enable compatibility mode operation for HYPERVISOR_acm_op. + +Index: 2007-01-08/xen/arch/x86/x86_64/compat/entry.S +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:20:00.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:20:01.000000000 +0100 +@@ -278,7 +278,6 @@ CFIX14: + + .section .rodata, "a", @progbits + +-#define compat_acm_op domain_crash_synchronous + #define compat_xenoprof_op domain_crash_synchronous + #define compat_sysctl domain_crash_synchronous + #define compat_domctl domain_crash_synchronous +Index: 2007-01-08/xen/common/Makefile +=================================================================== +--- 2007-01-08.orig/xen/common/Makefile 2007-01-08 15:19:22.000000000 +0100 ++++ 2007-01-08/xen/common/Makefile 2007-01-08 15:20:01.000000000 +0100 +@@ -42,6 +42,7 @@ version.o: $(BASEDIR)/include/xen/compil + + ifeq ($(CONFIG_COMPAT),y) + # extra dependencies ++acm_ops.o: compat/acm_ops.c + grant_table.o: compat/grant_table.c + schedule.o: compat/schedule.c + endif +Index: 2007-01-08/xen/common/acm_ops.c +=================================================================== +--- 2007-01-08.orig/xen/common/acm_ops.c 2007-01-08 15:04:23.000000000 +0100 ++++ 2007-01-08/xen/common/acm_ops.c 2007-01-08 15:20:01.000000000 +0100 +@@ -15,6 +15,7 @@ + * + */ + ++#ifndef COMPAT + #include + #include + #include +@@ -28,6 +29,10 @@ + #include + #include + ++typedef long ret_t; ++ ++#endif /* !COMPAT */ ++ + #ifndef ACM_SECURITY + + +@@ -40,6 +45,7 @@ long do_acm_op(int cmd, XEN_GUEST_HANDLE + #else + + ++#ifndef COMPAT + int acm_authorize_acm_ops(struct domain *d) + { + /* currently, policy management functions are restricted to privileged domains */ +@@ -47,11 +53,12 @@ int acm_authorize_acm_ops(struct domain + return -EPERM; + return 0; + } ++#endif + + +-long do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg) ++ret_t do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg) + { +- long rc = -EFAULT; ++ ret_t rc = -EFAULT; + + if (acm_authorize_acm_ops(current->domain)) + return -EPERM; +@@ -219,6 +226,10 @@ long do_acm_op(int cmd, XEN_GUEST_HANDLE + + #endif + ++#if defined(CONFIG_COMPAT) && !defined(COMPAT) ++#include "compat/acm_ops.c" ++#endif ++ + /* + * Local variables: + * mode: C +Index: 2007-01-08/xen/common/compat/acm_ops.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-08/xen/common/compat/acm_ops.c 2007-01-08 15:20:01.000000000 +0100 +@@ -0,0 +1,47 @@ ++/****************************************************************************** ++ * compat/acm_ops.c ++ */ ++ ++#include ++#include ++ ++#define COMPAT ++#define ret_t int ++ ++#define do_acm_op compat_acm_op ++ ++static inline XEN_GUEST_HANDLE(void) acm_xlat_handle(COMPAT_HANDLE(void) cmp) ++{ ++ XEN_GUEST_HANDLE(void) nat; ++ ++ guest_from_compat_handle(nat, cmp); ++ return nat; ++} ++ ++#define acm_setpolicy compat_acm_setpolicy ++#define acm_set_policy(h, sz) acm_set_policy(acm_xlat_handle(h), sz) ++ ++#define acm_getpolicy compat_acm_getpolicy ++#define acm_get_policy(h, sz) acm_get_policy(acm_xlat_handle(h), sz) ++ ++#define acm_dumpstats compat_acm_dumpstats ++#define acm_dump_statistics(h, sz) acm_dump_statistics(acm_xlat_handle(h), sz) ++ ++#define acm_getssid compat_acm_getssid ++#define acm_get_ssid(r, h, sz) acm_get_ssid(r, acm_xlat_handle(h), sz) ++ ++#define xen_acm_getdecision acm_getdecision ++CHECK_acm_getdecision; ++#undef xen_acm_getdecision ++ ++#include "../acm_ops.c" ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * tab-width: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ +Index: 2007-01-08/xen/include/xlat.lst +=================================================================== +--- 2007-01-08.orig/xen/include/xlat.lst 2007-01-08 15:19:22.000000000 +0100 ++++ 2007-01-08/xen/include/xlat.lst 2007-01-08 15:20:24.000000000 +0100 +@@ -9,6 +9,7 @@ + ! cpu_user_regs arch-@arch@/xen-@subarch@.h + ! trap_info arch-@arch@/xen.h + ! vcpu_guest_context arch-@arch@/xen.h ++? acm_getdecision acm_ops.h + ? evtchn_alloc_unbound event_channel.h + ? evtchn_bind_interdomain event_channel.h + ? evtchn_bind_ipi event_channel.h diff --git a/32on64-base.patch b/32on64-base.patch new file mode 100644 index 0000000..bc4695f --- /dev/null +++ b/32on64-base.patch @@ -0,0 +1,1058 @@ +Introduce _DOMF_compat and infrastructure as well as several conditionals +dealing with operations that need to distinguish between native and +compatibility mode guests. + +Index: 2007-01-08/config/x86_64.mk +=================================================================== +--- 2007-01-08.orig/config/x86_64.mk 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/config/x86_64.mk 2007-01-08 14:45:40.000000000 +0100 +@@ -2,6 +2,7 @@ CONFIG_X86 := y + CONFIG_X86_64 := y + CONFIG_X86_$(XEN_OS) := y + ++CONFIG_COMPAT := y + CONFIG_HVM := y + CONFIG_MIGRATE := y + CONFIG_XCUTILS := y +Index: 2007-01-08/tools/libxc/xc_linux_build.c +=================================================================== +--- 2007-01-08.orig/tools/libxc/xc_linux_build.c 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/tools/libxc/xc_linux_build.c 2007-01-08 14:45:40.000000000 +0100 +@@ -595,6 +595,7 @@ static int compat_check(int xc_handle, s + return 0; + } + ++#ifndef __x86_64__//temp + if (strstr(xen_caps, "xen-3.0-x86_32p")) { + if (dsi->pae_kernel == PAEKERN_bimodal) { + dsi->pae_kernel = PAEKERN_extended_cr3; +@@ -612,6 +613,7 @@ static int compat_check(int xc_handle, s + return 0; + } + } ++#endif + + return 1; + } +Index: 2007-01-08/xen/arch/x86/boot/x86_64.S +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/boot/x86_64.S 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/boot/x86_64.S 2007-01-08 14:45:40.000000000 +0100 +@@ -226,15 +226,34 @@ high_start: + .align PAGE_SIZE, 0 + ENTRY(gdt_table) + .quad 0x0000000000000000 /* unused */ +- .quad 0x00cf9a000000ffff /* 0xe008 ring 0 code, compatibility */ +- .quad 0x00af9a000000ffff /* 0xe010 ring 0 code, 64-bit mode */ +- .quad 0x00cf92000000ffff /* 0xe018 ring 0 data */ ++ .quad 0x00af9a000000ffff /* 0xe008 ring 0 code, 64-bit mode */ ++ .quad 0x00cf92000000ffff /* 0xe010 ring 0 data */ ++ .quad 0x0000000000000000 /* reserved */ + .quad 0x00cffa000000ffff /* 0xe023 ring 3 code, compatibility */ + .quad 0x00cff2000000ffff /* 0xe02b ring 3 data */ + .quad 0x00affa000000ffff /* 0xe033 ring 3 code, 64-bit mode */ +- .quad 0x0000000000000000 /* unused */ ++ .quad 0x00cf9a000000ffff /* 0xe038 ring 0 code, compatibility */ ++ .org gdt_table - FIRST_RESERVED_GDT_BYTE + __TSS(0) * 8 + .fill 4*NR_CPUS,8,0 /* space for TSS and LDT per CPU */ + ++#ifdef CONFIG_COMPAT ++ .align PAGE_SIZE, 0 ++/* NB. Even rings != 0 get access to the full 4Gb, as only the */ ++/* (compatibility) machine->physical mapping table lives there. */ ++ENTRY(compat_gdt_table) ++ .quad 0x0000000000000000 /* unused */ ++ .quad 0x00af9a000000ffff /* 0xe008 ring 0 code, 64-bit mode */ ++ .quad 0x00cf92000000ffff /* 0xe010 ring 0 data */ ++ .quad 0x00cfba000000ffff /* 0xe019 ring 1 code, compatibility */ ++ .quad 0x00cfb2000000ffff /* 0xe021 ring 1 data */ ++ .quad 0x00cffa000000ffff /* 0xe02b ring 3 code, compatibility */ ++ .quad 0x00cff2000000ffff /* 0xe033 ring 3 data */ ++ .quad 0x00cf9a000000ffff /* 0xe038 ring 0 code, compatibility */ ++ .org compat_gdt_table - FIRST_RESERVED_GDT_BYTE + __TSS(0) * 8 ++ .fill 4*NR_CPUS,8,0 /* space for TSS and LDT per CPU */ ++# undef LIMIT ++#endif ++ + /* Initial PML4 -- level-4 page table. */ + .align PAGE_SIZE, 0 + ENTRY(idle_pg_table) +Index: 2007-01-08/xen/arch/x86/domain.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/domain.c 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/domain.c 2007-01-08 14:45:40.000000000 +0100 +@@ -287,17 +287,18 @@ int arch_set_info_guest( + + if ( !is_hvm_vcpu(v) ) + { +- fixup_guest_stack_selector(c->user_regs.ss); +- fixup_guest_stack_selector(c->kernel_ss); +- fixup_guest_code_selector(c->user_regs.cs); +- +-#ifdef __i386__ +- fixup_guest_code_selector(c->event_callback_cs); +- fixup_guest_code_selector(c->failsafe_callback_cs); +-#endif ++ fixup_guest_stack_selector(d, c->user_regs.ss); ++ fixup_guest_stack_selector(d, c->kernel_ss); ++ fixup_guest_code_selector(d, c->user_regs.cs); ++ ++ if ( CONFIG_PAGING_LEVELS < 4 || IS_COMPAT(d) ) ++ { ++ fixup_guest_code_selector(d, c->event_callback_cs); ++ fixup_guest_code_selector(d, c->failsafe_callback_cs); ++ } + + for ( i = 0; i < 256; i++ ) +- fixup_guest_code_selector(c->trap_ctxt[i].cs); ++ fixup_guest_code_selector(d, c->trap_ctxt[i].cs); + + /* LDT safety checks. */ + if ( ((c->ldt_base & (PAGE_SIZE-1)) != 0) || +@@ -502,27 +503,30 @@ static void load_segments(struct vcpu *n + all_segs_okay &= loadsegment(gs, nctxt->user_regs.gs); + } + +- /* This can only be non-zero if selector is NULL. */ +- if ( nctxt->fs_base ) +- wrmsr(MSR_FS_BASE, +- nctxt->fs_base, +- nctxt->fs_base>>32); +- +- /* Most kernels have non-zero GS base, so don't bother testing. */ +- /* (This is also a serialising instruction, avoiding AMD erratum #88.) */ +- wrmsr(MSR_SHADOW_GS_BASE, +- nctxt->gs_base_kernel, +- nctxt->gs_base_kernel>>32); +- +- /* This can only be non-zero if selector is NULL. */ +- if ( nctxt->gs_base_user ) +- wrmsr(MSR_GS_BASE, +- nctxt->gs_base_user, +- nctxt->gs_base_user>>32); +- +- /* If in kernel mode then switch the GS bases around. */ +- if ( n->arch.flags & TF_kernel_mode ) +- __asm__ __volatile__ ( "swapgs" ); ++ if ( !IS_COMPAT(n->domain) ) ++ { ++ /* This can only be non-zero if selector is NULL. */ ++ if ( nctxt->fs_base ) ++ wrmsr(MSR_FS_BASE, ++ nctxt->fs_base, ++ nctxt->fs_base>>32); ++ ++ /* Most kernels have non-zero GS base, so don't bother testing. */ ++ /* (This is also a serialising instruction, avoiding AMD erratum #88.) */ ++ wrmsr(MSR_SHADOW_GS_BASE, ++ nctxt->gs_base_kernel, ++ nctxt->gs_base_kernel>>32); ++ ++ /* This can only be non-zero if selector is NULL. */ ++ if ( nctxt->gs_base_user ) ++ wrmsr(MSR_GS_BASE, ++ nctxt->gs_base_user, ++ nctxt->gs_base_user>>32); ++ ++ /* If in kernel mode then switch the GS bases around. */ ++ if ( (n->arch.flags & TF_kernel_mode) ) ++ __asm__ __volatile__ ( "swapgs" ); ++ } + + if ( unlikely(!all_segs_okay) ) + { +@@ -533,6 +537,55 @@ static void load_segments(struct vcpu *n + (unsigned long *)nctxt->kernel_sp; + unsigned long cs_and_mask, rflags; + ++ if ( IS_COMPAT(n->domain) ) ++ { ++ unsigned int *esp = ring_1(regs) ? ++ (unsigned int *)regs->rsp : ++ (unsigned int *)nctxt->kernel_sp; ++ unsigned int cs_and_mask, eflags; ++ int ret = 0; ++ ++ /* CS longword also contains full evtchn_upcall_mask. */ ++ cs_and_mask = (unsigned short)regs->cs | ++ ((unsigned int)n->vcpu_info->evtchn_upcall_mask << 16); ++ /* Fold upcall mask into RFLAGS.IF. */ ++ eflags = regs->_eflags & ~X86_EFLAGS_IF; ++ eflags |= !n->vcpu_info->evtchn_upcall_mask << 9; ++ ++ if ( !ring_1(regs) ) ++ { ++ ret = put_user(regs->ss, esp-1); ++ ret |= put_user(regs->_esp, esp-2); ++ esp -= 2; ++ } ++ ++ if ( ret | ++ put_user(eflags, esp-1) | ++ put_user(cs_and_mask, esp-2) | ++ put_user(regs->_eip, esp-3) | ++ put_user(nctxt->user_regs.gs, esp-4) | ++ put_user(nctxt->user_regs.fs, esp-5) | ++ put_user(nctxt->user_regs.es, esp-6) | ++ put_user(nctxt->user_regs.ds, esp-7) ) ++ { ++ gdprintk(XENLOG_ERR, "Error while creating compat " ++ "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->_eflags &= 0xFFFCBEFFUL; ++ regs->ss = FLAT_COMPAT_KERNEL_SS; ++ regs->_esp = (unsigned long)(esp-7); ++ regs->cs = FLAT_COMPAT_KERNEL_CS; ++ regs->_eip = nctxt->failsafe_callback_eip; ++ return; ++ } ++ + if ( !(n->arch.flags & TF_kernel_mode) ) + toggle_guest_mode(n); + else +@@ -594,7 +647,7 @@ static void save_segments(struct vcpu *v + if ( regs->es ) + dirty_segment_mask |= DIRTY_ES; + +- if ( regs->fs ) ++ if ( regs->fs || IS_COMPAT(v->domain) ) + { + dirty_segment_mask |= DIRTY_FS; + ctxt->fs_base = 0; /* != 0 selector kills fs_base */ +@@ -604,7 +657,7 @@ static void save_segments(struct vcpu *v + dirty_segment_mask |= DIRTY_FS_BASE; + } + +- if ( regs->gs ) ++ if ( regs->gs || IS_COMPAT(v->domain) ) + { + dirty_segment_mask |= DIRTY_GS; + ctxt->gs_base_user = 0; /* != 0 selector kills gs_base_user */ +@@ -736,6 +789,23 @@ void context_switch(struct vcpu *prev, s + { + __context_switch(); + ++#ifdef CONFIG_COMPAT ++ if ( is_idle_vcpu(prev) ++ || IS_COMPAT(prev->domain) != IS_COMPAT(next->domain) ) ++ { ++ uint32_t efer_lo, efer_hi; ++ ++ local_flush_tlb_one(GDT_VIRT_START(next) + FIRST_RESERVED_GDT_BYTE); ++ ++ rdmsr(MSR_EFER, efer_lo, efer_hi); ++ if ( !IS_COMPAT(next->domain) == !(efer_lo & EFER_SCE) ) ++ { ++ efer_lo ^= EFER_SCE; ++ wrmsr(MSR_EFER, efer_lo, efer_hi); ++ } ++ } ++#endif ++ + /* Re-enable interrupts before restoring state which may fault. */ + local_irq_enable(); + +@@ -948,6 +1018,10 @@ void domain_relinquish_resources(struct + put_page(mfn_to_page(pfn)); + else + put_page_and_type(mfn_to_page(pfn)); ++#ifdef __x86_64__ ++ if ( pfn == pagetable_get_pfn(v->arch.guest_table_user) ) ++ v->arch.guest_table_user = pagetable_null(); ++#endif + v->arch.guest_table = pagetable_null(); + } + +Index: 2007-01-08/xen/arch/x86/domain_build.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/domain_build.c 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/domain_build.c 2007-01-08 15:34:55.000000000 +0100 +@@ -319,10 +319,38 @@ int construct_dom0(struct domain *d, + + nr_pages = compute_dom0_nr_pages(); + +- if ( (rc = parseelfimage(&dsi)) != 0 ) +- return rc; ++ rc = parseelfimage(&dsi); ++#ifdef CONFIG_COMPAT ++ if ( rc == -ENOSYS ++ && (rc = parseelf32image(&dsi)) == 0 ) ++ { ++ l1_pgentry_t gdt_l1e; ++ ++ set_bit(_DOMF_compat, &d->domain_flags); ++ ++ if ( nr_pages != (unsigned int)nr_pages ) ++ nr_pages = UINT_MAX; ++ ++ /* ++ * Map compatibility Xen segments into every VCPU's GDT. See ++ * arch_domain_create() for further comments. ++ */ ++ gdt_l1e = l1e_from_page(virt_to_page(compat_gdt_table), ++ PAGE_HYPERVISOR); ++ for ( i = 0; i < MAX_VIRT_CPUS; i++ ) ++ d->arch.mm_perdomain_pt[((i << GDT_LDT_VCPU_SHIFT) + ++ FIRST_RESERVED_GDT_PAGE)] = gdt_l1e; ++ local_flush_tlb_one(GDT_LDT_VIRT_START + FIRST_RESERVED_GDT_BYTE); ++ } ++#endif ++ if ( rc != 0) ++ { ++ if ( rc == -ENOSYS ) ++ printk("DOM0 image is not a Xen-compatible Elf image.\n"); ++ return rc; ++ } + +- xen_pae = (CONFIG_PAGING_LEVELS == 3); ++ xen_pae = (CONFIG_PAGING_LEVELS == 3) || IS_COMPAT(d); + if (dsi.pae_kernel == PAEKERN_bimodal) + dom0_pae = xen_pae; + else +@@ -338,7 +366,13 @@ int construct_dom0(struct domain *d, + dsi.pae_kernel == PAEKERN_bimodal) ) + set_bit(VMASST_TYPE_pae_extended_cr3, &d->vm_assist); + +- if ( (p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES)) != NULL ) ++#ifdef CONFIG_COMPAT ++ if ( IS_COMPAT(d) ) ++ p = xen_elf32note_string(&dsi, XEN_ELFNOTE_FEATURES); ++ else ++#endif ++ p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES); ++ if ( p != NULL ) + { + parse_features(p, + dom0_features_supported, +@@ -590,6 +624,12 @@ int construct_dom0(struct domain *d, + return -EINVAL; + } + ++ if ( IS_COMPAT(d) ) ++ { ++ v->arch.guest_context.failsafe_callback_cs = FLAT_COMPAT_KERNEL_CS; ++ v->arch.guest_context.event_callback_cs = FLAT_COMPAT_KERNEL_CS; ++ } ++ + /* WARNING: The new domain must have its 'processor' field filled in! */ + maddr_to_page(mpt_alloc)->u.inuse.type_info = PGT_l4_page_table; + l4start = l4tab = __va(mpt_alloc); mpt_alloc += PAGE_SIZE; +@@ -599,6 +639,8 @@ int construct_dom0(struct domain *d, + l4tab[l4_table_offset(PERDOMAIN_VIRT_START)] = + l4e_from_paddr(__pa(d->arch.mm_perdomain_l3), __PAGE_HYPERVISOR); + v->arch.guest_table = pagetable_from_paddr(__pa(l4start)); ++ if ( IS_COMPAT(d) ) ++ v->arch.guest_table_user = v->arch.guest_table; + + l4tab += l4_table_offset(dsi.v_start); + mfn = alloc_spfn; +@@ -711,10 +753,20 @@ int construct_dom0(struct domain *d, + write_ptbase(v); + + /* Copy the OS image and free temporary buffer. */ +- (void)loadelfimage(&dsi); +- +- hypercall_page = +- xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &hypercall_page_defined); ++#ifdef CONFIG_COMPAT ++ if ( IS_COMPAT(d) ) ++ { ++ (void)loadelf32image(&dsi); ++ hypercall_page = ++ xen_elf32note_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &hypercall_page_defined); ++ } ++ else ++#endif ++ { ++ (void)loadelfimage(&dsi); ++ hypercall_page = ++ xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &hypercall_page_defined); ++ } + if ( hypercall_page_defined ) + { + if ( (hypercall_page < dsi.v_start) || (hypercall_page >= v_end) ) +@@ -747,7 +799,7 @@ int construct_dom0(struct domain *d, + si->mfn_list = vphysmap_start; + sprintf(si->magic, "xen-%i.%i-x86_%d%s", + xen_major_version(), xen_minor_version(), +- BITS_PER_LONG, xen_pae ? "p" : ""); ++ !IS_COMPAT(d) ? BITS_PER_LONG : 32, xen_pae ? "p" : ""); + + /* Write the phys->machine and machine->phys table entries. */ + for ( pfn = 0; pfn < d->tot_pages; pfn++ ) +@@ -819,9 +871,11 @@ int construct_dom0(struct domain *d, + * [EAX,EBX,ECX,EDX,EDI,EBP are zero] + */ + regs = &v->arch.guest_context.user_regs; +- regs->ds = regs->es = regs->fs = regs->gs = FLAT_KERNEL_DS; +- regs->ss = FLAT_KERNEL_SS; +- regs->cs = FLAT_KERNEL_CS; ++ regs->ds = regs->es = regs->fs = regs->gs = !IS_COMPAT(d) ++ ? FLAT_KERNEL_DS ++ : FLAT_COMPAT_KERNEL_DS; ++ regs->ss = !IS_COMPAT(d) ? FLAT_KERNEL_SS : FLAT_COMPAT_KERNEL_SS; ++ regs->cs = !IS_COMPAT(d) ? FLAT_KERNEL_CS : FLAT_COMPAT_KERNEL_CS; + regs->eip = dsi.v_kernentry; + regs->esp = vstack_end; + regs->esi = vstartinfo_start; +@@ -906,13 +960,28 @@ int elf_sanity_check(const Elf_Ehdr *ehd + (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) || + (ehdr->e_type != ET_EXEC) ) + { +- printk("DOM0 image is not a Xen-compatible Elf image.\n"); + return 0; + } + + return 1; + } + ++#ifdef CONFIG_COMPAT ++int elf32_sanity_check(const Elf32_Ehdr *ehdr) ++{ ++ if ( !IS_ELF(*ehdr) || ++ (ehdr->e_ident[EI_CLASS] != ELFCLASS32) || ++ (ehdr->e_machine != EM_386) || ++ (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) || ++ (ehdr->e_type != ET_EXEC) ) ++ { ++ return 0; ++ } ++ ++ return 1; ++} ++#endif ++ + /* + * Local variables: + * mode: C +Index: 2007-01-08/xen/arch/x86/mm.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/mm.c 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/mm.c 2007-01-08 14:45:40.000000000 +0100 +@@ -401,7 +401,7 @@ static int alloc_segdesc_page(struct pag + descs = map_domain_page(page_to_mfn(page)); + + for ( i = 0; i < 512; i++ ) +- if ( unlikely(!check_descriptor(&descs[i])) ) ++ if ( unlikely(!check_descriptor(page_get_owner(page), &descs[i])) ) + goto fail; + + unmap_domain_page(descs); +@@ -2833,7 +2833,7 @@ long do_update_descriptor(u64 pa, u64 de + mfn = gmfn_to_mfn(dom, gmfn); + if ( (((unsigned int)pa % sizeof(struct desc_struct)) != 0) || + !mfn_valid(mfn) || +- !check_descriptor(&d) ) ++ !check_descriptor(dom, &d) ) + { + UNLOCK_BIGLOCK(dom); + return -EINVAL; +Index: 2007-01-08/xen/arch/x86/setup.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/setup.c 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/setup.c 2007-01-08 14:45:40.000000000 +0100 +@@ -791,6 +791,9 @@ void arch_get_xen_caps(xen_capabilities_ + #elif defined(CONFIG_X86_64) + + p += sprintf(p, "xen-%d.%d-x86_64 ", major, minor); ++#ifdef CONFIG_COMPAT ++ p += sprintf(p, "xen-%d.%d-x86_32p ", major, minor); ++#endif + if ( hvm_enabled ) + { + p += sprintf(p, "hvm-%d.%d-x86_32 ", major, minor); +Index: 2007-01-08/xen/arch/x86/traps.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/traps.c 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/traps.c 2007-01-08 14:45:40.000000000 +0100 +@@ -398,7 +398,7 @@ static int do_guest_trap( + if ( TI_GET_IF(ti) ) + tb->flags |= TBF_INTERRUPT; + +- if ( unlikely(null_trap_bounce(tb)) ) ++ if ( unlikely(null_trap_bounce(v, tb)) ) + gdprintk(XENLOG_WARNING, "Unhandled %s fault/trap [#%d] in " + "domain %d on VCPU %d [ec=%04x]\n", + trapstr(trapnr), trapnr, v->domain->domain_id, v->vcpu_id, +@@ -689,7 +689,7 @@ void propagate_page_fault(unsigned long + tb->eip = ti->address; + if ( TI_GET_IF(ti) ) + tb->flags |= TBF_INTERRUPT; +- if ( unlikely(null_trap_bounce(tb)) ) ++ if ( unlikely(null_trap_bounce(v, tb)) ) + { + printk("Unhandled page fault in domain %d on VCPU %d (ec=%04X)\n", + v->domain->domain_id, v->vcpu_id, error_code); +@@ -1801,6 +1801,13 @@ void set_tss_desc(unsigned int n, void * + (unsigned long)addr, + offsetof(struct tss_struct, __cacheline_filler) - 1, + 9); ++#ifdef CONFIG_COMPAT ++ _set_tssldt_desc( ++ compat_gdt_table + __TSS(n) - FIRST_RESERVED_GDT_ENTRY, ++ (unsigned long)addr, ++ offsetof(struct tss_struct, __cacheline_filler) - 1, ++ 11); ++#endif + } + + void __init trap_init(void) +@@ -1875,7 +1882,7 @@ long do_set_trap_table(XEN_GUEST_HANDLE( + if ( cur.address == 0 ) + break; + +- fixup_guest_code_selector(cur.cs); ++ fixup_guest_code_selector(current->domain, cur.cs); + + memcpy(&dst[cur.vector], &cur, sizeof(cur)); + +Index: 2007-01-08/xen/arch/x86/x86_32/mm.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_32/mm.c 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_32/mm.c 2007-01-08 14:45:40.000000000 +0100 +@@ -230,7 +230,7 @@ long do_stack_switch(unsigned long ss, u + int nr = smp_processor_id(); + struct tss_struct *t = &init_tss[nr]; + +- fixup_guest_stack_selector(ss); ++ fixup_guest_stack_selector(current->domain, ss); + + current->arch.guest_context.kernel_ss = ss; + current->arch.guest_context.kernel_sp = esp; +@@ -241,7 +241,7 @@ long do_stack_switch(unsigned long ss, u + } + + /* Returns TRUE if given descriptor is valid for GDT or LDT. */ +-int check_descriptor(struct desc_struct *d) ++int check_descriptor(const struct domain *dom, struct desc_struct *d) + { + unsigned long base, limit; + u32 a = d->a, b = d->b; +@@ -261,8 +261,8 @@ int check_descriptor(struct desc_struct + * gates (consider a call gate pointing at another kernel descriptor with + * DPL 0 -- this would get the OS ring-0 privileges). + */ +- if ( (b & _SEGMENT_DPL) < (GUEST_KERNEL_RPL << 13) ) +- d->b = b = (b & ~_SEGMENT_DPL) | (GUEST_KERNEL_RPL << 13); ++ if ( (b & _SEGMENT_DPL) < (GUEST_KERNEL_RPL(dom) << 13) ) ++ d->b = b = (b & ~_SEGMENT_DPL) | (GUEST_KERNEL_RPL(dom) << 13); + + if ( !(b & _SEGMENT_S) ) + { +@@ -284,8 +284,8 @@ int check_descriptor(struct desc_struct + + /* Validate and fix up the target code selector. */ + cs = a >> 16; +- fixup_guest_code_selector(cs); +- if ( !guest_gate_selector_okay(cs) ) ++ fixup_guest_code_selector(dom, cs); ++ if ( !guest_gate_selector_okay(dom, cs) ) + goto bad; + a = d->a = (d->a & 0xffffU) | (cs << 16); + +Index: 2007-01-08/xen/arch/x86/x86_32/traps.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_32/traps.c 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_32/traps.c 2007-01-08 14:45:40.000000000 +0100 +@@ -296,7 +296,7 @@ void init_int80_direct_trap(struct vcpu + * switch to the Xen stack and we need to swap back to the guest + * kernel stack before passing control to the system call entry point. + */ +- if ( TI_GET_IF(ti) || !guest_gate_selector_okay(ti->cs) || ++ if ( TI_GET_IF(ti) || !guest_gate_selector_okay(v->domain, ti->cs) || + supervisor_mode_kernel ) + { + v->arch.int80_desc.a = v->arch.int80_desc.b = 0; +@@ -326,7 +326,7 @@ static long register_guest_callback(stru + long ret = 0; + struct vcpu *v = current; + +- fixup_guest_code_selector(reg->address.cs); ++ fixup_guest_code_selector(v->domain, reg->address.cs); + + switch ( reg->type ) + { +Index: 2007-01-08/xen/arch/x86/x86_64/asm-offsets.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_64/asm-offsets.c 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_64/asm-offsets.c 2007-01-08 14:45:40.000000000 +0100 +@@ -58,12 +58,16 @@ void __dummy__(void) + OFFSET(VCPU_thread_flags, struct vcpu, arch.flags); + OFFSET(VCPU_event_addr, struct vcpu, + arch.guest_context.event_callback_eip); ++ OFFSET(VCPU_event_sel, struct vcpu, ++ arch.guest_context.event_callback_cs); + OFFSET(VCPU_failsafe_addr, struct vcpu, + arch.guest_context.failsafe_callback_eip); ++ OFFSET(VCPU_failsafe_sel, struct vcpu, ++ arch.guest_context.failsafe_callback_cs); + OFFSET(VCPU_syscall_addr, struct vcpu, + arch.guest_context.syscall_callback_eip); +- OFFSET(VCPU_kernel_sp, struct vcpu, +- arch.guest_context.kernel_sp); ++ OFFSET(VCPU_kernel_sp, struct vcpu, arch.guest_context.kernel_sp); ++ OFFSET(VCPU_kernel_ss, struct vcpu, arch.guest_context.kernel_ss); + OFFSET(VCPU_guest_context_flags, struct vcpu, arch.guest_context.flags); + OFFSET(VCPU_arch_guest_fpu_ctxt, struct vcpu, arch.guest_context.fpu_ctxt); + OFFSET(VCPU_flags, struct vcpu, vcpu_flags); +Index: 2007-01-08/xen/arch/x86/x86_64/mm.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_64/mm.c 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_64/mm.c 2007-01-08 14:45:40.000000000 +0100 +@@ -231,7 +231,7 @@ long subarch_memory_op(int op, XEN_GUEST + + long do_stack_switch(unsigned long ss, unsigned long esp) + { +- fixup_guest_stack_selector(ss); ++ fixup_guest_stack_selector(current->domain, ss); + current->arch.guest_context.kernel_ss = ss; + current->arch.guest_context.kernel_sp = esp; + return 0; +@@ -291,7 +291,7 @@ long do_set_segment_base(unsigned int wh + + + /* Returns TRUE if given descriptor is valid for GDT or LDT. */ +-int check_descriptor(struct desc_struct *d) ++int check_descriptor(const struct domain *dom, struct desc_struct *d) + { + u32 a = d->a, b = d->b; + u16 cs; +@@ -301,8 +301,8 @@ int check_descriptor(struct desc_struct + goto good; + + /* Check and fix up the DPL. */ +- if ( (b & _SEGMENT_DPL) < (GUEST_KERNEL_RPL << 13) ) +- d->b = b = (b & ~_SEGMENT_DPL) | (GUEST_KERNEL_RPL << 13); ++ if ( (b & _SEGMENT_DPL) < (GUEST_KERNEL_RPL(dom) << 13) ) ++ d->b = b = (b & ~_SEGMENT_DPL) | (GUEST_KERNEL_RPL(dom) << 13); + + /* All code and data segments are okay. No base/limit checking. */ + if ( (b & _SEGMENT_S) ) +@@ -318,8 +318,8 @@ int check_descriptor(struct desc_struct + + /* Validate and fix up the target code selector. */ + cs = a >> 16; +- fixup_guest_code_selector(cs); +- if ( !guest_gate_selector_okay(cs) ) ++ fixup_guest_code_selector(dom, cs); ++ if ( !guest_gate_selector_okay(dom, cs) ) + goto bad; + a = d->a = (d->a & 0xffffU) | (cs << 16); + +Index: 2007-01-08/xen/arch/x86/x86_64/traps.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_64/traps.c 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_64/traps.c 2007-01-08 14:45:40.000000000 +0100 +@@ -178,6 +178,8 @@ asmlinkage void do_double_fault(struct c + + void toggle_guest_mode(struct vcpu *v) + { ++ if ( IS_COMPAT(v->domain) ) ++ return; + v->arch.flags ^= TF_kernel_mode; + __asm__ __volatile__ ( "swapgs" ); + update_cr3(v); +Index: 2007-01-08/xen/common/Makefile +=================================================================== +--- 2007-01-08.orig/xen/common/Makefile 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/common/Makefile 2007-01-08 14:45:40.000000000 +0100 +@@ -3,6 +3,7 @@ obj-y += bitmap.o + obj-y += domctl.o + obj-y += domain.o + obj-y += elf.o ++obj-$(CONFIG_COMPAT) += elf32.o + obj-y += event_channel.o + obj-y += grant_table.o + obj-y += kernel.o +Index: 2007-01-08/xen/common/elf.c +=================================================================== +--- 2007-01-08.orig/xen/common/elf.c 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/common/elf.c 2007-01-08 14:45:40.000000000 +0100 +@@ -203,7 +203,7 @@ int parseelfimage(struct domain_setup_in + int h, virt_base_defined, elf_pa_off_defined, virt_entry_defined; + + if ( !elf_sanity_check(ehdr) ) +- return -EINVAL; ++ return -ENOSYS; + + if ( (ehdr->e_phoff + (ehdr->e_phnum*ehdr->e_phentsize)) > image_len ) + { +Index: 2007-01-08/xen/common/elf32.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-08/xen/common/elf32.c 2007-01-08 14:45:40.000000000 +0100 +@@ -0,0 +1,19 @@ ++/****************************************************************************** ++ * elf32.c ++ * ++ * Stub to support 32-bit ELF images on 64-bit platforms. ++ */ ++ ++#include ++#undef ELFSIZE ++#define ELFSIZE 32 ++#include ++#include ++ ++#define xen_elfnote_string xen_elf32note_string ++#define xen_elfnote_numeric xen_elf32note_numeric ++#define parseelfimage parseelf32image ++#define loadelfimage loadelf32image ++#define elf_sanity_check elf32_sanity_check ++ ++#include "elf.c" +Index: 2007-01-08/xen/include/asm-x86/config.h +=================================================================== +--- 2007-01-08.orig/xen/include/asm-x86/config.h 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/include/asm-x86/config.h 2007-01-08 14:45:40.000000000 +0100 +@@ -91,6 +91,7 @@ extern unsigned long _end; /* standard E + #if defined(__x86_64__) + + #define CONFIG_X86_64 1 ++#define CONFIG_COMPAT 1 + + #define asmlinkage + +@@ -185,13 +186,21 @@ extern unsigned long _end; /* standard E + #define DIRECTMAP_VIRT_START (PML4_ADDR(262)) + #define DIRECTMAP_VIRT_END (DIRECTMAP_VIRT_START + PML4_ENTRY_BYTES*2) + ++#define __HYPERVISOR_COMPAT_VIRT_START 0xF5800000 ++#define HYPERVISOR_COMPAT_VIRT_START \ ++ mk_unsigned_long(__HYPERVISOR_COMPAT_VIRT_START) ++#define MACH2PHYS_COMPAT_VIRT_START HYPERVISOR_COMPAT_VIRT_START ++#define MACH2PHYS_COMPAT_VIRT_END 0xFFE00000 ++#define MACH2PHYS_COMPAT_NR_ENTRIES \ ++ ((MACH2PHYS_COMPAT_VIRT_END-MACH2PHYS_COMPAT_VIRT_START)>>2) ++ + #define PGT_base_page_table PGT_l4_page_table + +-#define __HYPERVISOR_CS64 0xe010 +-#define __HYPERVISOR_CS32 0xe008 ++#define __HYPERVISOR_CS64 0xe008 ++#define __HYPERVISOR_CS32 0xe038 + #define __HYPERVISOR_CS __HYPERVISOR_CS64 + #define __HYPERVISOR_DS64 0x0000 +-#define __HYPERVISOR_DS32 0xe018 ++#define __HYPERVISOR_DS32 0xe010 + #define __HYPERVISOR_DS __HYPERVISOR_DS64 + + /* For generic assembly code: use macros to define operation/operand sizes. */ +Index: 2007-01-08/xen/include/asm-x86/desc.h +=================================================================== +--- 2007-01-08.orig/xen/include/asm-x86/desc.h 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/include/asm-x86/desc.h 2007-01-08 14:45:40.000000000 +0100 +@@ -18,31 +18,76 @@ + + #define LDT_ENTRY_SIZE 8 + ++#if defined(__x86_64__) ++ ++#define FLAT_COMPAT_RING1_CS 0xe019 /* GDT index 259 */ ++#define FLAT_COMPAT_RING1_DS 0xe021 /* GDT index 260 */ ++#define FLAT_COMPAT_RING1_SS 0xe021 /* GDT index 260 */ ++#define FLAT_COMPAT_RING3_CS 0xe02b /* GDT index 261 */ ++#define FLAT_COMPAT_RING3_DS 0xe033 /* GDT index 262 */ ++#define FLAT_COMPAT_RING3_SS 0xe033 /* GDT index 262 */ ++ ++#define FLAT_COMPAT_KERNEL_DS FLAT_COMPAT_RING1_DS ++#define FLAT_COMPAT_KERNEL_CS FLAT_COMPAT_RING1_CS ++#define FLAT_COMPAT_KERNEL_SS FLAT_COMPAT_RING1_SS ++#define FLAT_COMPAT_USER_DS FLAT_COMPAT_RING3_DS ++#define FLAT_COMPAT_USER_CS FLAT_COMPAT_RING3_CS ++#define FLAT_COMPAT_USER_SS FLAT_COMPAT_RING3_SS ++ ++#define __FIRST_TSS_ENTRY (FIRST_RESERVED_GDT_ENTRY + 8) ++#define __FIRST_LDT_ENTRY (__FIRST_TSS_ENTRY + 2) ++ ++#define __TSS(n) (((n)<<2) + __FIRST_TSS_ENTRY) ++#define __LDT(n) (((n)<<2) + __FIRST_LDT_ENTRY) ++ ++#elif defined(__i386__) ++ ++#define FLAT_COMPAT_KERNEL_CS FLAT_KERNEL_CS ++#define FLAT_COMPAT_KERNEL_DS FLAT_KERNEL_DS ++#define FLAT_COMPAT_KERNEL_SS FLAT_KERNEL_SS ++#define FLAT_COMPAT_USER_CS FLAT_USER_CS ++#define FLAT_COMPAT_USER_DS FLAT_USER_DS ++#define FLAT_COMPAT_USER_SS FLAT_USER_SS ++ ++#define __DOUBLEFAULT_TSS_ENTRY FIRST_RESERVED_GDT_ENTRY ++ ++#define __FIRST_TSS_ENTRY (FIRST_RESERVED_GDT_ENTRY + 8) ++#define __FIRST_LDT_ENTRY (__FIRST_TSS_ENTRY + 1) ++ ++#define __TSS(n) (((n)<<1) + __FIRST_TSS_ENTRY) ++#define __LDT(n) (((n)<<1) + __FIRST_LDT_ENTRY) ++ ++#endif ++ ++#ifndef __ASSEMBLY__ ++ + #define load_TR(n) __asm__ __volatile__ ("ltr %%ax" : : "a" (__TSS(n)<<3) ) + + #if defined(__x86_64__) +-#define GUEST_KERNEL_RPL 3 ++#define GUEST_KERNEL_RPL(d) (!IS_COMPAT(d) ? 3 : 1) + #elif defined(__i386__) +-#define GUEST_KERNEL_RPL 1 ++#define GUEST_KERNEL_RPL(d) ((void)(d), 1) + #endif + + /* Fix up the RPL of a guest segment selector. */ +-#define __fixup_guest_selector(sel) \ +- ((sel) = (((sel) & 3) >= GUEST_KERNEL_RPL) ? (sel) : \ +- (((sel) & ~3) | GUEST_KERNEL_RPL)) ++#define __fixup_guest_selector(d, sel) \ ++({ \ ++ uint16_t _rpl = GUEST_KERNEL_RPL(d); \ ++ (sel) = (((sel) & 3) >= _rpl) ? (sel) : (((sel) & ~3) | _rpl); \ ++}) + + /* Stack selectors don't need fixing up if the kernel runs in ring 0. */ + #ifdef CONFIG_X86_SUPERVISOR_MODE_KERNEL +-#define fixup_guest_stack_selector(ss) ((void)0) ++#define fixup_guest_stack_selector(d, ss) ((void)0) + #else +-#define fixup_guest_stack_selector(ss) __fixup_guest_selector(ss) ++#define fixup_guest_stack_selector(d, ss) __fixup_guest_selector(d, ss) + #endif + + /* + * Code selectors are always fixed up. It allows the Xen exit stub to detect + * return to guest context, even when the guest kernel runs in ring 0. + */ +-#define fixup_guest_code_selector(cs) __fixup_guest_selector(cs) ++#define fixup_guest_code_selector(d, cs) __fixup_guest_selector(d, cs) + + /* + * We need this function because enforcing the correct guest kernel RPL is +@@ -57,11 +102,15 @@ + * DPL < CPL then they'll be cleared automatically. If SS RPL or DPL differs + * from CS RPL then we'll #GP. + */ +-#define guest_gate_selector_okay(sel) \ ++#define guest_gate_selector_okay(d, sel) \ + ((((sel)>>3) < FIRST_RESERVED_GDT_ENTRY) || /* Guest seg? */ \ +- ((sel) == FLAT_KERNEL_CS) || /* Xen default seg? */ \ ++ ((sel) == (!IS_COMPAT(d) ? \ ++ FLAT_KERNEL_CS : /* Xen default seg? */ \ ++ FLAT_COMPAT_KERNEL_CS)) || /* Xen default compat seg? */ \ + ((sel) & 4)) /* LDT seg? */ + ++#endif /* __ASSEMBLY__ */ ++ + /* These are bitmasks for the high 32 bits of a descriptor table entry. */ + #define _SEGMENT_TYPE (15<< 8) + #define _SEGMENT_EC ( 1<<10) /* Expand-down or Conforming segment */ +@@ -81,12 +130,6 @@ struct desc_struct { + + #if defined(__x86_64__) + +-#define __FIRST_TSS_ENTRY (FIRST_RESERVED_GDT_ENTRY + 8) +-#define __FIRST_LDT_ENTRY (__FIRST_TSS_ENTRY + 2) +- +-#define __TSS(n) (((n)<<2) + __FIRST_TSS_ENTRY) +-#define __LDT(n) (((n)<<2) + __FIRST_LDT_ENTRY) +- + typedef struct { + u64 a, b; + } idt_entry_t; +@@ -118,14 +161,6 @@ do { + + #elif defined(__i386__) + +-#define __DOUBLEFAULT_TSS_ENTRY FIRST_RESERVED_GDT_ENTRY +- +-#define __FIRST_TSS_ENTRY (FIRST_RESERVED_GDT_ENTRY + 8) +-#define __FIRST_LDT_ENTRY (__FIRST_TSS_ENTRY + 1) +- +-#define __TSS(n) (((n)<<1) + __FIRST_TSS_ENTRY) +-#define __LDT(n) (((n)<<1) + __FIRST_LDT_ENTRY) +- + typedef struct desc_struct idt_entry_t; + + #define _set_gate(gate_addr,type,dpl,addr) \ +@@ -155,6 +190,11 @@ __asm__ __volatile__ ("movw %w3,0(%2)\n\ + #endif + + extern struct desc_struct gdt_table[]; ++#ifdef CONFIG_COMPAT ++extern struct desc_struct compat_gdt_table[]; ++#else ++# define compat_gdt_table gdt_table ++#endif + + struct Xgt_desc_struct { + unsigned short size; +Index: 2007-01-08/xen/include/asm-x86/ldt.h +=================================================================== +--- 2007-01-08.orig/xen/include/asm-x86/ldt.h 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/include/asm-x86/ldt.h 2007-01-08 14:45:40.000000000 +0100 +@@ -17,7 +17,8 @@ static inline void load_LDT(struct vcpu + else + { + cpu = smp_processor_id(); +- desc = gdt_table + __LDT(cpu) - FIRST_RESERVED_GDT_ENTRY; ++ desc = (!IS_COMPAT(v->domain) ? gdt_table : compat_gdt_table) ++ + __LDT(cpu) - FIRST_RESERVED_GDT_ENTRY; + _set_tssldt_desc(desc, LDT_VIRT_START(v), ents*8-1, 2); + __asm__ __volatile__ ( "lldt %%ax" : : "a" (__LDT(cpu)<<3) ); + } +Index: 2007-01-08/xen/include/asm-x86/mm.h +=================================================================== +--- 2007-01-08.orig/xen/include/asm-x86/mm.h 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/include/asm-x86/mm.h 2007-01-08 14:45:40.000000000 +0100 +@@ -244,7 +244,7 @@ unsigned long + pae_copy_root(struct vcpu *v, l3_pgentry_t *l3tab); + #endif /* CONFIG_PAGING_LEVELS == 3 */ + +-int check_descriptor(struct desc_struct *d); ++int check_descriptor(const struct domain *, struct desc_struct *d); + + /* + * The MPT (machine->physical mapping table) is an array of word-sized +Index: 2007-01-08/xen/include/asm-x86/regs.h +=================================================================== +--- 2007-01-08.orig/xen/include/asm-x86/regs.h 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/include/asm-x86/regs.h 2007-01-08 14:45:40.000000000 +0100 +@@ -38,7 +38,8 @@ enum EFLAGS { + ASSERT(diff < STACK_SIZE); \ + /* If a guest frame, it must be have guest privs (unless HVM guest). */ \ + /* We permit CS==0 which can come from an uninitialised trap entry. */ \ +- ASSERT((diff != 0) || vm86_mode(r) || ((r->cs&3) >= GUEST_KERNEL_RPL) || \ ++ ASSERT((diff != 0) || vm86_mode(r) || \ ++ ((r->cs&3) >= GUEST_KERNEL_RPL(current->domain)) || \ + (r->cs == 0) || is_hvm_vcpu(current)); \ + /* If not a guest frame, it must be a hypervisor frame. */ \ + ASSERT((diff == 0) || (!vm86_mode(r) && (r->cs == __HYPERVISOR_CS))); \ +Index: 2007-01-08/xen/include/asm-x86/x86_32/regs.h +=================================================================== +--- 2007-01-08.orig/xen/include/asm-x86/x86_32/regs.h 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/include/asm-x86/x86_32/regs.h 2007-01-08 14:45:40.000000000 +0100 +@@ -17,7 +17,7 @@ + ((dpl) >= (vm86_mode(r) ? 3 : ((r)->cs & 3))) + + /* Check for null trap callback handler: Is the selector null (0-3)? */ +-#define null_trap_bounce(tb) (((tb)->cs & ~3) == 0) ++#define null_trap_bounce(v, tb) (((tb)->cs & ~3) == 0) + + /* Number of bytes of on-stack execution state to be context-switched. */ + #define CTXT_SWITCH_STACK_BYTES (sizeof(struct cpu_user_regs)) +Index: 2007-01-08/xen/include/asm-x86/x86_64/regs.h +=================================================================== +--- 2007-01-08.orig/xen/include/asm-x86/x86_64/regs.h 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/include/asm-x86/x86_64/regs.h 2007-01-08 14:45:40.000000000 +0100 +@@ -11,13 +11,16 @@ + #define ring_3(r) (((r)->cs & 3) == 3) + + #define guest_kernel_mode(v, r) \ +- (ring_3(r) && ((v)->arch.flags & TF_kernel_mode)) ++ (!IS_COMPAT((v)->domain) ? \ ++ ring_3(r) && ((v)->arch.flags & TF_kernel_mode) : \ ++ ring_1(r)) + + #define permit_softint(dpl, v, r) \ + ((dpl) >= (guest_kernel_mode(v, r) ? 1 : 3)) + + /* Check for null trap callback handler: Is the EIP null? */ +-#define null_trap_bounce(tb) ((tb)->eip == 0) ++#define null_trap_bounce(v, tb) \ ++ (!IS_COMPAT((v)->domain) ? (tb)->eip == 0 : ((tb)->cs & ~3) == 0) + + /* Number of bytes of on-stack execution state to be context-switched. */ + /* NB. Segment registers and bases are not saved/restored on x86/64 stack. */ +Index: 2007-01-08/xen/include/public/arch-x86/xen.h +=================================================================== +--- 2007-01-08.orig/xen/include/public/arch-x86/xen.h 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/include/public/arch-x86/xen.h 2007-01-08 14:52:24.000000000 +0100 +@@ -141,8 +141,18 @@ struct vcpu_guest_context { + #else + unsigned long event_callback_eip; + unsigned long failsafe_callback_eip; ++#ifdef __XEN__ ++ union { ++ unsigned long syscall_callback_eip; ++ struct { ++ unsigned int event_callback_cs; /* compat CS of event cb */ ++ unsigned int failsafe_callback_cs; /* compat CS of failsafe cb */ ++ }; ++ }; ++#else + unsigned long syscall_callback_eip; + #endif ++#endif + unsigned long vm_assist; /* VMASST_TYPE_* bitmap */ + #ifdef __x86_64__ + /* Segment base addresses. */ +Index: 2007-01-08/xen/include/public/arch-x86/xen-x86_64.h +=================================================================== +--- 2007-01-08.orig/xen/include/public/arch-x86/xen-x86_64.h 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/include/public/arch-x86/xen-x86_64.h 2007-01-08 14:52:13.000000000 +0100 +@@ -141,7 +141,10 @@ struct iret_context { + + #ifdef __GNUC__ + /* Anonymous union includes both 32- and 64-bit names (e.g., eax/rax). */ +-#define __DECL_REG(name) union { uint64_t r ## name, e ## name; } ++#define __DECL_REG(name) union { \ ++ uint64_t r ## name, e ## name; \ ++ uint32_t _e ## name; \ ++} + #else + /* Non-gcc sources must always use the proper 64-bit name (e.g., rax). */ + #define __DECL_REG(name) uint64_t r ## name +Index: 2007-01-08/xen/include/xen/elf.h +=================================================================== +--- 2007-01-08.orig/xen/include/xen/elf.h 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/include/xen/elf.h 2007-01-08 14:47:11.000000000 +0100 +@@ -525,6 +525,15 @@ extern unsigned long long xen_elfnote_nu + int type, int *defined); + extern const char *xen_elfnote_string(struct domain_setup_info *dsi, int type); + ++#ifdef CONFIG_COMPAT ++extern int elf32_sanity_check(const Elf32_Ehdr *ehdr); ++extern int loadelf32image(struct domain_setup_info *); ++extern int parseelf32image(struct domain_setup_info *); ++extern unsigned long long xen_elf32note_numeric(struct domain_setup_info *, ++ int type, int *defined); ++extern const char *xen_elf32note_string(struct domain_setup_info *, int type); ++#endif ++ + #ifdef Elf_Ehdr + extern int elf_sanity_check(const Elf_Ehdr *ehdr); + #endif +Index: 2007-01-08/xen/include/xen/sched.h +=================================================================== +--- 2007-01-08.orig/xen/include/xen/sched.h 2007-01-08 15:34:30.000000000 +0100 ++++ 2007-01-08/xen/include/xen/sched.h 2007-01-08 14:45:40.000000000 +0100 +@@ -422,6 +422,9 @@ extern struct domain *domain_list; + /* Domain is paused by the hypervisor? */ + #define _DOMF_paused 5 + #define DOMF_paused (1UL<<_DOMF_paused) ++ /* Domain is a compatibility one? */ ++#define _DOMF_compat 6 ++#define DOMF_compat (1UL<<_DOMF_compat) + + static inline int vcpu_runnable(struct vcpu *v) + { +@@ -458,6 +461,13 @@ static inline void vcpu_unblock(struct v + + #define IS_PRIV(_d) ((_d)->is_privileged) + ++#ifdef CONFIG_COMPAT ++#define IS_COMPAT(_d) \ ++ (test_bit(_DOMF_compat, &(_d)->domain_flags)) ++#else ++#define IS_COMPAT(_d) 0 ++#endif ++ + #define VM_ASSIST(_d,_t) (test_bit((_t), &(_d)->vm_assist)) + + #define is_hvm_domain(d) ((d)->is_hvm) diff --git a/32on64-call-gates.patch b/32on64-call-gates.patch new file mode 100644 index 0000000..34fcfea --- /dev/null +++ b/32on64-call-gates.patch @@ -0,0 +1,484 @@ +Index: 2007-01-31/xen/arch/x86/traps.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/traps.c 2007-01-31 09:39:19.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/traps.c 2007-01-31 09:41:46.000000000 +0100 +@@ -1051,6 +1051,63 @@ static int read_descriptor(unsigned int + return 1; + } + ++#ifdef CONFIG_COMPAT/* XXX __x86_64__ */ ++static int read_gate_descriptor(unsigned int gate_sel, ++ const struct vcpu *v, ++ unsigned int *sel, ++ unsigned long *off, ++ unsigned int *ar) ++{ ++ struct desc_struct desc; ++ const struct desc_struct *pdesc; ++ ++ ++ pdesc = (const struct desc_struct *)(!(gate_sel & 4) ? ++ GDT_VIRT_START(v) : ++ LDT_VIRT_START(v)) ++ + (gate_sel >> 3); ++ if ( gate_sel < 4 || ++ (gate_sel >= FIRST_RESERVED_GDT_BYTE && !(gate_sel & 4)) || ++ __get_user(desc, pdesc) ) ++ return 0; ++ ++ *sel = (desc.a >> 16) & 0x0000fffc; ++ *off = (desc.a & 0x0000ffff) | (desc.b & 0xffff0000); ++ *ar = desc.b & 0x0000ffff; ++ /* ++ * check_descriptor() clears the DPL field and stores the ++ * guest requested DPL in the selector's RPL field. ++ */ ++ ASSERT(!(*ar & _SEGMENT_DPL)); ++ *ar |= (desc.a >> (16 - 13)) & _SEGMENT_DPL; ++ ++ if ( !IS_COMPAT(v->domain) ) ++ { ++ if ( (*ar & 0x1f00) != 0x0c00 || ++ (gate_sel >= FIRST_RESERVED_GDT_BYTE - 8 && !(gate_sel & 4)) || ++ __get_user(desc, pdesc + 1) || ++ (desc.b & 0x1f00) ) ++ return 0; ++ ++ *off |= (unsigned long)desc.a << 32; ++ return 1; ++ } ++ ++ switch ( *ar & 0x1f00 ) ++ { ++ case 0x0400: ++ *off &= 0xffff; ++ break; ++ case 0x0c00: ++ break; ++ default: ++ return 0; ++ } ++ ++ return 1; ++} ++#endif ++ + /* Has the guest requested sufficient permission for this I/O access? */ + static inline int guest_io_okay( + unsigned int port, unsigned int bytes, +@@ -1118,6 +1175,8 @@ unsigned long guest_to_host_gpr_switch(u + #define insn_fetch(type, base, eip, limit) \ + ({ unsigned long _rc, _ptr = (base) + (eip); \ + type _x; \ ++ if ( ad_default < 8 ) \ ++ _ptr = (unsigned int)_ptr; \ + if ( (limit) < sizeof(_x) - 1 || (eip) > (limit) - (sizeof(_x) - 1) ) \ + goto fail; \ + if ( (_rc = copy_from_user(&_x, (type *)_ptr, sizeof(_x))) != 0 ) \ +@@ -1714,6 +1773,336 @@ static int emulate_privileged_op(struct + return 0; + } + ++static inline int check_stack_limit(unsigned int ar, unsigned int limit, ++ unsigned int esp, unsigned int decr) ++{ ++ return esp - decr < esp - 1 && ++ (!(ar & _SEGMENT_EC) ? esp - 1 <= limit : esp - decr > limit); ++} ++ ++static int emulate_gate_op(struct cpu_user_regs *regs) ++{ ++#ifdef CONFIG_COMPAT/* XXX __x86_64__ */ ++ struct vcpu *v = current; ++ unsigned int sel, ar, dpl, nparm, opnd_sel; ++ unsigned int op_default, op_bytes, ad_default, ad_bytes; ++ unsigned long off, eip, opnd_off, base, limit; ++ int jump; ++ ++ /* Check whether this fault is due to the use of a call gate. */ ++ if ( !read_gate_descriptor(regs->error_code, v, &sel, &off, &ar) || ++ ((ar >> 13) & 3) < (regs->cs & 3) || ++ (ar & _SEGMENT_TYPE) != 0xc00 ) ++ return do_guest_trap(TRAP_gp_fault, regs, 1); ++ if ( !(ar & _SEGMENT_P) ) ++ return do_guest_trap(TRAP_no_segment, regs, 1); ++ dpl = (ar >> 13) & 3; ++ nparm = ar & 0x1f; ++ ++ /* ++ * Decode instruction (and perhaps operand) to determine RPL, ++ * whether this is a jump or a call, and the call return offset. ++ */ ++ if ( !read_descriptor(regs->cs, v, regs, &base, &limit, &ar, 0) || ++ !(ar & _SEGMENT_S) || ++ !(ar & _SEGMENT_P) || ++ !(ar & _SEGMENT_CODE) ) ++ return do_guest_trap(TRAP_gp_fault, regs, 1); ++ ++ op_bytes = op_default = ar & _SEGMENT_DB ? 4 : 2; ++ ad_default = ad_bytes = op_default; ++ opnd_sel = opnd_off = 0; ++ jump = -1; ++ for ( eip = regs->eip; eip - regs->_eip < 10; ) ++ { ++ switch ( insn_fetch(u8, base, eip, limit) ) ++ { ++ case 0x66: /* operand-size override */ ++ op_bytes = op_default ^ 6; /* switch between 2/4 bytes */ ++ continue; ++ case 0x67: /* address-size override */ ++ ad_bytes = ad_default != 4 ? 4 : 2; /* switch to 2/4 bytes */ ++ continue; ++ case 0x2e: /* CS override */ ++ opnd_sel = regs->cs; ++ ASSERT(opnd_sel); ++ continue; ++ case 0x3e: /* DS override */ ++ opnd_sel = read_sreg(regs, ds); ++ if ( !opnd_sel ) ++ opnd_sel = dpl; ++ continue; ++ case 0x26: /* ES override */ ++ opnd_sel = read_sreg(regs, es); ++ if ( !opnd_sel ) ++ opnd_sel = dpl; ++ continue; ++ case 0x64: /* FS override */ ++ opnd_sel = read_sreg(regs, fs); ++ if ( !opnd_sel ) ++ opnd_sel = dpl; ++ continue; ++ case 0x65: /* GS override */ ++ opnd_sel = read_sreg(regs, gs); ++ if ( !opnd_sel ) ++ opnd_sel = dpl; ++ continue; ++ case 0x36: /* SS override */ ++ opnd_sel = regs->ss; ++ if ( !opnd_sel ) ++ opnd_sel = dpl; ++ continue; ++ case 0xea: ++ ++jump; ++ /* FALLTHROUGH */ ++ case 0x9a: ++ ++jump; ++ opnd_sel = regs->cs; ++ opnd_off = eip; ++ ad_bytes = ad_default; ++ eip += op_bytes + 2; ++ break; ++ case 0xff: ++ { ++ unsigned int modrm; ++ ++ switch ( (modrm = insn_fetch(u8, base, eip, limit)) & 0xf8 ) ++ { ++ case 0x28: case 0x68: case 0xa8: ++ ++jump; ++ /* FALLTHROUGH */ ++ case 0x18: case 0x58: case 0x98: ++ ++jump; ++ if ( ad_bytes != 2 ) ++ { ++ if ( (modrm & 7) == 4 ) ++ { ++ unsigned int sib = insn_fetch(u8, base, eip, limit); ++ ++ modrm = (modrm & ~7) | (sib & 7); ++ if ( (sib >>= 3) != 4 ) ++ opnd_off = *(unsigned long *)decode_register(sib & 7, regs, 0); ++ opnd_off <<= sib >> 3; ++ } ++ if ( (modrm & 7) != 5 || (modrm & 0xc0) ) ++ opnd_off += *(unsigned long *)decode_register(modrm & 7, regs, 0); ++ else ++ modrm |= 0x87; ++ if ( !opnd_sel ) ++ { ++ switch ( modrm & 7 ) ++ { ++ default: ++ opnd_sel = read_sreg(regs, ds); ++ break; ++ case 4: case 5: ++ opnd_sel = regs->ss; ++ break; ++ } ++ } ++ } ++ else ++ { ++ switch ( modrm & 7 ) ++ { ++ case 0: case 1: case 7: ++ opnd_off = regs->ebx; ++ break; ++ case 6: ++ if ( !(modrm & 0xc0) ) ++ modrm |= 0x80; ++ else ++ case 2: case 3: ++ { ++ opnd_off = regs->ebp; ++ if ( !opnd_sel ) ++ opnd_sel = regs->ss; ++ } ++ break; ++ } ++ if ( !opnd_sel ) ++ opnd_sel = read_sreg(regs, ds); ++ switch ( modrm & 7 ) ++ { ++ case 0: case 2: case 4: ++ opnd_off += regs->esi; ++ break; ++ case 1: case 3: case 5: ++ opnd_off += regs->edi; ++ break; ++ } ++ } ++ switch ( modrm & 0xc0 ) ++ { ++ case 0x40: ++ opnd_off += insn_fetch(s8, base, eip, limit); ++ break; ++ case 0x80: ++ opnd_off += insn_fetch(s32, base, eip, limit); ++ break; ++ } ++ if ( ad_bytes == 4 ) ++ opnd_off = (unsigned int)opnd_off; ++ else if ( ad_bytes == 2 ) ++ opnd_off = (unsigned short)opnd_off; ++ break; ++ } ++ } ++ break; ++ } ++ break; ++ } ++ ++ if ( jump < 0 ) ++ { ++ fail: ++ return do_guest_trap(TRAP_gp_fault, regs, 1); ++ } ++ ++ if ( (opnd_sel != regs->cs && ++ !read_descriptor(opnd_sel, v, regs, &base, &limit, &ar, 0)) || ++ !(ar & _SEGMENT_S) || ++ !(ar & _SEGMENT_P) || ++ ((ar & _SEGMENT_CODE) && !(ar & _SEGMENT_WR)) ) ++ return do_guest_trap(TRAP_gp_fault, regs, 1); ++ ++ opnd_off += op_bytes; ++#define ad_default ad_bytes ++ opnd_sel = insn_fetch(u16, base, opnd_off, limit); ++#undef ad_default ++ ASSERT((opnd_sel & ~3) == regs->error_code); ++ if ( dpl < (opnd_sel & 3) ) ++ return do_guest_trap(TRAP_gp_fault, regs, 1); ++ ++ if ( !read_descriptor(sel, v, regs, &base, &limit, &ar, 0) || ++ !(ar & _SEGMENT_S) || ++ !(ar & _SEGMENT_CODE) || ++ (!jump || (ar & _SEGMENT_EC) ? ++ ((ar >> 13) & 3) > (regs->cs & 3) : ++ ((ar >> 13) & 3) != (regs->cs & 3)) ) ++ { ++ regs->error_code = sel; ++ return do_guest_trap(TRAP_gp_fault, regs, 1); ++ } ++ if ( !(ar & _SEGMENT_P) ) ++ { ++ regs->error_code = sel; ++ return do_guest_trap(TRAP_no_segment, regs, 1); ++ } ++ if ( off > limit ) ++ { ++ regs->error_code = 0; ++ return do_guest_trap(TRAP_gp_fault, regs, 1); ++ } ++ ++ if ( !jump ) ++ { ++ unsigned int ss, esp, *stkp; ++ int rc; ++#define push(item) do \ ++ { \ ++ --stkp; \ ++ esp -= 4; \ ++ rc = __put_user(item, stkp); \ ++ if ( rc ) \ ++ { \ ++ propagate_page_fault((unsigned long)(stkp + 1) - rc, \ ++ PFEC_write_access); \ ++ return 0; \ ++ } \ ++ } while ( 0 ) ++ ++ if ( ((ar >> 13) & 3) < (regs->cs & 3) ) ++ { ++ sel |= (ar >> 13) & 3; ++ /* Inner stack known only for kernel ring. */ ++ if ( (sel & 3) != GUEST_KERNEL_RPL(v->domain) ) ++ return do_guest_trap(TRAP_gp_fault, regs, 1); ++ esp = v->arch.guest_context.kernel_sp; ++ ss = v->arch.guest_context.kernel_ss; ++ if ( (ss & 3) != (sel & 3) || ++ !read_descriptor(ss, v, regs, &base, &limit, &ar, 0) || ++ ((ar >> 13) & 3) != (sel & 3) || ++ !(ar & _SEGMENT_S) || ++ (ar & _SEGMENT_CODE) || ++ !(ar & _SEGMENT_WR) ) ++ { ++ regs->error_code = ss & ~3; ++ return do_guest_trap(TRAP_invalid_tss, regs, 1); ++ } ++ if ( !(ar & _SEGMENT_P) || ++ !check_stack_limit(ar, limit, esp, (4 + nparm) * 4) ) ++ { ++ regs->error_code = ss & ~3; ++ return do_guest_trap(TRAP_stack_error, regs, 1); ++ } ++ stkp = (unsigned int *)(unsigned long)((unsigned int)base + esp); ++ if ( !compat_access_ok(stkp - 4 - nparm, (4 + nparm) * 4) ) ++ return do_guest_trap(TRAP_gp_fault, regs, 1); ++ push(regs->ss); ++ push(regs->esp); ++ if ( nparm ) ++ { ++ const unsigned int *ustkp; ++ ++ if ( !read_descriptor(regs->ss, v, regs, &base, &limit, &ar, 0) || ++ ((ar >> 13) & 3) != (regs->cs & 3) || ++ !(ar & _SEGMENT_S) || ++ (ar & _SEGMENT_CODE) || ++ !(ar & _SEGMENT_WR) || ++ !check_stack_limit(ar, limit, esp + nparm * 4, nparm * 4) ) ++ return do_guest_trap(TRAP_gp_fault, regs, 1); ++ ustkp = (unsigned int *)(unsigned long)((unsigned int)base + regs->_esp + nparm * 4); ++ if ( !compat_access_ok(ustkp - nparm, nparm * 4) ) ++ return do_guest_trap(TRAP_gp_fault, regs, 1); ++ do ++ { ++ unsigned int parm; ++ ++ --ustkp; ++ rc = __get_user(parm, ustkp); ++ if ( rc ) ++ { ++ propagate_page_fault((unsigned long)(ustkp + 1) - rc, 0); ++ return 0; ++ } ++ push(parm); ++ } while ( --nparm ); ++ } ++ } ++ else ++ { ++ sel |= (regs->cs & 3); ++ esp = regs->esp; ++ ss = regs->ss; ++ if ( !read_descriptor(ss, v, regs, &base, &limit, &ar, 0) || ++ ((ar >> 13) & 3) != (sel & 3) ) ++ return do_guest_trap(TRAP_gp_fault, regs, 1); ++ if ( !check_stack_limit(ar, limit, esp, 2 * 4) ) ++ { ++ regs->error_code = 0; ++ return do_guest_trap(TRAP_stack_error, regs, 1); ++ } ++ stkp = (unsigned int *)(unsigned long)((unsigned int)base + esp); ++ if ( !compat_access_ok(stkp - 2, 2 * 4) ) ++ return do_guest_trap(TRAP_gp_fault, regs, 1); ++ } ++ push(regs->cs); ++ push(eip); ++#undef push ++ regs->esp = esp; ++ regs->ss = ss; ++ } ++ else ++ sel |= (regs->cs & 3); ++ ++ regs->eip = off; ++ regs->cs = sel; ++#endif ++ ++ return 0; ++} ++ + asmlinkage int do_general_protection(struct cpu_user_regs *regs) + { + struct vcpu *v = current; +@@ -1759,6 +2148,8 @@ asmlinkage int do_general_protection(str + return do_guest_trap(vector, regs, 0); + } + } ++ else if ( IS_COMPAT(v->domain) && regs->error_code ) ++ return emulate_gate_op(regs); + + /* Emulate some simple privileged and I/O instructions. */ + if ( (regs->error_code == 0) && +Index: 2007-01-31/xen/arch/x86/x86_64/mm.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/x86_64/mm.c 2007-01-31 09:29:17.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/x86_64/mm.c 2007-01-31 09:41:46.000000000 +0100 +@@ -366,14 +366,16 @@ int check_descriptor(const struct domain + { + u32 a = d->a, b = d->b; + u16 cs; ++ unsigned int dpl; + + /* A not-present descriptor will always fault, so is safe. */ + if ( !(b & _SEGMENT_P) ) + goto good; + + /* Check and fix up the DPL. */ +- if ( (b & _SEGMENT_DPL) < (GUEST_KERNEL_RPL(dom) << 13) ) +- d->b = b = (b & ~_SEGMENT_DPL) | (GUEST_KERNEL_RPL(dom) << 13); ++ dpl = (b >> 13) & 3; ++ __fixup_guest_selector(dom, dpl); ++ b = (b & ~_SEGMENT_DPL) | (dpl << 13); + + /* All code and data segments are okay. No base/limit checking. */ + if ( (b & _SEGMENT_S) ) +@@ -391,18 +393,33 @@ int check_descriptor(const struct domain + if ( (b & _SEGMENT_TYPE) != 0xc00 ) + goto bad; + +- /* Validate and fix up the target code selector. */ ++ /* Validate the target code selector. */ + cs = a >> 16; +- fixup_guest_code_selector(dom, cs); + if ( !guest_gate_selector_okay(dom, cs) ) + goto bad; +- a = d->a = (d->a & 0xffffU) | (cs << 16); ++#ifdef __x86_64__ ++ /* ++ * Force DPL to zero, causing a GP fault with its error code indicating ++ * the gate in use, allowing emulation. This is necessary because with ++ * native guests (kernel in ring 3) call gates cannot be used directly ++ * to transition from user to kernel mode (and whether a gate is used ++ * to enter the kernel can only be determined when the gate is being ++ * used), and with compat guests call gates cannot be used at all as ++ * there are only 64-bit ones. ++ * Store the original DPL in the selector's RPL field. ++ */ ++ b &= ~_SEGMENT_DPL; ++ cs = (cs & ~3) | dpl; ++#endif ++ a = (a & 0xffffU) | (cs << 16); + + /* Reserved bits must be zero. */ +- if ( (b & 0xe0) != 0 ) ++ if ( b & (CONFIG_PAGING_LEVELS < 4 || IS_COMPAT(dom) ? 0xe0 : 0xff) ) + goto bad; + + good: ++ d->a = a; ++ d->b = b; + return 1; + bad: + return 0; diff --git a/32on64-domctl.patch b/32on64-domctl.patch new file mode 100644 index 0000000..b0b6900 --- /dev/null +++ b/32on64-domctl.patch @@ -0,0 +1,1336 @@ +Enable compatibility mode operation for HYPERVISOR_domctl. Also add logic +to switch a domain to/from compatibility mode (supposed to happen early +after domain creation only). + +Index: 2007-01-08/xen/arch/ia64/xen/domain.c +=================================================================== +--- 2007-01-08.orig/xen/arch/ia64/xen/domain.c 2007-01-08 15:04:22.000000000 +0100 ++++ 2007-01-08/xen/arch/ia64/xen/domain.c 2007-01-08 15:20:39.000000000 +0100 +@@ -522,14 +522,14 @@ void arch_domain_destroy(struct domain * + deallocate_rid_range(d); + } + +-void arch_getdomaininfo_ctxt(struct vcpu *v, struct vcpu_guest_context *c) ++void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c) + { + int i; +- struct vcpu_extra_regs *er = &c->extra_regs; ++ struct vcpu_extra_regs *er = &c.nat->extra_regs; + +- c->user_regs = *vcpu_regs (v); +- c->privregs_pfn = get_gpfn_from_mfn(virt_to_maddr(v->arch.privregs) >> +- PAGE_SHIFT); ++ c.nat->user_regs = *vcpu_regs(v); ++ c.nat->privregs_pfn = get_gpfn_from_mfn(virt_to_maddr(v->arch.privregs) >> ++ PAGE_SHIFT); + + /* Fill extra regs. */ + for (i = 0; i < 8; i++) { +@@ -549,12 +549,12 @@ void arch_getdomaininfo_ctxt(struct vcpu + er->iva = v->arch.iva; + } + +-int arch_set_info_guest(struct vcpu *v, struct vcpu_guest_context *c) ++int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c) + { + struct pt_regs *regs = vcpu_regs (v); + struct domain *d = v->domain; + +- *regs = c->user_regs; ++ *regs = c.nat->user_regs; + + if (!d->arch.is_vti) { + /* domain runs at PL2/3 */ +@@ -562,9 +562,9 @@ int arch_set_info_guest(struct vcpu *v, + regs->ar_rsc |= (2 << 2); /* force PL2/3 */ + } + +- if (c->flags & VGCF_EXTRA_REGS) { ++ if (c.nat->flags & VGCF_EXTRA_REGS) { + int i; +- struct vcpu_extra_regs *er = &c->extra_regs; ++ struct vcpu_extra_regs *er = &c.nat->extra_regs; + + for (i = 0; i < 8; i++) { + vcpu_set_itr(v, i, er->itrs[i].pte, +Index: 2007-01-08/xen/arch/powerpc/domain.c +=================================================================== +--- 2007-01-08.orig/xen/arch/powerpc/domain.c 2007-01-08 15:04:22.000000000 +0100 ++++ 2007-01-08/xen/arch/powerpc/domain.c 2007-01-08 15:20:39.000000000 +0100 +@@ -150,9 +150,9 @@ void vcpu_destroy(struct vcpu *v) + { + } + +-int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_t *c) ++int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c) + { +- memcpy(&v->arch.ctxt, &c->user_regs, sizeof(c->user_regs)); ++ memcpy(&v->arch.ctxt, &c.nat->user_regs, sizeof(c.nat->user_regs)); + + printk("Domain[%d].%d: initializing\n", + v->domain->domain_id, v->vcpu_id); +Index: 2007-01-08/xen/arch/powerpc/domctl.c +=================================================================== +--- 2007-01-08.orig/xen/arch/powerpc/domctl.c 2007-01-08 15:04:22.000000000 +0100 ++++ 2007-01-08/xen/arch/powerpc/domctl.c 2007-01-08 15:20:39.000000000 +0100 +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -29,10 +30,9 @@ + #include + #include + +-void arch_getdomaininfo_ctxt(struct vcpu *, vcpu_guest_context_t *); +-void arch_getdomaininfo_ctxt(struct vcpu *v, vcpu_guest_context_t *c) ++void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c) + { +- memcpy(&c->user_regs, &v->arch.ctxt, sizeof(struct cpu_user_regs)); ++ memcpy(&c.nat->user_regs, &v->arch.ctxt, sizeof(struct cpu_user_regs)); + /* XXX fill in rest of vcpu_guest_context_t */ + } + +Index: 2007-01-08/xen/arch/x86/domain.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/domain.c 2007-01-08 15:19:19.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/domain.c 2007-01-08 15:20:39.000000000 +0100 +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -250,6 +251,69 @@ static void release_compat_l4(struct vcp + v->arch.guest_table_user = pagetable_null(); + } + ++static inline int may_switch_mode(struct domain *d) ++{ ++ return 1; /* XXX */ ++} ++ ++int switch_native(struct domain *d) ++{ ++ l1_pgentry_t gdt_l1e; ++ unsigned int vcpuid; ++ ++ if ( !d ) ++ return -EINVAL; ++ if ( !may_switch_mode(d) ) ++ return -EACCES; ++ if ( !IS_COMPAT(d) ) ++ return 0; ++ ++ clear_bit(_DOMF_compat, &d->domain_flags); ++ release_arg_xlat_area(d); ++ ++ /* switch gdt */ ++ gdt_l1e = l1e_from_page(virt_to_page(gdt_table), PAGE_HYPERVISOR); ++ for ( vcpuid = 0; vcpuid < MAX_VIRT_CPUS; vcpuid++ ) ++ { ++ d->arch.mm_perdomain_pt[((vcpuid << GDT_LDT_VCPU_SHIFT) + ++ FIRST_RESERVED_GDT_PAGE)] = gdt_l1e; ++ if (d->vcpu[vcpuid]) ++ release_compat_l4(d->vcpu[vcpuid]); ++ } ++ ++ return 0; ++} ++ ++int switch_compat(struct domain *d) ++{ ++ l1_pgentry_t gdt_l1e; ++ unsigned int vcpuid; ++ ++ if ( !d ) ++ return -EINVAL; ++ if ( compat_disabled ) ++ return -ENOSYS; ++ if ( !may_switch_mode(d) ) ++ return -EACCES; ++ if ( IS_COMPAT(d) ) ++ return 0; ++ ++ set_bit(_DOMF_compat, &d->domain_flags); ++ ++ /* switch gdt */ ++ gdt_l1e = l1e_from_page(virt_to_page(compat_gdt_table), PAGE_HYPERVISOR); ++ for ( vcpuid = 0; vcpuid < MAX_VIRT_CPUS; vcpuid++ ) ++ { ++ d->arch.mm_perdomain_pt[((vcpuid << GDT_LDT_VCPU_SHIFT) + ++ FIRST_RESERVED_GDT_PAGE)] = gdt_l1e; ++ if (d->vcpu[vcpuid] ++ && setup_compat_l4(d->vcpu[vcpuid]) != 0) ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ + #else + #define release_arg_xlat_area(d) ((void)0) + #define setup_compat_l4(v) 0 +@@ -420,43 +484,80 @@ void arch_domain_destroy(struct domain * + + /* This is called by arch_final_setup_guest and do_boot_vcpu */ + int arch_set_info_guest( +- struct vcpu *v, struct vcpu_guest_context *c) ++ struct vcpu *v, vcpu_guest_context_u c) + { + struct domain *d = v->domain; ++#ifdef CONFIG_COMPAT ++#define c(fld) (!IS_COMPAT(d) ? (c.nat->fld) : (c.cmp->fld)) ++#else ++#define c(fld) (c.nat->fld) ++#endif + unsigned long cr3_pfn = INVALID_MFN; ++ unsigned long flags = c(flags); + int i, rc; + + if ( !is_hvm_vcpu(v) ) + { +- fixup_guest_stack_selector(d, c->user_regs.ss); +- fixup_guest_stack_selector(d, c->kernel_ss); +- fixup_guest_code_selector(d, c->user_regs.cs); +- +- if ( CONFIG_PAGING_LEVELS < 4 || IS_COMPAT(d) ) ++ if ( !IS_COMPAT(d) ) + { +- fixup_guest_code_selector(d, c->event_callback_cs); +- fixup_guest_code_selector(d, c->failsafe_callback_cs); +- } ++ fixup_guest_stack_selector(d, c.nat->user_regs.ss); ++ fixup_guest_stack_selector(d, c.nat->kernel_ss); ++ fixup_guest_code_selector(d, c.nat->user_regs.cs); ++#ifdef __i386__ ++ fixup_guest_code_selector(d, c.nat->event_callback_cs); ++ fixup_guest_code_selector(d, c.nat->failsafe_callback_cs); ++#endif + +- for ( i = 0; i < 256; i++ ) +- fixup_guest_code_selector(d, c->trap_ctxt[i].cs); ++ for ( i = 0; i < 256; i++ ) ++ fixup_guest_code_selector(d, c.nat->trap_ctxt[i].cs); + +- /* LDT safety checks. */ +- if ( ((c->ldt_base & (PAGE_SIZE-1)) != 0) || +- (c->ldt_ents > 8192) || +- !array_access_ok(c->ldt_base, c->ldt_ents, LDT_ENTRY_SIZE) ) +- return -EINVAL; ++ /* LDT safety checks. */ ++ if ( ((c.nat->ldt_base & (PAGE_SIZE-1)) != 0) || ++ (c.nat->ldt_ents > 8192) || ++ !array_access_ok(c.nat->ldt_base, ++ c.nat->ldt_ents, ++ LDT_ENTRY_SIZE) ) ++ return -EINVAL; ++ } ++#ifdef CONFIG_COMPAT ++ else ++ { ++ fixup_guest_stack_selector(d, c.cmp->user_regs.ss); ++ fixup_guest_stack_selector(d, c.cmp->kernel_ss); ++ fixup_guest_code_selector(d, c.cmp->user_regs.cs); ++ fixup_guest_code_selector(d, c.cmp->event_callback_cs); ++ fixup_guest_code_selector(d, c.cmp->failsafe_callback_cs); ++ ++ for ( i = 0; i < 256; i++ ) ++ fixup_guest_code_selector(d, c.cmp->trap_ctxt[i].cs); ++ ++ /* LDT safety checks. */ ++ if ( ((c.cmp->ldt_base & (PAGE_SIZE-1)) != 0) || ++ (c.cmp->ldt_ents > 8192) || ++ !compat_array_access_ok(c.cmp->ldt_base, ++ c.cmp->ldt_ents, ++ LDT_ENTRY_SIZE) ) ++ return -EINVAL; ++ } ++#endif + } + + clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags); +- if ( c->flags & VGCF_i387_valid ) ++ if ( flags & VGCF_I387_VALID ) + set_bit(_VCPUF_fpu_initialised, &v->vcpu_flags); + + v->arch.flags &= ~TF_kernel_mode; +- if ( (c->flags & VGCF_in_kernel) || is_hvm_vcpu(v)/*???*/ ) ++ if ( (flags & VGCF_in_kernel) || is_hvm_vcpu(v)/*???*/ ) + v->arch.flags |= TF_kernel_mode; + +- memcpy(&v->arch.guest_context, c, sizeof(*c)); ++ if ( !IS_COMPAT(v->domain) ) ++ memcpy(&v->arch.guest_context, c.nat, sizeof(*c.nat)); ++#ifdef CONFIG_COMPAT ++ else ++ { ++ XLAT_vcpu_guest_context(&v->arch.guest_context, c.cmp); ++ } ++#endif + + /* Only CR0.TS is modifiable by guest or admin. */ + v->arch.guest_context.ctrlreg[0] &= X86_CR0_TS; +@@ -484,19 +585,34 @@ int arch_set_info_guest( + memset(v->arch.guest_context.debugreg, 0, + sizeof(v->arch.guest_context.debugreg)); + for ( i = 0; i < 8; i++ ) +- (void)set_debugreg(v, i, c->debugreg[i]); ++ (void)set_debugreg(v, i, c(debugreg[i])); + + if ( v->vcpu_id == 0 ) +- d->vm_assist = c->vm_assist; ++ d->vm_assist = c(vm_assist); + + if ( !is_hvm_vcpu(v) ) + { +- if ( (rc = (int)set_gdt(v, c->gdt_frames, c->gdt_ents)) != 0 ) ++ if ( !IS_COMPAT(d) ) ++ rc = (int)set_gdt(v, c.nat->gdt_frames, c.nat->gdt_ents); ++#ifdef CONFIG_COMPAT ++ else ++ { ++ unsigned long gdt_frames[ARRAY_SIZE(c.cmp->gdt_frames)]; ++ unsigned int i, n = (c.cmp->gdt_ents + 511) / 512; ++ ++ if ( n > ARRAY_SIZE(c.cmp->gdt_frames) ) ++ return -EINVAL; ++ for ( i = 0; i < n; ++i ) ++ gdt_frames[i] = c.cmp->gdt_frames[i]; ++ rc = (int)set_gdt(v, gdt_frames, c.cmp->gdt_ents); ++ } ++#endif ++ if ( rc != 0 ) + return rc; + + if ( !IS_COMPAT(d) ) + { +- cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c->ctrlreg[3])); ++ cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c.nat->ctrlreg[3])); + + if ( shadow_mode_refcounts(d) + ? !get_page(mfn_to_page(cr3_pfn), d) +@@ -514,7 +630,7 @@ int arch_set_info_guest( + { + l4_pgentry_t *l4tab; + +- cr3_pfn = gmfn_to_mfn(d, compat_cr3_to_pfn(c->ctrlreg[3])); ++ cr3_pfn = gmfn_to_mfn(d, compat_cr3_to_pfn(c.cmp->ctrlreg[3])); + + if ( shadow_mode_refcounts(d) + ? !get_page(mfn_to_page(cr3_pfn), d) +@@ -552,6 +668,7 @@ int arch_set_info_guest( + update_cr3(v); + + return 0; ++#undef c + } + + long +Index: 2007-01-08/xen/arch/x86/domctl.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/domctl.c 2007-01-08 15:19:14.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/domctl.c 2007-01-08 15:20:39.000000000 +0100 +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -23,12 +24,21 @@ + #include + #include + #include ++#ifdef CONFIG_COMPAT ++#include ++#endif + +-long arch_do_domctl( ++#ifndef COMPAT ++#define _long long ++#define copy_from_xxx_offset copy_from_guest_offset ++#define copy_to_xxx_offset copy_to_guest_offset ++#endif ++ ++_long arch_do_domctl( + struct xen_domctl *domctl, + XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) + { +- long ret = 0; ++ _long ret = 0; + + switch ( domctl->cmd ) + { +@@ -40,7 +50,9 @@ long arch_do_domctl( + d = find_domain_by_id(domctl->domain); + if ( d != NULL ) + { +- ret = shadow_domctl(d, &domctl->u.shadow_op, u_domctl); ++ ret = shadow_domctl(d, ++ &domctl->u.shadow_op, ++ guest_handle_cast(u_domctl, void)); + put_domain(d); + copy_to_guest(u_domctl, domctl, 1); + } +@@ -123,12 +135,12 @@ long arch_do_domctl( + + case XEN_DOMCTL_getpageframeinfo2: + { +-#define GPF2_BATCH (PAGE_SIZE / sizeof(long)) ++#define GPF2_BATCH (PAGE_SIZE / sizeof(_long)) + int n,j; + int num = domctl->u.getpageframeinfo2.num; + domid_t dom = domctl->domain; + struct domain *d; +- unsigned long *l_arr; ++ unsigned _long *l_arr; + ret = -ESRCH; + + if ( unlikely((d = find_domain_by_id(dom)) == NULL) ) +@@ -148,9 +160,9 @@ long arch_do_domctl( + { + int k = ((num-n)>GPF2_BATCH)?GPF2_BATCH:(num-n); + +- if ( copy_from_guest_offset(l_arr, +- domctl->u.getpageframeinfo2.array, +- n, k) ) ++ if ( copy_from_xxx_offset(l_arr, ++ domctl->u.getpageframeinfo2.array, ++ n, k) ) + { + ret = -EINVAL; + break; +@@ -159,13 +171,13 @@ long arch_do_domctl( + for ( j = 0; j < k; j++ ) + { + struct page_info *page; +- unsigned long mfn = l_arr[j]; ++ unsigned _long mfn = l_arr[j]; + + page = mfn_to_page(mfn); + + if ( likely(mfn_valid(mfn) && get_page(page, d)) ) + { +- unsigned long type = 0; ++ unsigned _long type = 0; + + switch( page->u.inuse.type_info & PGT_type_mask ) + { +@@ -193,8 +205,8 @@ long arch_do_domctl( + + } + +- if ( copy_to_guest_offset(domctl->u.getpageframeinfo2.array, +- n, l_arr, k) ) ++ if ( copy_to_xxx_offset(domctl->u.getpageframeinfo2.array, ++ n, l_arr, k) ) + { + ret = -EINVAL; + break; +@@ -214,7 +226,7 @@ long arch_do_domctl( + int i; + struct domain *d = find_domain_by_id(domctl->domain); + unsigned long max_pfns = domctl->u.getmemlist.max_pfns; +- unsigned long mfn; ++ xen_pfn_t mfn; + struct list_head *list_ent; + + ret = -EINVAL; +@@ -229,8 +241,8 @@ long arch_do_domctl( + { + mfn = page_to_mfn(list_entry( + list_ent, struct page_info, list)); +- if ( copy_to_guest_offset(domctl->u.getmemlist.buffer, +- i, &mfn, 1) ) ++ if ( copy_to_xxx_offset(domctl->u.getmemlist.buffer, ++ i, &mfn, 1) ) + { + ret = -EFAULT; + break; +@@ -289,37 +301,68 @@ long arch_do_domctl( + return ret; + } + +-void arch_getdomaininfo_ctxt( +- struct vcpu *v, struct vcpu_guest_context *c) ++#ifndef COMPAT ++void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c) + { +- memcpy(c, &v->arch.guest_context, sizeof(*c)); ++#ifdef CONFIG_COMPAT ++#define c(fld) (!IS_COMPAT(v->domain) ? (c.nat->fld) : (c.cmp->fld)) ++#else ++#define c(fld) (c.nat->fld) ++#endif ++ unsigned long flags; ++ ++ if ( !IS_COMPAT(v->domain) ) ++ memcpy(c.nat, &v->arch.guest_context, sizeof(*c.nat)); ++#ifdef CONFIG_COMPAT ++ else ++ { ++ XLAT_vcpu_guest_context(c.cmp, &v->arch.guest_context); ++ } ++#endif + + if ( is_hvm_vcpu(v) ) + { +- hvm_store_cpu_guest_regs(v, &c->user_regs, c->ctrlreg); ++ if ( !IS_COMPAT(v->domain) ) ++ hvm_store_cpu_guest_regs(v, &c.nat->user_regs, c.nat->ctrlreg); ++#ifdef CONFIG_COMPAT ++ else ++ { ++ struct cpu_user_regs user_regs; ++ typeof(c.nat->ctrlreg) ctrlreg; ++ unsigned i; ++ ++ hvm_store_cpu_guest_regs(v, &user_regs, ctrlreg); ++ XLAT_cpu_user_regs(&c.cmp->user_regs, &user_regs); ++ for ( i = 0; i < ARRAY_SIZE(c.cmp->ctrlreg); ++i ) ++ c.cmp->ctrlreg[i] = ctrlreg[i]; ++ } ++#endif + } + else + { + /* IOPL privileges are virtualised: merge back into returned eflags. */ +- BUG_ON((c->user_regs.eflags & EF_IOPL) != 0); +- c->user_regs.eflags |= v->arch.iopl << 12; ++ BUG_ON((c(user_regs.eflags) & EF_IOPL) != 0); ++ c(user_regs.eflags |= v->arch.iopl << 12); + } + +- c->flags = 0; ++ flags = 0; + if ( test_bit(_VCPUF_fpu_initialised, &v->vcpu_flags) ) +- c->flags |= VGCF_i387_valid; ++ flags |= VGCF_i387_valid; + if ( guest_kernel_mode(v, &v->arch.guest_context.user_regs) ) +- c->flags |= VGCF_in_kernel; ++ flags |= VGCF_in_kernel; ++ c(flags = flags); + + if ( !IS_COMPAT(v->domain) ) +- c->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); ++ c.nat->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); + #ifdef CONFIG_COMPAT + else +- c->ctrlreg[3] = compat_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); ++ c.cmp->ctrlreg[3] = compat_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); + #endif + +- c->vm_assist = v->domain->vm_assist; ++ c(vm_assist = v->domain->vm_assist); ++#undef c + } ++#endif + + /* + * Local variables: +Index: 2007-01-08/xen/arch/x86/mm/shadow/common.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/mm/shadow/common.c 2007-01-08 15:19:11.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/mm/shadow/common.c 2007-01-08 15:20:39.000000000 +0100 +@@ -3211,7 +3211,7 @@ void sh_do_mark_dirty(struct domain *d, + + int shadow_domctl(struct domain *d, + xen_domctl_shadow_op_t *sc, +- XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) ++ XEN_GUEST_HANDLE(void) u_domctl) + { + int rc, preempted = 0; + +Index: 2007-01-08/xen/arch/x86/x86_32/traps.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_32/traps.c 2007-01-08 15:04:22.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_32/traps.c 2007-01-08 15:20:39.000000000 +0100 +@@ -193,7 +193,7 @@ unsigned long do_iret(void) + + /* + * Pop, fix up and restore EFLAGS. We fix up in a local staging area +- * to avoid firing the BUG_ON(IOPL) check in arch_getdomaininfo_ctxt. ++ * to avoid firing the BUG_ON(IOPL) check in arch_get_info_guest. + */ + if ( unlikely(__copy_from_user(&eflags, (void __user *)regs->esp, 4)) ) + goto exit_and_crash; +Index: 2007-01-08/xen/arch/x86/x86_64/Makefile +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_64/Makefile 2007-01-08 15:20:32.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_64/Makefile 2007-01-08 15:20:39.000000000 +0100 +@@ -5,6 +5,7 @@ obj-y += traps.o + + obj-$(CONFIG_COMPAT) += compat.o + obj-$(CONFIG_COMPAT) += domain.o ++obj-$(CONFIG_COMPAT) += domctl.o + obj-$(CONFIG_COMPAT) += physdev.o + obj-$(CONFIG_COMPAT) += platform_hypercall.o + obj-$(CONFIG_COMPAT) += sysctl.o +@@ -12,6 +13,7 @@ obj-$(CONFIG_COMPAT) += sysctl.o + ifeq ($(CONFIG_COMPAT),y) + # extra dependencies + compat.o: ../compat.c ++domctl.o: ../domctl.c + entry.o: compat/entry.S + mm.o: compat/mm.c + physdev.o: ../physdev.c +Index: 2007-01-08/xen/arch/x86/x86_64/compat/entry.S +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:20:32.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:20:39.000000000 +0100 +@@ -278,8 +278,6 @@ CFIX14: + + .section .rodata, "a", @progbits + +-#define compat_domctl domain_crash_synchronous +- + ENTRY(compat_hypercall_table) + .quad compat_set_trap_table /* 0 */ + .quad do_mmu_update +Index: 2007-01-08/xen/arch/x86/x86_64/compat/traps.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/traps.c 2007-01-08 15:19:19.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_64/compat/traps.c 2007-01-08 15:20:39.000000000 +0100 +@@ -49,7 +49,7 @@ unsigned int compat_iret(void) + + /* + * Fix up and restore EFLAGS. We fix up in a local staging area +- * to avoid firing the BUG_ON(IOPL) check in arch_getdomaininfo_ctxt. ++ * to avoid firing the BUG_ON(IOPL) check in arch_get_info_guest. + */ + if ( unlikely(__get_user(eflags, (u32 __user *)regs->rsp + 3)) ) + goto exit_and_crash; +Index: 2007-01-08/xen/arch/x86/x86_64/domctl.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-08/xen/arch/x86/x86_64/domctl.c 2007-01-08 15:20:39.000000000 +0100 +@@ -0,0 +1,111 @@ ++/****************************************************************************** ++ * Arch-specific compatibility domctl.c ++ */ ++ ++#include ++#include ++#include ++#include ++ ++DEFINE_XEN_GUEST_HANDLE(compat_domctl_t); ++#define xen_domctl compat_domctl ++#define xen_domctl_t compat_domctl_t ++#define arch_do_domctl(x, h) arch_compat_domctl(x, _##h) ++ ++static int compat_shadow_domctl(struct domain *d, ++ compat_domctl_shadow_op_t *csc, ++ XEN_GUEST_HANDLE(void) u_domctl) ++{ ++ xen_domctl_shadow_op_t nsc; ++ int rc, mode; ++ ++#define XLAT_domctl_shadow_op_HNDL_dirty_bitmap(_d_, _s_) \ ++ do \ ++ { \ ++ if ( (_s_)->op != XEN_DOMCTL_SHADOW_OP_CLEAN \ ++ && (_s_)->op != XEN_DOMCTL_SHADOW_OP_PEEK ) \ ++ { \ ++ set_xen_guest_handle((_d_)->dirty_bitmap, NULL); \ ++ mode = -1; \ ++ } \ ++ else if ( compat_handle_is_null((_s_)->dirty_bitmap) \ ++ || (((_s_)->pages - 1) \ ++ & (BITS_PER_LONG - COMPAT_BITS_PER_LONG)) \ ++ == BITS_PER_LONG - COMPAT_BITS_PER_LONG ) \ ++ { \ ++ XEN_GUEST_HANDLE(void) tmp; \ ++ guest_from_compat_handle(tmp, (_s_)->dirty_bitmap); \ ++ (_d_)->dirty_bitmap = guest_handle_cast(tmp, ulong); \ ++ mode = 0; \ ++ } \ ++ else if ( (_s_)->pages > COMPAT_ARG_XLAT_SIZE * 8 ) \ ++ { \ ++ printk("Cannot translate compatibility mode XEN_DOMCTL_SHADOW_OP_{CLEAN,PEEK} (0x%lX)\n", \ ++ (_s_)->pages); \ ++ return -E2BIG; \ ++ } \ ++ else \ ++ { \ ++ set_xen_guest_handle((_d_)->dirty_bitmap, \ ++ (void *)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id)); \ ++ mode = 1; \ ++ } \ ++ } while (0) ++ XLAT_domctl_shadow_op(&nsc, csc); ++#undef XLAT_domctl_shadow_op_HNDL_dirty_bitmap ++ rc = shadow_domctl(d, &nsc, u_domctl); ++ if ( rc != __HYPERVISOR_domctl ) ++ { ++ BUG_ON(rc > 0); ++#define XLAT_domctl_shadow_op_HNDL_dirty_bitmap(_d_, _s_) \ ++ do \ ++ { \ ++ if ( rc == 0 \ ++ && mode > 0 \ ++ && copy_to_compat((_d_)->dirty_bitmap, \ ++ (unsigned int *)(_s_)->dirty_bitmap.p, \ ++ ((_s_)->pages + COMPAT_BITS_PER_LONG - 1) / COMPAT_BITS_PER_LONG) ) \ ++ rc = -EFAULT; \ ++ } while (0) ++ XLAT_domctl_shadow_op(csc, &nsc); ++#undef XLAT_domctl_shadow_op_HNDL_dirty_bitmap ++ } ++ return rc; ++} ++#define xen_domctl_shadow_op compat_domctl_shadow_op ++#define xen_domctl_shadow_op_t compat_domctl_shadow_op_t ++#define shadow_domctl(d, sc, u) compat_shadow_domctl(d, sc, u) ++ ++#define xen_domctl_ioport_permission compat_domctl_ioport_permission ++#define xen_domctl_ioport_permission_t compat_domctl_ioport_permission_t ++ ++#define xen_domctl_getpageframeinfo compat_domctl_getpageframeinfo ++#define xen_domctl_getpageframeinfo_t compat_domctl_getpageframeinfo_t ++ ++#define xen_domctl_getpageframeinfo2 compat_domctl_getpageframeinfo2 ++#define xen_domctl_getpageframeinfo2_t compat_domctl_getpageframeinfo2_t ++ ++#define xen_domctl_getmemlist compat_domctl_getmemlist ++#define xen_domctl_getmemlist_t compat_domctl_getmemlist_t ++#define xen_pfn_t compat_pfn_t ++ ++#define xen_domctl_hypercall_init compat_domctl_hypercall_init ++#define xen_domctl_hypercall_init_t compat_domctl_hypercall_init_t ++ ++#define COMPAT ++#define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t) ++#define _long int ++#define copy_from_xxx_offset copy_from_compat_offset ++#define copy_to_xxx_offset copy_to_compat_offset ++ ++#include "../domctl.c" ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * tab-width: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ +Index: 2007-01-08/xen/common/compat/Makefile +=================================================================== +--- 2007-01-08.orig/xen/common/compat/Makefile 2007-01-08 15:20:32.000000000 +0100 ++++ 2007-01-08/xen/common/compat/Makefile 2007-01-08 15:20:39.000000000 +0100 +@@ -1,4 +1,5 @@ + obj-y += domain.o ++obj-y += domctl.o + obj-y += kernel.o + obj-y += memory.o + obj-y += multicall.o +@@ -6,6 +7,7 @@ obj-y += sysctl.o + obj-y += xlat.o + + # extra dependencies ++domctl.o: ../domctl.c + kernel.o: ../kernel.c + multicall.o: ../multicall.c + sysctl.o: ../sysctl.c +Index: 2007-01-08/xen/common/compat/domain.c +=================================================================== +--- 2007-01-08.orig/xen/common/compat/domain.c 2007-01-08 15:19:19.000000000 +0100 ++++ 2007-01-08/xen/common/compat/domain.c 2007-01-08 15:20:39.000000000 +0100 +@@ -28,7 +28,6 @@ int compat_vcpu_op(int cmd, int vcpuid, + case VCPUOP_initialise: + { + struct compat_vcpu_guest_context *cmp_ctxt; +- struct vcpu_guest_context *nat_ctxt; + + if ( (cmp_ctxt = xmalloc(struct compat_vcpu_guest_context)) == NULL ) + { +@@ -43,23 +42,13 @@ int compat_vcpu_op(int cmd, int vcpuid, + break; + } + +- if ( (nat_ctxt = xmalloc(struct vcpu_guest_context)) == NULL ) +- { +- rc = -ENOMEM; +- break; +- } +- +- memset(nat_ctxt, 0, sizeof(*nat_ctxt)); +- XLAT_vcpu_guest_context(nat_ctxt, cmp_ctxt); +- xfree(cmp_ctxt); +- + LOCK_BIGLOCK(d); + rc = -EEXIST; + if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) ) +- rc = boot_vcpu(d, vcpuid, nat_ctxt); ++ rc = boot_vcpu(d, vcpuid, cmp_ctxt); + UNLOCK_BIGLOCK(d); + +- xfree(nat_ctxt); ++ xfree(cmp_ctxt); + break; + } + +Index: 2007-01-08/xen/common/compat/domctl.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-08/xen/common/compat/domctl.c 2007-01-08 15:20:39.000000000 +0100 +@@ -0,0 +1,137 @@ ++/****************************************************************************** ++ * compat/domctl.c ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++DEFINE_XEN_GUEST_HANDLE(compat_domctl_t); ++#define xen_domctl compat_domctl ++#define xen_domctl_t compat_domctl_t ++#define do_domctl(h) compat_domctl(_##h) ++#define arch_do_domctl(x, h) arch_compat_domctl(x, _##h) ++ ++#define xen_domain_handle_t compat_domain_handle_t ++ ++#define xen_domctl_vcpucontext compat_domctl_vcpucontext ++#define xen_domctl_vcpucontext_t compat_domctl_vcpucontext_t ++ ++#define xen_domctl_createdomain compat_domctl_createdomain ++#define xen_domctl_createdomain_t compat_domctl_createdomain_t ++ ++#define xen_domctl_max_vcpus compat_domctl_max_vcpus ++#define xen_domctl_max_vcpus_t compat_domctl_max_vcpus_t ++ ++static void cpumask_to_compat_ctl_cpumap( ++ struct compat_ctl_cpumap *cmpctl_cpumap, cpumask_t *cpumask) ++{ ++ unsigned int guest_bytes, copy_bytes, i; ++ /*static const*/ uint8_t zero = 0; ++ ++ if ( compat_handle_is_null(cmpctl_cpumap->bitmap) ) ++ return; ++ ++ guest_bytes = (cmpctl_cpumap->nr_cpus + 7) / 8; ++ copy_bytes = min_t(unsigned int, guest_bytes, (NR_CPUS + 7) / 8); ++ ++ copy_to_compat(cmpctl_cpumap->bitmap, ++ (uint8_t *)cpus_addr(*cpumask), ++ copy_bytes); ++ ++ for ( i = copy_bytes; i < guest_bytes; i++ ) ++ copy_to_compat_offset(cmpctl_cpumap->bitmap, i, &zero, 1); ++} ++#define cpumask_to_xenctl_cpumap cpumask_to_compat_ctl_cpumap ++ ++void compat_ctl_cpumap_to_cpumask( ++ cpumask_t *cpumask, struct compat_ctl_cpumap *cmpctl_cpumap) ++{ ++ unsigned int guest_bytes, copy_bytes; ++ ++ guest_bytes = (cmpctl_cpumap->nr_cpus + 7) / 8; ++ copy_bytes = min_t(unsigned int, guest_bytes, (NR_CPUS + 7) / 8); ++ ++ cpus_clear(*cpumask); ++ ++ if ( compat_handle_is_null(cmpctl_cpumap->bitmap) ) ++ return; ++ ++ copy_from_compat((uint8_t *)cpus_addr(*cpumask), ++ cmpctl_cpumap->bitmap, ++ copy_bytes); ++} ++#define xenctl_cpumap_to_cpumask compat_ctl_cpumap_to_cpumask ++ ++#define xen_domctl_vcpuaffinity compat_domctl_vcpuaffinity ++#define xen_domctl_vcpuaffinity_t compat_domctl_vcpuaffinity_t ++ ++static int compat_sched_adjust(struct domain *d, ++ struct compat_domctl_scheduler_op *cop) ++{ ++ struct xen_domctl_scheduler_op nop; ++ int ret; ++ enum XLAT_domctl_scheduler_op_u u; ++ ++ switch ( cop->sched_id ) ++ { ++ case XEN_SCHEDULER_SEDF: u = XLAT_domctl_scheduler_op_u_sedf; break; ++ case XEN_SCHEDULER_CREDIT: u = XLAT_domctl_scheduler_op_u_credit; break; ++ default: return -EINVAL; ++ } ++ XLAT_domctl_scheduler_op(&nop, cop); ++ ret = sched_adjust(d, &nop); ++ XLAT_domctl_scheduler_op(cop, &nop); ++ ++ return ret; ++} ++#define sched_adjust(d, op) compat_sched_adjust(d, op) ++#define xen_domctl_scheduler_op compat_domctl_scheduler_op ++#define xen_domctl_scheduler_op_t compat_domctl_scheduler_op_t ++ ++#define xen_domctl_getdomaininfo compat_domctl_getdomaininfo ++#define xen_domctl_getdomaininfo_t compat_domctl_getdomaininfo_t ++#define getdomaininfo(d, i) compat_getdomaininfo(d, i) ++ ++#define xen_domctl_getvcpuinfo compat_domctl_getvcpuinfo ++#define xen_domctl_getvcpuinfo_t compat_domctl_getvcpuinfo_t ++ ++#define xen_domctl_max_mem compat_domctl_max_mem ++#define xen_domctl_max_mem_t compat_domctl_max_mem_t ++ ++#define xen_domctl_setdomainhandle compat_domctl_setdomainhandle ++#define xen_domctl_setdomainhandle_t compat_domctl_setdomainhandle_t ++ ++#define xen_domctl_setdebugging compat_domctl_setdebugging ++#define xen_domctl_setdebugging_t compat_domctl_setdebugging_t ++ ++#define xen_domctl_irq_permission compat_domctl_irq_permission ++#define xen_domctl_irq_permission_t compat_domctl_irq_permission_t ++ ++#define xen_domctl_iomem_permission compat_domctl_iomem_permission ++#define xen_domctl_iomem_permission_t compat_domctl_iomem_permission_t ++ ++#define xen_domctl_settimeoffset compat_domctl_settimeoffset ++#define xen_domctl_settimeoffset_t compat_domctl_settimeoffset_t ++ ++#define COMPAT ++#define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t) ++#define _u_domctl u_domctl ++//#undef guest_handle_cast ++//#define guest_handle_cast compat_handle_cast ++//#define copy_to_xxx_offset copy_to_compat_offset ++typedef int ret_t; ++ ++#include "../domctl.c" ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * tab-width: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ +Index: 2007-01-08/xen/common/compat/sysctl.c +=================================================================== +--- 2007-01-08.orig/xen/common/compat/sysctl.c 2007-01-08 15:20:32.000000000 +0100 ++++ 2007-01-08/xen/common/compat/sysctl.c 2007-01-08 15:20:39.000000000 +0100 +@@ -40,13 +40,6 @@ static int compat_tb_control(struct comp + #define xen_sysctl_sched_id compat_sysctl_sched_id + #define xen_sysctl_sched_id_t compat_sysctl_sched_id_t + +-static void compat_getdomaininfo(struct domain *d, struct compat_domctl_getdomaininfo *ci) +-{ +- struct xen_domctl_getdomaininfo ni; +- +- getdomaininfo(d, &ni); +- XLAT_domctl_getdomaininfo(ci, &ni); +-} + #define xen_sysctl_getdomaininfolist compat_sysctl_getdomaininfolist + #define xen_sysctl_getdomaininfolist_t compat_sysctl_getdomaininfolist_t + #define xen_domctl_getdomaininfo compat_domctl_getdomaininfo +Index: 2007-01-08/xen/common/domain.c +=================================================================== +--- 2007-01-08.orig/xen/common/domain.c 2007-01-08 15:19:11.000000000 +0100 ++++ 2007-01-08/xen/common/domain.c 2007-01-08 15:20:39.000000000 +0100 +@@ -26,6 +26,9 @@ + #include + #include + #include ++#ifdef CONFIG_COMPAT ++#include ++#endif + + /* Both these structures are protected by the domlist_lock. */ + DEFINE_RWLOCK(domlist_lock); +@@ -451,32 +454,64 @@ void domain_unpause_by_systemcontroller( + * the userspace dom0 domain builder. + */ + int set_info_guest(struct domain *d, +- xen_domctl_vcpucontext_t *vcpucontext) ++ xen_domctl_vcpucontext_u vcpucontext) + { + int rc = 0; +- struct vcpu_guest_context *c = NULL; +- unsigned long vcpu = vcpucontext->vcpu; ++ vcpu_guest_context_u c; ++#ifdef CONFIG_COMPAT ++ CHECK_FIELD(domctl_vcpucontext, vcpu); ++#endif ++ unsigned long vcpu = vcpucontext.nat->vcpu; + struct vcpu *v; + + if ( (vcpu >= MAX_VIRT_CPUS) || ((v = d->vcpu[vcpu]) == NULL) ) + return -EINVAL; + +- if ( (c = xmalloc(struct vcpu_guest_context)) == NULL ) ++#ifdef CONFIG_COMPAT ++ BUILD_BUG_ON(sizeof(struct vcpu_guest_context) ++ < sizeof(struct compat_vcpu_guest_context)); ++#endif ++ if ( (c.nat = xmalloc(struct vcpu_guest_context)) == NULL ) + return -ENOMEM; + + domain_pause(d); + +- rc = -EFAULT; +- if ( copy_from_guest(c, vcpucontext->ctxt, 1) == 0 ) ++ if ( !IS_COMPAT(v->domain) ) ++ { ++ if ( !IS_COMPAT(current->domain) ++ ? copy_from_guest(c.nat, vcpucontext.nat->ctxt, 1) ++#ifndef CONFIG_COMPAT ++ : 0 ) ++#else ++ : copy_from_guest(c.nat, ++ compat_handle_cast(vcpucontext.cmp->ctxt, ++ void), ++ 1) ) ++#endif ++ rc = -EFAULT; ++ } ++#ifdef CONFIG_COMPAT ++ else ++ { ++ if ( !IS_COMPAT(current->domain) ++ ? copy_from_guest(c.cmp, ++ guest_handle_cast(vcpucontext.nat->ctxt, void), ++ 1) ++ : copy_from_compat(c.cmp, vcpucontext.cmp->ctxt, 1) ) ++ rc = -EFAULT; ++ } ++#endif ++ ++ if ( rc == 0 ) + rc = arch_set_info_guest(v, c); + + domain_unpause(d); + +- xfree(c); ++ xfree(c.nat); + return rc; + } + +-int boot_vcpu(struct domain *d, int vcpuid, struct vcpu_guest_context *ctxt) ++int boot_vcpu(struct domain *d, int vcpuid, vcpu_guest_context_u ctxt) + { + struct vcpu *v = d->vcpu[vcpuid]; + +Index: 2007-01-08/xen/common/domctl.c +=================================================================== +--- 2007-01-08.orig/xen/common/domctl.c 2007-01-08 15:04:22.000000000 +0100 ++++ 2007-01-08/xen/common/domctl.c 2007-01-08 15:20:39.000000000 +0100 +@@ -18,14 +18,22 @@ + #include + #include + #include ++#ifdef CONFIG_COMPAT ++#include ++#endif + #include + #include + #include + +-extern long arch_do_domctl( ++#ifndef COMPAT ++typedef long ret_t; ++#define copy_to_xxx_offset copy_to_guest_offset ++#endif ++ ++extern ret_t arch_do_domctl( + struct xen_domctl *op, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl); +-extern void arch_getdomaininfo_ctxt( +- struct vcpu *, struct vcpu_guest_context *); ++ ++#ifndef COMPAT + + void cpumask_to_xenctl_cpumap( + struct xenctl_cpumap *xenctl_cpumap, cpumask_t *cpumask) +@@ -65,6 +73,8 @@ void xenctl_cpumap_to_cpumask( + copy_bytes); + } + ++#endif /* COMPAT */ ++ + static inline int is_free_domid(domid_t dom) + { + struct domain *d; +@@ -169,9 +179,9 @@ static unsigned int default_vcpu0_locati + return cpu; + } + +-long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) ++ret_t do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) + { +- long ret = 0; ++ ret_t ret = 0; + struct xen_domctl curop, *op = &curop; + void *ssid = NULL; /* save security ptr between pre and post/fail hooks */ + static DEFINE_SPINLOCK(domctl_lock); +@@ -283,11 +293,36 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc + if ( (d = domain_create(dom, domcr_flags)) == NULL ) + break; + ++ ret = 0; ++ switch ( (op->u.createdomain.flags >> XEN_DOMCTL_CDF_WORDSIZE_SHIFT) ++ & XEN_DOMCTL_CDF_WORDSIZE_MASK ) ++ { ++ case 0: ++ if ( !IS_COMPAT(current->domain) ) ++ op->u.createdomain.flags |= BITS_PER_LONG ++ << XEN_DOMCTL_CDF_WORDSIZE_SHIFT; ++#ifdef CONFIG_COMPAT ++ else ++ { ++ op->u.createdomain.flags |= COMPAT_BITS_PER_LONG ++ << XEN_DOMCTL_CDF_WORDSIZE_SHIFT; ++ case COMPAT_BITS_PER_LONG: ++ ret = switch_compat(d); ++ } ++#endif ++ break; ++ case BITS_PER_LONG: ++ break; ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ if ( ret ) ++ break; ++ + memcpy(d->handle, op->u.createdomain.handle, + sizeof(xen_domain_handle_t)); + +- ret = 0; +- + op->domain = d->domain_id; + if ( copy_to_guest(u_domctl, op, 1) ) + ret = -EFAULT; +@@ -446,7 +481,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc + + case XEN_DOMCTL_getvcpucontext: + { +- struct vcpu_guest_context *c; ++ vcpu_guest_context_u c; + struct domain *d; + struct vcpu *v; + +@@ -466,23 +501,48 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc + if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) ) + goto getvcpucontext_out; + ++#ifdef CONFIG_COMPAT ++ BUILD_BUG_ON(sizeof(struct vcpu_guest_context) ++ < sizeof(struct compat_vcpu_guest_context)); ++#endif + ret = -ENOMEM; +- if ( (c = xmalloc(struct vcpu_guest_context)) == NULL ) ++ if ( (c.nat = xmalloc(struct vcpu_guest_context)) == NULL ) + goto getvcpucontext_out; + + if ( v != current ) + vcpu_pause(v); + +- arch_getdomaininfo_ctxt(v,c); ++ arch_get_info_guest(v, c); + ret = 0; + + if ( v != current ) + vcpu_unpause(v); + +- if ( copy_to_guest(op->u.vcpucontext.ctxt, c, 1) ) +- ret = -EFAULT; ++ if ( !IS_COMPAT(v->domain) ) ++ { ++#ifndef COMPAT ++ if ( copy_to_guest(op->u.vcpucontext.ctxt, c.nat, 1) ) ++#else ++ if ( copy_to_guest(compat_handle_cast(op->u.vcpucontext.ctxt, ++ void), ++ c.nat, 1) ) ++#endif ++ ret = -EFAULT; ++ } ++#ifdef CONFIG_COMPAT ++ else ++ { ++#ifndef COMPAT ++ if ( copy_to_guest(guest_handle_cast(op->u.vcpucontext.ctxt, void), ++ c.cmp, 1) ) ++#else ++ if ( copy_to_compat(op->u.vcpucontext.ctxt, c.cmp, 1) ) ++#endif ++ ret = -EFAULT; ++ } ++#endif + +- xfree(c); ++ xfree(c.nat); + + if ( copy_to_guest(u_domctl, op, 1) ) + ret = -EFAULT; +@@ -646,6 +706,16 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc + } + break; + ++#ifdef CONFIG_COMPAT ++ case XEN_DOMCTL_set_compat: ++ ret = switch_compat(find_domain_by_id(op->domain)); ++ break; ++ ++ case XEN_DOMCTL_set_native: ++ ret = switch_native(find_domain_by_id(op->domain)); ++ break; ++#endif ++ + default: + ret = arch_do_domctl(op, u_domctl); + break; +Index: 2007-01-08/xen/common/schedule.c +=================================================================== +--- 2007-01-08.orig/xen/common/schedule.c 2007-01-08 15:19:21.000000000 +0100 ++++ 2007-01-08/xen/common/schedule.c 2007-01-08 15:20:39.000000000 +0100 +@@ -33,8 +33,6 @@ + #include + #include + +-extern void arch_getdomaininfo_ctxt(struct vcpu *, +- struct vcpu_guest_context *); + /* opt_sched: scheduler - default to credit */ + static char opt_sched[10] = "credit"; + string_param("sched", opt_sched); +Index: 2007-01-08/xen/include/asm-x86/shadow.h +=================================================================== +--- 2007-01-08.orig/xen/include/asm-x86/shadow.h 2007-01-08 15:04:22.000000000 +0100 ++++ 2007-01-08/xen/include/asm-x86/shadow.h 2007-01-08 15:20:39.000000000 +0100 +@@ -315,7 +315,7 @@ int shadow_test_enable(struct domain *d) + * and log-dirty bitmap ops all happen through here. */ + int shadow_domctl(struct domain *d, + xen_domctl_shadow_op_t *sc, +- XEN_GUEST_HANDLE(xen_domctl_t) u_domctl); ++ XEN_GUEST_HANDLE(void) u_domctl); + + /* Call when destroying a domain */ + void shadow_teardown(struct domain *d); +Index: 2007-01-08/xen/include/public/domctl.h +=================================================================== +--- 2007-01-08.orig/xen/include/public/domctl.h 2007-01-08 15:04:22.000000000 +0100 ++++ 2007-01-08/xen/include/public/domctl.h 2007-01-08 15:20:39.000000000 +0100 +@@ -53,6 +53,8 @@ struct xen_domctl_createdomain { + /* Is this an HVM guest (as opposed to a PV guest)? */ + #define _XEN_DOMCTL_CDF_hvm_guest 0 + #define XEN_DOMCTL_CDF_hvm_guest (1U<<_XEN_DOMCTL_CDF_hvm_guest) ++#define XEN_DOMCTL_CDF_WORDSIZE_MASK 255 ++#define XEN_DOMCTL_CDF_WORDSIZE_SHIFT 24 + uint32_t flags; + }; + typedef struct xen_domctl_createdomain xen_domctl_createdomain_t; +@@ -392,6 +394,9 @@ struct xen_domctl_real_mode_area { + typedef struct xen_domctl_real_mode_area xen_domctl_real_mode_area_t; + DEFINE_XEN_GUEST_HANDLE(xen_domctl_real_mode_area_t); + ++#define XEN_DOMCTL_set_compat 42 ++#define XEN_DOMCTL_set_native 43 ++ + struct xen_domctl { + uint32_t cmd; + uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */ +Index: 2007-01-08/xen/include/xen/compat.h +=================================================================== +--- 2007-01-08.orig/xen/include/xen/compat.h 2007-01-08 15:19:19.000000000 +0100 ++++ 2007-01-08/xen/include/xen/compat.h 2007-01-08 15:20:39.000000000 +0100 +@@ -166,6 +166,9 @@ void xlat_start_info(struct start_info * + struct vcpu_runstate_info; + void xlat_vcpu_runstate_info(struct vcpu_runstate_info *); + ++int switch_compat(struct domain *); ++int switch_native(struct domain *); ++ + #define BITS_PER_GUEST_LONG(d) (!IS_COMPAT(d) ? BITS_PER_LONG : COMPAT_BITS_PER_LONG) + + #else +Index: 2007-01-08/xen/include/xen/domain.h +=================================================================== +--- 2007-01-08.orig/xen/include/xen/domain.h 2007-01-08 15:20:32.000000000 +0100 ++++ 2007-01-08/xen/include/xen/domain.h 2007-01-08 15:20:39.000000000 +0100 +@@ -2,10 +2,15 @@ + #ifndef __XEN_DOMAIN_H__ + #define __XEN_DOMAIN_H__ + ++typedef union { ++ struct vcpu_guest_context *nat; ++ struct compat_vcpu_guest_context *cmp; ++} vcpu_guest_context_u __attribute__((__transparent_union__)); ++ + struct vcpu *alloc_vcpu( + struct domain *d, unsigned int vcpu_id, unsigned int cpu_id); + int boot_vcpu( +- struct domain *d, int vcpuid, struct vcpu_guest_context *ctxt); ++ struct domain *d, int vcpuid, vcpu_guest_context_u ctxt); + struct vcpu *alloc_idle_vcpu(unsigned int cpu_id); + + struct domain *alloc_domain(domid_t domid); +@@ -14,6 +19,9 @@ void free_domain(struct domain *d); + struct xen_domctl_getdomaininfo; + void getdomaininfo( + struct domain *d, struct xen_domctl_getdomaininfo *info); ++struct compat_domctl_getdomaininfo; ++void compat_getdomaininfo( ++ struct domain *d, struct compat_domctl_getdomaininfo *info); + + /* + * Arch-specifics. +@@ -37,7 +45,8 @@ int arch_domain_create(struct domain *d) + + void arch_domain_destroy(struct domain *d); + +-int arch_set_info_guest(struct vcpu *v, struct vcpu_guest_context *c); ++int arch_set_info_guest(struct vcpu *, vcpu_guest_context_u); ++void arch_get_info_guest(struct vcpu *, vcpu_guest_context_u); + + void domain_relinquish_resources(struct domain *d); + +Index: 2007-01-08/xen/include/xen/sched.h +=================================================================== +--- 2007-01-08.orig/xen/include/xen/sched.h 2007-01-08 15:19:19.000000000 +0100 ++++ 2007-01-08/xen/include/xen/sched.h 2007-01-08 15:20:39.000000000 +0100 +@@ -275,7 +275,13 @@ int construct_dom0( + unsigned long image_start, unsigned long image_len, + unsigned long initrd_start, unsigned long initrd_len, + char *cmdline); +-int set_info_guest(struct domain *d, xen_domctl_vcpucontext_t *); ++ ++typedef union { ++ struct xen_domctl_vcpucontext *nat; ++ struct compat_domctl_vcpucontext *cmp; ++} xen_domctl_vcpucontext_u __attribute__((__transparent_union__)); ++ ++int set_info_guest(struct domain *d, xen_domctl_vcpucontext_u); + + struct domain *find_domain_by_id(domid_t dom); + void domain_destroy(struct domain *d); +Index: 2007-01-08/xen/include/xlat.lst +=================================================================== +--- 2007-01-08.orig/xen/include/xlat.lst 2007-01-08 15:20:32.000000000 +0100 ++++ 2007-01-08/xen/include/xlat.lst 2007-01-08 15:20:39.000000000 +0100 +@@ -11,7 +11,9 @@ + ! vcpu_guest_context arch-@arch@/xen.h + ? acm_getdecision acm_ops.h + ! ctl_cpumap domctl.h +-! domctl_getdomaininfo domctl.h ++! domctl_scheduler_op domctl.h ++! domctl_shadow_op domctl.h ++! domctl_shadow_op_stats domctl.h + ? evtchn_alloc_unbound event_channel.h + ? evtchn_bind_interdomain event_channel.h + ? evtchn_bind_ipi event_channel.h diff --git a/32on64-emul.patch b/32on64-emul.patch new file mode 100644 index 0000000..d860710 --- /dev/null +++ b/32on64-emul.patch @@ -0,0 +1,647 @@ +Adjust emulation code to deal with compatibility mode guests. This +includes enhancements to emulate_privileged_op() that aren't directly +related to such guests. + +Index: 2006-12-18/xen/arch/x86/domain.c +=================================================================== +--- 2006-12-18.orig/xen/arch/x86/domain.c 2006-12-18 17:53:11.000000000 +0100 ++++ 2006-12-18/xen/arch/x86/domain.c 2006-12-18 09:49:18.000000000 +0100 +@@ -1065,6 +1065,20 @@ void domain_relinquish_resources(struct + { + /* Drop ref to guest_table (from new_guest_cr3(), svm/vmx cr3 handling, + * or sh_update_paging_modes()) */ ++#ifdef CONFIG_COMPAT ++ if ( IS_COMPAT(d) ) ++ { ++ pfn = l4e_get_pfn(*(l4_pgentry_t *)__va(pagetable_get_paddr(v->arch.guest_table))); ++ if ( pfn != 0 ) ++ { ++ if ( shadow_mode_refcounts(d) ) ++ put_page(mfn_to_page(pfn)); ++ else ++ put_page_and_type(mfn_to_page(pfn)); ++ } ++ continue; ++ } ++#endif + pfn = pagetable_get_pfn(v->arch.guest_table); + if ( pfn != 0 ) + { +Index: 2006-12-18/xen/arch/x86/mm.c +=================================================================== +--- 2006-12-18.orig/xen/arch/x86/mm.c 2006-12-18 17:53:11.000000000 +0100 ++++ 2006-12-18/xen/arch/x86/mm.c 2006-12-18 09:49:18.000000000 +0100 +@@ -1759,6 +1759,33 @@ int new_guest_cr3(unsigned long mfn) + if ( is_hvm_domain(d) && !hvm_paging_enabled(v) ) + return 0; + ++#ifdef CONFIG_COMPAT ++ if ( IS_COMPAT(d) ) ++ { ++ l4_pgentry_t l4e = l4e_from_pfn(mfn, _PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED); ++ ++ if ( shadow_mode_refcounts(d) ) ++ { ++ okay = get_page_from_pagenr(mfn, d); ++ old_base_mfn = l4e_get_pfn(l4e); ++ if ( okay && old_base_mfn ) ++ put_page(mfn_to_page(old_base_mfn)); ++ } ++ else ++ okay = mod_l4_entry(__va(pagetable_get_paddr(v->arch.guest_table)), ++ l4e, 0); ++ if ( unlikely(!okay) ) ++ { ++ MEM_LOG("Error while installing new compat baseptr %lx", mfn); ++ return 0; ++ } ++ ++ invalidate_shadow_ldt(v); ++ write_ptbase(v); ++ ++ return 1; ++ } ++#endif + if ( shadow_mode_refcounts(d) ) + { + okay = get_page_from_pagenr(mfn, d); +@@ -3212,7 +3239,7 @@ static int ptwr_emulated_update( + nl1e = l1e_from_intpte(val); + if ( unlikely(!get_page_from_l1e(gl1e_to_ml1e(d, nl1e), d)) ) + { +- if ( (CONFIG_PAGING_LEVELS == 3) && ++ if ( (CONFIG_PAGING_LEVELS == 3 || IS_COMPAT(d)) && + (bytes == 4) && + !do_cmpxchg && + (l1e_get_flags(nl1e) & _PAGE_PRESENT) ) +@@ -3356,7 +3383,7 @@ int ptwr_do_page_fault(struct vcpu *v, u + goto bail; + + ptwr_ctxt.ctxt.regs = guest_cpu_user_regs(); +- ptwr_ctxt.ctxt.mode = X86EMUL_MODE_HOST; ++ ptwr_ctxt.ctxt.mode = !IS_COMPAT(d) ? X86EMUL_MODE_HOST : X86EMUL_MODE_PROT32; + ptwr_ctxt.cr2 = addr; + ptwr_ctxt.pte = pte; + if ( x86_emulate_memop(&ptwr_ctxt.ctxt, &ptwr_emulate_ops) ) +Index: 2006-12-18/xen/arch/x86/traps.c +=================================================================== +--- 2006-12-18.orig/xen/arch/x86/traps.c 2006-12-18 17:53:11.000000000 +0100 ++++ 2006-12-18/xen/arch/x86/traps.c 2006-12-18 17:53:52.000000000 +0100 +@@ -993,6 +993,64 @@ long do_fpu_taskswitch(int set) + return 0; + } + ++static int read_descriptor(unsigned int sel, ++ const struct vcpu *v, ++ const struct cpu_user_regs * regs, ++ unsigned long *base, ++ unsigned long *limit, ++ unsigned int *ar, ++ unsigned int vm86attr) ++{ ++ struct desc_struct desc; ++ ++ if ( !vm86_mode(regs) ) ++ { ++ if ( sel < 4) ++ desc.b = desc.a = 0; ++ else if ( __get_user(desc, ++ (const struct desc_struct *)(!(sel & 4) ++ ? GDT_VIRT_START(v) ++ : LDT_VIRT_START(v)) ++ + (sel >> 3)) ) ++ return 0; ++ if ( !(vm86attr & _SEGMENT_CODE) ) ++ desc.b &= ~_SEGMENT_L; ++ } ++ else ++ { ++ desc.a = (sel << 20) | 0xffff; ++ desc.b = vm86attr | (sel >> 12); ++ } ++ ++ *ar = desc.b & 0x00f0ff00; ++ if ( !(desc.b & _SEGMENT_L) ) ++ { ++ *base = (desc.a >> 16) + ((desc.b & 0xff) << 16) + (desc.b & 0xff000000); ++ *limit = (desc.a & 0xffff) | (desc.b & 0x000f0000); ++ if ( desc.b & _SEGMENT_G ) ++ *limit = ((*limit + 1) << 12) - 1; ++#ifndef NDEBUG ++ if ( !vm86_mode(regs) && sel > 3 ) ++ { ++ unsigned int a, l; ++ unsigned char valid; ++ ++ __asm__("larl %2, %0\n\tsetz %1" : "=r" (a), "=rm" (valid) : "rm" (sel)); ++ BUG_ON(valid && (a & 0x00f0ff00) != *ar); ++ __asm__("lsll %2, %0\n\tsetz %1" : "=r" (l), "=rm" (valid) : "rm" (sel)); ++ BUG_ON(valid && l != *limit); ++ } ++#endif ++ } ++ else ++ { ++ *base = 0UL; ++ *limit = ~0UL; ++ } ++ ++ return 1; ++} ++ + /* Has the guest requested sufficient permission for this I/O access? */ + static inline int guest_io_okay( + unsigned int port, unsigned int bytes, +@@ -1057,65 +1115,113 @@ unsigned long guest_to_host_gpr_switch(u + __attribute__((__regparm__(1))); + + /* Instruction fetch with error handling. */ +-#define insn_fetch(_type, _size, cs, eip) \ +-({ unsigned long _rc, _x, _ptr = eip; \ +- if ( vm86_mode(regs) ) \ +- _ptr += cs << 4; \ +- if ( (_rc = copy_from_user(&_x, (_type *)_ptr, sizeof(_type))) != 0 ) \ ++#define insn_fetch(type, base, eip, limit) \ ++({ unsigned long _rc, _ptr = (base) + (eip); \ ++ type _x; \ ++ if ( (limit) < sizeof(_x) - 1 || (eip) > (limit) - (sizeof(_x) - 1) ) \ ++ goto fail; \ ++ if ( (_rc = copy_from_user(&_x, (type *)_ptr, sizeof(_x))) != 0 ) \ + { \ +- propagate_page_fault(eip + sizeof(_type) - _rc, 0); \ ++ propagate_page_fault(_ptr + sizeof(_x) - _rc, 0); \ + return EXCRET_fault_fixed; \ + } \ +- eip += _size; (_type)_x; }) ++ (eip) += sizeof(_x); _x; }) ++ ++#if defined(CONFIG_X86_32) ++# define read_sreg(regs, sr) ((regs)->sr) ++#elif defined(CONFIG_X86_64) ++# define read_sreg(regs, sr) read_segment_register(sr) ++#endif + + static int emulate_privileged_op(struct cpu_user_regs *regs) + { + struct vcpu *v = current; +- unsigned long *reg, eip = regs->eip, cs = regs->cs, res; +- u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0; +- unsigned int port, i, op_bytes = 4, data, rc; ++ unsigned long *reg, eip = regs->eip, res; ++ u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0, rex = 0; ++ enum { lm_seg_none, lm_seg_fs, lm_seg_gs } lm_ovr = lm_seg_none; ++ unsigned int port, i, data_sel, ar, data, rc; ++ unsigned int op_bytes, op_default, ad_bytes, ad_default; ++#define rd_ad(reg) (ad_bytes >= sizeof(regs->reg) \ ++ ? regs->reg \ ++ : ad_bytes == 4 \ ++ ? (u32)regs->reg \ ++ : (u16)regs->reg) ++#define wr_ad(reg, val) (ad_bytes >= sizeof(regs->reg) \ ++ ? regs->reg = (val) \ ++ : ad_bytes == 4 \ ++ ? (*(u32 *)®s->reg = (val)) \ ++ : (*(u16 *)®s->reg = (val))) ++ unsigned long code_base, code_limit; + char io_emul_stub[16]; + void (*io_emul)(struct cpu_user_regs *) __attribute__((__regparm__(1))); + u32 l, h; + ++ if ( !read_descriptor(regs->cs, v, regs, ++ &code_base, &code_limit, &ar, ++ _SEGMENT_CODE|_SEGMENT_S|_SEGMENT_DPL|_SEGMENT_P) ) ++ goto fail; ++ op_default = op_bytes = (ar & (_SEGMENT_L|_SEGMENT_DB)) ? 4 : 2; ++ ad_default = ad_bytes = (ar & _SEGMENT_L) ? 8 : op_default; ++ if ( !(ar & (_SEGMENT_CODE|_SEGMENT_S|_SEGMENT_P)) ) ++ goto fail; ++ ++ /* emulating only opcodes not allowing SS to be default */ ++ data_sel = read_sreg(regs, ds); ++ + /* Legacy prefixes. */ +- for ( i = 0; i < 8; i++ ) ++ for ( i = 0; i < 8; i++, rex == opcode || (rex = 0) ) + { +- switch ( opcode = insn_fetch(u8, 1, cs, eip) ) ++ switch ( opcode = insn_fetch(u8, code_base, eip, code_limit) ) + { + case 0x66: /* operand-size override */ +- op_bytes ^= 6; /* switch between 2/4 bytes */ +- break; ++ op_bytes = op_default ^ 6; /* switch between 2/4 bytes */ ++ continue; + case 0x67: /* address-size override */ ++ ad_bytes = ad_default != 4 ? 4 : 2; /* switch to 2/4 bytes */ ++ continue; + case 0x2e: /* CS override */ ++ data_sel = regs->cs; ++ continue; + case 0x3e: /* DS override */ ++ data_sel = read_sreg(regs, ds); ++ continue; + case 0x26: /* ES override */ ++ data_sel = read_sreg(regs, es); ++ continue; + case 0x64: /* FS override */ ++ data_sel = read_sreg(regs, fs); ++ lm_ovr = lm_seg_fs; ++ continue; + case 0x65: /* GS override */ ++ data_sel = read_sreg(regs, gs); ++ lm_ovr = lm_seg_gs; ++ continue; + case 0x36: /* SS override */ ++ data_sel = regs->ss; ++ continue; + case 0xf0: /* LOCK */ ++ continue; + case 0xf2: /* REPNE/REPNZ */ +- break; + case 0xf3: /* REP/REPE/REPZ */ + rep_prefix = 1; +- break; ++ continue; + default: +- goto done_prefixes; ++ if ( (ar & _SEGMENT_L) && (opcode & 0xf0) == 0x40 ) ++ { ++ rex = opcode; ++ continue; ++ } ++ break; + } ++ break; + } +- done_prefixes: + +-#ifdef __x86_64__ + /* REX prefix. */ +- if ( (opcode & 0xf0) == 0x40 ) +- { +- modrm_reg = (opcode & 4) << 1; /* REX.R */ +- modrm_rm = (opcode & 1) << 3; /* REX.B */ +- +- /* REX.W and REX.X do not need to be decoded. */ +- opcode = insn_fetch(u8, 1, cs, eip); +- } +-#endif ++ if ( rex & 8 ) /* REX.W */ ++ op_bytes = 4; /* emulating only opcodes not supporting 64-bit operands */ ++ modrm_reg = (rex & 4) << 1; /* REX.R */ ++ /* REX.X does not need to be decoded. */ ++ modrm_rm = (rex & 1) << 3; /* REX.B */ + + if ( opcode == 0x0f ) + goto twobyte_opcode; +@@ -1123,16 +1229,68 @@ static int emulate_privileged_op(struct + /* Input/Output String instructions. */ + if ( (opcode >= 0x6c) && (opcode <= 0x6f) ) + { +- if ( rep_prefix && (regs->ecx == 0) ) ++ unsigned long data_base, data_limit; ++ ++ if ( rep_prefix && (rd_ad(ecx) == 0) ) + goto done; + ++ if ( !(opcode & 2) ) ++ { ++ data_sel = read_sreg(regs, es); ++ lm_ovr = lm_seg_none; ++ } ++ ++ if ( !(ar & _SEGMENT_L) ) ++ { ++ if ( !read_descriptor(data_sel, v, regs, ++ &data_base, &data_limit, &ar, ++ _SEGMENT_WR|_SEGMENT_S|_SEGMENT_DPL|_SEGMENT_P) ) ++ goto fail; ++ if ( !(ar & (_SEGMENT_S|_SEGMENT_P)) || ++ (opcode & 2 ? ++ (ar & _SEGMENT_CODE) && !(ar & _SEGMENT_WR) : ++ (ar & _SEGMENT_CODE) || !(ar & _SEGMENT_WR)) ) ++ goto fail; ++ } ++#ifdef CONFIG_X86_64 ++ else ++ { ++ if ( lm_ovr == lm_seg_none || data_sel < 4 ) ++ { ++ switch ( lm_ovr ) ++ { ++ case lm_seg_none: ++ data_base = 0UL; ++ break; ++ case lm_seg_fs: ++ data_base = v->arch.guest_context.fs_base; ++ break; ++ case lm_seg_gs: ++ if ( guest_kernel_mode(v, regs) ) ++ data_base = v->arch.guest_context.gs_base_kernel; ++ else ++ data_base = v->arch.guest_context.gs_base_user; ++ break; ++ } ++ } ++ else ++ read_descriptor(data_sel, v, regs, ++ &data_base, &data_limit, &ar, ++ 0); ++ data_limit = ~0UL; ++ ar = _SEGMENT_WR|_SEGMENT_S|_SEGMENT_DPL|_SEGMENT_P; ++ } ++#endif ++ + continue_io_string: + switch ( opcode ) + { + case 0x6c: /* INSB */ + op_bytes = 1; + case 0x6d: /* INSW/INSL */ +- if ( !guest_io_okay((u16)regs->edx, op_bytes, v, regs) ) ++ if ( data_limit < op_bytes - 1 || ++ rd_ad(edi) > data_limit - (op_bytes - 1) || ++ !guest_io_okay((u16)regs->edx, op_bytes, v, regs) ) + goto fail; + port = (u16)regs->edx; + switch ( op_bytes ) +@@ -1150,24 +1308,26 @@ static int emulate_privileged_op(struct + data = (u32)(guest_inl_okay(port, v, regs) ? inl(port) : ~0); + break; + } +- if ( (rc = copy_to_user((void *)regs->edi, &data, op_bytes)) != 0 ) ++ if ( (rc = copy_to_user((void *)data_base + rd_ad(edi), &data, op_bytes)) != 0 ) + { +- propagate_page_fault(regs->edi + op_bytes - rc, ++ propagate_page_fault(data_base + rd_ad(edi) + op_bytes - rc, + PFEC_write_access); + return EXCRET_fault_fixed; + } +- regs->edi += (int)((regs->eflags & EF_DF) ? -op_bytes : op_bytes); ++ wr_ad(edi, regs->edi + (int)((regs->eflags & EF_DF) ? -op_bytes : op_bytes)); + break; + + case 0x6e: /* OUTSB */ + op_bytes = 1; + case 0x6f: /* OUTSW/OUTSL */ +- if ( !guest_io_okay((u16)regs->edx, op_bytes, v, regs) ) ++ if ( data_limit < op_bytes - 1 || ++ rd_ad(esi) > data_limit - (op_bytes - 1) || ++ !guest_io_okay((u16)regs->edx, op_bytes, v, regs) ) + goto fail; +- rc = copy_from_user(&data, (void *)regs->esi, op_bytes); ++ rc = copy_from_user(&data, (void *)data_base + rd_ad(esi), op_bytes); + if ( rc != 0 ) + { +- propagate_page_fault(regs->esi + op_bytes - rc, 0); ++ propagate_page_fault(data_base + rd_ad(esi) + op_bytes - rc, 0); + return EXCRET_fault_fixed; + } + port = (u16)regs->edx; +@@ -1188,11 +1348,11 @@ static int emulate_privileged_op(struct + outl((u32)data, port); + break; + } +- regs->esi += (int)((regs->eflags & EF_DF) ? -op_bytes : op_bytes); ++ wr_ad(esi, regs->esi + (int)((regs->eflags & EF_DF) ? -op_bytes : op_bytes)); + break; + } + +- if ( rep_prefix && (--regs->ecx != 0) ) ++ if ( rep_prefix && (wr_ad(ecx, regs->ecx - 1) != 0) ) + { + if ( !hypercall_preempt_check() ) + goto continue_io_string; +@@ -1232,7 +1392,7 @@ static int emulate_privileged_op(struct + case 0xe4: /* IN imm8,%al */ + op_bytes = 1; + case 0xe5: /* IN imm8,%eax */ +- port = insn_fetch(u8, 1, cs, eip); ++ port = insn_fetch(u8, code_base, eip, code_limit); + io_emul_stub[7] = port; /* imm8 */ + exec_in: + if ( !guest_io_okay(port, op_bytes, v, regs) ) +@@ -1274,7 +1434,7 @@ static int emulate_privileged_op(struct + case 0xe6: /* OUT %al,imm8 */ + op_bytes = 1; + case 0xe7: /* OUT %eax,imm8 */ +- port = insn_fetch(u8, 1, cs, eip); ++ port = insn_fetch(u8, code_base, eip, code_limit); + io_emul_stub[7] = port; /* imm8 */ + exec_out: + if ( !guest_io_okay(port, op_bytes, v, regs) ) +@@ -1327,7 +1487,7 @@ static int emulate_privileged_op(struct + goto fail; + + /* Privileged (ring 0) instructions. */ +- opcode = insn_fetch(u8, 1, cs, eip); ++ opcode = insn_fetch(u8, code_base, eip, code_limit); + switch ( opcode ) + { + case 0x06: /* CLTS */ +@@ -1345,7 +1505,7 @@ static int emulate_privileged_op(struct + break; + + case 0x20: /* MOV CR?, */ +- opcode = insn_fetch(u8, 1, cs, eip); ++ opcode = insn_fetch(u8, code_base, eip, code_limit); + modrm_reg |= (opcode >> 3) & 7; + modrm_rm |= (opcode >> 0) & 7; + reg = decode_register(modrm_rm, regs, 0); +@@ -1361,8 +1521,14 @@ static int emulate_privileged_op(struct + break; + + case 3: /* Read CR3 */ +- *reg = xen_pfn_to_cr3(mfn_to_gmfn( +- v->domain, pagetable_get_pfn(v->arch.guest_table))); ++ if ( !IS_COMPAT(v->domain) ) ++ *reg = xen_pfn_to_cr3(mfn_to_gmfn( ++ v->domain, pagetable_get_pfn(v->arch.guest_table))); ++#ifdef CONFIG_COMPAT ++ else ++ *reg = compat_pfn_to_cr3(mfn_to_gmfn( ++ v->domain, l4e_get_pfn(*(l4_pgentry_t *)__va(pagetable_get_paddr(v->arch.guest_table))))); ++#endif + break; + + case 4: /* Read CR4 */ +@@ -1379,7 +1545,7 @@ static int emulate_privileged_op(struct + break; + + case 0x21: /* MOV DR?, */ +- opcode = insn_fetch(u8, 1, cs, eip); ++ opcode = insn_fetch(u8, code_base, eip, code_limit); + modrm_reg |= (opcode >> 3) & 7; + modrm_rm |= (opcode >> 0) & 7; + reg = decode_register(modrm_rm, regs, 0); +@@ -1389,7 +1555,7 @@ static int emulate_privileged_op(struct + break; + + case 0x22: /* MOV ,CR? */ +- opcode = insn_fetch(u8, 1, cs, eip); ++ opcode = insn_fetch(u8, code_base, eip, code_limit); + modrm_reg |= (opcode >> 3) & 7; + modrm_rm |= (opcode >> 0) & 7; + reg = decode_register(modrm_rm, regs, 0); +@@ -1412,7 +1578,12 @@ static int emulate_privileged_op(struct + + case 3: /* Write CR3 */ + LOCK_BIGLOCK(v->domain); +- rc = new_guest_cr3(gmfn_to_mfn(v->domain, xen_cr3_to_pfn(*reg))); ++ if ( !IS_COMPAT(v->domain) ) ++ rc = new_guest_cr3(gmfn_to_mfn(v->domain, xen_cr3_to_pfn(*reg))); ++#ifdef CONFIG_COMPAT ++ else ++ rc = new_guest_cr3(gmfn_to_mfn(v->domain, compat_cr3_to_pfn(*reg))); ++#endif + UNLOCK_BIGLOCK(v->domain); + if ( rc == 0 ) /* not okay */ + goto fail; +@@ -1432,7 +1603,7 @@ static int emulate_privileged_op(struct + break; + + case 0x23: /* MOV ,DR? */ +- opcode = insn_fetch(u8, 1, cs, eip); ++ opcode = insn_fetch(u8, code_base, eip, code_limit); + modrm_reg |= (opcode >> 3) & 7; + modrm_rm |= (opcode >> 0) & 7; + reg = decode_register(modrm_rm, regs, 0); +@@ -1445,18 +1616,24 @@ static int emulate_privileged_op(struct + { + #ifdef CONFIG_X86_64 + case MSR_FS_BASE: ++ if ( IS_COMPAT(v->domain) ) ++ goto fail; + if ( wrmsr_safe(MSR_FS_BASE, regs->eax, regs->edx) ) + goto fail; + v->arch.guest_context.fs_base = + ((u64)regs->edx << 32) | regs->eax; + break; + case MSR_GS_BASE: ++ if ( IS_COMPAT(v->domain) ) ++ goto fail; + if ( wrmsr_safe(MSR_GS_BASE, regs->eax, regs->edx) ) + goto fail; + v->arch.guest_context.gs_base_kernel = + ((u64)regs->edx << 32) | regs->eax; + break; + case MSR_SHADOW_GS_BASE: ++ if ( IS_COMPAT(v->domain) ) ++ goto fail; + if ( wrmsr_safe(MSR_SHADOW_GS_BASE, regs->eax, regs->edx) ) + goto fail; + v->arch.guest_context.gs_base_user = +@@ -1481,14 +1658,20 @@ static int emulate_privileged_op(struct + { + #ifdef CONFIG_X86_64 + case MSR_FS_BASE: ++ if ( IS_COMPAT(v->domain) ) ++ goto fail; + regs->eax = v->arch.guest_context.fs_base & 0xFFFFFFFFUL; + regs->edx = v->arch.guest_context.fs_base >> 32; + break; + case MSR_GS_BASE: ++ if ( IS_COMPAT(v->domain) ) ++ goto fail; + regs->eax = v->arch.guest_context.gs_base_kernel & 0xFFFFFFFFUL; + regs->edx = v->arch.guest_context.gs_base_kernel >> 32; + break; + case MSR_SHADOW_GS_BASE: ++ if ( IS_COMPAT(v->domain) ) ++ goto fail; + regs->eax = v->arch.guest_context.gs_base_user & 0xFFFFFFFFUL; + regs->edx = v->arch.guest_context.gs_base_user >> 32; + break; +@@ -1517,6 +1700,9 @@ static int emulate_privileged_op(struct + goto fail; + } + ++#undef wr_ad ++#undef rd_ad ++ + done: + regs->eip = eip; + return EXCRET_fault_fixed; +Index: 2006-12-18/xen/arch/x86/x86_64/mm.c +=================================================================== +--- 2006-12-18.orig/xen/arch/x86/x86_64/mm.c 2006-12-18 17:53:11.000000000 +0100 ++++ 2006-12-18/xen/arch/x86/x86_64/mm.c 2006-12-18 09:49:18.000000000 +0100 +@@ -376,7 +376,11 @@ int check_descriptor(const struct domain + + /* All code and data segments are okay. No base/limit checking. */ + if ( (b & _SEGMENT_S) ) +- goto good; ++ { ++ if ( !IS_COMPAT(dom) || !(b & _SEGMENT_L) ) ++ goto good; ++ goto bad; ++ } + + /* Invalid type 0 is harmless. It is used for 2nd half of a call gate. */ + if ( (b & _SEGMENT_TYPE) == 0x000 ) +Index: 2006-12-18/xen/include/asm-x86/desc.h +=================================================================== +--- 2006-12-18.orig/xen/include/asm-x86/desc.h 2006-12-18 17:53:11.000000000 +0100 ++++ 2006-12-18/xen/include/asm-x86/desc.h 2006-12-18 09:49:18.000000000 +0100 +@@ -113,12 +113,19 @@ + + /* These are bitmasks for the high 32 bits of a descriptor table entry. */ + #define _SEGMENT_TYPE (15<< 8) ++#define _SEGMENT_WR ( 1<< 9) /* Writeable (data) or Readable (code) ++ segment */ + #define _SEGMENT_EC ( 1<<10) /* Expand-down or Conforming segment */ + #define _SEGMENT_CODE ( 1<<11) /* Code (vs data) segment for non-system + segments */ + #define _SEGMENT_S ( 1<<12) /* System descriptor (yes iff S==0) */ + #define _SEGMENT_DPL ( 3<<13) /* Descriptor Privilege Level */ + #define _SEGMENT_P ( 1<<15) /* Segment Present */ ++#ifdef __x86_64 ++#define _SEGMENT_L ( 1<<21) /* 64-bit segment */ ++#else ++#define _SEGMENT_L 0 ++#endif + #define _SEGMENT_DB ( 1<<22) /* 16- or 32-bit segment */ + #define _SEGMENT_G ( 1<<23) /* Granularity */ + +Index: 2006-12-18/xen/include/asm-x86/mm.h +=================================================================== +--- 2006-12-18.orig/xen/include/asm-x86/mm.h 2006-12-18 17:53:11.000000000 +0100 ++++ 2006-12-18/xen/include/asm-x86/mm.h 2006-12-18 09:49:18.000000000 +0100 +@@ -279,6 +279,11 @@ int check_descriptor(const struct domain + + #define INVALID_MFN (~0UL) + ++#ifdef CONFIG_COMPAT ++#define compat_pfn_to_cr3(pfn) (((unsigned)(pfn) << 12) | ((unsigned)(pfn) >> 20)) ++#define compat_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) << 20)) ++#endif ++ + #ifdef MEMORY_GUARD + void memguard_init(void); + void memguard_guard_range(void *p, unsigned long l); +Index: 2006-12-18/xen/include/asm-x86/x86_32/uaccess.h +=================================================================== +--- 2006-12-18.orig/xen/include/asm-x86/x86_32/uaccess.h 2006-12-18 17:53:11.000000000 +0100 ++++ 2006-12-18/xen/include/asm-x86/x86_32/uaccess.h 2006-12-18 09:49:18.000000000 +0100 +@@ -83,7 +83,7 @@ do { \ + case 2: __get_user_asm(x,ptr,retval,"w","w","=r",errret);break; \ + case 4: __get_user_asm(x,ptr,retval,"l","","=r",errret);break; \ + case 8: __get_user_u64(x,ptr,retval,errret);break; \ +- default: (x) = __get_user_bad(); \ ++ default: __get_user_bad(); \ + } \ + } while (0) + +Index: 2006-12-18/xen/include/asm-x86/x86_64/uaccess.h +=================================================================== +--- 2006-12-18.orig/xen/include/asm-x86/x86_64/uaccess.h 2006-12-18 17:53:11.000000000 +0100 ++++ 2006-12-18/xen/include/asm-x86/x86_64/uaccess.h 2006-12-18 09:49:18.000000000 +0100 +@@ -48,7 +48,7 @@ do { \ + case 2: __get_user_asm(x,ptr,retval,"w","w","=r",errret);break; \ + case 4: __get_user_asm(x,ptr,retval,"l","k","=r",errret);break; \ + case 8: __get_user_asm(x,ptr,retval,"q","","=r",errret); break; \ +- default: (x) = __get_user_bad(); \ ++ default: __get_user_bad(); \ + } \ + } while (0) + diff --git a/32on64-fixes.patch b/32on64-fixes.patch new file mode 100644 index 0000000..e279e81 --- /dev/null +++ b/32on64-fixes.patch @@ -0,0 +1,110 @@ +Index: 2007-01-08/xen/arch/x86/traps.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/traps.c 2007-01-25 13:53:38.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/traps.c 2007-01-25 16:01:23.000000000 +0100 +@@ -1162,7 +1162,9 @@ static int emulate_privileged_op(struct + goto fail; + op_default = op_bytes = (ar & (_SEGMENT_L|_SEGMENT_DB)) ? 4 : 2; + ad_default = ad_bytes = (ar & _SEGMENT_L) ? 8 : op_default; +- if ( !(ar & (_SEGMENT_CODE|_SEGMENT_S|_SEGMENT_P)) ) ++ if ( !(ar & _SEGMENT_S) || ++ !(ar & _SEGMENT_P) || ++ !(ar & _SEGMENT_CODE) ) + goto fail; + + /* emulating only opcodes not allowing SS to be default */ +@@ -1246,7 +1248,8 @@ static int emulate_privileged_op(struct + &data_base, &data_limit, &ar, + _SEGMENT_WR|_SEGMENT_S|_SEGMENT_DPL|_SEGMENT_P) ) + goto fail; +- if ( !(ar & (_SEGMENT_S|_SEGMENT_P)) || ++ if ( !(ar & _SEGMENT_S) || ++ !(ar & _SEGMENT_P) || + (opcode & 2 ? + (ar & _SEGMENT_CODE) && !(ar & _SEGMENT_WR) : + (ar & _SEGMENT_CODE) || !(ar & _SEGMENT_WR)) ) +Index: 2007-01-08/xen/arch/x86/x86_64/compat/entry.S +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/entry.S 2007-01-25 13:53:38.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_64/compat/entry.S 2007-01-25 16:01:22.000000000 +0100 +@@ -23,7 +23,9 @@ ENTRY(compat_hypercall) + movq %rsp,%rdi + movl $0xDEADBEEF,%eax + rep stosq +- popq %r9 ; popq %r8 ; popq %rcx; popq %rdx; popq %rsi; popq %rdi ++ popq %r8 ; popq %r9 ; xchgl %r8d,%r9d ++ popq %rdx; popq %rcx; xchgl %edx,%ecx ++ popq %rdi; popq %rsi; xchgl %edi,%esi + movl UREGS_rax(%rsp),%eax + pushq %rax + pushq UREGS_rip+8(%rsp) +@@ -31,8 +33,9 @@ ENTRY(compat_hypercall) + movl %eax,%eax + movl %ebp,%r9d + movl %edi,%r8d +- xchgl %ecx,%esi ++ xchgl %ecx,%esi + movl UREGS_rbx(%rsp),%edi ++ movl %edx,%edx + #endif + leaq compat_hypercall_table(%rip),%r10 + PERFC_INCR(PERFC_hypercalls, %rax) +Index: 2007-01-08/xen/arch/x86/x86_64/compat/mm.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/mm.c 2007-01-12 17:22:50.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_64/compat/mm.c 2007-01-10 16:06:16.000000000 +0100 +@@ -1,6 +1,7 @@ + #ifdef CONFIG_COMPAT + + #include ++#include + #include + #include + +@@ -289,20 +290,27 @@ int compat_mmuext_op(XEN_GUEST_HANDLE(mm + if ( err == __HYPERVISOR_mmuext_op ) + { + struct cpu_user_regs *regs = guest_cpu_user_regs(); +- unsigned int left = regs->ecx & ~MMU_UPDATE_PREEMPTED; ++ struct mc_state *mcs = &this_cpu(mc_state); ++ unsigned int arg1 = !test_bit(_MCSF_in_multicall, &mcs->flags) ++ ? regs->ecx ++ : mcs->call.args[1]; ++ unsigned int left = arg1 & ~MMU_UPDATE_PREEMPTED; + +- BUG_ON(!(regs->ecx & MMU_UPDATE_PREEMPTED)); ++ BUG_ON(left == arg1); + BUG_ON(left > count); + guest_handle_add_offset(nat_ops, count - left); + BUG_ON(left + i < count); + guest_handle_add_offset(cmp_uops, (signed int)(count - left - i)); + left = 1; + BUG_ON(!hypercall_xlat_continuation(&left, 0x01, nat_ops, cmp_uops)); +- BUG_ON(left != regs->ecx); +- regs->ecx += count - i; ++ BUG_ON(left != arg1); ++ if (!test_bit(_MCSF_in_multicall, &mcs->flags)) ++ regs->_ecx += count - i; ++ else ++ mcs->compat_call.args[1] += count - i; + } + else +- BUG_ON(rc > 0); ++ BUG_ON(err > 0); + rc = err; + } + +Index: 2007-01-08/xen/include/asm-x86/x86_64/uaccess.h +=================================================================== +--- 2007-01-08.orig/xen/include/asm-x86/x86_64/uaccess.h 2006-12-18 09:49:18.000000000 +0100 ++++ 2007-01-08/xen/include/asm-x86/x86_64/uaccess.h 2007-01-25 15:18:37.000000000 +0100 +@@ -20,7 +20,8 @@ + #define __compat_addr_ok(addr) \ + ((unsigned long)(addr) < HYPERVISOR_COMPAT_VIRT_START(current->domain)) + +-#define compat_access_ok(addr, size) __compat_addr_ok((addr) + (size)) ++#define compat_access_ok(addr, size) \ ++ __compat_addr_ok((unsigned long)(addr) + ((size) ? (size) - 1 : 0)) + + #define compat_array_access_ok(addr,count,size) \ + (likely((count) < (~0U / (size))) && \ diff --git a/32on64-gnttabop.patch b/32on64-gnttabop.patch new file mode 100644 index 0000000..f75b544 --- /dev/null +++ b/32on64-gnttabop.patch @@ -0,0 +1,281 @@ +Enable compatibility mode operation for HYPERVISOR_grant_table_op. + +Index: 2006-12-18/xen/arch/x86/x86_64/compat/entry.S +=================================================================== +--- 2006-12-18.orig/xen/arch/x86/x86_64/compat/entry.S 2006-12-18 09:49:57.000000000 +0100 ++++ 2006-12-18/xen/arch/x86/x86_64/compat/entry.S 2006-12-18 09:50:00.000000000 +0100 +@@ -279,7 +279,6 @@ CFIX14: + .section .rodata, "a", @progbits + + #define compat_platform_op domain_crash_synchronous +-#define compat_grant_table_op domain_crash_synchronous + #define compat_acm_op domain_crash_synchronous + #define compat_xenoprof_op domain_crash_synchronous + #define compat_sysctl domain_crash_synchronous +Index: 2006-12-18/xen/common/Makefile +=================================================================== +--- 2006-12-18.orig/xen/common/Makefile 2006-12-18 09:49:57.000000000 +0100 ++++ 2006-12-18/xen/common/Makefile 2006-12-18 09:50:00.000000000 +0100 +@@ -42,5 +42,6 @@ version.o: $(BASEDIR)/include/xen/compil + + ifeq ($(CONFIG_COMPAT),y) + # extra dependencies ++grant_table.o: compat/grant_table.c + schedule.o: compat/schedule.c + endif +Index: 2006-12-18/xen/common/compat/grant_table.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2006-12-18/xen/common/compat/grant_table.c 2006-12-18 09:50:00.000000000 +0100 +@@ -0,0 +1,218 @@ ++/****************************************************************************** ++ * common/compat/grant_table.c ++ * ++ */ ++ ++#include ++ ++#define xen_grant_entry grant_entry ++CHECK_grant_entry; ++#undef xen_grant_entry ++ ++#define xen_gnttab_map_grant_ref gnttab_map_grant_ref ++CHECK_gnttab_map_grant_ref; ++#undef xen_gnttab_map_grant_ref ++ ++#define xen_gnttab_unmap_grant_ref gnttab_unmap_grant_ref ++CHECK_gnttab_unmap_grant_ref; ++#undef xen_gnttab_unmap_grant_ref ++ ++DEFINE_XEN_GUEST_HANDLE(gnttab_setup_table_compat_t); ++DEFINE_XEN_GUEST_HANDLE(gnttab_transfer_compat_t); ++DEFINE_XEN_GUEST_HANDLE(gnttab_copy_compat_t); ++ ++#define xen_gnttab_dump_table gnttab_dump_table ++CHECK_gnttab_dump_table; ++#undef xen_gnttab_dump_table ++ ++int compat_grant_table_op(unsigned int cmd, ++ XEN_GUEST_HANDLE(void) cmp_uop, ++ unsigned int count) ++{ ++ int rc = 0; ++ unsigned int i; ++ ++ switch ( cmd ) ++ { ++#define CASE(name) \ ++ case GNTTABOP_##name: \ ++ if ( unlikely(!guest_handle_okay(guest_handle_cast(cmp_uop, \ ++ gnttab_##name##_compat_t), \ ++ count)) ) \ ++ rc = -EFAULT; \ ++ break ++ ++#ifndef CHECK_gnttab_map_grant_ref ++ CASE(map_grant_ref); ++#endif ++ ++#ifndef CHECK_gnttab_unmap_grant_ref ++ CASE(unmap_grant_ref); ++#endif ++ ++#ifndef CHECK_gnttab_setup_table ++ CASE(setup_table); ++#endif ++ ++#ifndef CHECK_gnttab_transfer ++ CASE(transfer); ++#endif ++ ++#ifndef CHECK_gnttab_copy ++ CASE(copy); ++#endif ++ ++#ifndef CHECK_gnttab_dump_table ++ CASE(dump_table); ++#endif ++ ++#undef CASE ++ default: ++ return do_grant_table_op(cmd, cmp_uop, count); ++ } ++ ++ if ( count > 512 ) ++ rc = -EINVAL; ++ ++ for ( i = 0; i < count && rc == 0; ) ++ { ++ unsigned int n; ++ union { ++ XEN_GUEST_HANDLE(void) uop; ++ struct gnttab_setup_table *setup; ++ struct gnttab_transfer *xfer; ++ struct gnttab_copy *copy; ++ } nat; ++ union { ++ struct compat_gnttab_setup_table setup; ++ struct compat_gnttab_transfer xfer; ++ struct compat_gnttab_copy copy; ++ } cmp; ++ ++ set_xen_guest_handle(nat.uop, (void *)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id)); ++ switch ( cmd ) ++ { ++ case GNTTABOP_setup_table: ++ if ( unlikely(count > 1) ) ++ rc = -EINVAL; ++ else if ( unlikely(__copy_from_guest(&cmp.setup, cmp_uop, 1)) ) ++ rc = -EFAULT; ++ else if ( unlikely(!compat_handle_okay(cmp.setup.frame_list, cmp.setup.nr_frames)) ) ++ rc = -EFAULT; ++ else ++ { ++ BUILD_BUG_ON((COMPAT_ARG_XLAT_SIZE - sizeof(*nat.setup)) / sizeof(*nat.setup->frame_list.p) < NR_GRANT_FRAMES); ++#define XLAT_gnttab_setup_table_HNDL_frame_list(_d_, _s_) \ ++ set_xen_guest_handle((_d_)->frame_list, (unsigned long *)(nat.setup + 1)) ++ XLAT_gnttab_setup_table(nat.setup, &cmp.setup); ++#undef XLAT_gnttab_setup_table_HNDL_frame_list ++ rc = gnttab_setup_table(guest_handle_cast(nat.uop, gnttab_setup_table_t), 1); ++ } ++ if ( rc == 0 ) ++ { ++ BUG_ON(nat.setup->nr_frames > NR_GRANT_FRAMES); ++#define XLAT_gnttab_setup_table_HNDL_frame_list(_d_, _s_) \ ++ do \ ++ { \ ++ if ( (_s_)->status == GNTST_okay ) \ ++ { \ ++ for ( i = 0; i < (_s_)->nr_frames; ++i ) \ ++ { \ ++ unsigned int frame = (_s_)->frame_list.p[i]; \ ++ BUG_ON(frame != (_s_)->frame_list.p[i]); \ ++ (void)__copy_to_compat_offset((_d_)->frame_list, i, &frame, 1); \ ++ } \ ++ } \ ++ } while (0) ++ XLAT_gnttab_setup_table(&cmp.setup, nat.setup); ++#undef XLAT_gnttab_setup_table_HNDL_frame_list ++ if ( unlikely(__copy_to_guest(cmp_uop, &cmp.setup, 1)) ) ++ rc = -EFAULT; ++ else ++ i = 1; ++ } ++ break; ++ ++ case GNTTABOP_transfer: ++ for ( n = 0; i < COMPAT_ARG_XLAT_SIZE / sizeof(*nat.xfer) && i < count && rc == 0; ++i, ++n ) ++ { ++ if ( unlikely(__copy_from_guest_offset(&cmp.xfer, cmp_uop, i, 1)) ) ++ rc = -EFAULT; ++ else ++ { ++ XLAT_gnttab_transfer(nat.xfer + n, &cmp.xfer); ++ } ++ } ++ if ( rc == 0 ) ++ rc = gnttab_transfer(guest_handle_cast(nat.uop, gnttab_transfer_t), n); ++ if ( rc == 0 ) ++ { ++ XEN_GUEST_HANDLE(gnttab_transfer_compat_t) xfer; ++ ++ xfer = guest_handle_cast(cmp_uop, gnttab_transfer_compat_t); ++ guest_handle_add_offset(xfer, i); ++ while ( n-- ) ++ { ++ guest_handle_add_offset(xfer, -1); ++ if ( __copy_field_to_guest(xfer, nat.xfer, status) ) ++ rc = -EFAULT; ++ } ++ } ++ break; ++ ++ case GNTTABOP_copy: ++ for ( n = 0; i < COMPAT_ARG_XLAT_SIZE / sizeof(*nat.copy) && i < count && rc == 0; ++i, ++n ) ++ { ++ if ( unlikely(__copy_from_guest_offset(&cmp.copy, cmp_uop, i, 1)) ) ++ rc = -EFAULT; ++ else ++ { ++ enum XLAT_gnttab_copy_source_u source_u; ++ enum XLAT_gnttab_copy_dest_u dest_u; ++ ++ if ( cmp.copy.flags & GNTCOPY_source_gref ) ++ source_u = XLAT_gnttab_copy_source_u_ref; ++ else ++ source_u = XLAT_gnttab_copy_source_u_gmfn; ++ if ( cmp.copy.flags & GNTCOPY_dest_gref ) ++ dest_u = XLAT_gnttab_copy_dest_u_ref; ++ else ++ dest_u = XLAT_gnttab_copy_dest_u_gmfn; ++ XLAT_gnttab_copy(nat.copy + n, &cmp.copy); ++ } ++ } ++ if ( rc == 0 ) ++ rc = gnttab_copy(guest_handle_cast(nat.uop, gnttab_copy_t), n); ++ if ( rc == 0 ) ++ { ++ XEN_GUEST_HANDLE(gnttab_copy_compat_t) copy; ++ ++ copy = guest_handle_cast(cmp_uop, gnttab_copy_compat_t); ++ guest_handle_add_offset(copy, i); ++ while ( n-- ) ++ { ++ guest_handle_add_offset(copy, -1); ++ if ( __copy_field_to_guest(copy, nat.copy, status) ) ++ rc = -EFAULT; ++ } ++ } ++ break; ++ ++ default: ++ domain_crash(current->domain); ++ break; ++ } ++ } ++ ++ return rc; ++} ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * tab-width: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ +Index: 2006-12-18/xen/common/grant_table.c +=================================================================== +--- 2006-12-18.orig/xen/common/grant_table.c 2006-12-13 11:15:54.000000000 +0100 ++++ 2006-12-18/xen/common/grant_table.c 2006-12-18 09:50:00.000000000 +0100 +@@ -1048,6 +1048,10 @@ do_grant_table_op( + return rc; + } + ++#ifdef CONFIG_COMPAT ++#include "compat/grant_table.c" ++#endif ++ + int + grant_table_create( + struct domain *d) +Index: 2006-12-18/xen/include/xlat.lst +=================================================================== +--- 2006-12-18.orig/xen/include/xlat.lst 2006-12-18 09:49:57.000000000 +0100 ++++ 2006-12-18/xen/include/xlat.lst 2006-12-18 09:50:00.000000000 +0100 +@@ -20,6 +20,13 @@ + ? evtchn_send event_channel.h + ? evtchn_status event_channel.h + ? evtchn_unmask event_channel.h ++! gnttab_copy grant_table.h ++? gnttab_dump_table grant_table.h ++? gnttab_map_grant_ref grant_table.h ++! gnttab_setup_table grant_table.h ++! gnttab_transfer grant_table.h ++? gnttab_unmap_grant_ref grant_table.h ++? grant_entry grant_table.h + ! add_to_physmap memory.h + ! foreign_memory_map memory.h + ! memory_exchange memory.h diff --git a/32on64-hvm.patch b/32on64-hvm.patch new file mode 100644 index 0000000..471b482 --- /dev/null +++ b/32on64-hvm.patch @@ -0,0 +1,184 @@ +unstable c/s 13276: Support for save and restore of compatibility guests + +Signed-off-by: Emmanuel Ackaouy + +unstable c/s 13279: Initial support for HVM compat guests + +Signed-off-by: Emmanuel Ackaouy + +Index: 2007-01-31/tools/libxc/xc_linux_save.c +=================================================================== +--- 2007-01-31.orig/tools/libxc/xc_linux_save.c 2007-01-31 09:19:49.000000000 +0100 ++++ 2007-01-31/tools/libxc/xc_linux_save.c 2007-01-31 09:33:01.000000000 +0100 +@@ -44,6 +44,7 @@ static xen_pfn_t *live_p2m = NULL; + + /* Live mapping of system MFN to PFN table. */ + static xen_pfn_t *live_m2p = NULL; ++static unsigned long m2p_mfn0; + + /* grep fodder: machine_to_phys */ + +@@ -467,13 +468,23 @@ static int canonicalize_pagetable(unsign + ** that this check will fail for other L2s. + */ + if (pt_levels == 3 && type == XEN_DOMCTL_PFINFO_L2TAB) { ++ int hstart; ++ unsigned long he; + +-/* XXX index of the L2 entry in PAE mode which holds the guest LPT */ +-#define PAE_GLPT_L2ENTRY (495) +- pte = ((const uint64_t*)spage)[PAE_GLPT_L2ENTRY]; ++ hstart = (hvirt_start >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff; ++ he = ((const uint64_t *) spage)[hstart]; + +- if(((pte >> PAGE_SHIFT) & 0x0fffffff) == live_p2m[pfn]) +- xen_start = (hvirt_start >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff; ++ if ( ((he >> PAGE_SHIFT) & 0x0fffffff) == m2p_mfn0 ) { ++ /* hvirt starts with xen stuff... */ ++ xen_start = hstart; ++ } else if ( hvirt_start != 0xf5800000 ) { ++ /* old L2s from before hole was shrunk... */ ++ hstart = (0xf5800000 >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff; ++ he = ((const uint64_t *) spage)[hstart]; ++ ++ if( ((he >> PAGE_SHIFT) & 0x0fffffff) == m2p_mfn0 ) ++ xen_start = hstart; ++ } + } + + if (pt_levels == 4 && type == XEN_DOMCTL_PFINFO_L4TAB) { +@@ -577,6 +588,8 @@ static xen_pfn_t *xc_map_m2p(int xc_hand + return NULL; + } + ++ m2p_mfn0 = entries[0].mfn; ++ + free(extent_start); + free(entries); + +Index: 2007-01-31/tools/libxc/xg_save_restore.h +=================================================================== +--- 2007-01-31.orig/tools/libxc/xg_save_restore.h 2007-01-08 14:16:35.000000000 +0100 ++++ 2007-01-31/tools/libxc/xg_save_restore.h 2007-01-31 09:33:01.000000000 +0100 +@@ -53,8 +53,17 @@ static int get_platform_info(int xc_hand + + *hvirt_start = xen_params.virt_start; + ++ /* ++ * XXX For now, 32bit dom0's can only save/restore 32bit domUs ++ * on 64bit hypervisors, so no need to check which type of domain ++ * we're dealing with. ++ */ + if (strstr(xen_caps, "xen-3.0-x86_64")) ++#if defined(__i386__) ++ *pt_levels = 3; ++#else + *pt_levels = 4; ++#endif + else if (strstr(xen_caps, "xen-3.0-x86_32p")) + *pt_levels = 3; + else if (strstr(xen_caps, "xen-3.0-x86_32")) +Index: 2007-01-31/xen/arch/x86/domain.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/domain.c 2007-01-31 09:31:01.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/domain.c 2007-01-31 09:34:52.000000000 +0100 +@@ -1405,7 +1405,11 @@ void domain_relinquish_resources(struct + #ifdef CONFIG_COMPAT + if ( IS_COMPAT(d) ) + { +- pfn = l4e_get_pfn(*(l4_pgentry_t *)__va(pagetable_get_paddr(v->arch.guest_table))); ++ if ( is_hvm_vcpu(v) ) ++ pfn = pagetable_get_pfn(v->arch.guest_table); ++ else ++ pfn = l4e_get_pfn(*(l4_pgentry_t *)__va(pagetable_get_paddr(v->arch.guest_table))); ++ + if ( pfn != 0 ) + { + if ( shadow_mode_refcounts(d) ) +Index: 2007-01-31/xen/arch/x86/domctl.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/domctl.c 2007-01-31 09:29:26.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/domctl.c 2007-01-31 09:33:01.000000000 +0100 +@@ -356,7 +356,10 @@ void arch_get_info_guest(struct vcpu *v, + c.nat->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); + #ifdef CONFIG_COMPAT + else +- c.cmp->ctrlreg[3] = compat_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); ++ { ++ l4_pgentry_t *l4e = __va(pagetable_get_paddr(v->arch.guest_table)); ++ c.cmp->ctrlreg[3] = compat_pfn_to_cr3(l4e_get_pfn(*l4e)); ++ } + #endif + + c(vm_assist = v->domain->vm_assist); +Index: 2007-01-31/xen/arch/x86/hvm/intercept.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/hvm/intercept.c 2006-12-13 11:15:53.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/hvm/intercept.c 2007-01-31 09:34:52.000000000 +0100 +@@ -180,7 +180,7 @@ int hvm_buffered_io_intercept(ioreq_t *p + spin_lock(buffered_io_lock); + + if ( buffered_iopage->write_pointer - buffered_iopage->read_pointer == +- (unsigned long)IOREQ_BUFFER_SLOT_NUM ) { ++ (unsigned int)IOREQ_BUFFER_SLOT_NUM ) { + /* the queue is full. + * send the iopacket through the normal path. + * NOTE: The arithimetic operation could handle the situation for +Index: 2007-01-31/xen/arch/x86/x86_64/compat/entry.S +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/x86_64/compat/entry.S 2007-01-31 09:29:27.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/x86_64/compat/entry.S 2007-01-31 09:34:52.000000000 +0100 +@@ -313,7 +313,7 @@ ENTRY(compat_hypercall_table) + .quad compat_xenoprof_op + .quad do_event_channel_op + .quad compat_physdev_op +- .quad compat_ni_hypercall ++ .quad do_hvm_op + .quad compat_sysctl /* 35 */ + .quad compat_domctl + .quad compat_kexec_op +@@ -356,7 +356,7 @@ ENTRY(compat_hypercall_args_table) + .byte 2 /* compat_xenoprof_op */ + .byte 2 /* compat_event_channel_op */ + .byte 2 /* compat_physdev_op */ +- .byte 0 /* compat_ni_hypercall */ ++ .byte 2 /* do_hvm_op */ + .byte 1 /* compat_sysctl */ /* 35 */ + .byte 1 /* compat_domctl */ + .byte 2 /* compat_kexec_op */ +Index: 2007-01-31/xen/include/asm-x86/x86_64/page.h +=================================================================== +--- 2007-01-31.orig/xen/include/asm-x86/x86_64/page.h 2007-01-31 09:29:11.000000000 +0100 ++++ 2007-01-31/xen/include/asm-x86/x86_64/page.h 2007-01-31 09:33:01.000000000 +0100 +@@ -96,7 +96,7 @@ typedef l4_pgentry_t root_pgentry_t; + #define L3_DISALLOW_MASK (BASE_DISALLOW_MASK | 0x180U /* must-be-zero */) + #define L4_DISALLOW_MASK (BASE_DISALLOW_MASK | 0x180U /* must-be-zero */) + +-#define COMPAT_L3_DISALLOW_MASK 0xFFFFF1E6U /* must-be-zero */ ++#define COMPAT_L3_DISALLOW_MASK L3_DISALLOW_MASK + + #define PAGE_HYPERVISOR (__PAGE_HYPERVISOR | _PAGE_GLOBAL) + #define PAGE_HYPERVISOR_NOCACHE (__PAGE_HYPERVISOR_NOCACHE | _PAGE_GLOBAL) +Index: 2007-01-31/xen/include/public/hvm/ioreq.h +=================================================================== +--- 2007-01-31.orig/xen/include/public/hvm/ioreq.h 2006-12-13 11:15:56.000000000 +0100 ++++ 2007-01-31/xen/include/public/hvm/ioreq.h 2007-01-31 09:34:52.000000000 +0100 +@@ -56,6 +56,7 @@ struct ioreq { + uint8_t dir:1; /* 1=read, 0=write */ + uint8_t df:1; + uint8_t type; /* I/O type */ ++ uint8_t _pad0[6]; + uint64_t io_count; /* How many IO done on a vcpu */ + }; + typedef struct ioreq ioreq_t; +@@ -74,8 +75,8 @@ typedef struct shared_iopage shared_iopa + + #define IOREQ_BUFFER_SLOT_NUM 80 + struct buffered_iopage { +- unsigned long read_pointer; +- unsigned long write_pointer; ++ unsigned int read_pointer; ++ unsigned int write_pointer; + ioreq_t ioreq[IOREQ_BUFFER_SLOT_NUM]; + }; /* sizeof this structure must be in one page */ + typedef struct buffered_iopage buffered_iopage_t; diff --git a/32on64-hypercall.patch b/32on64-hypercall.patch new file mode 100644 index 0000000..1c9b08b --- /dev/null +++ b/32on64-hypercall.patch @@ -0,0 +1,900 @@ +Add entry points for handling hypercalls from and returning to +compatibility mode guests. + +Index: 2006-12-18/xen/arch/x86/traps.c +=================================================================== +--- 2006-12-18.orig/xen/arch/x86/traps.c 2006-12-18 09:37:45.000000000 +0100 ++++ 2006-12-18/xen/arch/x86/traps.c 2006-12-18 09:43:08.000000000 +0100 +@@ -139,6 +139,12 @@ static void show_guest_stack(struct cpu_ + if ( is_hvm_vcpu(current) ) + return; + ++ if ( IS_COMPAT(container_of(regs, struct cpu_info, guest_cpu_user_regs)->current_vcpu->domain) ) ++ { ++ compat_show_guest_stack(regs, debug_stack_lines); ++ return; ++ } ++ + if ( vm86_mode(regs) ) + { + stack = (unsigned long *)((regs->ss << 4) + (regs->esp & 0xffff)); +Index: 2006-12-18/xen/arch/x86/x86_64/Makefile +=================================================================== +--- 2006-12-18.orig/xen/arch/x86/x86_64/Makefile 2006-12-13 11:15:54.000000000 +0100 ++++ 2006-12-18/xen/arch/x86/x86_64/Makefile 2006-12-18 09:43:08.000000000 +0100 +@@ -2,3 +2,9 @@ obj-y += entry.o + obj-y += gpr_switch.o + obj-y += mm.o + obj-y += traps.o ++ ++ifeq ($(CONFIG_COMPAT),y) ++# extra dependencies ++entry.o: compat/entry.S ++traps.o: compat/traps.c ++endif +Index: 2006-12-18/xen/arch/x86/x86_64/asm-offsets.c +=================================================================== +--- 2006-12-18.orig/xen/arch/x86/x86_64/asm-offsets.c 2006-12-18 09:37:45.000000000 +0100 ++++ 2006-12-18/xen/arch/x86/x86_64/asm-offsets.c 2006-12-18 09:43:08.000000000 +0100 +@@ -53,6 +53,7 @@ void __dummy__(void) + BLANK(); + + OFFSET(VCPU_processor, struct vcpu, processor); ++ OFFSET(VCPU_domain, struct vcpu, domain); + OFFSET(VCPU_vcpu_info, struct vcpu, vcpu_info); + OFFSET(VCPU_trap_bounce, struct vcpu, arch.trap_bounce); + OFFSET(VCPU_thread_flags, struct vcpu, arch.flags); +@@ -87,6 +88,10 @@ void __dummy__(void) + OFFSET(VCPU_vmx_cr2, struct vcpu, arch.hvm_vmx.cpu_cr2); + BLANK(); + ++ OFFSET(DOMAIN_domain_flags, struct domain, domain_flags); ++ DEFINE(_DOMF_compat, _DOMF_compat); ++ BLANK(); ++ + OFFSET(VMCB_rax, struct vmcb_struct, rax); + OFFSET(VMCB_tsc_offset, struct vmcb_struct, tsc_offset); + BLANK(); +@@ -95,6 +100,7 @@ void __dummy__(void) + OFFSET(VCPUINFO_upcall_mask, vcpu_info_t, evtchn_upcall_mask); + BLANK(); + ++ OFFSET(CPUINFO_current_vcpu, struct cpu_info, current_vcpu); + DEFINE(CPUINFO_sizeof, sizeof(struct cpu_info)); + BLANK(); + +Index: 2006-12-18/xen/arch/x86/x86_64/compat/entry.S +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2006-12-18/xen/arch/x86/x86_64/compat/entry.S 2006-12-18 09:43:08.000000000 +0100 +@@ -0,0 +1,395 @@ ++/* ++ * Compatibility hypercall routines. ++ */ ++ ++#include ++ ++.text ++ ++ENTRY(compat_hypercall) ++ pushq $0 ++ movl $TRAP_syscall,4(%rsp) ++ SAVE_ALL ++ GET_CURRENT(%rbx) ++ ++ cmpl $NR_hypercalls,%eax ++ jae compat_bad_hypercall ++#ifndef NDEBUG ++ /* Deliberately corrupt parameter regs not used by this hypercall. */ ++ pushq UREGS_rbx(%rsp); pushq %rcx; pushq %rdx; pushq %rsi; pushq %rdi; pushq UREGS_rbp+5*8(%rsp) ++ leaq compat_hypercall_args_table(%rip),%r10 ++ movq $6,%rcx ++ subb (%r10,%rax,1),%cl ++ movq %rsp,%rdi ++ movl $0xDEADBEEF,%eax ++ rep stosq ++ popq %r9 ; popq %r8 ; popq %rcx; popq %rdx; popq %rsi; popq %rdi ++ movl UREGS_rax(%rsp),%eax ++ pushq %rax ++ pushq UREGS_rip+8(%rsp) ++#else ++ movl %eax,%eax ++ movl %ebp,%r9d ++ movl %edi,%r8d ++ xchgl %ecx,%esi ++ movl UREGS_rbx(%rsp),%edi ++#endif ++ leaq compat_hypercall_table(%rip),%r10 ++ PERFC_INCR(PERFC_hypercalls, %rax) ++ callq *(%r10,%rax,8) ++#ifndef NDEBUG ++ /* Deliberately corrupt parameter regs used by this hypercall. */ ++ popq %r10 # Shadow RIP ++ cmpq %r10,UREGS_rip+8(%rsp) ++ popq %rcx # Shadow hypercall index ++ jne compat_skip_clobber /* If RIP has changed then don't clobber. */ ++ leaq compat_hypercall_args_table(%rip),%r10 ++ movb (%r10,%rcx,1),%cl ++ movl $0xDEADBEEF,%r10d ++ testb %cl,%cl; jz compat_skip_clobber; movl %r10d,UREGS_rbx(%rsp) ++ cmpb $2, %cl; jb compat_skip_clobber; movl %r10d,UREGS_rcx(%rsp) ++ cmpb $3, %cl; jb compat_skip_clobber; movl %r10d,UREGS_rdx(%rsp) ++ cmpb $4, %cl; jb compat_skip_clobber; movl %r10d,UREGS_rsi(%rsp) ++ cmpb $5, %cl; jb compat_skip_clobber; movl %r10d,UREGS_rdi(%rsp) ++ cmpb $6, %cl; jb compat_skip_clobber; movl %r10d,UREGS_rbp(%rsp) ++compat_skip_clobber: ++#endif ++ movl %eax,UREGS_rax(%rsp) # save the return value ++ ++/* %rbx: struct vcpu */ ++compat_test_all_events: ++ cli # tests must not race interrupts ++/*compat_test_softirqs:*/ ++ movl VCPU_processor(%rbx),%eax ++ shlq $IRQSTAT_shift,%rax ++ leaq irq_stat(%rip),%rcx ++ testl $~0,(%rcx,%rax,1) ++ jnz compat_process_softirqs ++ btrq $_VCPUF_nmi_pending,VCPU_flags(%rbx) ++ jc compat_process_nmi ++compat_test_guest_events: ++ movq VCPU_vcpu_info(%rbx),%rax ++ testb $0xFF,VCPUINFO_upcall_mask(%rax) ++ jnz compat_restore_all_guest ++ testb $0xFF,VCPUINFO_upcall_pending(%rax) ++ jz compat_restore_all_guest ++/*compat_process_guest_events:*/ ++ sti ++ leaq VCPU_trap_bounce(%rbx),%rdx ++ movl VCPU_event_addr(%rbx),%eax ++ movl %eax,TRAPBOUNCE_eip(%rdx) ++ movl VCPU_event_sel(%rbx),%eax ++ movl %eax,TRAPBOUNCE_cs(%rdx) ++ movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) ++ call compat_create_bounce_frame ++ jmp compat_test_all_events ++ ++ ALIGN ++/* %rbx: struct vcpu */ ++compat_process_softirqs: ++ sti ++ call do_softirq ++ jmp compat_test_all_events ++ ++ ALIGN ++/* %rbx: struct vcpu */ ++compat_process_nmi: ++ movl VCPU_nmi_addr(%rbx),%eax ++ testl %eax,%eax ++ jz compat_test_all_events ++ btsq $_VCPUF_nmi_masked,VCPU_flags(%rbx) ++ jc 1f ++ sti ++ leaq VCPU_trap_bounce(%rbx),%rdx ++ movl %eax,TRAPBOUNCE_eip(%rdx) ++ movl $FLAT_COMPAT_KERNEL_CS,TRAPBOUNCE_cs(%rdx) ++ movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) ++ call compat_create_bounce_frame ++ jmp compat_test_all_events ++1: ++ btsq $_VCPUF_nmi_pending,VCPU_flags(%rbx) ++ jmp compat_test_guest_events ++ ++compat_bad_hypercall: ++ movl $-ENOSYS,UREGS_rax(%rsp) ++ jmp compat_test_all_events ++ ++/* %rbx: struct vcpu, interrupts disabled */ ++compat_restore_all_guest: ++ RESTORE_ALL ++ addq $8,%rsp ++CFLT0: iretq ++ ++.section .fixup,"ax" ++CFIX0: popq -15*8-8(%rsp) # error_code/entry_vector ++ SAVE_ALL # 15*8 bytes pushed ++ movq -8(%rsp),%rsi # error_code/entry_vector ++ sti # after stack abuse (-1024(%rsp)) ++ pushq $__HYPERVISOR_DS # SS ++ leaq 8(%rsp),%rax ++ pushq %rax # RSP ++ pushfq # RFLAGS ++ pushq $__HYPERVISOR_CS # CS ++ leaq CDBLFLT0(%rip),%rax ++ pushq %rax # RIP ++ pushq %rsi # error_code/entry_vector ++ jmp handle_exception ++CDBLFLT0:GET_CURRENT(%rbx) ++ jmp compat_test_all_events ++compat_failsafe_callback: ++ GET_CURRENT(%rbx) ++ leaq VCPU_trap_bounce(%rbx),%rdx ++ movl VCPU_failsafe_addr(%rbx),%eax ++ movl %eax,TRAPBOUNCE_eip(%rdx) ++ movl VCPU_failsafe_sel(%rbx),%eax ++ movl %eax,TRAPBOUNCE_cs(%rdx) ++ movw $TBF_FAILSAFE,TRAPBOUNCE_flags(%rdx) ++ btq $_VGCF_failsafe_disables_events,VCPU_guest_context_flags(%rbx) ++ jnc 1f ++ orw $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) ++1: ++ call compat_create_bounce_frame ++ jmp compat_test_all_events ++.previous ++.section __pre_ex_table,"a" ++ .quad CFLT0,CFIX0 ++.previous ++.section __ex_table,"a" ++ .quad CDBLFLT0,compat_failsafe_callback ++.previous ++ ++/* %rdx: trap_bounce, %rbx: struct vcpu */ ++compat_post_handle_exception: ++ testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx) ++ jz compat_test_all_events ++ call compat_create_bounce_frame ++ jmp compat_test_all_events ++ ++/* CREATE A BASIC EXCEPTION FRAME ON GUEST OS (RING-1) STACK: */ ++/* {[ERRCODE,] EIP, CS, EFLAGS, [ESP, SS]} */ ++/* %rdx: trap_bounce, %rbx: struct vcpu */ ++/* On return only %rbx is guaranteed non-clobbered. */ ++compat_create_bounce_frame: ++ mov %fs,%edi ++ testb $2,UREGS_cs+8(%rsp) ++ jz 1f ++ /* Push new frame at registered guest-OS stack base. */ ++ movl VCPU_kernel_sp(%rbx),%esi ++CFLT1: mov VCPU_kernel_ss(%rbx),%fs ++ subl $2*4,%esi ++ movl UREGS_rsp+8(%rsp),%eax ++CFLT2: movl %eax,%fs:(%rsi) ++ movl UREGS_ss+8(%rsp),%eax ++CFLT3: movl %eax,%fs:4(%rsi) ++ jmp 2f ++1: /* In kernel context already: push new frame at existing %rsp. */ ++ movl UREGS_rsp+8(%rsp),%esi ++CFLT4: mov UREGS_ss+8(%rsp),%fs ++2: ++ movb TRAPBOUNCE_flags(%rdx),%cl ++ subl $3*4,%esi ++ movq VCPU_vcpu_info(%rbx),%rax ++ pushq VCPUINFO_upcall_mask(%rax) ++ testb $TBF_INTERRUPT,%cl ++ setnz %ch # TBF_INTERRUPT -> set upcall mask ++ orb %ch,VCPUINFO_upcall_mask(%rax) ++ popq %rax ++ shll $16,%eax # Bits 16-23: saved_upcall_mask ++ movw UREGS_cs+8(%rsp),%ax # Bits 0-15: CS ++CFLT5: movl %eax,%fs:4(%rsi) # CS / saved_upcall_mask ++ shrl $16,%eax ++ testb %al,%al # Bits 0-7: saved_upcall_mask ++ setz %ch # %ch == !saved_upcall_mask ++ movl UREGS_eflags+8(%rsp),%eax ++ andl $~X86_EFLAGS_IF,%eax ++ shlb $1,%ch # Bit 9 (EFLAGS.IF) ++ orb %ch,%ah # Fold EFLAGS.IF into %eax ++CFLT6: movl %eax,%fs:2*4(%rsi) # EFLAGS ++ movl UREGS_rip+8(%rsp),%eax ++CFLT7: movl %eax,%fs:(%rsi) # EIP ++ testb $TBF_EXCEPTION_ERRCODE,%cl ++ jz 1f ++ subl $4,%esi ++ movl TRAPBOUNCE_error_code(%rdx),%eax ++CFLT8: movl %eax,%fs:(%rsi) # ERROR CODE ++1: ++ testb $TBF_FAILSAFE,%cl ++ jz 2f ++ subl $4*4,%esi ++ movl %gs,%eax ++CFLT9: movl %eax,%fs:3*4(%rsi) # GS ++CFLT10: movl %edi,%fs:2*4(%rsi) # FS ++ movl %es,%eax ++CFLT11: movl %eax,%fs:1*4(%rsi) # ES ++ movl %ds,%eax ++CFLT12: movl %eax,%fs:0*4(%rsi) # DS ++2: ++ /* Rewrite our stack frame and return to guest-OS mode. */ ++ /* IA32 Ref. Vol. 3: TF, VM, RF and NT flags are cleared on trap. */ ++ movl $TRAP_syscall,UREGS_entry_vector+8(%rsp) ++ andl $~(X86_EFLAGS_VM|X86_EFLAGS_RF|\ ++ X86_EFLAGS_NT|X86_EFLAGS_TF),UREGS_eflags+8(%rsp) ++ mov %fs,UREGS_ss+8(%rsp) ++ movl %esi,UREGS_rsp+8(%rsp) ++CFLT13: mov %edi,%fs ++ movzwl TRAPBOUNCE_cs(%rdx),%eax ++ /* Null selectors (0-3) are not allowed. */ ++ testl $~3,%eax ++ jz domain_crash_synchronous ++ movl %eax,UREGS_cs+8(%rsp) ++ movl TRAPBOUNCE_eip(%rdx),%eax ++ movl %eax,UREGS_rip+8(%rsp) ++ movb $0,TRAPBOUNCE_flags(%rdx) ++ ret ++.section .fixup,"ax" ++CFIX13: ++ xorl %edi,%edi ++ jmp CFLT13 ++.previous ++.section __ex_table,"a" ++ .quad CFLT1,domain_crash_synchronous , CFLT2,compat_crash_page_fault ++ .quad CFLT3,compat_crash_page_fault_4 , CFLT4,domain_crash_synchronous ++ .quad CFLT5,compat_crash_page_fault_4 , CFLT6,compat_crash_page_fault_8 ++ .quad CFLT7,compat_crash_page_fault , CFLT8,compat_crash_page_fault ++ .quad CFLT9,compat_crash_page_fault_12, CFLT10,compat_crash_page_fault_8 ++ .quad CFLT11,compat_crash_page_fault_4 , CFLT12,compat_crash_page_fault ++ .quad CFLT13,CFIX13 ++.previous ++ ++compat_crash_page_fault_12: ++ addl $4,%esi ++compat_crash_page_fault_8: ++ addl $4,%esi ++compat_crash_page_fault_4: ++ addl $4,%esi ++compat_crash_page_fault: ++CFLT14: mov %edi,%fs ++ movl %esi,%edi ++ call show_page_walk ++ jmp domain_crash_synchronous ++.section .fixup,"ax" ++CFIX14: ++ xorl %edi,%edi ++ jmp CFLT14 ++.previous ++.section __ex_table,"a" ++ .quad CFLT14,CFIX14 ++.previous ++ ++.section .rodata, "a", @progbits ++ ++#define compat_set_trap_table domain_crash_synchronous ++#define compat_mmu_update domain_crash_synchronous ++#define compat_set_gdt domain_crash_synchronous ++#define compat_stack_switch domain_crash_synchronous ++#define compat_fpu_taskswitch domain_crash_synchronous ++#define compat_arch_sched_op_compat domain_crash_synchronous ++#define compat_platform_op domain_crash_synchronous ++#define compat_set_debugreg domain_crash_synchronous ++#define compat_get_debugreg domain_crash_synchronous ++#define compat_update_descriptor domain_crash_synchronous ++#define compat_memory_op domain_crash_synchronous ++#define compat_multicall domain_crash_synchronous ++#define compat_update_va_mapping domain_crash_synchronous ++#define compat_set_timer_op domain_crash_synchronous ++#define compat_event_channel_op_compat domain_crash_synchronous ++#define compat_xen_version domain_crash_synchronous ++#define compat_console_io domain_crash_synchronous ++#define compat_physdev_op_compat domain_crash_synchronous ++#define compat_grant_table_op domain_crash_synchronous ++#define compat_vm_assist domain_crash_synchronous ++#define compat_update_va_mapping_otherdomain domain_crash_synchronous ++#define compat_vcpu_op domain_crash_synchronous ++#define compat_mmuext_op domain_crash_synchronous ++#define compat_acm_op domain_crash_synchronous ++#define compat_nmi_op domain_crash_synchronous ++#define compat_arch_sched_op domain_crash_synchronous ++#define compat_xenoprof_op domain_crash_synchronous ++#define compat_event_channel_op domain_crash_synchronous ++#define compat_physdev_op domain_crash_synchronous ++#define compat_sysctl domain_crash_synchronous ++#define compat_domctl domain_crash_synchronous ++ ++ENTRY(compat_hypercall_table) ++ .quad compat_set_trap_table /* 0 */ ++ .quad compat_mmu_update ++ .quad compat_set_gdt ++ .quad compat_stack_switch ++ .quad compat_set_callbacks ++ .quad compat_fpu_taskswitch /* 5 */ ++ .quad compat_arch_sched_op_compat ++ .quad compat_platform_op ++ .quad compat_set_debugreg ++ .quad compat_get_debugreg ++ .quad compat_update_descriptor /* 10 */ ++ .quad do_ni_hypercall ++ .quad compat_memory_op ++ .quad compat_multicall ++ .quad compat_update_va_mapping ++ .quad compat_set_timer_op /* 15 */ ++ .quad compat_event_channel_op_compat ++ .quad compat_xen_version ++ .quad compat_console_io ++ .quad compat_physdev_op_compat ++ .quad compat_grant_table_op /* 20 */ ++ .quad compat_vm_assist ++ .quad compat_update_va_mapping_otherdomain ++ .quad compat_iret ++ .quad compat_vcpu_op ++ .quad do_ni_hypercall /* 25 */ ++ .quad compat_mmuext_op ++ .quad compat_acm_op ++ .quad compat_nmi_op ++ .quad compat_arch_sched_op ++ .quad compat_callback_op /* 30 */ ++ .quad compat_xenoprof_op ++ .quad compat_event_channel_op ++ .quad compat_physdev_op ++ .quad do_ni_hypercall ++ .quad compat_sysctl /* 35 */ ++ .quad compat_domctl ++ .rept NR_hypercalls-((.-compat_hypercall_table)/8) ++ .quad do_ni_hypercall ++ .endr ++ ++ENTRY(compat_hypercall_args_table) ++ .byte 1 /* compat_set_trap_table */ /* 0 */ ++ .byte 4 /* compat_mmu_update */ ++ .byte 2 /* compat_set_gdt */ ++ .byte 2 /* compat_stack_switch */ ++ .byte 4 /* compat_set_callbacks */ ++ .byte 1 /* compat_fpu_taskswitch */ /* 5 */ ++ .byte 2 /* compat_arch_sched_op_compat */ ++ .byte 1 /* compat_platform_op */ ++ .byte 2 /* compat_set_debugreg */ ++ .byte 1 /* compat_get_debugreg */ ++ .byte 4 /* compat_update_descriptor */ /* 10 */ ++ .byte 0 /* do_ni_hypercall */ ++ .byte 2 /* compat_memory_op */ ++ .byte 2 /* compat_multicall */ ++ .byte 4 /* compat_update_va_mapping */ ++ .byte 2 /* compat_set_timer_op */ /* 15 */ ++ .byte 1 /* compat_event_channel_op_compat */ ++ .byte 2 /* compat_xen_version */ ++ .byte 3 /* compat_console_io */ ++ .byte 1 /* compat_physdev_op_compat */ ++ .byte 3 /* compat_grant_table_op */ /* 20 */ ++ .byte 2 /* compat_vm_assist */ ++ .byte 5 /* compat_update_va_mapping_otherdomain */ ++ .byte 0 /* compat_iret */ ++ .byte 3 /* compat_vcpu_op */ ++ .byte 0 /* do_ni_hypercall */ /* 25 */ ++ .byte 4 /* compat_mmuext_op */ ++ .byte 1 /* compat_acm_op */ ++ .byte 2 /* compat_nmi_op */ ++ .byte 2 /* compat_arch_sched_op */ ++ .byte 2 /* compat_callback_op */ /* 30 */ ++ .byte 2 /* compat_xenoprof_op */ ++ .byte 2 /* compat_event_channel_op */ ++ .byte 2 /* compat_physdev_op */ ++ .byte 0 /* do_ni_hypercall */ ++ .byte 1 /* compat_sysctl */ /* 35 */ ++ .byte 1 /* compat_domctl */ ++ .rept NR_hypercalls-(.-compat_hypercall_args_table) ++ .byte 0 /* do_ni_hypercall */ ++ .endr +Index: 2006-12-18/xen/arch/x86/x86_64/compat/traps.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2006-12-18/xen/arch/x86/x86_64/compat/traps.c 2006-12-18 09:43:08.000000000 +0100 +@@ -0,0 +1,312 @@ ++#ifdef CONFIG_COMPAT ++ ++#if 0 /* XXX */ ++#include ++#else ++struct compat_xen_callback { ++ unsigned int cs; ++ unsigned int eip; ++}; ++typedef struct compat_xen_callback xen_callback_compat_t; ++ ++struct compat_callback_register { ++ uint16_t type; ++ uint16_t flags; ++ xen_callback_compat_t address; ++}; ++ ++struct compat_callback_unregister { ++ uint16_t type; ++ uint16_t _unused; ++}; ++#endif ++ ++void compat_show_guest_stack(struct cpu_user_regs *regs, int debug_stack_lines) ++{ ++ unsigned int i, *stack, addr; ++ ++ stack = (unsigned int *)(unsigned long)regs->_esp; ++ printk("Guest stack trace from esp=%08lx:\n ", (unsigned long)stack); ++ ++ for ( i = 0; i < debug_stack_lines * 8; i++ ) ++ { ++ if ( (((long)stack + 3) & (STACK_SIZE - 4)) == 0 ) ++ break; ++ if ( get_user(addr, stack) ) ++ { ++ if ( i != 0 ) ++ printk("\n "); ++ printk("Fault while accessing guest memory."); ++ i = 1; ++ break; ++ } ++ if ( (i != 0) && ((i % 8) == 0) ) ++ printk("\n "); ++ printk(" %08x", addr); ++ stack++; ++ } ++ if ( i == 0 ) ++ printk("Stack empty."); ++ printk("\n"); ++} ++ ++unsigned int compat_iret(void) ++{ ++ struct cpu_user_regs *regs = guest_cpu_user_regs(); ++ u32 eflags; ++ ++ /* Restore EAX (clobbered by hypercall). */ ++ if ( unlikely(__get_user(regs->_eax, (u32 __user *)regs->rsp)) ) ++ goto exit_and_crash; ++ ++ /* Restore CS and EIP. */ ++ if ( unlikely(__get_user(regs->_eip, (u32 __user *)regs->rsp + 1)) || ++ unlikely(__get_user(regs->cs, (u32 __user *)regs->rsp + 2)) ) ++ goto exit_and_crash; ++ ++ /* ++ * Fix up and restore EFLAGS. We fix up in a local staging area ++ * to avoid firing the BUG_ON(IOPL) check in arch_getdomaininfo_ctxt. ++ */ ++ if ( unlikely(__get_user(eflags, (u32 __user *)regs->rsp + 3)) ) ++ goto exit_and_crash; ++ regs->_eflags = (eflags & ~X86_EFLAGS_IOPL) | X86_EFLAGS_IF; ++ ++ if ( unlikely(eflags & X86_EFLAGS_VM) ) ++ { ++ /* ++ * Cannot return to VM86 mode: inject a GP fault instead. Note that ++ * the GP fault is reported on the first VM86 mode instruction, not on ++ * the IRET (which is why we can simply leave the stack frame as-is ++ * (except for perhaps having to copy it), which in turn seems better ++ * than teaching create_bounce_frame() to needlessly deal with vm86 ++ * mode frames). ++ */ ++ const struct trap_info *ti; ++ u32 x, ksp = current->arch.guest_context.kernel_sp - 40; ++ unsigned int i; ++ int rc = 0; ++ ++ gdprintk(XENLOG_ERR, "VM86 mode unavailable (ksp:%08X->%08X)\n", ++ regs->_esp, ksp); ++ if ( ksp < regs->_esp ) ++ { ++ for (i = 1; i < 10; ++i) ++ { ++ rc |= __get_user(x, (u32 __user *)regs->rsp + i); ++ rc |= __put_user(x, (u32 __user *)(unsigned long)ksp + i); ++ } ++ } ++ else if ( ksp > regs->_esp ) ++ { ++ for (i = 9; i > 0; ++i) ++ { ++ rc |= __get_user(x, (u32 __user *)regs->rsp + i); ++ rc |= __put_user(x, (u32 __user *)(unsigned long)ksp + i); ++ } ++ } ++ if ( rc ) ++ goto exit_and_crash; ++ regs->_esp = ksp; ++ regs->ss = current->arch.guest_context.kernel_ss; ++ ++ ti = ¤t->arch.guest_context.trap_ctxt[13]; ++ if ( TI_GET_IF(ti) ) ++ eflags &= ~X86_EFLAGS_IF; ++ regs->_eflags = eflags & ~(X86_EFLAGS_VM|X86_EFLAGS_RF| ++ X86_EFLAGS_NT|X86_EFLAGS_TF); ++ ++ if ( unlikely(__put_user(0, (u32 __user *)regs->rsp)) ) ++ goto exit_and_crash; ++ regs->_eip = ti->address; ++ regs->cs = ti->cs; ++ } ++ else if ( unlikely(ring_0(regs)) ) ++ goto exit_and_crash; ++ else if ( !ring_1(regs) ) ++ { ++ /* Return to ring 2/3: restore ESP and SS. */ ++ if ( __get_user(regs->ss, (u32 __user *)regs->rsp + 5) ++ || __get_user(regs->_esp, (u32 __user *)regs->rsp + 4)) ++ goto exit_and_crash; ++ } ++ else ++ regs->_esp += 16; ++ ++ /* No longer in NMI context. */ ++ clear_bit(_VCPUF_nmi_masked, ¤t->vcpu_flags); ++ ++ /* Restore upcall mask from supplied EFLAGS.IF. */ ++ current->vcpu_info->evtchn_upcall_mask = !(eflags & X86_EFLAGS_IF); ++ ++ /* ++ * The hypercall exit path will overwrite EAX with this return ++ * value. ++ */ ++ return regs->_eax; ++ ++ exit_and_crash: ++ gdprintk(XENLOG_ERR, "Fatal error\n"); ++ domain_crash(current->domain); ++ return 0; ++} ++ ++static long compat_register_guest_callback(struct compat_callback_register *reg) ++{ ++ long ret = 0; ++ struct vcpu *v = current; ++ ++ fixup_guest_code_selector(v->domain, reg->address.cs); ++ ++ switch ( reg->type ) ++ { ++ case CALLBACKTYPE_event: ++ v->arch.guest_context.event_callback_cs = reg->address.cs; ++ v->arch.guest_context.event_callback_eip = reg->address.eip; ++ break; ++ ++ case CALLBACKTYPE_failsafe: ++ v->arch.guest_context.failsafe_callback_cs = reg->address.cs; ++ v->arch.guest_context.failsafe_callback_eip = reg->address.eip; ++ if ( reg->flags & CALLBACKF_mask_events ) ++ set_bit(_VGCF_failsafe_disables_events, ++ &v->arch.guest_context.flags); ++ else ++ clear_bit(_VGCF_failsafe_disables_events, ++ &v->arch.guest_context.flags); ++ break; ++ ++ case CALLBACKTYPE_nmi: ++ ret = register_guest_nmi_callback(reg->address.eip); ++ break; ++ ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ ++ return ret; ++} ++ ++static long compat_unregister_guest_callback(struct compat_callback_unregister *unreg) ++{ ++ long ret; ++ ++ switch ( unreg->type ) ++ { ++ case CALLBACKTYPE_nmi: ++ ret = unregister_guest_nmi_callback(); ++ break; ++ ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ ++ return ret; ++} ++ ++ ++long compat_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg) ++{ ++ long ret; ++ ++ switch ( cmd ) ++ { ++ case CALLBACKOP_register: ++ { ++ struct compat_callback_register reg; ++ ++ ret = -EFAULT; ++ if ( copy_from_guest(®, arg, 1) ) ++ break; ++ ++ ret = compat_register_guest_callback(®); ++ } ++ break; ++ ++ case CALLBACKOP_unregister: ++ { ++ struct compat_callback_unregister unreg; ++ ++ ret = -EFAULT; ++ if ( copy_from_guest(&unreg, arg, 1) ) ++ break; ++ ++ ret = compat_unregister_guest_callback(&unreg); ++ } ++ break; ++ ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ ++ return ret; ++} ++ ++long compat_set_callbacks(unsigned long event_selector, ++ unsigned long event_address, ++ unsigned long failsafe_selector, ++ unsigned long failsafe_address) ++{ ++ struct compat_callback_register event = { ++ .type = CALLBACKTYPE_event, ++ .address = { ++ .cs = event_selector, ++ .eip = event_address ++ } ++ }; ++ struct compat_callback_register failsafe = { ++ .type = CALLBACKTYPE_failsafe, ++ .address = { ++ .cs = failsafe_selector, ++ .eip = failsafe_address ++ } ++ }; ++ ++ compat_register_guest_callback(&event); ++ compat_register_guest_callback(&failsafe); ++ ++ return 0; ++} ++ ++#endif /* CONFIG_COMPAT */ ++ ++static void hypercall_page_initialise_ring1_kernel(void *hypercall_page) ++{ ++ char *p; ++ int i; ++ ++ /* Fill in all the transfer points with template machine code. */ ++ ++ for ( i = 0; i < (PAGE_SIZE / 32); i++ ) ++ { ++ p = (char *)(hypercall_page + (i * 32)); ++ *(u8 *)(p+ 0) = 0xb8; /* mov $,%eax */ ++ *(u32 *)(p+ 1) = i; ++ *(u16 *)(p+ 5) = 0x82cd; /* int $0x82 */ ++ *(u8 *)(p+ 7) = 0xc3; /* ret */ ++ } ++ ++ /* ++ * HYPERVISOR_iret is special because it doesn't return and expects a ++ * special stack frame. Guests jump at this transfer point instead of ++ * calling it. ++ */ ++ p = (char *)(hypercall_page + (__HYPERVISOR_iret * 32)); ++ *(u8 *)(p+ 0) = 0x50; /* push %eax */ ++ *(u8 *)(p+ 1) = 0xb8; /* mov $__HYPERVISOR_iret,%eax */ ++ *(u32 *)(p+ 2) = __HYPERVISOR_iret; ++ *(u16 *)(p+ 6) = 0x82cd; /* int $0x82 */ ++} ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * tab-width: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ +Index: 2006-12-18/xen/arch/x86/x86_64/entry.S +=================================================================== +--- 2006-12-18.orig/xen/arch/x86/x86_64/entry.S 2006-12-18 09:36:35.000000000 +0100 ++++ 2006-12-18/xen/arch/x86/x86_64/entry.S 2006-12-18 09:43:08.000000000 +0100 +@@ -337,7 +337,16 @@ domain_crash_synchronous: + GET_GUEST_REGS(%rax) + movq %rax,%rsp + # create_bounce_frame() temporarily clobbers CS.RPL. Fix up. ++#ifdef CONFIG_COMPAT ++ movq CPUINFO_current_vcpu(%rax),%rax ++ movq VCPU_domain(%rax),%rax ++ btl $_DOMF_compat,DOMAIN_domain_flags(%rax) ++ setnc %al ++ leal (%rax,%rax,2),%eax ++ orb %al,UREGS_cs(%rsp) ++#else + orb $3,UREGS_cs(%rsp) ++#endif + # printk(domain_crash_synchronous_string) + leaq domain_crash_synchronous_string(%rip),%rdi + xorl %eax,%eax +@@ -349,8 +358,15 @@ domain_crash_synchronous: + ENTRY(ret_from_intr) + GET_CURRENT(%rbx) + testb $3,UREGS_cs(%rsp) +- jnz test_all_events +- jmp restore_all_xen ++ jz restore_all_xen ++#ifndef CONFIG_COMPAT ++ jmp test_all_events ++#else ++ movq VCPU_domain(%rbx),%rax ++ btl $_DOMF_compat,DOMAIN_domain_flags(%rax) ++ jnc test_all_events ++ jmp compat_test_all_events ++#endif + + ALIGN + /* No special register assumptions. */ +@@ -368,6 +384,11 @@ handle_exception: + testb $3,UREGS_cs(%rsp) + jz restore_all_xen + leaq VCPU_trap_bounce(%rbx),%rdx ++#ifdef CONFIG_COMPAT ++ movq VCPU_domain(%rbx),%rax ++ btl $_DOMF_compat,DOMAIN_domain_flags(%rax) ++ jc compat_post_handle_exception ++#endif + testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx) + jz test_all_events + call create_bounce_frame +@@ -625,3 +646,7 @@ ENTRY(hypercall_args_table) + .rept NR_hypercalls-(.-hypercall_args_table) + .byte 0 /* do_ni_hypercall */ + .endr ++ ++#ifdef CONFIG_COMPAT ++#include "compat/entry.S" ++#endif +Index: 2006-12-18/xen/arch/x86/x86_64/traps.c +=================================================================== +--- 2006-12-18.orig/xen/arch/x86/x86_64/traps.c 2006-12-18 09:37:45.000000000 +0100 ++++ 2006-12-18/xen/arch/x86/x86_64/traps.c 2006-12-18 09:43:08.000000000 +0100 +@@ -246,6 +246,7 @@ unsigned long do_iret(void) + } + + asmlinkage void syscall_enter(void); ++asmlinkage void compat_hypercall(void); + void __init percpu_traps_init(void) + { + char *stack_bottom, *stack; +@@ -257,6 +258,11 @@ void __init percpu_traps_init(void) + set_intr_gate(TRAP_double_fault, &double_fault); + idt_table[TRAP_double_fault].a |= 1UL << 32; /* IST1 */ + idt_table[TRAP_nmi].a |= 2UL << 32; /* IST2 */ ++ ++#ifdef CONFIG_COMPAT ++ /* The hypercall entry vector is only accessible from ring 1. */ ++ _set_gate(idt_table+HYPERCALL_VECTOR, 15, 1, &compat_hypercall); ++#endif + } + + stack_bottom = (char *)get_stack_bottom(); +@@ -503,12 +509,16 @@ static void hypercall_page_initialise_ri + *(u16 *)(p+ 9) = 0x050f; /* syscall */ + } + ++#include "compat/traps.c" ++ + void hypercall_page_initialise(struct domain *d, void *hypercall_page) + { + if ( is_hvm_domain(d) ) + hvm_hypercall_page_initialise(d, hypercall_page); +- else ++ else if ( !IS_COMPAT(d) ) + hypercall_page_initialise_ring3_kernel(hypercall_page); ++ else ++ hypercall_page_initialise_ring1_kernel(hypercall_page); + } + + /* +Index: 2006-12-18/xen/include/asm-x86/processor.h +=================================================================== +--- 2006-12-18.orig/xen/include/asm-x86/processor.h 2006-12-13 11:15:56.000000000 +0100 ++++ 2006-12-18/xen/include/asm-x86/processor.h 2006-12-18 09:43:08.000000000 +0100 +@@ -559,6 +559,12 @@ void show_execution_state(struct cpu_use + void show_page_walk(unsigned long addr); + asmlinkage void fatal_trap(int trapnr, struct cpu_user_regs *regs); + ++#ifdef CONFIG_COMPAT ++void compat_show_guest_stack(struct cpu_user_regs *, int lines); ++#else ++#define compat_show_guest_stack(regs, lines) ((void)0) ++#endif ++ + /* Dumps current register and stack state. */ + #define dump_execution_state() \ + /* NB. Needs interrupts enabled else we end up in fatal_trap(). */ \ diff --git a/32on64-interface.patch b/32on64-interface.patch new file mode 100644 index 0000000..983f68b --- /dev/null +++ b/32on64-interface.patch @@ -0,0 +1,616 @@ +Add logic to generate headers reflecting the compatibility mode layout +of hypercall arguments. Provide infrastructure for accessing handles +passed from compatibility mode guests. Vector those hypercalls not +needing any translation to their native implementations. + +Index: 2007-01-08/xen/Makefile +=================================================================== +--- 2007-01-08.orig/xen/Makefile 2007-01-08 15:17:24.000000000 +0100 ++++ 2007-01-08/xen/Makefile 2007-01-08 15:17:29.000000000 +0100 +@@ -48,6 +48,7 @@ _debug: + .PHONY: _clean + _clean: delete-unfresh-files + $(MAKE) -C tools clean ++ $(MAKE) -f $(BASEDIR)/Rules.mk -C include clean + $(MAKE) -f $(BASEDIR)/Rules.mk -C common clean + $(MAKE) -f $(BASEDIR)/Rules.mk -C drivers clean + $(MAKE) -f $(BASEDIR)/Rules.mk -C acm clean +@@ -69,6 +70,7 @@ $(TARGET): delete-unfresh-files + $(MAKE) -f $(BASEDIR)/Rules.mk include/xen/compile.h + $(MAKE) -f $(BASEDIR)/Rules.mk include/xen/acm_policy.h + [ -e include/asm ] || ln -sf asm-$(TARGET_ARCH) include/asm ++ $(MAKE) -f $(BASEDIR)/Rules.mk -C include + $(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) asm-offsets.s + $(MAKE) -f $(BASEDIR)/Rules.mk include/asm-$(TARGET_ARCH)/asm-offsets.h + $(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) $(TARGET) +Index: 2007-01-08/xen/Rules.mk +=================================================================== +--- 2007-01-08.orig/xen/Rules.mk 2007-01-08 15:17:24.000000000 +0100 ++++ 2007-01-08/xen/Rules.mk 2007-01-08 15:17:29.000000000 +0100 +@@ -34,6 +34,7 @@ TARGET := $(BASEDIR)/xen + + HDRS := $(wildcard $(BASEDIR)/include/xen/*.h) + HDRS += $(wildcard $(BASEDIR)/include/public/*.h) ++HDRS += $(wildcard $(BASEDIR)/include/compat/*.h) + HDRS += $(wildcard $(BASEDIR)/include/asm-$(TARGET_ARCH)/*.h) + HDRS += $(wildcard $(BASEDIR)/include/asm-$(TARGET_ARCH)/$(TARGET_SUBARCH)/*.h) + +Index: 2007-01-08/xen/arch/x86/x86_64/compat/entry.S +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:17:24.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:17:29.000000000 +0100 +@@ -281,28 +281,19 @@ CFIX14: + #define compat_set_trap_table domain_crash_synchronous + #define compat_mmu_update domain_crash_synchronous + #define compat_set_gdt domain_crash_synchronous +-#define compat_stack_switch domain_crash_synchronous +-#define compat_fpu_taskswitch domain_crash_synchronous +-#define compat_arch_sched_op_compat domain_crash_synchronous + #define compat_platform_op domain_crash_synchronous +-#define compat_set_debugreg domain_crash_synchronous +-#define compat_get_debugreg domain_crash_synchronous + #define compat_update_descriptor domain_crash_synchronous + #define compat_memory_op domain_crash_synchronous + #define compat_multicall domain_crash_synchronous + #define compat_update_va_mapping domain_crash_synchronous + #define compat_set_timer_op domain_crash_synchronous + #define compat_event_channel_op_compat domain_crash_synchronous +-#define compat_xen_version domain_crash_synchronous +-#define compat_console_io domain_crash_synchronous + #define compat_physdev_op_compat domain_crash_synchronous + #define compat_grant_table_op domain_crash_synchronous +-#define compat_vm_assist domain_crash_synchronous + #define compat_update_va_mapping_otherdomain domain_crash_synchronous + #define compat_vcpu_op domain_crash_synchronous + #define compat_mmuext_op domain_crash_synchronous + #define compat_acm_op domain_crash_synchronous +-#define compat_nmi_op domain_crash_synchronous + #define compat_arch_sched_op domain_crash_synchronous + #define compat_xenoprof_op domain_crash_synchronous + #define compat_event_channel_op domain_crash_synchronous +@@ -314,29 +305,29 @@ ENTRY(compat_hypercall_table) + .quad compat_set_trap_table /* 0 */ + .quad compat_mmu_update + .quad compat_set_gdt +- .quad compat_stack_switch ++ .quad do_stack_switch + .quad compat_set_callbacks +- .quad compat_fpu_taskswitch /* 5 */ +- .quad compat_arch_sched_op_compat ++ .quad do_fpu_taskswitch /* 5 */ ++ .quad do_sched_op_compat + .quad compat_platform_op +- .quad compat_set_debugreg +- .quad compat_get_debugreg ++ .quad do_set_debugreg ++ .quad do_get_debugreg + .quad compat_update_descriptor /* 10 */ +- .quad do_ni_hypercall ++ .quad compat_ni_hypercall + .quad compat_memory_op + .quad compat_multicall + .quad compat_update_va_mapping + .quad compat_set_timer_op /* 15 */ + .quad compat_event_channel_op_compat + .quad compat_xen_version +- .quad compat_console_io ++ .quad do_console_io + .quad compat_physdev_op_compat + .quad compat_grant_table_op /* 20 */ + .quad compat_vm_assist + .quad compat_update_va_mapping_otherdomain + .quad compat_iret + .quad compat_vcpu_op +- .quad do_ni_hypercall /* 25 */ ++ .quad compat_ni_hypercall /* 25 */ + .quad compat_mmuext_op + .quad compat_acm_op + .quad compat_nmi_op +@@ -345,11 +336,11 @@ ENTRY(compat_hypercall_table) + .quad compat_xenoprof_op + .quad compat_event_channel_op + .quad compat_physdev_op +- .quad do_ni_hypercall ++ .quad compat_ni_hypercall + .quad compat_sysctl /* 35 */ + .quad compat_domctl + .rept NR_hypercalls-((.-compat_hypercall_table)/8) +- .quad do_ni_hypercall ++ .quad compat_ni_hypercall + .endr + + ENTRY(compat_hypercall_args_table) +@@ -359,12 +350,12 @@ ENTRY(compat_hypercall_args_table) + .byte 2 /* compat_stack_switch */ + .byte 4 /* compat_set_callbacks */ + .byte 1 /* compat_fpu_taskswitch */ /* 5 */ +- .byte 2 /* compat_arch_sched_op_compat */ ++ .byte 2 /* compat_sched_op_compat */ + .byte 1 /* compat_platform_op */ + .byte 2 /* compat_set_debugreg */ + .byte 1 /* compat_get_debugreg */ + .byte 4 /* compat_update_descriptor */ /* 10 */ +- .byte 0 /* do_ni_hypercall */ ++ .byte 0 /* compat_ni_hypercall */ + .byte 2 /* compat_memory_op */ + .byte 2 /* compat_multicall */ + .byte 4 /* compat_update_va_mapping */ +@@ -378,7 +369,7 @@ ENTRY(compat_hypercall_args_table) + .byte 5 /* compat_update_va_mapping_otherdomain */ + .byte 0 /* compat_iret */ + .byte 3 /* compat_vcpu_op */ +- .byte 0 /* do_ni_hypercall */ /* 25 */ ++ .byte 0 /* compat_ni_hypercall */ /* 25 */ + .byte 4 /* compat_mmuext_op */ + .byte 1 /* compat_acm_op */ + .byte 2 /* compat_nmi_op */ +@@ -387,9 +378,9 @@ ENTRY(compat_hypercall_args_table) + .byte 2 /* compat_xenoprof_op */ + .byte 2 /* compat_event_channel_op */ + .byte 2 /* compat_physdev_op */ +- .byte 0 /* do_ni_hypercall */ ++ .byte 0 /* compat_ni_hypercall */ + .byte 1 /* compat_sysctl */ /* 35 */ + .byte 1 /* compat_domctl */ + .rept NR_hypercalls-(.-compat_hypercall_args_table) +- .byte 0 /* do_ni_hypercall */ ++ .byte 0 /* compat_ni_hypercall */ + .endr +Index: 2007-01-08/xen/arch/x86/x86_64/compat/traps.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/traps.c 2007-01-08 15:17:24.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_64/compat/traps.c 2007-01-08 15:17:29.000000000 +0100 +@@ -1,25 +1,6 @@ + #ifdef CONFIG_COMPAT + +-#if 0 /* XXX */ + #include +-#else +-struct compat_xen_callback { +- unsigned int cs; +- unsigned int eip; +-}; +-typedef struct compat_xen_callback xen_callback_compat_t; +- +-struct compat_callback_register { +- uint16_t type; +- uint16_t flags; +- xen_callback_compat_t address; +-}; +- +-struct compat_callback_unregister { +- uint16_t type; +- uint16_t _unused; +-}; +-#endif + + void compat_show_guest_stack(struct cpu_user_regs *regs, int debug_stack_lines) + { +Index: 2007-01-08/xen/common/Makefile +=================================================================== +--- 2007-01-08.orig/xen/common/Makefile 2007-01-08 15:17:24.000000000 +0100 ++++ 2007-01-08/xen/common/Makefile 2007-01-08 15:17:29.000000000 +0100 +@@ -35,5 +35,7 @@ obj-$(xenoprof) += xenoprof.o + + obj-$(CONFIG_XENCOMM) += xencomm.o + ++subdir-$(CONFIG_COMPAT) += compat ++ + # Object file contains changeset and compiler information. + version.o: $(BASEDIR)/include/xen/compile.h +Index: 2007-01-08/xen/common/compat/Makefile +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-08/xen/common/compat/Makefile 2007-01-08 15:17:29.000000000 +0100 +@@ -0,0 +1,4 @@ ++obj-y += kernel.o ++ ++# extra dependencies ++kernel.o: ../kernel.c +Index: 2007-01-08/xen/common/compat/kernel.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-08/xen/common/compat/kernel.c 2007-01-08 15:17:29.000000000 +0100 +@@ -0,0 +1,59 @@ ++/****************************************************************************** ++ * kernel.c ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define xen_extraversion compat_extraversion ++#define xen_extraversion_t compat_extraversion_t ++ ++#define xen_compile_info compat_compile_info ++#define xen_compile_info_t compat_compile_info_t ++ ++CHECK_TYPE(capabilities_info); ++ ++#define xen_platform_parameters compat_platform_parameters ++#define xen_platform_parameters_t compat_platform_parameters_t ++#undef HYPERVISOR_VIRT_START ++#define HYPERVISOR_VIRT_START HYPERVISOR_COMPAT_VIRT_START ++ ++#define xen_changeset_info compat_changeset_info ++#define xen_changeset_info_t compat_changeset_info_t ++ ++#define xen_feature_info compat_feature_info ++#define xen_feature_info_t compat_feature_info_t ++ ++CHECK_TYPE(domain_handle); ++ ++#define xennmi_callback compat_nmi_callback ++#define xennmi_callback_t compat_nmi_callback_t ++ ++#define DO(fn) int compat_##fn ++#define COMPAT ++ ++#include "../kernel.c" ++ ++int compat_disabled = 0; ++boolean_param("no-pv-compat", compat_disabled); ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * tab-width: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ +Index: 2007-01-08/xen/common/kernel.c +=================================================================== +--- 2007-01-08.orig/xen/common/kernel.c 2007-01-08 15:17:24.000000000 +0100 ++++ 2007-01-08/xen/common/kernel.c 2007-01-08 15:17:29.000000000 +0100 +@@ -11,11 +11,14 @@ + #include + #include + #include ++#include + #include + #include + #include + #include + ++#ifndef COMPAT ++ + int tainted; + + void cmdline_parse(char *cmdline) +@@ -116,11 +119,15 @@ void add_taint(unsigned flag) + tainted |= flag; + } + ++# define DO(fn) long do_##fn ++ ++#endif ++ + /* + * Simple hypercalls. + */ + +-long do_xen_version(int cmd, XEN_GUEST_HANDLE(void) arg) ++DO(xen_version)(int cmd, XEN_GUEST_HANDLE(void) arg) + { + switch ( cmd ) + { +@@ -230,6 +237,8 @@ long do_xen_version(int cmd, XEN_GUEST_H + return -ENOSYS; + } + ++#ifndef COMPAT ++ + long register_guest_nmi_callback(unsigned long address) + { + struct vcpu *v = current; +@@ -260,7 +269,9 @@ long unregister_guest_nmi_callback(void) + return 0; + } + +-long do_nmi_op(unsigned int cmd, XEN_GUEST_HANDLE(void) arg) ++#endif ++ ++DO(nmi_op)(unsigned int cmd, XEN_GUEST_HANDLE(void) arg) + { + struct xennmi_callback cb; + long rc = 0; +@@ -284,12 +295,12 @@ long do_nmi_op(unsigned int cmd, XEN_GUE + return rc; + } + +-long do_vm_assist(unsigned int cmd, unsigned int type) ++DO(vm_assist)(unsigned int cmd, unsigned int type) + { + return vm_assist(current->domain, cmd, type); + } + +-long do_ni_hypercall(void) ++DO(ni_hypercall)(void) + { + /* No-op hypercall. */ + return -ENOSYS; +Index: 2007-01-08/xen/include/Makefile +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-08/xen/include/Makefile 2007-01-08 15:18:26.000000000 +0100 +@@ -0,0 +1,60 @@ ++ifneq ($(CONFIG_COMPAT),) ++ ++compat-subarch-$(CONFIG_X86) := x86_32 ++compat-arch-$(CONFIG_X86) := x86 ++ ++headers-y := $(shell echo public/*.h | sed -e 's,[^[:space:]]*-[^[:space:]]*,,g' -e 's,public/,compat/,g') ++headers-y := $(filter-out %/dom0_ops.h,$(headers-y)) ++headers-y += compat/arch-$(compat-subarch-y).h ++headers-y += compat/arch-$(compat-arch-y)/xen.h ++headers-y += compat/arch-$(compat-arch-y)/xen-$(compat-subarch-y).h ++ ++cppflags-y := -include public/xen-compat.h ++cppflags-$(CONFIG_X86) += -m32 ++ ++# 8-byte types are 4-byte aligned on x86_32 ... ++prefix-$(CONFIG_X86) := \#pragma pack(push, 4) ++suffix-$(CONFIG_X86) := \#pragma pack(pop) ++ ++endif ++ ++.PHONY: all ++all: $(headers-y) ++ ++compat/%.h: compat/%.i Makefile ++ id=_$$(echo $@ | sed 'y,abcdefghijklmnopqrstuvwxyz-/.,ABCDEFGHIJKLMNOPQRSTUVWXYZ___,'); \ ++ echo "#ifndef $$id" >$@.new; \ ++ echo "#define $$id" >>$@.new; \ ++ echo "#include " >>$@.new; \ ++ $(if $(filter-out compat/arch-%.h,$@),echo "#include <$(patsubst compat/%,public/%,$@)>" >>$@.new;) \ ++ $(if $(prefix-y),echo "$(prefix-y)" >>$@.new;) \ ++ grep -v '^# [[:digit:]]' $< | \ ++ sed -e 's,__InClUdE__,#include,' \ ++ -e 's,"xen-compat.h",,' \ ++ -e 's,\(struct\|union\|enum\)[[:space:]]\+\(xen_\?\)\?\([[:alpha:]_]\),\1 compat_\3,g' \ ++ -e 's,_t\([^[:alnum:]_]\|$$\),_compat_t\1,g' \ ++ -e 's,\(8\|16\|32\|64\)_compat_t\([^[:alnum:]_]\|$$\),\1_t\2,g' \ ++ -e 's,\(^\|[^[:alnum:]_]\)xen_\?\([[:alnum:]_]*\)_compat_t\([^[:alnum:]_]\|$$\),\1compat_\2_t\3,g' \ ++ -e 's,\(^\|[^[:alnum:]_]\)XEN_\?,\1COMPAT_,' \ ++ -e 's,\(^\|[^[:alnum:]_]\)Xen_\?,\1Compat_,' \ ++ -e 's,\(^\|[^[:alnum:]]\)long\([^[:alnum:]]\|$$\),\1int\2,g' | \ ++ uniq >>$@.new; \ ++ $(if $(suffix-y),echo "$(suffix-y)" >>$@.new;) \ ++ echo "#endif /* $$id */" >>$@.new ++ mv -f $@.new $@ ++ ++compat/%.i: compat/%.c Makefile ++ $(CPP) $(CFLAGS) $(cppflags-y) -o $@ $< ++ ++compat/%.c: public/%.h Makefile ++ mkdir -p $(@D) ++ grep -v 'DEFINE_XEN_GUEST_HANDLE(long)' $< | \ ++ sed -e 's,^[[:space:]]*#[[:space:]]*include[[:space:]]\+,__InClUdE__ ,' \ ++ -e 's,^[[:space:]]*#[[:space:]]*define[[:space:]]\+\([[:upper:]_]*_GUEST_HANDLE\),#define HIDE_\1,' \ ++ -e 's,^[[:space:]]*#[[:space:]]*define[[:space:]]\+\([[:lower:]_]*_guest_handle\),#define hide_\1,' \ ++ -e 's,XEN_GUEST_HANDLE\(_[[:xdigit:]]\+\)\?,COMPAT_HANDLE,g' \ ++ >$@.new ++ mv -f $@.new $@ ++ ++clean:: ++ rm -rf compat +Index: 2007-01-08/xen/include/asm-x86/compat.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-08/xen/include/asm-x86/compat.h 2007-01-08 15:17:29.000000000 +0100 +@@ -0,0 +1,6 @@ ++/****************************************************************************** ++ * compat.h ++ */ ++ ++typedef uint32_t compat_ptr_t; ++typedef unsigned long full_ptr_t; +Index: 2007-01-08/xen/include/asm-x86/x86_64/uaccess.h +=================================================================== +--- 2007-01-08.orig/xen/include/asm-x86/x86_64/uaccess.h 2007-01-08 15:17:24.000000000 +0100 ++++ 2007-01-08/xen/include/asm-x86/x86_64/uaccess.h 2007-01-08 15:17:29.000000000 +0100 +@@ -15,6 +15,19 @@ + + #define array_access_ok(addr, count, size) (__addr_ok(addr)) + ++#ifdef CONFIG_COMPAT ++ ++#define __compat_addr_ok(addr) \ ++ ((unsigned long)(addr) < HYPERVISOR_COMPAT_VIRT_START) ++ ++#define compat_access_ok(addr, size) __compat_addr_ok((addr) + (size)) ++ ++#define compat_array_access_ok(addr,count,size) \ ++ (likely((count) < (~0U / (size))) && \ ++ compat_access_ok(addr, (count) * (size))) ++ ++#endif ++ + #define __put_user_size(x,ptr,size,retval,errret) \ + do { \ + retval = 0; \ +Index: 2007-01-08/xen/include/xen/compat.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-08/xen/include/xen/compat.h 2007-01-08 15:17:29.000000000 +0100 +@@ -0,0 +1,167 @@ ++/****************************************************************************** ++ * compat.h ++ */ ++ ++#ifndef __XEN_COMPAT_H__ ++#define __XEN_COMPAT_H__ ++ ++#include ++ ++#ifdef CONFIG_COMPAT ++ ++#include ++#include ++#include ++ ++#define __DEFINE_COMPAT_HANDLE(name, type) \ ++ typedef struct { \ ++ compat_ptr_t c; \ ++ type *_[0] __attribute__((__packed__)); \ ++ } __compat_handle_ ## name ++ ++#define DEFINE_COMPAT_HANDLE(name) __DEFINE_COMPAT_HANDLE(name, name) ++#define COMPAT_HANDLE(name) __compat_handle_ ## name ++ ++/* Is the compat handle a NULL reference? */ ++#define compat_handle_is_null(hnd) ((hnd).c == 0) ++ ++/* Offset the given compat handle into the array it refers to. */ ++#define compat_handle_add_offset(hnd, nr) \ ++ ((hnd).c += (nr) * sizeof(**(hnd)._)) ++ ++/* Cast a compat handle to the specified type of handle. */ ++#define compat_handle_cast(chnd, type) ({ \ ++ type *_x = (__typeof__(**(chnd)._) *)(full_ptr_t)(chnd).c; \ ++ (XEN_GUEST_HANDLE(type)) { _x }; \ ++}) ++ ++#define guest_from_compat_handle(ghnd, chnd) \ ++ set_xen_guest_handle(ghnd, \ ++ (__typeof__(**(chnd)._) *)(full_ptr_t)(chnd).c) ++ ++/* ++ * Copy an array of objects to guest context via a compat handle, ++ * specifying an offset into the guest array. ++ */ ++#define copy_to_compat_offset(hnd, off, ptr, nr) ({ \ ++ const typeof(ptr) _x = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \ ++ const typeof(*(ptr)) *const _y = (ptr); \ ++ copy_to_user(_x + (off), _y, sizeof(*_x) * (nr)); \ ++}) ++ ++/* ++ * Copy an array of objects from guest context via a compat handle, ++ * specifying an offset into the guest array. ++ */ ++#define copy_from_compat_offset(ptr, hnd, off, nr) ({ \ ++ const typeof(ptr) _x = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \ ++ const typeof(ptr) _y = (ptr); \ ++ copy_from_user(_y, _x + (off), sizeof(*_x) * (nr)); \ ++}) ++ ++#define copy_to_compat(hnd, ptr, nr) \ ++ copy_to_compat_offset(hnd, 0, ptr, nr) ++ ++#define copy_from_compat(ptr, hnd, nr) \ ++ copy_from_compat_offset(ptr, hnd, 0, nr) ++ ++/* Copy sub-field of a structure to guest context via a compat handle. */ ++#define copy_field_to_compat(hnd, ptr, field) ({ \ ++ typeof((ptr)->field) *const _x = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \ ++ const typeof((ptr)->field) *const _y = &(ptr)->field; \ ++ copy_to_user(_x, _y, sizeof(*_x)); \ ++}) ++ ++/* Copy sub-field of a structure from guest context via a compat handle. */ ++#define copy_field_from_compat(ptr, hnd, field) ({ \ ++ typeof((ptr)->field) *const _x = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \ ++ typeof((ptr)->field) *const _y = &(ptr)->field; \ ++ copy_from_user(_y, _x, sizeof(*_x)); \ ++}) ++ ++/* ++ * Pre-validate a guest handle. ++ * Allows use of faster __copy_* functions. ++ */ ++#define compat_handle_okay(hnd, nr) \ ++ compat_array_access_ok((void *)(full_ptr_t)(hnd).c, (nr), sizeof(**(hnd)._)) ++ ++#define __copy_to_compat_offset(hnd, off, ptr, nr) ({ \ ++ const typeof(ptr) _x = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \ ++ const typeof(*(ptr)) *const _y = (ptr); \ ++ __copy_to_user(_x + (off), _y, sizeof(*_x) * (nr)); \ ++}) ++ ++#define __copy_from_compat_offset(ptr, hnd, off, nr) ({ \ ++ const typeof(ptr) _x = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \ ++ const typeof(ptr) _y = (ptr); \ ++ __copy_from_user(_y, _x + (off), sizeof(*_x) * (nr)); \ ++}) ++ ++#define __copy_to_compat(hnd, ptr, nr) \ ++ __copy_to_compat_offset(hnd, 0, ptr, nr) ++ ++#define __copy_from_compat(ptr, hnd, nr) \ ++ __copy_from_compat_offset(ptr, hnd, 0, nr) ++ ++#define __copy_field_to_compat(hnd, ptr, field) ({ \ ++ typeof((ptr)->field) *const _x = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \ ++ const typeof((ptr)->field) *const _y = &(ptr)->field; \ ++ __copy_to_user(_x, _y, sizeof(*_x)); \ ++}) ++ ++#define __copy_field_from_compat(ptr, hnd, field) ({ \ ++ typeof((ptr)->field) *const _x = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \ ++ typeof((ptr)->field) *const _y = &(ptr)->field; \ ++ __copy_from_user(_y, _x, sizeof(*_x)); \ ++}) ++ ++ ++#define CHECK_TYPE(name) \ ++ typedef int __checkT ## name[1 - ((xen_ ## name ## _t *)0 != \ ++ (compat_ ## name ## _t *)0) * 2] ++#define CHECK_TYPE_(k, n) \ ++ typedef int __checkT ## k ## _ ## n[1 - ((k xen_ ## n *)0 != \ ++ (k compat_ ## n *)0) * 2] ++ ++#define CHECK_SIZE(name) \ ++ typedef int __checkS ## name[1 - (sizeof(xen_ ## name ## _t) != \ ++ sizeof(compat_ ## name ## _t)) * 2] ++#define CHECK_SIZE_(k, n) \ ++ typedef int __checkS ## k ## _ ## n[1 - (sizeof(k xen_ ## n) != \ ++ sizeof(k compat_ ## n)) * 2] ++ ++#define CHECK_FIELD(t, f) \ ++ typedef int __checkF ## t ## __ ## f[1 - (&((xen_ ## t ## _t *)0)->f != \ ++ &((compat_ ## t ## _t *)0)->f) * 2] ++#define CHECK_FIELD_(k, n, f) \ ++ typedef int __checkF ## k ## _ ## n ## __ ## f[1 - (&((k xen_ ## n *)0)->f != \ ++ &((k compat_ ## n *)0)->f) * 2] ++ ++#define CHECK_SUBFIELD_1(t, f1, f2) \ ++ typedef int __checkF1 ## t ## __ ## f1 ## __ ## f2 \ ++ [1 - (&((xen_ ## t ## _t *)0)->f1.f2 != \ ++ &((compat_ ## t ## _t *)0)->f1.f2) * 2] ++#define CHECK_SUBFIELD_1_(k, n, f1, f2) \ ++ typedef int __checkF1 ## k ## _ ## n ## __ ## f1 ## __ ## f2 \ ++ [1 - (&((k xen_ ## n *)0)->f1.f2 != \ ++ &((k compat_ ## n *)0)->f1.f2) * 2] ++ ++#define CHECK_SUBFIELD_2(t, f1, f2, f3) \ ++ typedef int __checkF2 ## t ## __ ## f1 ## __ ## f2 ## __ ## f3 \ ++ [1 - (&((xen_ ## t ## _t *)0)->f1.f2.f3 != \ ++ &((compat_ ## t ## _t *)0)->f1.f2.f3) * 2] ++#define CHECK_SUBFIELD_2_(k, n, f1, f2, f3) \ ++ typedef int __checkF2 ## k ## _ ## n ## __ ## f1 ## __ ## f2 ## __ ## f3 \ ++ [1 - (&((k xen_ ## n *)0)->f1.f2.f3 != \ ++ &((k compat_ ## n *)0)->f1.f2.f3) * 2] ++ ++extern int compat_disabled; ++ ++/* In-place translation functons: */ ++struct start_info; ++void xlat_start_info(struct start_info *, enum XLAT_start_info_console); ++ ++#endif ++ ++#endif /* __XEN_COMPAT_H__ */ diff --git a/32on64-kexec.patch b/32on64-kexec.patch new file mode 100644 index 0000000..38baebd --- /dev/null +++ b/32on64-kexec.patch @@ -0,0 +1,226 @@ +Enable compatibility mode operation for kexec. + +Index: 2006-12-18/xen/arch/x86/x86_64/compat/entry.S +=================================================================== +--- 2006-12-18.orig/xen/arch/x86/x86_64/compat/entry.S 2006-12-18 09:50:12.000000000 +0100 ++++ 2006-12-18/xen/arch/x86/x86_64/compat/entry.S 2006-12-18 09:52:27.000000000 +0100 +@@ -316,6 +316,7 @@ ENTRY(compat_hypercall_table) + .quad compat_ni_hypercall + .quad compat_sysctl /* 35 */ + .quad compat_domctl ++ .quad compat_kexec_op + .rept NR_hypercalls-((.-compat_hypercall_table)/8) + .quad compat_ni_hypercall + .endr +@@ -358,6 +359,7 @@ ENTRY(compat_hypercall_args_table) + .byte 0 /* compat_ni_hypercall */ + .byte 1 /* compat_sysctl */ /* 35 */ + .byte 1 /* compat_domctl */ ++ .byte 2 /* compat_kexec_op */ + .rept NR_hypercalls-(.-compat_hypercall_args_table) + .byte 0 /* compat_ni_hypercall */ + .endr +Index: 2006-12-18/xen/common/Makefile +=================================================================== +--- 2006-12-18.orig/xen/common/Makefile 2006-12-18 09:50:08.000000000 +0100 ++++ 2006-12-18/xen/common/Makefile 2006-12-18 09:52:27.000000000 +0100 +@@ -44,6 +44,7 @@ ifeq ($(CONFIG_COMPAT),y) + # extra dependencies + acm_ops.o: compat/acm_ops.c + grant_table.o: compat/grant_table.c ++kexec.o: compat/kexec.c + schedule.o: compat/schedule.c + xenoprof.o: compat/xenoprof.c + endif +Index: 2006-12-18/xen/common/compat/kexec.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2006-12-18/xen/common/compat/kexec.c 2006-12-18 09:52:27.000000000 +0100 +@@ -0,0 +1,33 @@ ++/* ++ * compat/kexec.c ++ */ ++ ++#include ++ ++#define COMPAT ++#define ret_t int ++ ++#define do_kexec_op compat_kexec_op ++ ++#undef kexec_get ++#define kexec_get(x) compat_kexec_get_##x ++#define xen_kexec_range compat_kexec_range ++#define xen_kexec_range_t compat_kexec_range_t ++ ++#define kexec_load_unload compat_kexec_load_unload ++#define xen_kexec_load compat_kexec_load ++#define xen_kexec_load_t compat_kexec_load_t ++ ++CHECK_kexec_exec; ++ ++#include "../kexec.c" ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * tab-width: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ +Index: 2006-12-18/xen/common/kexec.c +=================================================================== +--- 2006-12-18.orig/xen/common/kexec.c 2006-12-15 16:33:59.000000000 +0100 ++++ 2006-12-18/xen/common/kexec.c 2006-12-18 09:52:27.000000000 +0100 +@@ -22,6 +22,10 @@ + #include + #include + ++#ifndef COMPAT ++ ++typedef long ret_t; ++ + DEFINE_PER_CPU (crash_note_t, crash_notes); + cpumask_t crash_saved_cpus; + +@@ -143,7 +147,11 @@ static __init int register_crashdump_tri + } + __initcall(register_crashdump_trigger); + +-static int kexec_get_reserve(xen_kexec_range_t *range) ++#define kexec_get(x) kexec_get_##x ++ ++#endif ++ ++static int kexec_get(reserve)(xen_kexec_range_t *range) + { + range->start = kexec_crash_area.start; + range->size = kexec_crash_area.size; +@@ -152,14 +160,14 @@ static int kexec_get_reserve(xen_kexec_r + + extern unsigned long _text; + +-static int kexec_get_xen(xen_kexec_range_t *range) ++static int kexec_get(xen)(xen_kexec_range_t *range) + { + range->start = virt_to_maddr(&_text); + range->size = (unsigned long)&_end - (unsigned long)&_text; + return 0; + } + +-static int kexec_get_cpu(xen_kexec_range_t *range) ++static int kexec_get(cpu)(xen_kexec_range_t *range) + { + if ( range->nr < 0 || range->nr >= num_present_cpus() ) + return -EINVAL; +@@ -169,7 +177,7 @@ static int kexec_get_cpu(xen_kexec_range + return 0; + } + +-static int kexec_get_range(XEN_GUEST_HANDLE(void) uarg) ++static int kexec_get(range)(XEN_GUEST_HANDLE(void) uarg) + { + xen_kexec_range_t range; + int ret = -EINVAL; +@@ -180,13 +188,13 @@ static int kexec_get_range(XEN_GUEST_HAN + switch ( range.range ) + { + case KEXEC_RANGE_MA_CRASH: +- ret = kexec_get_reserve(&range); ++ ret = kexec_get(reserve)(&range); + break; + case KEXEC_RANGE_MA_XEN: +- ret = kexec_get_xen(&range); ++ ret = kexec_get(xen)(&range); + break; + case KEXEC_RANGE_MA_CPU: +- ret = kexec_get_cpu(&range); ++ ret = kexec_get(cpu)(&range); + break; + } + +@@ -196,6 +204,8 @@ static int kexec_get_range(XEN_GUEST_HAN + return ret; + } + ++#ifndef COMPAT ++ + static int kexec_load_get_bits(int type, int *base, int *bit) + { + switch ( type ) +@@ -214,6 +224,8 @@ static int kexec_load_get_bits(int type, + return 0; + } + ++#endif ++ + static int kexec_load_unload(unsigned long op, XEN_GUEST_HANDLE(void) uarg) + { + xen_kexec_load_t load; +@@ -236,7 +248,11 @@ static int kexec_load_unload(unsigned lo + + BUG_ON(test_bit((base + !pos), &kexec_flags)); /* must be free */ + ++#ifndef COMPAT + memcpy(image, &load.image, sizeof(*image)); ++#else ++ XLAT_kexec_image(image, &load.image); ++#endif + + if ( !(ret = machine_kexec_load(load.type, base + !pos, image)) ) + { +@@ -261,6 +277,8 @@ static int kexec_load_unload(unsigned lo + return ret; + } + ++#ifndef COMPAT ++ + static int kexec_exec(XEN_GUEST_HANDLE(void) uarg) + { + xen_kexec_exec_t exec; +@@ -294,7 +312,9 @@ static int kexec_exec(XEN_GUEST_HANDLE(v + return -EINVAL; /* never reached */ + } + +-long do_kexec_op(unsigned long op, XEN_GUEST_HANDLE(void) uarg) ++#endif ++ ++ret_t do_kexec_op(unsigned long op, XEN_GUEST_HANDLE(void) uarg) + { + unsigned long flags; + int ret = -EINVAL; +@@ -305,7 +325,7 @@ long do_kexec_op(unsigned long op, XEN_G + switch ( op ) + { + case KEXEC_CMD_kexec_get_range: +- ret = kexec_get_range(uarg); ++ ret = kexec_get(range)(uarg); + break; + case KEXEC_CMD_kexec_load: + case KEXEC_CMD_kexec_unload: +@@ -324,6 +344,10 @@ long do_kexec_op(unsigned long op, XEN_G + return ret; + } + ++#if defined(CONFIG_COMPAT) && !defined(COMPAT) ++#include "compat/kexec.c" ++#endif ++ + /* + * Local variables: + * mode: C +Index: 2006-12-18/xen/include/xlat.lst +=================================================================== +--- 2006-12-18.orig/xen/include/xlat.lst 2006-12-18 09:52:23.000000000 +0100 ++++ 2006-12-18/xen/include/xlat.lst 2006-12-18 09:52:27.000000000 +0100 +@@ -32,6 +32,8 @@ + ! gnttab_transfer grant_table.h + ? gnttab_unmap_grant_ref grant_table.h + ? grant_entry grant_table.h ++? kexec_exec kexec.h ++! kexec_image kexec.h + ! add_to_physmap memory.h + ! foreign_memory_map memory.h + ! memory_exchange memory.h diff --git a/32on64-m2p.patch b/32on64-m2p.patch new file mode 100644 index 0000000..4ae0192 --- /dev/null +++ b/32on64-m2p.patch @@ -0,0 +1,1192 @@ +Add page table setup and handling, including the creation of an m2p table +meaningful to compatibility mode guests. + +Index: 2007-01-31/xen/arch/x86/domain.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/domain.c 2007-01-31 09:29:10.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/domain.c 2007-01-31 09:29:11.000000000 +0100 +@@ -127,6 +127,28 @@ void free_vcpu_struct(struct vcpu *v) + xfree(v); + } + ++#ifdef CONFIG_COMPAT ++static int setup_compat_l4(struct vcpu *v) ++{ ++ struct page_info *pg = alloc_domheap_page(NULL); ++ l4_pgentry_t *l4tab; ++ ++ if ( !pg ) ++ return -ENOMEM; ++ l4tab = copy_page(page_to_virt(pg), idle_pg_table); ++ l4tab[l4_table_offset(LINEAR_PT_VIRT_START)] = ++ l4e_from_page(pg, __PAGE_HYPERVISOR); ++ l4tab[l4_table_offset(PERDOMAIN_VIRT_START)] = ++ l4e_from_paddr(__pa(v->domain->arch.mm_perdomain_l3), __PAGE_HYPERVISOR); ++ v->arch.guest_table = pagetable_from_page(pg); ++ v->arch.guest_table_user = v->arch.guest_table; ++ ++ return 0; ++} ++#else ++#define setup_compat_l4(v) 0 ++#endif ++ + int vcpu_initialise(struct vcpu *v) + { + struct domain *d = v->domain; +@@ -161,11 +183,16 @@ int vcpu_initialise(struct vcpu *v) + v->arch.perdomain_ptes = + d->arch.mm_perdomain_pt + (v->vcpu_id << GDT_LDT_VCPU_SHIFT); + ++ if ( IS_COMPAT(d) && (rc = setup_compat_l4(v)) != 0 ) ++ return rc; ++ + return 0; + } + + void vcpu_destroy(struct vcpu *v) + { ++ if ( IS_COMPAT(v->domain) ) ++ free_domheap_page(pagetable_get_page(v->arch.guest_table)); + } + + int arch_domain_create(struct domain *d) +@@ -218,6 +245,10 @@ int arch_domain_create(struct domain *d) + + #endif /* __x86_64__ */ + ++#ifdef CONFIG_COMPAT ++ HYPERVISOR_COMPAT_VIRT_START(d) = __HYPERVISOR_COMPAT_VIRT_START; ++#endif ++ + shadow_lock_init(d); + for ( i = 0; i <= SHADOW_MAX_ORDER; i++ ) + INIT_LIST_HEAD(&d->arch.shadow.freelists[i]); +@@ -353,18 +384,41 @@ int arch_set_info_guest( + if ( (rc = (int)set_gdt(v, c->gdt_frames, c->gdt_ents)) != 0 ) + return rc; + +- cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c->ctrlreg[3])); +- +- if ( shadow_mode_refcounts(d) +- ? !get_page(mfn_to_page(cr3_pfn), d) +- : !get_page_and_type(mfn_to_page(cr3_pfn), d, +- PGT_base_page_table) ) ++ if ( !IS_COMPAT(d) ) + { +- destroy_gdt(v); +- return -EINVAL; ++ cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c->ctrlreg[3])); ++ ++ if ( shadow_mode_refcounts(d) ++ ? !get_page(mfn_to_page(cr3_pfn), d) ++ : !get_page_and_type(mfn_to_page(cr3_pfn), d, ++ PGT_base_page_table) ) ++ { ++ destroy_gdt(v); ++ return -EINVAL; ++ } ++ ++ v->arch.guest_table = pagetable_from_pfn(cr3_pfn); + } ++#ifdef CONFIG_COMPAT ++ else ++ { ++ l4_pgentry_t *l4tab; ++ ++ cr3_pfn = gmfn_to_mfn(d, compat_cr3_to_pfn(c->ctrlreg[3])); + +- v->arch.guest_table = pagetable_from_pfn(cr3_pfn); ++ if ( shadow_mode_refcounts(d) ++ ? !get_page(mfn_to_page(cr3_pfn), d) ++ : !get_page_and_type(mfn_to_page(cr3_pfn), d, ++ PGT_l3_page_table) ) ++ { ++ destroy_gdt(v); ++ return -EINVAL; ++ } ++ ++ l4tab = __va(pagetable_get_paddr(v->arch.guest_table)); ++ *l4tab = l4e_from_pfn(cr3_pfn, _PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED); ++ } ++#endif + } + + /* Shadow: make sure the domain has enough shadow memory to +Index: 2007-01-31/xen/arch/x86/domain_build.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/domain_build.c 2007-01-31 09:29:10.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/domain_build.c 2007-01-31 09:29:11.000000000 +0100 +@@ -91,9 +91,11 @@ string_param("dom0_ioports_disable", opt + #define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) + #define L3_PROT (_PAGE_PRESENT) + #elif defined(__x86_64__) +-/* Allow ring-3 access in long mode as guest cannot use ring 1. */ ++/* Allow ring-3 access in long mode as guest cannot use ring 1 ... */ + #define BASE_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER) + #define L1_PROT (BASE_PROT|_PAGE_GUEST_KERNEL) ++/* ... except for compatibility mode guests. */ ++#define COMPAT_L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED) + #define L2_PROT (BASE_PROT|_PAGE_DIRTY) + #define L3_PROT (BASE_PROT|_PAGE_DIRTY) + #define L4_PROT (BASE_PROT|_PAGE_DIRTY) +@@ -262,8 +264,8 @@ int construct_dom0(struct domain *d, + start_info_t *si; + struct vcpu *v = d->vcpu[0]; + const char *p; +- unsigned long hypercall_page; +- int hypercall_page_defined; ++ unsigned long long value; ++ int value_defined; + #if defined(__i386__) + char *image_start = (char *)_image_start; /* use lowmem mappings */ + char *initrd_start = (char *)_initrd_start; /* use lowmem mappings */ +@@ -323,6 +325,7 @@ int construct_dom0(struct domain *d, + rc = parseelfimage(&dsi); + #ifdef CONFIG_COMPAT + if ( rc == -ENOSYS ++ && !compat_disabled + && (rc = parseelf32image(&dsi)) == 0 ) + { + l1_pgentry_t gdt_l1e; +@@ -370,10 +373,37 @@ int construct_dom0(struct domain *d, + + #ifdef CONFIG_COMPAT + if ( IS_COMPAT(d) ) ++ { ++ value = xen_elf32note_numeric(&dsi, XEN_ELFNOTE_HV_START_LOW, &value_defined); + p = xen_elf32note_string(&dsi, XEN_ELFNOTE_FEATURES); ++ } + else + #endif ++ { ++ value = xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HV_START_LOW, &value_defined); + p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES); ++ } ++ if ( value_defined ) ++ { ++#if CONFIG_PAGING_LEVELS < 4 ++ unsigned long mask = (1UL << L2_PAGETABLE_SHIFT) - 1; ++#else ++ unsigned long mask = !IS_COMPAT(d) ++ ? (1UL << L4_PAGETABLE_SHIFT) - 1 ++ : (1UL << L2_PAGETABLE_SHIFT) - 1; ++#endif ++ ++ value = (value + mask) & ~mask; ++#ifdef CONFIG_COMPAT ++ HYPERVISOR_COMPAT_VIRT_START(d) = max_t(unsigned int, m2p_compat_vstart, value); ++ if ( value > (!IS_COMPAT(d) ? ++ HYPERVISOR_VIRT_START : ++ __HYPERVISOR_COMPAT_VIRT_START) ) ++#else ++ if ( value > HYPERVISOR_VIRT_START ) ++#endif ++ panic("Domain 0 expects too high a hypervisor start address.\n"); ++ } + if ( p != NULL ) + { + parse_features(p, +@@ -400,7 +430,9 @@ int construct_dom0(struct domain *d, + vinitrd_start = round_pgup(dsi.v_end); + vinitrd_end = vinitrd_start + initrd_len; + vphysmap_start = round_pgup(vinitrd_end); +- vphysmap_end = vphysmap_start + (nr_pages * sizeof(unsigned long)); ++ vphysmap_end = vphysmap_start + (nr_pages * (!IS_COMPAT(d) ? ++ sizeof(unsigned long) : ++ sizeof(unsigned int))); + vstartinfo_start = round_pgup(vphysmap_end); + vstartinfo_end = (vstartinfo_start + + sizeof(struct start_info) + +@@ -429,7 +461,9 @@ int construct_dom0(struct domain *d, + ((_l) & ~((1UL<<(_s))-1))) >> (_s)) + if ( (1 + /* # L4 */ + NR(dsi.v_start, v_end, L4_PAGETABLE_SHIFT) + /* # L3 */ +- NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT) + /* # L2 */ ++ (!IS_COMPAT(d) ? ++ NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT) : /* # L2 */ ++ 4) + /* # compat L2 */ + NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT)) /* # L1 */ + <= nr_pt_pages ) + break; +@@ -619,8 +653,10 @@ int construct_dom0(struct domain *d, + #elif defined(__x86_64__) + + /* Overlap with Xen protected area? */ +- if ( (dsi.v_start < HYPERVISOR_VIRT_END) && +- (v_end > HYPERVISOR_VIRT_START) ) ++ if ( !IS_COMPAT(d) ? ++ ((dsi.v_start < HYPERVISOR_VIRT_END) && ++ (v_end > HYPERVISOR_VIRT_START)) : ++ (v_end > HYPERVISOR_COMPAT_VIRT_START(d)) ) + { + printk("DOM0 image overlaps with Xen private area.\n"); + return -EINVAL; +@@ -633,8 +669,18 @@ int construct_dom0(struct domain *d, + } + + /* WARNING: The new domain must have its 'processor' field filled in! */ +- maddr_to_page(mpt_alloc)->u.inuse.type_info = PGT_l4_page_table; +- l4start = l4tab = __va(mpt_alloc); mpt_alloc += PAGE_SIZE; ++ if ( !IS_COMPAT(d) ) ++ { ++ maddr_to_page(mpt_alloc)->u.inuse.type_info = PGT_l4_page_table; ++ l4start = l4tab = __va(mpt_alloc); mpt_alloc += PAGE_SIZE; ++ } ++ else ++ { ++ page = alloc_domheap_page(NULL); ++ if ( !page ) ++ panic("Not enough RAM for domain 0 PML4.\n"); ++ l4start = l4tab = page_to_virt(page); ++ } + memcpy(l4tab, idle_pg_table, PAGE_SIZE); + l4tab[l4_table_offset(LINEAR_PT_VIRT_START)] = + l4e_from_paddr(__pa(l4start), __PAGE_HYPERVISOR); +@@ -679,7 +725,7 @@ int construct_dom0(struct domain *d, + *l2tab = l2e_from_paddr(__pa(l1start), L2_PROT); + l2tab++; + } +- *l1tab = l1e_from_pfn(mfn, L1_PROT); ++ *l1tab = l1e_from_pfn(mfn, !IS_COMPAT(d) ? L1_PROT : COMPAT_L1_PROT); + l1tab++; + + page = mfn_to_page(mfn); +@@ -690,6 +736,30 @@ int construct_dom0(struct domain *d, + mfn++; + } + ++#ifdef CONFIG_COMPAT ++ if ( IS_COMPAT(d) ) ++ { ++ /* Ensure the first four L3 entries are all populated. */ ++ for ( i = 0, l3tab = l3start; i < 4; ++i, ++l3tab ) ++ { ++ if ( !l3e_get_intpte(*l3tab) ) ++ { ++ maddr_to_page(mpt_alloc)->u.inuse.type_info = PGT_l2_page_table; ++ l2tab = __va(mpt_alloc); mpt_alloc += PAGE_SIZE; ++ clear_page(l2tab); ++ *l3tab = l3e_from_paddr(__pa(l2tab), L3_PROT); ++ } ++ if ( i == 3 ) ++ l3e_get_page(*l3tab)->u.inuse.type_info |= PGT_pae_xen_l2; ++ } ++ /* Install read-only guest visible MPT mapping. */ ++ l2tab = l3e_to_l2e(l3start[3]); ++ memcpy(&l2tab[COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(d)], ++ &compat_idle_pg_table_l2[l2_table_offset(HIRO_COMPAT_MPT_VIRT_START)], ++ COMPAT_L2_PAGETABLE_XEN_SLOTS(d) * sizeof(*l2tab)); ++ } ++#endif ++ + /* Pages that are part of page tables must be read only. */ + l4tab = l4start + l4_table_offset(vpt_start); + l3start = l3tab = l4e_to_l3e(*l4tab); +@@ -708,7 +778,8 @@ int construct_dom0(struct domain *d, + page->u.inuse.type_info |= PGT_validated | 1; + + /* Top-level p.t. is pinned. */ +- if ( (page->u.inuse.type_info & PGT_type_mask) == PGT_l4_page_table ) ++ if ( (page->u.inuse.type_info & PGT_type_mask) == ++ (!IS_COMPAT(d) ? PGT_l4_page_table : PGT_l3_page_table) ) + { + page->count_info += 1; + page->u.inuse.type_info += 1 | PGT_pinned; +@@ -761,26 +832,26 @@ int construct_dom0(struct domain *d, + if ( IS_COMPAT(d) ) + { + (void)loadelf32image(&dsi); +- hypercall_page = +- xen_elf32note_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &hypercall_page_defined); ++ value = ++ xen_elf32note_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &value_defined); + } + else + #endif + { + (void)loadelfimage(&dsi); +- hypercall_page = +- xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &hypercall_page_defined); ++ value = ++ xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &value_defined); + } +- if ( hypercall_page_defined ) ++ if ( value_defined ) + { +- if ( (hypercall_page < dsi.v_start) || (hypercall_page >= v_end) ) ++ if ( (value < dsi.v_start) || (value >= v_end) ) + { + write_ptbase(current); + local_irq_enable(); + printk("Invalid HYPERCALL_PAGE field in ELF notes.\n"); + return -1; + } +- hypercall_page_initialise(d, (void *)hypercall_page); ++ hypercall_page_initialise(d, (void *)(unsigned long)value); + } + + /* Copy the initial ramdisk. */ +@@ -798,7 +869,7 @@ int construct_dom0(struct domain *d, + si->shared_info = virt_to_maddr(d->shared_info); + + si->flags = SIF_PRIVILEGED | SIF_INITDOMAIN; +- si->pt_base = vpt_start; ++ si->pt_base = vpt_start + 2 * PAGE_SIZE * !!IS_COMPAT(d); + si->nr_pt_frames = nr_pt_pages; + si->mfn_list = vphysmap_start; + sprintf(si->magic, "xen-%i.%i-x86_%d%s", +@@ -814,7 +885,10 @@ int construct_dom0(struct domain *d, + if ( pfn > REVERSE_START ) + mfn = alloc_epfn - (pfn - REVERSE_START); + #endif +- ((unsigned long *)vphysmap_start)[pfn] = mfn; ++ if ( !IS_COMPAT(d) ) ++ ((unsigned long *)vphysmap_start)[pfn] = mfn; ++ else ++ ((unsigned int *)vphysmap_start)[pfn] = mfn; + set_gpfn_from_mfn(mfn, pfn); + } + while ( pfn < nr_pages ) +@@ -827,7 +901,10 @@ int construct_dom0(struct domain *d, + #ifndef NDEBUG + #define pfn (nr_pages - 1 - (pfn - (alloc_epfn - alloc_spfn))) + #endif +- ((unsigned long *)vphysmap_start)[pfn] = mfn; ++ if ( !IS_COMPAT(d) ) ++ ((unsigned long *)vphysmap_start)[pfn] = mfn; ++ else ++ ((unsigned int *)vphysmap_start)[pfn] = mfn; + set_gpfn_from_mfn(mfn, pfn); + #undef pfn + page++; pfn++; +Index: 2007-01-31/xen/arch/x86/domctl.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/domctl.c 2006-12-13 11:15:53.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/domctl.c 2007-01-31 09:29:11.000000000 +0100 +@@ -311,7 +311,12 @@ void arch_getdomaininfo_ctxt( + if ( guest_kernel_mode(v, &v->arch.guest_context.user_regs) ) + c->flags |= VGCF_in_kernel; + +- c->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); ++ if ( !IS_COMPAT(v->domain) ) ++ c->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); ++#ifdef CONFIG_COMPAT ++ else ++ c->ctrlreg[3] = compat_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); ++#endif + + c->vm_assist = v->domain->vm_assist; + } +Index: 2007-01-31/xen/arch/x86/e820.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/e820.c 2006-12-13 11:15:53.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/e820.c 2007-01-31 09:29:11.000000000 +0100 +@@ -1,6 +1,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -341,6 +342,39 @@ static void __init clip_4gb(void) + #define clip_4gb() ((void)0) + #endif + ++#ifdef CONFIG_COMPAT ++static void __init clip_compat(void) ++{ ++ unsigned long long limit; ++ unsigned int i; ++ ++ if ( compat_disabled ) ++ return; ++ /* 32-bit guests restricted to 166 GB (with current memory allocator). */ ++ limit = (unsigned long long)(MACH2PHYS_COMPAT_VIRT_END - ++ __HYPERVISOR_COMPAT_VIRT_START) << 10; ++ for ( i = 0; i < e820.nr_map; i++ ) ++ { ++ if ( (e820.map[i].addr + e820.map[i].size) <= limit ) ++ continue; ++ printk("WARNING: Only the first %Lu GB of the physical memory map " ++ "can be accessed\n" ++ " by compatibility mode guests. " ++ "Truncating the memory map...\n", ++ limit >> 30); ++ if ( e820.map[i].addr >= limit ) ++ e820.nr_map = i; ++ else ++ { ++ e820.map[i].size = limit - e820.map[i].addr; ++ e820.nr_map = i + 1; ++ } ++ } ++} ++#else ++#define clip_compat() ((void)0) ++#endif ++ + static void __init clip_mem(void) + { + int i; +@@ -374,6 +408,7 @@ static void __init machine_specific_memo + *raw_nr = nr; + (void)copy_e820_map(raw, nr); + clip_4gb(); ++ clip_compat(); + clip_mem(); + } + +Index: 2007-01-31/xen/arch/x86/mm.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/mm.c 2007-01-31 09:29:03.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/mm.c 2007-01-31 09:29:11.000000000 +0100 +@@ -126,13 +126,6 @@ + */ + #define MMU_UPDATE_PREEMPTED (~(~0U>>1)) + +-static void free_l2_table(struct page_info *page); +-static void free_l1_table(struct page_info *page); +- +-static int mod_l2_entry(l2_pgentry_t *, l2_pgentry_t, unsigned long, +- unsigned long type); +-static int mod_l1_entry(l1_pgentry_t *, l1_pgentry_t, unsigned long gl1mfn); +- + /* Used to defer flushing of memory structures. */ + struct percpu_mm_info { + #define DOP_FLUSH_TLB (1<<0) /* Flush the local TLB. */ +@@ -158,6 +151,15 @@ struct page_info *frame_table; + unsigned long max_page; + unsigned long total_pages; + ++#ifdef CONFIG_COMPAT ++l2_pgentry_t *compat_idle_pg_table_l2 = NULL; ++#define l3_disallow_mask(d) (!IS_COMPAT(d) ? \ ++ L3_DISALLOW_MASK : \ ++ COMPAT_L3_DISALLOW_MASK) ++#else ++#define l3_disallow_mask(d) L3_DISALLOW_MASK ++#endif ++ + void __init init_frametable(void) + { + unsigned long nr_pages, page_step, i, mfn; +@@ -629,9 +631,9 @@ get_page_from_l3e( + if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) ) + return 1; + +- if ( unlikely((l3e_get_flags(l3e) & L3_DISALLOW_MASK)) ) ++ if ( unlikely((l3e_get_flags(l3e) & l3_disallow_mask(d))) ) + { +- MEM_LOG("Bad L3 flags %x", l3e_get_flags(l3e) & L3_DISALLOW_MASK); ++ MEM_LOG("Bad L3 flags %x", l3e_get_flags(l3e) & l3_disallow_mask(d)); + return 0; + } + +@@ -668,9 +670,10 @@ get_page_from_l4e( + #ifdef __x86_64__ + + #ifdef USER_MAPPINGS_ARE_GLOBAL +-#define adjust_guest_l1e(pl1e) \ ++#define adjust_guest_l1e(pl1e, d) \ + do { \ +- if ( likely(l1e_get_flags((pl1e)) & _PAGE_PRESENT) ) \ ++ if ( likely(l1e_get_flags((pl1e)) & _PAGE_PRESENT) && \ ++ likely(!IS_COMPAT(d)) ) \ + { \ + /* _PAGE_GUEST_KERNEL page cannot have the Global bit set. */ \ + if ( (l1e_get_flags((pl1e)) & (_PAGE_GUEST_KERNEL|_PAGE_GLOBAL)) \ +@@ -684,39 +687,55 @@ get_page_from_l4e( + } \ + } while ( 0 ) + #else +-#define adjust_guest_l1e(pl1e) \ ++#define adjust_guest_l1e(pl1e, d) \ + do { \ +- if ( likely(l1e_get_flags((pl1e)) & _PAGE_PRESENT) ) \ ++ if ( likely(l1e_get_flags((pl1e)) & _PAGE_PRESENT) && \ ++ likely(!IS_COMPAT(d)) ) \ + l1e_add_flags((pl1e), _PAGE_USER); \ + } while ( 0 ) + #endif + +-#define adjust_guest_l2e(pl2e) \ ++#define adjust_guest_l2e(pl2e, d) \ + do { \ +- if ( likely(l2e_get_flags((pl2e)) & _PAGE_PRESENT) ) \ ++ if ( likely(l2e_get_flags((pl2e)) & _PAGE_PRESENT) && \ ++ likely(!IS_COMPAT(d)) ) \ + l2e_add_flags((pl2e), _PAGE_USER); \ + } while ( 0 ) + +-#define adjust_guest_l3e(pl3e) \ ++#define adjust_guest_l3e(pl3e, d) \ + do { \ + if ( likely(l3e_get_flags((pl3e)) & _PAGE_PRESENT) ) \ +- l3e_add_flags((pl3e), _PAGE_USER); \ ++ l3e_add_flags((pl3e), likely(!IS_COMPAT(d)) ? \ ++ _PAGE_USER : \ ++ _PAGE_USER|_PAGE_RW); \ + } while ( 0 ) + +-#define adjust_guest_l4e(pl4e) \ ++#define adjust_guest_l4e(pl4e, d) \ + do { \ +- if ( likely(l4e_get_flags((pl4e)) & _PAGE_PRESENT) ) \ ++ if ( likely(l4e_get_flags((pl4e)) & _PAGE_PRESENT) && \ ++ likely(!IS_COMPAT(d)) ) \ + l4e_add_flags((pl4e), _PAGE_USER); \ + } while ( 0 ) + + #else /* !defined(__x86_64__) */ + +-#define adjust_guest_l1e(_p) ((void)0) +-#define adjust_guest_l2e(_p) ((void)0) +-#define adjust_guest_l3e(_p) ((void)0) ++#define adjust_guest_l1e(_p, _d) ((void)(_d)) ++#define adjust_guest_l2e(_p, _d) ((void)(_d)) ++#define adjust_guest_l3e(_p, _d) ((void)(_d)) + + #endif + ++#ifdef CONFIG_COMPAT ++#define unadjust_guest_l3e(pl3e, d) \ ++ do { \ ++ if ( unlikely(IS_COMPAT(d)) && \ ++ likely(l3e_get_flags((pl3e)) & _PAGE_PRESENT) ) \ ++ l3e_remove_flags((pl3e), _PAGE_USER|_PAGE_RW|_PAGE_ACCESSED); \ ++ } while ( 0 ) ++#else ++#define unadjust_guest_l3e(_p, _d) ((void)(_d)) ++#endif ++ + void put_page_from_l1e(l1_pgentry_t l1e, struct domain *d) + { + unsigned long pfn = l1e_get_pfn(l1e); +@@ -818,7 +837,7 @@ static int alloc_l1_table(struct page_in + unlikely(!get_page_from_l1e(pl1e[i], d)) ) + goto fail; + +- adjust_guest_l1e(pl1e[i]); ++ adjust_guest_l1e(pl1e[i], d); + } + + unmap_domain_page(pl1e); +@@ -834,13 +853,20 @@ static int alloc_l1_table(struct page_in + return 0; + } + +-#ifdef CONFIG_X86_PAE +-static int create_pae_xen_mappings(l3_pgentry_t *pl3e) ++#if defined(CONFIG_X86_PAE) || defined(CONFIG_COMPAT) ++static int create_pae_xen_mappings(struct domain *d, l3_pgentry_t *pl3e) + { + struct page_info *page; +- l2_pgentry_t *pl2e, l2e; ++ l2_pgentry_t *pl2e; + l3_pgentry_t l3e3; ++#ifndef CONFIG_COMPAT ++ l2_pgentry_t l2e; + int i; ++#else ++ ++ if ( !IS_COMPAT(d) ) ++ return 1; ++#endif + + pl3e = (l3_pgentry_t *)((unsigned long)pl3e & PAGE_MASK); + +@@ -873,6 +899,7 @@ static int create_pae_xen_mappings(l3_pg + + /* Xen private mappings. */ + pl2e = map_domain_page(l3e_get_pfn(l3e3)); ++#ifndef CONFIG_COMPAT + memcpy(&pl2e[L2_PAGETABLE_FIRST_XEN_SLOT & (L2_PAGETABLE_ENTRIES-1)], + &idle_pg_table_l2[L2_PAGETABLE_FIRST_XEN_SLOT], + L2_PAGETABLE_XEN_SLOTS * sizeof(l2_pgentry_t)); +@@ -890,11 +917,20 @@ static int create_pae_xen_mappings(l3_pg + l2e = l2e_from_pfn(l3e_get_pfn(pl3e[i]), __PAGE_HYPERVISOR); + l2e_write(&pl2e[l2_table_offset(LINEAR_PT_VIRT_START) + i], l2e); + } ++#else ++ memcpy(&pl2e[COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(d)], ++ &compat_idle_pg_table_l2[l2_table_offset(HIRO_COMPAT_MPT_VIRT_START)], ++ COMPAT_L2_PAGETABLE_XEN_SLOTS(d) * sizeof(*pl2e)); ++#endif + unmap_domain_page(pl2e); + + return 1; + } ++#else ++# define create_pae_xen_mappings(d, pl3e) (1) ++#endif + ++#ifdef CONFIG_X86_PAE + /* Flush a pgdir update into low-memory caches. */ + static void pae_flush_pgd( + unsigned long mfn, unsigned int idx, l3_pgentry_t nl3e) +@@ -929,12 +965,8 @@ static void pae_flush_pgd( + + flush_tlb_mask(d->domain_dirty_cpumask); + } +- +-#elif CONFIG_X86_64 +-# define create_pae_xen_mappings(pl3e) (1) +-# define pae_flush_pgd(mfn, idx, nl3e) ((void)0) + #else +-# define create_pae_xen_mappings(pl3e) (1) ++# define pae_flush_pgd(mfn, idx, nl3e) ((void)0) + #endif + + static int alloc_l2_table(struct page_info *page, unsigned long type) +@@ -948,11 +980,11 @@ static int alloc_l2_table(struct page_in + + for ( i = 0; i < L2_PAGETABLE_ENTRIES; i++ ) + { +- if ( is_guest_l2_slot(type, i) && ++ if ( is_guest_l2_slot(d, type, i) && + unlikely(!get_page_from_l2e(pl2e[i], pfn, d)) ) + goto fail; + +- adjust_guest_l2e(pl2e[i]); ++ adjust_guest_l2e(pl2e[i], d); + } + + #if CONFIG_PAGING_LEVELS == 2 +@@ -975,7 +1007,7 @@ static int alloc_l2_table(struct page_in + fail: + MEM_LOG("Failure in alloc_l2_table: entry %d", i); + while ( i-- > 0 ) +- if ( is_guest_l2_slot(type, i) ) ++ if ( is_guest_l2_slot(d, type, i) ) + put_page_from_l2e(pl2e[i], pfn); + + unmap_domain_page(pl2e); +@@ -1007,13 +1039,24 @@ static int alloc_l3_table(struct page_in + #endif + + pl3e = map_domain_page(pfn); ++ ++ /* ++ * PAE guests allocate full pages, but aren't required to initialize ++ * more than the first four entries; when running in compatibility ++ * mode, however, the full page is visible to the MMU, and hence all ++ * 512 entries must be valid/verified, which is most easily achieved ++ * by clearing them out. ++ */ ++ if ( IS_COMPAT(d) ) ++ memset(pl3e + 4, 0, (L3_PAGETABLE_ENTRIES - 4) * sizeof(*pl3e)); ++ + for ( i = 0; i < L3_PAGETABLE_ENTRIES; i++ ) + { +-#ifdef CONFIG_X86_PAE +- if ( i == 3 ) ++#if defined(CONFIG_X86_PAE) || defined(CONFIG_COMPAT) ++ if ( (CONFIG_PAGING_LEVELS < 4 || IS_COMPAT(d)) && i == 3 ) + { + if ( !(l3e_get_flags(pl3e[i]) & _PAGE_PRESENT) || +- (l3e_get_flags(pl3e[i]) & L3_DISALLOW_MASK) || ++ (l3e_get_flags(pl3e[i]) & l3_disallow_mask(d)) || + !get_page_and_type_from_pagenr(l3e_get_pfn(pl3e[i]), + PGT_l2_page_table | + PGT_pae_xen_l2, +@@ -1026,10 +1069,10 @@ static int alloc_l3_table(struct page_in + unlikely(!get_page_from_l3e(pl3e[i], pfn, d)) ) + goto fail; + +- adjust_guest_l3e(pl3e[i]); ++ adjust_guest_l3e(pl3e[i], d); + } + +- if ( !create_pae_xen_mappings(pl3e) ) ++ if ( !create_pae_xen_mappings(d, pl3e) ) + goto fail; + + unmap_domain_page(pl3e); +@@ -1062,7 +1105,7 @@ static int alloc_l4_table(struct page_in + unlikely(!get_page_from_l4e(pl4e[i], pfn, d)) ) + goto fail; + +- adjust_guest_l4e(pl4e[i]); ++ adjust_guest_l4e(pl4e[i], d); + } + + /* Xen private mappings. */ +@@ -1110,6 +1153,9 @@ static void free_l1_table(struct page_in + + static void free_l2_table(struct page_info *page) + { ++#ifdef CONFIG_COMPAT ++ struct domain *d = page_get_owner(page); ++#endif + unsigned long pfn = page_to_mfn(page); + l2_pgentry_t *pl2e; + int i; +@@ -1117,7 +1163,7 @@ static void free_l2_table(struct page_in + pl2e = map_domain_page(pfn); + + for ( i = 0; i < L2_PAGETABLE_ENTRIES; i++ ) +- if ( is_guest_l2_slot(page->u.inuse.type_info, i) ) ++ if ( is_guest_l2_slot(d, page->u.inuse.type_info, i) ) + put_page_from_l2e(pl2e[i], pfn); + + unmap_domain_page(pl2e); +@@ -1130,6 +1176,7 @@ static void free_l2_table(struct page_in + + static void free_l3_table(struct page_info *page) + { ++ struct domain *d = page_get_owner(page); + unsigned long pfn = page_to_mfn(page); + l3_pgentry_t *pl3e; + int i; +@@ -1138,7 +1185,10 @@ static void free_l3_table(struct page_in + + for ( i = 0; i < L3_PAGETABLE_ENTRIES; i++ ) + if ( is_guest_l3_slot(i) ) ++ { + put_page_from_l3e(pl3e[i], pfn); ++ unadjust_guest_l3e(pl3e[i], d); ++ } + + unmap_domain_page(pl3e); + } +@@ -1234,7 +1284,7 @@ static int mod_l1_entry(l1_pgentry_t *pl + return 0; + } + +- adjust_guest_l1e(nl1e); ++ adjust_guest_l1e(nl1e, d); + + /* Fast path for identical mapping, r/w and presence. */ + if ( !l1e_has_changed(ol1e, nl1e, _PAGE_RW | _PAGE_PRESENT) ) +@@ -1297,8 +1347,9 @@ static int mod_l2_entry(l2_pgentry_t *pl + unsigned long type) + { + l2_pgentry_t ol2e; ++ struct domain *d = current->domain; + +- if ( unlikely(!is_guest_l2_slot(type,pgentry_ptr_to_slot(pl2e))) ) ++ if ( unlikely(!is_guest_l2_slot(d, type, pgentry_ptr_to_slot(pl2e))) ) + { + MEM_LOG("Illegal L2 update attempt in Xen-private area %p", pl2e); + return 0; +@@ -1316,7 +1367,7 @@ static int mod_l2_entry(l2_pgentry_t *pl + return 0; + } + +- adjust_guest_l2e(nl2e); ++ adjust_guest_l2e(nl2e, d); + + /* Fast path for identical mapping and presence. */ + if ( !l2e_has_changed(ol2e, nl2e, _PAGE_PRESENT)) +@@ -1348,6 +1399,7 @@ static int mod_l3_entry(l3_pgentry_t *pl + unsigned long pfn) + { + l3_pgentry_t ol3e; ++ struct domain *d = current->domain; + int okay; + + if ( unlikely(!is_guest_l3_slot(pgentry_ptr_to_slot(pl3e))) ) +@@ -1356,12 +1408,13 @@ static int mod_l3_entry(l3_pgentry_t *pl + return 0; + } + +-#ifdef CONFIG_X86_PAE ++#if defined(CONFIG_X86_PAE) || defined(CONFIG_COMPAT) + /* + * Disallow updates to final L3 slot. It contains Xen mappings, and it + * would be a pain to ensure they remain continuously valid throughout. + */ +- if ( pgentry_ptr_to_slot(pl3e) >= 3 ) ++ if ( (CONFIG_PAGING_LEVELS < 4 || IS_COMPAT(d)) && ++ pgentry_ptr_to_slot(pl3e) >= 3 ) + return 0; + #endif + +@@ -1370,14 +1423,14 @@ static int mod_l3_entry(l3_pgentry_t *pl + + if ( l3e_get_flags(nl3e) & _PAGE_PRESENT ) + { +- if ( unlikely(l3e_get_flags(nl3e) & L3_DISALLOW_MASK) ) ++ if ( unlikely(l3e_get_flags(nl3e) & l3_disallow_mask(d)) ) + { + MEM_LOG("Bad L3 flags %x", +- l3e_get_flags(nl3e) & L3_DISALLOW_MASK); ++ l3e_get_flags(nl3e) & l3_disallow_mask(d)); + return 0; + } + +- adjust_guest_l3e(nl3e); ++ adjust_guest_l3e(nl3e, d); + + /* Fast path for identical mapping and presence. */ + if (!l3e_has_changed(ol3e, nl3e, _PAGE_PRESENT)) +@@ -1397,7 +1450,7 @@ static int mod_l3_entry(l3_pgentry_t *pl + return 0; + } + +- okay = create_pae_xen_mappings(pl3e); ++ okay = create_pae_xen_mappings(d, pl3e); + BUG_ON(!okay); + + pae_flush_pgd(pfn, pgentry_ptr_to_slot(pl3e), nl3e); +@@ -1435,7 +1488,7 @@ static int mod_l4_entry(l4_pgentry_t *pl + return 0; + } + +- adjust_guest_l4e(nl4e); ++ adjust_guest_l4e(nl4e, current->domain); + + /* Fast path for identical mapping and presence. */ + if (!l4e_has_changed(ol4e, nl4e, _PAGE_PRESENT)) +@@ -2259,8 +2312,7 @@ int do_mmu_update( + case PGT_l2_page_table: + { + l2_pgentry_t l2e = l2e_from_intpte(req.val); +- okay = mod_l2_entry( +- (l2_pgentry_t *)va, l2e, mfn, type_info); ++ okay = mod_l2_entry(va, l2e, mfn, type_info); + } + break; + #if CONFIG_PAGING_LEVELS >= 3 +@@ -2273,11 +2325,12 @@ int do_mmu_update( + #endif + #if CONFIG_PAGING_LEVELS >= 4 + case PGT_l4_page_table: +- { +- l4_pgentry_t l4e = l4e_from_intpte(req.val); +- okay = mod_l4_entry(va, l4e, mfn); +- } +- break; ++ if ( !IS_COMPAT(FOREIGNDOM) ) ++ { ++ l4_pgentry_t l4e = l4e_from_intpte(req.val); ++ okay = mod_l4_entry(va, l4e, mfn); ++ } ++ break; + #endif + } + +@@ -2385,7 +2438,7 @@ static int create_grant_pte_mapping( + + ASSERT(spin_is_locked(&d->big_lock)); + +- adjust_guest_l1e(nl1e); ++ adjust_guest_l1e(nl1e, d); + + gmfn = pte_addr >> PAGE_SHIFT; + mfn = gmfn_to_mfn(d, gmfn); +@@ -2506,7 +2559,7 @@ static int create_grant_va_mapping( + + ASSERT(spin_is_locked(&d->big_lock)); + +- adjust_guest_l1e(nl1e); ++ adjust_guest_l1e(nl1e, d); + + pl1e = guest_map_l1e(v, va, &gl1mfn); + if ( !pl1e ) +@@ -3181,7 +3234,7 @@ static int ptwr_emulated_update( + } + } + +- adjust_guest_l1e(nl1e); ++ adjust_guest_l1e(nl1e, d); + + /* Checked successfully: do the update (write or cmpxchg). */ + pl1e = map_domain_page(page_to_mfn(page)); +Index: 2007-01-31/xen/arch/x86/x86_64/mm.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/x86_64/mm.c 2007-01-31 09:29:03.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/x86_64/mm.c 2007-01-31 09:29:11.000000000 +0100 +@@ -31,6 +31,10 @@ + #include + #include + ++#ifdef CONFIG_COMPAT ++unsigned int m2p_compat_vstart = __HYPERVISOR_COMPAT_VIRT_START; ++#endif ++ + struct page_info *alloc_xen_pagetable(void) + { + extern int early_boot; +@@ -121,6 +125,47 @@ void __init paging_init(void) + l2_ro_mpt++; + } + ++#ifdef CONFIG_COMPAT ++ if ( !compat_disabled ) ++ { ++ /* Create user-accessible L2 directory to map the MPT for compatibility guests. */ ++ BUILD_BUG_ON(l4_table_offset(RDWR_MPT_VIRT_START) != ++ l4_table_offset(HIRO_COMPAT_MPT_VIRT_START)); ++ l3_ro_mpt = l4e_to_l3e(idle_pg_table[l4_table_offset(HIRO_COMPAT_MPT_VIRT_START)]); ++ if ( (l2_pg = alloc_domheap_page(NULL)) == NULL ) ++ goto nomem; ++ compat_idle_pg_table_l2 = l2_ro_mpt = clear_page(page_to_virt(l2_pg)); ++ l3e_write(&l3_ro_mpt[l3_table_offset(HIRO_COMPAT_MPT_VIRT_START)], ++ l3e_from_page(l2_pg, __PAGE_HYPERVISOR)); ++ l2_ro_mpt += l2_table_offset(HIRO_COMPAT_MPT_VIRT_START); ++ /* ++ * Allocate and map the compatibility mode machine-to-phys table. ++ */ ++ mpt_size = (mpt_size >> 1) + (1UL << (L2_PAGETABLE_SHIFT - 1)); ++ if ( mpt_size > RDWR_COMPAT_MPT_VIRT_END - RDWR_COMPAT_MPT_VIRT_START ) ++ mpt_size = RDWR_COMPAT_MPT_VIRT_END - RDWR_COMPAT_MPT_VIRT_START; ++ mpt_size &= ~((1UL << L2_PAGETABLE_SHIFT) - 1UL); ++ if ( m2p_compat_vstart + mpt_size < MACH2PHYS_COMPAT_VIRT_END ) ++ m2p_compat_vstart = MACH2PHYS_COMPAT_VIRT_END - mpt_size; ++ for ( i = 0; i < (mpt_size >> L2_PAGETABLE_SHIFT); i++ ) ++ { ++ if ( (l1_pg = alloc_domheap_pages(NULL, PAGETABLE_ORDER, 0)) == NULL ) ++ goto nomem; ++ map_pages_to_xen( ++ RDWR_COMPAT_MPT_VIRT_START + (i << L2_PAGETABLE_SHIFT), ++ page_to_mfn(l1_pg), ++ 1UL << PAGETABLE_ORDER, ++ PAGE_HYPERVISOR); ++ memset((void *)(RDWR_COMPAT_MPT_VIRT_START + (i << L2_PAGETABLE_SHIFT)), ++ 0x55, ++ 1UL << L2_PAGETABLE_SHIFT); ++ /* NB. Cannot be GLOBAL as the pt entries get copied into per-VM space. */ ++ l2e_write(l2_ro_mpt, l2e_from_page(l1_pg, _PAGE_PSE|_PAGE_PRESENT)); ++ l2_ro_mpt++; ++ } ++ } ++#endif ++ + /* Set up linear page table mapping. */ + l4e_write(&idle_pg_table[l4_table_offset(LINEAR_PT_VIRT_START)], + l4e_from_paddr(__pa(idle_pg_table), __PAGE_HYPERVISOR)); +@@ -182,6 +227,30 @@ void subarch_init_memory(void) + share_xen_page_with_privileged_guests(page, XENSHARE_readonly); + } + } ++#ifdef CONFIG_COMPAT ++ if ( !compat_disabled ) ++ { ++ for ( v = RDWR_COMPAT_MPT_VIRT_START; ++ v != RDWR_COMPAT_MPT_VIRT_END; ++ v += 1 << L2_PAGETABLE_SHIFT ) ++ { ++ l3e = l4e_to_l3e(idle_pg_table[l4_table_offset(v)])[ ++ l3_table_offset(v)]; ++ if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) ) ++ continue; ++ l2e = l3e_to_l2e(l3e)[l2_table_offset(v)]; ++ if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) ) ++ continue; ++ m2p_start_mfn = l2e_get_pfn(l2e); ++ ++ for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ ) ++ { ++ struct page_info *page = mfn_to_page(m2p_start_mfn + i); ++ share_xen_page_with_privileged_guests(page, XENSHARE_readonly); ++ } ++ } ++ } ++#endif + } + + long subarch_memory_op(int op, XEN_GUEST_HANDLE(void) arg) +@@ -189,7 +258,8 @@ long subarch_memory_op(int op, XEN_GUEST + struct xen_machphys_mfn_list xmml; + l3_pgentry_t l3e; + l2_pgentry_t l2e; +- unsigned long mfn, v; ++ unsigned long v; ++ xen_pfn_t mfn; + unsigned int i; + long rc = 0; + +Index: 2007-01-31/xen/common/compat/kernel.c +=================================================================== +--- 2007-01-31.orig/xen/common/compat/kernel.c 2007-01-31 09:29:09.000000000 +0100 ++++ 2007-01-31/xen/common/compat/kernel.c 2007-01-31 09:29:11.000000000 +0100 +@@ -27,7 +27,7 @@ CHECK_TYPE(capabilities_info); + #define xen_platform_parameters compat_platform_parameters + #define xen_platform_parameters_t compat_platform_parameters_t + #undef HYPERVISOR_VIRT_START +-#define HYPERVISOR_VIRT_START HYPERVISOR_COMPAT_VIRT_START ++#define HYPERVISOR_VIRT_START HYPERVISOR_COMPAT_VIRT_START(current->domain) + + #define xen_changeset_info compat_changeset_info + #define xen_changeset_info_t compat_changeset_info_t +Index: 2007-01-31/xen/include/asm-x86/config.h +=================================================================== +--- 2007-01-31.orig/xen/include/asm-x86/config.h 2007-01-31 09:29:03.000000000 +0100 ++++ 2007-01-31/xen/include/asm-x86/config.h 2007-01-31 09:29:11.000000000 +0100 +@@ -133,7 +133,11 @@ extern unsigned long _end; /* standard E + * Page-frame information array. + * 0xffff828800000000 - 0xffff828bffffffff [16GB, 2^34 bytes, PML4:261] + * ioremap()/fixmap area. +- * 0xffff828c00000000 - 0xffff82ffffffffff [464GB, PML4:261] ++ * 0xffff828c00000000 - 0xffff828c3fffffff [1GB, 2^30 bytes, PML4:261] ++ * Compatibility machine-to-phys translation table. ++ * 0xffff828c40000000 - 0xffff828c7fffffff [1GB, 2^30 bytes, PML4:261] ++ * High read-only compatibility machine-to-phys translation table. ++ * 0xffff828c80000000 - 0xffff82ffffffffff [462GB, PML4:261] + * Reserved for future use. + * 0xffff830000000000 - 0xffff83ffffffffff [1TB, 2^40 bytes, PML4:262-263] + * 1:1 direct mapping of all physical memory. Xen and its heap live here. +@@ -182,17 +186,33 @@ extern unsigned long _end; /* standard E + /* Slot 261: ioremap()/fixmap area (16GB). */ + #define IOREMAP_VIRT_START (FRAMETABLE_VIRT_END) + #define IOREMAP_VIRT_END (IOREMAP_VIRT_START + (16UL<<30)) ++/* Slot 261: compatibility machine-to-phys conversion table (1GB). */ ++#define RDWR_COMPAT_MPT_VIRT_START IOREMAP_VIRT_END ++#define RDWR_COMPAT_MPT_VIRT_END (RDWR_COMPAT_MPT_VIRT_START + (1UL << 30)) ++/* Slot 261: high read-only compatibility machine-to-phys conversion table (1GB). */ ++#define HIRO_COMPAT_MPT_VIRT_START RDWR_COMPAT_MPT_VIRT_END ++#define HIRO_COMPAT_MPT_VIRT_END (HIRO_COMPAT_MPT_VIRT_START + (1UL << 30)) + /* Slot 262-263: A direct 1:1 mapping of all of physical memory. */ + #define DIRECTMAP_VIRT_START (PML4_ADDR(262)) + #define DIRECTMAP_VIRT_END (DIRECTMAP_VIRT_START + PML4_ENTRY_BYTES*2) + ++#ifndef __ASSEMBLY__ ++ ++/* This is not a fixed value, just a lower limit. */ + #define __HYPERVISOR_COMPAT_VIRT_START 0xF5800000 +-#define HYPERVISOR_COMPAT_VIRT_START \ +- mk_unsigned_long(__HYPERVISOR_COMPAT_VIRT_START) ++#define HYPERVISOR_COMPAT_VIRT_START(d) ((d)->arch.hv_compat_vstart) + #define MACH2PHYS_COMPAT_VIRT_START HYPERVISOR_COMPAT_VIRT_START + #define MACH2PHYS_COMPAT_VIRT_END 0xFFE00000 +-#define MACH2PHYS_COMPAT_NR_ENTRIES \ +- ((MACH2PHYS_COMPAT_VIRT_END-MACH2PHYS_COMPAT_VIRT_START)>>2) ++#define MACH2PHYS_COMPAT_NR_ENTRIES(d) \ ++ ((MACH2PHYS_COMPAT_VIRT_END-MACH2PHYS_COMPAT_VIRT_START(d))>>2) ++ ++#define COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(d) \ ++ l2_table_offset(HYPERVISOR_COMPAT_VIRT_START(d)) ++#define COMPAT_L2_PAGETABLE_LAST_XEN_SLOT l2_table_offset(~0U) ++#define COMPAT_L2_PAGETABLE_XEN_SLOTS(d) \ ++ (COMPAT_L2_PAGETABLE_LAST_XEN_SLOT - COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(d) + 1) ++ ++#endif + + #define PGT_base_page_table PGT_l4_page_table + +Index: 2007-01-31/xen/include/asm-x86/domain.h +=================================================================== +--- 2007-01-31.orig/xen/include/asm-x86/domain.h 2007-01-31 09:19:50.000000000 +0100 ++++ 2007-01-31/xen/include/asm-x86/domain.h 2007-01-31 09:29:11.000000000 +0100 +@@ -98,6 +98,10 @@ struct arch_domain + struct mapcache mapcache; + #endif + ++#ifdef CONFIG_COMPAT ++ unsigned int hv_compat_vstart; ++#endif ++ + /* I/O-port admin-specified access capabilities. */ + struct rangeset *ioport_caps; + +Index: 2007-01-31/xen/include/asm-x86/mm.h +=================================================================== +--- 2007-01-31.orig/xen/include/asm-x86/mm.h 2007-01-31 09:29:03.000000000 +0100 ++++ 2007-01-31/xen/include/asm-x86/mm.h 2007-01-31 09:29:11.000000000 +0100 +@@ -257,7 +257,16 @@ int check_descriptor(const struct domain + #define INVALID_M2P_ENTRY (~0UL) + #define VALID_M2P(_e) (!((_e) & (1UL<<(BITS_PER_LONG-1)))) + ++#ifdef CONFIG_COMPAT ++#define compat_machine_to_phys_mapping ((unsigned int *)RDWR_COMPAT_MPT_VIRT_START) ++#define set_gpfn_from_mfn(mfn, pfn) \ ++ ((void)(compat_disabled || \ ++ (mfn) >= (RDWR_COMPAT_MPT_VIRT_END - RDWR_COMPAT_MPT_VIRT_START) / 4 || \ ++ (compat_machine_to_phys_mapping[(mfn)] = (unsigned int)(pfn))), \ ++ machine_to_phys_mapping[(mfn)] = (pfn)) ++#else + #define set_gpfn_from_mfn(mfn, pfn) (machine_to_phys_mapping[(mfn)] = (pfn)) ++#endif + #define get_gpfn_from_mfn(mfn) (machine_to_phys_mapping[(mfn)]) + + +Index: 2007-01-31/xen/include/asm-x86/page.h +=================================================================== +--- 2007-01-31.orig/xen/include/asm-x86/page.h 2007-01-31 09:19:50.000000000 +0100 ++++ 2007-01-31/xen/include/asm-x86/page.h 2007-01-31 09:29:11.000000000 +0100 +@@ -206,6 +206,7 @@ typedef struct { u32 pfn; } pagetable_t; + typedef struct { u64 pfn; } pagetable_t; + #endif + #define pagetable_get_paddr(x) ((paddr_t)(x).pfn << PAGE_SHIFT) ++#define pagetable_get_page(x) mfn_to_page((x).pfn) + #define pagetable_get_pfn(x) ((x).pfn) + #define pagetable_is_null(x) ((x).pfn == 0) + #define pagetable_from_pfn(pfn) ((pagetable_t) { (pfn) }) +@@ -284,6 +285,10 @@ extern l2_pgentry_t idle_pg_table_l2[R + #else + extern root_pgentry_t idle_pg_table[ROOT_PAGETABLE_ENTRIES]; + extern l2_pgentry_t idle_pg_table_l2[ROOT_PAGETABLE_ENTRIES]; ++#ifdef CONFIG_COMPAT ++extern l2_pgentry_t *compat_idle_pg_table_l2; ++extern unsigned int m2p_compat_vstart; ++#endif + #endif + void paging_init(void); + void setup_idle_pagetable(void); +Index: 2007-01-31/xen/include/asm-x86/x86_32/page-2level.h +=================================================================== +--- 2007-01-31.orig/xen/include/asm-x86/x86_32/page-2level.h 2006-12-15 16:33:59.000000000 +0100 ++++ 2007-01-31/xen/include/asm-x86/x86_32/page-2level.h 2007-01-31 09:29:11.000000000 +0100 +@@ -42,7 +42,7 @@ typedef l2_pgentry_t root_pgentry_t; + + /* misc */ + #define is_guest_l1_slot(_s) (1) +-#define is_guest_l2_slot(_t,_s) ((_s) < L2_PAGETABLE_FIRST_XEN_SLOT) ++#define is_guest_l2_slot(_d, _t,_s) ((_s) < L2_PAGETABLE_FIRST_XEN_SLOT) + + /* + * PTE pfn and flags: +Index: 2007-01-31/xen/include/asm-x86/x86_32/page-3level.h +=================================================================== +--- 2007-01-31.orig/xen/include/asm-x86/x86_32/page-3level.h 2006-12-15 16:33:59.000000000 +0100 ++++ 2007-01-31/xen/include/asm-x86/x86_32/page-3level.h 2007-01-31 09:29:11.000000000 +0100 +@@ -67,7 +67,7 @@ typedef l3_pgentry_t root_pgentry_t; + + /* misc */ + #define is_guest_l1_slot(s) (1) +-#define is_guest_l2_slot(t,s) \ ++#define is_guest_l2_slot(d,t,s) \ + ( !((t) & PGT_pae_xen_l2) || \ + ((s) < (L2_PAGETABLE_FIRST_XEN_SLOT & (L2_PAGETABLE_ENTRIES - 1))) ) + #define is_guest_l3_slot(s) (1) +Index: 2007-01-31/xen/include/asm-x86/x86_64/page.h +=================================================================== +--- 2007-01-31.orig/xen/include/asm-x86/x86_64/page.h 2006-12-15 16:33:59.000000000 +0100 ++++ 2007-01-31/xen/include/asm-x86/x86_64/page.h 2007-01-31 09:29:11.000000000 +0100 +@@ -54,7 +54,10 @@ typedef l4_pgentry_t root_pgentry_t; + #define l4_linear_offset(_a) (((_a) & VADDR_MASK) >> L4_PAGETABLE_SHIFT) + + #define is_guest_l1_slot(_s) (1) +-#define is_guest_l2_slot(_t, _s) (1) ++#define is_guest_l2_slot(_d, _t, _s) \ ++ ( !IS_COMPAT(_d) || \ ++ !((_t) & PGT_pae_xen_l2) || \ ++ ((_s) < COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(_d)) ) + #define is_guest_l3_slot(_s) (1) + #define is_guest_l4_slot(_s) \ + (((_s) < ROOT_PAGETABLE_FIRST_XEN_SLOT) || \ +@@ -93,6 +96,8 @@ typedef l4_pgentry_t root_pgentry_t; + #define L3_DISALLOW_MASK (BASE_DISALLOW_MASK | 0x180U /* must-be-zero */) + #define L4_DISALLOW_MASK (BASE_DISALLOW_MASK | 0x180U /* must-be-zero */) + ++#define COMPAT_L3_DISALLOW_MASK 0xFFFFF1E6U /* must-be-zero */ ++ + #define PAGE_HYPERVISOR (__PAGE_HYPERVISOR | _PAGE_GLOBAL) + #define PAGE_HYPERVISOR_NOCACHE (__PAGE_HYPERVISOR_NOCACHE | _PAGE_GLOBAL) + +Index: 2007-01-31/xen/include/asm-x86/x86_64/uaccess.h +=================================================================== +--- 2007-01-31.orig/xen/include/asm-x86/x86_64/uaccess.h 2007-01-31 09:29:09.000000000 +0100 ++++ 2007-01-31/xen/include/asm-x86/x86_64/uaccess.h 2007-01-31 09:29:11.000000000 +0100 +@@ -18,7 +18,7 @@ + #ifdef CONFIG_COMPAT + + #define __compat_addr_ok(addr) \ +- ((unsigned long)(addr) < HYPERVISOR_COMPAT_VIRT_START) ++ ((unsigned long)(addr) < HYPERVISOR_COMPAT_VIRT_START(current->domain)) + + #define compat_access_ok(addr, size) __compat_addr_ok((addr) + (size)) + diff --git a/32on64-memop.patch b/32on64-memop.patch new file mode 100644 index 0000000..9d80af5 --- /dev/null +++ b/32on64-memop.patch @@ -0,0 +1,1196 @@ +Enable compatibility mode operation for HYPERVISOR_memory_op, +HYPERVISOR_update_descriptor, HYPERVISOR_update_va_mapping. This also +introduces infrastructure to do argument translation. + +Index: 2007-01-08/xen/arch/x86/domain.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/domain.c 2006-12-18 09:49:18.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/domain.c 2007-01-08 14:53:55.000000000 +0100 +@@ -128,10 +128,98 @@ void free_vcpu_struct(struct vcpu *v) + } + + #ifdef CONFIG_COMPAT ++ ++int setup_arg_xlat_area(struct vcpu *v, l4_pgentry_t *l4tab) ++{ ++ struct domain *d = v->domain; ++ unsigned i; ++ struct page_info *pg; ++ ++ if ( !d->arch.mm_arg_xlat_l3 ) ++ { ++ pg = alloc_domheap_page(NULL); ++ if ( !pg ) ++ return -ENOMEM; ++ d->arch.mm_arg_xlat_l3 = clear_page(page_to_virt(pg)); ++ } ++ ++ l4tab[l4_table_offset(COMPAT_ARG_XLAT_VIRT_BASE)] = ++ l4e_from_paddr(__pa(d->arch.mm_arg_xlat_l3), __PAGE_HYPERVISOR); ++ ++ for ( i = 0; i < COMPAT_ARG_XLAT_PAGES; ++i ) ++ { ++ unsigned long va = COMPAT_ARG_XLAT_VIRT_START(v->vcpu_id) + i * PAGE_SIZE; ++ l2_pgentry_t *l2tab; ++ l1_pgentry_t *l1tab; ++ ++ if ( !l3e_get_intpte(d->arch.mm_arg_xlat_l3[l3_table_offset(va)]) ) ++ { ++ pg = alloc_domheap_page(NULL); ++ if ( !pg ) ++ return -ENOMEM; ++ clear_page(page_to_virt(pg)); ++ d->arch.mm_arg_xlat_l3[l3_table_offset(va)] = l3e_from_page(pg, __PAGE_HYPERVISOR); ++ } ++ l2tab = l3e_to_l2e(d->arch.mm_arg_xlat_l3[l3_table_offset(va)]); ++ if ( !l2e_get_intpte(l2tab[l2_table_offset(va)]) ) ++ { ++ pg = alloc_domheap_page(NULL); ++ if ( !pg ) ++ return -ENOMEM; ++ clear_page(page_to_virt(pg)); ++ l2tab[l2_table_offset(va)] = l2e_from_page(pg, __PAGE_HYPERVISOR); ++ } ++ l1tab = l2e_to_l1e(l2tab[l2_table_offset(va)]); ++ BUG_ON(l1e_get_intpte(l1tab[l1_table_offset(va)])); ++ pg = alloc_domheap_page(NULL); ++ if ( !pg ) ++ return -ENOMEM; ++ l1tab[l1_table_offset(va)] = l1e_from_page(pg, PAGE_HYPERVISOR); ++ } ++ ++ return 0; ++} ++ ++static void release_arg_xlat_area(struct domain *d) ++{ ++ if ( d->arch.mm_arg_xlat_l3 ) ++ { ++ unsigned l3; ++ ++ for ( l3 = 0; l3 < L3_PAGETABLE_ENTRIES; ++l3 ) ++ { ++ if ( l3e_get_intpte(d->arch.mm_arg_xlat_l3[l3]) ) ++ { ++ l2_pgentry_t *l2tab = l3e_to_l2e(d->arch.mm_arg_xlat_l3[l3]); ++ unsigned l2; ++ ++ for ( l2 = 0; l2 < L2_PAGETABLE_ENTRIES; ++l2 ) ++ { ++ if ( l2e_get_intpte(l2tab[l2]) ) ++ { ++ l1_pgentry_t *l1tab = l2e_to_l1e(l2tab[l2]); ++ unsigned l1; ++ ++ for ( l1 = 0; l1 < L1_PAGETABLE_ENTRIES; ++l1 ) ++ { ++ if ( l1e_get_intpte(l1tab[l1]) ) ++ free_domheap_page(l1e_get_page(l1tab[l1])); ++ } ++ free_domheap_page(l2e_get_page(l2tab[l2])); ++ } ++ } ++ free_domheap_page(l3e_get_page(d->arch.mm_arg_xlat_l3[l3])); ++ } ++ } ++ free_domheap_page(virt_to_page(d->arch.mm_arg_xlat_l3)); ++ } ++} ++ + static int setup_compat_l4(struct vcpu *v) + { + struct page_info *pg = alloc_domheap_page(NULL); + l4_pgentry_t *l4tab; ++ int rc; + + if ( !pg ) + return -ENOMEM; +@@ -143,10 +231,26 @@ static int setup_compat_l4(struct vcpu * + v->arch.guest_table = pagetable_from_page(pg); + v->arch.guest_table_user = v->arch.guest_table; + ++ if ( (rc = setup_arg_xlat_area(v, l4tab)) < 0 ) ++ { ++ free_domheap_page(pg); ++ return rc; ++ } ++ + return 0; + } ++ ++static void release_compat_l4(struct vcpu *v) ++{ ++ free_domheap_page(pagetable_get_page(v->arch.guest_table)); ++ v->arch.guest_table = pagetable_null(); ++ v->arch.guest_table_user = pagetable_null(); ++} ++ + #else ++#define release_arg_xlat_area(d) ((void)0) + #define setup_compat_l4(v) 0 ++#define release_compat_l4(v) ((void)0) + #endif + + int vcpu_initialise(struct vcpu *v) +@@ -192,7 +296,7 @@ int vcpu_initialise(struct vcpu *v) + void vcpu_destroy(struct vcpu *v) + { + if ( IS_COMPAT(v->domain) ) +- free_domheap_page(pagetable_get_page(v->arch.guest_table)); ++ release_compat_l4(v); + } + + int arch_domain_create(struct domain *d) +@@ -305,6 +409,9 @@ void arch_domain_destroy(struct domain * + free_domheap_page(virt_to_page(d->arch.mm_perdomain_l3)); + #endif + ++ if ( IS_COMPAT(d) ) ++ release_arg_xlat_area(d); ++ + free_xenheap_page(d->shared_info); + } + +@@ -945,55 +1052,153 @@ unsigned long hypercall_create_continuat + + for ( i = 0; *p != '\0'; i++ ) + mcs->call.args[i] = next_arg(p, args); ++ if ( IS_COMPAT(current->domain) ) ++ { ++ for ( ; i < 6; i++ ) ++ mcs->call.args[i] = 0; ++ } + } + else + { + regs = guest_cpu_user_regs(); +-#if defined(__i386__) + regs->eax = op; ++ regs->eip -= 2; /* re-execute 'syscall' / 'int 0x82' */ + +- if ( supervisor_mode_kernel || is_hvm_vcpu(current) ) +- regs->eip &= ~31; /* re-execute entire hypercall entry stub */ ++#ifdef __x86_64__ ++ if ( !IS_COMPAT(current->domain) ) ++ { ++ for ( i = 0; *p != '\0'; i++ ) ++ { ++ arg = next_arg(p, args); ++ switch ( i ) ++ { ++ case 0: regs->rdi = arg; break; ++ case 1: regs->rsi = arg; break; ++ case 2: regs->rdx = arg; break; ++ case 3: regs->r10 = arg; break; ++ case 4: regs->r8 = arg; break; ++ case 5: regs->r9 = arg; break; ++ } ++ } ++ } + else +- regs->eip -= 2; /* re-execute 'int 0x82' */ +- +- for ( i = 0; *p != '\0'; i++ ) ++#endif + { +- arg = next_arg(p, args); +- switch ( i ) ++ if ( supervisor_mode_kernel || is_hvm_vcpu(current) ) ++ regs->eip &= ~31; /* re-execute entire hypercall entry stub */ ++ ++ for ( i = 0; *p != '\0'; i++ ) + { +- case 0: regs->ebx = arg; break; +- case 1: regs->ecx = arg; break; +- case 2: regs->edx = arg; break; +- case 3: regs->esi = arg; break; +- case 4: regs->edi = arg; break; +- case 5: regs->ebp = arg; break; ++ arg = next_arg(p, args); ++ switch ( i ) ++ { ++ case 0: regs->ebx = arg; break; ++ case 1: regs->ecx = arg; break; ++ case 2: regs->edx = arg; break; ++ case 3: regs->esi = arg; break; ++ case 4: regs->edi = arg; break; ++ case 5: regs->ebp = arg; break; ++ } + } + } +-#elif defined(__x86_64__) +- regs->rax = op; +- regs->rip -= 2; /* re-execute 'syscall' */ ++ } + +- for ( i = 0; *p != '\0'; i++ ) ++ va_end(args); ++ ++ return op; ++} ++ ++#ifdef CONFIG_COMPAT ++int hypercall_xlat_continuation(unsigned int *id, unsigned int mask, ...) ++{ ++ int rc = 0; ++ struct mc_state *mcs = &this_cpu(mc_state); ++ struct cpu_user_regs *regs; ++ unsigned int i, cval = 0; ++ unsigned long nval = 0; ++ va_list args; ++ ++ BUG_ON(*id > 5); ++ BUG_ON(mask & (1U << *id)); ++ ++ va_start(args, mask); ++ ++ if ( test_bit(_MCSF_in_multicall, &mcs->flags) ) ++ { ++ if ( !test_bit(_MCSF_call_preempted, &mcs->flags) ) ++ return 0; ++ for ( i = 0; i < 6; ++i, mask >>= 1 ) ++ { ++ if ( mask & 1 ) ++ { ++ nval = va_arg(args, unsigned long); ++ cval = va_arg(args, unsigned int); ++ if ( cval == nval ) ++ mask &= ~1U; ++ else ++ BUG_ON(nval == (unsigned int)nval); ++ } ++ else if ( id && *id == i ) ++ { ++ *id = mcs->call.args[i]; ++ id = NULL; ++ } ++ if ( (mask & 1) && mcs->call.args[i] == nval ) ++ ++rc; ++ else ++ { ++ cval = mcs->call.args[i]; ++ BUG_ON(mcs->call.args[i] != cval); ++ } ++ mcs->compat_call.args[i] = cval; ++ } ++ } ++ else ++ { ++ regs = guest_cpu_user_regs(); ++ for ( i = 0; i < 6; ++i, mask >>= 1 ) + { +- arg = next_arg(p, args); ++ unsigned long *reg; ++ + switch ( i ) + { +- case 0: regs->rdi = arg; break; +- case 1: regs->rsi = arg; break; +- case 2: regs->rdx = arg; break; +- case 3: regs->r10 = arg; break; +- case 4: regs->r8 = arg; break; +- case 5: regs->r9 = arg; break; ++ case 0: reg = ®s->ebx; break; ++ case 1: reg = ®s->ecx; break; ++ case 2: reg = ®s->edx; break; ++ case 3: reg = ®s->esi; break; ++ case 4: reg = ®s->edi; break; ++ case 5: reg = ®s->ebp; break; ++ default: BUG(); reg = NULL; break; + } ++ if ( (mask & 1) ) ++ { ++ nval = va_arg(args, unsigned long); ++ cval = va_arg(args, unsigned int); ++ if ( cval == nval ) ++ mask &= ~1U; ++ else ++ BUG_ON(nval == (unsigned int)nval); ++ } ++ else if ( id && *id == i ) ++ { ++ *id = *reg; ++ id = NULL; ++ } ++ if ( (mask & 1) && *reg == nval ) ++ { ++ *reg = cval; ++ ++rc; ++ } ++ else ++ BUG_ON(*reg != (unsigned int)*reg); + } +-#endif + } + + va_end(args); + +- return op; ++ return rc; + } ++#endif + + static void relinquish_memory(struct domain *d, struct list_head *list) + { +Index: 2007-01-08/xen/arch/x86/domain_build.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/domain_build.c 2007-01-08 15:35:48.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/domain_build.c 2007-01-08 15:35:59.000000000 +0100 +@@ -688,7 +688,11 @@ int construct_dom0(struct domain *d, + l4e_from_paddr(__pa(d->arch.mm_perdomain_l3), __PAGE_HYPERVISOR); + v->arch.guest_table = pagetable_from_paddr(__pa(l4start)); + if ( IS_COMPAT(d) ) ++ { + v->arch.guest_table_user = v->arch.guest_table; ++ if ( setup_arg_xlat_area(v, l4start) < 0 ) ++ panic("Not enough RAM for domain 0 hypercall argument translation.\n"); ++ } + + l4tab += l4_table_offset(dsi.v_start); + mfn = alloc_spfn; +Index: 2007-01-08/xen/arch/x86/mm.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/mm.c 2006-12-18 09:49:18.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/mm.c 2007-01-08 14:53:55.000000000 +0100 +@@ -1115,9 +1115,12 @@ static int alloc_l4_table(struct page_in + pl4e[l4_table_offset(LINEAR_PT_VIRT_START)] = + l4e_from_pfn(pfn, __PAGE_HYPERVISOR); + pl4e[l4_table_offset(PERDOMAIN_VIRT_START)] = +- l4e_from_page( +- virt_to_page(page_get_owner(page)->arch.mm_perdomain_l3), +- __PAGE_HYPERVISOR); ++ l4e_from_page(virt_to_page(d->arch.mm_perdomain_l3), ++ __PAGE_HYPERVISOR); ++ if ( IS_COMPAT(d) ) ++ pl4e[l4_table_offset(COMPAT_ARG_XLAT_VIRT_BASE)] = ++ l4e_from_page(virt_to_page(d->arch.mm_arg_xlat_l3), ++ __PAGE_HYPERVISOR); + + return 1; + +@@ -2754,7 +2757,9 @@ int do_update_va_mapping(unsigned long v + flush_tlb_mask(d->domain_dirty_cpumask); + break; + default: +- if ( unlikely(get_user(vmask, (unsigned long *)bmap_ptr)) ) ++ if ( unlikely(!IS_COMPAT(d) ? ++ get_user(vmask, (unsigned long *)bmap_ptr) : ++ get_user(vmask, (unsigned int *)bmap_ptr)) ) + rc = -EFAULT; + pmask = vcpumask_to_pcpumask(d, vmask); + flush_tlb_mask(pmask); +Index: 2007-01-08/xen/arch/x86/x86_64/Makefile +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_64/Makefile 2006-12-18 09:43:08.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_64/Makefile 2007-01-08 14:53:55.000000000 +0100 +@@ -6,5 +6,6 @@ obj-y += traps.o + ifeq ($(CONFIG_COMPAT),y) + # extra dependencies + entry.o: compat/entry.S ++mm.o: compat/mm.c + traps.o: compat/traps.c + endif +Index: 2007-01-08/xen/arch/x86/x86_64/compat/entry.S +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:19:11.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 14:53:55.000000000 +0100 +@@ -282,15 +282,11 @@ CFIX14: + #define compat_mmu_update domain_crash_synchronous + #define compat_set_gdt domain_crash_synchronous + #define compat_platform_op domain_crash_synchronous +-#define compat_update_descriptor domain_crash_synchronous +-#define compat_memory_op domain_crash_synchronous + #define compat_multicall domain_crash_synchronous +-#define compat_update_va_mapping domain_crash_synchronous + #define compat_set_timer_op domain_crash_synchronous + #define compat_event_channel_op_compat domain_crash_synchronous + #define compat_physdev_op_compat domain_crash_synchronous + #define compat_grant_table_op domain_crash_synchronous +-#define compat_update_va_mapping_otherdomain domain_crash_synchronous + #define compat_vcpu_op domain_crash_synchronous + #define compat_mmuext_op domain_crash_synchronous + #define compat_acm_op domain_crash_synchronous +Index: 2007-01-08/xen/arch/x86/x86_64/compat/mm.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-08/xen/arch/x86/x86_64/compat/mm.c 2007-01-08 14:53:55.000000000 +0100 +@@ -0,0 +1,148 @@ ++#ifdef CONFIG_COMPAT ++ ++#include ++ ++int compat_update_descriptor(u32 pa_lo, u32 pa_hi, u32 desc_lo, u32 desc_hi) ++{ ++ return do_update_descriptor(pa_lo | ((u64)pa_hi << 32), ++ desc_lo | ((u64)desc_hi << 32)); ++} ++ ++int compat_arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg) ++{ ++ struct compat_machphys_mfn_list xmml; ++ l2_pgentry_t l2e; ++ unsigned long v; ++ compat_pfn_t mfn; ++ unsigned int i; ++ int rc = 0; ++ ++ switch ( op ) ++ { ++ case XENMEM_add_to_physmap: ++ { ++ struct compat_add_to_physmap cmp; ++ struct xen_add_to_physmap *nat = (void *)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id); ++ ++ if ( copy_from_guest(&cmp, arg, 1) ) ++ return -EFAULT; ++ ++ XLAT_add_to_physmap(nat, &cmp); ++ rc = arch_memory_op(op, guest_handle_from_ptr(nat, void)); ++ ++ break; ++ } ++ ++ case XENMEM_set_memory_map: ++ { ++ struct compat_foreign_memory_map cmp; ++ struct xen_foreign_memory_map *nat = (void *)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id); ++ ++ if ( copy_from_guest(&cmp, arg, 1) ) ++ return -EFAULT; ++ ++#define XLAT_memory_map_HNDL_buffer(_d_, _s_) \ ++ guest_from_compat_handle((_d_)->buffer, (_s_)->buffer) ++ XLAT_foreign_memory_map(nat, &cmp); ++#undef XLAT_memory_map_HNDL_buffer ++ ++ rc = arch_memory_op(op, guest_handle_from_ptr(nat, void)); ++ ++ break; ++ } ++ ++ case XENMEM_memory_map: ++ case XENMEM_machine_memory_map: ++ { ++ struct compat_memory_map cmp; ++ struct xen_memory_map *nat = (void *)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id); ++ ++ if ( copy_from_guest(&cmp, arg, 1) ) ++ return -EFAULT; ++ ++#define XLAT_memory_map_HNDL_buffer(_d_, _s_) \ ++ guest_from_compat_handle((_d_)->buffer, (_s_)->buffer) ++ XLAT_memory_map(nat, &cmp); ++#undef XLAT_memory_map_HNDL_buffer ++ ++ rc = arch_memory_op(op, guest_handle_from_ptr(nat, void)); ++ if ( rc < 0 ) ++ break; ++ ++#define XLAT_memory_map_HNDL_buffer(_d_, _s_) ((void)0) ++ XLAT_memory_map(&cmp, nat); ++#undef XLAT_memory_map_HNDL_buffer ++ if ( copy_to_guest(arg, &cmp, 1) ) ++ rc = -EFAULT; ++ ++ break; ++ } ++ ++ case XENMEM_machphys_mapping: ++ { ++ struct domain *d = current->domain; ++ struct compat_machphys_mapping mapping = { ++ .v_start = MACH2PHYS_COMPAT_VIRT_START(d), ++ .v_end = MACH2PHYS_COMPAT_VIRT_END, ++ .max_mfn = MACH2PHYS_COMPAT_NR_ENTRIES(d) - 1 ++ }; ++ ++ if ( copy_to_guest(arg, &mapping, 1) ) ++ rc = -EFAULT; ++ ++ break; ++ } ++ ++ case XENMEM_machphys_mfn_list: ++ if ( copy_from_guest(&xmml, arg, 1) ) ++ return -EFAULT; ++ ++ for ( i = 0, v = RDWR_COMPAT_MPT_VIRT_START; ++ (i != xmml.max_extents) && (v != RDWR_COMPAT_MPT_VIRT_END); ++ i++, v += 1 << L2_PAGETABLE_SHIFT ) ++ { ++ l2e = compat_idle_pg_table_l2[l2_table_offset(v)]; ++ if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) ) ++ break; ++ mfn = l2e_get_pfn(l2e) + l1_table_offset(v); ++ if ( copy_to_compat_offset(xmml.extent_start, i, &mfn, 1) ) ++ return -EFAULT; ++ } ++ ++ xmml.nr_extents = i; ++ if ( copy_to_guest(arg, &xmml, 1) ) ++ rc = -EFAULT; ++ ++ break; ++ ++ default: ++ rc = -ENOSYS; ++ break; ++ } ++ ++ return rc; ++} ++ ++int compat_update_va_mapping(unsigned int va, u32 lo, u32 hi, ++ unsigned int flags) ++{ ++ return do_update_va_mapping(va, lo | ((u64)hi << 32), flags); ++} ++ ++int compat_update_va_mapping_otherdomain(unsigned long va, u32 lo, u32 hi, ++ unsigned long flags, ++ domid_t domid) ++{ ++ return do_update_va_mapping_otherdomain(va, lo | ((u64)hi << 32), flags, domid); ++} ++#endif /* CONFIG_COMPAT */ ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * tab-width: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ +Index: 2007-01-08/xen/arch/x86/x86_64/mm.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_64/mm.c 2006-12-18 09:49:18.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_64/mm.c 2007-01-08 14:53:55.000000000 +0100 +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -407,6 +408,8 @@ int check_descriptor(const struct domain + return 0; + } + ++#include "compat/mm.c" ++ + /* + * Local variables: + * mode: C +Index: 2007-01-08/xen/common/compat/Makefile +=================================================================== +--- 2007-01-08.orig/xen/common/compat/Makefile 2007-01-08 15:18:32.000000000 +0100 ++++ 2007-01-08/xen/common/compat/Makefile 2007-01-08 14:53:55.000000000 +0100 +@@ -1,4 +1,5 @@ + obj-y += kernel.o ++obj-y += memory.o + obj-y += xlat.o + + # extra dependencies +Index: 2007-01-08/xen/common/compat/memory.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-08/xen/common/compat/memory.c 2007-01-08 14:53:55.000000000 +0100 +@@ -0,0 +1,364 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE(void) compat) ++{ ++ int rc, split, op = cmd & MEMOP_CMD_MASK; ++ unsigned int start_extent = cmd >> MEMOP_EXTENT_SHIFT; ++ ++ do ++ { ++ unsigned int i, end_extent = 0; ++ union { ++ XEN_GUEST_HANDLE(void) hnd; ++ struct xen_memory_reservation *rsrv; ++ struct xen_memory_exchange *xchg; ++ struct xen_translate_gpfn_list *xlat; ++ } nat; ++ union { ++ struct compat_memory_reservation rsrv; ++ struct compat_memory_exchange xchg; ++ struct compat_translate_gpfn_list xlat; ++ } cmp; ++ ++ set_xen_guest_handle(nat.hnd, (void *)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id)); ++ split = 0; ++ switch ( op ) ++ { ++ xen_pfn_t *space; ++ ++ case XENMEM_increase_reservation: ++ case XENMEM_decrease_reservation: ++ case XENMEM_populate_physmap: ++ if ( copy_from_guest(&cmp.rsrv, compat, 1) ) ++ return start_extent; ++ ++ /* Is size too large for us to encode a continuation? */ ++ if ( cmp.rsrv.nr_extents > (UINT_MAX >> MEMOP_EXTENT_SHIFT) ) ++ return start_extent; ++ ++ if ( !compat_handle_is_null(cmp.rsrv.extent_start) && ++ !compat_handle_okay(cmp.rsrv.extent_start, cmp.rsrv.nr_extents) ) ++ return start_extent; ++ ++ end_extent = start_extent + (COMPAT_ARG_XLAT_SIZE - sizeof(*nat.rsrv)) / ++ sizeof(*space); ++ if ( end_extent > cmp.rsrv.nr_extents ) ++ end_extent = cmp.rsrv.nr_extents; ++ ++ space = (xen_pfn_t *)(nat.rsrv + 1); ++#define XLAT_memory_reservation_HNDL_extent_start(_d_, _s_) \ ++ do \ ++ { \ ++ if ( !compat_handle_is_null((_s_)->extent_start) ) \ ++ { \ ++ set_xen_guest_handle((_d_)->extent_start, space - start_extent); \ ++ if ( op != XENMEM_increase_reservation ) \ ++ { \ ++ for ( i = start_extent; i < end_extent; ++i ) \ ++ { \ ++ compat_pfn_t pfn; \ ++ if ( __copy_from_compat_offset(&pfn, (_s_)->extent_start, i, 1) ) \ ++ { \ ++ end_extent = i; \ ++ split = -1; \ ++ break; \ ++ } \ ++ *space++ = pfn; \ ++ } \ ++ } \ ++ } \ ++ else \ ++ { \ ++ set_xen_guest_handle((_d_)->extent_start, NULL); \ ++ end_extent = cmp.rsrv.nr_extents; \ ++ } \ ++ } while (0) ++ XLAT_memory_reservation(nat.rsrv, &cmp.rsrv); ++#undef XLAT_memory_reservation_HNDL_extent_start ++ ++ if ( end_extent < cmp.rsrv.nr_extents ) ++ { ++ nat.rsrv->nr_extents = end_extent; ++ ++split; ++ } ++ ++ break; ++ ++ case XENMEM_exchange: ++ { ++ int order_delta; ++ ++ if ( copy_from_guest(&cmp.xchg, compat, 1) ) ++ return -EFAULT; ++ ++ order_delta = cmp.xchg.out.extent_order - cmp.xchg.in.extent_order; ++ /* Various sanity checks. */ ++ if ( (cmp.xchg.nr_exchanged > cmp.xchg.in.nr_extents) || ++ (order_delta > 0 && (cmp.xchg.nr_exchanged & ((1U << order_delta) - 1))) || ++ /* Sizes of input and output lists do not overflow an int? */ ++ ((~0U >> cmp.xchg.in.extent_order) < cmp.xchg.in.nr_extents) || ++ ((~0U >> cmp.xchg.out.extent_order) < cmp.xchg.out.nr_extents) || ++ /* Sizes of input and output lists match? */ ++ ((cmp.xchg.in.nr_extents << cmp.xchg.in.extent_order) != ++ (cmp.xchg.out.nr_extents << cmp.xchg.out.extent_order)) ) ++ return -EINVAL; ++ ++ start_extent = cmp.xchg.nr_exchanged; ++ end_extent = (COMPAT_ARG_XLAT_SIZE - sizeof(*nat.xchg)) / ++ (((1U << __builtin_abs(order_delta)) + 1) * ++ sizeof(*space)); ++ if ( end_extent == 0 ) ++ { ++ printk("Cannot translate compatibility mode XENMEM_exchange extents (%u,%u)\n", ++ cmp.xchg.in.extent_order, cmp.xchg.out.extent_order); ++ return -E2BIG; ++ } ++ if ( order_delta > 0 ) ++ end_extent <<= order_delta; ++ end_extent += start_extent; ++ if ( end_extent > cmp.xchg.in.nr_extents ) ++ end_extent = cmp.xchg.in.nr_extents; ++ ++ space = (xen_pfn_t *)(nat.xchg + 1); ++ /* Code below depends upon .in preceding .out. */ ++ BUILD_BUG_ON(offsetof(xen_memory_exchange_t, in) > offsetof(xen_memory_exchange_t, out)); ++#define XLAT_memory_reservation_HNDL_extent_start(_d_, _s_) \ ++ do \ ++ { \ ++ set_xen_guest_handle((_d_)->extent_start, space - start_extent); \ ++ for ( i = start_extent; i < end_extent; ++i ) \ ++ { \ ++ compat_pfn_t pfn; \ ++ if ( __copy_from_compat_offset(&pfn, (_s_)->extent_start, i, 1) ) \ ++ return -EFAULT; \ ++ *space++ = pfn; \ ++ } \ ++ if ( order_delta > 0 ) \ ++ { \ ++ start_extent >>= order_delta; \ ++ end_extent >>= order_delta; \ ++ } \ ++ else \ ++ { \ ++ start_extent <<= -order_delta; \ ++ end_extent <<= -order_delta; \ ++ } \ ++ order_delta = -order_delta; \ ++ } while (0) ++ XLAT_memory_exchange(nat.xchg, &cmp.xchg); ++#undef XLAT_memory_reservation_HNDL_extent_start ++ ++ if ( end_extent < cmp.xchg.in.nr_extents ) ++ { ++ nat.xchg->in.nr_extents = end_extent; ++ if ( order_delta >= 0 ) ++ nat.xchg->out.nr_extents = end_extent >> order_delta; ++ else ++ nat.xchg->out.nr_extents = end_extent << order_delta; ++ ++split; ++ } ++ ++ break; ++ } ++ ++ case XENMEM_current_reservation: ++ case XENMEM_maximum_reservation: ++ { ++#define xen_domid_t domid_t ++#define compat_domid_t domid_compat_t ++ CHECK_TYPE(domid); ++#undef compat_domid_t ++#undef xen_domid_t ++ } ++ case XENMEM_maximum_ram_page: ++ nat.hnd = compat; ++ break; ++ ++ case XENMEM_translate_gpfn_list: ++ if ( copy_from_guest(&cmp.xlat, compat, 1) ) ++ return -EFAULT; ++ ++ /* Is size too large for us to encode a continuation? */ ++ if ( cmp.xlat.nr_gpfns > (UINT_MAX >> MEMOP_EXTENT_SHIFT) ) ++ return -EINVAL; ++ ++ if ( !compat_handle_okay(cmp.xlat.gpfn_list, cmp.xlat.nr_gpfns) || ++ !compat_handle_okay(cmp.xlat.mfn_list, cmp.xlat.nr_gpfns) ) ++ return -EFAULT; ++ ++ end_extent = start_extent + (COMPAT_ARG_XLAT_SIZE - sizeof(*nat.xlat)) / ++ sizeof(*space); ++ if ( end_extent > cmp.xlat.nr_gpfns ) ++ end_extent = cmp.xlat.nr_gpfns; ++ ++ space = (xen_pfn_t *)(nat.xlat + 1); ++ /* Code below depends upon .gpfn_list preceding .mfn_list. */ ++ BUILD_BUG_ON(offsetof(xen_translate_gpfn_list_t, gpfn_list) > offsetof(xen_translate_gpfn_list_t, mfn_list)); ++#define XLAT_translate_gpfn_list_HNDL_gpfn_list(_d_, _s_) \ ++ do \ ++ { \ ++ set_xen_guest_handle((_d_)->gpfn_list, space - start_extent); \ ++ for ( i = start_extent; i < end_extent; ++i ) \ ++ { \ ++ compat_pfn_t pfn; \ ++ if ( __copy_from_compat_offset(&pfn, (_s_)->gpfn_list, i, 1) ) \ ++ return -EFAULT; \ ++ *space++ = pfn; \ ++ } \ ++ } while (0) ++#define XLAT_translate_gpfn_list_HNDL_mfn_list(_d_, _s_) \ ++ (_d_)->mfn_list = (_d_)->gpfn_list ++ XLAT_translate_gpfn_list(nat.xlat, &cmp.xlat); ++#undef XLAT_translate_gpfn_list_HNDL_mfn_list ++#undef XLAT_translate_gpfn_list_HNDL_gpfn_list ++ ++ if ( end_extent < cmp.xlat.nr_gpfns ) ++ { ++ nat.xlat->nr_gpfns = end_extent; ++ ++split; ++ } ++ ++ break; ++ ++ default: ++ return compat_arch_memory_op(cmd, compat); ++ } ++ ++ rc = do_memory_op(cmd, nat.hnd); ++ if ( rc < 0 ) ++ return rc; ++ ++ cmd = 0; ++ if ( hypercall_xlat_continuation(&cmd, 0x02, nat.hnd, compat) ) ++ { ++ BUG_ON(rc != __HYPERVISOR_memory_op); ++ BUG_ON((cmd & MEMOP_CMD_MASK) != op); ++ split = -1; ++ } ++ ++ switch ( op ) ++ { ++ case XENMEM_increase_reservation: ++ case XENMEM_decrease_reservation: ++ case XENMEM_populate_physmap: ++ end_extent = split >= 0 ? rc : cmd >> MEMOP_EXTENT_SHIFT; ++ if ( op != XENMEM_decrease_reservation && ++ !guest_handle_is_null(nat.rsrv->extent_start) ) ++ { ++ for ( ; start_extent < end_extent; ++start_extent ) ++ { ++ compat_pfn_t pfn = nat.rsrv->extent_start.p[start_extent]; ++ ++ BUG_ON(pfn != nat.rsrv->extent_start.p[start_extent]); ++ if ( __copy_to_compat_offset(cmp.rsrv.extent_start, start_extent, &pfn, 1) ) ++ { ++ if ( split >= 0 ) ++ { ++ rc = start_extent; ++ split = 0; ++ } ++ else ++ /* ++ * Short of being able to cancel the continuation, ++ * force it to restart here; eventually we shall ++ * get out of this state. ++ */ ++ rc = (start_extent << MEMOP_EXTENT_SHIFT) | op; ++ break; ++ } ++ } ++ } ++ else ++ start_extent = end_extent; ++ break; ++ ++ case XENMEM_exchange: ++ { ++ DEFINE_XEN_GUEST_HANDLE(compat_memory_exchange_t); ++ int order_delta; ++ ++ BUG_ON(split >= 0 && rc); ++ BUG_ON(end_extent < nat.xchg->nr_exchanged); ++ end_extent = nat.xchg->nr_exchanged; ++ ++ order_delta = cmp.xchg.out.extent_order - cmp.xchg.in.extent_order; ++ if ( order_delta > 0 ) ++ { ++ start_extent >>= order_delta; ++ BUG_ON(end_extent & ((1U << order_delta) - 1)); ++ end_extent >>= order_delta; ++ } ++ else ++ { ++ start_extent <<= -order_delta; ++ end_extent <<= -order_delta; ++ } ++ ++ for ( ; start_extent < end_extent; ++start_extent ) ++ { ++ compat_pfn_t pfn = nat.xchg->out.extent_start.p[start_extent]; ++ ++ BUG_ON(pfn != nat.xchg->out.extent_start.p[start_extent]); ++ /* Note that we ignore errors accessing the output extent list. */ ++ __copy_to_compat_offset(cmp.xchg.out.extent_start, start_extent, &pfn, 1); ++ } ++ ++ cmp.xchg.nr_exchanged = nat.xchg->nr_exchanged; ++ if ( copy_field_to_guest(guest_handle_cast(compat, compat_memory_exchange_t), ++ &cmp.xchg, nr_exchanged) ) ++ { ++ if ( split < 0 ) ++ /* Cannot cancel the continuation... */ ++ domain_crash(current->domain); ++ return -EFAULT; ++ } ++ break; ++ } ++ ++ case XENMEM_maximum_ram_page: ++ case XENMEM_current_reservation: ++ case XENMEM_maximum_reservation: ++ break; ++ ++ case XENMEM_translate_gpfn_list: ++ if ( split < 0 ) ++ end_extent = cmd >> MEMOP_EXTENT_SHIFT; ++ else ++ BUG_ON(rc); ++ ++ for ( ; start_extent < end_extent; ++start_extent ) ++ { ++ compat_pfn_t pfn = nat.xlat->mfn_list.p[start_extent]; ++ ++ BUG_ON(pfn != nat.xlat->mfn_list.p[start_extent]); ++ if ( __copy_to_compat_offset(cmp.xlat.mfn_list, start_extent, &pfn, 1) ) ++ { ++ if ( split < 0 ) ++ /* Cannot cancel the continuation... */ ++ domain_crash(current->domain); ++ return -EFAULT; ++ } ++ } ++ break; ++ ++ default: ++ domain_crash(current->domain); ++ split = 0; ++ break; ++ } ++ ++ cmd = op | (start_extent << MEMOP_EXTENT_SHIFT); ++ if ( split > 0 && hypercall_preempt_check() ) ++ return hypercall_create_continuation( ++ __HYPERVISOR_memory_op, "ih", cmd, compat); ++ } while ( split > 0 ); ++ ++ return rc; ++} +Index: 2007-01-08/xen/common/memory.c +=================================================================== +--- 2007-01-08.orig/xen/common/memory.c 2007-01-08 15:34:15.000000000 +0100 ++++ 2007-01-08/xen/common/memory.c 2007-01-08 14:53:55.000000000 +0100 +@@ -17,18 +17,12 @@ + #include + #include + #include ++#include + #include + #include + #include + #include + +-/* +- * To allow safe resume of do_memory_op() after preemption, we need to know +- * at what point in the page list to resume. For this purpose I steal the +- * high-order bits of the @cmd parameter, which are otherwise unused and zero. +- */ +-#define START_EXTENT_SHIFT 4 /* cmd[:4] == start_extent */ +- + struct memop_args { + /* INPUT */ + struct domain *domain; /* Domain to be affected. */ +@@ -236,7 +230,7 @@ static long translate_gpfn_list( + return -EFAULT; + + /* Is size too large for us to encode a continuation? */ +- if ( op.nr_gpfns > (ULONG_MAX >> START_EXTENT_SHIFT) ) ++ if ( op.nr_gpfns > (ULONG_MAX >> MEMOP_EXTENT_SHIFT) ) + return -EINVAL; + + if ( !guest_handle_okay(op.gpfn_list, op.nr_gpfns) || +@@ -511,20 +505,20 @@ long do_memory_op(unsigned long cmd, XEN + struct memop_args args; + domid_t domid; + +- op = cmd & ((1 << START_EXTENT_SHIFT) - 1); ++ op = cmd & MEMOP_CMD_MASK; + + switch ( op ) + { + case XENMEM_increase_reservation: + case XENMEM_decrease_reservation: + case XENMEM_populate_physmap: +- start_extent = cmd >> START_EXTENT_SHIFT; ++ start_extent = cmd >> MEMOP_EXTENT_SHIFT; + + if ( copy_from_guest(&reservation, arg, 1) ) + return start_extent; + + /* Is size too large for us to encode a continuation? */ +- if ( reservation.nr_extents > (ULONG_MAX >> START_EXTENT_SHIFT) ) ++ if ( reservation.nr_extents > (ULONG_MAX >> MEMOP_EXTENT_SHIFT) ) + return start_extent; + + if ( unlikely(start_extent > reservation.nr_extents) ) +@@ -574,7 +568,7 @@ long do_memory_op(unsigned long cmd, XEN + if ( args.preempted ) + return hypercall_create_continuation( + __HYPERVISOR_memory_op, "lh", +- op | (rc << START_EXTENT_SHIFT), arg); ++ op | (rc << MEMOP_EXTENT_SHIFT), arg); + + break; + +@@ -606,14 +600,14 @@ long do_memory_op(unsigned long cmd, XEN + break; + + case XENMEM_translate_gpfn_list: +- progress = cmd >> START_EXTENT_SHIFT; ++ progress = cmd >> MEMOP_EXTENT_SHIFT; + rc = translate_gpfn_list( + guest_handle_cast(arg, xen_translate_gpfn_list_t), + &progress); + if ( rc == -EAGAIN ) + return hypercall_create_continuation( + __HYPERVISOR_memory_op, "lh", +- op | (progress << START_EXTENT_SHIFT), arg); ++ op | (progress << MEMOP_EXTENT_SHIFT), arg); + break; + + default: +Index: 2007-01-08/xen/include/asm-x86/config.h +=================================================================== +--- 2007-01-08.orig/xen/include/asm-x86/config.h 2007-01-08 14:53:50.000000000 +0100 ++++ 2007-01-08/xen/include/asm-x86/config.h 2007-01-08 14:53:55.000000000 +0100 +@@ -112,7 +112,7 @@ extern unsigned long _end; /* standard E + /* + * Memory layout: + * 0x0000000000000000 - 0x00007fffffffffff [128TB, 2^47 bytes, PML4:0-255] +- * Guest-defined use. ++ * Guest-defined use (see below for compatibility mode guests). + * 0x0000800000000000 - 0xffff7fffffffffff [16EB] + * Inaccessible: current arch only supports 48-bit sign-extended VAs. + * 0xffff800000000000 - 0xffff803fffffffff [256GB, 2^38 bytes, PML4:256] +@@ -145,6 +145,18 @@ extern unsigned long _end; /* standard E + * Reserved for future use. + * 0xffff880000000000 - 0xffffffffffffffff [120TB, PML4:272-511] + * Guest-defined use. ++ * ++ * Compatibility guest area layout: ++ * 0x0000000000000000 - 0x00000000f57fffff [3928MB, PML4:0] ++ * Guest-defined use. ++ * 0x0000000f58000000 - 0x00000000ffffffff [168MB, PML4:0] ++ * Read-only machine-to-phys translation table (GUEST ACCESSIBLE). ++ * 0x0000000000000000 - 0x00000000ffffffff [508GB, PML4:0] ++ * Unused. ++ * 0x0000008000000000 - 0x000000ffffffffff [512GB, 2^39 bytes, PML4:1] ++ * Hypercall argument translation area. ++ * 0x0000010000000000 - 0x00007fffffffffff [127TB, 2^46 bytes, PML4:2-255] ++ * Reserved for future use. + */ + + +@@ -214,6 +226,14 @@ extern unsigned long _end; /* standard E + + #endif + ++#define COMPAT_ARG_XLAT_VIRT_BASE (1UL << ROOT_PAGETABLE_SHIFT) ++#define COMPAT_ARG_XLAT_SHIFT 0 ++#define COMPAT_ARG_XLAT_PAGES (1U << COMPAT_ARG_XLAT_SHIFT) ++#define COMPAT_ARG_XLAT_SIZE (COMPAT_ARG_XLAT_PAGES << PAGE_SHIFT) ++#define COMPAT_ARG_XLAT_VIRT_START(vcpu_id) \ ++ (COMPAT_ARG_XLAT_VIRT_BASE + ((unsigned long)(vcpu_id) << \ ++ (PAGE_SHIFT + COMPAT_ARG_XLAT_SHIFT + 1))) ++ + #define PGT_base_page_table PGT_l4_page_table + + #define __HYPERVISOR_CS64 0xe008 +Index: 2007-01-08/xen/include/asm-x86/domain.h +=================================================================== +--- 2007-01-08.orig/xen/include/asm-x86/domain.h 2007-01-08 14:53:50.000000000 +0100 ++++ 2007-01-08/xen/include/asm-x86/domain.h 2007-01-08 14:53:55.000000000 +0100 +@@ -100,6 +100,7 @@ struct arch_domain + + #ifdef CONFIG_COMPAT + unsigned int hv_compat_vstart; ++ l3_pgentry_t *mm_arg_xlat_l3; + #endif + + /* I/O-port admin-specified access capabilities. */ +Index: 2007-01-08/xen/include/asm-x86/mm.h +=================================================================== +--- 2007-01-08.orig/xen/include/asm-x86/mm.h 2006-12-18 09:49:18.000000000 +0100 ++++ 2007-01-08/xen/include/asm-x86/mm.h 2007-01-08 14:53:55.000000000 +0100 +@@ -329,10 +329,20 @@ int __sync_lazy_execstate(void); + /* Arch-specific portion of memory_op hypercall. */ + long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg); + long subarch_memory_op(int op, XEN_GUEST_HANDLE(void) arg); ++#ifdef CONFIG_COMPAT ++int compat_arch_memory_op(int op, XEN_GUEST_HANDLE(void)); ++int compat_subarch_memory_op(int op, XEN_GUEST_HANDLE(void)); ++#endif + + int steal_page( + struct domain *d, struct page_info *page, unsigned int memflags); + + int map_ldt_shadow_page(unsigned int); + ++#ifdef CONFIG_COMPAT ++int setup_arg_xlat_area(struct vcpu *, l4_pgentry_t *); ++#else ++# define setup_arg_xlat_area(vcpu, l4tab) 0 ++#endif ++ + #endif /* __ASM_X86_MM_H__ */ +Index: 2007-01-08/xen/include/xen/hypercall.h +=================================================================== +--- 2007-01-08.orig/xen/include/xen/hypercall.h 2007-01-08 15:34:15.000000000 +0100 ++++ 2007-01-08/xen/include/xen/hypercall.h 2007-01-08 14:53:55.000000000 +0100 +@@ -42,9 +42,17 @@ extern long + do_platform_op( + XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op); + ++/* ++ * To allow safe resume of do_memory_op() after preemption, we need to know ++ * at what point in the page list to resume. For this purpose I steal the ++ * high-order bits of the @cmd parameter, which are otherwise unused and zero. ++ */ ++#define MEMOP_EXTENT_SHIFT 4 /* cmd[:4] == start_extent */ ++#define MEMOP_CMD_MASK ((1 << MEMOP_EXTENT_SHIFT) - 1) ++ + extern long + do_memory_op( +- int cmd, ++ unsigned long cmd, + XEN_GUEST_HANDLE(void) arg); + + extern long +@@ -108,4 +116,13 @@ do_kexec_op( + int arg1, + XEN_GUEST_HANDLE(void) arg); + ++#ifdef CONFIG_COMPAT ++ ++extern int ++compat_memory_op( ++ unsigned int cmd, ++ XEN_GUEST_HANDLE(void) arg); ++ ++#endif ++ + #endif /* __XEN_HYPERCALL_H__ */ +Index: 2007-01-08/xen/include/xen/compat.h +=================================================================== +--- 2007-01-08.orig/xen/include/xen/compat.h 2007-01-08 15:19:11.000000000 +0100 ++++ 2007-01-08/xen/include/xen/compat.h 2007-01-08 14:53:55.000000000 +0100 +@@ -158,6 +158,8 @@ + + extern int compat_disabled; + ++int hypercall_xlat_continuation(unsigned int *id, unsigned int mask, ...); ++ + /* In-place translation functons: */ + struct start_info; + void xlat_start_info(struct start_info *, enum XLAT_start_info_console); +Index: 2007-01-08/xen/include/xlat.lst +=================================================================== +--- 2007-01-08.orig/xen/include/xlat.lst 2007-01-08 15:19:11.000000000 +0100 ++++ 2007-01-08/xen/include/xlat.lst 2007-01-08 14:53:55.000000000 +0100 +@@ -4,3 +4,9 @@ + ? dom0_vga_console_info xen.h + ! start_info xen.h + ? vcpu_time_info xen.h ++! add_to_physmap memory.h ++! foreign_memory_map memory.h ++! memory_exchange memory.h ++! memory_map memory.h ++! memory_reservation memory.h ++! translate_gpfn_list memory.h diff --git a/32on64-mmuop.patch b/32on64-mmuop.patch new file mode 100644 index 0000000..81d42a7 --- /dev/null +++ b/32on64-mmuop.patch @@ -0,0 +1,292 @@ +Enable compatibility mode operation for HYPERVISOR_mmu_update and +HYPERVISOR_mmuext_op. + +Index: 2006-12-18/xen/arch/x86/mm.c +=================================================================== +--- 2006-12-18.orig/xen/arch/x86/mm.c 2006-12-18 09:49:30.000000000 +0100 ++++ 2006-12-18/xen/arch/x86/mm.c 2006-12-18 09:49:35.000000000 +0100 +@@ -106,6 +106,7 @@ + #include + #include + #include ++#include + #include + + #define MEM_LOG(_f, _a...) gdprintk(XENLOG_WARNING , _f "\n" , ## _a) +@@ -119,13 +120,6 @@ + #define PTE_UPDATE_WITH_CMPXCHG + #endif + +-/* +- * Both do_mmuext_op() and do_mmu_update(): +- * We steal the m.s.b. of the @count parameter to indicate whether this +- * invocation of do_mmu_update() is resuming a previously preempted call. +- */ +-#define MMU_UPDATE_PREEMPTED (~(~0U>>1)) +- + /* Used to defer flushing of memory structures. */ + struct percpu_mm_info { + #define DOP_FLUSH_TLB (1<<0) /* Flush the local TLB. */ +@@ -2027,6 +2021,8 @@ int do_mmuext_op( + goto pin_page; + + case MMUEXT_PIN_L4_TABLE: ++ if ( IS_COMPAT(FOREIGNDOM) ) ++ break; + type = PGT_l4_page_table; + + pin_page: +@@ -2090,7 +2086,11 @@ int do_mmuext_op( + + #ifdef __x86_64__ + case MMUEXT_NEW_USER_BASEPTR: +- okay = 1; ++ if ( IS_COMPAT(FOREIGNDOM) ) ++ { ++ okay = 0; ++ break; ++ } + if (likely(mfn != 0)) + { + if ( shadow_mode_refcounts(d) ) +Index: 2006-12-18/xen/arch/x86/x86_64/compat/entry.S +=================================================================== +--- 2006-12-18.orig/xen/arch/x86/x86_64/compat/entry.S 2006-12-18 09:49:30.000000000 +0100 ++++ 2006-12-18/xen/arch/x86/x86_64/compat/entry.S 2006-12-18 09:49:35.000000000 +0100 +@@ -279,7 +279,6 @@ CFIX14: + .section .rodata, "a", @progbits + + #define compat_set_trap_table domain_crash_synchronous +-#define compat_mmu_update domain_crash_synchronous + #define compat_set_gdt domain_crash_synchronous + #define compat_platform_op domain_crash_synchronous + #define compat_multicall domain_crash_synchronous +@@ -288,7 +287,6 @@ CFIX14: + #define compat_physdev_op_compat domain_crash_synchronous + #define compat_grant_table_op domain_crash_synchronous + #define compat_vcpu_op domain_crash_synchronous +-#define compat_mmuext_op domain_crash_synchronous + #define compat_acm_op domain_crash_synchronous + #define compat_arch_sched_op domain_crash_synchronous + #define compat_xenoprof_op domain_crash_synchronous +@@ -299,7 +297,7 @@ CFIX14: + + ENTRY(compat_hypercall_table) + .quad compat_set_trap_table /* 0 */ +- .quad compat_mmu_update ++ .quad do_mmu_update + .quad compat_set_gdt + .quad do_stack_switch + .quad compat_set_callbacks +Index: 2006-12-18/xen/arch/x86/x86_64/compat/mm.c +=================================================================== +--- 2006-12-18.orig/xen/arch/x86/x86_64/compat/mm.c 2006-12-18 09:49:30.000000000 +0100 ++++ 2006-12-18/xen/arch/x86/x86_64/compat/mm.c 2006-12-18 09:49:35.000000000 +0100 +@@ -1,6 +1,8 @@ + #ifdef CONFIG_COMPAT + ++#include + #include ++#include + + int compat_update_descriptor(u32 pa_lo, u32 pa_hi, u32 desc_lo, u32 desc_hi) + { +@@ -135,6 +137,152 @@ int compat_update_va_mapping_otherdomain + { + return do_update_va_mapping_otherdomain(va, lo | ((u64)hi << 32), flags, domid); + } ++ ++DEFINE_XEN_GUEST_HANDLE(mmuext_op_compat_t); ++ ++int compat_mmuext_op(XEN_GUEST_HANDLE(mmuext_op_compat_t) cmp_uops, ++ unsigned int count, ++ XEN_GUEST_HANDLE(uint) pdone, ++ unsigned int foreigndom) ++{ ++ unsigned int i, preempt_mask; ++ int rc = 0; ++ XEN_GUEST_HANDLE(mmuext_op_t) nat_ops; ++ ++ preempt_mask = count & MMU_UPDATE_PREEMPTED; ++ count ^= preempt_mask; ++ ++ if ( unlikely(!guest_handle_okay(cmp_uops, count)) ) ++ return -EFAULT; ++ ++ set_xen_guest_handle(nat_ops, (void *)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id)); ++ ++ for ( ; count; count -= i ) ++ { ++ mmuext_op_t *nat_op = nat_ops.p; ++ unsigned int limit; ++ int err; ++ ++ if ( hypercall_preempt_check() ) ++ { ++ rc = hypercall_create_continuation( ++ __HYPERVISOR_mmuext_op, "hihi", ++ cmp_uops, count | MMU_UPDATE_PREEMPTED, pdone, foreigndom); ++ break; ++ } ++ ++ limit = COMPAT_ARG_XLAT_SIZE / sizeof(*nat_op); ++ ++ for ( i = 0; i < min(limit, count); ++i ) ++ { ++ mmuext_op_compat_t cmp_op; ++ enum XLAT_mmuext_op_arg1 arg1; ++ enum XLAT_mmuext_op_arg2 arg2; ++ ++ if ( unlikely(__copy_from_guest(&cmp_op, cmp_uops, 1) != 0) ) ++ { ++ rc = -EFAULT; ++ break; ++ } ++ ++ switch ( cmp_op.cmd ) ++ { ++ case MMUEXT_PIN_L1_TABLE: ++ case MMUEXT_PIN_L2_TABLE: ++ case MMUEXT_PIN_L3_TABLE: ++ case MMUEXT_PIN_L4_TABLE: ++ case MMUEXT_UNPIN_TABLE: ++ case MMUEXT_NEW_BASEPTR: ++ arg1 = XLAT_mmuext_op_arg1_mfn; ++ break; ++ default: ++ arg1 = XLAT_mmuext_op_arg1_linear_addr; ++ break; ++ case MMUEXT_NEW_USER_BASEPTR: ++ rc = -EINVAL; ++ case MMUEXT_TLB_FLUSH_LOCAL: ++ case MMUEXT_TLB_FLUSH_MULTI: ++ case MMUEXT_TLB_FLUSH_ALL: ++ case MMUEXT_FLUSH_CACHE: ++ arg1 = -1; ++ break; ++ } ++ ++ if ( rc ) ++ break; ++ ++ switch ( cmp_op.cmd ) ++ { ++ case MMUEXT_SET_LDT: ++ arg2 = XLAT_mmuext_op_arg2_nr_ents; ++ break; ++ case MMUEXT_TLB_FLUSH_MULTI: ++ case MMUEXT_INVLPG_MULTI: ++ arg2 = XLAT_mmuext_op_arg2_vcpumask; ++ break; ++ default: ++ arg2 = -1; ++ break; ++ } ++ ++#define XLAT_mmuext_op_HNDL_arg2_vcpumask(_d_, _s_) \ ++ do \ ++ { \ ++ unsigned int vcpumask; \ ++ if ( i < --limit ) \ ++ { \ ++ (_d_)->arg2.vcpumask.p = (void *)(nat_ops.p + limit); \ ++ if ( copy_from_compat(&vcpumask, (_s_)->arg2.vcpumask, 1) == 0 ) \ ++ *(unsigned long *)(_d_)->arg2.vcpumask.p = vcpumask; \ ++ else \ ++ rc = -EFAULT; \ ++ } \ ++ } while(0) ++ XLAT_mmuext_op(nat_op, &cmp_op); ++#undef XLAT_mmuext_op_HNDL_arg2_vcpumask ++ ++ if ( rc || i >= limit ) ++ break; ++ ++ guest_handle_add_offset(cmp_uops, 1); ++ ++nat_op; ++ } ++ ++ err = do_mmuext_op(nat_ops, i | preempt_mask, pdone, foreigndom); ++ ++ if ( err ) ++ { ++ BUILD_BUG_ON(__HYPERVISOR_mmuext_op <= 0); ++ if ( err == __HYPERVISOR_mmuext_op ) ++ { ++ struct cpu_user_regs *regs = guest_cpu_user_regs(); ++ unsigned int left = regs->ecx & ~MMU_UPDATE_PREEMPTED; ++ ++ BUG_ON(!(regs->ecx & MMU_UPDATE_PREEMPTED)); ++ BUG_ON(left > count); ++ guest_handle_add_offset(nat_ops, count - left); ++ BUG_ON(left + i < count); ++ guest_handle_add_offset(cmp_uops, (signed int)(count - left - i)); ++ left = 1; ++ BUG_ON(!hypercall_xlat_continuation(&left, 0x01, nat_ops, cmp_uops)); ++ BUG_ON(left != regs->ecx); ++ regs->ecx += count - i; ++ } ++ else ++ BUG_ON(rc > 0); ++ rc = err; ++ } ++ ++ if ( rc ) ++ break; ++ ++ /* Force do_mmuext_op() to not start counting from zero again. */ ++ preempt_mask = MMU_UPDATE_PREEMPTED; ++ } ++ ++ return rc; ++} ++ + #endif /* CONFIG_COMPAT */ + + /* +Index: 2006-12-18/xen/common/compat/xlat.c +=================================================================== +--- 2006-12-18.orig/xen/common/compat/xlat.c 2006-12-18 09:46:14.000000000 +0100 ++++ 2006-12-18/xen/common/compat/xlat.c 2006-12-18 09:49:35.000000000 +0100 +@@ -21,6 +21,10 @@ void xlat_start_info(struct start_info * + CHECK_dom0_vga_console_info; + #undef dom0_vga_console_info + ++#define xen_mmu_update mmu_update ++CHECK_mmu_update; ++#undef xen_mmu_update ++ + #define xen_vcpu_time_info vcpu_time_info + CHECK_vcpu_time_info; + #undef xen_vcpu_time_info +Index: 2006-12-18/xen/include/asm-x86/hypercall.h +=================================================================== +--- 2006-12-18.orig/xen/include/asm-x86/hypercall.h 2006-12-13 11:15:56.000000000 +0100 ++++ 2006-12-18/xen/include/asm-x86/hypercall.h 2006-12-18 09:49:35.000000000 +0100 +@@ -8,6 +8,13 @@ + #include + #include + ++/* ++ * Both do_mmuext_op() and do_mmu_update(): ++ * We steal the m.s.b. of the @count parameter to indicate whether this ++ * invocation of do_mmu_update() is resuming a previously preempted call. ++ */ ++#define MMU_UPDATE_PREEMPTED (~(~0U>>1)) ++ + extern long + do_event_channel_op_compat( + XEN_GUEST_HANDLE(evtchn_op_t) uop); +Index: 2006-12-18/xen/include/xlat.lst +=================================================================== +--- 2006-12-18.orig/xen/include/xlat.lst 2006-12-18 09:49:30.000000000 +0100 ++++ 2006-12-18/xen/include/xlat.lst 2006-12-18 09:49:35.000000000 +0100 +@@ -2,6 +2,8 @@ + # ! - needs translation + # ? - needs checking + ? dom0_vga_console_info xen.h ++? mmu_update xen.h ++! mmuext_op xen.h + ! start_info xen.h + ? vcpu_time_info xen.h + ! add_to_physmap memory.h diff --git a/32on64-multicall.patch b/32on64-multicall.patch new file mode 100644 index 0000000..a4204ae --- /dev/null +++ b/32on64-multicall.patch @@ -0,0 +1,168 @@ +Enable compatibility mode operation for HYPERVISOR_multicall. + +Index: 2006-12-11/xen/arch/x86/x86_64/asm-offsets.c +=================================================================== +--- 2006-12-11.orig/xen/arch/x86/x86_64/asm-offsets.c 2006-12-15 15:28:41.000000000 +0100 ++++ 2006-12-11/xen/arch/x86/x86_64/asm-offsets.c 2006-12-15 15:33:03.000000000 +0100 +@@ -135,5 +135,17 @@ void __dummy__(void) + OFFSET(MULTICALL_result, struct multicall_entry, result); + BLANK(); + ++#ifdef CONFIG_COMPAT ++ OFFSET(COMPAT_MULTICALL_op, struct compat_multicall_entry, op); ++ OFFSET(COMPAT_MULTICALL_arg0, struct compat_multicall_entry, args[0]); ++ OFFSET(COMPAT_MULTICALL_arg1, struct compat_multicall_entry, args[1]); ++ OFFSET(COMPAT_MULTICALL_arg2, struct compat_multicall_entry, args[2]); ++ OFFSET(COMPAT_MULTICALL_arg3, struct compat_multicall_entry, args[3]); ++ OFFSET(COMPAT_MULTICALL_arg4, struct compat_multicall_entry, args[4]); ++ OFFSET(COMPAT_MULTICALL_arg5, struct compat_multicall_entry, args[5]); ++ OFFSET(COMPAT_MULTICALL_result, struct compat_multicall_entry, result); ++ BLANK(); ++#endif ++ + DEFINE(IRQSTAT_shift, LOG_2(sizeof(irq_cpustat_t))); + } +Index: 2006-12-11/xen/arch/x86/x86_64/compat/entry.S +=================================================================== +--- 2006-12-11.orig/xen/arch/x86/x86_64/compat/entry.S 2006-12-15 15:32:58.000000000 +0100 ++++ 2006-12-11/xen/arch/x86/x86_64/compat/entry.S 2006-12-15 15:33:03.000000000 +0100 +@@ -279,7 +279,6 @@ CFIX14: + .section .rodata, "a", @progbits + + #define compat_platform_op domain_crash_synchronous +-#define compat_multicall domain_crash_synchronous + #define compat_set_timer_op domain_crash_synchronous + #define compat_grant_table_op domain_crash_synchronous + #define compat_acm_op domain_crash_synchronous +Index: 2006-12-11/xen/common/compat/Makefile +=================================================================== +--- 2006-12-11.orig/xen/common/compat/Makefile 2006-12-15 15:32:56.000000000 +0100 ++++ 2006-12-11/xen/common/compat/Makefile 2006-12-15 15:33:03.000000000 +0100 +@@ -1,7 +1,9 @@ + obj-y += domain.o + obj-y += kernel.o + obj-y += memory.o ++obj-y += multicall.o + obj-y += xlat.o + + # extra dependencies + kernel.o: ../kernel.c ++multicall.o: ../multicall.c +Index: 2006-12-11/xen/common/compat/multicall.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2006-12-11/xen/common/compat/multicall.c 2006-12-15 15:33:03.000000000 +0100 +@@ -0,0 +1,31 @@ ++/****************************************************************************** ++ * multicall.c ++ */ ++ ++#include ++#include ++#include ++ ++#define COMPAT ++typedef int ret_t; ++#undef do_multicall_call ++ ++DEFINE_XEN_GUEST_HANDLE(multicall_entry_compat_t); ++#define multicall_entry compat_multicall_entry ++#define multicall_entry_t multicall_entry_compat_t ++#define do_multicall_call compat_multicall_call ++#define call compat_call ++#define do_multicall(l, n) compat_multicall(_##l, n) ++#define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t) ++ ++#include "../multicall.c" ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * tab-width: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ +Index: 2006-12-11/xen/common/multicall.c +=================================================================== +--- 2006-12-11.orig/xen/common/multicall.c 2006-12-15 15:20:37.000000000 +0100 ++++ 2006-12-11/xen/common/multicall.c 2006-12-15 15:33:03.000000000 +0100 +@@ -13,9 +13,12 @@ + #include + #include + ++#ifndef COMPAT + DEFINE_PER_CPU(struct mc_state, mc_state); ++typedef long ret_t; ++#endif + +-long ++ret_t + do_multicall( + XEN_GUEST_HANDLE(multicall_entry_t) call_list, unsigned int nr_calls) + { +Index: 2006-12-11/xen/include/asm-x86/multicall.h +=================================================================== +--- 2006-12-11.orig/xen/include/asm-x86/multicall.h 2006-12-15 15:20:34.000000000 +0100 ++++ 2006-12-11/xen/include/asm-x86/multicall.h 2006-12-15 15:33:03.000000000 +0100 +@@ -35,6 +35,31 @@ + "r8", "r9", "r10", "r11" ); \ + } while ( 0 ) + ++#define compat_multicall_call(_call) \ ++ do { \ ++ __asm__ __volatile__ ( \ ++ " movl "STR(COMPAT_MULTICALL_op)"(%0),%%eax; " \ ++ " leaq compat_hypercall_table(%%rip),%%rdi; " \ ++ " cmpl $("STR(NR_hypercalls)"),%%eax; " \ ++ " jae 2f; " \ ++ " movq (%%rdi,%%rax,8),%%rax; " \ ++ " movl "STR(COMPAT_MULTICALL_arg0)"(%0),%%edi; " \ ++ " movl "STR(COMPAT_MULTICALL_arg1)"(%0),%%esi; " \ ++ " movl "STR(COMPAT_MULTICALL_arg2)"(%0),%%edx; " \ ++ " movl "STR(COMPAT_MULTICALL_arg3)"(%0),%%ecx; " \ ++ " movl "STR(COMPAT_MULTICALL_arg4)"(%0),%%r8d; " \ ++ " callq *%%rax; " \ ++ "1: movl %%eax,"STR(COMPAT_MULTICALL_result)"(%0)\n"\ ++ ".section .fixup,\"ax\"\n" \ ++ "2: movl $-"STR(ENOSYS)",%%eax\n" \ ++ " jmp 1b\n" \ ++ ".previous\n" \ ++ : : "b" (_call) \ ++ /* all the caller-saves registers */ \ ++ : "rax", "rcx", "rdx", "rsi", "rdi", \ ++ "r8", "r9", "r10", "r11" ); \ ++ } while ( 0 ) ++ + #else + + #define do_multicall_call(_call) \ +Index: 2006-12-11/xen/include/xen/multicall.h +=================================================================== +--- 2006-12-11.orig/xen/include/xen/multicall.h 2006-12-15 15:20:37.000000000 +0100 ++++ 2006-12-11/xen/include/xen/multicall.h 2006-12-15 15:33:42.000000000 +0100 +@@ -7,6 +7,9 @@ + + #include + #include ++#ifdef CONFIG_COMPAT ++#include ++#endif + + #define _MCSF_in_multicall 0 + #define _MCSF_call_preempted 1 +@@ -14,7 +17,12 @@ + #define MCSF_call_preempted (1<<_MCSF_call_preempted) + struct mc_state { + unsigned long flags; +- struct multicall_entry call; ++ union { ++ struct multicall_entry call; ++#ifdef CONFIG_COMPAT ++ struct compat_multicall_entry compat_call; ++#endif ++ }; + }; + + DECLARE_PER_CPU(struct mc_state, mc_state); diff --git a/32on64-per-domain-pa-bits.patch b/32on64-per-domain-pa-bits.patch new file mode 100644 index 0000000..8f7e62d --- /dev/null +++ b/32on64-per-domain-pa-bits.patch @@ -0,0 +1,78 @@ +Index: 2007-01-08/xen/arch/x86/domain.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/domain.c 2007-01-08 15:20:39.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/domain.c 2007-01-08 14:54:35.000000000 +0100 +@@ -253,7 +253,7 @@ static void release_compat_l4(struct vcp + + static inline int may_switch_mode(struct domain *d) + { +- return 1; /* XXX */ ++ return d->tot_pages == 0; + } + + int switch_native(struct domain *d) +@@ -281,6 +281,8 @@ int switch_native(struct domain *d) + release_compat_l4(d->vcpu[vcpuid]); + } + ++ d->pa_bitsize = 0; ++ + return 0; + } + +@@ -311,6 +313,9 @@ int switch_compat(struct domain *d) + return -ENOMEM; + } + ++ d->pa_bitsize = fls((1UL << 32) - HYPERVISOR_COMPAT_VIRT_START(d)) - 1 ++ + (PAGE_SIZE - 2); ++ + return 0; + } + +Index: 2007-01-08/xen/arch/x86/domain_build.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/domain_build.c 2007-01-08 14:54:33.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/domain_build.c 2007-01-08 15:36:39.000000000 +0100 +@@ -396,6 +396,8 @@ int construct_dom0(struct domain *d, + value = (value + mask) & ~mask; + #ifdef CONFIG_COMPAT + HYPERVISOR_COMPAT_VIRT_START(d) = max_t(unsigned int, m2p_compat_vstart, value); ++ d->pa_bitsize = fls((1UL << 32) - HYPERVISOR_COMPAT_VIRT_START(d)) - 1 ++ + (PAGE_SIZE - 2); + if ( value > (!IS_COMPAT(d) ? + HYPERVISOR_VIRT_START : + __HYPERVISOR_COMPAT_VIRT_START) ) +Index: 2007-01-08/xen/common/page_alloc.c +=================================================================== +--- 2007-01-08.orig/xen/common/page_alloc.c 2007-01-08 14:54:33.000000000 +0100 ++++ 2007-01-08/xen/common/page_alloc.c 2007-01-08 14:54:35.000000000 +0100 +@@ -718,7 +718,12 @@ struct page_info *__alloc_domheap_pages( + if ( bits && bits <= PAGE_SHIFT + 1 ) + return NULL; + +- zone_hi = bits - PAGE_SHIFT - 1; ++#ifdef CONFIG_COMPAT ++ if ( d && d->pa_bitsize && bits > d->pa_bitsize ) ++ zone_hi = d->pa_bitsize - PAGE_SHIFT - 1; ++ else ++#endif ++ zone_hi = bits - PAGE_SHIFT - 1; + if ( zone_hi >= NR_ZONES ) + zone_hi = NR_ZONES - 1; + +Index: 2007-01-08/xen/include/xen/sched.h +=================================================================== +--- 2007-01-08.orig/xen/include/xen/sched.h 2007-01-08 15:20:39.000000000 +0100 ++++ 2007-01-08/xen/include/xen/sched.h 2007-01-08 14:54:35.000000000 +0100 +@@ -165,6 +165,10 @@ struct domain + + unsigned long domain_flags; + ++#ifdef CONFIG_COMPAT ++ unsigned int pa_bitsize; ++#endif ++ + /* Boolean: Is this an HVM guest? */ + char is_hvm; + diff --git a/32on64-physdevop.patch b/32on64-physdevop.patch new file mode 100644 index 0000000..bbd9d8a --- /dev/null +++ b/32on64-physdevop.patch @@ -0,0 +1,316 @@ +Enable compatibility mode operation for HYPERVISOR_physdev_op and +HYPERVISOR_event_channel_op. + +Index: 2006-12-11/xen/arch/x86/compat.c +=================================================================== +--- 2006-12-11.orig/xen/arch/x86/compat.c 2006-12-15 15:20:34.000000000 +0100 ++++ 2006-12-11/xen/arch/x86/compat.c 2006-12-15 15:32:54.000000000 +0100 +@@ -9,17 +9,23 @@ + #include + #include + ++#ifndef COMPAT ++typedef long ret_t; ++#endif ++ + /* Legacy hypercall (as of 0x00030202). */ +-long do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop) ++ret_t do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop) + { + struct physdev_op op; + + if ( unlikely(copy_from_guest(&op, uop, 1) != 0) ) + return -EFAULT; + +- return do_physdev_op(op.cmd, (XEN_GUEST_HANDLE(void)) { &uop.p->u }); ++ return do_physdev_op(op.cmd, guest_handle_from_ptr(&uop.p->u, void)); + } + ++#ifndef COMPAT ++ + /* Legacy hypercall (as of 0x00030202). */ + long do_event_channel_op_compat(XEN_GUEST_HANDLE(evtchn_op_t) uop) + { +@@ -28,5 +34,7 @@ long do_event_channel_op_compat(XEN_GUES + if ( unlikely(copy_from_guest(&op, uop, 1) != 0) ) + return -EFAULT; + +- return do_event_channel_op(op.cmd, (XEN_GUEST_HANDLE(void)) {&uop.p->u }); ++ return do_event_channel_op(op.cmd, guest_handle_from_ptr(&uop.p->u, void)); + } ++ ++#endif +Index: 2006-12-11/xen/arch/x86/physdev.c +=================================================================== +--- 2006-12-11.orig/xen/arch/x86/physdev.c 2006-12-15 15:20:34.000000000 +0100 ++++ 2006-12-11/xen/arch/x86/physdev.c 2006-12-15 15:32:54.000000000 +0100 +@@ -9,9 +9,14 @@ + #include + #include + #include ++#include + #include + #include + ++#ifndef COMPAT ++typedef long ret_t; ++#endif ++ + int + ioapic_guest_read( + unsigned long physbase, unsigned int reg, u32 *pval); +@@ -19,10 +24,10 @@ int + ioapic_guest_write( + unsigned long physbase, unsigned int reg, u32 pval); + +-long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg) ++ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg) + { + int irq; +- long ret; ++ ret_t ret; + + switch ( cmd ) + { +@@ -129,7 +134,11 @@ long do_physdev_op(int cmd, XEN_GUEST_HA + (set_iobitmap.nr_ports > 65536) ) + break; + ret = 0; ++#ifndef COMPAT + current->arch.iobmp = set_iobitmap.bitmap; ++#else ++ guest_from_compat_handle(current->arch.iobmp, set_iobitmap.bitmap); ++#endif + current->arch.iobmp_limit = set_iobitmap.nr_ports; + break; + } +Index: 2006-12-11/xen/arch/x86/x86_64/Makefile +=================================================================== +--- 2006-12-11.orig/xen/arch/x86/x86_64/Makefile 2006-12-15 15:29:19.000000000 +0100 ++++ 2006-12-11/xen/arch/x86/x86_64/Makefile 2006-12-15 15:32:54.000000000 +0100 +@@ -3,9 +3,14 @@ obj-y += gpr_switch.o + obj-y += mm.o + obj-y += traps.o + ++obj-$(CONFIG_COMPAT) += compat.o ++obj-$(CONFIG_COMPAT) += physdev.o ++ + ifeq ($(CONFIG_COMPAT),y) + # extra dependencies ++compat.o: ../compat.c + entry.o: compat/entry.S + mm.o: compat/mm.c ++physdev.o: ../physdev.c + traps.o: compat/traps.c + endif +Index: 2006-12-11/xen/arch/x86/x86_64/compat.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2006-12-11/xen/arch/x86/x86_64/compat.c 2006-12-15 15:32:54.000000000 +0100 +@@ -0,0 +1,30 @@ ++/****************************************************************************** ++ * compat.c ++ */ ++ ++#include ++#include ++#include ++#include ++ ++DEFINE_XEN_GUEST_HANDLE(physdev_op_compat_t); ++#define physdev_op compat_physdev_op ++#define physdev_op_t physdev_op_compat_t ++#define do_physdev_op compat_physdev_op ++#define do_physdev_op_compat(x) compat_physdev_op_compat(_##x) ++ ++#define COMPAT ++#define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t) ++typedef int ret_t; ++ ++#include "../compat.c" ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * tab-width: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ +Index: 2006-12-11/xen/arch/x86/x86_64/compat/entry.S +=================================================================== +--- 2006-12-11.orig/xen/arch/x86/x86_64/compat/entry.S 2006-12-15 15:32:08.000000000 +0100 ++++ 2006-12-11/xen/arch/x86/x86_64/compat/entry.S 2006-12-15 15:32:54.000000000 +0100 +@@ -283,15 +283,11 @@ CFIX14: + #define compat_platform_op domain_crash_synchronous + #define compat_multicall domain_crash_synchronous + #define compat_set_timer_op domain_crash_synchronous +-#define compat_event_channel_op_compat domain_crash_synchronous +-#define compat_physdev_op_compat domain_crash_synchronous + #define compat_grant_table_op domain_crash_synchronous + #define compat_vcpu_op domain_crash_synchronous + #define compat_acm_op domain_crash_synchronous + #define compat_arch_sched_op domain_crash_synchronous + #define compat_xenoprof_op domain_crash_synchronous +-#define compat_event_channel_op domain_crash_synchronous +-#define compat_physdev_op domain_crash_synchronous + #define compat_sysctl domain_crash_synchronous + #define compat_domctl domain_crash_synchronous + +@@ -312,7 +308,7 @@ ENTRY(compat_hypercall_table) + .quad compat_multicall + .quad compat_update_va_mapping + .quad compat_set_timer_op /* 15 */ +- .quad compat_event_channel_op_compat ++ .quad do_event_channel_op_compat + .quad compat_xen_version + .quad do_console_io + .quad compat_physdev_op_compat +@@ -328,7 +324,7 @@ ENTRY(compat_hypercall_table) + .quad compat_arch_sched_op + .quad compat_callback_op /* 30 */ + .quad compat_xenoprof_op +- .quad compat_event_channel_op ++ .quad do_event_channel_op + .quad compat_physdev_op + .quad compat_ni_hypercall + .quad compat_sysctl /* 35 */ +Index: 2006-12-11/xen/arch/x86/x86_64/physdev.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2006-12-11/xen/arch/x86/x86_64/physdev.c 2006-12-15 15:32:54.000000000 +0100 +@@ -0,0 +1,48 @@ ++/****************************************************************************** ++ * physdev.c ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define do_physdev_op compat_physdev_op ++ ++#define physdev_apic compat_physdev_apic ++#define physdev_apic_t physdev_apic_compat_t ++ ++#define physdev_eoi compat_physdev_eoi ++#define physdev_eoi_t physdev_eoi_compat_t ++ ++#define physdev_set_iobitmap compat_physdev_set_iobitmap ++#define physdev_set_iobitmap_t physdev_set_iobitmap_compat_t ++ ++#define physdev_set_iopl compat_physdev_set_iopl ++#define physdev_set_iopl_t physdev_set_iopl_compat_t ++ ++#define physdev_irq compat_physdev_irq ++#define physdev_irq_t physdev_irq_compat_t ++ ++#define physdev_irq_status_query compat_physdev_irq_status_query ++#define physdev_irq_status_query_t physdev_irq_status_query_compat_t ++ ++#define COMPAT ++#undef guest_handle_okay ++#define guest_handle_okay compat_handle_okay ++typedef int ret_t; ++ ++#include "../physdev.c" ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * tab-width: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ +Index: 2006-12-11/xen/common/compat/xlat.c +=================================================================== +--- 2006-12-11.orig/xen/common/compat/xlat.c 2006-12-15 15:32:08.000000000 +0100 ++++ 2006-12-11/xen/common/compat/xlat.c 2006-12-15 15:32:54.000000000 +0100 +@@ -4,8 +4,8 @@ + + #include + #include +-#include + #include ++#include + + /* In-place translation functons: */ + void xlat_start_info(struct start_info *native, +@@ -21,6 +21,30 @@ void xlat_start_info(struct start_info * + CHECK_dom0_vga_console_info; + #undef dom0_vga_console_info + ++#define xen_evtchn_alloc_unbound evtchn_alloc_unbound ++#define xen_evtchn_bind_interdomain evtchn_bind_interdomain ++#define xen_evtchn_bind_ipi evtchn_bind_ipi ++#define xen_evtchn_bind_pirq evtchn_bind_pirq ++#define xen_evtchn_bind_vcpu evtchn_bind_vcpu ++#define xen_evtchn_bind_virq evtchn_bind_virq ++#define xen_evtchn_close evtchn_close ++#define xen_evtchn_op evtchn_op ++#define xen_evtchn_send evtchn_send ++#define xen_evtchn_status evtchn_status ++#define xen_evtchn_unmask evtchn_unmask ++CHECK_evtchn_op; ++#undef xen_evtchn_alloc_unbound ++#undef xen_evtchn_bind_interdomain ++#undef xen_evtchn_bind_ipi ++#undef xen_evtchn_bind_pirq ++#undef xen_evtchn_bind_vcpu ++#undef xen_evtchn_bind_virq ++#undef xen_evtchn_close ++#undef xen_evtchn_op ++#undef xen_evtchn_send ++#undef xen_evtchn_status ++#undef xen_evtchn_unmask ++ + #define xen_mmu_update mmu_update + CHECK_mmu_update; + #undef xen_mmu_update +Index: 2006-12-11/xen/include/asm-x86/hypercall.h +=================================================================== +--- 2006-12-11.orig/xen/include/asm-x86/hypercall.h 2006-12-15 15:32:08.000000000 +0100 ++++ 2006-12-11/xen/include/asm-x86/hypercall.h 2006-12-15 15:32:54.000000000 +0100 +@@ -123,4 +123,13 @@ do_set_callbacks( + + #endif + ++#ifdef CONFIG_COMPAT ++ ++extern int ++compat_physdev_op( ++ int cmd, ++ XEN_GUEST_HANDLE(void) arg); ++ ++#endif ++ + #endif /* __ASM_X86_HYPERCALL_H__ */ +Index: 2006-12-11/xen/include/xlat.lst +=================================================================== +--- 2006-12-11.orig/xen/include/xlat.lst 2006-12-15 15:32:08.000000000 +0100 ++++ 2006-12-11/xen/include/xlat.lst 2006-12-15 15:32:54.000000000 +0100 +@@ -6,6 +6,17 @@ + ! mmuext_op xen.h + ! start_info xen.h + ? vcpu_time_info xen.h ++? evtchn_alloc_unbound event_channel.h ++? evtchn_bind_interdomain event_channel.h ++? evtchn_bind_ipi event_channel.h ++? evtchn_bind_pirq event_channel.h ++? evtchn_bind_vcpu event_channel.h ++? evtchn_bind_virq event_channel.h ++? evtchn_close event_channel.h ++? evtchn_op event_channel.h ++? evtchn_send event_channel.h ++? evtchn_status event_channel.h ++? evtchn_unmask event_channel.h + ! add_to_physmap memory.h + ! foreign_memory_map memory.h + ! memory_exchange memory.h diff --git a/32on64-pltop.patch b/32on64-pltop.patch new file mode 100644 index 0000000..52631bd --- /dev/null +++ b/32on64-pltop.patch @@ -0,0 +1,108 @@ +Enable compatibility mode operation for HYPERVISOR_platformop. + +Index: 2006-12-11/xen/arch/x86/platform_hypercall.c +=================================================================== +--- 2006-12-11.orig/xen/arch/x86/platform_hypercall.c 2006-12-15 15:20:33.000000000 +0100 ++++ 2006-12-11/xen/arch/x86/platform_hypercall.c 2006-12-15 15:37:24.000000000 +0100 +@@ -23,11 +23,17 @@ + #include + #include "cpu/mtrr/mtrr.h" + +-long do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op) ++#ifndef COMPAT ++typedef long ret_t; ++DEFINE_SPINLOCK(xenpf_lock); ++#else ++extern spinlock_t xenpf_lock; ++#endif ++ ++ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op) + { +- long ret = 0; ++ ret_t ret = 0; + struct xen_platform_op curop, *op = &curop; +- static DEFINE_SPINLOCK(xenpf_lock); + + if ( !IS_PRIV(current->domain) ) + return -EPERM; +@@ -105,8 +111,15 @@ long do_platform_op(XEN_GUEST_HANDLE(xen + case XENPF_microcode_update: + { + extern int microcode_update(XEN_GUEST_HANDLE(void), unsigned long len); ++#ifndef COMPAT + ret = microcode_update(op->u.microcode.data, + op->u.microcode.length); ++#else ++ XEN_GUEST_HANDLE(void) data; ++ ++ guest_from_compat_handle(data, op->u.microcode.data); ++ ret = microcode_update(data, op->u.microcode.length); ++#endif + } + break; + +Index: 2006-12-11/xen/arch/x86/x86_64/Makefile +=================================================================== +--- 2006-12-11.orig/xen/arch/x86/x86_64/Makefile 2006-12-15 15:37:19.000000000 +0100 ++++ 2006-12-11/xen/arch/x86/x86_64/Makefile 2006-12-15 15:37:24.000000000 +0100 +@@ -6,6 +6,7 @@ obj-y += traps.o + obj-$(CONFIG_COMPAT) += compat.o + obj-$(CONFIG_COMPAT) += domain.o + obj-$(CONFIG_COMPAT) += physdev.o ++obj-$(CONFIG_COMPAT) += platform_hypercall.o + + ifeq ($(CONFIG_COMPAT),y) + # extra dependencies +@@ -13,5 +14,6 @@ compat.o: ../compat.c + entry.o: compat/entry.S + mm.o: compat/mm.c + physdev.o: ../physdev.c ++platform_hypercall.o: ../platform_hypercall.c + traps.o: compat/traps.c + endif +Index: 2006-12-11/xen/arch/x86/x86_64/compat/entry.S +=================================================================== +--- 2006-12-11.orig/xen/arch/x86/x86_64/compat/entry.S 2006-12-15 15:37:22.000000000 +0100 ++++ 2006-12-11/xen/arch/x86/x86_64/compat/entry.S 2006-12-15 15:37:24.000000000 +0100 +@@ -278,7 +278,6 @@ CFIX14: + + .section .rodata, "a", @progbits + +-#define compat_platform_op domain_crash_synchronous + #define compat_acm_op domain_crash_synchronous + #define compat_xenoprof_op domain_crash_synchronous + #define compat_sysctl domain_crash_synchronous +Index: 2006-12-11/xen/arch/x86/x86_64/platform_hypercall.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2006-12-11/xen/arch/x86/x86_64/platform_hypercall.c 2006-12-15 15:37:24.000000000 +0100 +@@ -0,0 +1,29 @@ ++/****************************************************************************** ++ * platform_hypercall.c ++ * ++ */ ++ ++#include ++#include ++#include ++ ++DEFINE_XEN_GUEST_HANDLE(compat_platform_op_t); ++#define xen_platform_op compat_platform_op ++#define xen_platform_op_t compat_platform_op_t ++#define do_platform_op(x) compat_platform_op(_##x) ++ ++#define COMPAT ++#define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t) ++typedef int ret_t; ++ ++#include "../platform_hypercall.c" ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * tab-width: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ diff --git a/32on64-schedop.patch b/32on64-schedop.patch new file mode 100644 index 0000000..3e27dae --- /dev/null +++ b/32on64-schedop.patch @@ -0,0 +1,167 @@ +Enable compatibility mode operation for HYPERVISOR_sched_op and +HYPERVISOR_set_timer_op. + +Index: 2006-12-18/xen/arch/x86/x86_64/compat/entry.S +=================================================================== +--- 2006-12-18.orig/xen/arch/x86/x86_64/compat/entry.S 2006-12-18 09:49:55.000000000 +0100 ++++ 2006-12-18/xen/arch/x86/x86_64/compat/entry.S 2006-12-18 09:49:57.000000000 +0100 +@@ -279,10 +279,8 @@ CFIX14: + .section .rodata, "a", @progbits + + #define compat_platform_op domain_crash_synchronous +-#define compat_set_timer_op domain_crash_synchronous + #define compat_grant_table_op domain_crash_synchronous + #define compat_acm_op domain_crash_synchronous +-#define compat_arch_sched_op domain_crash_synchronous + #define compat_xenoprof_op domain_crash_synchronous + #define compat_sysctl domain_crash_synchronous + #define compat_domctl domain_crash_synchronous +@@ -317,7 +315,7 @@ ENTRY(compat_hypercall_table) + .quad compat_mmuext_op + .quad compat_acm_op + .quad compat_nmi_op +- .quad compat_arch_sched_op ++ .quad compat_sched_op + .quad compat_callback_op /* 30 */ + .quad compat_xenoprof_op + .quad do_event_channel_op +@@ -359,7 +357,7 @@ ENTRY(compat_hypercall_args_table) + .byte 4 /* compat_mmuext_op */ + .byte 1 /* compat_acm_op */ + .byte 2 /* compat_nmi_op */ +- .byte 2 /* compat_arch_sched_op */ ++ .byte 2 /* compat_sched_op */ + .byte 2 /* compat_callback_op */ /* 30 */ + .byte 2 /* compat_xenoprof_op */ + .byte 2 /* compat_event_channel_op */ +Index: 2006-12-18/xen/common/Makefile +=================================================================== +--- 2006-12-18.orig/xen/common/Makefile 2006-12-18 09:43:12.000000000 +0100 ++++ 2006-12-18/xen/common/Makefile 2006-12-18 09:49:57.000000000 +0100 +@@ -39,3 +39,8 @@ subdir-$(CONFIG_COMPAT) += compat + + # Object file contains changeset and compiler information. + version.o: $(BASEDIR)/include/xen/compile.h ++ ++ifeq ($(CONFIG_COMPAT),y) ++# extra dependencies ++schedule.o: compat/schedule.c ++endif +Index: 2006-12-18/xen/common/compat/schedule.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2006-12-18/xen/common/compat/schedule.c 2006-12-18 09:49:57.000000000 +0100 +@@ -0,0 +1,51 @@ ++/**************************************************************************** ++ * schedule.c ++ * ++ */ ++ ++#include ++ ++#define COMPAT ++#define ret_t int ++ ++#define do_sched_op compat_sched_op ++ ++#define xen_sched_shutdown sched_shutdown ++CHECK_sched_shutdown; ++#undef xen_sched_shutdown ++ ++#define xen_sched_remote_shutdown sched_remote_shutdown ++CHECK_sched_remote_shutdown; ++#undef xen_sched_remote_shutdown ++ ++static int compat_poll(struct compat_sched_poll *compat) ++{ ++ struct sched_poll native; ++ ++#define XLAT_sched_poll_HNDL_ports(_d_, _s_) \ ++ guest_from_compat_handle((_d_)->ports, (_s_)->ports) ++ XLAT_sched_poll(&native, compat); ++#undef XLAT_sched_poll_HNDL_ports ++ ++ return do_poll(&native); ++} ++ ++#define do_poll compat_poll ++#define sched_poll compat_sched_poll ++ ++#include "../schedule.c" ++ ++int compat_set_timer_op(u32 lo, s32 hi) ++{ ++ return do_set_timer_op(((s64)hi << 32) | lo); ++} ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * tab-width: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ +Index: 2006-12-18/xen/common/schedule.c +=================================================================== +--- 2006-12-18.orig/xen/common/schedule.c 2006-12-18 09:46:14.000000000 +0100 ++++ 2006-12-18/xen/common/schedule.c 2006-12-18 09:49:57.000000000 +0100 +@@ -13,6 +13,7 @@ + * + */ + ++#ifndef COMPAT + #include + #include + #include +@@ -366,9 +367,13 @@ long do_sched_op_compat(int cmd, unsigne + return ret; + } + +-long do_sched_op(int cmd, XEN_GUEST_HANDLE(void) arg) ++typedef long ret_t; ++ ++#endif /* !COMPAT */ ++ ++ret_t do_sched_op(int cmd, XEN_GUEST_HANDLE(void) arg) + { +- long ret = 0; ++ ret_t ret = 0; + + switch ( cmd ) + { +@@ -445,6 +450,8 @@ long do_sched_op(int cmd, XEN_GUEST_HAND + return ret; + } + ++#ifndef COMPAT ++ + /* Per-domain one-shot-timer hypercall. */ + long do_set_timer_op(s_time_t timeout) + { +@@ -736,6 +743,12 @@ void dump_runq(unsigned char key) + local_irq_restore(flags); + } + ++#ifdef CONFIG_COMPAT ++#include "compat/schedule.c" ++#endif ++ ++#endif /* !COMPAT */ ++ + /* + * Local variables: + * mode: C +Index: 2006-12-18/xen/include/xlat.lst +=================================================================== +--- 2006-12-18.orig/xen/include/xlat.lst 2006-12-18 09:49:49.000000000 +0100 ++++ 2006-12-18/xen/include/xlat.lst 2006-12-18 09:49:57.000000000 +0100 +@@ -26,4 +26,7 @@ + ! memory_map memory.h + ! memory_reservation memory.h + ! translate_gpfn_list memory.h ++! sched_poll sched.h ++? sched_remote_shutdown sched.h ++? sched_shutdown sched.h + ! vcpu_runstate_info vcpu.h diff --git a/32on64-settrap.patch b/32on64-settrap.patch new file mode 100644 index 0000000..6795236 --- /dev/null +++ b/32on64-settrap.patch @@ -0,0 +1,123 @@ +Enable compatibility mode operation for HYPERVISOR_set_trap_table and +HYPERVISOR_set_gdt. + +Index: 2006-12-11/xen/arch/x86/x86_64/compat/entry.S +=================================================================== +--- 2006-12-11.orig/xen/arch/x86/x86_64/compat/entry.S 2006-12-15 15:32:56.000000000 +0100 ++++ 2006-12-11/xen/arch/x86/x86_64/compat/entry.S 2006-12-15 15:32:58.000000000 +0100 +@@ -278,8 +278,6 @@ CFIX14: + + .section .rodata, "a", @progbits + +-#define compat_set_trap_table domain_crash_synchronous +-#define compat_set_gdt domain_crash_synchronous + #define compat_platform_op domain_crash_synchronous + #define compat_multicall domain_crash_synchronous + #define compat_set_timer_op domain_crash_synchronous +Index: 2006-12-11/xen/arch/x86/x86_64/compat/mm.c +=================================================================== +--- 2006-12-11.orig/xen/arch/x86/x86_64/compat/mm.c 2006-12-15 15:32:08.000000000 +0100 ++++ 2006-12-11/xen/arch/x86/x86_64/compat/mm.c 2006-12-15 15:32:58.000000000 +0100 +@@ -4,6 +4,39 @@ + #include + #include + ++int compat_set_gdt(XEN_GUEST_HANDLE(uint) frame_list, unsigned int entries) ++{ ++ unsigned int i, nr_pages = (entries + 511) / 512; ++ unsigned long frames[16]; ++ long ret; ++ ++ /* Rechecked in set_gdt, but ensures a sane limit for copy_from_user(). */ ++ if ( entries > FIRST_RESERVED_GDT_ENTRY ) ++ return -EINVAL; ++ ++ if ( !guest_handle_okay(frame_list, nr_pages) ) ++ return -EFAULT; ++ ++ for ( i = 0; i < nr_pages; ++i ) ++ { ++ unsigned int frame; ++ ++ if ( __copy_from_guest(&frame, frame_list, 1) ) ++ return -EFAULT; ++ frames[i] = frame; ++ guest_handle_add_offset(frame_list, 1); ++ } ++ ++ LOCK_BIGLOCK(current->domain); ++ ++ if ( (ret = set_gdt(current, frames, entries)) == 0 ) ++ local_flush_tlb(); ++ ++ UNLOCK_BIGLOCK(current->domain); ++ ++ return ret; ++} ++ + int compat_update_descriptor(u32 pa_lo, u32 pa_hi, u32 desc_lo, u32 desc_hi) + { + return do_update_descriptor(pa_lo | ((u64)pa_hi << 32), +Index: 2006-12-11/xen/arch/x86/x86_64/compat/traps.c +=================================================================== +--- 2006-12-11.orig/xen/arch/x86/x86_64/compat/traps.c 2006-12-15 15:28:41.000000000 +0100 ++++ 2006-12-11/xen/arch/x86/x86_64/compat/traps.c 2006-12-15 15:32:58.000000000 +0100 +@@ -1,6 +1,8 @@ + #ifdef CONFIG_COMPAT + ++#include + #include ++#include + + void compat_show_guest_stack(struct cpu_user_regs *regs, int debug_stack_lines) + { +@@ -252,6 +254,49 @@ long compat_set_callbacks(unsigned long + return 0; + } + ++DEFINE_XEN_GUEST_HANDLE(trap_info_compat_t); ++ ++int compat_set_trap_table(XEN_GUEST_HANDLE(trap_info_compat_t) traps) ++{ ++ struct compat_trap_info cur; ++ struct trap_info *dst = current->arch.guest_context.trap_ctxt; ++ long rc = 0; ++ ++ /* If no table is presented then clear the entire virtual IDT. */ ++ if ( guest_handle_is_null(traps) ) ++ { ++ memset(dst, 0, 256 * sizeof(*dst)); ++ return 0; ++ } ++ ++ for ( ; ; ) ++ { ++ if ( hypercall_preempt_check() ) ++ { ++ rc = hypercall_create_continuation( ++ __HYPERVISOR_set_trap_table, "h", traps); ++ break; ++ } ++ ++ if ( copy_from_guest(&cur, traps, 1) ) ++ { ++ rc = -EFAULT; ++ break; ++ } ++ ++ if ( cur.address == 0 ) ++ break; ++ ++ fixup_guest_code_selector(current->domain, cur.cs); ++ ++ XLAT_trap_info(dst + cur.vector, &cur); ++ ++ guest_handle_add_offset(traps, 1); ++ } ++ ++ return rc; ++} ++ + #endif /* CONFIG_COMPAT */ + + static void hypercall_page_initialise_ring1_kernel(void *hypercall_page) diff --git a/32on64-shadow.patch b/32on64-shadow.patch new file mode 100644 index 0000000..2343031 --- /dev/null +++ b/32on64-shadow.patch @@ -0,0 +1,199 @@ +Preliminary, likely incomplete and/or wrong, adjustments to shadow code. + +unstable c/s 13296: [HVM] Fix shadow memory tracking +Fixes a missing free from cset 13275, and a missing prealloc. +Signed-off-by: Tim Deegan + +Index: 2007-01-31/xen/arch/x86/mm/shadow/common.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/mm/shadow/common.c 2007-01-31 09:31:33.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/mm/shadow/common.c 2007-01-31 09:36:44.000000000 +0100 +@@ -2427,7 +2427,7 @@ void sh_update_paging_modes(struct vcpu + /// + #if CONFIG_PAGING_LEVELS == 4 + if ( pv_32bit_guest(v) ) +- v->arch.shadow.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,4,3); ++ v->arch.shadow.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,3,3); + else + v->arch.shadow.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,4,4); + #elif CONFIG_PAGING_LEVELS == 3 +Index: 2007-01-31/xen/arch/x86/mm/shadow/multi.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/mm/shadow/multi.c 2007-01-31 09:31:33.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/mm/shadow/multi.c 2007-01-31 09:36:54.000000000 +0100 +@@ -1423,7 +1423,7 @@ void sh_install_xen_entries_in_l4(struct + } + #endif + +-#if CONFIG_PAGING_LEVELS == 3 && GUEST_PAGING_LEVELS == 3 ++#if (CONFIG_PAGING_LEVELS == 3 || defined(CONFIG_COMPAT)) && GUEST_PAGING_LEVELS == 3 + // For 3-on-3 PV guests, we need to make sure the xen mappings are in + // place, which means that we need to populate the l2h entry in the l3 + // table. +@@ -1433,12 +1433,20 @@ void sh_install_xen_entries_in_l2h(struc + { + struct domain *d = v->domain; + shadow_l2e_t *sl2e; ++#if CONFIG_PAGING_LEVELS == 3 + int i; ++#else ++ ++ if ( !pv_32bit_guest(v) ) ++ return; ++#endif + + sl2e = sh_map_domain_page(sl2hmfn); + ASSERT(sl2e != NULL); + ASSERT(sizeof (l2_pgentry_t) == sizeof (shadow_l2e_t)); + ++#if CONFIG_PAGING_LEVELS == 3 ++ + /* Copy the common Xen mappings from the idle domain */ + memcpy(&sl2e[L2_PAGETABLE_FIRST_XEN_SLOT & (L2_PAGETABLE_ENTRIES-1)], + &idle_pg_table_l2[L2_PAGETABLE_FIRST_XEN_SLOT], +@@ -1479,6 +1487,15 @@ void sh_install_xen_entries_in_l2h(struc + } + sh_unmap_domain_page(p2m); + } ++ ++#else ++ ++ /* Copy the common Xen mappings from the idle domain */ ++ memcpy(&sl2e[COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(d)], ++ &compat_idle_pg_table_l2[l2_table_offset(HIRO_COMPAT_MPT_VIRT_START)], ++ COMPAT_L2_PAGETABLE_XEN_SLOTS(d) * sizeof(*sl2e)); ++ ++#endif + + sh_unmap_domain_page(sl2e); + } +@@ -1639,12 +1656,15 @@ make_fl1_shadow(struct vcpu *v, gfn_t gf + mfn_t + sh_make_monitor_table(struct vcpu *v) + { ++ struct domain *d = v->domain; + + ASSERT(pagetable_get_pfn(v->arch.monitor_table) == 0); + ++ /* Guarantee we can get the memory we need */ ++ shadow_prealloc(d, SHADOW_MAX_ORDER); ++ + #if CONFIG_PAGING_LEVELS == 4 + { +- struct domain *d = v->domain; + mfn_t m4mfn; + m4mfn = shadow_alloc(d, SH_type_monitor_table, 0); + sh_install_xen_entries_in_l4(v, m4mfn, m4mfn); +@@ -1661,6 +1681,19 @@ sh_make_monitor_table(struct vcpu *v) + l4e = sh_map_domain_page(m4mfn); + l4e[0] = l4e_from_pfn(mfn_x(m3mfn), __PAGE_HYPERVISOR); + sh_unmap_domain_page(l4e); ++ if ( pv_32bit_guest(v) ) ++ { ++ // Install a monitor l2 table in slot 3 of the l3 table. ++ // This is used for all Xen entries. ++ mfn_t m2mfn; ++ l3_pgentry_t *l3e; ++ m2mfn = shadow_alloc(d, SH_type_monitor_table, 0); ++ mfn_to_page(m2mfn)->shadow_flags = 2; ++ l3e = sh_map_domain_page(m3mfn); ++ l3e[3] = l3e_from_pfn(mfn_x(m2mfn), _PAGE_PRESENT); ++ sh_install_xen_entries_in_l2h(v, m2mfn); ++ sh_unmap_domain_page(l3e); ++ } + } + #endif /* SHADOW_PAGING_LEVELS < 4 */ + return m4mfn; +@@ -1669,7 +1702,6 @@ sh_make_monitor_table(struct vcpu *v) + #elif CONFIG_PAGING_LEVELS == 3 + + { +- struct domain *d = v->domain; + mfn_t m3mfn, m2mfn; + l3_pgentry_t *l3e; + l2_pgentry_t *l2e; +@@ -1703,7 +1735,6 @@ sh_make_monitor_table(struct vcpu *v) + #elif CONFIG_PAGING_LEVELS == 2 + + { +- struct domain *d = v->domain; + mfn_t m2mfn; + m2mfn = shadow_alloc(d, SH_type_monitor_table, 0); + sh_install_xen_entries_in_l2(v, m2mfn, m2mfn); +@@ -2066,9 +2097,19 @@ void sh_destroy_monitor_table(struct vcp + #if (CONFIG_PAGING_LEVELS == 4) && (SHADOW_PAGING_LEVELS != 4) + /* Need to destroy the l3 monitor page in slot 0 too */ + { ++ mfn_t m3mfn; + l4_pgentry_t *l4e = sh_map_domain_page(mmfn); + ASSERT(l4e_get_flags(l4e[0]) & _PAGE_PRESENT); +- shadow_free(d, _mfn(l4e_get_pfn(l4e[0]))); ++ m3mfn = _mfn(l4e_get_pfn(l4e[0])); ++ if ( pv_32bit_guest(v) ) ++ { ++ /* Need to destroy the l2 monitor page in slot 3 too */ ++ l3_pgentry_t *l3e = sh_map_domain_page(m3mfn); ++ ASSERT(l3e_get_flags(l3e[3]) & _PAGE_PRESENT); ++ shadow_free(d, _mfn(l3e_get_pfn(l3e[3]))); ++ sh_unmap_domain_page(l3e); ++ } ++ shadow_free(d, m3mfn); + sh_unmap_domain_page(l4e); + } + #elif CONFIG_PAGING_LEVELS == 3 +@@ -3048,12 +3089,15 @@ sh_update_linear_entries(struct vcpu *v) + + #elif (CONFIG_PAGING_LEVELS == 4) && (SHADOW_PAGING_LEVELS == 3) + +- /* This case only exists in HVM. To give ourselves a linear map of the +- * shadows, we need to extend a PAE shadow to 4 levels. We do this by +- * having a monitor l3 in slot 0 of the monitor l4 table, and +- * copying the PAE l3 entries into it. Then, by having the monitor l4e +- * for shadow pagetables also point to the monitor l4, we can use it +- * to access the shadows. */ ++ /* PV: XXX ++ * ++ * HVM: To give ourselves a linear map of the shadows, we need to ++ * extend a PAE shadow to 4 levels. We do this by having a monitor ++ * l3 in slot 0 of the monitor l4 table, and copying the PAE l3 ++ * entries into it. Then, by having the monitor l4e for shadow ++ * pagetables also point to the monitor l4, we can use it to access ++ * the shadows. ++ */ + + if ( shadow_mode_external(d) ) + { +@@ -3096,6 +3140,8 @@ sh_update_linear_entries(struct vcpu *v) + if ( v != current ) + sh_unmap_domain_page(ml3e); + } ++ else ++ domain_crash(d); /* XXX */ + + #elif CONFIG_PAGING_LEVELS == 3 + +Index: 2007-01-31/xen/include/asm-x86/shadow.h +=================================================================== +--- 2007-01-31.orig/xen/include/asm-x86/shadow.h 2007-01-31 09:31:33.000000000 +0100 ++++ 2007-01-31/xen/include/asm-x86/shadow.h 2007-01-31 09:36:44.000000000 +0100 +@@ -70,9 +70,9 @@ + + // How do we tell that we have a 32-bit PV guest in a 64-bit Xen? + #ifdef __x86_64__ +-#define pv_32bit_guest(_v) 0 // not yet supported ++#define pv_32bit_guest(_v) (!is_hvm_vcpu(_v) && IS_COMPAT((_v)->domain)) + #else +-#define pv_32bit_guest(_v) !is_hvm_vcpu(v) ++#define pv_32bit_guest(_v) (!is_hvm_vcpu(_v)) + #endif + + /* The shadow lock. +@@ -418,7 +418,7 @@ static inline void update_cr3(struct vcp + } + + #if CONFIG_PAGING_LEVELS == 4 +- if ( !(v->arch.flags & TF_kernel_mode) ) ++ if ( !(v->arch.flags & TF_kernel_mode) && !IS_COMPAT(v->domain) ) + cr3_mfn = pagetable_get_pfn(v->arch.guest_table_user); + else + #endif diff --git a/32on64-shared.patch b/32on64-shared.patch new file mode 100644 index 0000000..920db96 --- /dev/null +++ b/32on64-shared.patch @@ -0,0 +1,900 @@ +Handle shared info (having different layout for native and compatibility +mode guests) accesses. + +Index: 2007-01-08/xen/arch/x86/crash.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/crash.c 2007-01-08 15:34:16.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/crash.c 2007-01-08 15:19:11.000000000 +0100 +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + + static atomic_t waiting_for_crash_ipi; +@@ -103,7 +104,7 @@ void machine_crash_shutdown(void) + + info = kexec_crash_save_info(); + info->dom0_pfn_to_mfn_frame_list_list = +- dom0->shared_info->arch.pfn_to_mfn_frame_list_list; ++ arch_get_pfn_to_mfn_frame_list_list(dom0); + } + + /* +Index: 2007-01-08/xen/arch/x86/domain.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/domain.c 2007-01-08 14:45:40.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/domain.c 2007-01-08 15:19:11.000000000 +0100 +@@ -547,10 +547,10 @@ static void load_segments(struct vcpu *n + + /* CS longword also contains full evtchn_upcall_mask. */ + cs_and_mask = (unsigned short)regs->cs | +- ((unsigned int)n->vcpu_info->evtchn_upcall_mask << 16); ++ ((unsigned int)vcpu_info(n, evtchn_upcall_mask) << 16); + /* Fold upcall mask into RFLAGS.IF. */ + eflags = regs->_eflags & ~X86_EFLAGS_IF; +- eflags |= !n->vcpu_info->evtchn_upcall_mask << 9; ++ eflags |= !vcpu_info(n, evtchn_upcall_mask) << 9; + + if ( !ring_1(regs) ) + { +@@ -575,7 +575,7 @@ static void load_segments(struct vcpu *n + + if ( test_bit(_VGCF_failsafe_disables_events, + &n->arch.guest_context.flags) ) +- n->vcpu_info->evtchn_upcall_mask = 1; ++ vcpu_info(n, evtchn_upcall_mask) = 1; + + regs->entry_vector = TRAP_syscall; + regs->_eflags &= 0xFFFCBEFFUL; +@@ -593,11 +593,11 @@ static void load_segments(struct vcpu *n + + /* CS longword also contains full evtchn_upcall_mask. */ + cs_and_mask = (unsigned long)regs->cs | +- ((unsigned long)n->vcpu_info->evtchn_upcall_mask << 32); ++ ((unsigned long)vcpu_info(n, evtchn_upcall_mask) << 32); + + /* Fold upcall mask into RFLAGS.IF. */ + rflags = regs->rflags & ~X86_EFLAGS_IF; +- rflags |= !n->vcpu_info->evtchn_upcall_mask << 9; ++ rflags |= !vcpu_info(n, evtchn_upcall_mask) << 9; + + if ( put_user(regs->ss, rsp- 1) | + put_user(regs->rsp, rsp- 2) | +@@ -618,7 +618,7 @@ static void load_segments(struct vcpu *n + + if ( test_bit(_VGCF_failsafe_disables_events, + &n->arch.guest_context.flags) ) +- n->vcpu_info->evtchn_upcall_mask = 1; ++ vcpu_info(n, evtchn_upcall_mask) = 1; + + regs->entry_vector = TRAP_syscall; + regs->rflags &= ~(X86_EFLAGS_AC|X86_EFLAGS_VM|X86_EFLAGS_RF| +Index: 2007-01-08/xen/arch/x86/domain_build.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/domain_build.c 2007-01-08 15:35:20.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/domain_build.c 2007-01-08 15:35:36.000000000 +0100 +@@ -328,6 +328,7 @@ int construct_dom0(struct domain *d, + l1_pgentry_t gdt_l1e; + + set_bit(_DOMF_compat, &d->domain_flags); ++ v->vcpu_info = (void *)&d->shared_info->compat.vcpu_info[0]; + + if ( nr_pages != (unsigned int)nr_pages ) + nr_pages = UINT_MAX; +@@ -730,7 +731,7 @@ int construct_dom0(struct domain *d, + + /* Mask all upcalls... */ + for ( i = 0; i < MAX_VIRT_CPUS; i++ ) +- d->shared_info->vcpu_info[i].evtchn_upcall_mask = 1; ++ shared_info(d, vcpu_info[i].evtchn_upcall_mask) = 1; + + if ( opt_dom0_max_vcpus == 0 ) + opt_dom0_max_vcpus = num_online_cpus(); +@@ -738,6 +739,8 @@ int construct_dom0(struct domain *d, + opt_dom0_max_vcpus = num_online_cpus(); + if ( opt_dom0_max_vcpus > MAX_VIRT_CPUS ) + opt_dom0_max_vcpus = MAX_VIRT_CPUS; ++ if ( opt_dom0_max_vcpus > BITS_PER_GUEST_LONG(d) ) ++ opt_dom0_max_vcpus = BITS_PER_GUEST_LONG(d); + printk("Dom0 has maximum %u VCPUs\n", opt_dom0_max_vcpus); + + for ( i = 1; i < opt_dom0_max_vcpus; i++ ) +Index: 2007-01-08/xen/arch/x86/irq.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/irq.c 2007-01-08 15:34:16.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/irq.c 2007-01-08 15:19:11.000000000 +0100 +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -332,7 +333,7 @@ int pirq_guest_unmask(struct domain *d) + irq < NR_IRQS; + irq = find_next_bit(d->pirq_mask, NR_IRQS, irq+1) ) + { +- if ( !test_bit(d->pirq_to_evtchn[irq], s->evtchn_mask) ) ++ if ( !test_bit(d->pirq_to_evtchn[irq], __shared_info_addr(d, s, evtchn_mask)) ) + __pirq_guest_eoi(d, irq); + } + +@@ -624,14 +625,13 @@ static void dump_irqs(unsigned char key) + printk("%u(%c%c%c%c)", + d->domain_id, + (test_bit(d->pirq_to_evtchn[irq], +- d->shared_info->evtchn_pending) ? ++ shared_info_addr(d, evtchn_pending)) ? + 'P' : '-'), +- (test_bit(d->pirq_to_evtchn[irq]/BITS_PER_LONG, +- &d->shared_info->vcpu_info[0]. +- evtchn_pending_sel) ? ++ (test_bit(d->pirq_to_evtchn[irq]/BITS_PER_GUEST_LONG(d), ++ vcpu_info_addr(d->vcpu[0], evtchn_pending_sel)) ? + 'S' : '-'), + (test_bit(d->pirq_to_evtchn[irq], +- d->shared_info->evtchn_mask) ? ++ shared_info_addr(d, evtchn_mask)) ? + 'M' : '-'), + (test_bit(irq, d->pirq_mask) ? + 'M' : '-')); +Index: 2007-01-08/xen/arch/x86/mm/shadow/common.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/mm/shadow/common.c 2007-01-08 15:34:16.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/mm/shadow/common.c 2007-01-08 15:19:11.000000000 +0100 +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + #include "private.h" + + #if SHADOW_AUDIT +@@ -2890,7 +2891,7 @@ sh_alloc_log_dirty_bitmap(struct domain + { + ASSERT(d->arch.shadow.dirty_bitmap == NULL); + d->arch.shadow.dirty_bitmap_size = +- (d->shared_info->arch.max_pfn + (BITS_PER_LONG - 1)) & ++ (arch_get_max_pfn(d) + (BITS_PER_LONG - 1)) & + ~(BITS_PER_LONG - 1); + d->arch.shadow.dirty_bitmap = + xmalloc_array(unsigned long, +Index: 2007-01-08/xen/arch/x86/setup.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/setup.c 2007-01-08 15:18:32.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/setup.c 2007-01-08 15:19:11.000000000 +0100 +@@ -548,14 +548,13 @@ void __init __start_xen(multiboot_info_t + + BUILD_BUG_ON(sizeof(start_info_t) > PAGE_SIZE); + BUILD_BUG_ON(sizeof(shared_info_t) > PAGE_SIZE); +- BUILD_BUG_ON(sizeof(vcpu_info_t) != 64); ++ BUILD_BUG_ON(sizeof(struct vcpu_info) != 64); + + #ifdef CONFIG_COMPAT + BUILD_BUG_ON(sizeof(((struct compat_platform_op *)0)->u) != + sizeof(((struct compat_platform_op *)0)->u.pad)); + BUILD_BUG_ON(sizeof(start_info_compat_t) > PAGE_SIZE); +- BUILD_BUG_ON(sizeof(shared_info_compat_t) > PAGE_SIZE); +- BUILD_BUG_ON(sizeof(vcpu_info_compat_t) != 64); ++ BUILD_BUG_ON(sizeof(struct compat_vcpu_info) != 64); + #endif + + /* Check definitions in public headers match internal defs. */ +Index: 2007-01-08/xen/arch/x86/time.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/time.c 2007-01-08 15:34:16.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/time.c 2007-01-08 15:19:11.000000000 +0100 +@@ -676,7 +676,7 @@ static inline void __update_vcpu_system_ + struct vcpu_time_info *u; + + t = &this_cpu(cpu_time); +- u = &v->vcpu_info->time; ++ u = &vcpu_info(v, time); + + version_update_begin(&u->version); + +@@ -690,7 +690,7 @@ static inline void __update_vcpu_system_ + + void update_vcpu_system_time(struct vcpu *v) + { +- if ( v->vcpu_info->time.tsc_timestamp != ++ if ( vcpu_info(v, time.tsc_timestamp) != + this_cpu(cpu_time).local_tsc_stamp ) + __update_vcpu_system_time(v); + } +@@ -698,10 +698,10 @@ void update_vcpu_system_time(struct vcpu + void update_domain_wallclock_time(struct domain *d) + { + spin_lock(&wc_lock); +- version_update_begin(&d->shared_info->wc_version); +- d->shared_info->wc_sec = wc_sec + d->time_offset_seconds; +- d->shared_info->wc_nsec = wc_nsec; +- version_update_end(&d->shared_info->wc_version); ++ version_update_begin(&shared_info(d, wc_version)); ++ shared_info(d, wc_sec) = wc_sec + d->time_offset_seconds; ++ shared_info(d, wc_nsec) = wc_nsec; ++ version_update_end(&shared_info(d, wc_version)); + spin_unlock(&wc_lock); + } + +Index: 2007-01-08/xen/arch/x86/traps.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/traps.c 2006-12-18 09:43:08.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/traps.c 2007-01-08 15:19:11.000000000 +0100 +@@ -58,6 +58,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -681,7 +682,7 @@ void propagate_page_fault(unsigned long + struct trap_bounce *tb = &v->arch.trap_bounce; + + v->arch.guest_context.ctrlreg[2] = addr; +- v->vcpu_info->arch.cr2 = addr; ++ arch_set_cr2(v, addr); + + /* Re-set error_code.user flag appropriately for the guest. */ + error_code &= ~PFEC_user_mode; +@@ -1406,7 +1407,7 @@ static int emulate_privileged_op(struct + + case 2: /* Write CR2 */ + v->arch.guest_context.ctrlreg[2] = *reg; +- v->vcpu_info->arch.cr2 = *reg; ++ arch_set_cr2(v, *reg); + break; + + case 3: /* Write CR3 */ +@@ -1617,7 +1618,7 @@ static void nmi_dom0_report(unsigned int + if ( ((d = dom0) == NULL) || ((v = d->vcpu[0]) == NULL) ) + return; + +- set_bit(reason_idx, &d->shared_info->arch.nmi_reason); ++ set_bit(reason_idx, nmi_reason(d)); + + if ( test_and_set_bit(_VCPUF_nmi_pending, &v->vcpu_flags) ) + raise_softirq(NMI_SOFTIRQ); /* not safe to wake up a vcpu here */ +Index: 2007-01-08/xen/arch/x86/x86_64/asm-offsets.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_64/asm-offsets.c 2006-12-18 09:43:08.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_64/asm-offsets.c 2007-01-08 15:19:11.000000000 +0100 +@@ -7,6 +7,9 @@ + #include + #include + #include ++#ifdef CONFIG_COMPAT ++#include ++#endif + #include + #include + +@@ -96,9 +99,15 @@ void __dummy__(void) + OFFSET(VMCB_tsc_offset, struct vmcb_struct, tsc_offset); + BLANK(); + +- OFFSET(VCPUINFO_upcall_pending, vcpu_info_t, evtchn_upcall_pending); +- OFFSET(VCPUINFO_upcall_mask, vcpu_info_t, evtchn_upcall_mask); ++ OFFSET(VCPUINFO_upcall_pending, struct vcpu_info, evtchn_upcall_pending); ++ OFFSET(VCPUINFO_upcall_mask, struct vcpu_info, evtchn_upcall_mask); ++ BLANK(); ++ ++#ifdef CONFIG_COMPAT ++ OFFSET(COMPAT_VCPUINFO_upcall_pending, struct compat_vcpu_info, evtchn_upcall_pending); ++ OFFSET(COMPAT_VCPUINFO_upcall_mask, struct compat_vcpu_info, evtchn_upcall_mask); + BLANK(); ++#endif + + OFFSET(CPUINFO_current_vcpu, struct cpu_info, current_vcpu); + DEFINE(CPUINFO_sizeof, sizeof(struct cpu_info)); +Index: 2007-01-08/xen/arch/x86/x86_64/compat/entry.S +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:17:29.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:19:11.000000000 +0100 +@@ -69,9 +69,9 @@ compat_test_all_events: + jc compat_process_nmi + compat_test_guest_events: + movq VCPU_vcpu_info(%rbx),%rax +- testb $0xFF,VCPUINFO_upcall_mask(%rax) ++ testb $0xFF,COMPAT_VCPUINFO_upcall_mask(%rax) + jnz compat_restore_all_guest +- testb $0xFF,VCPUINFO_upcall_pending(%rax) ++ testb $0xFF,COMPAT_VCPUINFO_upcall_pending(%rax) + jz compat_restore_all_guest + /*compat_process_guest_events:*/ + sti +@@ -189,10 +189,10 @@ CFLT4: mov UREGS_ss+8(%rsp),%fs + movb TRAPBOUNCE_flags(%rdx),%cl + subl $3*4,%esi + movq VCPU_vcpu_info(%rbx),%rax +- pushq VCPUINFO_upcall_mask(%rax) ++ pushq COMPAT_VCPUINFO_upcall_mask(%rax) + testb $TBF_INTERRUPT,%cl + setnz %ch # TBF_INTERRUPT -> set upcall mask +- orb %ch,VCPUINFO_upcall_mask(%rax) ++ orb %ch,COMPAT_VCPUINFO_upcall_mask(%rax) + popq %rax + shll $16,%eax # Bits 16-23: saved_upcall_mask + movw UREGS_cs+8(%rsp),%ax # Bits 0-15: CS +Index: 2007-01-08/xen/arch/x86/x86_64/compat/traps.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/traps.c 2007-01-08 15:17:29.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_64/compat/traps.c 2007-01-08 15:19:11.000000000 +0100 +@@ -118,7 +118,7 @@ unsigned int compat_iret(void) + clear_bit(_VCPUF_nmi_masked, ¤t->vcpu_flags); + + /* Restore upcall mask from supplied EFLAGS.IF. */ +- current->vcpu_info->evtchn_upcall_mask = !(eflags & X86_EFLAGS_IF); ++ vcpu_info(current, evtchn_upcall_mask) = !(eflags & X86_EFLAGS_IF); + + /* + * The hypercall exit path will overwrite EAX with this return +Index: 2007-01-08/xen/arch/x86/x86_64/traps.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_64/traps.c 2006-12-18 09:43:08.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_64/traps.c 2007-01-08 15:19:11.000000000 +0100 +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -52,7 +53,7 @@ void show_registers(struct cpu_user_regs + if ( guest_mode(regs) ) + { + context = "guest"; +- fault_crs[2] = current->vcpu_info->arch.cr2; ++ fault_crs[2] = arch_get_cr2(current); + } + else + { +@@ -234,7 +235,7 @@ unsigned long do_iret(void) + clear_bit(_VCPUF_nmi_masked, ¤t->vcpu_flags); + + /* Restore upcall mask from supplied EFLAGS.IF. */ +- current->vcpu_info->evtchn_upcall_mask = !(iret_saved.rflags & EF_IE); ++ vcpu_info(current, evtchn_upcall_mask) = !(iret_saved.rflags & EF_IE); + + /* Saved %rax gets written back to regs->rax in entry.S. */ + return iret_saved.rax; +Index: 2007-01-08/xen/common/compat/xlat.c +=================================================================== +--- 2007-01-08.orig/xen/common/compat/xlat.c 2007-01-08 15:18:32.000000000 +0100 ++++ 2007-01-08/xen/common/compat/xlat.c 2007-01-08 15:19:11.000000000 +0100 +@@ -21,6 +21,10 @@ void xlat_start_info(struct start_info * + CHECK_dom0_vga_console_info; + #undef dom0_vga_console_info + ++#define xen_vcpu_time_info vcpu_time_info ++CHECK_vcpu_time_info; ++#undef xen_vcpu_time_info ++ + /* + * Local variables: + * mode: C +Index: 2007-01-08/xen/common/domain.c +=================================================================== +--- 2007-01-08.orig/xen/common/domain.c 2007-01-08 15:34:16.000000000 +0100 ++++ 2007-01-08/xen/common/domain.c 2007-01-08 15:19:11.000000000 +0100 +@@ -90,7 +90,7 @@ struct vcpu *alloc_vcpu( + + v->domain = d; + v->vcpu_id = vcpu_id; +- v->vcpu_info = &d->shared_info->vcpu_info[vcpu_id]; ++ v->vcpu_info = shared_info_addr(d, vcpu_info[vcpu_id]); + spin_lock_init(&v->pause_lock); + + v->runstate.state = is_idle_vcpu(v) ? RUNSTATE_running : RUNSTATE_offline; +Index: 2007-01-08/xen/common/event_channel.c +=================================================================== +--- 2007-01-08.orig/xen/common/event_channel.c 2007-01-08 15:34:16.000000000 +0100 ++++ 2007-01-08/xen/common/event_channel.c 2007-01-08 15:19:11.000000000 +0100 +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -33,7 +34,7 @@ + #define bucket_from_port(d,p) \ + ((d)->evtchn[(p)/EVTCHNS_PER_BUCKET]) + #define port_is_valid(d,p) \ +- (((p) >= 0) && ((p) < MAX_EVTCHNS) && \ ++ (((p) >= 0) && ((p) < MAX_EVTCHNS(d)) && \ + (bucket_from_port(d,p) != NULL)) + #define evtchn_from_port(d,p) \ + (&(bucket_from_port(d,p))[(p)&(EVTCHNS_PER_BUCKET-1)]) +@@ -82,7 +83,7 @@ static int get_free_port(struct domain * + if ( evtchn_from_port(d, port)->state == ECS_FREE ) + return port; + +- if ( port == MAX_EVTCHNS ) ++ if ( port == MAX_EVTCHNS(d) ) + return -ENOSPC; + + chn = xmalloc_array(struct evtchn, EVTCHNS_PER_BUCKET); +@@ -517,12 +518,12 @@ void evtchn_set_pending(struct vcpu *v, + * others may require explicit memory barriers. + */ + +- if ( test_and_set_bit(port, s->evtchn_pending) ) ++ if ( test_and_set_bit(port, __shared_info_addr(d, s, evtchn_pending)) ) + return; + +- if ( !test_bit (port, s->evtchn_mask) && +- !test_and_set_bit(port / BITS_PER_LONG, +- &v->vcpu_info->evtchn_pending_sel) ) ++ if ( !test_bit (port, __shared_info_addr(d, s, evtchn_mask)) && ++ !test_and_set_bit(port / BITS_PER_GUEST_LONG(d), ++ vcpu_info_addr(v, evtchn_pending_sel)) ) + { + vcpu_mark_events_pending(v); + } +@@ -720,10 +721,10 @@ static long evtchn_unmask(evtchn_unmask_ + * These operations must happen in strict order. Based on + * include/xen/event.h:evtchn_set_pending(). + */ +- if ( test_and_clear_bit(port, s->evtchn_mask) && +- test_bit (port, s->evtchn_pending) && +- !test_and_set_bit (port / BITS_PER_LONG, +- &v->vcpu_info->evtchn_pending_sel) ) ++ if ( test_and_clear_bit(port, __shared_info_addr(d, s, evtchn_mask)) && ++ test_bit (port, __shared_info_addr(d, s, evtchn_pending)) && ++ !test_and_set_bit (port / BITS_PER_GUEST_LONG(d), ++ vcpu_info_addr(v, evtchn_pending_sel)) ) + { + vcpu_mark_events_pending(v); + } +Index: 2007-01-08/xen/common/kernel.c +=================================================================== +--- 2007-01-08.orig/xen/common/kernel.c 2007-01-08 15:17:29.000000000 +0100 ++++ 2007-01-08/xen/common/kernel.c 2007-01-08 15:19:11.000000000 +0100 +@@ -16,6 +16,9 @@ + #include + #include + #include ++#ifdef CONFIG_X86 ++#include ++#endif + + #ifndef COMPAT + +@@ -253,7 +256,7 @@ long register_guest_nmi_callback(unsigne + * If no handler was registered we can 'lose the NMI edge'. Re-assert it + * now. + */ +- if ( d->shared_info->arch.nmi_reason != 0 ) ++ if ( arch_get_nmi_reason(d) != 0 ) + set_bit(_VCPUF_nmi_pending, &v->vcpu_flags); + #endif + +Index: 2007-01-08/xen/common/keyhandler.c +=================================================================== +--- 2007-01-08.orig/xen/common/keyhandler.c 2007-01-08 15:34:16.000000000 +0100 ++++ 2007-01-08/xen/common/keyhandler.c 2007-01-08 15:19:11.000000000 +0100 +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -171,8 +172,8 @@ static void dump_domains(unsigned char k + v->vcpu_id, v->processor, + test_bit(_VCPUF_running, &v->vcpu_flags) ? 'T':'F', + v->vcpu_flags, +- v->vcpu_info->evtchn_upcall_pending, +- v->vcpu_info->evtchn_upcall_mask); ++ vcpu_info(v, evtchn_upcall_pending), ++ vcpu_info(v, evtchn_upcall_mask)); + cpuset_print(cpuset, sizeof(cpuset), v->vcpu_dirty_cpumask); + printk("dirty_cpus=%s ", cpuset); + cpuset_print(cpuset, sizeof(cpuset), v->cpu_affinity); +@@ -181,11 +182,11 @@ static void dump_domains(unsigned char k + printk(" Notifying guest (virq %d, port %d, stat %d/%d/%d)\n", + VIRQ_DEBUG, v->virq_to_evtchn[VIRQ_DEBUG], + test_bit(v->virq_to_evtchn[VIRQ_DEBUG], +- d->shared_info->evtchn_pending), ++ shared_info_addr(d, evtchn_pending)), + test_bit(v->virq_to_evtchn[VIRQ_DEBUG], +- d->shared_info->evtchn_mask), +- test_bit(v->virq_to_evtchn[VIRQ_DEBUG]/BITS_PER_LONG, +- &v->vcpu_info->evtchn_pending_sel)); ++ shared_info_addr(d, evtchn_mask)), ++ test_bit(v->virq_to_evtchn[VIRQ_DEBUG]/BITS_PER_GUEST_LONG(d), ++ vcpu_info_addr(v, evtchn_pending_sel))); + send_guest_vcpu_virq(v, VIRQ_DEBUG); + } + } +Index: 2007-01-08/xen/common/schedule.c +=================================================================== +--- 2007-01-08.orig/xen/common/schedule.c 2007-01-08 15:34:16.000000000 +0100 ++++ 2007-01-08/xen/common/schedule.c 2007-01-08 15:19:11.000000000 +0100 +@@ -277,10 +277,11 @@ static long do_block(void) + + static long do_poll(struct sched_poll *sched_poll) + { +- struct vcpu *v = current; +- evtchn_port_t port; +- long rc = 0; +- unsigned int i; ++ struct vcpu *v = current; ++ struct domain *d = v->domain; ++ evtchn_port_t port; ++ long rc = 0; ++ unsigned int i; + + /* Fairly arbitrary limit. */ + if ( sched_poll->nr_ports > 128 ) +@@ -292,7 +293,7 @@ static long do_poll(struct sched_poll *s + /* These operations must occur in order. */ + set_bit(_VCPUF_blocked, &v->vcpu_flags); + set_bit(_VCPUF_polling, &v->vcpu_flags); +- set_bit(_DOMF_polling, &v->domain->domain_flags); ++ set_bit(_DOMF_polling, &d->domain_flags); + + /* Check for events /after/ setting flags: avoids wakeup waiting race. */ + for ( i = 0; i < sched_poll->nr_ports; i++ ) +@@ -302,18 +303,18 @@ static long do_poll(struct sched_poll *s + goto out; + + rc = -EINVAL; +- if ( port >= MAX_EVTCHNS ) ++ if ( port >= MAX_EVTCHNS(d) ) + goto out; + + rc = 0; +- if ( test_bit(port, v->domain->shared_info->evtchn_pending) ) ++ if ( test_bit(port, shared_info_addr(d, evtchn_pending)) ) + goto out; + } + + if ( sched_poll->timeout != 0 ) + set_timer(&v->poll_timer, sched_poll->timeout); + +- TRACE_2D(TRC_SCHED_BLOCK, v->domain->domain_id, v->vcpu_id); ++ TRACE_2D(TRC_SCHED_BLOCK, d->domain_id, v->vcpu_id); + raise_softirq(SCHEDULE_SOFTIRQ); + + return 0; +Index: 2007-01-08/xen/include/Makefile +=================================================================== +--- 2007-01-08.orig/xen/include/Makefile 2007-01-08 15:18:58.000000000 +0100 ++++ 2007-01-08/xen/include/Makefile 2007-01-08 15:19:11.000000000 +0100 +@@ -32,6 +32,7 @@ compat/%.h: compat/%.i Makefile + sed -e 's,__InClUdE__,#include,' \ + -e 's,"xen-compat.h",,' \ + -e 's,\(struct\|union\|enum\)[[:space:]]\+\(xen_\?\)\?\([[:alpha:]_]\),\1 compat_\3,g' \ ++ -e 's,@KeeP@,,g' \ + -e 's,_t\([^[:alnum:]_]\|$$\),_compat_t\1,g' \ + -e 's,\(8\|16\|32\|64\)_compat_t\([^[:alnum:]_]\|$$\),\1_t\2,g' \ + -e 's,\(^\|[^[:alnum:]_]\)xen_\?\([[:alnum:]_]*\)_compat_t\([^[:alnum:]_]\|$$\),\1compat_\2_t\3,g' \ +@@ -46,13 +47,15 @@ compat/%.h: compat/%.i Makefile + compat/%.i: compat/%.c Makefile + $(CPP) $(CFLAGS) $(cppflags-y) -o $@ $< + +-compat/%.c: public/%.h Makefile ++compat/%.c: public/%.h xlat.lst Makefile + mkdir -p $(@D) + grep -v 'DEFINE_XEN_GUEST_HANDLE(long)' $< | \ + sed -e 's,^[[:space:]]*#[[:space:]]*include[[:space:]]\+,__InClUdE__ ,' \ + -e 's,^[[:space:]]*#[[:space:]]*define[[:space:]]\+\([[:upper:]_]*_GUEST_HANDLE\),#define HIDE_\1,' \ + -e 's,^[[:space:]]*#[[:space:]]*define[[:space:]]\+\([[:lower:]_]*_guest_handle\),#define hide_\1,' \ + -e 's,XEN_GUEST_HANDLE\(_[[:xdigit:]]\+\)\?,COMPAT_HANDLE,g' \ ++ $(foreach n,$(shell sed -n 's,^[[:space:]]*?[[:space:]]\+\([[:alnum:]_]*\)[[:space:]].*,\1,p' xlat.lst), \ ++ -e 's,\(struct\|union\)[[:space:]]\+\(xen_\?\)\?$n[[:space:]]\+\([[:alpha:]_]\),\1 @KeeP@\2$n \3,g') \ + >$@.new + mv -f $@.new $@ + +Index: 2007-01-08/xen/include/asm-ia64/shared.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-08/xen/include/asm-ia64/shared.h 2007-01-08 15:19:11.000000000 +0100 +@@ -0,0 +1,4 @@ ++#ifndef __XEN_ASM_SHARED_H__ ++#define __XEN_ASM_SHARED_H__ ++ ++#endif /* __XEN_ASM_SHARED_H__ */ +Index: 2007-01-08/xen/include/asm-powerpc/shared.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-08/xen/include/asm-powerpc/shared.h 2007-01-08 15:19:11.000000000 +0100 +@@ -0,0 +1,4 @@ ++#ifndef __XEN_ASM_SHARED_H__ ++#define __XEN_ASM_SHARED_H__ ++ ++#endif /* __XEN_ASM_SHARED_H__ */ +Index: 2007-01-08/xen/include/asm-x86/shared.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-08/xen/include/asm-x86/shared.h 2007-01-08 15:19:11.000000000 +0100 +@@ -0,0 +1,78 @@ ++#ifndef __XEN_X86_SHARED_H__ ++#define __XEN_X86_SHARED_H__ ++ ++#ifdef CONFIG_COMPAT ++ ++#define nmi_reason(d) (!IS_COMPAT(d) ? \ ++ (void *)&(d)->shared_info->native.arch.nmi_reason : \ ++ (void *)&(d)->shared_info->compat.arch.nmi_reason) ++ ++#define GET_SET_SHARED(type, field) \ ++static inline type arch_get_##field(const struct domain *d) \ ++{ \ ++ return !IS_COMPAT(d) ? \ ++ d->shared_info->native.arch.field : \ ++ d->shared_info->compat.arch.field; \ ++} \ ++static inline void arch_set_##field(struct domain *d, \ ++ type val) \ ++{ \ ++ if ( !IS_COMPAT(d) ) \ ++ d->shared_info->native.arch.field = val; \ ++ else \ ++ d->shared_info->compat.arch.field = val; \ ++} ++ ++#define GET_SET_VCPU(type, field) \ ++static inline type arch_get_##field(const struct vcpu *v) \ ++{ \ ++ return !IS_COMPAT(v->domain) ? \ ++ v->vcpu_info->native.arch.field : \ ++ v->vcpu_info->compat.arch.field; \ ++} \ ++static inline void arch_set_##field(struct vcpu *v, \ ++ type val) \ ++{ \ ++ if ( !IS_COMPAT(v->domain) ) \ ++ v->vcpu_info->native.arch.field = val; \ ++ else \ ++ v->vcpu_info->compat.arch.field = val; \ ++} ++ ++#else ++ ++#define nmi_reason(d) ((void *)&(d)->shared_info->arch.nmi_reason) ++ ++#define GET_SET_SHARED(type, field) \ ++static inline type arch_get_##field(const struct domain *d) \ ++{ \ ++ return d->shared_info->arch.field; \ ++} \ ++static inline void arch_set_##field(struct domain *d, \ ++ type val) \ ++{ \ ++ d->shared_info->arch.field = val; \ ++} ++ ++#define GET_SET_VCPU(type, field) \ ++static inline type arch_get_##field(const struct vcpu *v) \ ++{ \ ++ return v->vcpu_info->arch.field; \ ++} \ ++static inline void arch_set_##field(struct vcpu *v, \ ++ type val) \ ++{ \ ++ v->vcpu_info->arch.field = val; \ ++} ++#endif ++ ++GET_SET_SHARED(unsigned long, max_pfn) ++GET_SET_SHARED(xen_pfn_t, pfn_to_mfn_frame_list_list) ++GET_SET_SHARED(unsigned long, nmi_reason) ++ ++GET_SET_VCPU(unsigned long, cr2) ++ ++#undef GET_SET_VCPU ++#undef GET_SET_SHARED ++ ++#endif /* __XEN_X86_SHARED_H__ */ +Index: 2007-01-08/xen/include/asm-x86/compat.h +=================================================================== +--- 2007-01-08.orig/xen/include/asm-x86/compat.h 2007-01-08 15:17:29.000000000 +0100 ++++ 2007-01-08/xen/include/asm-x86/compat.h 2007-01-08 15:19:11.000000000 +0100 +@@ -2,5 +2,7 @@ + * compat.h + */ + ++#define COMPAT_BITS_PER_LONG 32 ++ + typedef uint32_t compat_ptr_t; + typedef unsigned long full_ptr_t; +Index: 2007-01-08/xen/include/asm-x86/event.h +=================================================================== +--- 2007-01-08.orig/xen/include/asm-x86/event.h 2007-01-08 15:34:16.000000000 +0100 ++++ 2007-01-08/xen/include/asm-x86/event.h 2007-01-08 15:19:11.000000000 +0100 +@@ -9,6 +9,8 @@ + #ifndef __ASM_EVENT_H__ + #define __ASM_EVENT_H__ + ++#include ++ + static inline void vcpu_kick(struct vcpu *v) + { + /* +@@ -28,7 +30,7 @@ static inline void vcpu_kick(struct vcpu + + static inline void vcpu_mark_events_pending(struct vcpu *v) + { +- if ( !test_and_set_bit(0, &v->vcpu_info->evtchn_upcall_pending) ) ++ if ( !test_and_set_bit(0, &vcpu_info(v, evtchn_upcall_pending)) ) + vcpu_kick(v); + } + +@@ -36,23 +38,23 @@ static inline int local_events_need_deli + { + struct vcpu *v = current; + /* Note: Bitwise operations result in fast code with no branches. */ +- return (!!v->vcpu_info->evtchn_upcall_pending & +- !v->vcpu_info->evtchn_upcall_mask); ++ return (!!vcpu_info(v, evtchn_upcall_pending) & ++ !vcpu_info(v, evtchn_upcall_mask)); + } + + static inline int local_event_delivery_is_enabled(void) + { +- return !current->vcpu_info->evtchn_upcall_mask; ++ return !vcpu_info(current, evtchn_upcall_mask); + } + + static inline void local_event_delivery_disable(void) + { +- current->vcpu_info->evtchn_upcall_mask = 1; ++ vcpu_info(current, evtchn_upcall_mask) = 1; + } + + static inline void local_event_delivery_enable(void) + { +- current->vcpu_info->evtchn_upcall_mask = 0; ++ vcpu_info(current, evtchn_upcall_mask) = 0; + } + + /* No arch specific virq definition now. Default to global. */ +Index: 2007-01-08/xen/include/public/xen.h +=================================================================== +--- 2007-01-08.orig/xen/include/public/xen.h 2007-01-08 15:34:16.000000000 +0100 ++++ 2007-01-08/xen/include/public/xen.h 2007-01-08 15:19:11.000000000 +0100 +@@ -408,7 +408,9 @@ struct vcpu_info { + struct arch_vcpu_info arch; + struct vcpu_time_info time; + }; /* 64 bytes (x86) */ ++#ifndef __XEN__ + typedef struct vcpu_info vcpu_info_t; ++#endif + + /* + * Xen/kernel shared data -- pointer provided in start_info. +@@ -466,7 +468,9 @@ struct shared_info { + struct arch_shared_info arch; + + }; ++#ifndef __XEN__ + typedef struct shared_info shared_info_t; ++#endif + + /* + * Start-of-day memory layout for the initial domain (DOM0): +Index: 2007-01-08/xen/include/xen/compat.h +=================================================================== +--- 2007-01-08.orig/xen/include/xen/compat.h 2007-01-08 15:17:29.000000000 +0100 ++++ 2007-01-08/xen/include/xen/compat.h 2007-01-08 15:19:11.000000000 +0100 +@@ -162,6 +162,12 @@ extern int compat_disabled; + struct start_info; + void xlat_start_info(struct start_info *, enum XLAT_start_info_console); + ++#define BITS_PER_GUEST_LONG(d) (!IS_COMPAT(d) ? BITS_PER_LONG : COMPAT_BITS_PER_LONG) ++ ++#else ++ ++#define BITS_PER_GUEST_LONG(d) BITS_PER_LONG ++ + #endif + + #endif /* __XEN_COMPAT_H__ */ +Index: 2007-01-08/xen/include/xen/sched.h +=================================================================== +--- 2007-01-08.orig/xen/include/xen/sched.h 2007-01-08 14:45:40.000000000 +0100 ++++ 2007-01-08/xen/include/xen/sched.h 2007-01-08 15:19:11.000000000 +0100 +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -23,9 +24,15 @@ extern rwlock_t domlist_lock; + /* A global pointer to the initial domain (DOM0). */ + extern struct domain *dom0; + +-#define MAX_EVTCHNS NR_EVENT_CHANNELS ++#ifndef CONFIG_COMPAT ++#define MAX_EVTCHNS(d) NR_EVENT_CHANNELS ++#else ++#define MAX_EVTCHNS(d) (!IS_COMPAT(d) ? \ ++ NR_EVENT_CHANNELS : \ ++ sizeof(unsigned int) * sizeof(unsigned int) * 64) ++#endif + #define EVTCHNS_PER_BUCKET 128 +-#define NR_EVTCHN_BUCKETS (MAX_EVTCHNS / EVTCHNS_PER_BUCKET) ++#define NR_EVTCHN_BUCKETS (NR_EVENT_CHANNELS / EVTCHNS_PER_BUCKET) + + struct evtchn + { +Index: 2007-01-08/xen/include/xen/shared.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-08/xen/include/xen/shared.h 2007-01-08 15:19:11.000000000 +0100 +@@ -0,0 +1,54 @@ ++#ifndef __XEN_SHARED_H__ ++#define __XEN_SHARED_H__ ++ ++#include ++ ++#ifdef CONFIG_COMPAT ++ ++#include ++ ++typedef union { ++ struct shared_info native; ++ struct compat_shared_info compat; ++} shared_info_t; ++ ++#define __shared_info(d, s, field) (*(!IS_COMPAT(d) ? \ ++ &(s)->native.field : \ ++ &(s)->compat.field)) ++#define __shared_info_addr(d, s, field) (!IS_COMPAT(d) ? \ ++ (void *)&(s)->native.field : \ ++ (void *)&(s)->compat.field) ++ ++#define shared_info(d, field) __shared_info(d, (d)->shared_info, field) ++#define shared_info_addr(d, field) __shared_info_addr(d, (d)->shared_info, field) ++ ++typedef union { ++ struct vcpu_info native; ++ struct compat_vcpu_info compat; ++} vcpu_info_t; ++ ++#define vcpu_info(v, field) (*(!IS_COMPAT((v)->domain) ? \ ++ &(v)->vcpu_info->native.field : \ ++ &(v)->vcpu_info->compat.field)) ++#define vcpu_info_addr(v, field) (!IS_COMPAT((v)->domain) ? \ ++ (void *)&(v)->vcpu_info->native.field : \ ++ (void *)&(v)->vcpu_info->compat.field) ++ ++#else ++ ++typedef struct shared_info shared_info_t; ++ ++#define __shared_info(d, s, field) ((s)->field) ++#define __shared_info_addr(d, s, field) ((void *)&(s)->field) ++ ++#define shared_info(d, field) ((d)->shared_info->field) ++#define shared_info_addr(d, field) ((void *)&(d)->shared_info->field) ++ ++typedef struct vcpu_info vcpu_info_t; ++ ++#define vcpu_info(v, field) ((v)->vcpu_info->field) ++#define vcpu_info_addr(v, field) ((void *)&(v)->vcpu_info->field) ++ ++#endif ++ ++#endif /* __XEN_SHARED_H__ */ +Index: 2007-01-08/xen/include/xlat.lst +=================================================================== +--- 2007-01-08.orig/xen/include/xlat.lst 2007-01-08 15:18:32.000000000 +0100 ++++ 2007-01-08/xen/include/xlat.lst 2007-01-08 15:19:11.000000000 +0100 +@@ -3,3 +3,4 @@ + # ? - needs checking + ? dom0_vga_console_info xen.h + ! start_info xen.h ++? vcpu_time_info xen.h diff --git a/32on64-startup.patch b/32on64-startup.patch new file mode 100644 index 0000000..737ce0c --- /dev/null +++ b/32on64-startup.patch @@ -0,0 +1,584 @@ +Handle the creation of startup info for compatibility mode guests. This +includes a script to auto-generate checking or translation code between +native and compatibility mode hypercall argument structures. + +Index: 2007-01-08/Config.mk +=================================================================== +--- 2007-01-08.orig/Config.mk 2007-01-08 15:34:16.000000000 +0100 ++++ 2007-01-08/Config.mk 2007-01-08 15:18:32.000000000 +0100 +@@ -11,6 +11,8 @@ XEN_OS ?= $(shell uname -s) + + CONFIG_$(XEN_OS) := y + ++SHELL ?= /bin/sh ++ + # Tools to run on system hosting the build + HOSTCC = gcc + HOSTCFLAGS = -Wall -Werror -Wstrict-prototypes -O2 -fomit-frame-pointer +Index: 2007-01-08/xen/arch/x86/domain_build.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/domain_build.c 2007-01-08 15:34:55.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/domain_build.c 2007-01-08 15:35:20.000000000 +0100 +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -848,6 +849,11 @@ int construct_dom0(struct domain *d, + si->console.dom0.info_size = sizeof(struct dom0_vga_console_info); + } + ++#ifdef CONFIG_COMPAT ++ if ( IS_COMPAT(d) ) ++ xlat_start_info(si, XLAT_start_info_console_dom0); ++#endif ++ + /* Reinstate the caller's page tables. */ + write_ptbase(current); + local_irq_enable(); +Index: 2007-01-08/xen/arch/x86/setup.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/setup.c 2007-01-08 14:45:40.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/setup.c 2007-01-08 15:18:32.000000000 +0100 +@@ -18,6 +18,10 @@ + #include + #include + #include ++#ifdef CONFIG_COMPAT ++#include ++#include ++#endif + #include + #include + #include +@@ -546,6 +550,14 @@ void __init __start_xen(multiboot_info_t + BUILD_BUG_ON(sizeof(shared_info_t) > PAGE_SIZE); + BUILD_BUG_ON(sizeof(vcpu_info_t) != 64); + ++#ifdef CONFIG_COMPAT ++ BUILD_BUG_ON(sizeof(((struct compat_platform_op *)0)->u) != ++ sizeof(((struct compat_platform_op *)0)->u.pad)); ++ BUILD_BUG_ON(sizeof(start_info_compat_t) > PAGE_SIZE); ++ BUILD_BUG_ON(sizeof(shared_info_compat_t) > PAGE_SIZE); ++ BUILD_BUG_ON(sizeof(vcpu_info_compat_t) != 64); ++#endif ++ + /* Check definitions in public headers match internal defs. */ + BUILD_BUG_ON(__HYPERVISOR_VIRT_START != HYPERVISOR_VIRT_START); + #ifdef HYPERVISOR_VIRT_END +Index: 2007-01-08/xen/common/compat/Makefile +=================================================================== +--- 2007-01-08.orig/xen/common/compat/Makefile 2007-01-08 15:17:29.000000000 +0100 ++++ 2007-01-08/xen/common/compat/Makefile 2007-01-08 15:18:32.000000000 +0100 +@@ -1,4 +1,5 @@ + obj-y += kernel.o ++obj-y += xlat.o + + # extra dependencies + kernel.o: ../kernel.c +Index: 2007-01-08/xen/common/compat/xlat.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-08/xen/common/compat/xlat.c 2007-01-08 15:18:32.000000000 +0100 +@@ -0,0 +1,32 @@ ++/****************************************************************************** ++ * xlat.c ++ */ ++ ++#include ++#include ++#include ++#include ++ ++/* In-place translation functons: */ ++void xlat_start_info(struct start_info *native, ++ enum XLAT_start_info_console console) ++{ ++ struct compat_start_info *compat = (void *)native; ++ ++ BUILD_BUG_ON(sizeof(*native) < sizeof(*compat)); ++ XLAT_start_info(compat, native); ++} ++ ++#define xen_dom0_vga_console_info dom0_vga_console_info ++CHECK_dom0_vga_console_info; ++#undef dom0_vga_console_info ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * tab-width: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ +Index: 2007-01-08/xen/include/Makefile +=================================================================== +--- 2007-01-08.orig/xen/include/Makefile 2007-01-08 15:18:26.000000000 +0100 ++++ 2007-01-08/xen/include/Makefile 2007-01-08 15:18:58.000000000 +0100 +@@ -5,7 +5,7 @@ compat-arch-$(CONFIG_X86) := x86 + + headers-y := $(shell echo public/*.h | sed -e 's,[^[:space:]]*-[^[:space:]]*,,g' -e 's,public/,compat/,g') + headers-y := $(filter-out %/dom0_ops.h,$(headers-y)) +-headers-y += compat/arch-$(compat-subarch-y).h ++headers-y += compat/arch-$(compat-subarch-y).h compat/xlat.h + headers-y += compat/arch-$(compat-arch-y)/xen.h + headers-y += compat/arch-$(compat-arch-y)/xen-$(compat-subarch-y).h + +@@ -56,5 +56,12 @@ compat/%.c: public/%.h Makefile + >$@.new + mv -f $@.new $@ + ++compat/xlat.h: xlat.lst $(filter-out compat/xlat.h,$(headers-y)) $(BASEDIR)/tools/get-fields.sh Makefile ++ grep -v '^[[:space:]]*#' xlat.lst | \ ++ while read what name hdr; do \ ++ $(SHELL) $(BASEDIR)/tools/get-fields.sh "$$what" compat_$$name $$(echo compat/$$hdr | sed -e 's,@arch@,$(compat-arch-y),g' -e 's,@subarch@,$(compat-subarch-y),g') || exit $$?; \ ++ done >$@.new ++ mv -f $@.new $@ ++ + clean:: + rm -rf compat +Index: 2007-01-08/xen/include/xlat.lst +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-08/xen/include/xlat.lst 2007-01-08 15:18:32.000000000 +0100 +@@ -0,0 +1,5 @@ ++# First column indicator: ++# ! - needs translation ++# ? - needs checking ++? dom0_vga_console_info xen.h ++! start_info xen.h +Index: 2007-01-08/xen/tools/get-fields.sh +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-08/xen/tools/get-fields.sh 2007-01-08 15:18:32.000000000 +0100 +@@ -0,0 +1,425 @@ ++#!/bin/sh ++test -n "$1" -a -n "$2" -a -n "$3" ++set -ef ++ ++get_fields() { ++ local level=1 aggr=0 name= fields= ++ for token in $2 ++ do ++ case "$token" in ++ struct|union) ++ test $level != 1 || aggr=1 fields= name= ++ ;; ++ "{") ++ level=$(expr $level + 1) ++ ;; ++ "}") ++ level=$(expr $level - 1) ++ if [ $level = 1 -a $name = $1 ] ++ then ++ echo "$fields }" ++ return 0 ++ fi ++ ;; ++ [[:alpha:]_]*) ++ test $aggr = 0 -o -n "$name" || name="$token" ++ ;; ++ esac ++ test $aggr = 0 || fields="$fields $token" ++ done ++} ++ ++build_enums() { ++ local level=1 kind= fields= members= named= id= token ++ for token in $2 ++ do ++ case "$token" in ++ struct|union) ++ test $level != 2 || fields=" " ++ kind="$token;$kind" ++ ;; ++ "{") ++ level=$(expr $level + 1) ++ ;; ++ "}") ++ level=$(expr $level - 1) ++ if [ $level = 1 ] ++ then ++ if [ "${kind%%;*}" = union ] ++ then ++ echo ++ echo "enum XLAT_$1 {" ++ for m in $members ++ do ++ echo " XLAT_${1}_$m," ++ done ++ echo "};" ++ fi ++ return 0 ++ elif [ $level = 2 ] ++ then ++ named='?' ++ fi ++ ;; ++ [[:alpha:]]*) ++ id=$token ++ if [ -n "$named" -a -n "${kind#*;}" ] ++ then ++ build_enums ${1}_$token "$fields" ++ named='!' ++ fi ++ ;; ++ ",") ++ test $level != 2 || members="$members $id" ++ ;; ++ ";") ++ test $level != 2 || members="$members $id" ++ test -z "$named" || kind=${kind#*;} ++ named= ++ ;; ++ esac ++ test -z "$fields" || fields="$fields $token" ++ done ++} ++ ++handle_field() { ++ if [ -z "$5" ] ++ then ++ echo " \\" ++ if [ -z "$4" ] ++ then ++ echo -n "$1(_d_)->$3 = (_s_)->$3;" ++ else ++ echo -n "$1XLAT_${2}_HNDL_$(echo $3 | sed 's,\.,_,g')(_d_, _s_);" ++ fi ++ elif [ -z "$(echo "$5" | sed 's,[^{}],,g')" ] ++ then ++ local tag=$(echo "$5" | sed 's,[[:space:]]*\(struct\|union\)[[:space:]]\+\(compat_\)\?\([[:alnum:]_]\+\)[[:space:]].*,\3,') ++ echo " \\" ++ echo -n "${1}XLAT_$tag(&(_d_)->$3, &(_s_)->$3);" ++ else ++ local level=1 kind= fields= id= array= arrlvl=1 array_type= type= token ++ for token in $5 ++ do ++ case "$token" in ++ struct|union) ++ test $level != 2 || fields=" " ++ if [ $level == 1 ] ++ then ++ kind=$token ++ if [ $kind = union ] ++ then ++ echo " \\" ++ echo -n "${1}switch ($(echo $3 | sed 's,\.,_,g')) {" ++ fi ++ fi ++ ;; ++ "{") ++ level=$(expr $level + 1) id= ++ ;; ++ "}") ++ level=$(expr $level - 1) id= ++ if [ $level == 1 -a $kind = union ] ++ then ++ echo " \\" ++ echo -n "$1}" ++ fi ++ ;; ++ "[") ++ if [ $level != 2 -o $arrlvl != 1 ] ++ then ++ : ++ elif [ -z "$array" ] ++ then ++ array=" " ++ else ++ array="$array;" ++ fi ++ arrlvl=$(expr $arrlvl + 1) ++ ;; ++ "]") ++ arrlvl=$(expr $arrlvl - 1) ++ ;; ++ COMPAT_HANDLE\(*\)) ++ if [ $level == 2 -a -z "$id" ] ++ then ++ type=${token#COMPAT_HANDLE?} ++ type=${type%?} ++ type=${type#compat_} ++ fi ++ ;; ++ compat_domain_handle_t) ++ if [ $level == 2 -a -z "$id" ] ++ then ++ array_type=$token ++ fi ++ ;; ++ [[:alpha:]]*) ++ id=$token ++ ;; ++ [\,\;]) ++ if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ] ++ then ++ if [ $kind = union ] ++ then ++ echo " \\" ++ echo -n "${1}case XLAT_${2}_$(echo $3.$id | sed 's,\.,_,g'):" ++ handle_field "$1 " $2 $3.$id "$type" "$fields" ++ elif [ -z "$array" -a -z "$array_type" ] ++ then ++ handle_field "$1" $2 $3.$id "$type" "$fields" ++ elif [ -z "$array" ] ++ then ++ copy_array " " $3.$id ++ else ++ handle_array "$1" $2 $3.$id "${array#*;}" "$type" "$fields" ++ fi ++ test "$token" != ";" || fields= id= type= ++ array= ++ if [ $kind = union ] ++ then ++ echo " \\" ++ echo -n "$1 break;" ++ fi ++ fi ++ ;; ++ *) ++ if [ -n "$array" ] ++ then ++ array="$array $token" ++ fi ++ ;; ++ esac ++ test -z "$fields" || fields="$fields $token" ++ done ++ fi ++} ++ ++copy_array() { ++ echo " \\" ++ echo "${1}if ((_d_)->$2 != (_s_)->$2) \\" ++ echo -n "$1 memcpy((_d_)->$2, (_s_)->$2, sizeof((_d_)->$2));" ++} ++ ++handle_array() { ++ local i="i$(echo $4 | sed 's,[^;], ,g' | wc -w)" ++ echo " \\" ++ echo "$1{ \\" ++ echo "$1 unsigned int $i; \\" ++ echo -n "$1 for ($i = 0; $i < "${4%%;*}"; ++$i) {" ++ if [ "$4" = "${4#*;}" ] ++ then ++ handle_field "$1 " $2 $3[$i] "$5" "$6" ++ else ++ handle_array "$1 " $2 $3[$i] "${4#*;}" "$5" "$6" ++ fi ++ echo " \\" ++ echo "$1 } \\" ++ echo -n "$1}" ++} ++ ++build_body() { ++ echo ++ echo -n "#define XLAT_$1(_d_, _s_)" ++ local level=1 fields= id= array= arrlvl=1 array_type= type= token ++ for token in $2 ++ do ++ case "$token" in ++ struct|union) ++ test $level != 2 || fields=" " ++ ;; ++ "{") ++ level=$(expr $level + 1) id= ++ ;; ++ "}") ++ level=$(expr $level - 1) id= ++ ;; ++ "[") ++ if [ $level != 2 -o $arrlvl != 1 ] ++ then ++ : ++ elif [ -z "$array" ] ++ then ++ array=" " ++ else ++ array="$array;" ++ fi ++ arrlvl=$(expr $arrlvl + 1) ++ ;; ++ "]") ++ arrlvl=$(expr $arrlvl - 1) ++ ;; ++ COMPAT_HANDLE\(*\)) ++ if [ $level == 2 -a -z "$id" ] ++ then ++ type=${token#COMPAT_HANDLE?} ++ type=${type%?} ++ type=${type#compat_} ++ fi ++ ;; ++ compat_domain_handle_t) ++ if [ $level == 2 -a -z "$id" ] ++ then ++ array_type=$token ++ fi ++ ;; ++ [[:alpha:]_]*) ++ if [ -n "$array" ] ++ then ++ array="$array $token" ++ else ++ id=$token ++ fi ++ ;; ++ [\,\;]) ++ if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ] ++ then ++ if [ -z "$array" -a -z "$array_type" ] ++ then ++ handle_field " " $1 $id "$type" "$fields" ++ elif [ -z "$array" ] ++ then ++ copy_array " " $id ++ else ++ handle_array " " $1 $id "${array#*;}" "$type" "$fields" ++ fi ++ test "$token" != ";" || fields= id= type= ++ array= ++ fi ++ ;; ++ *) ++ if [ -n "$array" ] ++ then ++ array="$array $token" ++ fi ++ ;; ++ esac ++ test -z "$fields" || fields="$fields $token" ++ done ++ echo "" ++} ++ ++check_field() { ++ if [ -z "$(echo "$4" | sed 's,[^{}],,g')" ] ++ then ++ echo "; \\" ++ local n=$(echo $3 | sed 's,[^.], ,g' | wc -w) ++ if [ -n "$4" ] ++ then ++ for n in $4 ++ do ++ case $n in ++ struct|union) ++ ;; ++ [[:alpha:]_]*) ++ echo -n " CHECK_$n" ++ break ++ ;; ++ *) ++ echo "Malformed compound declaration: '$n'" >&2 ++ exit 1 ++ ;; ++ esac ++ done ++ elif [ $n = 0 ] ++ then ++ echo -n " CHECK_FIELD_($1, $2, $3)" ++ else ++ echo -n " CHECK_SUBFIELD_${n}_($1, $2, $(echo $3 | sed 's!\.!, !g'))" ++ fi ++ else ++ local level=1 fields= id= token ++ for token in $4 ++ do ++ case "$token" in ++ struct|union) ++ test $level != 2 || fields=" " ++ ;; ++ "{") ++ level=$(expr $level + 1) id= ++ ;; ++ "}") ++ level=$(expr $level - 1) id= ++ ;; ++ [[:alpha:]]*) ++ id=$token ++ ;; ++ [\,\;]) ++ if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ] ++ then ++ check_field $1 $2 $3.$id "$fields" ++ test "$token" != ";" || fields= id= ++ fi ++ ;; ++ esac ++ test -z "$fields" || fields="$fields $token" ++ done ++ fi ++} ++ ++build_check() { ++ echo ++ echo "#define CHECK_$1 \\" ++ local level=1 fields= kind= id= arrlvl=1 token ++ for token in $2 ++ do ++ case "$token" in ++ struct|union) ++ if [ $level == 1 ] ++ then ++ kind=$token ++ echo -n " CHECK_SIZE_($kind, $1)" ++ elif [ $level == 2 ] ++ then ++ fields=" " ++ fi ++ ;; ++ "{") ++ level=$(expr $level + 1) id= ++ ;; ++ "}") ++ level=$(expr $level - 1) id= ++ ;; ++ "[") ++ arrlvl=$(expr $arrlvl + 1) ++ ;; ++ "]") ++ arrlvl=$(expr $arrlvl - 1) ++ ;; ++ [[:alpha:]_]*) ++ test $level != 2 -o $arrlvl != 1 || id=$token ++ ;; ++ [\,\;]) ++ if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ] ++ then ++ check_field $kind $1 $id "$fields" ++ test "$token" != ";" || fields= id= ++ fi ++ ;; ++ esac ++ test -z "$fields" || fields="$fields $token" ++ done ++ echo "" ++} ++ ++fields="$(get_fields $(echo $2 | sed 's,^compat_xen,compat_,') "$(sed -e 's,^[[:space:]]#.*,,' -e 's!\([]\[,;:{}]\)! \1 !g' $3)")" ++if [ -z "$fields" ] ++then ++ echo "Fields of '$2' not found in '$3'" >&2 ++ exit 1 ++fi ++name=${2#compat_} ++name=${name#xen} ++case "$1" in ++"!") ++ build_enums $name "$fields" ++ build_body $name "$fields" ++ ;; ++"?") ++ build_check $name "$fields" ++ ;; ++*) ++ echo "Invalid translation indicator: '$1'" >&2 ++ exit 1 ++ ;; ++esac diff --git a/32on64-sysctl.patch b/32on64-sysctl.patch new file mode 100644 index 0000000..9a962f0 --- /dev/null +++ b/32on64-sysctl.patch @@ -0,0 +1,312 @@ +Enable compatibility mode operation for HYPERVISOR_sysctl. + +Index: 2007-01-08/xen/arch/x86/sysctl.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/sysctl.c 2007-01-08 15:04:23.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/sysctl.c 2007-01-08 15:20:32.000000000 +0100 +@@ -25,10 +25,14 @@ + #include + #include + +-long arch_do_sysctl( ++#ifndef COMPAT ++typedef long ret_t; ++#endif ++ ++ret_t arch_do_sysctl( + struct xen_sysctl *sysctl, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl) + { +- long ret = 0; ++ ret_t ret = 0; + + switch ( sysctl->cmd ) + { +Index: 2007-01-08/xen/arch/x86/x86_64/Makefile +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_64/Makefile 2007-01-08 15:20:00.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_64/Makefile 2007-01-08 15:20:32.000000000 +0100 +@@ -7,6 +7,7 @@ obj-$(CONFIG_COMPAT) += compat.o + obj-$(CONFIG_COMPAT) += domain.o + obj-$(CONFIG_COMPAT) += physdev.o + obj-$(CONFIG_COMPAT) += platform_hypercall.o ++obj-$(CONFIG_COMPAT) += sysctl.o + + ifeq ($(CONFIG_COMPAT),y) + # extra dependencies +@@ -15,5 +16,6 @@ entry.o: compat/entry.S + mm.o: compat/mm.c + physdev.o: ../physdev.c + platform_hypercall.o: ../platform_hypercall.c ++sysctl.o: ../sysctl.c + traps.o: compat/traps.c + endif +Index: 2007-01-08/xen/arch/x86/x86_64/compat/entry.S +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:20:29.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:20:32.000000000 +0100 +@@ -278,7 +278,6 @@ CFIX14: + + .section .rodata, "a", @progbits + +-#define compat_sysctl domain_crash_synchronous + #define compat_domctl domain_crash_synchronous + + ENTRY(compat_hypercall_table) +Index: 2007-01-08/xen/arch/x86/x86_64/sysctl.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-08/xen/arch/x86/x86_64/sysctl.c 2007-01-08 15:20:32.000000000 +0100 +@@ -0,0 +1,33 @@ ++/****************************************************************************** ++ * Arch-specific compatibility sysctl.c ++ */ ++ ++#include ++#include ++ ++DEFINE_XEN_GUEST_HANDLE(compat_sysctl_t); ++#define xen_sysctl compat_sysctl ++#define xen_sysctl_t compat_sysctl_t ++#define arch_do_sysctl(x, h) arch_compat_sysctl(x, _##h) ++ ++#define xen_sysctl_physinfo compat_sysctl_physinfo ++#define xen_sysctl_physinfo_t compat_sysctl_physinfo_t ++ ++#define xen_sysctl_ioport_emulation compat_sysctl_ioport_emulation ++#define xen_sysctl_ioport_emulation_t compat_sysctl_ioport_emulation_t ++ ++#define COMPAT ++#define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t) ++typedef int ret_t; ++ ++#include "../sysctl.c" ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * tab-width: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ +Index: 2007-01-08/xen/common/compat/Makefile +=================================================================== +--- 2007-01-08.orig/xen/common/compat/Makefile 2007-01-08 15:19:20.000000000 +0100 ++++ 2007-01-08/xen/common/compat/Makefile 2007-01-08 15:20:32.000000000 +0100 +@@ -2,8 +2,10 @@ obj-y += domain.o + obj-y += kernel.o + obj-y += memory.o + obj-y += multicall.o ++obj-y += sysctl.o + obj-y += xlat.o + + # extra dependencies + kernel.o: ../kernel.c + multicall.o: ../multicall.c ++sysctl.o: ../sysctl.c +Index: 2007-01-08/xen/common/compat/sysctl.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-08/xen/common/compat/sysctl.c 2007-01-08 15:20:32.000000000 +0100 +@@ -0,0 +1,102 @@ ++/****************************************************************************** ++ * compat/sysctl.c ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++DEFINE_XEN_GUEST_HANDLE(compat_sysctl_t); ++#define xen_sysctl compat_sysctl ++#define xen_sysctl_t compat_sysctl_t ++#define do_sysctl(h) compat_sysctl(_##h) ++#define arch_do_sysctl(x, h) arch_compat_sysctl(x, _##h) ++ ++#define xen_sysctl_readconsole compat_sysctl_readconsole ++#define xen_sysctl_readconsole_t compat_sysctl_readconsole_t ++ ++static int compat_tb_control(struct compat_sysctl_tbuf_op *cmp_tbc) ++{ ++ struct xen_sysctl_tbuf_op nat_tbc; ++ int ret; ++ ++#define XLAT_ctl_cpumap_HNDL_bitmap(_d_, _s_) \ ++ guest_from_compat_handle((_d_)->bitmap, (_s_)->bitmap) ++ XLAT_sysctl_tbuf_op(&nat_tbc, cmp_tbc); ++#undef XLAT_ctl_cpumap_HNDL_bitmap ++ ret = tb_control(&nat_tbc); ++#define XLAT_ctl_cpumap_HNDL_bitmap(_d_, _s_) ((void)0) ++ XLAT_sysctl_tbuf_op(cmp_tbc, &nat_tbc); ++#undef XLAT_ctl_cpumap_HNDL_bitmap ++ return ret; ++} ++#define xen_sysctl_tbuf_op compat_sysctl_tbuf_op ++#define xen_sysctl_tbuf_op_t compat_sysctl_tbuf_op_t ++#define tb_control(p) compat_tb_control(p) ++ ++#define xen_sysctl_sched_id compat_sysctl_sched_id ++#define xen_sysctl_sched_id_t compat_sysctl_sched_id_t ++ ++static void compat_getdomaininfo(struct domain *d, struct compat_domctl_getdomaininfo *ci) ++{ ++ struct xen_domctl_getdomaininfo ni; ++ ++ getdomaininfo(d, &ni); ++ XLAT_domctl_getdomaininfo(ci, &ni); ++} ++#define xen_sysctl_getdomaininfolist compat_sysctl_getdomaininfolist ++#define xen_sysctl_getdomaininfolist_t compat_sysctl_getdomaininfolist_t ++#define xen_domctl_getdomaininfo compat_domctl_getdomaininfo ++#define xen_domctl_getdomaininfo_t compat_domctl_getdomaininfo_t ++#define getdomaininfo(d, i) compat_getdomaininfo(d, i) ++ ++#ifdef PERF_COUNTERS ++static int compat_perfc_control(struct compat_sysctl_perfc_op *cmp_pc) ++{ ++ CHECK_sysctl_perfc_desc; ++ CHECK_TYPE(sysctl_perfc_val); ++ struct xen_sysctl_perfc_op nat_pc; ++ int ret; ++ ++#define XLAT_sysctl_perfc_op_HNDL_desc(_d_, _s_) \ ++ guest_from_compat_handle((_d_)->desc, (_s_)->desc) ++#define XLAT_sysctl_perfc_op_HNDL_val(_d_, _s_) \ ++ guest_from_compat_handle((_d_)->val, (_s_)->val) ++ XLAT_sysctl_perfc_op(&nat_pc, cmp_pc); ++#undef XLAT_sysctl_perfc_op_HNDL_val ++#undef XLAT_sysctl_perfc_op_HNDL_desc ++ ret = perfc_control(&nat_pc); ++#define XLAT_sysctl_perfc_op_HNDL_desc(_d_, _s_) ++#define XLAT_sysctl_perfc_op_HNDL_val(_d_, _s_) ++ XLAT_sysctl_perfc_op(cmp_pc, &nat_pc); ++#undef XLAT_sysctl_perfc_op_HNDL_val ++#undef XLAT_sysctl_perfc_op_HNDL_desc ++ return ret; ++} ++#define xen_sysctl_perfc_op compat_sysctl_perfc_op ++#define xen_sysctl_perfc_op_t compat_sysctl_perfc_op_t ++#define perfc_control(p) compat_perfc_control(p) ++#endif ++ ++#define COMPAT ++#define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t) ++#define _u_sysctl u_sysctl ++#undef guest_handle_cast ++#define guest_handle_cast compat_handle_cast ++#define copy_to_xxx_offset copy_to_compat_offset ++typedef int ret_t; ++ ++#include "../sysctl.c" ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * tab-width: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ +Index: 2007-01-08/xen/common/sysctl.c +=================================================================== +--- 2007-01-08.orig/xen/common/sysctl.c 2007-01-08 15:04:23.000000000 +0100 ++++ 2007-01-08/xen/common/sysctl.c 2007-01-08 15:20:32.000000000 +0100 +@@ -21,14 +21,17 @@ + #include + #include + +-extern long arch_do_sysctl( ++#ifndef COMPAT ++typedef long ret_t; ++#define copy_to_xxx_offset copy_to_guest_offset ++#endif ++ ++extern ret_t arch_do_sysctl( + struct xen_sysctl *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl); +-extern void getdomaininfo( +- struct domain *d, struct xen_domctl_getdomaininfo *info); + +-long do_sysctl(XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl) ++ret_t do_sysctl(XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl) + { +- long ret = 0; ++ ret_t ret = 0; + struct xen_sysctl curop, *op = &curop; + static DEFINE_SPINLOCK(sysctl_lock); + +@@ -98,8 +101,8 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc + + put_domain(d); + +- if ( copy_to_guest_offset(op->u.getdomaininfolist.buffer, +- num_domains, &info, 1) ) ++ if ( copy_to_xxx_offset(op->u.getdomaininfolist.buffer, ++ num_domains, &info, 1) ) + { + ret = -EFAULT; + break; +@@ -123,7 +126,6 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc + #ifdef PERF_COUNTERS + case XEN_SYSCTL_perfc_op: + { +- extern int perfc_control(xen_sysctl_perfc_op_t *); + ret = perfc_control(&op->u.perfc_op); + if ( copy_to_guest(u_sysctl, op, 1) ) + ret = -EFAULT; +Index: 2007-01-08/xen/include/xen/domain.h +=================================================================== +--- 2007-01-08.orig/xen/include/xen/domain.h 2007-01-08 15:04:23.000000000 +0100 ++++ 2007-01-08/xen/include/xen/domain.h 2007-01-08 15:20:32.000000000 +0100 +@@ -11,6 +11,10 @@ struct vcpu *alloc_idle_vcpu(unsigned in + struct domain *alloc_domain(domid_t domid); + void free_domain(struct domain *d); + ++struct xen_domctl_getdomaininfo; ++void getdomaininfo( ++ struct domain *d, struct xen_domctl_getdomaininfo *info); ++ + /* + * Arch-specifics. + */ +Index: 2007-01-08/xen/include/xen/perfc.h +=================================================================== +--- 2007-01-08.orig/xen/include/xen/perfc.h 2007-01-08 15:04:23.000000000 +0100 ++++ 2007-01-08/xen/include/xen/perfc.h 2007-01-08 15:20:32.000000000 +0100 +@@ -102,6 +102,9 @@ extern struct perfcounter perfcounters; + #else + #define perfc_incr_histo(_x,_v,_n) ((void)0) + #endif ++ ++struct xen_sysctl_perfc_op; ++int perfc_control(struct xen_sysctl_perfc_op *); + + #else /* PERF_COUNTERS */ + +Index: 2007-01-08/xen/include/xlat.lst +=================================================================== +--- 2007-01-08.orig/xen/include/xlat.lst 2007-01-08 15:20:29.000000000 +0100 ++++ 2007-01-08/xen/include/xlat.lst 2007-01-08 15:20:32.000000000 +0100 +@@ -10,6 +10,8 @@ + ! trap_info arch-@arch@/xen.h + ! vcpu_guest_context arch-@arch@/xen.h + ? acm_getdecision acm_ops.h ++! ctl_cpumap domctl.h ++! domctl_getdomaininfo domctl.h + ? evtchn_alloc_unbound event_channel.h + ? evtchn_bind_interdomain event_channel.h + ? evtchn_bind_ipi event_channel.h +@@ -37,6 +39,9 @@ + ! sched_poll sched.h + ? sched_remote_shutdown sched.h + ? sched_shutdown sched.h ++? sysctl_perfc_desc sysctl.h ++! sysctl_perfc_op sysctl.h ++! sysctl_tbuf_op sysctl.h + ! vcpu_runstate_info vcpu.h + ? xenoprof_init xenoprof.h + ? xenoprof_passive xenoprof.h diff --git a/32on64-trace.patch b/32on64-trace.patch new file mode 100644 index 0000000..921f0e4 --- /dev/null +++ b/32on64-trace.patch @@ -0,0 +1,142 @@ +Enable compatibility mode operation for trace buffer access. + +Index: 2006-12-11/xen/common/trace.c +=================================================================== +--- 2006-12-11.orig/xen/common/trace.c 2006-12-15 15:20:32.000000000 +0100 ++++ 2006-12-11/xen/common/trace.c 2006-12-15 15:39:01.000000000 +0100 +@@ -32,13 +32,29 @@ + #include + #include + ++#ifdef CONFIG_COMPAT ++#include ++#define xen_t_buf t_buf ++CHECK_t_buf; ++#undef xen_t_buf ++#define TB_COMPAT IS_COMPAT(dom0) ++#else ++#define compat_t_rec t_rec ++#define TB_COMPAT 0 ++#endif ++ ++typedef union { ++ struct t_rec *nat; ++ struct compat_t_rec *cmp; ++} t_rec_u; ++ + /* opt_tbuf_size: trace buffer size (in pages) */ + static unsigned int opt_tbuf_size = 0; + integer_param("tbuf_size", opt_tbuf_size); + + /* Pointers to the meta-data objects for all system trace buffers */ + static DEFINE_PER_CPU(struct t_buf *, t_bufs); +-static DEFINE_PER_CPU(struct t_rec *, t_recs); ++static DEFINE_PER_CPU(t_rec_u, t_recs); + static int nr_recs; + + /* High water mark for trace buffers; */ +@@ -87,7 +103,7 @@ static int alloc_trace_bufs(void) + nr_pages = num_online_cpus() * opt_tbuf_size; + order = get_order_from_pages(nr_pages); + nr_recs = (opt_tbuf_size * PAGE_SIZE - sizeof(struct t_buf)) / +- sizeof(struct t_rec); ++ (!TB_COMPAT ? sizeof(struct t_rec) : sizeof(struct compat_t_rec)); + + if ( (rawbuf = alloc_xenheap_pages(order)) == NULL ) + { +@@ -106,7 +122,7 @@ static int alloc_trace_bufs(void) + buf = per_cpu(t_bufs, i) = (struct t_buf *) + &rawbuf[i*opt_tbuf_size*PAGE_SIZE]; + buf->cons = buf->prod = 0; +- per_cpu(t_recs, i) = (struct t_rec *)(buf + 1); ++ per_cpu(t_recs, i).nat = (struct t_rec *)(buf + 1); + } + + t_buf_highwater = nr_recs >> 1; /* 50% high water */ +@@ -232,7 +248,7 @@ void trace(u32 event, unsigned long d1, + unsigned long d3, unsigned long d4, unsigned long d5) + { + struct t_buf *buf; +- struct t_rec *rec; ++ t_rec_u rec; + unsigned long flags; + + BUG_ON(!tb_init_done); +@@ -269,25 +285,51 @@ void trace(u32 event, unsigned long d1, + + if ( unlikely(this_cpu(lost_records) != 0) ) + { +- rec = &this_cpu(t_recs)[buf->prod % nr_recs]; +- memset(rec, 0, sizeof(*rec)); +- rec->cycles = (u64)get_cycles(); +- rec->event = TRC_LOST_RECORDS; +- rec->data[0] = this_cpu(lost_records); +- this_cpu(lost_records) = 0; ++ if ( !TB_COMPAT ) ++ { ++ rec.nat = &this_cpu(t_recs).nat[buf->prod % nr_recs]; ++ memset(rec.nat, 0, sizeof(*rec.nat)); ++ rec.nat->cycles = (u64)get_cycles(); ++ rec.nat->event = TRC_LOST_RECORDS; ++ rec.nat->data[0] = this_cpu(lost_records); ++ this_cpu(lost_records) = 0; ++ } ++ else ++ { ++ rec.cmp = &this_cpu(t_recs).cmp[buf->prod % nr_recs]; ++ memset(rec.cmp, 0, sizeof(*rec.cmp)); ++ rec.cmp->cycles = (u64)get_cycles(); ++ rec.cmp->event = TRC_LOST_RECORDS; ++ rec.cmp->data[0] = this_cpu(lost_records); ++ this_cpu(lost_records) = 0; ++ } + + wmb(); + buf->prod++; + } + +- rec = &this_cpu(t_recs)[buf->prod % nr_recs]; +- rec->cycles = (u64)get_cycles(); +- rec->event = event; +- rec->data[0] = d1; +- rec->data[1] = d2; +- rec->data[2] = d3; +- rec->data[3] = d4; +- rec->data[4] = d5; ++ if ( !TB_COMPAT ) ++ { ++ rec.nat = &this_cpu(t_recs).nat[buf->prod % nr_recs]; ++ rec.nat->cycles = (u64)get_cycles(); ++ rec.nat->event = event; ++ rec.nat->data[0] = d1; ++ rec.nat->data[1] = d2; ++ rec.nat->data[2] = d3; ++ rec.nat->data[3] = d4; ++ rec.nat->data[4] = d5; ++ } ++ else ++ { ++ rec.cmp = &this_cpu(t_recs).cmp[buf->prod % nr_recs]; ++ rec.cmp->cycles = (u64)get_cycles(); ++ rec.cmp->event = event; ++ rec.cmp->data[0] = d1; ++ rec.cmp->data[1] = d2; ++ rec.cmp->data[2] = d3; ++ rec.cmp->data[3] = d4; ++ rec.cmp->data[4] = d5; ++ } + + wmb(); + buf->prod++; +Index: 2006-12-11/xen/include/xlat.lst +=================================================================== +--- 2006-12-11.orig/xen/include/xlat.lst 2006-12-15 15:37:45.000000000 +0100 ++++ 2006-12-11/xen/include/xlat.lst 2006-12-15 15:39:01.000000000 +0100 +@@ -44,6 +44,7 @@ + ? sysctl_perfc_desc sysctl.h + ! sysctl_perfc_op sysctl.h + ! sysctl_tbuf_op sysctl.h ++? t_buf trace.h + ! vcpu_runstate_info vcpu.h + ? xenoprof_init xenoprof.h + ? xenoprof_passive xenoprof.h diff --git a/32on64-vcpuop.patch b/32on64-vcpuop.patch new file mode 100644 index 0000000..a1a610c --- /dev/null +++ b/32on64-vcpuop.patch @@ -0,0 +1,379 @@ +Enable compatibility mode operation for HYPERVISOR_vcpu_op. + +Index: 2007-01-08/xen/arch/x86/domain.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/domain.c 2007-01-08 15:07:36.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/domain.c 2007-01-08 15:07:40.000000000 +0100 +@@ -40,6 +40,9 @@ + #include + #include + #include ++#ifdef CONFIG_COMPAT ++#include ++#endif + + DEFINE_PER_CPU(struct vcpu *, curr_vcpu); + +@@ -572,16 +575,16 @@ arch_do_vcpu_op( + break; + + rc = 0; +- v->runstate_guest = area.addr.h; ++ runstate_guest(v) = area.addr.h; + + if ( v == current ) + { +- __copy_to_guest(v->runstate_guest, &v->runstate, 1); ++ __copy_to_guest(runstate_guest(v), &v->runstate, 1); + } + else + { + vcpu_runstate_get(v, &runstate); +- __copy_to_guest(v->runstate_guest, &runstate, 1); ++ __copy_to_guest(runstate_guest(v), &runstate, 1); + } + + break; +@@ -980,8 +983,20 @@ void context_switch(struct vcpu *prev, s + context_saved(prev); + + /* Update per-VCPU guest runstate shared memory area (if registered). */ +- if ( !guest_handle_is_null(next->runstate_guest) ) +- __copy_to_guest(next->runstate_guest, &next->runstate, 1); ++ if ( !guest_handle_is_null(runstate_guest(next)) ) ++ { ++ if ( !IS_COMPAT(next->domain) ) ++ __copy_to_guest(runstate_guest(next), &next->runstate, 1); ++#ifdef CONFIG_COMPAT ++ else ++ { ++ struct compat_vcpu_runstate_info info; ++ ++ XLAT_vcpu_runstate_info(&info, &next->runstate); ++ __copy_to_guest(next->runstate_guest.compat, &info, 1); ++ } ++#endif ++ } + + schedule_tail(next); + BUG(); +Index: 2007-01-08/xen/arch/x86/x86_64/Makefile +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_64/Makefile 2007-01-08 15:07:38.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_64/Makefile 2007-01-08 15:07:40.000000000 +0100 +@@ -4,6 +4,7 @@ obj-y += mm.o + obj-y += traps.o + + obj-$(CONFIG_COMPAT) += compat.o ++obj-$(CONFIG_COMPAT) += domain.o + obj-$(CONFIG_COMPAT) += physdev.o + + ifeq ($(CONFIG_COMPAT),y) +Index: 2007-01-08/xen/arch/x86/x86_64/compat/entry.S +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:07:38.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:07:40.000000000 +0100 +@@ -284,7 +284,6 @@ CFIX14: + #define compat_multicall domain_crash_synchronous + #define compat_set_timer_op domain_crash_synchronous + #define compat_grant_table_op domain_crash_synchronous +-#define compat_vcpu_op domain_crash_synchronous + #define compat_acm_op domain_crash_synchronous + #define compat_arch_sched_op domain_crash_synchronous + #define compat_xenoprof_op domain_crash_synchronous +Index: 2007-01-08/xen/arch/x86/x86_64/domain.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-08/xen/arch/x86/x86_64/domain.c 2007-01-08 15:07:40.000000000 +0100 +@@ -0,0 +1,68 @@ ++/****************************************************************************** ++ * arch/x86/x86_64/domain.c ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++int ++arch_compat_vcpu_op( ++ int cmd, struct vcpu *v, XEN_GUEST_HANDLE(void) arg) ++{ ++ long rc = 0; ++ ++ switch ( cmd ) ++ { ++ case VCPUOP_register_runstate_memory_area: ++ { ++ struct compat_vcpu_register_runstate_memory_area area; ++ struct compat_vcpu_runstate_info info; ++ ++ rc = -EFAULT; ++ if ( copy_from_guest(&area, arg, 1) ) ++ break; ++ ++ if ( area.addr.h.c != area.addr.p || ++ !compat_handle_okay(area.addr.h, 1) ) ++ break; ++ ++ rc = 0; ++ guest_from_compat_handle(v->runstate_guest.compat, area.addr.h); ++ ++ if ( v == current ) ++ { ++ XLAT_vcpu_runstate_info(&info, &v->runstate); ++ } ++ else ++ { ++ struct vcpu_runstate_info runstate; ++ ++ vcpu_runstate_get(v, &runstate); ++ XLAT_vcpu_runstate_info(&info, &v->runstate); ++ } ++ __copy_to_guest(v->runstate_guest.compat, &info, 1); ++ ++ break; ++ } ++ ++ default: ++ rc = -ENOSYS; ++ break; ++ } ++ ++ return rc; ++} ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * tab-width: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ +Index: 2007-01-08/xen/common/compat/Makefile +=================================================================== +--- 2007-01-08.orig/xen/common/compat/Makefile 2007-01-08 15:07:36.000000000 +0100 ++++ 2007-01-08/xen/common/compat/Makefile 2007-01-08 15:07:40.000000000 +0100 +@@ -1,3 +1,4 @@ ++obj-y += domain.o + obj-y += kernel.o + obj-y += memory.o + obj-y += xlat.o +Index: 2007-01-08/xen/common/compat/domain.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-08/xen/common/compat/domain.c 2007-01-08 15:07:40.000000000 +0100 +@@ -0,0 +1,102 @@ ++/****************************************************************************** ++ * domain.c ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++int compat_vcpu_op(int cmd, int vcpuid, XEN_GUEST_HANDLE(void) arg) ++{ ++ struct domain *d = current->domain; ++ struct vcpu *v; ++ long rc = 0; ++ ++ if ( (vcpuid < 0) || (vcpuid >= MAX_VIRT_CPUS) ) ++ return -EINVAL; ++ ++ if ( (v = d->vcpu[vcpuid]) == NULL ) ++ return -ENOENT; ++ ++ switch ( cmd ) ++ { ++ case VCPUOP_initialise: ++ { ++ struct compat_vcpu_guest_context *cmp_ctxt; ++ struct vcpu_guest_context *nat_ctxt; ++ ++ if ( (cmp_ctxt = xmalloc(struct compat_vcpu_guest_context)) == NULL ) ++ { ++ rc = -ENOMEM; ++ break; ++ } ++ ++ if ( copy_from_guest(cmp_ctxt, arg, 1) ) ++ { ++ xfree(cmp_ctxt); ++ rc = -EFAULT; ++ break; ++ } ++ ++ if ( (nat_ctxt = xmalloc(struct vcpu_guest_context)) == NULL ) ++ { ++ rc = -ENOMEM; ++ break; ++ } ++ ++ memset(nat_ctxt, 0, sizeof(*nat_ctxt)); ++ XLAT_vcpu_guest_context(nat_ctxt, cmp_ctxt); ++ xfree(cmp_ctxt); ++ ++ LOCK_BIGLOCK(d); ++ rc = -EEXIST; ++ if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) ) ++ rc = boot_vcpu(d, vcpuid, nat_ctxt); ++ UNLOCK_BIGLOCK(d); ++ ++ xfree(nat_ctxt); ++ break; ++ } ++ ++ case VCPUOP_up: ++ case VCPUOP_down: ++ case VCPUOP_is_up: ++ rc = do_vcpu_op(cmd, vcpuid, arg); ++ break; ++ ++ case VCPUOP_get_runstate_info: ++ { ++ union { ++ struct vcpu_runstate_info nat; ++ struct compat_vcpu_runstate_info cmp; ++ } runstate; ++ ++ vcpu_runstate_get(v, &runstate.nat); ++ xlat_vcpu_runstate_info(&runstate.nat); ++ if ( copy_to_guest(arg, &runstate.cmp, 1) ) ++ rc = -EFAULT; ++ break; ++ } ++ ++ default: ++ rc = arch_compat_vcpu_op(cmd, v, arg); ++ break; ++ } ++ ++ return rc; ++} ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * tab-width: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ +Index: 2007-01-08/xen/common/compat/xlat.c +=================================================================== +--- 2007-01-08.orig/xen/common/compat/xlat.c 2007-01-08 15:07:38.000000000 +0100 ++++ 2007-01-08/xen/common/compat/xlat.c 2007-01-08 15:07:40.000000000 +0100 +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + + /* In-place translation functons: */ + void xlat_start_info(struct start_info *native, +@@ -17,6 +18,14 @@ void xlat_start_info(struct start_info * + XLAT_start_info(compat, native); + } + ++void xlat_vcpu_runstate_info(struct vcpu_runstate_info *native) ++{ ++ struct compat_vcpu_runstate_info *compat = (void *)native; ++ ++ BUILD_BUG_ON(sizeof(*native) < sizeof(*compat)); ++ XLAT_vcpu_runstate_info(compat, native); ++} ++ + #define xen_dom0_vga_console_info dom0_vga_console_info + CHECK_dom0_vga_console_info; + #undef dom0_vga_console_info +Index: 2007-01-08/xen/include/asm-x86/hypercall.h +=================================================================== +--- 2007-01-08.orig/xen/include/asm-x86/hypercall.h 2007-01-08 15:07:38.000000000 +0100 ++++ 2007-01-08/xen/include/asm-x86/hypercall.h 2007-01-08 15:07:40.000000000 +0100 +@@ -130,6 +130,10 @@ compat_physdev_op( + int cmd, + XEN_GUEST_HANDLE(void) arg); + ++extern int ++arch_compat_vcpu_op( ++ int cmd, struct vcpu *v, XEN_GUEST_HANDLE(void) arg); ++ + #endif + + #endif /* __ASM_X86_HYPERCALL_H__ */ +Index: 2007-01-08/xen/include/xen/compat.h +=================================================================== +--- 2007-01-08.orig/xen/include/xen/compat.h 2007-01-08 15:07:36.000000000 +0100 ++++ 2007-01-08/xen/include/xen/compat.h 2007-01-08 15:07:40.000000000 +0100 +@@ -163,6 +163,8 @@ int hypercall_xlat_continuation(unsigned + /* In-place translation functons: */ + struct start_info; + void xlat_start_info(struct start_info *, enum XLAT_start_info_console); ++struct vcpu_runstate_info; ++void xlat_vcpu_runstate_info(struct vcpu_runstate_info *); + + #define BITS_PER_GUEST_LONG(d) (!IS_COMPAT(d) ? BITS_PER_LONG : COMPAT_BITS_PER_LONG) + +Index: 2007-01-08/xen/include/xen/sched.h +=================================================================== +--- 2007-01-08.orig/xen/include/xen/sched.h 2007-01-08 15:07:28.000000000 +0100 ++++ 2007-01-08/xen/include/xen/sched.h 2007-01-08 15:07:40.000000000 +0100 +@@ -18,6 +18,11 @@ + #include + #include + ++#ifdef CONFIG_COMPAT ++#include ++DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t); ++#endif ++ + extern unsigned long volatile jiffies; + extern rwlock_t domlist_lock; + +@@ -82,7 +87,16 @@ struct vcpu + void *sched_priv; /* scheduler-specific data */ + + struct vcpu_runstate_info runstate; ++#ifndef CONFIG_COMPAT ++# define runstate_guest(v) ((v)->runstate_guest) + XEN_GUEST_HANDLE(vcpu_runstate_info_t) runstate_guest; /* guest address */ ++#else ++# define runstate_guest(v) ((v)->runstate_guest.native) ++ union { ++ XEN_GUEST_HANDLE(vcpu_runstate_info_t) native; ++ XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t) compat; ++ } runstate_guest; /* guest address */ ++#endif + + unsigned long vcpu_flags; + +Index: 2007-01-08/xen/include/xlat.lst +=================================================================== +--- 2007-01-08.orig/xen/include/xlat.lst 2007-01-08 15:07:38.000000000 +0100 ++++ 2007-01-08/xen/include/xlat.lst 2007-01-08 15:08:28.000000000 +0100 +@@ -6,6 +6,9 @@ + ! mmuext_op xen.h + ! start_info xen.h + ? vcpu_time_info xen.h ++! cpu_user_regs arch-@arch@/xen-@subarch@.h ++! trap_info arch-@arch@/xen.h ++! vcpu_guest_context arch-@arch@/xen.h + ? evtchn_alloc_unbound event_channel.h + ? evtchn_bind_interdomain event_channel.h + ? evtchn_bind_ipi event_channel.h +@@ -23,3 +26,4 @@ + ! memory_map memory.h + ! memory_reservation memory.h + ! translate_gpfn_list memory.h ++! vcpu_runstate_info vcpu.h diff --git a/32on64-xenoprof.patch b/32on64-xenoprof.patch new file mode 100644 index 0000000..34bbaf9 --- /dev/null +++ b/32on64-xenoprof.patch @@ -0,0 +1,326 @@ +Enable compatibility mode operation for HYPERVISOR_xenoprof_op. + +Index: 2006-12-18/xen/arch/x86/x86_64/compat/entry.S +=================================================================== +--- 2006-12-18.orig/xen/arch/x86/x86_64/compat/entry.S 2006-12-18 09:50:05.000000000 +0100 ++++ 2006-12-18/xen/arch/x86/x86_64/compat/entry.S 2006-12-18 09:50:08.000000000 +0100 +@@ -278,7 +278,6 @@ CFIX14: + + .section .rodata, "a", @progbits + +-#define compat_xenoprof_op domain_crash_synchronous + #define compat_sysctl domain_crash_synchronous + #define compat_domctl domain_crash_synchronous + +Index: 2006-12-18/xen/include/public/xenoprof.h +=================================================================== +--- 2006-12-18.orig/xen/include/public/xenoprof.h 2006-12-15 16:33:59.000000000 +0100 ++++ 2006-12-18/xen/include/public/xenoprof.h 2006-12-18 09:50:08.000000000 +0100 +@@ -74,8 +74,10 @@ struct xenoprof_buf { + uint64_t lost_samples; + struct event_log event_log[1]; + }; ++#ifndef __XEN__ + typedef struct xenoprof_buf xenoprof_buf_t; + DEFINE_XEN_GUEST_HANDLE(xenoprof_buf_t); ++#endif + + struct xenoprof_init { + int32_t num_events; +Index: 2006-12-18/xen/include/xen/xenoprof.h +=================================================================== +--- 2006-12-18.orig/xen/include/xen/xenoprof.h 2006-12-13 11:15:57.000000000 +0100 ++++ 2006-12-18/xen/include/xen/xenoprof.h 2006-12-18 09:50:08.000000000 +0100 +@@ -10,6 +10,7 @@ + #ifndef __XEN_XENOPROF_H__ + #define __XEN_XENOPROF_H__ + ++#include + #include + #include + +@@ -22,9 +23,19 @@ + #define XENOPROF_READY 2 + #define XENOPROF_PROFILING 3 + ++#ifndef CONFIG_COMPAT ++typedef struct xenoprof_buf xenoprof_buf_t; ++#else ++#include ++typedef union { ++ struct xenoprof_buf native; ++ struct compat_oprof_buf compat; ++} xenoprof_buf_t; ++#endif ++ + struct xenoprof_vcpu { + int event_size; +- struct xenoprof_buf *buffer; ++ xenoprof_buf_t *buffer; + }; + + struct xenoprof { +@@ -35,9 +46,22 @@ struct xenoprof { + int domain_type; + int domain_ready; + int is_primary; ++#ifdef CONFIG_COMPAT ++ int is_compat; ++#endif + struct xenoprof_vcpu vcpu [MAX_VIRT_CPUS]; + }; + ++#ifndef CONFIG_COMPAT ++#define XENOPROF_COMPAT(x) 0 ++#define xenoprof_buf(d, b, field) ((b)->field) ++#else ++#define XENOPROF_COMPAT(x) ((x)->is_compat) ++#define xenoprof_buf(d, b, field) (*(!(d)->xenoprof->is_compat ? \ ++ &(b)->native.field : \ ++ &(b)->compat.field)) ++#endif ++ + struct domain; + void free_xenoprof_pages(struct domain *d); + +Index: 2006-12-18/xen/include/xlat.lst +=================================================================== +--- 2006-12-18.orig/xen/include/xlat.lst 2006-12-18 09:50:05.000000000 +0100 ++++ 2006-12-18/xen/include/xlat.lst 2006-12-18 09:50:08.000000000 +0100 +@@ -38,3 +38,5 @@ + ? sched_remote_shutdown sched.h + ? sched_shutdown sched.h + ! vcpu_runstate_info vcpu.h ++? xenoprof_init xenoprof.h ++? xenoprof_passive xenoprof.h +Index: 2006-12-18/xen/common/Makefile +=================================================================== +--- 2006-12-18.orig/xen/common/Makefile 2006-12-18 09:50:05.000000000 +0100 ++++ 2006-12-18/xen/common/Makefile 2006-12-18 09:50:08.000000000 +0100 +@@ -45,4 +45,5 @@ ifeq ($(CONFIG_COMPAT),y) + acm_ops.o: compat/acm_ops.c + grant_table.o: compat/grant_table.c + schedule.o: compat/schedule.c ++xenoprof.o: compat/xenoprof.c + endif +Index: 2006-12-18/xen/common/compat/xenoprof.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2006-12-18/xen/common/compat/xenoprof.c 2006-12-18 09:50:08.000000000 +0100 +@@ -0,0 +1,40 @@ ++/* ++ * compat/xenoprof.c ++ */ ++ ++#include ++ ++#define COMPAT ++ ++#define do_xenoprof_op compat_xenoprof_op ++ ++#define xen_oprof_init xenoprof_init ++CHECK_oprof_init; ++#undef xen_oprof_init ++ ++#define xenoprof_get_buffer compat_oprof_get_buffer ++#define xenoprof_op_get_buffer compat_oprof_op_get_buffer ++ ++#define xen_domid_t domid_t ++#define compat_domid_t domid_compat_t ++CHECK_TYPE(domid); ++#undef compat_domid_t ++#undef xen_domid_t ++ ++#define xen_oprof_passive xenoprof_passive ++CHECK_oprof_passive; ++#undef xen_oprof_passive ++ ++#define xenoprof_counter compat_oprof_counter ++ ++#include "../xenoprof.c" ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * tab-width: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ +Index: 2006-12-18/xen/common/xenoprof.c +=================================================================== +--- 2006-12-18.orig/xen/common/xenoprof.c 2006-12-13 11:15:54.000000000 +0100 ++++ 2006-12-18/xen/common/xenoprof.c 2006-12-18 09:50:08.000000000 +0100 +@@ -9,6 +9,7 @@ + * VA Linux Systems Japan K.K. + */ + ++#ifndef COMPAT + #include + #include + #include +@@ -72,7 +73,7 @@ static void xenoprof_reset_stat(void) + static void xenoprof_reset_buf(struct domain *d) + { + int j; +- struct xenoprof_buf *buf; ++ xenoprof_buf_t *buf; + + if ( d->xenoprof == NULL ) + { +@@ -86,8 +87,8 @@ static void xenoprof_reset_buf(struct do + buf = d->xenoprof->vcpu[j].buffer; + if ( buf != NULL ) + { +- buf->event_head = 0; +- buf->event_tail = 0; ++ xenoprof_buf(d, buf, event_head) = 0; ++ xenoprof_buf(d, buf, event_tail) = 0; + } + } + } +@@ -166,15 +167,24 @@ static int alloc_xenoprof_struct( + for_each_vcpu ( d, v ) + nvcpu++; + ++ bufsize = sizeof(struct xenoprof_buf); ++ i = sizeof(struct event_log); ++#ifdef CONFIG_COMPAT ++ d->xenoprof->is_compat = IS_COMPAT(is_passive ? dom0 : d); ++ if ( XENOPROF_COMPAT(d->xenoprof) ) ++ { ++ bufsize = sizeof(struct compat_oprof_buf); ++ i = sizeof(struct compat_event_log); ++ } ++#endif ++ + /* reduce max_samples if necessary to limit pages allocated */ + max_bufsize = (MAX_OPROF_SHARED_PAGES * PAGE_SIZE) / nvcpu; +- max_max_samples = ( (max_bufsize - sizeof(struct xenoprof_buf)) / +- sizeof(struct event_log) ) + 1; ++ max_max_samples = ( (max_bufsize - bufsize) / i ) + 1; + if ( (unsigned)max_samples > max_max_samples ) + max_samples = max_max_samples; + +- bufsize = sizeof(struct xenoprof_buf) + +- (max_samples - 1) * sizeof(struct event_log); ++ bufsize += (max_samples - 1) * i; + npages = (nvcpu * bufsize - 1) / PAGE_SIZE + 1; + + d->xenoprof->rawbuf = alloc_xenheap_pages(get_order_from_pages(npages)); +@@ -195,11 +205,12 @@ static int alloc_xenoprof_struct( + i = 0; + for_each_vcpu ( d, v ) + { ++ xenoprof_buf_t *buf = (xenoprof_buf_t *)&d->xenoprof->rawbuf[i * bufsize]; ++ + d->xenoprof->vcpu[v->vcpu_id].event_size = max_samples; +- d->xenoprof->vcpu[v->vcpu_id].buffer = +- (struct xenoprof_buf *)&d->xenoprof->rawbuf[i * bufsize]; +- d->xenoprof->vcpu[v->vcpu_id].buffer->event_size = max_samples; +- d->xenoprof->vcpu[v->vcpu_id].buffer->vcpu_id = v->vcpu_id; ++ d->xenoprof->vcpu[v->vcpu_id].buffer = buf; ++ xenoprof_buf(d, buf, event_size) = max_samples; ++ xenoprof_buf(d, buf, vcpu_id) = v->vcpu_id; + + i++; + /* in the unlikely case that the number of active vcpus changes */ +@@ -406,8 +417,9 @@ static int add_passive_list(XEN_GUEST_HA + void xenoprof_log_event( + struct vcpu *vcpu, unsigned long eip, int mode, int event) + { ++ struct domain *d = vcpu->domain; + struct xenoprof_vcpu *v; +- struct xenoprof_buf *buf; ++ xenoprof_buf_t *buf; + int head; + int tail; + int size; +@@ -417,13 +429,13 @@ void xenoprof_log_event( + + /* ignore samples of un-monitored domains */ + /* Count samples in idle separate from other unmonitored domains */ +- if ( !is_profiled(vcpu->domain) ) ++ if ( !is_profiled(d) ) + { + others_samples++; + return; + } + +- v = &vcpu->domain->xenoprof->vcpu[vcpu->vcpu_id]; ++ v = &d->xenoprof->vcpu[vcpu->vcpu_id]; + + /* Sanity check. Should never happen */ + if ( v->buffer == NULL ) +@@ -432,10 +444,10 @@ void xenoprof_log_event( + return; + } + +- buf = vcpu->domain->xenoprof->vcpu[vcpu->vcpu_id].buffer; ++ buf = v->buffer; + +- head = buf->event_head; +- tail = buf->event_tail; ++ head = xenoprof_buf(d, buf, event_head); ++ tail = xenoprof_buf(d, buf, event_tail); + size = v->event_size; + + /* make sure indexes in shared buffer are sane */ +@@ -447,28 +459,28 @@ void xenoprof_log_event( + + if ( (head == tail - 1) || (head == size - 1 && tail == 0) ) + { +- buf->lost_samples++; ++ xenoprof_buf(d, buf, lost_samples)++; + lost_samples++; + } + else + { +- buf->event_log[head].eip = eip; +- buf->event_log[head].mode = mode; +- buf->event_log[head].event = event; ++ xenoprof_buf(d, buf, event_log[head].eip) = eip; ++ xenoprof_buf(d, buf, event_log[head].mode) = mode; ++ xenoprof_buf(d, buf, event_log[head].event) = event; + head++; + if ( head >= size ) + head = 0; +- buf->event_head = head; ++ xenoprof_buf(d, buf, event_head) = head; + if ( is_active(vcpu->domain) ) + active_samples++; + else + passive_samples++; + if ( mode == 0 ) +- buf->user_samples++; ++ xenoprof_buf(d, buf, user_samples)++; + else if ( mode == 1 ) +- buf->kernel_samples++; ++ xenoprof_buf(d, buf, kernel_samples)++; + else +- buf->xen_samples++; ++ xenoprof_buf(d, buf, xen_samples)++; + } + } + +@@ -494,6 +506,8 @@ static int xenoprof_op_init(XEN_GUEST_HA + return 0; + } + ++#endif /* !COMPAT */ ++ + static int xenoprof_op_get_buffer(XEN_GUEST_HANDLE(void) arg) + { + struct xenoprof_get_buffer xenoprof_get_buffer; +@@ -732,6 +746,10 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN + return ret; + } + ++#if defined(CONFIG_COMPAT) && !defined(COMPAT) ++#include "compat/xenoprof.c" ++#endif ++ + /* + * Local variables: + * mode: C diff --git a/README.SuSE b/README.SuSE index a0b0565..143bfc2 100644 --- a/README.SuSE +++ b/README.SuSE @@ -18,7 +18,7 @@ About Xen allows you to run multiple virtual machines on a single physical machine. See the Xen homepage for more information: - http://www.cl.cam.ac.uk/Research/SRG/netos/xen/ + http://www.cl.cam.ac.uk/research/srg/netos/xen/ If you want to use Xen, you need to install the Xen hypervisor and a number of supporting packages. During the initial SUSE installation (or when installing @@ -30,11 +30,13 @@ instead, you wish to install Xen manually later, install the following packages: xen xen-libs xen-tools - xen-tools-ioemu (Only required for hardware-assisted virtualization) + xen-tools-ioemu (Required for hardware-assisted virtualization) + multipath-tools (Required by xen-tools for domUloader) xen-doc-* (Optional) + python-gtk (Optional, to install VMs graphically) + virt-manager (Optional, to manage VMs graphically) tightvnc (Optional, to view VMs) - yast2-vm (Optional, to facilitate creation and management of VMs) - multipath-tools (Required by yast2-vm, for domUloader) + yast2-vm (Optional, convenient icons to install/manage VMs) You then need to reboot your machine. Instead of booting a normal Linux kernel, you will boot the Xen hypervisor and a slightly changed Linux kernel. @@ -44,10 +46,10 @@ hardware. This approach is called para-virtualization, since it is a partial virtualization (the Linux kernel needs to be changed slightly, to make the virtualization easier). It results in very good performance (consult -http://www.cl.cam.ac.uk/Research/SRG/netos/xen/performance.html) but has the -downside of unchanged operating systems not being supported. However, -upcoming hardware features (e.g., Intel's VT and AMD's Virtualization) will -help overcome this limitation. +http://www.cl.cam.ac.uk/research/srg/netos/xen/performance.html) but has the +downside of unchanged operating systems not being supported. However, new +hardware features (e.g., Intel's VT and AMD's V) are overcoming this +limitation. Terminology @@ -73,7 +75,7 @@ machines". The acronym "HVM" refers to a hardware-assisted virtual machine. These are VMs that have not been modified (e.g., Windows) and therefore need hardware -support such as Intel's VT or AMD's Virtualization to run on Xen. +support such as Intel's VT or AMD's V to run on Xen. Kernels @@ -155,8 +157,8 @@ Start Scripts ------------- Before you can create additional VMs (or use any other xm command) xend must be running. This init script is part of the xen-tools package, and it is -activated at installation time. You can (de)activate it using insserv (or -chkconfig). You can also start it manually with "rcxend start". +activated at installation time. You can (de)activate it using insserv. You +can also start it manually with "rcxend start". One other relevant startup script is xendomains. This script can be used to start other VMs when the VM server boots. It also cleanly shuts down the @@ -165,59 +167,53 @@ symbolic link in /etc/xen/auto that points to the VM's configuration file. Look in /etc/sysconfig/xendomains for relevant settings. -Creating a VM with YaST ------------------------ -YaST is the recommended method to create VMs. The YaST module (from the -yast2-vm package) handles creating both the VM's configuration file and -disk(s). YaST can help install any operating system, not just SUSE. +Creating a VM with vm-install +----------------------------- +The vm-install program (part of the xen-tools package, and accessible +through YaST's Control Center) is the recommended method to create VMs. This +program handles creating both the VM's configuration file and disk(s). It can +help install any operating system, not just SUSE. -From the command line, run "yast2 xen". From the GUI, start YaST, select -"System", then start "Virtual Machine Management (Xen)". For full -functionality, YaST must run in graphical mode, not ncurses. - -The first screen shows all created and running VMs. To create a new one, -click "Add". Now adjust the VM's configuration to your liking. +From the command line, run "vm-install". If the DISPLAY environment +variable is set and the supporting packages (python-gtk) are installed, a +graphical wizard will start. Otherwise, a text wizard will start. Xen does not yet properly support removable media in VMs in paravirtual mode, so installing an operating system from CDs can be difficult. We recommend using a network installation source, a DVD, or a DVD ISO. CDs do, however, work as expected in fully-virtual mode. -Note that paravirtualized SUSE Linux will default to using a text-based -installation. To perform a graphical installation, add "vnc=1" to the -"Installation Options" line in YaST. See this page for further guidance on -installing via VNC: +Note that older paravirtualized SUSE Linux (older than SLES 10 SP1) will +default to using a text-based installation. To perform a graphical +installation of these OSs, add "vnc=1" to the "Additional Arguments" field +(found on the "Operating System Installation" page in the wizard). See this +page for further guidance on installing via VNC: http://www.novell.com/coolsolutions/feature/15568.html +SLES 10 SP1 and later will automatically install graphically, as they contain +the paravirtual frame buffer driver. -Once you have the VM configured, click "Next". YaST will now create a +Once you have the VM configured, click "OK". The wizard will now create a configuration file for the VM, and create a disk image. The disk image will exist in /var/lib/xen/images, and a corresponding config file will exist in /etc/xen/vm. The operating system's installation program will then run within the VM. -When the VM shuts down (because the installation -- or at least the first stage -of it -- is done), YaST gives you a chance to finalize the VM's configuration. -This is useful, for example, if the installer and the application that will -run in the VM have different memory or network requirements. +When the VM shuts down (because the installation -- or at least the first +stage of it -- is done), the wizard gives you a chance to finalize the VM's +configuration. This is useful, for example, if the installer and the +application that will run in the VM have different memory or network +requirements. -The creation of VMs can be automated with AutoYaST. A single AutoYaST profile -can control the VM's settings (regardless of OS type) and/or the actual -installation of the OS within the VM (for SUSE only). Perhaps the easiest way -to create such a profile is to install a SUSE OS within a VM and "clone" the -operating system in the final stage of the OS installation. Then copy the -resulting file (/root/autoinst.xml) into the VM server's filesystem, into the -directory /var/lib/autoinstall/repository/. Start the AutoYaST tool (YaST > -Miscellaneous > Autoinstall) and then open the profile. Select the "Virtual -Machine Management (Xen)" heading, and add the settings for the VM. Save the -profile. Now the single profile can direct both the configuration of a VM, -and the installation of the OS within the VM. +The creation of VMs can be automated; read the vm-install man page for more +details. The installation of an OS within the VM can be automated if the OS +supports it. Creating a VM Manually ---------------------- -If you create a VM manually (as opposed to using YaST, which is the recommended -way), you will need to create a disk (or reuse an existing one) and a -configuration file. +If you create a VM manually (as opposed to using vm-install, which is the +recommended way), you will need to create a disk (or reuse an existing one) +and a configuration file. Each VM needs to have its own root filesystem. The root filesystem can live on a block device (e.g., a hard disk partition, or an LVM2 or EVMS volume) or in @@ -253,22 +249,10 @@ boots. (See "Network Troubleshooting" below.) XenSource has been allocated a range of MAC addresses with the OUI of 00-16-3E. By using MACs from this range you can be sure they will not conflict with any physical adapters. -To get started quickly, you can use a modified rescue image from the Novell -SUSE installation CD/DVD. It's on the first CD/DVD in the boot/ directory with -the name "rescue". To make it usable with Xen, run the script -/usr/share/doc/packages/xen/mk-xen-rescue-img.sh (run it with no arguments to -get help). The script replaces the normal Linux kernel in the image with a -Xen-enabled Linux kernel (among other things; read the script for details). -The script also creates a matching configuration file. The disadvantage of -using the rescue way of constructing a root filesystem is that the result does -not have an RPM database, so you can't easily add packages using rpm. On the -positive side, the result is relatively small yet has most of what's needed to -get started with networking. - Managing Virtual Machines ------------------------- -VMs can be managed from the command line or from YaST. +VMs can be managed from the command line or from virt-manager. To create a new VM from the command line, use a command like: xm create my-vm @@ -372,10 +356,6 @@ FW_FORWARD_ALWAYS_INOUT_DEV="xenbr0". If xenbr0 and xenbr1 are being used, the line should be: FW_FORWARD_ALWAYS_INOUT_DEV="xenbr0 xenbr1". -If you use the rescue images created by the above mentioned script, you'll -have a boot script inside that parses the ip=.... boot parameter. You can set -this parameter in the config file, and can have networking work automatically. - When using bridging, the eth0 in domain 0 device will be renamed to peth0 and its MAC address will be set to fe:ff:ff:ff:ff:ff and ARP will be disabled. veth0 will take over the old MAC address, be renamed to eth0, and be enabled @@ -475,13 +455,15 @@ grow the virtual hardware beyond what the kernel has been booted with. But you can trick domU Linux to prepare for a larger amount of RAM by passing the mem= boot parameter. -The export of virtual hard disks from files in Xen is handled via the loopback -driver. You can easily run out of those, as by default only 8 loopback devices -are supported. You can change this by inserting: +The export of virtual hard disks from files in Xen can be handled via the +loopback driver (although in Xen 3.0.4, this is being replaced by the "blktap" +user-space driver.) If you are still using loopback, you can easily run out +of loopback devices, as by default only 8 are supported. You can change this +by inserting: options loop max_loop=64 into /etc/modprobe.conf.local in domain 0. -Similarly, the netback driver comes up with 8 virtual network device pairs +Similarly, the netback driver comes up with 4 virtual network device pairs (vif0.X - vethX). You can change this by inserting: options netloop nloopbacks=64 into /etc/modprobe.conf.local in domain 0. @@ -526,7 +508,7 @@ may help. Xen and Linux understand similar ACPI boot parameters. Try the options acpi=off,force,strict,ht,noirq or acpi_skip_timer_override. Other useful debugging options to Xen may be nosmp, noreboot, mem=1024M, sync_console, noirqbalance (Dell). For a complete list of Xen boot options, -consult chapter 10.3 of the Xen users' manual. +consult chapter 11.3 of the Xen users' manual. If domain 0 Linux crashes on X11 startup, please try to boot into runlevel 3. diff --git a/blktools-bimodal.diff b/blktools-bimodal.diff new file mode 100644 index 0000000..308e962 --- /dev/null +++ b/blktools-bimodal.diff @@ -0,0 +1,71 @@ +bimodal: blk tools + +Add one more option to the disk configuration, so one can specify the +protocol the frontend speaks in the config file. This is needed for +old frontends which don't advertise the protocol they are speaking +themself. + +I'm not that happy with this approach, but it works for now and I'm +kida lost in the stack of python classes doing domain and device +handling ... + +Signed-off-by: Gerd Hoffmann +--- + tools/python/xen/xend/server/blkif.py | 3 +++ + tools/python/xen/xm/create.py | 7 ++++++- + 2 files changed, 9 insertions(+), 1 deletion(-) + +Index: build-64-release304-13133/tools/python/xen/xend/server/blkif.py +=================================================================== +--- build-64-release304-13133.orig/tools/python/xen/xend/server/blkif.py ++++ build-64-release304-13133/tools/python/xen/xend/server/blkif.py +@@ -38,6 +38,7 @@ class BlkifController(DevController): + """@see DevController.getDeviceDetails""" + uname = config.get('uname', '') + dev = config.get('dev', '') ++ protocol = config.get('protocol') + + if 'ioemu:' in dev: + (_, dev) = string.split(dev, ':', 1) +@@ -85,6 +86,8 @@ class BlkifController(DevController): + front = { 'virtual-device' : "%i" % devid, + 'device-type' : dev_type + } ++ if protocol: ++ front.update({ 'protocol' : protocol }); + + return (devid, back, front) + +Index: build-64-release304-13133/tools/python/xen/xm/create.py +=================================================================== +--- build-64-release304-13133.orig/tools/python/xen/xm/create.py ++++ build-64-release304-13133/tools/python/xen/xm/create.py +@@ -531,7 +531,7 @@ def configure_image(vals): + def configure_disks(config_devs, vals): + """Create the config for disks (virtual block devices). + """ +- for (uname, dev, mode, backend) in vals.disk: ++ for (uname, dev, mode, backend, protocol) in vals.disk: + if uname.startswith('tap:'): + cls = 'tap' + else: +@@ -543,6 +543,8 @@ def configure_disks(config_devs, vals): + ['mode', mode ] ] + if backend: + config_vbd.append(['backend', backend]) ++ if protocol: ++ config_vbd.append(['protocol', protocol]) + config_devs.append(['device', config_vbd]) + + def configure_pci(config_devs, vals): +@@ -787,7 +789,10 @@ def preprocess_disk(vals): + n = len(d) + if n == 3: + d.append(None) ++ d.append(None) + elif n == 4: ++ d.append(None) ++ elif n == 5: + pass + else: + err('Invalid disk specifier: ' + v) diff --git a/block-iscsi b/block-iscsi index 72ea1f3..b7ab3a6 100644 --- a/block-iscsi +++ b/block-iscsi @@ -1,90 +1,90 @@ -#!/bin/bash - -# Usage: block-iscsi [add tgtname | remove dev] -# -# This assumes you're running a correctly configured -# iscsi target (server) at the other end! -# Note that we assume that the passwords for discovery (if needed) -# are in /etc/iscsid.conf -# and the node session passwords (if required) in the -# open-iscsi database below /var/lib/open-iscsi/node.db -# -# (c) Kurt Garloff , 2006-09-04, GNU GPL - -dir=$(dirname "$0") -. "$dir/block-common.sh" -#command=$1 - -#echo "DBG:xen/scripts/block-iscsi $1 $2 XENBUS_PATH=$XENBUS_PATH $par $node" - -#write_dev() -#{ -# echo "$1" -#} - -find_sdev() -{ - unset dev - for session in /sys/class/iscsi_session/session*; do - if test $1 = `cat $session/targetname`; then - dev=`readlink $session/device/target*/*:0:*/block*` - dev=${dev##*/} - return - fi - done -} - -find_sdev_rev() -{ - unset tgt - for session in /sys/class/iscsi_session/session*; do - dev=`readlink $session/device/target*/*:0:*/block*` - dev=${dev##*/} - if test $dev = $1; then - tgt=`cat $session/targetname` - return - fi - done -} - -case "$command" in - add) - # load modules and start iscsid - /etc/init.d/open-iscsi status >/dev/null 2>&1 || - { /etc/init.d/open-iscsi start >/dev/null 2>&1; sleep 1; } - # list of targets on node - par=`xenstore-read $XENBUS_PATH/params` || true - TGTID=$par; TGTID=${TGTID//@/:} - while read rec port uuid; do - if test $uuid = $TGTID; then - rec=${rec%]}; rec=${rec#[} - find_sdev $TGTID - if test -z "$dev"; then - iscsiadm -m node -r $rec -l || exit 2 - usleep 100000 - find_sdev $TGTID - fi - xenstore-write $XENBUS_PATH/node /dev/$dev - write_dev /dev/$dev - exit 0 - fi - done < <(iscsiadm -m node) - exit 1 - ;; - remove) - node=`xenstore-read $XENBUS_PATH/node` || true - dev=$node; dev=${dev#/dev/} - find_sdev_rev $dev - #echo $tgt - if test -x /sbin/blockdev -a -n "$node"; then blockdev --flushbufs $node; fi - test -z "$tgt" && exit 2 - while read rec port uuid; do - if test $uuid = $tgt; then - rec=${rec%]}; rec=${rec#[} - iscsiadm -m node -r $rec -u - exit 0 - fi - done < <(iscsiadm -m node) - exit 1 - ;; -esac +#!/bin/bash + +# Usage: block-iscsi [add tgtname | remove dev] +# +# This assumes you're running a correctly configured +# iscsi target (server) at the other end! +# Note that we assume that the passwords for discovery (if needed) +# are in /etc/iscsid.conf +# and the node session passwords (if required) in the +# open-iscsi database below /var/lib/open-iscsi/node.db +# +# (c) Kurt Garloff , 2006-09-04, GNU GPL + +dir=$(dirname "$0") +. "$dir/block-common.sh" +#command=$1 + +#echo "DBG:xen/scripts/block-iscsi $1 $2 XENBUS_PATH=$XENBUS_PATH $par $node" + +#write_dev() +#{ +# echo "$1" +#} + +find_sdev() +{ + unset dev + for session in /sys/class/iscsi_session/session*; do + if test $1 = `cat $session/targetname`; then + dev=`readlink $session/device/target*/*:0:*/block*` + dev=${dev##*/} + return + fi + done +} + +find_sdev_rev() +{ + unset tgt + for session in /sys/class/iscsi_session/session*; do + dev=`readlink $session/device/target*/*:0:*/block*` + dev=${dev##*/} + if test $dev = $1; then + tgt=`cat $session/targetname` + return + fi + done +} + +case "$command" in + add) + # load modules and start iscsid + /etc/init.d/open-iscsi status >/dev/null 2>&1 || + { /etc/init.d/open-iscsi start >/dev/null 2>&1; sleep 1; } + # list of targets on node + par=`xenstore-read $XENBUS_PATH/params` || true + TGTID=$par; TGTID=${TGTID//@/:} + while read rec port uuid; do + if test $uuid = $TGTID; then + rec=${rec%]}; rec=${rec#[} + find_sdev $TGTID + if test -z "$dev"; then + iscsiadm -m node -r $rec -l || exit 2 + usleep 100000 + find_sdev $TGTID + fi + xenstore-write $XENBUS_PATH/node /dev/$dev + write_dev /dev/$dev + exit 0 + fi + done < <(iscsiadm -m node) + exit 1 + ;; + remove) + node=`xenstore-read $XENBUS_PATH/node` || true + dev=$node; dev=${dev#/dev/} + find_sdev_rev $dev + #echo $tgt + if test -x /sbin/blockdev -a -n "$node"; then blockdev --flushbufs $node; fi + test -z "$tgt" && exit 2 + while read rec port uuid; do + if test $uuid = $tgt; then + rec=${rec%]}; rec=${rec#[} + iscsiadm -m node -r $rec -u + exit 0 + fi + done < <(iscsiadm -m node) + exit 1 + ;; +esac diff --git a/block-losetup-retry.diff b/block-losetup-retry.diff index b2741bb..2f5aa05 100644 --- a/block-losetup-retry.diff +++ b/block-losetup-retry.diff @@ -1,8 +1,8 @@ -Index: xen-unstable/tools/examples/block +Index: xen-3.0.4-testing/tools/examples/block =================================================================== ---- xen-unstable.orig/tools/examples/block -+++ xen-unstable/tools/examples/block -@@ -391,8 +391,18 @@ mount it read-write in a guest domain." +--- xen-3.0.4-testing.orig/tools/examples/block ++++ xen-3.0.4-testing/tools/examples/block +@@ -390,8 +390,18 @@ mount it read-write in a guest domain." file) node=$(xenstore_read "$XENBUS_PATH/node") diff --git a/block-nbd b/block-nbd index 3ffc21e..9538103 100644 --- a/block-nbd +++ b/block-nbd @@ -12,7 +12,7 @@ dir=$(dirname "$0") #set -x par=`xenstore-read $XENBUS_PATH/params` || true -echo $par +#echo $par case "$command" in add) diff --git a/block-sync.diff b/block-sync.diff index 572cf1b..862d376 100644 --- a/block-sync.diff +++ b/block-sync.diff @@ -1,7 +1,7 @@ -Index: xen-unstable/tools/examples/block +Index: xen-3.0.4-testing/tools/examples/block =================================================================== ---- xen-unstable.orig/tools/examples/block -+++ xen-unstable/tools/examples/block +--- xen-3.0.4-testing.orig/tools/examples/block ++++ xen-3.0.4-testing/tools/examples/block @@ -42,6 +42,20 @@ canonicalise_mode() fi } diff --git a/bridge-hostonly.diff b/bridge-hostonly.diff new file mode 100644 index 0000000..42ff9a8 --- /dev/null +++ b/bridge-hostonly.diff @@ -0,0 +1,82 @@ +Add support for "hostonly" xen bridges. + +Add support for "hostonly" networking, i.e. create a bridge without a +physical network device linked in. The virtual machines can see each +other and the host, but can't (directly) talk to the outside. Pass +"netdev=none" to the network-bridge script to activate this. + +I'm using this on a laptop which has different network connections at +different times (wired / wireless), so it is inconvinient to add the +physical device into the bridge. In case the laptop is offline the +virtual network still works just fine. It also avoids the problem that +bridging doesn't work with wireless due to being limited to one mac +address then. + +dom0 on that laptop also runs a dhcp server for the virtual network. +Guests can talk to the internet via apache configured as http proxy. +Another possible approach for guest internet access is NATing the +virtual network. + +Signed-off-by: Gerd Hoffmann +--- + tools/examples/network-bridge | 37 +++++++++++++++++++++++++++++++++++-- + 1 file changed, 35 insertions(+), 2 deletions(-) + +Index: build-32-unstable-11624/tools/examples/network-bridge +=================================================================== +--- build-32-unstable-11624.orig/tools/examples/network-bridge ++++ build-32-unstable-11624/tools/examples/network-bridge +@@ -269,6 +269,31 @@ op_stop () { + brctl delbr ${bridge} + } + ++op_start_hostonly () { ++ if [ "${bridge}" = "null" ] ; then ++ return ++ fi ++ if link_exists "${bridge}"; then ++ return ++ fi ++ ++ create_bridge ${bridge} ++ setup_bridge_port ${vif0} ++ add_to_bridge ${bridge} ${vif0} ++} ++ ++op_stop_hostonly () { ++ if [ "${bridge}" = "null" ]; then ++ return ++ fi ++ if ! link_exists "$bridge"; then ++ return ++ fi ++ ++ brctl delbr ${bridge} ++} ++ ++ + # adds $dev to $bridge but waits for $dev to be in running state first + add_to_bridge2() { + local bridge=$1 +@@ -293,11 +318,19 @@ add_to_bridge2() { + + case "$command" in + start) +- op_start ++ if test "$netdev" = "none"; then ++ op_start_hostonly ++ else ++ op_start ++ fi + ;; + + stop) +- op_stop ++ if test "$netdev" = "none"; then ++ op_stop_hostonly ++ else ++ op_stop ++ fi + ;; + + status) diff --git a/bug.patch b/bug.patch new file mode 100644 index 0000000..df129c0 --- /dev/null +++ b/bug.patch @@ -0,0 +1,325 @@ +Index: 2007-01-31/xen/arch/powerpc/backtrace.c +=================================================================== +--- 2007-01-31.orig/xen/arch/powerpc/backtrace.c 2006-12-15 16:33:59.000000000 +0100 ++++ 2007-01-31/xen/arch/powerpc/backtrace.c 2007-01-31 09:42:07.000000000 +0100 +@@ -206,7 +206,7 @@ void show_backtrace_regs(struct cpu_user + console_end_sync(); + } + +-void __warn(char *file, int line) ++void __warn(const char *file, int line) + { + ulong sp; + ulong lr; +Index: 2007-01-31/xen/arch/x86/mm/shadow/common.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/mm/shadow/common.c 2007-01-31 09:36:44.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/mm/shadow/common.c 2007-01-31 09:42:07.000000000 +0100 +@@ -940,6 +940,7 @@ mfn_t shadow_alloc(struct domain *d, + * we might free up higher-level pages that the caller is working on. */ + SHADOW_PRINTK("Can't allocate %i shadow pages!\n", 1 << order); + BUG(); ++ return _mfn(0); + } + + +Index: 2007-01-31/xen/arch/x86/mm/shadow/multi.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/mm/shadow/multi.c 2007-01-31 09:36:54.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/mm/shadow/multi.c 2007-01-31 09:42:07.000000000 +0100 +@@ -3160,7 +3160,7 @@ sh_update_linear_entries(struct vcpu *v) + */ + { + l2_pgentry_t *l2e, new_l2e; +- shadow_l3e_t *guest_l3e = NULL, *shadow_l3e; ++ shadow_l3e_t *guest_l3e = NULL, *shadow_l3e = NULL; + int i; + int unmap_l2e = 0; + +Index: 2007-01-31/xen/arch/x86/traps.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/traps.c 2007-01-31 09:41:54.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/traps.c 2007-01-31 09:42:07.000000000 +0100 +@@ -635,14 +635,50 @@ asmlinkage int do_invalid_op(struct cpu_ + + if ( unlikely(!guest_mode(regs)) ) + { +- char sig[5]; +- /* Signature (ud2; .ascii "dbg") indicates dump state and continue. */ +- if ( (__copy_from_user(sig, (char *)regs->eip, sizeof(sig)) == 0) && +- (memcmp(sig, "\xf\xb""dbg", sizeof(sig)) == 0) ) +- { +- show_execution_state(regs); +- regs->eip += sizeof(sig); +- return EXCRET_fault_fixed; ++ struct bug_frame f; ++ ++ if ( (__copy_from_user(&f, (char *)regs->eip, sizeof(f)) == 0) && ++ f.ud2[0] == 0x0f && f.ud2[1] == 0x0b && f.ret == 0xc2 ) ++ { ++ const char *text = NULL; ++ char file[40]; ++ ++ switch ( f.id ) ++ { ++ case bug_bug: ++ text = "BUG"; ++ break; ++ case bug_warn: ++ text = "Badness"; ++ break; ++ case bug_dump_state: ++ text = "State"; ++ break; ++ case bug_crash_dom: ++ text = "domain_crash called"; ++ break; ++ } ++ if ( text ) ++ { ++ const void *ptr; ++ ++ ptr = &((const struct bug_frame *)regs->eip)->id + f.file_rel; ++ if ( __addr_ok(ptr) || ++ __copy_from_user(file, ptr, sizeof(file) - 1) ) ++ text = NULL; ++ else ++ file[sizeof(file) - 1] = 0; ++ } ++ if ( text ) ++ { ++ printk("%s at %s:%d\n", text, file, f.line); ++ if ( f.id != bug_bug ) ++ { ++ show_execution_state(regs); ++ regs->eip += sizeof(f); ++ return EXCRET_fault_fixed; ++ } ++ } + } + DEBUGGER_trap_fatal(TRAP_invalid_op, regs); + show_execution_state(regs); +Index: 2007-01-31/xen/common/keyhandler.c +=================================================================== +--- 2007-01-31.orig/xen/common/keyhandler.c 2007-01-31 09:29:10.000000000 +0100 ++++ 2007-01-31/xen/common/keyhandler.c 2007-01-31 09:42:07.000000000 +0100 +@@ -94,7 +94,7 @@ static void show_handlers(unsigned char + + static void __dump_execstate(void *unused) + { +- dump_execution_state(); ++ DUMP_STATE(); + } + + static void dump_registers(unsigned char key, struct cpu_user_regs *regs) +Index: 2007-01-31/xen/drivers/char/console.c +=================================================================== +--- 2007-01-31.orig/xen/drivers/char/console.c 2006-12-15 16:33:59.000000000 +0100 ++++ 2007-01-31/xen/drivers/char/console.c 2007-01-31 09:42:07.000000000 +0100 +@@ -880,15 +880,21 @@ void panic(const char *fmt, ...) + } + } + +-void __bug(char *file, int line) ++void __bug(const char *file, int line) + { + console_start_sync(); + printk("BUG at %s:%d\n", file, line); +- dump_execution_state(); ++ DUMP_STATE(); + panic("BUG at %s:%d\n", file, line); + for ( ; ; ) ; + } + ++void __warn(const char *file, int line) __attribute__((__weak__)); ++void __warn(const char *file, int line) ++{ ++ printk("Badness at %s:%d\n", file, line); ++} ++ + /* + * Local variables: + * mode: C +Index: 2007-01-31/xen/include/asm-ia64/bug.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-31/xen/include/asm-ia64/bug.h 2007-01-31 09:42:07.000000000 +0100 +@@ -0,0 +1,6 @@ ++#ifndef __ASM_IA64_BUG_H__ ++#define __ASM_IA64_BUG_H__ ++ ++#define DUMP_STATE() printk("FIXME: implement ia64 dump_execution_state()\n"); ++ ++#endif /* __ASM_IA64_BUG_H__ */ +Index: 2007-01-31/xen/include/asm-ia64/linux-xen/asm/iosapic.h +=================================================================== +--- 2007-01-31.orig/xen/include/asm-ia64/linux-xen/asm/iosapic.h 2006-12-13 11:15:55.000000000 +0100 ++++ 2007-01-31/xen/include/asm-ia64/linux-xen/asm/iosapic.h 2007-01-31 09:42:07.000000000 +0100 +@@ -123,11 +123,10 @@ static inline void list_move(struct list + + #define move_irq(x) + +-#define WARN_ON(condition) do { \ +- if (unlikely((condition)!=0)) { \ +- printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ +- dump_stack(); \ +- } \ ++#undef WARN ++#define WARN() do { \ ++ printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ ++ dump_stack(); \ + } while (0) + + #ifdef nop +Index: 2007-01-31/xen/include/asm-ia64/xenprocessor.h +=================================================================== +--- 2007-01-31.orig/xen/include/asm-ia64/xenprocessor.h 2006-12-13 11:15:55.000000000 +0100 ++++ 2007-01-31/xen/include/asm-ia64/xenprocessor.h 2007-01-31 09:42:07.000000000 +0100 +@@ -237,6 +237,4 @@ typedef union { + u64 itir; + } ia64_itir_t; + +-#define dump_execution_state() printk("FIXME: implement ia64 dump_execution_state()\n"); +- + #endif // _ASM_IA64_XENPROCESSOR_H +Index: 2007-01-31/xen/include/asm-powerpc/bug.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-31/xen/include/asm-powerpc/bug.h 2007-01-31 09:42:07.000000000 +0100 +@@ -0,0 +1,7 @@ ++#ifndef __ASM_PPC_BUG_H__ ++#define __ASM_PPC_BUG_H__ ++ ++extern void dump_execution_state(void); ++#define DUMP_STATE() dump_execution_state() ++ ++#endif /* __ASM_PPC_BUG_H__ */ +Index: 2007-01-31/xen/include/asm-powerpc/debugger.h +=================================================================== +--- 2007-01-31.orig/xen/include/asm-powerpc/debugger.h 2006-12-15 16:33:59.000000000 +0100 ++++ 2007-01-31/xen/include/asm-powerpc/debugger.h 2007-01-31 09:42:07.000000000 +0100 +@@ -67,10 +67,6 @@ static inline void unimplemented(void) + #endif + } + +-extern void __warn(char *file, int line); +-#define WARN() __warn(__FILE__, __LINE__) +-#define WARN_ON(_p) do { if (_p) WARN(); } while ( 0 ) +- + extern void __attn(void); + #define ATTN() __attn(); + +Index: 2007-01-31/xen/include/asm-x86/bug.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ 2007-01-31/xen/include/asm-x86/bug.h 2007-01-31 09:42:07.000000000 +0100 +@@ -0,0 +1,60 @@ ++#ifndef __ASM_X86_BUG_H__ ++#define __ASM_X86_BUG_H__ ++ ++enum bug_id { ++ bug_bug = 0xb8, ++ bug_warn, ++ bug_dump_state, ++ bug_crash_dom ++} __attribute__((__packed__)); ++ ++struct bug_frame { ++ unsigned char ud2[2]; ++ enum bug_id id; ++ signed int file_rel; ++ unsigned char ret; ++ unsigned short line; ++} __attribute__((__packed__)); ++ ++/* NB. These need interrupts enabled else we end up in fatal_trap(). */ ++ ++#define BUG() __asm__ __volatile__( \ ++ "pushf\n\t" \ ++ "sti\n\t" \ ++ "ud2\n\t" \ ++ "movl $%c0-.,%%eax\n\t" \ ++ "ret $%c1\n\t" \ ++ "popf" \ ++ : : "i" (__FILE__), "i" (__LINE__)) ++ ++#define WARN() __asm__ __volatile__( \ ++ "pushf\n\t" \ ++ "sti\n\t" \ ++ "ud2\n\t" \ ++ "movl $%c0-.,%%ecx\n\t" \ ++ "ret $%c1\n\t" \ ++ "popf" \ ++ : : "i" (__FILE__), "i" (__LINE__)) ++ ++#define DUMP_STATE() __asm__ __volatile__( \ ++ "pushf\n\t" \ ++ "sti\n\t" \ ++ "ud2\n\t" \ ++ "movl $%c0-.,%%edx\n\t" \ ++ "ret $%c1\n\t" \ ++ "popf" \ ++ : : "i" (__FILE__), "i" (__LINE__)) ++ ++#define CRASH_DOM(d) do { \ ++ __asm__ __volatile__( \ ++ "pushf\n\t" \ ++ "sti\n\t" \ ++ "ud2\n\t" \ ++ "movl $%c0-.,%%ebx\n\t" \ ++ "ret $%c1\n\t" \ ++ "popf" \ ++ : : "i" (__FILE__), "i" (__LINE__)); \ ++ __domain_crash(d); \ ++ } while (0) ++ ++#endif /* __ASM_X86_BUG_H__ */ +Index: 2007-01-31/xen/include/asm-x86/processor.h +=================================================================== +--- 2007-01-31.orig/xen/include/asm-x86/processor.h 2007-01-31 09:29:08.000000000 +0100 ++++ 2007-01-31/xen/include/asm-x86/processor.h 2007-01-31 09:42:07.000000000 +0100 +@@ -565,11 +565,6 @@ void compat_show_guest_stack(struct cpu_ + #define compat_show_guest_stack(regs, lines) ((void)0) + #endif + +-/* Dumps current register and stack state. */ +-#define dump_execution_state() \ +- /* NB. Needs interrupts enabled else we end up in fatal_trap(). */ \ +- __asm__ __volatile__ ( "pushf ; sti ; ud2 ; .ascii \"dbg\" ; popf" ) +- + extern void mtrr_ap_init(void); + extern void mtrr_bp_init(void); + +Index: 2007-01-31/xen/include/xen/lib.h +=================================================================== +--- 2007-01-31.orig/xen/include/xen/lib.h 2007-01-08 14:16:35.000000000 +0100 ++++ 2007-01-31/xen/include/xen/lib.h 2007-01-31 09:42:07.000000000 +0100 +@@ -7,10 +7,26 @@ + #include + #include + #include ++#include + +-extern void __bug(char *file, int line) __attribute__((noreturn)); ++#ifndef BUG ++extern void __bug(const char *file, int line) __attribute__((noreturn)); + #define BUG() __bug(__FILE__, __LINE__) +-#define BUG_ON(_p) do { if (_p) BUG(); } while ( 0 ) ++#endif ++ ++#ifndef WARN ++extern void __warn(const char *file, int line); ++#define WARN() __warn(__FILE__, __LINE__) ++#endif ++ ++#ifndef CRASH_DOM ++#define CRASH_DOM(d) domain_crash(d) ++#endif ++ ++#define BUG_ON(_p) do { if (unlikely(_p)) BUG(); } while ( 0 ) ++#define WARN_ON(_p) do { if (unlikely(_p)) WARN(); } while ( 0 ) ++#define DUMP_STATE_ON(_p) do { if (unlikely(_p)) DUMP_STATE(); } while ( 0 ) ++#define CRASH_DOM_ON(_d, _p) do { if (unlikely(_p)) CRASH_DOM(_d); } while ( 0 ) + + /* Force a compilation error if condition is true */ + #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 * !!(condition)])) diff --git a/cross-build-fix.diff b/cross-build-fix.diff new file mode 100644 index 0000000..ef4f696 --- /dev/null +++ b/cross-build-fix.diff @@ -0,0 +1,45 @@ +Fix 32bit xen-tools build. + +This fixes building 32bit xen-tools on a amd64 machine, i.e. +"XEN_TARGET_ARCH=x86_32 make". + +For ioemu I've taken the lazy path and just disabled them for +cross-builds, I'll leave that to fix to someone who knows the +qemu makefiles better than I do ;) + +Signed-off-by: Gerd Hoffmann +--- + config/x86_32.mk | 6 ++++-- + tools/Makefile | 2 +- + 2 files changed, 5 insertions(+), 3 deletions(-) + +Index: build-32-unstable-12621/config/x86_32.mk +=================================================================== +--- build-32-unstable-12621.orig/config/x86_32.mk ++++ build-32-unstable-12621/config/x86_32.mk +@@ -6,8 +6,10 @@ CONFIG_MIGRATE := y + CONFIG_XCUTILS := y + CONFIG_IOEMU := y + +-CFLAGS += -m32 -march=i686 +-LIBDIR := lib ++CFLAGS += -m32 -march=i686 ++LDFLAGS += -m32 ++ASFLAGS += -m32 ++LIBDIR := lib + + # Use only if calling $(LD) directly. + ifeq ($(XEN_OS),OpenBSD) +Index: build-32-unstable-12621/tools/Makefile +=================================================================== +--- build-32-unstable-12621.orig/tools/Makefile ++++ build-32-unstable-12621/tools/Makefile +@@ -62,7 +62,7 @@ check_clean: + $(MAKE) -C check clean + + .PHONY: ioemu ioemuinstall ioemuclean +-ifeq ($(CONFIG_IOEMU),y) ++ifeq ($(XEN_COMPILE_ARCH)$(CONFIG_IOEMU),$(XEN_TARGET_ARCH)y) + export IOEMU_DIR ?= ioemu + ioemu ioemuinstall: + [ -f $(IOEMU_DIR)/config-host.mak ] || \ diff --git a/domUloader.py b/domUloader.py index 4f99a77..9cae97f 100644 --- a/domUloader.py +++ b/domUloader.py @@ -1,39 +1,35 @@ #!/usr/bin/env python # domUloader.py """Loader for kernel and (optional) ramdisk from domU filesystem + +Given a physical disk (or disk image) for a domU and the path of a kernel and +optional ramdisk, copies the kernel and ramdisk from the domU disk to a +temporary location in dom0. + +The --entry parameter specifies the location of the kernel (and optional +ramdisk) within the domU filesystem. dev is the disk as seen by domU. +Filenames are relative to that filesystem. + +The disk is passed as the last parameter. It must be a block device or raw +disk image. More complex disk images (QCOW, VMDK, etc) must already be +configured via blktap and presented as a block device. + +The script writes an sxpr specifying the locations of the copied kernel and +ramdisk into the file specified by --output (default is stdout). + +Limitations: + - It is assumed both kernel and ramdisk are on the same filesystem. + - domUs might use LVM; the script currently does not have support for setting + up LVM mappings for domUs; it's not trivial and we might risk namespace + conflicts. If you want to use LVM inside domUs, set up a small non-LVM boot + partition and specify it in bootentry. - Uses bootentry = [dev:]kernel[,initrd] to get a kernel [and initrd] - from a domU filesystem to boot it for Xen. - dev is the disk as seen by domU, filenames are relative to - that filesystem. The script uses the disk settings from the - config file to find the domU filesystems. - The bootentry is passed to the script using --entry= - Optionally, dev: can be omitted; the script then looks at the - root filesystem, parses /etc/fstab to resolve the path to the - kernel [and the initrd]. Obviously, the paths relative to the - domU root filesystem needs to be specified for the kernel - and initrd filenames. +The script uses kpartx (multipath-tools) to create mappings for devices that +are exported as whole disk devices that are partitioned. - The root FS is passed using --root=, the filesystem setup in - --disks=. The disks list is a python list - [[uname, dev, mode, backend], [uname, dev, mode, backend], ...] - passed as a string. The script writes an sxpr specifying the - locations of the copied kernel and initrd into the file - specified by --output (default is stdout). - - Limitations: - - It is assumed both kernel and initrd are on the same filesystem. - - domUs might use LVM; the script currently does not have support - for setting up LVM mappings for domUs; it's not trivial and we - might risk namespace conflicts. If you want to use LVM inside domUs, - set up a small non-LVM boot partition and specify it in bootentry. - - The script uses kpartx (multipath-tools) to create mappings for - devices that are exported as whole disk devices that are partitioned. - - (c) 01/2006 Novell Inc - License: GNU GPL - Author: Kurt Garloff +(c) 01/2006 Novell Inc +License: GNU GPL +Author: Kurt Garloff """ import os, sys, getopt @@ -44,23 +40,21 @@ import time # Global options quiet = False -dryrun = False verbose = False +dryrun = False tmpdir = '/var/lib/xen/tmp' -# List of partitions -# It's created by setting up the all the devices from the xen disk -# config; every entry creates on Wholedisk object, which does necessary -# preparatory steps such as losetup and kpartx -a; then a Partition -# object is setup for every partition (which may be one or several per -# Wholedisk); it references the Wholedisk if needed; python reference -# counting will take care of the cleanup. -partitions = [] - # Helper functions +def error(s): + print >> sys.stderr, "domUloader error: %s" % s + +def verbose_print(s): + if verbose: + print >> sys.stderr, "domUloader: %s" % s + def traildigits(strg): - "Return the trailing digits, used to split the partition number off" + """Return the trailing digits, used to split the partition number off""" idx = len(strg)-1 while strg[idx].isdigit(): if len == 0: @@ -68,33 +62,49 @@ def traildigits(strg): idx -= 1 return strg[idx+1:] -def isWholedisk(domUname): - "Determines whether dev is a wholedisk dev" - return not domUname[-1:].isdigit() +def getWholedisk(part): + while len(part) and part[len(part)-1].isdigit(): + part = part[:-1] + return part +#def isWholedisk(domUname): +# """Determines whether dev is a wholedisk dev""" +# return not domUname[-1:].isdigit() -def findPart(dev): - "Find device dev in list of partitions" - if len(dev) > 5 and dev[:5] == "/dev/": - dev = dev[5:] - for part in partitions: - if dev == part.domname: - return part - return None class Wholedisk: - "Class representing a whole disk that has partitions" - def __init__(self, domname, physdev, loopfile = None): + "Class representing a whole disk that may have partitions" + def __init__(self, vdev, pdev): "c'tor: set up" - self.domname = domname - self.physdev = physdev - self.loopfile = loopfile - self.mapped = 0 - self.pcount = self.scanpartitions() + self.is_blk = (S_ISBLK(os.stat(pdev)[ST_MODE])) + self.ldev = None + self.vdev = vdev + self.pdev = pdev + self.mapped = 0 + self.partitions = [] + self.pcount = self.scanpartitions() + + def physdev(self): + """Gets the physical device used to access the device from dom0""" + if self.ldev: + return self.ldev + return self.pdev + + def findPart(self, vdev): + "Find device dev in list of partitions" + if len(vdev) > 5 and vdev[:5] == "/dev/": + vdev = vdev[5:] + for part in self.partitions: + if vdev == part.vdev: + return part + return None def loopsetup(self): - "Setup the loop mapping" - if self.loopfile and not self.physdev: + """Sets up the loop mapping for a disk image. + + Will raise if no loopbacks are available. + """ + if not self.is_blk and not self.ldev: # Loops through all loopback devices, attempting to # find a free one to set up. Don't scan for free and # then try to set it up as a separate step - too racy! @@ -104,28 +114,29 @@ class Wholedisk: if not os.path.exists(ldev): break i += 1 - fd = os.popen("losetup %s %s 2> /dev/null" % (ldev, self.loopfile)) + fd = os.popen("losetup %s %s 2> /dev/null" % (ldev, self.pdev)) if not fd.close(): - if verbose: - print "domUloader: losetup %s %s" % (ldev, self.loopfile) - self.physdev = ldev + verbose_print("losetup %s %s" % (ldev, self.pdev)) + self.ldev = ldev break - if not self.physdev: - raise RuntimeError("domUloader: No free loop device found") + if not self.ldev: + raise RuntimeError("No free loop device found") def loopclean(self): - "Delete the loop mapping" - if self.loopfile and self.physdev: - if verbose: - print "domUloader: losetup -d %s" % self.physdev + """Delete the loop mapping. + + Will never raise. + """ + if self.ldev: + verbose_print("losetup -d %s" % self.ldev) # Even seemingly innocent queries like "losetup /dev/loop0" # can temporarily block the loopback and cause transient # failures deleting the loopback, hence the retry logic. retries = 10 while retries: - fd = os.popen("losetup -d %s" % self.physdev) + fd = os.popen("losetup -d %s" % self.ldev) if not fd.close(): - self.physdev = None + self.ldev = None break else: time.sleep(0.1) @@ -137,25 +148,27 @@ class Wholedisk: self.loopsetup() # TODO: We could use fdisk -l instead and look at the type of # partitions; this way we could also detect LVM and support it. - fd = os.popen("kpartx -l %s" % self.physdev) + fd = os.popen("kpartx -l %s" % self.physdev()) pcount = 0 for line in fd.readlines(): line = line.strip() + verbose_print("kpartx -l: %s" % (line,)) (pname, params) = line.split(':') pno = int(traildigits(pname.strip())) #if pname.rfind('/') != -1: # pname = pname[pname.rfind('/')+1:] - #pname = self.physdev[:self.physdev.rfind('/')] + '/' + pname + #pname = self.pdev[:self.pdev.rfind('/')] + '/' + pname pname = "/dev/mapper/" + pname - partitions.append(Partition(self, self.domname + '%i' % pno, pname)) + verbose_print("Found partition: vdev %s, pdev %s" % ('%s%i' % (self.vdev, pno), pname)) + self.partitions.append(Partition(self, '%s%i' % (self.vdev, pno), pname)) pcount += 1 fd.close() if not pcount: - if self.loopfile: + if self.ldev: ref = self else: ref = None - partitions.append(Partition(ref, self.domname, self.physdev)) + self.partitions.append(Partition(ref, self.vdev, self.pdev)) return pcount def activatepartitions(self): @@ -163,22 +176,23 @@ class Wholedisk: if not self.mapped: self.loopsetup() if self.pcount: - if verbose: - print "domUloader: kpartx -a %s" % self.physdev - fd = os.popen("kpartx -a %s" % self.physdev) + verbose_print("kpartx -a %s" % self.physdev()) + fd = os.popen("kpartx -a %s" % self.physdev()) fd.close() self.mapped += 1 def deactivatepartitions(self): - "Remove device-mapper mappings and loop mapping" + """Remove device-mapper mappings and loop mapping. + + Will never raise. + """ if not self.mapped: return self.mapped -= 1 if not self.mapped: if self.pcount: - if verbose: - print "domUloader: kpartx -d %s" % self.physdev - fd = os.popen("kpartx -d %s" % self.physdev) + verbose_print("kpartx -d %s" % self.physdev()) + fd = os.popen("kpartx -d %s" % self.physdev()) fd.close() self.loopclean() @@ -189,24 +203,20 @@ class Wholedisk: def __repr__(self): "string representation for debugging" - strg = "[" + self.domname + "," - if self.physdev: - strg += self.physdev - strg += "," - if self.loopfile: - strg += self.loopfile + strg = "[" + self.vdev + "," + self.pdev + "," + if self.ldev: + strg += self.ldev strg += "," + str(self.pcount) + ",mapped %ix]" % self.mapped return strg class Partition: """Class representing a domU filesystem (partition) that can be mounted in dom0""" - def __init__(self, whole = None, domname = None, - physdev = None): + def __init__(self, whole = None, vdev = None, pdev = None): "c'tor: setup" - self.wholedisk = whole - self.domname = domname - self.physdev = physdev + self.wholedisk = whole + self.vdev = vdev + self.pdev = pdev self.mountpoint = None def __del__(self): @@ -219,7 +229,7 @@ class Partition: def __repr__(self): "string representation for debugging" - strg = "[" + self.domname + "," + self.physdev + "," + strg = "[" + self.vdev + "," + self.pdev + "," if self.mountpoint: strg += "mounted on " + self.mountpoint + "," else: @@ -235,171 +245,69 @@ class Partition: return if self.wholedisk: self.wholedisk.activatepartitions() - mtpt = tempfile.mkdtemp(prefix = "%s." % self.domname, dir = tmpdir) + mtpt = tempfile.mkdtemp(prefix = "%s." % self.vdev, dir = tmpdir) mopts = "" if fstype: mopts += " -t %s" % fstype mopts += " -o %s" % options - if verbose: - print "domUloader: mount %s %s %s" % (mopts, self.physdev, mtpt) - fd = os.popen("mount %s %s %s" % (mopts, self.physdev, mtpt)) + verbose_print("mount %s %s %s" % (mopts, self.pdev, mtpt)) + fd = os.popen("mount %s %s %s" % (mopts, self.pdev, mtpt)) err = fd.close() if err: - raise RuntimeError("domUloader: Error %i from mount %s %s on %s" % \ - (err, mopts, self.physdev, mtpt)) + raise RuntimeError("Error %i from mount %s %s on %s" % \ + (err, mopts, self.pdev, mtpt)) self.mountpoint = mtpt def umount(self): - "umount filesystem at self.mountpoint" + """umount filesystem at self.mountpoint""" if not self.mountpoint: return - if verbose: - print "domUloader: umount %s" % self.mountpoint + verbose_print("umount %s" % self.mountpoint) fd = os.popen("umount %s" % self.mountpoint) err = fd.close() - os.rmdir(self.mountpoint) + try: + os.rmdir(self.mountpoint) + except: + pass if err: - raise RuntimeError("domUloader: Error %i from umount %s" % \ - (err, self.mountpoint)) - self.mountpoint = None + error("Error %i from umount %s" % (err, self.mountpoint)) + else: + self.mountpoint = None if self.wholedisk: self.wholedisk.deactivatepartitions() - -def setupOneDisk(cfg): - """Sets up one exported disk (incl. partitions if existing) - @param cfg: 4-tuple (uname, dev, mode, backend)""" - from xen.util.blkif import blkdev_uname_to_file - values = cfg[0].split(':') - if len(values) == 2: - (type, dev) = values - else: - (type, subtype, dev) = values - (loopfile, physdev) = (None, None) - if type == "tap": - if subtype == "aio": - # FIXME: if device, "/dev/" may need to be prepended - mode = os.stat(dev)[ST_MODE] - if S_ISBLK(mode): - physdev = dev - else: - loopfile = dev - else: - raise RuntimeError("domUloader: domUloader supports 'tap' only with 'aio'.") - if type == "file": - loopfile = dev - elif type == "phy": - physdev = blkdev_uname_to_file(cfg[0]) - wdisk = Wholedisk(cfg[1], physdev, loopfile) - -def setupDisks(vbds): - """Create a list of all disks from the disk config: - @param vbds: The disk config as list of 4-tuples - (uname, dev, mode, backend)""" - disks = eval(vbds) - for disk in disks: - setupOneDisk(disk) - if verbose: - print "Partitions: " + str(partitions) - -class Fstab: - "Class representing an fstab" - - class FstabEntry: - "Class representing one fstab line" - def __init__(self, line): - "c'tor: parses one line" - spline = line.split() - self.dev, self.mtpt, self.fstype, self.opts = \ - spline[0], spline[1], spline[2], spline[3] - if len(self.mtpt) > 1: - self.mtpt = self.mtpt.rstrip('/') - - def __init__(self, filename): - "c'tor: parses fstab" - self.entries = [] - fd = open(filename) - for line in fd.readlines(): - line = line.strip() - if len(line) == 0 or line[0] == '#': - continue - self.entries.append(Fstab.FstabEntry(line)) - - def find(self, fname): - "Looks for matching filesystem in fstab" - matchlen = 0 - match = None - fnmlst = fname.split('/') - for fs in self.entries: - entlst = fs.mtpt.split('/') - # '/' needs special treatment :-( - if entlst == ['','']: - entlst = [''] - entln = len(entlst) - if len(fnmlst) >= entln and fnmlst[:entln] == entlst \ - and entln > matchlen: - match = fs - matchlen = entln - if not match: - return (None, None) - return (match.dev, match.mtpt) - -def fsFromFstab(kernel, initrd, root): - """Investigate rootFS fstab, check for filesystem that contains the kernel - and return it; also returns adapted kernel and initrd path. - """ - part = findPart(root) - if not part: - raise RuntimeError("domUloader: Root fs %s not exported?" % root) - part.mount() - if not os.access(part.mountpoint + '/etc/fstab', os.R_OK): - part.umount() - raise RuntimeError("domUloader: /etc/fstab not found on %s" % root) - fstab = Fstab(part.mountpoint + '/etc/fstab') - (dev, fs) = fstab.find(kernel) - if not fs: - raise RuntimeError("domUloader: no matching filesystem for image %s found in fstab" % kernel) - #return (None, kernel, initrd) - if fs == '/': - ln = 0 - # this avoids the stupid /dev/root problem - dev = root - else: - ln = len(fs) - kernel = kernel[ln:] - if initrd: - initrd = initrd[ln:] - if verbose: - print "fsFromFstab: %s %s -- %s,%s" % (dev, fs, kernel, initrd) - return (kernel, initrd, dev) - def parseEntry(entry): - "disects bootentry and returns kernel, initrd, filesys" - fs = None - initrd = None + "disects bootentry and returns vdev, kernel, ramdisk" + def bad(): + raise RuntimeError, "Malformed --entry" fsspl = entry.split(':') - if len(fsspl) > 1: - fs = fsspl[0] - entry = fsspl[1] + if len(fsspl) != 2: + bad() + vdev = fsspl[0] + entry = fsspl[1] enspl = entry.split(',') + if len(enspl) not in (1, 2): + bad() # Prepend '/' if missing kernel = enspl[0] + if kernel == '': + bad() if kernel[0] != '/': kernel = '/' + kernel + ramdisk = None if len(enspl) > 1: - initrd = enspl[1] - if initrd[0] != '/': - initrd = '/' + initrd - return kernel, initrd, fs + ramdisk = enspl[1] + if ramdisk != '' and ramdisk[0] != '/': + ramdisk = '/' + ramdisk + return vdev, kernel, ramdisk def copyFile(src, dst): "Wrapper for shutil.filecopy" import shutil - if verbose: - print "domUloader: cp %s %s" % (src, dst) + verbose_print("cp %s %s" % (src, dst)) stat = os.stat(src) if stat.st_size > 16*1024*1024: - raise RuntimeError("domUloader: Too large file %s (%s larger than 16MB)" \ + raise RuntimeError("Too large file %s (%s larger than 16MB)" \ % (src, stat.st_size)) try: shutil.copyfile(src, dst) @@ -407,36 +315,37 @@ def copyFile(src, dst): os.unlink(dst) raise() -def copyKernelAndInitrd(fs, kernel, initrd): - """Finds fs in list of partitions, mounts the partition, copies - kernel [and initrd] off to dom0 files, umounts the parition again, +def copyKernelAndRamdisk(disk, vdev, kernel, ramdisk): + """Finds vdev in list of partitions, mounts the partition, copies + kernel [and ramdisk] off to dom0 files, umounts the parition again, and returns sxpr pointing to these copies.""" + verbose_print("copyKernelAndRamdisk(%s, %s, %s, %s)" % (disk, vdev, kernel, ramdisk)) if dryrun: - return "linux (kernel vmlinuz.dummy) (ramdisk initrd.dummy)" - import shutil - part = findPart(fs) + return "linux (kernel kernel.dummy) (ramdisk ramdisk.dummy)" + part = disk.findPart(vdev) if not part: - raise RuntimeError("domUloader: Filesystem %s not exported\n" % fs) + raise RuntimeError("Partition '%s' does not exist" % vdev) part.mount() try: - (fd, knm) = tempfile.mkstemp(prefix = "vmlinuz.", dir = tmpdir) + (fd, knm) = tempfile.mkstemp(prefix = "kernel.", dir = tmpdir) os.close(fd) copyFile(part.mountpoint + kernel, knm) except: os.unlink(knm) + part.umount() raise if not quiet: - print "Copy kernel %s from %s to %s for booting" % \ - (kernel, fs, knm) + print "Copy kernel %s from %s to %s for booting" % (kernel, vdev, knm) sxpr = "linux (kernel %s)" % knm - if (initrd): + if ramdisk: try: - (fd, inm) = tempfile.mkstemp(prefix = "initrd.", dir = tmpdir) + (fd, inm) = tempfile.mkstemp(prefix = "ramdisk.", dir = tmpdir) os.close(fd) - copyFile(part.mountpoint + initrd, inm) + copyFile(part.mountpoint + ramdisk, inm) except: os.unlink(knm) os.unlink(inm) + part.umount() raise sxpr += "(ramdisk %s)" % inm part.umount() @@ -448,46 +357,49 @@ def main(argv): def usage(): "Help output (usage info)" global verbose, quiet, dryrun - print >> sys.stderr, "domUloader usage: domUloader --disks=disklist [--root=rootFS]\n" \ - + " --entry=kernel[,initrd] [--output=fd] [--quiet] [--dryrun] [--verbose] [--help]\n" + print >> sys.stderr, "domUloader usage: domUloader [--output=fd] [--quiet] [--dryrun] [--verbose]\n" +\ + "[--help] --entry=dev:kernel[,ramdisk] physdisk [virtdisk]\n" print >> sys.stderr, __doc__ - #print "domUloader " + str(argv) try: (optlist, args) = getopt.gnu_getopt(argv, 'qvh', \ - ('disks=', 'root=', 'entry=', 'output=', - 'tmpdir=', 'help', 'quiet', 'dryrun', 'verbose')) + ('entry=', 'output=', 'tmpdir=', 'help', 'quiet', 'dryrun', 'verbose')) except: usage() sys.exit(1) entry = None output = None - root = None - disks = None + pdisk = None + vdisk = None for (opt, oarg) in optlist: if opt in ('-h', '--help'): usage() - sys.exit(0) + sys.exit(1) elif opt in ('-q', '--quiet'): quiet = True elif opt in ('-n', '--dryrun'): dryrun = True elif opt in ('-v', '--verbose'): verbose = True - elif opt == '--root': - root = oarg elif opt == '--output': output = oarg - elif opt == '--disks': - disks = oarg elif opt == '--entry': entry = oarg elif opt == '--tmpdir': tmpdir = oarg - if not entry or not disks: + verbose_print(str(argv)) + + if args: + if len(args) == 2: + pdisk = args[1] + elif len(args) == 3: + pdisk = args[1] + vdisk = args[2] + + if not entry or not pdisk: usage() sys.exit(1) @@ -500,22 +412,34 @@ def main(argv): os.mkdir(tmpdir) os.chmod(tmpdir, 0750) - # We assume kernel and initrd are on the same FS, - # so only one fs - kernel, initrd, fs = parseEntry(entry) - setupDisks(disks) - if not fs: - if not root: - usage() - raise RuntimeError("domUloader: No root= to parse fstab and no disk in bootentry") - sys.exit(1) - kernel, initrd, fs = fsFromFstab(kernel, initrd, root) + vdev, kernel, ramdisk = parseEntry(entry) + if not vdisk: + vdisk = getWholedisk(vdev) + verbose_print("vdisk not specified; guessing '%s' based on '%s'" % (vdisk, vdev)) + if not vdev.startswith(vdisk): + error("Virtual disk '%s' does not match entry '%s'" % (vdisk, entry)) + sys.exit(1) + disk = Wholedisk(vdisk, pdisk) - sxpr = copyKernelAndInitrd(fs, kernel, initrd) - sys.stdout.flush() - os.write(fd, sxpr) + r = 0 + try: + sxpr = copyKernelAndRamdisk(disk, vdev, kernel, ramdisk) + os.write(fd, sxpr) + except Exception, e: + error(str(e)) + r = 1 + + for part in disk.partitions: + part.wholedisk = None + del disk + + return r # Call main if called (and not imported) if __name__ == "__main__": - main(sys.argv) - + r = 1 + try: + r = main(sys.argv) + except Exception, e: + error(str(e)) + sys.exit(r) diff --git a/domheap-no-dma.patch b/domheap-no-dma.patch new file mode 100644 index 0000000..c02b1ad --- /dev/null +++ b/domheap-no-dma.patch @@ -0,0 +1,168 @@ +Index: xen-3.0.4-testing/xen/arch/x86/domain_build.c +=================================================================== +--- xen-3.0.4-testing.orig/xen/arch/x86/domain_build.c ++++ xen-3.0.4-testing/xen/arch/x86/domain_build.c +@@ -473,11 +473,14 @@ int construct_dom0(struct domain *d, + if ( (1UL << order) > nr_pages ) + panic("Domain 0 allocation is too small for kernel image.\n"); + +- /* +- * Allocate from DMA pool: on i386 this ensures that our low-memory 1:1 +- * mapping covers the allocation. +- */ +- if ( (page = alloc_domheap_pages(d, order, MEMF_dma)) == NULL ) ++#ifdef __i386__ ++ /* Ensure that our low-memory 1:1 mapping covers the allocation. */ ++ page = alloc_domheap_pages(d, order, ++ MEMF_bits(30 + (dsi.v_start >> 31))); ++#else ++ page = alloc_domheap_pages(d, order, 0); ++#endif ++ if ( page == NULL ) + panic("Not enough RAM for domain 0 allocation.\n"); + alloc_spfn = page_to_mfn(page); + alloc_epfn = alloc_spfn + d->tot_pages; +Index: xen-3.0.4-testing/xen/common/memory.c +=================================================================== +--- xen-3.0.4-testing.orig/xen/common/memory.c ++++ xen-3.0.4-testing/xen/common/memory.c +@@ -322,12 +322,12 @@ static long memory_exchange(XEN_GUEST_HA + (exch.out.address_bits < + (get_order_from_pages(max_page) + PAGE_SHIFT)) ) + { +- if ( exch.out.address_bits < dma_bitsize ) ++ if ( exch.out.address_bits <= PAGE_SHIFT ) + { + rc = -ENOMEM; + goto fail_early; + } +- memflags = MEMF_dma; ++ memflags = MEMF_bits(exch.out.address_bits); + } + + if ( exch.in.extent_order <= exch.out.extent_order ) +@@ -535,9 +535,9 @@ long do_memory_op(unsigned long cmd, XEN + (reservation.address_bits < + (get_order_from_pages(max_page) + PAGE_SHIFT)) ) + { +- if ( reservation.address_bits < dma_bitsize ) ++ if ( reservation.address_bits <= PAGE_SHIFT ) + return start_extent; +- args.memflags = MEMF_dma; ++ args.memflags = MEMF_bits(reservation.address_bits); + } + + if ( likely(reservation.domid == DOMID_SELF) ) +Index: xen-3.0.4-testing/xen/common/page_alloc.c +=================================================================== +--- xen-3.0.4-testing.orig/xen/common/page_alloc.c ++++ xen-3.0.4-testing/xen/common/page_alloc.c +@@ -62,8 +62,8 @@ custom_param("lowmem_emergency_pool", pa + /* + * Bit width of the DMA heap. + */ +-unsigned int dma_bitsize = CONFIG_DMA_BITSIZE; +-unsigned long max_dma_mfn = (1UL << (CONFIG_DMA_BITSIZE - PAGE_SHIFT)) - 1; ++static unsigned int dma_bitsize = CONFIG_DMA_BITSIZE; ++static unsigned long max_dma_mfn = (1UL << (CONFIG_DMA_BITSIZE - PAGE_SHIFT)) - 1; + static void parse_dma_bits(char *s) + { + unsigned int v = simple_strtol(s, NULL, 0); +@@ -72,7 +72,7 @@ static void parse_dma_bits(char *s) + dma_bitsize = BITS_PER_LONG + PAGE_SHIFT; + max_dma_mfn = ~0UL; + } +- else if ( v > PAGE_SHIFT ) ++ else if ( v > PAGE_SHIFT + 1 ) + { + dma_bitsize = v; + max_dma_mfn = (1UL << (dma_bitsize - PAGE_SHIFT)) - 1; +@@ -725,12 +725,22 @@ struct page_info *__alloc_domheap_pages( + struct page_info *pg = NULL; + cpumask_t mask; + unsigned long i; ++ unsigned int bits = memflags >> _MEMF_bits, zone_hi; + + ASSERT(!in_irq()); + +- if ( !(memflags & MEMF_dma) ) ++ if ( bits && bits <= PAGE_SHIFT + 1 ) ++ return NULL; ++ ++ zone_hi = bits - PAGE_SHIFT - 1; ++ if ( zone_hi >= NR_ZONES ) ++ zone_hi = NR_ZONES - 1; ++ ++ if ( NR_ZONES + PAGE_SHIFT > dma_bitsize && ++ (!bits || bits > dma_bitsize) ) + { +- pg = alloc_heap_pages(dma_bitsize - PAGE_SHIFT, NR_ZONES - 1, cpu, order); ++ pg = alloc_heap_pages(dma_bitsize - PAGE_SHIFT, zone_hi, cpu, order); ++ + /* Failure? Then check if we can fall back to the DMA pool. */ + if ( unlikely(pg == NULL) && + ((order > MAX_ORDER) || +@@ -743,7 +753,7 @@ struct page_info *__alloc_domheap_pages( + + if ( pg == NULL ) + if ( (pg = alloc_heap_pages(MEMZONE_XEN + 1, +- dma_bitsize - PAGE_SHIFT - 1, ++ zone_hi, + cpu, order)) == NULL ) + return NULL; + +Index: xen-3.0.4-testing/xen/include/asm-ia64/config.h +=================================================================== +--- xen-3.0.4-testing.orig/xen/include/asm-ia64/config.h ++++ xen-3.0.4-testing/xen/include/asm-ia64/config.h +@@ -41,7 +41,7 @@ + #define CONFIG_IOSAPIC + #define supervisor_mode_kernel (0) + +-#define CONFIG_DMA_BITSIZE 30 ++#define CONFIG_DMA_BITSIZE 32 + + /* If PERFC is used, include privop maps. */ + #ifdef PERF_COUNTERS +Index: xen-3.0.4-testing/xen/include/asm-x86/config.h +=================================================================== +--- xen-3.0.4-testing.orig/xen/include/asm-x86/config.h ++++ xen-3.0.4-testing/xen/include/asm-x86/config.h +@@ -82,7 +82,7 @@ + /* Debug stack is restricted to 8kB by guard pages. */ + #define DEBUG_STACK_SIZE 8192 + +-#define CONFIG_DMA_BITSIZE 30 ++#define CONFIG_DMA_BITSIZE 32 + + #ifndef __ASSEMBLY__ + extern unsigned long _end; /* standard ELF symbol */ +Index: xen-3.0.4-testing/xen/include/xen/mm.h +=================================================================== +--- xen-3.0.4-testing.orig/xen/include/xen/mm.h ++++ xen-3.0.4-testing/xen/include/xen/mm.h +@@ -71,10 +71,10 @@ int assign_pages( + unsigned int memflags); + + /* memflags: */ +-#define _MEMF_dma 0 +-#define MEMF_dma (1U<<_MEMF_dma) +-#define _MEMF_no_refcount 1 ++#define _MEMF_no_refcount 0 + #define MEMF_no_refcount (1U<<_MEMF_no_refcount) ++#define _MEMF_bits 24 ++#define MEMF_bits(n) ((n)<<_MEMF_bits) + + #ifdef CONFIG_PAGEALLOC_MAX_ORDER + #define MAX_ORDER CONFIG_PAGEALLOC_MAX_ORDER +@@ -82,10 +82,6 @@ int assign_pages( + #define MAX_ORDER 20 /* 2^20 contiguous pages */ + #endif + +-/* DMA heap parameters. */ +-extern unsigned int dma_bitsize; +-extern unsigned long max_dma_mfn; +- + /* Automatic page scrubbing for dead domains. */ + extern struct list_head page_scrub_list; + #define page_scrub_schedule_work() \ diff --git a/emul-privop-lock.patch b/emul-privop-lock.patch new file mode 100644 index 0000000..e5564db --- /dev/null +++ b/emul-privop-lock.patch @@ -0,0 +1,76 @@ +Index: 2007-01-31/xen/arch/x86/traps.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/traps.c 2007-01-31 09:41:46.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/traps.c 2007-01-31 09:41:54.000000000 +0100 +@@ -1196,7 +1196,7 @@ static int emulate_privileged_op(struct + { + struct vcpu *v = current; + unsigned long *reg, eip = regs->eip, res; +- u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0, rex = 0; ++ u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0, lock = 0, rex = 0; + enum { lm_seg_none, lm_seg_fs, lm_seg_gs } lm_ovr = lm_seg_none; + unsigned int port, i, data_sel, ar, data, rc; + unsigned int op_bytes, op_default, ad_bytes, ad_default; +@@ -1261,6 +1261,7 @@ static int emulate_privileged_op(struct + data_sel = regs->ss; + continue; + case 0xf0: /* LOCK */ ++ lock = 1; + continue; + case 0xf2: /* REPNE/REPNZ */ + case 0xf3: /* REP/REPE/REPZ */ +@@ -1287,6 +1288,9 @@ static int emulate_privileged_op(struct + if ( opcode == 0x0f ) + goto twobyte_opcode; + ++ if ( lock ) ++ goto fail; ++ + /* Input/Output String instructions. */ + if ( (opcode >= 0x6c) && (opcode <= 0x6f) ) + { +@@ -1550,6 +1554,8 @@ static int emulate_privileged_op(struct + + /* Privileged (ring 0) instructions. */ + opcode = insn_fetch(u8, code_base, eip, code_limit); ++ if ( lock && (opcode & ~3) != 0x20 ) ++ goto fail; + switch ( opcode ) + { + case 0x06: /* CLTS */ +@@ -1568,7 +1574,7 @@ static int emulate_privileged_op(struct + + case 0x20: /* MOV CR?, */ + opcode = insn_fetch(u8, code_base, eip, code_limit); +- modrm_reg |= (opcode >> 3) & 7; ++ modrm_reg += ((opcode >> 3) & 7) + (lock << 3); + modrm_rm |= (opcode >> 0) & 7; + reg = decode_register(modrm_rm, regs, 0); + switch ( modrm_reg ) +@@ -1608,7 +1614,7 @@ static int emulate_privileged_op(struct + + case 0x21: /* MOV DR?, */ + opcode = insn_fetch(u8, code_base, eip, code_limit); +- modrm_reg |= (opcode >> 3) & 7; ++ modrm_reg += ((opcode >> 3) & 7) + (lock << 3); + modrm_rm |= (opcode >> 0) & 7; + reg = decode_register(modrm_rm, regs, 0); + if ( (res = do_get_debugreg(modrm_reg)) > (unsigned long)-256 ) +@@ -1618,7 +1624,7 @@ static int emulate_privileged_op(struct + + case 0x22: /* MOV ,CR? */ + opcode = insn_fetch(u8, code_base, eip, code_limit); +- modrm_reg |= (opcode >> 3) & 7; ++ modrm_reg += ((opcode >> 3) & 7) + (lock << 3); + modrm_rm |= (opcode >> 0) & 7; + reg = decode_register(modrm_rm, regs, 0); + switch ( modrm_reg ) +@@ -1666,7 +1672,7 @@ static int emulate_privileged_op(struct + + case 0x23: /* MOV ,DR? */ + opcode = insn_fetch(u8, code_base, eip, code_limit); +- modrm_reg |= (opcode >> 3) & 7; ++ modrm_reg += ((opcode >> 3) & 7) + (lock << 3); + modrm_rm |= (opcode >> 0) & 7; + reg = decode_register(modrm_rm, regs, 0); + if ( do_set_debugreg(modrm_reg, *reg) != 0 ) diff --git a/fbback-bimodal.diff b/fbback-bimodal.diff new file mode 100644 index 0000000..5496936 --- /dev/null +++ b/fbback-bimodal.diff @@ -0,0 +1,158 @@ +bimodal: pvfb backend + +Teach pvfb backend to deal with bith 32 and 64 bit frontends. + +Signed-off-by: Gerd Hoffmann +--- + tools/xenfb/xenfb.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 87 insertions(+), 11 deletions(-) + +Index: build-32-release304-13133/tools/xenfb/xenfb.c +=================================================================== +--- build-32-release304-13133.orig/tools/xenfb/xenfb.c ++++ build-32-release304-13133/tools/xenfb/xenfb.c +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -40,6 +41,7 @@ struct xenfb_private { + struct xs_handle *xsh; /* xs daemon handle */ + struct xenfb_device fb, kbd; + size_t fb_len; /* size of framebuffer */ ++ char protocol[64]; /* frontend protocol */ + }; + + static void xenfb_detach_dom(struct xenfb_private *); +@@ -324,36 +326,107 @@ static int xenfb_wait_for_frontend_initi + return 0; + } + ++static void xenfb_copy_mfns(int mode, int count, unsigned long *dst, void *src) ++{ ++ uint32_t *src32 = src; ++ uint64_t *src64 = src; ++ int i; ++ ++ for (i = 0; i < count; i++) ++ dst[i] = (mode == 32) ? src32[i] : src64[i]; ++} ++ + static int xenfb_map_fb(struct xenfb_private *xenfb, int domid) + { + struct xenfb_page *page = xenfb->fb.page; + int n_fbmfns; + int n_fbdirs; +- unsigned long *fbmfns; ++ unsigned long *pgmfns = NULL; ++ unsigned long *fbmfns = NULL; ++ void *map, *pd; ++ int mode, ret = -1; ++ ++ /* default to native */ ++ pd = page->pd; ++ mode = sizeof(unsigned long) * 8; ++ ++ if (0 == strlen(xenfb->protocol)) { ++ /* ++ * Undefined protocol, some guesswork needed. ++ * ++ * Old frontends which don't set the protocol use ++ * one page directory only, thus pd[1] must be zero. ++ * pd[1] of the 32bit struct layout and the lower ++ * 32 bits of pd[0] of the 64bit struct layout have ++ * the same location, so we can check that ... ++ */ ++ uint32_t *ptr32 = NULL; ++ uint32_t *ptr64 = NULL; ++#if defined(__i386__) ++ ptr32 = (void*)page->pd; ++ ptr64 = ((void*)page->pd) + 4; ++#elif defined(__x86_64__) ++ ptr32 = ((void*)page->pd) - 4; ++ ptr64 = (void*)page->pd; ++#endif ++ if (ptr32) { ++ if (0 == ptr32[1]) { ++ mode = 32; ++ pd = ptr32; ++ } else { ++ mode = 64; ++ pd = ptr64; ++ } ++ } ++#if defined(__x86_64__) ++ } else if (0 == strcmp(xenfb->protocol, XEN_IO_PROTO_ABI_X86_32)) { ++ /* 64bit dom0, 32bit domU */ ++ mode = 32; ++ pd = ((void*)page->pd) - 4; ++#elif defined(__i386__) ++ } else if (0 == strcmp(xenfb->protocol, XEN_IO_PROTO_ABI_X86_64)) { ++ /* 32bit dom0, 64bit domU */ ++ mode = 64; ++ pd = ((void*)page->pd) + 4; ++#endif ++ } + + n_fbmfns = (xenfb->fb_len + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE; +- n_fbdirs = n_fbmfns * sizeof(unsigned long); ++ n_fbdirs = n_fbmfns * mode / 8; + n_fbdirs = (n_fbdirs + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE; + ++ pgmfns = malloc(sizeof(unsigned long) * n_fbdirs); ++ fbmfns = malloc(sizeof(unsigned long) * n_fbmfns); ++ if (!pgmfns || !fbmfns) ++ goto out; ++ + /* + * Bug alert: xc_map_foreign_batch() can fail partly and + * return a non-null value. This is a design flaw. When it + * happens, we happily continue here, and later crash on + * access. + */ +- fbmfns = xc_map_foreign_batch(xenfb->xc, domid, +- PROT_READ, page->pd, n_fbdirs); +- if (fbmfns == NULL) +- return -1; ++ xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd); ++ map = xc_map_foreign_batch(xenfb->xc, domid, ++ PROT_READ, pgmfns, n_fbdirs); ++ if (map == NULL) ++ goto out; ++ xenfb_copy_mfns(mode, n_fbmfns, fbmfns, map); ++ munmap(map, n_fbdirs * XC_PAGE_SIZE); + + xenfb->pub.pixels = xc_map_foreign_batch(xenfb->xc, domid, + PROT_READ | PROT_WRITE, fbmfns, n_fbmfns); +- if (xenfb->pub.pixels == NULL) { +- munmap(fbmfns, n_fbdirs * XC_PAGE_SIZE); +- return -1; +- } ++ if (xenfb->pub.pixels == NULL) ++ goto out; + +- return munmap(fbmfns, n_fbdirs * XC_PAGE_SIZE); ++ ret = 0; /* all is fine */ ++ ++ out: ++ if (pgmfns) ++ free(pgmfns); ++ if (fbmfns) ++ free(fbmfns); ++ return ret; + } + + static int xenfb_bind(struct xenfb_device *dev) +@@ -491,6 +564,9 @@ int xenfb_attach_dom(struct xenfb *xenfb + errno = ENOTSUP; + goto error; + } ++ if (xenfb_xs_scanf1(xsh, xenfb->fb.otherend, "protocol", "%63s", ++ xenfb->protocol) < 0) ++ xenfb->protocol[0] = '\0'; + xenfb_xs_printf(xsh, xenfb->fb.nodename, "request-update", "1"); + + /* TODO check for permitted ranges */ diff --git a/hide-asm-labels.patch b/hide-asm-labels.patch new file mode 100644 index 0000000..ac168a3 --- /dev/null +++ b/hide-asm-labels.patch @@ -0,0 +1,505 @@ +Index: 2006-12-11/xen/arch/x86/x86_32/entry.S +=================================================================== +--- 2006-12-11.orig/xen/arch/x86/x86_32/entry.S 2006-12-15 15:21:44.000000000 +0100 ++++ 2006-12-11/xen/arch/x86/x86_32/entry.S 2006-12-15 15:39:13.000000000 +0100 +@@ -84,10 +84,10 @@ restore_all_guest: + jmp restore_all_vm86 + 1: + #endif +-FLT1: mov UREGS_ds(%esp),%ds +-FLT2: mov UREGS_es(%esp),%es +-FLT3: mov UREGS_fs(%esp),%fs +-FLT4: mov UREGS_gs(%esp),%gs ++.LFT1: mov UREGS_ds(%esp),%ds ++.LFT2: mov UREGS_es(%esp),%es ++.LFT3: mov UREGS_fs(%esp),%fs ++.LFT4: mov UREGS_gs(%esp),%gs + restore_all_vm86: + popl %ebx + popl %ecx +@@ -97,9 +97,9 @@ restore_all_vm86: + popl %ebp + popl %eax + addl $4,%esp +-FLT5: iret ++.LFT5: iret + .section .fixup,"ax" +-FIX5: subl $28,%esp ++.LFX5: subl $28,%esp + pushl 28(%esp) # error_code/entry_vector + movl %eax,UREGS_eax+4(%esp) + movl %ebp,UREGS_ebp+4(%esp) +@@ -108,7 +108,7 @@ FIX5: subl $28,%esp + movl %edx,UREGS_edx+4(%esp) + movl %ecx,UREGS_ecx+4(%esp) + movl %ebx,UREGS_ebx+4(%esp) +-FIX1: SET_XEN_SEGMENTS(a) ++.LFX1: SET_XEN_SEGMENTS(a) + movl %eax,%fs + movl %eax,%gs + sti +@@ -116,11 +116,11 @@ FIX1: SET_XEN_SEGMENTS(a) + pushfl # EFLAGS + movl $__HYPERVISOR_CS,%eax + pushl %eax # CS +- movl $DBLFLT1,%eax ++ movl $.LDF1,%eax + pushl %eax # EIP + pushl %esi # error_code/entry_vector + jmp handle_exception +-DBLFLT1:GET_CURRENT(%ebx) ++.LDF1: GET_CURRENT(%ebx) + jmp test_all_events + failsafe_callback: + GET_CURRENT(%ebx) +@@ -142,14 +142,14 @@ failsafe_callback: + jmp test_all_events + .previous + .section __pre_ex_table,"a" +- .long FLT1,FIX1 +- .long FLT2,FIX1 +- .long FLT3,FIX1 +- .long FLT4,FIX1 +- .long FLT5,FIX5 ++ .long .LFT1,.LFX1 ++ .long .LFT2,.LFX1 ++ .long .LFT3,.LFX1 ++ .long .LFT4,.LFX1 ++ .long .LFT5,.LFX5 + .previous + .section __ex_table,"a" +- .long DBLFLT1,failsafe_callback ++ .long .LDF1,failsafe_callback + .previous + + ALIGN +@@ -288,32 +288,33 @@ create_bounce_frame: + testl $(2|X86_EFLAGS_VM),%ecx + jz ring1 /* jump if returning to an existing ring-1 activation */ + movl VCPU_kernel_sp(%ebx),%esi +-FLT6: mov VCPU_kernel_ss(%ebx),%gs ++.LFT6: mov VCPU_kernel_ss(%ebx),%gs + testl $X86_EFLAGS_VM,UREGS_eflags+4(%esp) +- jz nvm86_1 ++ jz .Lnvm86_1 + subl $16,%esi /* push ES/DS/FS/GS (VM86 stack frame) */ + movl UREGS_es+4(%esp),%eax +-FLT7: movl %eax,%gs:(%esi) ++.LFT7: movl %eax,%gs:(%esi) + movl UREGS_ds+4(%esp),%eax +-FLT8: movl %eax,%gs:4(%esi) ++.LFT8: movl %eax,%gs:4(%esi) + movl UREGS_fs+4(%esp),%eax +-FLT9: movl %eax,%gs:8(%esi) ++.LFT9: movl %eax,%gs:8(%esi) + movl UREGS_gs+4(%esp),%eax +-FLT10: movl %eax,%gs:12(%esi) +-nvm86_1:subl $8,%esi /* push SS/ESP (inter-priv iret) */ ++.LFT10: movl %eax,%gs:12(%esi) ++.Lnvm86_1: ++ subl $8,%esi /* push SS/ESP (inter-priv iret) */ + movl UREGS_esp+4(%esp),%eax +-FLT11: movl %eax,%gs:(%esi) ++.LFT11: movl %eax,%gs:(%esi) + movl UREGS_ss+4(%esp),%eax +-FLT12: movl %eax,%gs:4(%esi) ++.LFT12: movl %eax,%gs:4(%esi) + jmp 1f + ring1: /* obtain ss/esp from oldss/oldesp -- a ring-1 activation exists */ + movl UREGS_esp+4(%esp),%esi +-FLT13: mov UREGS_ss+4(%esp),%gs ++.LFT13: mov UREGS_ss+4(%esp),%gs + 1: /* Construct a stack frame: EFLAGS, CS/EIP */ + movb TRAPBOUNCE_flags(%edx),%cl + subl $12,%esi + movl UREGS_eip+4(%esp),%eax +-FLT14: movl %eax,%gs:(%esi) ++.LFT14: movl %eax,%gs:(%esi) + movl VCPU_vcpu_info(%ebx),%eax + pushl VCPUINFO_upcall_mask(%eax) + testb $TBF_INTERRUPT,%cl +@@ -324,49 +325,51 @@ FLT14: movl %eax,%gs:(%esi) + movw UREGS_cs+4(%esp),%ax # Bits 0-15: CS + #ifdef CONFIG_X86_SUPERVISOR_MODE_KERNEL + testw $2,%ax +- jnz FLT15 ++ jnz .LFT15 + and $~3,%ax # RPL 1 -> RPL 0 + #endif +-FLT15: movl %eax,%gs:4(%esi) ++.LFT15: movl %eax,%gs:4(%esi) + test $0x00FF0000,%eax # Bits 16-23: saved_upcall_mask + setz %ch # %ch == !saved_upcall_mask + movl UREGS_eflags+4(%esp),%eax + andl $~X86_EFLAGS_IF,%eax + shlb $1,%ch # Bit 9 (EFLAGS.IF) + orb %ch,%ah # Fold EFLAGS.IF into %eax +-FLT16: movl %eax,%gs:8(%esi) ++.LFT16: movl %eax,%gs:8(%esi) + test $TBF_EXCEPTION_ERRCODE,%cl + jz 1f + subl $4,%esi # push error_code onto guest frame + movl TRAPBOUNCE_error_code(%edx),%eax +-FLT17: movl %eax,%gs:(%esi) ++.LFT17: movl %eax,%gs:(%esi) + 1: testb $TBF_FAILSAFE,%cl + jz 2f + subl $16,%esi # add DS/ES/FS/GS to failsafe stack frame + testl $X86_EFLAGS_VM,UREGS_eflags+4(%esp) +- jz nvm86_2 ++ jz .Lnvm86_2 + xorl %eax,%eax # VM86: we write zero selector values +-FLT18: movl %eax,%gs:(%esi) +-FLT19: movl %eax,%gs:4(%esi) +-FLT20: movl %eax,%gs:8(%esi) +-FLT21: movl %eax,%gs:12(%esi) ++.LFT18: movl %eax,%gs:(%esi) ++.LFT19: movl %eax,%gs:4(%esi) ++.LFT20: movl %eax,%gs:8(%esi) ++.LFT21: movl %eax,%gs:12(%esi) + jmp 2f +-nvm86_2:movl UREGS_ds+4(%esp),%eax # non-VM86: write real selector values +-FLT22: movl %eax,%gs:(%esi) ++.Lnvm86_2: ++ movl UREGS_ds+4(%esp),%eax # non-VM86: write real selector values ++.LFT22: movl %eax,%gs:(%esi) + movl UREGS_es+4(%esp),%eax +-FLT23: movl %eax,%gs:4(%esi) ++.LFT23: movl %eax,%gs:4(%esi) + movl UREGS_fs+4(%esp),%eax +-FLT24: movl %eax,%gs:8(%esi) ++.LFT24: movl %eax,%gs:8(%esi) + movl UREGS_gs+4(%esp),%eax +-FLT25: movl %eax,%gs:12(%esi) ++.LFT25: movl %eax,%gs:12(%esi) + 2: testl $X86_EFLAGS_VM,UREGS_eflags+4(%esp) +- jz nvm86_3 ++ jz .Lnvm86_3 + xorl %eax,%eax /* zero DS-GS, just as a real CPU would */ + movl %eax,UREGS_ds+4(%esp) + movl %eax,UREGS_es+4(%esp) + movl %eax,UREGS_fs+4(%esp) + movl %eax,UREGS_gs+4(%esp) +-nvm86_3:/* Rewrite our stack frame and return to ring 1. */ ++.Lnvm86_3: ++ /* Rewrite our stack frame and return to ring 1. */ + /* IA32 Ref. Vol. 3: TF, VM, RF and NT flags are cleared on trap. */ + andl $~(X86_EFLAGS_VM|X86_EFLAGS_RF|\ + X86_EFLAGS_NT|X86_EFLAGS_TF),UREGS_eflags+4(%esp) +@@ -382,16 +385,16 @@ nvm86_3:/* Rewrite our stack frame and r + movb $0,TRAPBOUNCE_flags(%edx) + ret + .section __ex_table,"a" +- .long FLT6,domain_crash_synchronous , FLT7,domain_crash_page_fault +- .long FLT8,domain_crash_page_fault_4 , FLT9,domain_crash_page_fault_8 +- .long FLT10,domain_crash_page_fault_12, FLT11,domain_crash_page_fault +- .long FLT12,domain_crash_page_fault_4 , FLT13,domain_crash_synchronous +- .long FLT14,domain_crash_page_fault , FLT15,domain_crash_page_fault_4 +- .long FLT16,domain_crash_page_fault_8 , FLT17,domain_crash_page_fault +- .long FLT18,domain_crash_page_fault , FLT19,domain_crash_page_fault_4 +- .long FLT20,domain_crash_page_fault_8 , FLT21,domain_crash_page_fault_12 +- .long FLT22,domain_crash_page_fault , FLT23,domain_crash_page_fault_4 +- .long FLT24,domain_crash_page_fault_8 , FLT25,domain_crash_page_fault_12 ++ .long .LFT6,domain_crash_synchronous , .LFT7,domain_crash_page_fault ++ .long .LFT8,domain_crash_page_fault_4 , .LFT9,domain_crash_page_fault_8 ++ .long .LFT10,domain_crash_page_fault_12, .LFT11,domain_crash_page_fault ++ .long .LFT12,domain_crash_page_fault_4 , .LFT13,domain_crash_synchronous ++ .long .LFT14,domain_crash_page_fault , .LFT15,domain_crash_page_fault_4 ++ .long .LFT16,domain_crash_page_fault_8 , .LFT17,domain_crash_page_fault ++ .long .LFT18,domain_crash_page_fault , .LFT19,domain_crash_page_fault_4 ++ .long .LFT20,domain_crash_page_fault_8 , .LFT21,domain_crash_page_fault_12 ++ .long .LFT22,domain_crash_page_fault , .LFT23,domain_crash_page_fault_4 ++ .long .LFT24,domain_crash_page_fault_8 , .LFT25,domain_crash_page_fault_12 + .previous + + .section .rodata,"a" +Index: 2006-12-11/xen/arch/x86/x86_64/compat/entry.S +=================================================================== +--- 2006-12-11.orig/xen/arch/x86/x86_64/compat/entry.S 2006-12-15 15:39:03.000000000 +0100 ++++ 2006-12-11/xen/arch/x86/x86_64/compat/entry.S 2006-12-15 15:39:13.000000000 +0100 +@@ -118,10 +118,10 @@ compat_bad_hypercall: + compat_restore_all_guest: + RESTORE_ALL + addq $8,%rsp +-CFLT0: iretq ++.Lft0: iretq + + .section .fixup,"ax" +-CFIX0: popq -15*8-8(%rsp) # error_code/entry_vector ++.Lfx0: popq -15*8-8(%rsp) # error_code/entry_vector + SAVE_ALL # 15*8 bytes pushed + movq -8(%rsp),%rsi # error_code/entry_vector + sti # after stack abuse (-1024(%rsp)) +@@ -130,11 +130,11 @@ CFIX0: popq -15*8-8(%rsp) # + pushq %rax # RSP + pushfq # RFLAGS + pushq $__HYPERVISOR_CS # CS +- leaq CDBLFLT0(%rip),%rax ++ leaq .Ldf0(%rip),%rax + pushq %rax # RIP + pushq %rsi # error_code/entry_vector + jmp handle_exception +-CDBLFLT0:GET_CURRENT(%rbx) ++.Ldf0: GET_CURRENT(%rbx) + jmp compat_test_all_events + compat_failsafe_callback: + GET_CURRENT(%rbx) +@@ -152,10 +152,10 @@ compat_failsafe_callback: + jmp compat_test_all_events + .previous + .section __pre_ex_table,"a" +- .quad CFLT0,CFIX0 ++ .quad .Lft0,.Lfx0 + .previous + .section __ex_table,"a" +- .quad CDBLFLT0,compat_failsafe_callback ++ .quad .Ldf0,compat_failsafe_callback + .previous + + /* %rdx: trap_bounce, %rbx: struct vcpu */ +@@ -175,16 +175,16 @@ compat_create_bounce_frame: + jz 1f + /* Push new frame at registered guest-OS stack base. */ + movl VCPU_kernel_sp(%rbx),%esi +-CFLT1: mov VCPU_kernel_ss(%rbx),%fs ++.Lft1: mov VCPU_kernel_ss(%rbx),%fs + subl $2*4,%esi + movl UREGS_rsp+8(%rsp),%eax +-CFLT2: movl %eax,%fs:(%rsi) ++.Lft2: movl %eax,%fs:(%rsi) + movl UREGS_ss+8(%rsp),%eax +-CFLT3: movl %eax,%fs:4(%rsi) ++.Lft3: movl %eax,%fs:4(%rsi) + jmp 2f + 1: /* In kernel context already: push new frame at existing %rsp. */ + movl UREGS_rsp+8(%rsp),%esi +-CFLT4: mov UREGS_ss+8(%rsp),%fs ++.Lft4: mov UREGS_ss+8(%rsp),%fs + 2: + movb TRAPBOUNCE_flags(%rdx),%cl + subl $3*4,%esi +@@ -196,7 +196,7 @@ CFLT4: mov UREGS_ss+8(%rsp),%fs + popq %rax + shll $16,%eax # Bits 16-23: saved_upcall_mask + movw UREGS_cs+8(%rsp),%ax # Bits 0-15: CS +-CFLT5: movl %eax,%fs:4(%rsi) # CS / saved_upcall_mask ++.Lft5: movl %eax,%fs:4(%rsi) # CS / saved_upcall_mask + shrl $16,%eax + testb %al,%al # Bits 0-7: saved_upcall_mask + setz %ch # %ch == !saved_upcall_mask +@@ -204,25 +204,25 @@ CFLT5: movl %eax,%fs:4(%rsi) + andl $~X86_EFLAGS_IF,%eax + shlb $1,%ch # Bit 9 (EFLAGS.IF) + orb %ch,%ah # Fold EFLAGS.IF into %eax +-CFLT6: movl %eax,%fs:2*4(%rsi) # EFLAGS ++.Lft6: movl %eax,%fs:2*4(%rsi) # EFLAGS + movl UREGS_rip+8(%rsp),%eax +-CFLT7: movl %eax,%fs:(%rsi) # EIP ++.Lft7: movl %eax,%fs:(%rsi) # EIP + testb $TBF_EXCEPTION_ERRCODE,%cl + jz 1f + subl $4,%esi + movl TRAPBOUNCE_error_code(%rdx),%eax +-CFLT8: movl %eax,%fs:(%rsi) # ERROR CODE ++.Lft8: movl %eax,%fs:(%rsi) # ERROR CODE + 1: + testb $TBF_FAILSAFE,%cl + jz 2f + subl $4*4,%esi + movl %gs,%eax +-CFLT9: movl %eax,%fs:3*4(%rsi) # GS +-CFLT10: movl %edi,%fs:2*4(%rsi) # FS ++.Lft9: movl %eax,%fs:3*4(%rsi) # GS ++.Lft10: movl %edi,%fs:2*4(%rsi) # FS + movl %es,%eax +-CFLT11: movl %eax,%fs:1*4(%rsi) # ES ++.Lft11: movl %eax,%fs:1*4(%rsi) # ES + movl %ds,%eax +-CFLT12: movl %eax,%fs:0*4(%rsi) # DS ++.Lft12: movl %eax,%fs:0*4(%rsi) # DS + 2: + /* Rewrite our stack frame and return to guest-OS mode. */ + /* IA32 Ref. Vol. 3: TF, VM, RF and NT flags are cleared on trap. */ +@@ -231,7 +231,7 @@ CFLT12: movl %eax,%fs:0*4(%rsi) + X86_EFLAGS_NT|X86_EFLAGS_TF),UREGS_eflags+8(%rsp) + mov %fs,UREGS_ss+8(%rsp) + movl %esi,UREGS_rsp+8(%rsp) +-CFLT13: mov %edi,%fs ++.Lft13: mov %edi,%fs + movzwl TRAPBOUNCE_cs(%rdx),%eax + /* Null selectors (0-3) are not allowed. */ + testl $~3,%eax +@@ -242,18 +242,18 @@ CFLT13: mov %edi,%fs + movb $0,TRAPBOUNCE_flags(%rdx) + ret + .section .fixup,"ax" +-CFIX13: ++.Lfx13: + xorl %edi,%edi +- jmp CFLT13 ++ jmp .Lft13 + .previous + .section __ex_table,"a" +- .quad CFLT1,domain_crash_synchronous , CFLT2,compat_crash_page_fault +- .quad CFLT3,compat_crash_page_fault_4 , CFLT4,domain_crash_synchronous +- .quad CFLT5,compat_crash_page_fault_4 , CFLT6,compat_crash_page_fault_8 +- .quad CFLT7,compat_crash_page_fault , CFLT8,compat_crash_page_fault +- .quad CFLT9,compat_crash_page_fault_12, CFLT10,compat_crash_page_fault_8 +- .quad CFLT11,compat_crash_page_fault_4 , CFLT12,compat_crash_page_fault +- .quad CFLT13,CFIX13 ++ .quad .Lft1,domain_crash_synchronous , .Lft2,compat_crash_page_fault ++ .quad .Lft3,compat_crash_page_fault_4 , .Lft4,domain_crash_synchronous ++ .quad .Lft5,compat_crash_page_fault_4 , .Lft6,compat_crash_page_fault_8 ++ .quad .Lft7,compat_crash_page_fault , .Lft8,compat_crash_page_fault ++ .quad .Lft9,compat_crash_page_fault_12, .Lft10,compat_crash_page_fault_8 ++ .quad .Lft11,compat_crash_page_fault_4 , .Lft12,compat_crash_page_fault ++ .quad .Lft13,.Lfx13 + .previous + + compat_crash_page_fault_12: +@@ -263,17 +263,17 @@ compat_crash_page_fault_8: + compat_crash_page_fault_4: + addl $4,%esi + compat_crash_page_fault: +-CFLT14: mov %edi,%fs ++.Lft14: mov %edi,%fs + movl %esi,%edi + call show_page_walk + jmp domain_crash_synchronous + .section .fixup,"ax" +-CFIX14: ++.Lfx14: + xorl %edi,%edi +- jmp CFLT14 ++ jmp .Lft14 + .previous + .section __ex_table,"a" +- .quad CFLT14,CFIX14 ++ .quad .Lft14,.Lfx14 + .previous + + .section .rodata, "a", @progbits +Index: 2006-12-11/xen/arch/x86/x86_64/entry.S +=================================================================== +--- 2006-12-11.orig/xen/arch/x86/x86_64/entry.S 2006-12-15 15:23:16.000000000 +0100 ++++ 2006-12-11/xen/arch/x86/x86_64/entry.S 2006-12-15 15:39:13.000000000 +0100 +@@ -56,10 +56,10 @@ restore_all_guest: + /* No special register assumptions. */ + iret_exit_to_guest: + addq $8,%rsp +-FLT1: iretq ++.LFT1: iretq + + .section .fixup,"ax" +-FIX1: popq -15*8-8(%rsp) # error_code/entry_vector ++.LFX1: popq -15*8-8(%rsp) # error_code/entry_vector + SAVE_ALL # 15*8 bytes pushed + movq -8(%rsp),%rsi # error_code/entry_vector + sti # after stack abuse (-1024(%rsp)) +@@ -68,11 +68,11 @@ FIX1: popq -15*8-8(%rsp) # + pushq %rax # RSP + pushf # RFLAGS + pushq $__HYPERVISOR_CS # CS +- leaq DBLFLT1(%rip),%rax ++ leaq .LDF1(%rip),%rax + pushq %rax # RIP + pushq %rsi # error_code/entry_vector + jmp handle_exception +-DBLFLT1:GET_CURRENT(%rbx) ++.LDF1: GET_CURRENT(%rbx) + jmp test_all_events + failsafe_callback: + GET_CURRENT(%rbx) +@@ -87,10 +87,10 @@ failsafe_callback: + jmp test_all_events + .previous + .section __pre_ex_table,"a" +- .quad FLT1,FIX1 ++ .quad .LFT1,.LFX1 + .previous + .section __ex_table,"a" +- .quad DBLFLT1,failsafe_callback ++ .quad .LDF1,failsafe_callback + .previous + + ALIGN +@@ -249,9 +249,9 @@ create_bounce_frame: + 1: movb TRAPBOUNCE_flags(%rdx),%cl + subq $40,%rsi + movq UREGS_ss+8(%rsp),%rax +-FLT2: movq %rax,32(%rsi) # SS ++.LFT2: movq %rax,32(%rsi) # SS + movq UREGS_rsp+8(%rsp),%rax +-FLT3: movq %rax,24(%rsi) # RSP ++.LFT3: movq %rax,24(%rsi) # RSP + movq VCPU_vcpu_info(%rbx),%rax + pushq VCPUINFO_upcall_mask(%rax) + testb $TBF_INTERRUPT,%cl +@@ -260,7 +260,7 @@ FLT3: movq %rax,24(%rsi) + popq %rax + shlq $32,%rax # Bits 32-39: saved_upcall_mask + movw UREGS_cs+8(%rsp),%ax # Bits 0-15: CS +-FLT4: movq %rax,8(%rsi) # CS / saved_upcall_mask ++.LFT4: movq %rax,8(%rsi) # CS / saved_upcall_mask + shrq $32,%rax + testb $0xFF,%al # Bits 0-7: saved_upcall_mask + setz %ch # %ch == !saved_upcall_mask +@@ -268,30 +268,30 @@ FLT4: movq %rax,8(%rsi) + andq $~X86_EFLAGS_IF,%rax + shlb $1,%ch # Bit 9 (EFLAGS.IF) + orb %ch,%ah # Fold EFLAGS.IF into %eax +-FLT5: movq %rax,16(%rsi) # RFLAGS ++.LFT5: movq %rax,16(%rsi) # RFLAGS + movq UREGS_rip+8(%rsp),%rax +-FLT6: movq %rax,(%rsi) # RIP ++.LFT6: movq %rax,(%rsi) # RIP + testb $TBF_EXCEPTION_ERRCODE,%cl + jz 1f + subq $8,%rsi + movl TRAPBOUNCE_error_code(%rdx),%eax +-FLT7: movq %rax,(%rsi) # ERROR CODE ++.LFT7: movq %rax,(%rsi) # ERROR CODE + 1: testb $TBF_FAILSAFE,%cl + jz 2f + subq $32,%rsi + movl %gs,%eax +-FLT8: movq %rax,24(%rsi) # GS ++.LFT8: movq %rax,24(%rsi) # GS + movl %fs,%eax +-FLT9: movq %rax,16(%rsi) # FS ++.LFT9: movq %rax,16(%rsi) # FS + movl %es,%eax +-FLT10: movq %rax,8(%rsi) # ES ++.LFT10: movq %rax,8(%rsi) # ES + movl %ds,%eax +-FLT11: movq %rax,(%rsi) # DS ++.LFT11: movq %rax,(%rsi) # DS + 2: subq $16,%rsi + movq UREGS_r11+8(%rsp),%rax +-FLT12: movq %rax,8(%rsi) # R11 ++.LFT12: movq %rax,8(%rsi) # R11 + movq UREGS_rcx+8(%rsp),%rax +-FLT13: movq %rax,(%rsi) # RCX ++.LFT13: movq %rax,(%rsi) # RCX + /* Rewrite our stack frame and return to guest-OS mode. */ + /* IA32 Ref. Vol. 3: TF, VM, RF and NT flags are cleared on trap. */ + /* Also clear AC: alignment checks shouldn't trigger in kernel mode. */ +@@ -308,12 +308,12 @@ FLT13: movq %rax,(%rsi) + movb $0,TRAPBOUNCE_flags(%rdx) + ret + .section __ex_table,"a" +- .quad FLT2,domain_crash_page_fault_32, FLT3,domain_crash_page_fault_24 +- .quad FLT4,domain_crash_page_fault_8 , FLT5,domain_crash_page_fault_16 +- .quad FLT6,domain_crash_page_fault , FLT7,domain_crash_page_fault +- .quad FLT8,domain_crash_page_fault_24, FLT9,domain_crash_page_fault_16 +- .quad FLT10,domain_crash_page_fault_8 , FLT11,domain_crash_page_fault +- .quad FLT12,domain_crash_page_fault_8 , FLT13,domain_crash_page_fault ++ .quad .LFT2,domain_crash_page_fault_32, .LFT3,domain_crash_page_fault_24 ++ .quad .LFT4,domain_crash_page_fault_8 , .LFT5,domain_crash_page_fault_16 ++ .quad .LFT6,domain_crash_page_fault , .LFT7,domain_crash_page_fault ++ .quad .LFT8,domain_crash_page_fault_24, .LFT9,domain_crash_page_fault_16 ++ .quad .LFT10,domain_crash_page_fault_8 , .LFT11,domain_crash_page_fault ++ .quad .LFT12,domain_crash_page_fault_8 , .LFT13,domain_crash_page_fault + .previous + + .section .rodata,"a" diff --git a/init.xend b/init.xend index 585d8a9..1c16be4 100644 --- a/init.xend +++ b/init.xend @@ -48,6 +48,23 @@ cleanup() rm -f /var/lib/xen/xenbl* 2>/dev/null } +parseln() +{ + name=${1:0:$((${#1}-36))} + name=${name%% *} + rest="${1: -36}" + id=${rest:0:4} + id=`echo $id` + mem=${rest:4:6} + mem=`echo $mem` + vcpu=${rest:10:6} + vcpu=`echo $vcpu` + state=${rest:16:11} + state=`echo $state` + tm=${rest:27} + tm=`echo $tm` +} + if [ "$1" == status ]; then if [ ! -e /proc/xen/capabilities ]; then xend_abort 3 @@ -70,7 +87,6 @@ fi XEND=`ps ax | grep xend | grep python | awk '{ print $1 }'` XEND=`echo $XEND` -#export PYTHONOPTIMIZE=2 case "$1" in start) echo -n "Starting xend " @@ -101,14 +117,16 @@ case "$1" in else echo -n "(pid $XEND) " unset sysrq_sent - while read nm id mem vcpu state time; do - if [ $id = 0 ]; then continue; fi + while read LN; do + parseln "$LN" + [ -z "$id" ] && continue + [ "$id" = 0 ] && continue sysrq_sent=1 - echo -en "\n Warning: Domain $nm (ID $id) still up ($state)" + echo -en "\n Warning: Domain $name (ID $id) still up ($state)" # Domains should be closed down by xendomains; anyway, send # SysRq-S to avoid the worst in case domains are not shut down. xm sysrq $id s - done < <(xm list | grep -v ^Name) + done < <(xm list | grep -v '^Name *ID') if [ -n "$sysrq_sent" ]; then sleep 1; fi xend stop cleanup @@ -146,6 +164,5 @@ case "$1" in rc_exit esac -#unset PYTHONOPTIMIZE rc_status -v rc_exit diff --git a/init.xendomains b/init.xendomains index 61a97a5..620962b 100644 --- a/init.xendomains +++ b/init.xendomains @@ -105,10 +105,19 @@ running_auto_names() parseln() { - name=`echo "$1" | cut -c0-49` + name=${1:0:$((${#1}-36))} name=${name%% *} - rest=`echo "$1" | cut -c40- ` - read id mem vcpu state tm < <(echo "$rest") + rest="${1: -36}" + id=${rest:0:4} + id=`echo $id` + mem=${rest:4:6} + mem=`echo $mem` + vcpu=${rest:10:6} + vcpu=`echo $vcpu` + state=${rest:16:11} + state=`echo $state` + tm=${rest:27} + tm=`echo $tm` } is_cfg_running() @@ -116,9 +125,12 @@ is_cfg_running() get_name_from_cfg "$1" while read LN; do parseln "$LN" - [ $id = 0 ] && continue - [ "$name" = "$NM" ] && return 0 - done < <(xm list | grep -v '^Name') + [ "$id" = 0 ] && continue + if [ "$name" = "$NM" ]; then + [ -z "$state" ] && return 1 + return 0 + fi + done < <(xm list | grep -v '^Name *ID') return 1 } @@ -189,9 +201,10 @@ any_non_zombies() { while read LN; do parseln "$LN" - [ $id = 0 ] && continue + [ "$id" = 0 ] && continue + [ -z "$state" ] && continue is_zombie_state "$state" || return 0 - done < <(xm list | grep -v '^Name') + done < <(xm list | grep -v '^Name *ID') return 1 } @@ -261,7 +274,8 @@ stop() local printed=0 while read LN; do parseln "$LN" - [ $id = 0 ] && continue + [ "$id" = 0 ] && continue + [ -z "$state" ] && continue printed=1 if [ "$XENDOMAINS_AUTO_ONLY" = "true" ]; then is_auto_domain=0 @@ -354,7 +368,7 @@ stop() fi rc_status -v fi - done < <(xm list | grep -v '^Name') + done < <(xm list | grep -v '^Name *ID') if [ -n "$XENDOMAINS_SHUTDOWN_ALL" ] && any_non_zombies ; then echo -n " others: shutting down... " @@ -379,9 +393,12 @@ check_domain_up() { while read LN; do parseln "$LN" - [ $id = 0 ] && continue - [ "$name" = "$1" ] && return 0 - done < <(xm list | grep -v "^Name") + [ "$id" = 0 ] && continue + if [ "$name" = "$1" ]; then + [ -z "$state" ] && return 1 + return 0 + fi + done < <(xm list | grep -v '^Name *ID') return 1 } diff --git a/libelf-add-to-xenkernel.diff b/libelf-add-to-xenkernel.diff new file mode 100644 index 0000000..5de12b1 --- /dev/null +++ b/libelf-add-to-xenkernel.diff @@ -0,0 +1,3100 @@ +add libelf: an ELF binary parser library. + +This patch adds a library with a small collection of helper functions +to parse and load elf binaries. The library handles endianess and +elfsize at runtime. + +The patch also shuffles around the include files a bit. Now there is +*one* include file holding all the elf structures +(xen/include/public/elfstructs.h) which is included by everyone who +needs them. + +It's dead code with this patch only, putting the code into use happens +in followup patches. + +Signed-off-by: Gerd Hoffmann +--- + tools/libxc/xc_elf.h | 525 ----------------------------------- + xen/arch/x86/boot/mkelf32.c | 2 + xen/common/Makefile | 2 + xen/common/libelf/Makefile | 4 + xen/common/libelf/README | 1 + xen/common/libelf/libelf-dominfo.c | 420 ++++++++++++++++++++++++++++ + xen/common/libelf/libelf-loader.c | 156 ++++++++++ + xen/common/libelf/libelf-private.h | 51 +++ + xen/common/libelf/libelf-relocate.c | 345 +++++++++++++++++++++++ + xen/common/libelf/libelf-tools.c | 225 +++++++++++++++ + xen/include/public/elfstructs.h | 527 ++++++++++++++++++++++++++++++++++++ + xen/include/public/libelf.h | 238 ++++++++++++++++ + xen/include/xen/elf.h | 490 --------------------------------- + 13 files changed, 1972 insertions(+), 1014 deletions(-) + +Index: build-32-release304-13132/xen/common/Makefile +=================================================================== +--- build-32-release304-13132.orig/xen/common/Makefile ++++ build-32-release304-13132/xen/common/Makefile +@@ -37,6 +37,8 @@ obj-$(CONFIG_XENCOMM) += xencomm.o + + subdir-$(CONFIG_COMPAT) += compat + ++subdir-y += libelf ++ + # Object file contains changeset and compiler information. + version.o: $(BASEDIR)/include/xen/compile.h + +Index: build-32-release304-13132/xen/common/libelf/Makefile +=================================================================== +--- /dev/null ++++ build-32-release304-13132/xen/common/libelf/Makefile +@@ -0,0 +1,4 @@ ++obj-y += libelf-tools.o ++obj-y += libelf-loader.o ++obj-y += libelf-dominfo.o ++#obj-y += libelf-relocate.o +Index: build-32-release304-13132/xen/common/libelf/README +=================================================================== +--- /dev/null ++++ build-32-release304-13132/xen/common/libelf/README +@@ -0,0 +1 @@ ++Take care, this code is used by both xen and tools ... +Index: build-32-release304-13132/xen/common/libelf/libelf-dominfo.c +=================================================================== +--- /dev/null ++++ build-32-release304-13132/xen/common/libelf/libelf-dominfo.c +@@ -0,0 +1,420 @@ ++/* ++ * parse xen-specific informations out of elf kernel binaries. ++ */ ++ ++#include "libelf-private.h" ++ ++/* ------------------------------------------------------------------------ */ ++/* xen features */ ++ ++const char *elf_xen_feature_names[] = { ++ [XENFEAT_writable_page_tables] = "writable_page_tables", ++ [XENFEAT_writable_descriptor_tables] = "writable_descriptor_tables", ++ [XENFEAT_auto_translated_physmap] = "auto_translated_physmap", ++ [XENFEAT_supervisor_mode_kernel] = "supervisor_mode_kernel", ++ [XENFEAT_pae_pgdir_above_4gb] = "pae_pgdir_above_4gb" ++}; ++const int elf_xen_features = ++ sizeof(elf_xen_feature_names) / sizeof(elf_xen_feature_names[0]); ++ ++int elf_xen_parse_features(const char *features, ++ uint32_t *supported, ++ uint32_t *required) ++{ ++ char feature[64]; ++ int pos, len, i; ++ ++ if (NULL == features) ++ return 0; ++ for (pos = 0; features[pos] != '\0'; pos += len) ++ { ++ memset(feature, 0, sizeof(feature)); ++ for (len = 0;; len++) ++ { ++ if (len >= sizeof(feature)-1) ++ break; ++ if (features[pos + len] == '\0') ++ break; ++ if (features[pos + len] == '|') ++ { ++ len++; ++ break; ++ } ++ feature[len] = features[pos + len]; ++ } ++ ++ for (i = 0; i < elf_xen_features; i++) ++ { ++ if (!elf_xen_feature_names[i]) ++ continue; ++ if (NULL != required && feature[0] == '!') ++ { ++ /* required */ ++ if (0 == strcmp(feature + 1, elf_xen_feature_names[i])) ++ { ++ elf_xen_feature_set(i, supported); ++ elf_xen_feature_set(i, required); ++ break; ++ } ++ } ++ else ++ { ++ /* supported */ ++ if (0 == strcmp(feature, elf_xen_feature_names[i])) ++ { ++ elf_xen_feature_set(i, supported); ++ break; ++ } ++ } ++ } ++ if (i == elf_xen_features) ++ return -1; ++ } ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* xen elf notes */ ++ ++int elf_xen_parse_note(struct elf_binary *elf, ++ struct elf_dom_parms *parms, ++ const elf_note *note) ++{ ++/* *INDENT-OFF* */ ++ static const struct { ++ char *name; ++ int str; ++ } note_desc[] = { ++ [XEN_ELFNOTE_ENTRY] = { "ENTRY", 0}, ++ [XEN_ELFNOTE_HYPERCALL_PAGE] = { "HYPERCALL_PAGE", 0}, ++ [XEN_ELFNOTE_VIRT_BASE] = { "VIRT_BASE", 0}, ++ [XEN_ELFNOTE_PADDR_OFFSET] = { "PADDR_OFFSET", 0}, ++ [XEN_ELFNOTE_HV_START_LOW] = { "HV_START_LOW", 0}, ++ [XEN_ELFNOTE_XEN_VERSION] = { "XEN_VERSION", 1}, ++ [XEN_ELFNOTE_GUEST_OS] = { "GUEST_OS", 1}, ++ [XEN_ELFNOTE_GUEST_VERSION] = { "GUEST_VERSION", 1}, ++ [XEN_ELFNOTE_LOADER] = { "LOADER", 1}, ++ [XEN_ELFNOTE_PAE_MODE] = { "PAE_MODE", 1}, ++ [XEN_ELFNOTE_FEATURES] = { "FEATURES", 1}, ++ [XEN_ELFNOTE_BSD_SYMTAB] = { "BSD_SYMTAB", 1}, ++ }; ++/* *INDENT-ON* */ ++ ++ const char *str = NULL; ++ uint64_t val = 0; ++ int type = elf_uval(elf, note, type); ++ ++ if ((type >= sizeof(note_desc) / sizeof(note_desc[0])) || ++ (NULL == note_desc[type].name)) ++ { ++ elf_err(elf, "%s: unknown xen elf note (0x%x)\n", ++ __FUNCTION__, type); ++ return -1; ++ } ++ ++ if (note_desc[type].str) ++ { ++ str = elf_note_desc(elf, note); ++ elf_msg(elf, "%s: %s = \"%s\"\n", __FUNCTION__, ++ note_desc[type].name, str); ++ } ++ else ++ { ++ val = elf_note_numeric(elf, note); ++ elf_msg(elf, "%s: %s = 0x%" PRIx64 "\n", __FUNCTION__, ++ note_desc[type].name, val); ++ } ++ ++ switch (type) ++ { ++ case XEN_ELFNOTE_LOADER: ++ strncpy(parms->loader, str, sizeof(parms->loader)); ++ break; ++ case XEN_ELFNOTE_GUEST_OS: ++ strncpy(parms->guest_os, str, sizeof(parms->guest_os)); ++ break; ++ case XEN_ELFNOTE_GUEST_VERSION: ++ strncpy(parms->guest_ver, str, sizeof(parms->guest_ver)); ++ break; ++ case XEN_ELFNOTE_XEN_VERSION: ++ strncpy(parms->xen_ver, str, sizeof(parms->xen_ver)); ++ break; ++ case XEN_ELFNOTE_PAE_MODE: ++ if (0 == strcmp(str, "yes")) ++ parms->pae = 2 /* extended_cr3 */; ++ if (strstr(str, "bimodal")) ++ parms->pae = 3 /* bimodal */; ++ break; ++ case XEN_ELFNOTE_BSD_SYMTAB: ++ if (0 == strcmp(str, "yes")) ++ parms->bsd_symtab = 1; ++ break; ++ ++ case XEN_ELFNOTE_VIRT_BASE: ++ parms->virt_base = val; ++ break; ++ case XEN_ELFNOTE_ENTRY: ++ parms->virt_entry = val; ++ break; ++ case XEN_ELFNOTE_PADDR_OFFSET: ++ parms->elf_paddr_offset = val; ++ break; ++ case XEN_ELFNOTE_HYPERCALL_PAGE: ++ parms->virt_hypercall = val; ++ break; ++ case XEN_ELFNOTE_HV_START_LOW: ++ parms->virt_hv_start_low = val; ++ break; ++ ++ case XEN_ELFNOTE_FEATURES: ++ if (0 != elf_xen_parse_features(str, parms->f_supported, ++ parms->f_required)) ++ return -1; ++ break; ++ ++ } ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* __xen_guest section */ ++ ++int elf_xen_parse_guest_info(struct elf_binary *elf, ++ struct elf_dom_parms *parms) ++{ ++ const char *h; ++ char name[32], value[128]; ++ int len; ++ ++ h = parms->guest_info; ++ while (*h) ++ { ++ memset(name, 0, sizeof(name)); ++ memset(value, 0, sizeof(value)); ++ for (len = 0;; len++, h++) { ++ if (len >= sizeof(name)-1) ++ break; ++ if (*h == '\0') ++ break; ++ if (*h == ',') ++ { ++ h++; ++ break; ++ } ++ if (*h == '=') ++ { ++ h++; ++ for (len = 0;; len++, h++) { ++ if (len >= sizeof(value)-1) ++ break; ++ if (*h == '\0') ++ break; ++ if (*h == ',') ++ { ++ h++; ++ break; ++ } ++ value[len] = *h; ++ } ++ break; ++ } ++ name[len] = *h; ++ } ++ elf_msg(elf, "%s: %s=\"%s\"\n", __FUNCTION__, name, value); ++ ++ /* strings */ ++ if (0 == strcmp(name, "LOADER")) ++ strncpy(parms->loader, value, sizeof(parms->loader)); ++ if (0 == strcmp(name, "GUEST_OS")) ++ strncpy(parms->guest_os, value, sizeof(parms->guest_os)); ++ if (0 == strcmp(name, "GUEST_VER")) ++ strncpy(parms->guest_ver, value, sizeof(parms->guest_ver)); ++ if (0 == strcmp(name, "XEN_VER")) ++ strncpy(parms->xen_ver, value, sizeof(parms->xen_ver)); ++ if (0 == strcmp(name, "PAE")) ++ { ++ if (0 == strcmp(value, "yes[extended-cr3]")) ++ parms->pae = 2 /* extended_cr3 */; ++ else if (0 == strncmp(value, "yes", 3)) ++ parms->pae = 1 /* yes */; ++ } ++ if (0 == strcmp(name, "BSD_SYMTAB")) ++ parms->bsd_symtab = 1; ++ ++ /* longs */ ++ if (0 == strcmp(name, "VIRT_BASE")) ++ parms->virt_base = strtoull(value, NULL, 0); ++ if (0 == strcmp(name, "VIRT_ENTRY")) ++ parms->virt_entry = strtoull(value, NULL, 0); ++ if (0 == strcmp(name, "ELF_PADDR_OFFSET")) ++ parms->elf_paddr_offset = strtoull(value, NULL, 0); ++ if (0 == strcmp(name, "HYPERCALL_PAGE")) ++ parms->virt_hypercall = (strtoull(value, NULL, 0) << 12) + ++ parms->virt_base; ++ ++ /* other */ ++ if (0 == strcmp(name, "FEATURES")) ++ if (0 != elf_xen_parse_features(value, parms->f_supported, ++ parms->f_required)) ++ return -1; ++ } ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* sanity checks */ ++ ++static int elf_xen_note_check(struct elf_binary *elf, ++ struct elf_dom_parms *parms) ++{ ++ if (NULL == parms->elf_note_start && NULL == parms->guest_info) { ++ int machine = elf_uval(elf, elf->ehdr, e_machine); ++ if (EM_386 == machine || EM_X86_64 == machine) { ++ elf_err(elf, "%s: ERROR: Not a Xen-ELF image: " ++ "No ELF notes or '__xen_guest' section found.\n", ++ __FUNCTION__); ++ return -1; ++ } ++ return 0; ++ } ++ ++ /* Check the contents of the Xen notes or guest string. */ ++ if ( ( 0 == strlen(parms->loader) || strncmp(parms->loader, "generic", 7) ) && ++ ( 0 == strlen(parms->guest_os) || strncmp(parms->guest_os, "linux", 5) ) ) ++ { ++ elf_err(elf, "%s: ERROR: Will only load images built for the generic " ++ "loader or Linux images", __FUNCTION__); ++ return -1; ++ } ++ ++ if ( 0 == strlen(parms->xen_ver) || strncmp(parms->xen_ver, "xen-3.0", 7) ) ++ { ++ elf_err(elf, "%s: ERROR: Xen will only load images built for Xen v3.0\n", ++ __FUNCTION__); ++ return -1; ++ } ++ return 0; ++} ++ ++static int elf_xen_addr_calc_check(struct elf_binary *elf, ++ struct elf_dom_parms *parms) ++{ ++ if (UNSET_ADDR != parms->elf_paddr_offset && ++ UNSET_ADDR == parms->virt_base ) ++ { ++ elf_err(elf, "%s: ERROR: ELF_PADDR_OFFSET set, VIRT_BASE unset\n", ++ __FUNCTION__); ++ return -1; ++ } ++ ++ /* Initial guess for virt_base is 0 if it is not explicitly defined. */ ++ if (UNSET_ADDR == parms->virt_base) ++ { ++ parms->virt_base = 0; ++ elf_msg(elf, "%s: VIRT_BASE unset, using 0x%" PRIx64 "\n", ++ __FUNCTION__, parms->virt_base); ++ } ++ ++ /* ++ * If we are using the legacy __xen_guest section then elf_pa_off ++ * defaults to v_start in order to maintain compatibility with ++ * older hypervisors which set padd in the ELF header to ++ * virt_base. ++ * ++ * If we are using the modern ELF notes interface then the default ++ * is 0. ++ */ ++ if (UNSET_ADDR == parms->elf_paddr_offset) ++ { ++ if (parms->elf_note_start) ++ parms->elf_paddr_offset = 0; ++ else ++ parms->elf_paddr_offset = parms->virt_base; ++ elf_msg(elf, "%s: ELF_PADDR_OFFSET unset, using 0x%" PRIx64 "\n", ++ __FUNCTION__, parms->elf_paddr_offset); ++ } ++ ++ parms->virt_offset = parms->virt_base - parms->elf_paddr_offset; ++ parms->virt_kstart = elf->pstart + parms->virt_offset; ++ parms->virt_kend = elf->pend + parms->virt_offset; ++ ++ if (UNSET_ADDR == parms->virt_entry) ++ parms->virt_entry = elf_uval(elf, elf->ehdr, e_entry); ++ ++ elf_msg(elf, "%s: addresses:\n", __FUNCTION__); ++ elf_msg(elf, " virt_base = 0x%" PRIx64 "\n", parms->virt_base); ++ elf_msg(elf, " elf_paddr_offset = 0x%" PRIx64 "\n", parms->elf_paddr_offset); ++ elf_msg(elf, " virt_offset = 0x%" PRIx64 "\n", parms->virt_offset); ++ elf_msg(elf, " virt_kstart = 0x%" PRIx64 "\n", parms->virt_kstart); ++ elf_msg(elf, " virt_kend = 0x%" PRIx64 "\n", parms->virt_kend); ++ elf_msg(elf, " virt_entry = 0x%" PRIx64 "\n", parms->virt_entry); ++ ++ if ( (parms->virt_kstart > parms->virt_kend) || ++ (parms->virt_entry < parms->virt_kstart) || ++ (parms->virt_entry > parms->virt_kend) || ++ (parms->virt_base > parms->virt_kstart) ) ++ { ++ elf_err(elf, "%s: ERROR: ELF start or entries are out of bounds.\n", ++ __FUNCTION__); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* glue it all together ... */ ++ ++int elf_xen_parse(struct elf_binary *elf, ++ struct elf_dom_parms *parms) ++{ ++ const elf_note *note; ++ const elf_shdr *shdr; ++ int xen_elfnotes = 0; ++ int i, count; ++ ++ memset(parms, 0, sizeof(*parms)); ++ parms->virt_base = UNSET_ADDR; ++ parms->virt_entry = UNSET_ADDR; ++ parms->virt_hypercall = UNSET_ADDR; ++ parms->virt_hv_start_low = UNSET_ADDR; ++ parms->elf_paddr_offset = UNSET_ADDR; ++ ++ /* find and parse elf notes */ ++ count = elf_shdr_count(elf); ++ for (i = 0; i < count; i++) ++ { ++ shdr = elf_shdr_by_index(elf, i); ++ if (0 == strcmp(elf_section_name(elf, shdr), "__xen_guest")) ++ parms->guest_info = elf_section_start(elf, shdr); ++ if (elf_uval(elf, shdr, sh_type) != SHT_NOTE) ++ continue; ++ parms->elf_note_start = elf_section_start(elf, shdr); ++ parms->elf_note_end = elf_section_end(elf, shdr); ++ for (note = parms->elf_note_start; ++ (void *)note < parms->elf_note_end; ++ note = elf_note_next(elf, note)) ++ { ++ if (0 != strcmp(elf_note_name(elf, note), "Xen")) ++ continue; ++ if (0 != elf_xen_parse_note(elf, parms, note)) ++ return -1; ++ xen_elfnotes++; ++ } ++ } ++ ++ if (!xen_elfnotes && parms->guest_info) ++ { ++ parms->elf_note_start = NULL; ++ parms->elf_note_end = NULL; ++ elf_msg(elf, "%s: __xen_guest: \"%s\"\n", __FUNCTION__, ++ parms->guest_info); ++ elf_xen_parse_guest_info(elf, parms); ++ } ++ ++ if (0 != elf_xen_note_check(elf, parms)) ++ return -1; ++ if (0 != elf_xen_addr_calc_check(elf, parms)) ++ return -1; ++ return 0; ++} +Index: build-32-release304-13132/xen/common/libelf/libelf-loader.c +=================================================================== +--- /dev/null ++++ build-32-release304-13132/xen/common/libelf/libelf-loader.c +@@ -0,0 +1,156 @@ ++/* ++ * parse and load elf binaries ++ */ ++ ++#include "libelf-private.h" ++ ++/* ------------------------------------------------------------------------ */ ++ ++int elf_init(struct elf_binary *elf, const char *image, size_t size) ++{ ++ const elf_shdr *shdr; ++ uint64_t i, count, section, offset; ++ ++ if (!elf_is_elfbinary(image)) ++ { ++ elf_err(elf, "%s: not an ELF binary\n", __FUNCTION__); ++ return -1; ++ } ++ ++ memset(elf, 0, sizeof(*elf)); ++ elf->image = image; ++ elf->size = size; ++ elf->ehdr = (elf_ehdr *) image; ++ elf->class = elf->ehdr->e32.e_ident[EI_CLASS]; ++ elf->data = elf->ehdr->e32.e_ident[EI_DATA]; ++ ++ /* sanity check phdr */ ++ offset = elf_uval(elf, elf->ehdr, e_phoff) + ++ elf_uval(elf, elf->ehdr, e_phentsize) * elf_phdr_count(elf); ++ if (offset > elf->size) ++ { ++ elf_err(elf, "%s: phdr overflow (off %" PRIx64 " > size %lx)\n", ++ __FUNCTION__, offset, (unsigned long)elf->size); ++ return -1; ++ } ++ ++ /* sanity check shdr */ ++ offset = elf_uval(elf, elf->ehdr, e_shoff) + ++ elf_uval(elf, elf->ehdr, e_shentsize) * elf_shdr_count(elf); ++ if (offset > elf->size) ++ { ++ elf_err(elf, "%s: shdr overflow (off %" PRIx64 " > size %lx)\n", ++ __FUNCTION__, offset, (unsigned long)elf->size); ++ return -1; ++ } ++ ++ /* find section string table */ ++ section = elf_uval(elf, elf->ehdr, e_shstrndx); ++ shdr = elf_shdr_by_index(elf, section); ++ if (NULL != shdr) ++ elf->sec_strtab = elf_section_start(elf, shdr); ++ ++ /* find symbol table, symbol string table */ ++ count = elf_shdr_count(elf); ++ for (i = 0; i < count; i++) ++ { ++ shdr = elf_shdr_by_index(elf, i); ++ if (elf_uval(elf, shdr, sh_type) != SHT_SYMTAB) ++ continue; ++ elf->sym_tab = shdr; ++ shdr = elf_shdr_by_index(elf, elf_uval(elf, shdr, sh_link)); ++ if (NULL == shdr) ++ { ++ elf->sym_tab = NULL; ++ continue; ++ } ++ elf->sym_strtab = elf_section_start(elf, shdr); ++ break; ++ } ++ return 0; ++} ++ ++#ifndef __XEN__ ++void elf_set_logfile(struct elf_binary *elf, FILE * log, int verbose) ++{ ++ elf->log = log; ++ elf->verbose = verbose; ++} ++#else ++void elf_set_verbose(struct elf_binary *elf) ++{ ++ elf->verbose = 1; ++} ++#endif ++ ++void elf_parse_binary(struct elf_binary *elf) ++{ ++ const elf_phdr *phdr; ++ uint64_t low = -1; ++ uint64_t high = 0; ++ uint64_t i, count, paddr, memsz; ++ ++ count = elf_uval(elf, elf->ehdr, e_phnum); ++ for (i = 0; i < count; i++) ++ { ++ phdr = elf_phdr_by_index(elf, i); ++ if (!elf_phdr_is_loadable(elf, phdr)) ++ continue; ++ paddr = elf_uval(elf, phdr, p_paddr); ++ memsz = elf_uval(elf, phdr, p_memsz); ++ elf_msg(elf, "%s: phdr: paddr=0x%" PRIx64 ++ " memsz=0x%" PRIx64 "\n", __FUNCTION__, paddr, memsz); ++ if (low > paddr) ++ low = paddr; ++ if (high < paddr + memsz) ++ high = paddr + memsz; ++ } ++ elf->pstart = low; ++ elf->pend = high; ++ elf_msg(elf, "%s: memory: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", ++ __FUNCTION__, elf->pstart, elf->pend); ++} ++ ++void elf_load_binary(struct elf_binary *elf) ++{ ++ const elf_phdr *phdr; ++ uint64_t i, count, paddr, offset, filesz, memsz; ++ char *dest; ++ ++ count = elf_uval(elf, elf->ehdr, e_phnum); ++ for (i = 0; i < count; i++) ++ { ++ phdr = elf_phdr_by_index(elf, i); ++ if (!elf_phdr_is_loadable(elf, phdr)) ++ continue; ++ paddr = elf_uval(elf, phdr, p_paddr); ++ offset = elf_uval(elf, phdr, p_offset); ++ filesz = elf_uval(elf, phdr, p_filesz); ++ memsz = elf_uval(elf, phdr, p_memsz); ++ dest = elf_get_ptr(elf, paddr); ++ memcpy(dest, elf->image + offset, filesz); ++ memset(dest + filesz, 0, memsz - filesz); ++ } ++} ++ ++void *elf_get_ptr(struct elf_binary *elf, unsigned long addr) ++{ ++ return elf->dest + addr - elf->pstart; ++} ++ ++uint64_t elf_lookup_addr(struct elf_binary * elf, const char *symbol) ++{ ++ const elf_sym *sym; ++ uint64_t value; ++ ++ sym = elf_sym_by_name(elf, symbol); ++ if (NULL == sym) ++ { ++ elf_err(elf, "%s: not found: %s\n", __FUNCTION__, symbol); ++ return -1; ++ } ++ value = elf_uval(elf, sym, st_value); ++ elf_msg(elf, "%s: symbol \"%s\" at 0x%" PRIx64 "\n", __FUNCTION__, ++ symbol, value); ++ return value; ++} +Index: build-32-release304-13132/xen/common/libelf/libelf-private.h +=================================================================== +--- /dev/null ++++ build-32-release304-13132/xen/common/libelf/libelf-private.h +@@ -0,0 +1,51 @@ ++#ifdef __XEN__ ++ ++#include ++#include ++#include ++#include ++ ++#define elf_msg(elf, fmt, args ... ) \ ++ if (elf->verbose) printk(fmt, ## args ) ++#define elf_err(elf, fmt, args ... ) \ ++ printk(fmt, ## args ) ++ ++#define strtoull(str, end, base) simple_strtoull(str, end, base) ++#define bswap_16(x) \ ++ ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)) ++#define bswap_32(x) \ ++ ( (((x) & 0xff000000) >> 24) \ ++ | (((x) & 0x00ff0000) >> 8) \ ++ | (((x) & 0x0000ff00) << 8) \ ++ | (((x) & 0x000000ff) << 24)) ++#define bswap_64(x) \ ++ ( (((x) & 0xff00000000000000ull) >> 56) \ ++ | (((x) & 0x00ff000000000000ull) >> 40) \ ++ | (((x) & 0x0000ff0000000000ull) >> 24) \ ++ | (((x) & 0x000000ff00000000ull) >> 8) \ ++ | (((x) & 0x00000000ff000000ull) << 8) \ ++ | (((x) & 0x0000000000ff0000ull) << 24) \ ++ | (((x) & 0x000000000000ff00ull) << 40) \ ++ | (((x) & 0x00000000000000ffull) << 56)) ++ ++#else /* !__XEN__ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "xenctrl.h" ++#include "xc_private.h" ++ ++#define elf_msg(elf, fmt, args ... ) \ ++ if (elf->log && elf->verbose) fprintf(elf->log, fmt , ## args ) ++#define elf_err(elf, fmt, args ... ) do { \ ++ if (elf->log) \ ++ fprintf(elf->log, fmt , ## args ); \ ++ xc_set_error(XC_INVALID_KERNEL, fmt , ## args ); \ ++ } while (0) ++ ++#endif +Index: build-32-release304-13132/xen/common/libelf/libelf-relocate.c +=================================================================== +--- /dev/null ++++ build-32-release304-13132/xen/common/libelf/libelf-relocate.c +@@ -0,0 +1,345 @@ ++/* ++ * ELF relocation code (not used by xen kernel right now). ++ */ ++ ++#include "libelf-private.h" ++ ++/* ------------------------------------------------------------------------ */ ++ ++static const char *rel_names_i386[] = { ++ "R_386_NONE", ++ "R_386_32", ++ "R_386_PC32", ++ "R_386_GOT32", ++ "R_386_PLT32", ++ "R_386_COPY", ++ "R_386_GLOB_DAT", ++ "R_386_JMP_SLOT", ++ "R_386_RELATIVE", ++ "R_386_GOTOFF", ++ "R_386_GOTPC", ++ "R_386_32PLT", ++ "R_386_TLS_TPOFF", ++ "R_386_TLS_IE", ++ "R_386_TLS_GOTIE", ++ "R_386_TLS_LE", ++ "R_386_TLS_GD", ++ "R_386_TLS_LDM", ++ "R_386_16", ++ "R_386_PC16", ++ "R_386_8", ++ "R_386_PC8", ++ "R_386_TLS_GD_32", ++ "R_386_TLS_GD_PUSH", ++ "R_386_TLS_GD_CALL", ++ "R_386_TLS_GD_POP", ++ "R_386_TLS_LDM_32", ++ "R_386_TLS_LDM_PUSH", ++ "R_386_TLS_LDM_CALL", ++ "R_386_TLS_LDM_POP", ++ "R_386_TLS_LDO_32", ++ "R_386_TLS_IE_32", ++ "R_386_TLS_LE_32", ++ "R_386_TLS_DTPMOD32", ++ "R_386_TLS_DTPOFF32", ++ "R_386_TLS_TPOFF32", ++}; ++ ++static int elf_reloc_i386(struct elf_binary *elf, int type, ++ uint64_t addr, uint64_t value) ++{ ++ void *ptr = elf_get_ptr(elf, addr); ++ uint32_t *u32; ++ ++ switch (type) ++ { ++ case 1 /* R_386_32 */ : ++ u32 = ptr; ++ *u32 += elf->reloc_offset; ++ break; ++ case 2 /* R_386_PC32 */ : ++ /* nothing */ ++ break; ++ default: ++ return -1; ++ } ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++ ++static const char *rel_names_x86_64[] = { ++ "R_X86_64_NONE", ++ "R_X86_64_64", ++ "R_X86_64_PC32", ++ "R_X86_64_GOT32", ++ "R_X86_64_PLT32", ++ "R_X86_64_COPY", ++ "R_X86_64_GLOB_DAT", ++ "R_X86_64_JUMP_SLOT", ++ "R_X86_64_RELATIVE", ++ "R_X86_64_GOTPCREL", ++ "R_X86_64_32", ++ "R_X86_64_32S", ++ "R_X86_64_16", ++ "R_X86_64_PC16", ++ "R_X86_64_8", ++ "R_X86_64_PC8", ++ "R_X86_64_DTPMOD64", ++ "R_X86_64_DTPOFF64", ++ "R_X86_64_TPOFF64", ++ "R_X86_64_TLSGD", ++ "R_X86_64_TLSLD", ++ "R_X86_64_DTPOFF32", ++ "R_X86_64_GOTTPOFF", ++ "R_X86_64_TPOFF32", ++}; ++ ++static int elf_reloc_x86_64(struct elf_binary *elf, int type, ++ uint64_t addr, uint64_t value) ++{ ++ void *ptr = elf_get_ptr(elf, addr); ++ uint64_t *u64; ++ uint32_t *u32; ++ int32_t *s32; ++ ++ switch (type) ++ { ++ case 1 /* R_X86_64_64 */ : ++ u64 = ptr; ++ value += elf->reloc_offset; ++ *u64 = value; ++ break; ++ case 2 /* R_X86_64_PC32 */ : ++ u32 = ptr; ++ *u32 = value - addr; ++ if (*u32 != (uint32_t) (value - addr)) ++ { ++ elf_err(elf, "R_X86_64_PC32 overflow: 0x%" PRIx32 " != 0x%" PRIx32 "\n", ++ *u32, (uint32_t) (value - addr)); ++ return -1; ++ } ++ break; ++ case 10 /* R_X86_64_32 */ : ++ u32 = ptr; ++ value += elf->reloc_offset; ++ *u32 = value; ++ if (*u32 != value) ++ { ++ elf_err(elf, "R_X86_64_32 overflow: 0x%" PRIx32 " != 0x%" PRIx64 "\n", ++ *u32, value); ++ return -1; ++ } ++ break; ++ case 11 /* R_X86_64_32S */ : ++ s32 = ptr; ++ value += elf->reloc_offset; ++ *s32 = value; ++ if (*s32 != (int64_t) value) ++ { ++ elf_err(elf, "R_X86_64_32S overflow: 0x%" PRIx32 " != 0x%" PRIx64 "\n", ++ *s32, (int64_t) value); ++ return -1; ++ } ++ break; ++ default: ++ return -1; ++ } ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++ ++static struct relocs { ++ const char **names; ++ int count; ++ int (*func) (struct elf_binary * elf, int type, uint64_t addr, ++ uint64_t value); ++} relocs[] = ++/* *INDENT-OFF* */ ++{ ++ [EM_386] = { ++ .names = rel_names_i386, ++ .count = sizeof(rel_names_i386) / sizeof(rel_names_i386[0]), ++ .func = elf_reloc_i386, ++ }, ++ [EM_X86_64] = { ++ .names = rel_names_x86_64, ++ .count = sizeof(rel_names_x86_64) / sizeof(rel_names_x86_64[0]), ++ .func = elf_reloc_x86_64, ++ } ++}; ++/* *INDENT-ON* */ ++ ++/* ------------------------------------------------------------------------ */ ++ ++static const char *rela_name(int machine, int type) ++{ ++ if (machine > sizeof(relocs) / sizeof(relocs[0])) ++ return "unknown mach"; ++ if (!relocs[machine].names) ++ return "unknown mach"; ++ if (type > relocs[machine].count) ++ return "unknown rela"; ++ return relocs[machine].names[type]; ++} ++ ++static int elf_reloc_section(struct elf_binary *elf, ++ const elf_shdr * rels, ++ const elf_shdr * sect, const elf_shdr * syms) ++{ ++ const void *ptr, *end; ++ const elf_shdr *shdr; ++ const elf_rela *rela; ++ const elf_rel *rel; ++ const elf_sym *sym; ++ uint64_t s_type; ++ uint64_t r_offset; ++ uint64_t r_info; ++ uint64_t r_addend; ++ int r_type, r_sym; ++ size_t rsize; ++ uint64_t shndx, sbase, addr, value; ++ const char *sname; ++ int machine; ++ ++ machine = elf_uval(elf, elf->ehdr, e_machine); ++ if (machine >= sizeof(relocs) / sizeof(relocs[0]) || ++ NULL == relocs[machine].func) ++ { ++ elf_err(elf, "%s: can't handle machine %d\n", ++ __FUNCTION__, machine); ++ return -1; ++ } ++ if (elf_swap(elf)) ++ { ++ elf_err(elf, "%s: non-native byte order, relocation not supported\n", ++ __FUNCTION__); ++ return -1; ++ } ++ ++ s_type = elf_uval(elf, rels, sh_type); ++ rsize = (SHT_REL == s_type) ? elf_size(elf, rel) : elf_size(elf, rela); ++ ptr = elf_section_start(elf, rels); ++ end = elf_section_end(elf, rels); ++ ++ for (; ptr < end; ptr += rsize) ++ { ++ switch (s_type) ++ { ++ case SHT_REL: ++ rel = ptr; ++ r_offset = elf_uval(elf, rel, r_offset); ++ r_info = elf_uval(elf, rel, r_info); ++ r_addend = 0; ++ break; ++ case SHT_RELA: ++ rela = ptr; ++ r_offset = elf_uval(elf, rela, r_offset); ++ r_info = elf_uval(elf, rela, r_info); ++ r_addend = elf_uval(elf, rela, r_addend); ++ break; ++ default: ++ /* can't happen */ ++ return -1; ++ } ++ if (elf_64bit(elf)) ++ { ++ r_type = ELF64_R_TYPE(r_info); ++ r_sym = ELF64_R_SYM(r_info); ++ } ++ else ++ { ++ r_type = ELF32_R_TYPE(r_info); ++ r_sym = ELF32_R_SYM(r_info); ++ } ++ ++ sym = elf_sym_by_index(elf, r_sym); ++ shndx = elf_uval(elf, sym, st_shndx); ++ switch (shndx) ++ { ++ case SHN_UNDEF: ++ sname = "*UNDEF*"; ++ sbase = 0; ++ break; ++ case SHN_COMMON: ++ elf_err(elf, "%s: invalid section: %" PRId64 "\n", ++ __FUNCTION__, shndx); ++ return -1; ++ case SHN_ABS: ++ sname = "*ABS*"; ++ sbase = 0; ++ break; ++ default: ++ shdr = elf_shdr_by_index(elf, shndx); ++ if (NULL == shdr) ++ { ++ elf_err(elf, "%s: invalid section: %" PRId64 "\n", ++ __FUNCTION__, shndx); ++ return -1; ++ } ++ sname = elf_section_name(elf, shdr); ++ sbase = elf_uval(elf, shdr, sh_addr); ++ } ++ ++ addr = r_offset; ++ value = elf_uval(elf, sym, st_value); ++ value += r_addend; ++ ++ if (elf->log && elf->verbose > 1) ++ { ++ uint64_t st_name = elf_uval(elf, sym, st_name); ++ const char *name = st_name ? elf->sym_strtab + st_name : "*NONE*"; ++ ++ elf_msg(elf, ++ "%s: type %s [%d], off 0x%" PRIx64 ", add 0x%" PRIx64 "," ++ " sym %s [0x%" PRIx64 "], sec %s [0x%" PRIx64 "]" ++ " -> addr 0x%" PRIx64 " value 0x%" PRIx64 "\n", ++ __FUNCTION__, rela_name(machine, r_type), r_type, r_offset, ++ r_addend, name, elf_uval(elf, sym, st_value), sname, sbase, ++ addr, value); ++ } ++ ++ if (-1 == relocs[machine].func(elf, r_type, addr, value)) ++ { ++ elf_err(elf, "%s: unknown/unsupported reloc type %s [%d]\n", ++ __FUNCTION__, rela_name(machine, r_type), r_type); ++ return -1; ++ } ++ } ++ return 0; ++} ++ ++int elf_reloc(struct elf_binary *elf) ++{ ++ const elf_shdr *rels, *sect, *syms; ++ uint64_t i, count, type; ++ ++ count = elf_shdr_count(elf); ++ for (i = 0; i < count; i++) ++ { ++ rels = elf_shdr_by_index(elf, i); ++ type = elf_uval(elf, rels, sh_type); ++ if (type != SHT_REL && type != SHT_RELA) ++ continue; ++ ++ sect = elf_shdr_by_index(elf, elf_uval(elf, rels, sh_info)); ++ syms = elf_shdr_by_index(elf, elf_uval(elf, rels, sh_link)); ++ if (NULL == sect || NULL == syms) ++ continue; ++ ++ if (!(elf_uval(elf, sect, sh_flags) & SHF_ALLOC)) ++ { ++ elf_msg(elf, "%s: relocations for %s, skipping\n", ++ __FUNCTION__, elf_section_name(elf, sect)); ++ continue; ++ } ++ ++ elf_msg(elf, "%s: relocations for %s @ 0x%" PRIx64 "\n", ++ __FUNCTION__, elf_section_name(elf, sect), ++ elf_uval(elf, sect, sh_addr)); ++ if (0 != elf_reloc_section(elf, rels, sect, syms)) ++ return -1; ++ } ++ return 0; ++} +Index: build-32-release304-13132/xen/common/libelf/libelf-tools.c +=================================================================== +--- /dev/null ++++ build-32-release304-13132/xen/common/libelf/libelf-tools.c +@@ -0,0 +1,225 @@ ++/* ++ * various helper functions to access elf structures ++ */ ++ ++#include "libelf-private.h" ++ ++/* ------------------------------------------------------------------------ */ ++ ++uint64_t elf_access_unsigned(struct elf_binary * elf, const void *ptr, ++ off_t offset, size_t size) ++{ ++ int need_swap = elf_swap(elf); ++ const uint8_t *u8; ++ const uint16_t *u16; ++ const uint32_t *u32; ++ const uint64_t *u64; ++ ++ switch (size) ++ { ++ case 1: ++ u8 = ptr + offset; ++ return *u8; ++ case 2: ++ u16 = ptr + offset; ++ return need_swap ? bswap_16(*u16) : *u16; ++ case 4: ++ u32 = ptr + offset; ++ return need_swap ? bswap_32(*u32) : *u32; ++ case 8: ++ u64 = ptr + offset; ++ return need_swap ? bswap_64(*u64) : *u64; ++ default: ++ return 0; ++ } ++} ++ ++int64_t elf_access_signed(struct elf_binary *elf, const void *ptr, ++ off_t offset, size_t size) ++{ ++ int need_swap = elf_swap(elf); ++ const int8_t *s8; ++ const int16_t *s16; ++ const int32_t *s32; ++ const int64_t *s64; ++ ++ switch (size) ++ { ++ case 1: ++ s8 = ptr + offset; ++ return *s8; ++ case 2: ++ s16 = ptr + offset; ++ return need_swap ? bswap_16(*s16) : *s16; ++ case 4: ++ s32 = ptr + offset; ++ return need_swap ? bswap_32(*s32) : *s32; ++ case 8: ++ s64 = ptr + offset; ++ return need_swap ? bswap_64(*s64) : *s64; ++ default: ++ return 0; ++ } ++} ++ ++uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr) ++{ ++ int elf_round = (elf_64bit(elf) ? 8 : 4) - 1; ++ ++ return (addr + elf_round) & ~elf_round; ++} ++ ++/* ------------------------------------------------------------------------ */ ++ ++int elf_shdr_count(struct elf_binary *elf) ++{ ++ return elf_uval(elf, elf->ehdr, e_shnum); ++} ++ ++int elf_phdr_count(struct elf_binary *elf) ++{ ++ return elf_uval(elf, elf->ehdr, e_phnum); ++} ++ ++const elf_shdr *elf_shdr_by_name(struct elf_binary *elf, const char *name) ++{ ++ uint64_t count = elf_shdr_count(elf); ++ const elf_shdr *shdr; ++ const char *sname; ++ int i; ++ ++ for (i = 0; i < count; i++) { ++ shdr = elf_shdr_by_index(elf, i); ++ sname = elf_section_name(elf, shdr); ++ if (sname && 0 == strcmp(sname, name)) ++ return shdr; ++ } ++ return NULL; ++} ++ ++const elf_shdr *elf_shdr_by_index(struct elf_binary *elf, int index) ++{ ++ uint64_t count = elf_shdr_count(elf); ++ const void *ptr = NULL; ++ ++ if (index < count) ++ ptr = elf->image ++ + elf_uval(elf, elf->ehdr, e_shoff) ++ + elf_uval(elf, elf->ehdr, e_shentsize) * index; ++ return ptr; ++} ++ ++const elf_phdr *elf_phdr_by_index(struct elf_binary *elf, int index) ++{ ++ uint64_t count = elf_uval(elf, elf->ehdr, e_phnum); ++ const void *ptr = NULL; ++ ++ if (index < count) ++ ptr = elf->image ++ + elf_uval(elf, elf->ehdr, e_phoff) ++ + elf_uval(elf, elf->ehdr, e_phentsize) * index; ++ return ptr; ++} ++ ++const char *elf_section_name(struct elf_binary *elf, const elf_shdr * shdr) ++{ ++ if (NULL == elf->sec_strtab) ++ return "unknown"; ++ return elf->sec_strtab + elf_uval(elf, shdr, sh_name); ++} ++ ++const void *elf_section_start(struct elf_binary *elf, const elf_shdr * shdr) ++{ ++ return elf->image + elf_uval(elf, shdr, sh_offset); ++} ++ ++const void *elf_section_end(struct elf_binary *elf, const elf_shdr * shdr) ++{ ++ return elf->image ++ + elf_uval(elf, shdr, sh_offset) + elf_uval(elf, shdr, sh_size); ++} ++ ++const elf_sym *elf_sym_by_name(struct elf_binary *elf, const char *symbol) ++{ ++ const void *ptr = elf_section_start(elf, elf->sym_tab); ++ const void *end = elf_section_end(elf, elf->sym_tab); ++ const elf_sym *sym; ++ uint64_t info, name; ++ ++ for (; ptr < end; ptr += elf_size(elf, sym)) ++ { ++ sym = ptr; ++ info = elf_uval(elf, sym, st_info); ++ name = elf_uval(elf, sym, st_name); ++ if (ELF32_ST_BIND(info) != STB_GLOBAL) ++ continue; ++ if (strcmp(elf->sym_strtab + name, symbol) != 0) ++ continue; ++ return sym; ++ } ++ return NULL; ++} ++ ++const elf_sym *elf_sym_by_index(struct elf_binary *elf, int index) ++{ ++ const void *ptr = elf_section_start(elf, elf->sym_tab); ++ const elf_sym *sym; ++ ++ sym = ptr + index * elf_size(elf, sym); ++ return sym; ++} ++ ++const char *elf_note_name(struct elf_binary *elf, const elf_note * note) ++{ ++ return (void *)note + elf_size(elf, note); ++} ++ ++const void *elf_note_desc(struct elf_binary *elf, const elf_note * note) ++{ ++ int namesz = (elf_uval(elf, note, namesz) + 3) & ~3; ++ ++ return (void *)note + elf_size(elf, note) + namesz; ++} ++ ++uint64_t elf_note_numeric(struct elf_binary *elf, const elf_note * note) ++{ ++ const void *desc = elf_note_desc(elf, note); ++ int descsz = elf_uval(elf, note, descsz); ++ ++ switch (descsz) ++ { ++ case 1: ++ case 2: ++ case 4: ++ case 8: ++ return elf_access_unsigned(elf, desc, 0, descsz); ++ default: ++ return 0; ++ } ++} ++const elf_note *elf_note_next(struct elf_binary *elf, const elf_note * note) ++{ ++ int namesz = (elf_uval(elf, note, namesz) + 3) & ~3; ++ int descsz = (elf_uval(elf, note, descsz) + 3) & ~3; ++ ++ return (void *)note + elf_size(elf, note) + namesz + descsz; ++} ++ ++/* ------------------------------------------------------------------------ */ ++ ++int elf_is_elfbinary(const void *image) ++{ ++ const Elf32_Ehdr *ehdr = image; ++ ++ if (IS_ELF(*ehdr)) ++ return 1; ++ return 0; ++} ++ ++int elf_phdr_is_loadable(struct elf_binary *elf, const elf_phdr * phdr) ++{ ++ uint64_t p_type = elf_uval(elf, phdr, p_type); ++ uint64_t p_flags = elf_uval(elf, phdr, p_flags); ++ ++ return ((p_type == PT_LOAD) && (p_flags & (PF_W | PF_X)) != 0); ++} +Index: build-32-release304-13132/xen/include/public/elfstructs.h +=================================================================== +--- /dev/null ++++ build-32-release304-13132/xen/include/public/elfstructs.h +@@ -0,0 +1,527 @@ ++#ifndef __XEN_PUBLIC_ELFSTRUCTS_H__ ++#define __XEN_PUBLIC_ELFSTRUCTS_H__ 1 ++/* ++ * Copyright (c) 1995, 1996 Erik Theisen. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The name of the author may not be used to endorse or promote products ++ * derived from this software without specific prior written permission ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++typedef uint8_t Elf_Byte; ++ ++typedef uint32_t Elf32_Addr; /* Unsigned program address */ ++typedef uint32_t Elf32_Off; /* Unsigned file offset */ ++typedef int32_t Elf32_Sword; /* Signed large integer */ ++typedef uint32_t Elf32_Word; /* Unsigned large integer */ ++typedef uint16_t Elf32_Half; /* Unsigned medium integer */ ++ ++typedef uint64_t Elf64_Addr; ++typedef uint64_t Elf64_Off; ++typedef int32_t Elf64_Shalf; ++ ++typedef int32_t Elf64_Sword; ++typedef uint32_t Elf64_Word; ++ ++typedef int64_t Elf64_Sxword; ++typedef uint64_t Elf64_Xword; ++ ++typedef uint32_t Elf64_Half; ++typedef uint16_t Elf64_Quarter; ++ ++/* ++ * e_ident[] identification indexes ++ * See http://www.caldera.com/developers/gabi/2000-07-17/ch4.eheader.html ++ */ ++#define EI_MAG0 0 /* file ID */ ++#define EI_MAG1 1 /* file ID */ ++#define EI_MAG2 2 /* file ID */ ++#define EI_MAG3 3 /* file ID */ ++#define EI_CLASS 4 /* file class */ ++#define EI_DATA 5 /* data encoding */ ++#define EI_VERSION 6 /* ELF header version */ ++#define EI_OSABI 7 /* OS/ABI ID */ ++#define EI_ABIVERSION 8 /* ABI version */ ++#define EI_PAD 9 /* start of pad bytes */ ++#define EI_NIDENT 16 /* Size of e_ident[] */ ++ ++/* e_ident[] magic number */ ++#define ELFMAG0 0x7f /* e_ident[EI_MAG0] */ ++#define ELFMAG1 'E' /* e_ident[EI_MAG1] */ ++#define ELFMAG2 'L' /* e_ident[EI_MAG2] */ ++#define ELFMAG3 'F' /* e_ident[EI_MAG3] */ ++#define ELFMAG "\177ELF" /* magic */ ++#define SELFMAG 4 /* size of magic */ ++ ++/* e_ident[] file class */ ++#define ELFCLASSNONE 0 /* invalid */ ++#define ELFCLASS32 1 /* 32-bit objs */ ++#define ELFCLASS64 2 /* 64-bit objs */ ++#define ELFCLASSNUM 3 /* number of classes */ ++ ++/* e_ident[] data encoding */ ++#define ELFDATANONE 0 /* invalid */ ++#define ELFDATA2LSB 1 /* Little-Endian */ ++#define ELFDATA2MSB 2 /* Big-Endian */ ++#define ELFDATANUM 3 /* number of data encode defines */ ++ ++/* e_ident[] Operating System/ABI */ ++#define ELFOSABI_SYSV 0 /* UNIX System V ABI */ ++#define ELFOSABI_HPUX 1 /* HP-UX operating system */ ++#define ELFOSABI_NETBSD 2 /* NetBSD */ ++#define ELFOSABI_LINUX 3 /* GNU/Linux */ ++#define ELFOSABI_HURD 4 /* GNU/Hurd */ ++#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */ ++#define ELFOSABI_SOLARIS 6 /* Solaris */ ++#define ELFOSABI_MONTEREY 7 /* Monterey */ ++#define ELFOSABI_IRIX 8 /* IRIX */ ++#define ELFOSABI_FREEBSD 9 /* FreeBSD */ ++#define ELFOSABI_TRU64 10 /* TRU64 UNIX */ ++#define ELFOSABI_MODESTO 11 /* Novell Modesto */ ++#define ELFOSABI_OPENBSD 12 /* OpenBSD */ ++#define ELFOSABI_ARM 97 /* ARM */ ++#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ ++ ++/* e_ident */ ++#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ ++ (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ ++ (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ ++ (ehdr).e_ident[EI_MAG3] == ELFMAG3) ++ ++/* ELF Header */ ++typedef struct elfhdr { ++ unsigned char e_ident[EI_NIDENT]; /* ELF Identification */ ++ Elf32_Half e_type; /* object file type */ ++ Elf32_Half e_machine; /* machine */ ++ Elf32_Word e_version; /* object file version */ ++ Elf32_Addr e_entry; /* virtual entry point */ ++ Elf32_Off e_phoff; /* program header table offset */ ++ Elf32_Off e_shoff; /* section header table offset */ ++ Elf32_Word e_flags; /* processor-specific flags */ ++ Elf32_Half e_ehsize; /* ELF header size */ ++ Elf32_Half e_phentsize; /* program header entry size */ ++ Elf32_Half e_phnum; /* number of program header entries */ ++ Elf32_Half e_shentsize; /* section header entry size */ ++ Elf32_Half e_shnum; /* number of section header entries */ ++ Elf32_Half e_shstrndx; /* section header table's "section ++ header string table" entry offset */ ++} Elf32_Ehdr; ++ ++typedef struct { ++ unsigned char e_ident[EI_NIDENT]; /* Id bytes */ ++ Elf64_Quarter e_type; /* file type */ ++ Elf64_Quarter e_machine; /* machine type */ ++ Elf64_Half e_version; /* version number */ ++ Elf64_Addr e_entry; /* entry point */ ++ Elf64_Off e_phoff; /* Program hdr offset */ ++ Elf64_Off e_shoff; /* Section hdr offset */ ++ Elf64_Half e_flags; /* Processor flags */ ++ Elf64_Quarter e_ehsize; /* sizeof ehdr */ ++ Elf64_Quarter e_phentsize; /* Program header entry size */ ++ Elf64_Quarter e_phnum; /* Number of program headers */ ++ Elf64_Quarter e_shentsize; /* Section header entry size */ ++ Elf64_Quarter e_shnum; /* Number of section headers */ ++ Elf64_Quarter e_shstrndx; /* String table index */ ++} Elf64_Ehdr; ++ ++/* e_type */ ++#define ET_NONE 0 /* No file type */ ++#define ET_REL 1 /* relocatable file */ ++#define ET_EXEC 2 /* executable file */ ++#define ET_DYN 3 /* shared object file */ ++#define ET_CORE 4 /* core file */ ++#define ET_NUM 5 /* number of types */ ++#define ET_LOPROC 0xff00 /* reserved range for processor */ ++#define ET_HIPROC 0xffff /* specific e_type */ ++ ++/* e_machine */ ++#define EM_NONE 0 /* No Machine */ ++#define EM_M32 1 /* AT&T WE 32100 */ ++#define EM_SPARC 2 /* SPARC */ ++#define EM_386 3 /* Intel 80386 */ ++#define EM_68K 4 /* Motorola 68000 */ ++#define EM_88K 5 /* Motorola 88000 */ ++#define EM_486 6 /* Intel 80486 - unused? */ ++#define EM_860 7 /* Intel 80860 */ ++#define EM_MIPS 8 /* MIPS R3000 Big-Endian only */ ++/* ++ * Don't know if EM_MIPS_RS4_BE, ++ * EM_SPARC64, EM_PARISC, ++ * or EM_PPC are ABI compliant ++ */ ++#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ ++#define EM_SPARC64 11 /* SPARC v9 64-bit unoffical */ ++#define EM_PARISC 15 /* HPPA */ ++#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */ ++#define EM_PPC 20 /* PowerPC */ ++#define EM_PPC64 21 /* PowerPC 64-bit */ ++#define EM_ARM 40 /* Advanced RISC Machines ARM */ ++#define EM_ALPHA 41 /* DEC ALPHA */ ++#define EM_SPARCV9 43 /* SPARC version 9 */ ++#define EM_ALPHA_EXP 0x9026 /* DEC ALPHA */ ++#define EM_IA_64 50 /* Intel Merced */ ++#define EM_X86_64 62 /* AMD x86-64 architecture */ ++#define EM_VAX 75 /* DEC VAX */ ++ ++/* Version */ ++#define EV_NONE 0 /* Invalid */ ++#define EV_CURRENT 1 /* Current */ ++#define EV_NUM 2 /* number of versions */ ++ ++/* Section Header */ ++typedef struct { ++ Elf32_Word sh_name; /* name - index into section header ++ string table section */ ++ Elf32_Word sh_type; /* type */ ++ Elf32_Word sh_flags; /* flags */ ++ Elf32_Addr sh_addr; /* address */ ++ Elf32_Off sh_offset; /* file offset */ ++ Elf32_Word sh_size; /* section size */ ++ Elf32_Word sh_link; /* section header table index link */ ++ Elf32_Word sh_info; /* extra information */ ++ Elf32_Word sh_addralign; /* address alignment */ ++ Elf32_Word sh_entsize; /* section entry size */ ++} Elf32_Shdr; ++ ++typedef struct { ++ Elf64_Half sh_name; /* section name */ ++ Elf64_Half sh_type; /* section type */ ++ Elf64_Xword sh_flags; /* section flags */ ++ Elf64_Addr sh_addr; /* virtual address */ ++ Elf64_Off sh_offset; /* file offset */ ++ Elf64_Xword sh_size; /* section size */ ++ Elf64_Half sh_link; /* link to another */ ++ Elf64_Half sh_info; /* misc info */ ++ Elf64_Xword sh_addralign; /* memory alignment */ ++ Elf64_Xword sh_entsize; /* table entry size */ ++} Elf64_Shdr; ++ ++/* Special Section Indexes */ ++#define SHN_UNDEF 0 /* undefined */ ++#define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */ ++#define SHN_LOPROC 0xff00 /* reserved range for processor */ ++#define SHN_HIPROC 0xff1f /* specific section indexes */ ++#define SHN_ABS 0xfff1 /* absolute value */ ++#define SHN_COMMON 0xfff2 /* common symbol */ ++#define SHN_HIRESERVE 0xffff /* upper bounds of reserved indexes */ ++ ++/* sh_type */ ++#define SHT_NULL 0 /* inactive */ ++#define SHT_PROGBITS 1 /* program defined information */ ++#define SHT_SYMTAB 2 /* symbol table section */ ++#define SHT_STRTAB 3 /* string table section */ ++#define SHT_RELA 4 /* relocation section with addends*/ ++#define SHT_HASH 5 /* symbol hash table section */ ++#define SHT_DYNAMIC 6 /* dynamic section */ ++#define SHT_NOTE 7 /* note section */ ++#define SHT_NOBITS 8 /* no space section */ ++#define SHT_REL 9 /* relation section without addends */ ++#define SHT_SHLIB 10 /* reserved - purpose unknown */ ++#define SHT_DYNSYM 11 /* dynamic symbol table section */ ++#define SHT_NUM 12 /* number of section types */ ++#define SHT_LOPROC 0x70000000 /* reserved range for processor */ ++#define SHT_HIPROC 0x7fffffff /* specific section header types */ ++#define SHT_LOUSER 0x80000000 /* reserved range for application */ ++#define SHT_HIUSER 0xffffffff /* specific indexes */ ++ ++/* Section names */ ++#define ELF_BSS ".bss" /* uninitialized data */ ++#define ELF_DATA ".data" /* initialized data */ ++#define ELF_DEBUG ".debug" /* debug */ ++#define ELF_DYNAMIC ".dynamic" /* dynamic linking information */ ++#define ELF_DYNSTR ".dynstr" /* dynamic string table */ ++#define ELF_DYNSYM ".dynsym" /* dynamic symbol table */ ++#define ELF_FINI ".fini" /* termination code */ ++#define ELF_GOT ".got" /* global offset table */ ++#define ELF_HASH ".hash" /* symbol hash table */ ++#define ELF_INIT ".init" /* initialization code */ ++#define ELF_REL_DATA ".rel.data" /* relocation data */ ++#define ELF_REL_FINI ".rel.fini" /* relocation termination code */ ++#define ELF_REL_INIT ".rel.init" /* relocation initialization code */ ++#define ELF_REL_DYN ".rel.dyn" /* relocaltion dynamic link info */ ++#define ELF_REL_RODATA ".rel.rodata" /* relocation read-only data */ ++#define ELF_REL_TEXT ".rel.text" /* relocation code */ ++#define ELF_RODATA ".rodata" /* read-only data */ ++#define ELF_SHSTRTAB ".shstrtab" /* section header string table */ ++#define ELF_STRTAB ".strtab" /* string table */ ++#define ELF_SYMTAB ".symtab" /* symbol table */ ++#define ELF_TEXT ".text" /* code */ ++ ++ ++/* Section Attribute Flags - sh_flags */ ++#define SHF_WRITE 0x1 /* Writable */ ++#define SHF_ALLOC 0x2 /* occupies memory */ ++#define SHF_EXECINSTR 0x4 /* executable */ ++#define SHF_MASKPROC 0xf0000000 /* reserved bits for processor */ ++ /* specific section attributes */ ++ ++/* Symbol Table Entry */ ++typedef struct elf32_sym { ++ Elf32_Word st_name; /* name - index into string table */ ++ Elf32_Addr st_value; /* symbol value */ ++ Elf32_Word st_size; /* symbol size */ ++ unsigned char st_info; /* type and binding */ ++ unsigned char st_other; /* 0 - no defined meaning */ ++ Elf32_Half st_shndx; /* section header index */ ++} Elf32_Sym; ++ ++typedef struct { ++ Elf64_Half st_name; /* Symbol name index in str table */ ++ Elf_Byte st_info; /* type / binding attrs */ ++ Elf_Byte st_other; /* unused */ ++ Elf64_Quarter st_shndx; /* section index of symbol */ ++ Elf64_Xword st_value; /* value of symbol */ ++ Elf64_Xword st_size; /* size of symbol */ ++} Elf64_Sym; ++ ++/* Symbol table index */ ++#define STN_UNDEF 0 /* undefined */ ++ ++/* Extract symbol info - st_info */ ++#define ELF32_ST_BIND(x) ((x) >> 4) ++#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf) ++#define ELF32_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf)) ++ ++#define ELF64_ST_BIND(x) ((x) >> 4) ++#define ELF64_ST_TYPE(x) (((unsigned int) x) & 0xf) ++#define ELF64_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf)) ++ ++/* Symbol Binding - ELF32_ST_BIND - st_info */ ++#define STB_LOCAL 0 /* Local symbol */ ++#define STB_GLOBAL 1 /* Global symbol */ ++#define STB_WEAK 2 /* like global - lower precedence */ ++#define STB_NUM 3 /* number of symbol bindings */ ++#define STB_LOPROC 13 /* reserved range for processor */ ++#define STB_HIPROC 15 /* specific symbol bindings */ ++ ++/* Symbol type - ELF32_ST_TYPE - st_info */ ++#define STT_NOTYPE 0 /* not specified */ ++#define STT_OBJECT 1 /* data object */ ++#define STT_FUNC 2 /* function */ ++#define STT_SECTION 3 /* section */ ++#define STT_FILE 4 /* file */ ++#define STT_NUM 5 /* number of symbol types */ ++#define STT_LOPROC 13 /* reserved range for processor */ ++#define STT_HIPROC 15 /* specific symbol types */ ++ ++/* Relocation entry with implicit addend */ ++typedef struct { ++ Elf32_Addr r_offset; /* offset of relocation */ ++ Elf32_Word r_info; /* symbol table index and type */ ++} Elf32_Rel; ++ ++/* Relocation entry with explicit addend */ ++typedef struct { ++ Elf32_Addr r_offset; /* offset of relocation */ ++ Elf32_Word r_info; /* symbol table index and type */ ++ Elf32_Sword r_addend; ++} Elf32_Rela; ++ ++/* Extract relocation info - r_info */ ++#define ELF32_R_SYM(i) ((i) >> 8) ++#define ELF32_R_TYPE(i) ((unsigned char) (i)) ++#define ELF32_R_INFO(s,t) (((s) << 8) + (unsigned char)(t)) ++ ++typedef struct { ++ Elf64_Xword r_offset; /* where to do it */ ++ Elf64_Xword r_info; /* index & type of relocation */ ++} Elf64_Rel; ++ ++typedef struct { ++ Elf64_Xword r_offset; /* where to do it */ ++ Elf64_Xword r_info; /* index & type of relocation */ ++ Elf64_Sxword r_addend; /* adjustment value */ ++} Elf64_Rela; ++ ++#define ELF64_R_SYM(info) ((info) >> 32) ++#define ELF64_R_TYPE(info) ((info) & 0xFFFFFFFF) ++#define ELF64_R_INFO(s,t) (((s) << 32) + (u_int32_t)(t)) ++ ++/* Program Header */ ++typedef struct { ++ Elf32_Word p_type; /* segment type */ ++ Elf32_Off p_offset; /* segment offset */ ++ Elf32_Addr p_vaddr; /* virtual address of segment */ ++ Elf32_Addr p_paddr; /* physical address - ignored? */ ++ Elf32_Word p_filesz; /* number of bytes in file for seg. */ ++ Elf32_Word p_memsz; /* number of bytes in mem. for seg. */ ++ Elf32_Word p_flags; /* flags */ ++ Elf32_Word p_align; /* memory alignment */ ++} Elf32_Phdr; ++ ++typedef struct { ++ Elf64_Half p_type; /* entry type */ ++ Elf64_Half p_flags; /* flags */ ++ Elf64_Off p_offset; /* offset */ ++ Elf64_Addr p_vaddr; /* virtual address */ ++ Elf64_Addr p_paddr; /* physical address */ ++ Elf64_Xword p_filesz; /* file size */ ++ Elf64_Xword p_memsz; /* memory size */ ++ Elf64_Xword p_align; /* memory & file alignment */ ++} Elf64_Phdr; ++ ++/* Segment types - p_type */ ++#define PT_NULL 0 /* unused */ ++#define PT_LOAD 1 /* loadable segment */ ++#define PT_DYNAMIC 2 /* dynamic linking section */ ++#define PT_INTERP 3 /* the RTLD */ ++#define PT_NOTE 4 /* auxiliary information */ ++#define PT_SHLIB 5 /* reserved - purpose undefined */ ++#define PT_PHDR 6 /* program header */ ++#define PT_NUM 7 /* Number of segment types */ ++#define PT_LOPROC 0x70000000 /* reserved range for processor */ ++#define PT_HIPROC 0x7fffffff /* specific segment types */ ++ ++/* Segment flags - p_flags */ ++#define PF_X 0x1 /* Executable */ ++#define PF_W 0x2 /* Writable */ ++#define PF_R 0x4 /* Readable */ ++#define PF_MASKPROC 0xf0000000 /* reserved bits for processor */ ++ /* specific segment flags */ ++ ++/* Dynamic structure */ ++typedef struct { ++ Elf32_Sword d_tag; /* controls meaning of d_val */ ++ union { ++ Elf32_Word d_val; /* Multiple meanings - see d_tag */ ++ Elf32_Addr d_ptr; /* program virtual address */ ++ } d_un; ++} Elf32_Dyn; ++ ++typedef struct { ++ Elf64_Xword d_tag; /* controls meaning of d_val */ ++ union { ++ Elf64_Addr d_ptr; ++ Elf64_Xword d_val; ++ } d_un; ++} Elf64_Dyn; ++ ++/* Dynamic Array Tags - d_tag */ ++#define DT_NULL 0 /* marks end of _DYNAMIC array */ ++#define DT_NEEDED 1 /* string table offset of needed lib */ ++#define DT_PLTRELSZ 2 /* size of relocation entries in PLT */ ++#define DT_PLTGOT 3 /* address PLT/GOT */ ++#define DT_HASH 4 /* address of symbol hash table */ ++#define DT_STRTAB 5 /* address of string table */ ++#define DT_SYMTAB 6 /* address of symbol table */ ++#define DT_RELA 7 /* address of relocation table */ ++#define DT_RELASZ 8 /* size of relocation table */ ++#define DT_RELAENT 9 /* size of relocation entry */ ++#define DT_STRSZ 10 /* size of string table */ ++#define DT_SYMENT 11 /* size of symbol table entry */ ++#define DT_INIT 12 /* address of initialization func. */ ++#define DT_FINI 13 /* address of termination function */ ++#define DT_SONAME 14 /* string table offset of shared obj */ ++#define DT_RPATH 15 /* string table offset of library ++ search path */ ++#define DT_SYMBOLIC 16 /* start sym search in shared obj. */ ++#define DT_REL 17 /* address of rel. tbl. w addends */ ++#define DT_RELSZ 18 /* size of DT_REL relocation table */ ++#define DT_RELENT 19 /* size of DT_REL relocation entry */ ++#define DT_PLTREL 20 /* PLT referenced relocation entry */ ++#define DT_DEBUG 21 /* bugger */ ++#define DT_TEXTREL 22 /* Allow rel. mod. to unwritable seg */ ++#define DT_JMPREL 23 /* add. of PLT's relocation entries */ ++#define DT_BIND_NOW 24 /* Bind now regardless of env setting */ ++#define DT_NUM 25 /* Number used. */ ++#define DT_LOPROC 0x70000000 /* reserved range for processor */ ++#define DT_HIPROC 0x7fffffff /* specific dynamic array tags */ ++ ++/* Standard ELF hashing function */ ++unsigned int elf_hash(const unsigned char *name); ++ ++/* ++ * Note Definitions ++ */ ++typedef struct { ++ Elf32_Word namesz; ++ Elf32_Word descsz; ++ Elf32_Word type; ++} Elf32_Note; ++ ++typedef struct { ++ Elf64_Half namesz; ++ Elf64_Half descsz; ++ Elf64_Half type; ++} Elf64_Note; ++ ++ ++#if defined(ELFSIZE) ++#define CONCAT(x,y) __CONCAT(x,y) ++#define ELFNAME(x) CONCAT(elf,CONCAT(ELFSIZE,CONCAT(_,x))) ++#define ELFNAME2(x,y) CONCAT(x,CONCAT(_elf,CONCAT(ELFSIZE,CONCAT(_,y)))) ++#define ELFNAMEEND(x) CONCAT(x,CONCAT(_elf,ELFSIZE)) ++#define ELFDEFNNAME(x) CONCAT(ELF,CONCAT(ELFSIZE,CONCAT(_,x))) ++#endif ++ ++#if defined(ELFSIZE) && (ELFSIZE == 32) ++#define Elf_Ehdr Elf32_Ehdr ++#define Elf_Phdr Elf32_Phdr ++#define Elf_Shdr Elf32_Shdr ++#define Elf_Sym Elf32_Sym ++#define Elf_Rel Elf32_Rel ++#define Elf_RelA Elf32_Rela ++#define Elf_Dyn Elf32_Dyn ++#define Elf_Word Elf32_Word ++#define Elf_Sword Elf32_Sword ++#define Elf_Addr Elf32_Addr ++#define Elf_Off Elf32_Off ++#define Elf_Nhdr Elf32_Nhdr ++#define Elf_Note Elf32_Note ++ ++#define ELF_R_SYM ELF32_R_SYM ++#define ELF_R_TYPE ELF32_R_TYPE ++#define ELF_R_INFO ELF32_R_INFO ++#define ELFCLASS ELFCLASS32 ++ ++#define ELF_ST_BIND ELF32_ST_BIND ++#define ELF_ST_TYPE ELF32_ST_TYPE ++#define ELF_ST_INFO ELF32_ST_INFO ++ ++#define AuxInfo Aux32Info ++#elif defined(ELFSIZE) && (ELFSIZE == 64) ++#define Elf_Ehdr Elf64_Ehdr ++#define Elf_Phdr Elf64_Phdr ++#define Elf_Shdr Elf64_Shdr ++#define Elf_Sym Elf64_Sym ++#define Elf_Rel Elf64_Rel ++#define Elf_RelA Elf64_Rela ++#define Elf_Dyn Elf64_Dyn ++#define Elf_Word Elf64_Word ++#define Elf_Sword Elf64_Sword ++#define Elf_Addr Elf64_Addr ++#define Elf_Off Elf64_Off ++#define Elf_Nhdr Elf64_Nhdr ++#define Elf_Note Elf64_Note ++ ++#define ELF_R_SYM ELF64_R_SYM ++#define ELF_R_TYPE ELF64_R_TYPE ++#define ELF_R_INFO ELF64_R_INFO ++#define ELFCLASS ELFCLASS64 ++ ++#define ELF_ST_BIND ELF64_ST_BIND ++#define ELF_ST_TYPE ELF64_ST_TYPE ++#define ELF_ST_INFO ELF64_ST_INFO ++ ++#define AuxInfo Aux64Info ++#endif ++ ++#endif /* __XEN_PUBLIC_ELFSTRUCTS_H__ */ +Index: build-32-release304-13132/xen/include/public/libelf.h +=================================================================== +--- /dev/null ++++ build-32-release304-13132/xen/include/public/libelf.h +@@ -0,0 +1,238 @@ ++#ifndef __XC_LIBELF__ ++#define __XC_LIBELF__ 1 ++ ++#ifdef __XEN__ ++ ++#include ++#include ++typedef uint64_t off_t; ++ ++#define LITTLE_ENDIAN 1234 ++#define BIG_ENDIAN 4321 ++#if defined(__i386__) || defined(__x86_64) || defined(__ia64__) ++#define BYTE_ORDER LITTLE_ENDIAN ++#elif defined(__powerpc__) ++#define BYTE_ORDER BIG_ENDIAN ++#endif ++ ++#else /* !__XEN__ */ ++ ++#include ++#include ++ ++#endif ++ ++#undef ELFSIZE ++#include "elfstructs.h" ++#include "features.h" ++ ++/* ------------------------------------------------------------------------ */ ++ ++typedef union { ++ Elf32_Ehdr e32; ++ Elf64_Ehdr e64; ++} elf_ehdr; ++ ++typedef union { ++ Elf32_Phdr e32; ++ Elf64_Phdr e64; ++} elf_phdr; ++ ++typedef union { ++ Elf32_Shdr e32; ++ Elf64_Shdr e64; ++} elf_shdr; ++ ++typedef union { ++ Elf32_Sym e32; ++ Elf64_Sym e64; ++} elf_sym; ++ ++typedef union { ++ Elf32_Rel e32; ++ Elf64_Rel e64; ++} elf_rel; ++ ++typedef union { ++ Elf32_Rela e32; ++ Elf64_Rela e64; ++} elf_rela; ++ ++typedef union { ++ Elf32_Note e32; ++ Elf64_Note e64; ++} elf_note; ++ ++struct elf_binary { ++ /* elf binary */ ++ const char *image; ++ size_t size; ++ char class; ++ char data; ++ ++ const elf_ehdr *ehdr; ++ const char *sec_strtab; ++ const elf_shdr *sym_tab; ++ const char *sym_strtab; ++ ++ /* loaded to */ ++ char *dest; ++ uint64_t pstart; ++ uint64_t pend; ++ uint64_t reloc_offset; ++ ++#ifndef __XEN__ ++ /* misc */ ++ FILE *log; ++#endif ++ int verbose; ++}; ++ ++/* ------------------------------------------------------------------------ */ ++/* accessing elf header fields */ ++ ++#if !defined(BYTE_ORDER) ++# error BYTE_ORDER not defined ++#elif BYTE_ORDER == BIG_ENDIAN ++# define NATIVE_ELFDATA ELFDATA2MSB ++#elif BYTE_ORDER == LITTLE_ENDIAN ++# define NATIVE_ELFDATA ELFDATA2LSB ++#else ++# error BYTE_ORDER unknown ++#endif ++ ++#define elf_32bit(elf) (ELFCLASS32 == (elf)->class) ++#define elf_64bit(elf) (ELFCLASS64 == (elf)->class) ++#define elf_msb(elf) (ELFDATA2MSB == (elf)->data) ++#define elf_lsb(elf) (ELFDATA2LSB == (elf)->data) ++#define elf_swap(elf) (NATIVE_ELFDATA != (elf)->data) ++ ++#define elf_uval(elf, str, elem) \ ++ ((ELFCLASS64 == (elf)->class) \ ++ ? elf_access_unsigned((elf), (str), \ ++ offsetof(typeof(*(str)),e64.elem), \ ++ sizeof((str)->e64.elem)) \ ++ : elf_access_unsigned((elf), (str), \ ++ offsetof(typeof(*(str)),e32.elem), \ ++ sizeof((str)->e32.elem))) ++ ++#define elf_sval(elf, str, elem) \ ++ ((ELFCLASS64 == (elf)->class) \ ++ ? elf_access_signed((elf), (str), \ ++ offsetof(typeof(*(str)),e64.elem), \ ++ sizeof((str)->e64.elem)) \ ++ : elf_access_signed((elf), (str), \ ++ offsetof(typeof(*(str)),e32.elem), \ ++ sizeof((str)->e32.elem))) ++ ++#define elf_size(elf, str) \ ++ ((ELFCLASS64 == (elf)->class) \ ++ ? sizeof((str)->e64) \ ++ : sizeof((str)->e32)) ++ ++uint64_t elf_access_unsigned(struct elf_binary *elf, const void *ptr, ++ off_t offset, size_t size); ++int64_t elf_access_signed(struct elf_binary *elf, const void *ptr, ++ off_t offset, size_t size); ++ ++uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr); ++ ++/* ------------------------------------------------------------------------ */ ++/* xc_libelf_tools.c */ ++ ++int elf_shdr_count(struct elf_binary *elf); ++int elf_phdr_count(struct elf_binary *elf); ++ ++const elf_shdr *elf_shdr_by_name(struct elf_binary *elf, const char *name); ++const elf_shdr *elf_shdr_by_index(struct elf_binary *elf, int index); ++const elf_phdr *elf_phdr_by_index(struct elf_binary *elf, int index); ++ ++const char *elf_section_name(struct elf_binary *elf, const elf_shdr * shdr); ++const void *elf_section_start(struct elf_binary *elf, const elf_shdr * shdr); ++const void *elf_section_end(struct elf_binary *elf, const elf_shdr * shdr); ++ ++const elf_sym *elf_sym_by_name(struct elf_binary *elf, const char *symbol); ++const elf_sym *elf_sym_by_index(struct elf_binary *elf, int index); ++ ++const char *elf_note_name(struct elf_binary *elf, const elf_note * note); ++const void *elf_note_desc(struct elf_binary *elf, const elf_note * note); ++uint64_t elf_note_numeric(struct elf_binary *elf, const elf_note * note); ++const elf_note *elf_note_next(struct elf_binary *elf, const elf_note * note); ++ ++int elf_is_elfbinary(const void *image); ++int elf_phdr_is_loadable(struct elf_binary *elf, const elf_phdr * phdr); ++ ++/* ------------------------------------------------------------------------ */ ++/* xc_libelf_loader.c */ ++ ++int elf_init(struct elf_binary *elf, const char *image, size_t size); ++#ifdef __XEN__ ++void elf_set_verbose(struct elf_binary *elf); ++#else ++void elf_set_logfile(struct elf_binary *elf, FILE * log, int verbose); ++#endif ++ ++void elf_parse_binary(struct elf_binary *elf); ++void elf_load_binary(struct elf_binary *elf); ++ ++void *elf_get_ptr(struct elf_binary *elf, unsigned long addr); ++uint64_t elf_lookup_addr(struct elf_binary *elf, const char *symbol); ++ ++/* ------------------------------------------------------------------------ */ ++/* xc_libelf_relocate.c */ ++ ++int elf_reloc(struct elf_binary *elf); ++ ++/* ------------------------------------------------------------------------ */ ++/* xc_libelf_dominfo.c */ ++ ++#define UNSET_ADDR ((uint64_t)-1) ++ ++struct elf_dom_parms { ++ /* raw */ ++ const char *guest_info; ++ const void *elf_note_start; ++ const void *elf_note_end; ++ ++ /* parsed */ ++ char guest_os[16]; ++ char guest_ver[16]; ++ char xen_ver[16]; ++ char loader[16]; ++ int pae; ++ int bsd_symtab; ++ uint64_t virt_base; ++ uint64_t virt_entry; ++ uint64_t virt_hypercall; ++ uint64_t virt_hv_start_low; ++ uint64_t elf_paddr_offset; ++ uint32_t f_supported[XENFEAT_NR_SUBMAPS]; ++ uint32_t f_required[XENFEAT_NR_SUBMAPS]; ++ ++ /* calculated */ ++ uint64_t virt_offset; ++ uint64_t virt_kstart; ++ uint64_t virt_kend; ++}; ++ ++static inline void elf_xen_feature_set(int nr, uint32_t * addr) ++{ ++ addr[nr >> 5] |= 1 << (nr & 31); ++} ++static inline int elf_xen_feature_get(int nr, uint32_t * addr) ++{ ++ return !!(addr[nr >> 5] & (1 << (nr & 31))); ++} ++ ++int elf_xen_parse_features(const char *features, ++ uint32_t *supported, ++ uint32_t *required); ++int elf_xen_parse_note(struct elf_binary *elf, ++ struct elf_dom_parms *parms, ++ const elf_note *note); ++int elf_xen_parse_guest_info(struct elf_binary *elf, ++ struct elf_dom_parms *parms); ++int elf_xen_parse(struct elf_binary *elf, ++ struct elf_dom_parms *parms); ++ ++#endif /* __XC_LIBELF__ */ +Index: build-32-release304-13132/tools/libxc/xc_elf.h +=================================================================== +--- build-32-release304-13132.orig/tools/libxc/xc_elf.h ++++ build-32-release304-13132/tools/libxc/xc_elf.h +@@ -1,524 +1 @@ +-/* +- * Copyright (c) 1995, 1996 Erik Theisen. All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 3. The name of the author may not be used to endorse or promote products +- * derived from this software without specific prior written permission +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- */ +- +-typedef uint8_t Elf_Byte; +- +-typedef uint32_t Elf32_Addr; /* Unsigned program address */ +-typedef uint32_t Elf32_Off; /* Unsigned file offset */ +-typedef int32_t Elf32_Sword; /* Signed large integer */ +-typedef uint32_t Elf32_Word; /* Unsigned large integer */ +-typedef uint16_t Elf32_Half; /* Unsigned medium integer */ +- +-typedef uint64_t Elf64_Addr; +-typedef uint64_t Elf64_Off; +-typedef int32_t Elf64_Shalf; +- +-typedef int32_t Elf64_Sword; +-typedef uint32_t Elf64_Word; +- +-typedef int64_t Elf64_Sxword; +-typedef uint64_t Elf64_Xword; +- +-typedef uint32_t Elf64_Half; +-typedef uint16_t Elf64_Quarter; +- +-/* +- * e_ident[] identification indexes +- * See http://www.caldera.com/developers/gabi/2000-07-17/ch4.eheader.html +- */ +-#define EI_MAG0 0 /* file ID */ +-#define EI_MAG1 1 /* file ID */ +-#define EI_MAG2 2 /* file ID */ +-#define EI_MAG3 3 /* file ID */ +-#define EI_CLASS 4 /* file class */ +-#define EI_DATA 5 /* data encoding */ +-#define EI_VERSION 6 /* ELF header version */ +-#define EI_OSABI 7 /* OS/ABI ID */ +-#define EI_ABIVERSION 8 /* ABI version */ +-#define EI_PAD 9 /* start of pad bytes */ +-#define EI_NIDENT 16 /* Size of e_ident[] */ +- +-/* e_ident[] magic number */ +-#define ELFMAG0 0x7f /* e_ident[EI_MAG0] */ +-#define ELFMAG1 'E' /* e_ident[EI_MAG1] */ +-#define ELFMAG2 'L' /* e_ident[EI_MAG2] */ +-#define ELFMAG3 'F' /* e_ident[EI_MAG3] */ +-#define ELFMAG "\177ELF" /* magic */ +-#define SELFMAG 4 /* size of magic */ +- +-/* e_ident[] file class */ +-#define ELFCLASSNONE 0 /* invalid */ +-#define ELFCLASS32 1 /* 32-bit objs */ +-#define ELFCLASS64 2 /* 64-bit objs */ +-#define ELFCLASSNUM 3 /* number of classes */ +- +-/* e_ident[] data encoding */ +-#define ELFDATANONE 0 /* invalid */ +-#define ELFDATA2LSB 1 /* Little-Endian */ +-#define ELFDATA2MSB 2 /* Big-Endian */ +-#define ELFDATANUM 3 /* number of data encode defines */ +- +-/* e_ident[] Operating System/ABI */ +-#define ELFOSABI_SYSV 0 /* UNIX System V ABI */ +-#define ELFOSABI_HPUX 1 /* HP-UX operating system */ +-#define ELFOSABI_NETBSD 2 /* NetBSD */ +-#define ELFOSABI_LINUX 3 /* GNU/Linux */ +-#define ELFOSABI_HURD 4 /* GNU/Hurd */ +-#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */ +-#define ELFOSABI_SOLARIS 6 /* Solaris */ +-#define ELFOSABI_MONTEREY 7 /* Monterey */ +-#define ELFOSABI_IRIX 8 /* IRIX */ +-#define ELFOSABI_FREEBSD 9 /* FreeBSD */ +-#define ELFOSABI_TRU64 10 /* TRU64 UNIX */ +-#define ELFOSABI_MODESTO 11 /* Novell Modesto */ +-#define ELFOSABI_OPENBSD 12 /* OpenBSD */ +-#define ELFOSABI_ARM 97 /* ARM */ +-#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ +- +-/* e_ident */ +-#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ +- (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ +- (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ +- (ehdr).e_ident[EI_MAG3] == ELFMAG3) +- +-/* ELF Header */ +-typedef struct elfhdr { +- unsigned char e_ident[EI_NIDENT]; /* ELF Identification */ +- Elf32_Half e_type; /* object file type */ +- Elf32_Half e_machine; /* machine */ +- Elf32_Word e_version; /* object file version */ +- Elf32_Addr e_entry; /* virtual entry point */ +- Elf32_Off e_phoff; /* program header table offset */ +- Elf32_Off e_shoff; /* section header table offset */ +- Elf32_Word e_flags; /* processor-specific flags */ +- Elf32_Half e_ehsize; /* ELF header size */ +- Elf32_Half e_phentsize; /* program header entry size */ +- Elf32_Half e_phnum; /* number of program header entries */ +- Elf32_Half e_shentsize; /* section header entry size */ +- Elf32_Half e_shnum; /* number of section header entries */ +- Elf32_Half e_shstrndx; /* section header table's "section +- header string table" entry offset */ +-} Elf32_Ehdr; +- +-typedef struct { +- unsigned char e_ident[EI_NIDENT]; /* Id bytes */ +- Elf64_Quarter e_type; /* file type */ +- Elf64_Quarter e_machine; /* machine type */ +- Elf64_Half e_version; /* version number */ +- Elf64_Addr e_entry; /* entry point */ +- Elf64_Off e_phoff; /* Program hdr offset */ +- Elf64_Off e_shoff; /* Section hdr offset */ +- Elf64_Half e_flags; /* Processor flags */ +- Elf64_Quarter e_ehsize; /* sizeof ehdr */ +- Elf64_Quarter e_phentsize; /* Program header entry size */ +- Elf64_Quarter e_phnum; /* Number of program headers */ +- Elf64_Quarter e_shentsize; /* Section header entry size */ +- Elf64_Quarter e_shnum; /* Number of section headers */ +- Elf64_Quarter e_shstrndx; /* String table index */ +-} Elf64_Ehdr; +- +-/* e_type */ +-#define ET_NONE 0 /* No file type */ +-#define ET_REL 1 /* relocatable file */ +-#define ET_EXEC 2 /* executable file */ +-#define ET_DYN 3 /* shared object file */ +-#define ET_CORE 4 /* core file */ +-#define ET_NUM 5 /* number of types */ +-#define ET_LOPROC 0xff00 /* reserved range for processor */ +-#define ET_HIPROC 0xffff /* specific e_type */ +- +-/* e_machine */ +-#define EM_NONE 0 /* No Machine */ +-#define EM_M32 1 /* AT&T WE 32100 */ +-#define EM_SPARC 2 /* SPARC */ +-#define EM_386 3 /* Intel 80386 */ +-#define EM_68K 4 /* Motorola 68000 */ +-#define EM_88K 5 /* Motorola 88000 */ +-#define EM_486 6 /* Intel 80486 - unused? */ +-#define EM_860 7 /* Intel 80860 */ +-#define EM_MIPS 8 /* MIPS R3000 Big-Endian only */ +-/* +- * Don't know if EM_MIPS_RS4_BE, +- * EM_SPARC64, EM_PARISC, +- * or EM_PPC are ABI compliant +- */ +-#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ +-#define EM_SPARC64 11 /* SPARC v9 64-bit unoffical */ +-#define EM_PARISC 15 /* HPPA */ +-#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */ +-#define EM_PPC 20 /* PowerPC */ +-#define EM_PPC64 21 /* PowerPC 64-bit */ +-#define EM_ARM 40 /* Advanced RISC Machines ARM */ +-#define EM_ALPHA 41 /* DEC ALPHA */ +-#define EM_SPARCV9 43 /* SPARC version 9 */ +-#define EM_ALPHA_EXP 0x9026 /* DEC ALPHA */ +-#define EM_IA_64 50 /* Intel Merced */ +-#define EM_X86_64 62 /* AMD x86-64 architecture */ +-#define EM_VAX 75 /* DEC VAX */ +- +-/* Version */ +-#define EV_NONE 0 /* Invalid */ +-#define EV_CURRENT 1 /* Current */ +-#define EV_NUM 2 /* number of versions */ +- +-/* Section Header */ +-typedef struct { +- Elf32_Word sh_name; /* name - index into section header +- string table section */ +- Elf32_Word sh_type; /* type */ +- Elf32_Word sh_flags; /* flags */ +- Elf32_Addr sh_addr; /* address */ +- Elf32_Off sh_offset; /* file offset */ +- Elf32_Word sh_size; /* section size */ +- Elf32_Word sh_link; /* section header table index link */ +- Elf32_Word sh_info; /* extra information */ +- Elf32_Word sh_addralign; /* address alignment */ +- Elf32_Word sh_entsize; /* section entry size */ +-} Elf32_Shdr; +- +-typedef struct { +- Elf64_Half sh_name; /* section name */ +- Elf64_Half sh_type; /* section type */ +- Elf64_Xword sh_flags; /* section flags */ +- Elf64_Addr sh_addr; /* virtual address */ +- Elf64_Off sh_offset; /* file offset */ +- Elf64_Xword sh_size; /* section size */ +- Elf64_Half sh_link; /* link to another */ +- Elf64_Half sh_info; /* misc info */ +- Elf64_Xword sh_addralign; /* memory alignment */ +- Elf64_Xword sh_entsize; /* table entry size */ +-} Elf64_Shdr; +- +-/* Special Section Indexes */ +-#define SHN_UNDEF 0 /* undefined */ +-#define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */ +-#define SHN_LOPROC 0xff00 /* reserved range for processor */ +-#define SHN_HIPROC 0xff1f /* specific section indexes */ +-#define SHN_ABS 0xfff1 /* absolute value */ +-#define SHN_COMMON 0xfff2 /* common symbol */ +-#define SHN_HIRESERVE 0xffff /* upper bounds of reserved indexes */ +- +-/* sh_type */ +-#define SHT_NULL 0 /* inactive */ +-#define SHT_PROGBITS 1 /* program defined information */ +-#define SHT_SYMTAB 2 /* symbol table section */ +-#define SHT_STRTAB 3 /* string table section */ +-#define SHT_RELA 4 /* relocation section with addends*/ +-#define SHT_HASH 5 /* symbol hash table section */ +-#define SHT_DYNAMIC 6 /* dynamic section */ +-#define SHT_NOTE 7 /* note section */ +-#define SHT_NOBITS 8 /* no space section */ +-#define SHT_REL 9 /* relation section without addends */ +-#define SHT_SHLIB 10 /* reserved - purpose unknown */ +-#define SHT_DYNSYM 11 /* dynamic symbol table section */ +-#define SHT_NUM 12 /* number of section types */ +-#define SHT_LOPROC 0x70000000 /* reserved range for processor */ +-#define SHT_HIPROC 0x7fffffff /* specific section header types */ +-#define SHT_LOUSER 0x80000000 /* reserved range for application */ +-#define SHT_HIUSER 0xffffffff /* specific indexes */ +- +-/* Section names */ +-#define ELF_BSS ".bss" /* uninitialized data */ +-#define ELF_DATA ".data" /* initialized data */ +-#define ELF_DEBUG ".debug" /* debug */ +-#define ELF_DYNAMIC ".dynamic" /* dynamic linking information */ +-#define ELF_DYNSTR ".dynstr" /* dynamic string table */ +-#define ELF_DYNSYM ".dynsym" /* dynamic symbol table */ +-#define ELF_FINI ".fini" /* termination code */ +-#define ELF_GOT ".got" /* global offset table */ +-#define ELF_HASH ".hash" /* symbol hash table */ +-#define ELF_INIT ".init" /* initialization code */ +-#define ELF_REL_DATA ".rel.data" /* relocation data */ +-#define ELF_REL_FINI ".rel.fini" /* relocation termination code */ +-#define ELF_REL_INIT ".rel.init" /* relocation initialization code */ +-#define ELF_REL_DYN ".rel.dyn" /* relocaltion dynamic link info */ +-#define ELF_REL_RODATA ".rel.rodata" /* relocation read-only data */ +-#define ELF_REL_TEXT ".rel.text" /* relocation code */ +-#define ELF_RODATA ".rodata" /* read-only data */ +-#define ELF_SHSTRTAB ".shstrtab" /* section header string table */ +-#define ELF_STRTAB ".strtab" /* string table */ +-#define ELF_SYMTAB ".symtab" /* symbol table */ +-#define ELF_TEXT ".text" /* code */ +- +- +-/* Section Attribute Flags - sh_flags */ +-#define SHF_WRITE 0x1 /* Writable */ +-#define SHF_ALLOC 0x2 /* occupies memory */ +-#define SHF_EXECINSTR 0x4 /* executable */ +-#define SHF_MASKPROC 0xf0000000 /* reserved bits for processor */ +- /* specific section attributes */ +- +-/* Symbol Table Entry */ +-typedef struct elf32_sym { +- Elf32_Word st_name; /* name - index into string table */ +- Elf32_Addr st_value; /* symbol value */ +- Elf32_Word st_size; /* symbol size */ +- unsigned char st_info; /* type and binding */ +- unsigned char st_other; /* 0 - no defined meaning */ +- Elf32_Half st_shndx; /* section header index */ +-} Elf32_Sym; +- +-typedef struct { +- Elf64_Half st_name; /* Symbol name index in str table */ +- Elf_Byte st_info; /* type / binding attrs */ +- Elf_Byte st_other; /* unused */ +- Elf64_Quarter st_shndx; /* section index of symbol */ +- Elf64_Xword st_value; /* value of symbol */ +- Elf64_Xword st_size; /* size of symbol */ +-} Elf64_Sym; +- +-/* Symbol table index */ +-#define STN_UNDEF 0 /* undefined */ +- +-/* Extract symbol info - st_info */ +-#define ELF32_ST_BIND(x) ((x) >> 4) +-#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf) +-#define ELF32_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf)) +- +-#define ELF64_ST_BIND(x) ((x) >> 4) +-#define ELF64_ST_TYPE(x) (((unsigned int) x) & 0xf) +-#define ELF64_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf)) +- +-/* Symbol Binding - ELF32_ST_BIND - st_info */ +-#define STB_LOCAL 0 /* Local symbol */ +-#define STB_GLOBAL 1 /* Global symbol */ +-#define STB_WEAK 2 /* like global - lower precedence */ +-#define STB_NUM 3 /* number of symbol bindings */ +-#define STB_LOPROC 13 /* reserved range for processor */ +-#define STB_HIPROC 15 /* specific symbol bindings */ +- +-/* Symbol type - ELF32_ST_TYPE - st_info */ +-#define STT_NOTYPE 0 /* not specified */ +-#define STT_OBJECT 1 /* data object */ +-#define STT_FUNC 2 /* function */ +-#define STT_SECTION 3 /* section */ +-#define STT_FILE 4 /* file */ +-#define STT_NUM 5 /* number of symbol types */ +-#define STT_LOPROC 13 /* reserved range for processor */ +-#define STT_HIPROC 15 /* specific symbol types */ +- +-/* Relocation entry with implicit addend */ +-typedef struct { +- Elf32_Addr r_offset; /* offset of relocation */ +- Elf32_Word r_info; /* symbol table index and type */ +-} Elf32_Rel; +- +-/* Relocation entry with explicit addend */ +-typedef struct { +- Elf32_Addr r_offset; /* offset of relocation */ +- Elf32_Word r_info; /* symbol table index and type */ +- Elf32_Sword r_addend; +-} Elf32_Rela; +- +-/* Extract relocation info - r_info */ +-#define ELF32_R_SYM(i) ((i) >> 8) +-#define ELF32_R_TYPE(i) ((unsigned char) (i)) +-#define ELF32_R_INFO(s,t) (((s) << 8) + (unsigned char)(t)) +- +-typedef struct { +- Elf64_Xword r_offset; /* where to do it */ +- Elf64_Xword r_info; /* index & type of relocation */ +-} Elf64_Rel; +- +-typedef struct { +- Elf64_Xword r_offset; /* where to do it */ +- Elf64_Xword r_info; /* index & type of relocation */ +- Elf64_Sxword r_addend; /* adjustment value */ +-} Elf64_Rela; +- +-#define ELF64_R_SYM(info) ((info) >> 32) +-#define ELF64_R_TYPE(info) ((info) & 0xFFFFFFFF) +-#define ELF64_R_INFO(s,t) (((s) << 32) + (u_int32_t)(t)) +- +-/* Program Header */ +-typedef struct { +- Elf32_Word p_type; /* segment type */ +- Elf32_Off p_offset; /* segment offset */ +- Elf32_Addr p_vaddr; /* virtual address of segment */ +- Elf32_Addr p_paddr; /* physical address - ignored? */ +- Elf32_Word p_filesz; /* number of bytes in file for seg. */ +- Elf32_Word p_memsz; /* number of bytes in mem. for seg. */ +- Elf32_Word p_flags; /* flags */ +- Elf32_Word p_align; /* memory alignment */ +-} Elf32_Phdr; +- +-typedef struct { +- Elf64_Half p_type; /* entry type */ +- Elf64_Half p_flags; /* flags */ +- Elf64_Off p_offset; /* offset */ +- Elf64_Addr p_vaddr; /* virtual address */ +- Elf64_Addr p_paddr; /* physical address */ +- Elf64_Xword p_filesz; /* file size */ +- Elf64_Xword p_memsz; /* memory size */ +- Elf64_Xword p_align; /* memory & file alignment */ +-} Elf64_Phdr; +- +-/* Segment types - p_type */ +-#define PT_NULL 0 /* unused */ +-#define PT_LOAD 1 /* loadable segment */ +-#define PT_DYNAMIC 2 /* dynamic linking section */ +-#define PT_INTERP 3 /* the RTLD */ +-#define PT_NOTE 4 /* auxiliary information */ +-#define PT_SHLIB 5 /* reserved - purpose undefined */ +-#define PT_PHDR 6 /* program header */ +-#define PT_NUM 7 /* Number of segment types */ +-#define PT_LOPROC 0x70000000 /* reserved range for processor */ +-#define PT_HIPROC 0x7fffffff /* specific segment types */ +- +-/* Segment flags - p_flags */ +-#define PF_X 0x1 /* Executable */ +-#define PF_W 0x2 /* Writable */ +-#define PF_R 0x4 /* Readable */ +-#define PF_MASKPROC 0xf0000000 /* reserved bits for processor */ +- /* specific segment flags */ +- +-/* Dynamic structure */ +-typedef struct { +- Elf32_Sword d_tag; /* controls meaning of d_val */ +- union { +- Elf32_Word d_val; /* Multiple meanings - see d_tag */ +- Elf32_Addr d_ptr; /* program virtual address */ +- } d_un; +-} Elf32_Dyn; +- +-typedef struct { +- Elf64_Xword d_tag; /* controls meaning of d_val */ +- union { +- Elf64_Addr d_ptr; +- Elf64_Xword d_val; +- } d_un; +-} Elf64_Dyn; +- +-/* Dynamic Array Tags - d_tag */ +-#define DT_NULL 0 /* marks end of _DYNAMIC array */ +-#define DT_NEEDED 1 /* string table offset of needed lib */ +-#define DT_PLTRELSZ 2 /* size of relocation entries in PLT */ +-#define DT_PLTGOT 3 /* address PLT/GOT */ +-#define DT_HASH 4 /* address of symbol hash table */ +-#define DT_STRTAB 5 /* address of string table */ +-#define DT_SYMTAB 6 /* address of symbol table */ +-#define DT_RELA 7 /* address of relocation table */ +-#define DT_RELASZ 8 /* size of relocation table */ +-#define DT_RELAENT 9 /* size of relocation entry */ +-#define DT_STRSZ 10 /* size of string table */ +-#define DT_SYMENT 11 /* size of symbol table entry */ +-#define DT_INIT 12 /* address of initialization func. */ +-#define DT_FINI 13 /* address of termination function */ +-#define DT_SONAME 14 /* string table offset of shared obj */ +-#define DT_RPATH 15 /* string table offset of library +- search path */ +-#define DT_SYMBOLIC 16 /* start sym search in shared obj. */ +-#define DT_REL 17 /* address of rel. tbl. w addends */ +-#define DT_RELSZ 18 /* size of DT_REL relocation table */ +-#define DT_RELENT 19 /* size of DT_REL relocation entry */ +-#define DT_PLTREL 20 /* PLT referenced relocation entry */ +-#define DT_DEBUG 21 /* bugger */ +-#define DT_TEXTREL 22 /* Allow rel. mod. to unwritable seg */ +-#define DT_JMPREL 23 /* add. of PLT's relocation entries */ +-#define DT_BIND_NOW 24 /* Bind now regardless of env setting */ +-#define DT_NUM 25 /* Number used. */ +-#define DT_LOPROC 0x70000000 /* reserved range for processor */ +-#define DT_HIPROC 0x7fffffff /* specific dynamic array tags */ +- +-/* Standard ELF hashing function */ +-unsigned int elf_hash(const unsigned char *name); +- +-/* +- * Note Definitions +- */ +-typedef struct { +- Elf32_Word namesz; +- Elf32_Word descsz; +- Elf32_Word type; +-} Elf32_Note; +- +-typedef struct { +- Elf64_Half namesz; +- Elf64_Half descsz; +- Elf64_Half type; +-} Elf64_Note; +- +- +-#if defined(ELFSIZE) +-#define CONCAT(x,y) __CONCAT(x,y) +-#define ELFNAME(x) CONCAT(elf,CONCAT(ELFSIZE,CONCAT(_,x))) +-#define ELFNAME2(x,y) CONCAT(x,CONCAT(_elf,CONCAT(ELFSIZE,CONCAT(_,y)))) +-#define ELFNAMEEND(x) CONCAT(x,CONCAT(_elf,ELFSIZE)) +-#define ELFDEFNNAME(x) CONCAT(ELF,CONCAT(ELFSIZE,CONCAT(_,x))) +-#endif +- +-#if defined(ELFSIZE) && (ELFSIZE == 32) +-#define Elf_Ehdr Elf32_Ehdr +-#define Elf_Phdr Elf32_Phdr +-#define Elf_Shdr Elf32_Shdr +-#define Elf_Sym Elf32_Sym +-#define Elf_Rel Elf32_Rel +-#define Elf_RelA Elf32_Rela +-#define Elf_Dyn Elf32_Dyn +-#define Elf_Word Elf32_Word +-#define Elf_Sword Elf32_Sword +-#define Elf_Addr Elf32_Addr +-#define Elf_Off Elf32_Off +-#define Elf_Nhdr Elf32_Nhdr +-#define Elf_Note Elf32_Note +- +-#define ELF_R_SYM ELF32_R_SYM +-#define ELF_R_TYPE ELF32_R_TYPE +-#define ELF_R_INFO ELF32_R_INFO +-#define ELFCLASS ELFCLASS32 +- +-#define ELF_ST_BIND ELF32_ST_BIND +-#define ELF_ST_TYPE ELF32_ST_TYPE +-#define ELF_ST_INFO ELF32_ST_INFO +- +-#define AuxInfo Aux32Info +-#elif defined(ELFSIZE) && (ELFSIZE == 64) +-#define Elf_Ehdr Elf64_Ehdr +-#define Elf_Phdr Elf64_Phdr +-#define Elf_Shdr Elf64_Shdr +-#define Elf_Sym Elf64_Sym +-#define Elf_Rel Elf64_Rel +-#define Elf_RelA Elf64_Rela +-#define Elf_Dyn Elf64_Dyn +-#define Elf_Word Elf64_Word +-#define Elf_Sword Elf64_Sword +-#define Elf_Addr Elf64_Addr +-#define Elf_Off Elf64_Off +-#define Elf_Nhdr Elf64_Nhdr +-#define Elf_Note Elf64_Note +- +-#define ELF_R_SYM ELF64_R_SYM +-#define ELF_R_TYPE ELF64_R_TYPE +-#define ELF_R_INFO ELF64_R_INFO +-#define ELFCLASS ELFCLASS64 +- +-#define ELF_ST_BIND ELF64_ST_BIND +-#define ELF_ST_TYPE ELF64_ST_TYPE +-#define ELF_ST_INFO ELF64_ST_INFO +- +-#define AuxInfo Aux64Info +-#endif +- ++#include +Index: build-32-release304-13132/xen/include/xen/elf.h +=================================================================== +--- build-32-release304-13132.orig/xen/include/xen/elf.h ++++ build-32-release304-13132/xen/include/xen/elf.h +@@ -27,495 +27,7 @@ + #ifndef __XEN_ELF_H__ + #define __XEN_ELF_H__ + +-typedef u8 Elf_Byte; +- +-typedef u32 Elf32_Addr; /* Unsigned program address */ +-typedef u32 Elf32_Off; /* Unsigned file offset */ +-typedef s32 Elf32_Sword; /* Signed large integer */ +-typedef u32 Elf32_Word; /* Unsigned large integer */ +-typedef u16 Elf32_Half; /* Unsigned medium integer */ +- +-typedef u64 Elf64_Addr; +-typedef u64 Elf64_Off; +-typedef s32 Elf64_Shalf; +- +-typedef s32 Elf64_Sword; +-typedef u32 Elf64_Word; +- +-typedef s64 Elf64_Sxword; +-typedef u64 Elf64_Xword; +- +-typedef u32 Elf64_Half; +-typedef u16 Elf64_Quarter; +- +-/* +- * e_ident[] identification indexes +- * See http://www.caldera.com/developers/gabi/2000-07-17/ch4.eheader.html +- */ +-#define EI_MAG0 0 /* file ID */ +-#define EI_MAG1 1 /* file ID */ +-#define EI_MAG2 2 /* file ID */ +-#define EI_MAG3 3 /* file ID */ +-#define EI_CLASS 4 /* file class */ +-#define EI_DATA 5 /* data encoding */ +-#define EI_VERSION 6 /* ELF header version */ +-#define EI_OSABI 7 /* OS/ABI ID */ +-#define EI_ABIVERSION 8 /* ABI version */ +-#define EI_PAD 9 /* start of pad bytes */ +-#define EI_NIDENT 16 /* Size of e_ident[] */ +- +-/* e_ident[] magic number */ +-#define ELFMAG0 0x7f /* e_ident[EI_MAG0] */ +-#define ELFMAG1 'E' /* e_ident[EI_MAG1] */ +-#define ELFMAG2 'L' /* e_ident[EI_MAG2] */ +-#define ELFMAG3 'F' /* e_ident[EI_MAG3] */ +-#define ELFMAG "\177ELF" /* magic */ +-#define SELFMAG 4 /* size of magic */ +- +-/* e_ident[] file class */ +-#define ELFCLASSNONE 0 /* invalid */ +-#define ELFCLASS32 1 /* 32-bit objs */ +-#define ELFCLASS64 2 /* 64-bit objs */ +-#define ELFCLASSNUM 3 /* number of classes */ +- +-/* e_ident[] data encoding */ +-#define ELFDATANONE 0 /* invalid */ +-#define ELFDATA2LSB 1 /* Little-Endian */ +-#define ELFDATA2MSB 2 /* Big-Endian */ +-#define ELFDATANUM 3 /* number of data encode defines */ +- +-/* e_ident[] Operating System/ABI */ +-#define ELFOSABI_SYSV 0 /* UNIX System V ABI */ +-#define ELFOSABI_HPUX 1 /* HP-UX operating system */ +-#define ELFOSABI_NETBSD 2 /* NetBSD */ +-#define ELFOSABI_LINUX 3 /* GNU/Linux */ +-#define ELFOSABI_HURD 4 /* GNU/Hurd */ +-#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */ +-#define ELFOSABI_SOLARIS 6 /* Solaris */ +-#define ELFOSABI_MONTEREY 7 /* Monterey */ +-#define ELFOSABI_IRIX 8 /* IRIX */ +-#define ELFOSABI_FREEBSD 9 /* FreeBSD */ +-#define ELFOSABI_TRU64 10 /* TRU64 UNIX */ +-#define ELFOSABI_MODESTO 11 /* Novell Modesto */ +-#define ELFOSABI_OPENBSD 12 /* OpenBSD */ +-#define ELFOSABI_ARM 97 /* ARM */ +-#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ +- +-/* e_ident */ +-#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ +- (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ +- (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ +- (ehdr).e_ident[EI_MAG3] == ELFMAG3) +- +-/* ELF Header */ +-typedef struct elfhdr { +- unsigned char e_ident[EI_NIDENT]; /* ELF Identification */ +- Elf32_Half e_type; /* object file type */ +- Elf32_Half e_machine; /* machine */ +- Elf32_Word e_version; /* object file version */ +- Elf32_Addr e_entry; /* virtual entry point */ +- Elf32_Off e_phoff; /* program header table offset */ +- Elf32_Off e_shoff; /* section header table offset */ +- Elf32_Word e_flags; /* processor-specific flags */ +- Elf32_Half e_ehsize; /* ELF header size */ +- Elf32_Half e_phentsize; /* program header entry size */ +- Elf32_Half e_phnum; /* number of program header entries */ +- Elf32_Half e_shentsize; /* section header entry size */ +- Elf32_Half e_shnum; /* number of section header entries */ +- Elf32_Half e_shstrndx; /* section header table's "section +- header string table" entry offset */ +-} Elf32_Ehdr; +- +-typedef struct { +- unsigned char e_ident[EI_NIDENT]; /* Id bytes */ +- Elf64_Quarter e_type; /* file type */ +- Elf64_Quarter e_machine; /* machine type */ +- Elf64_Half e_version; /* version number */ +- Elf64_Addr e_entry; /* entry point */ +- Elf64_Off e_phoff; /* Program hdr offset */ +- Elf64_Off e_shoff; /* Section hdr offset */ +- Elf64_Half e_flags; /* Processor flags */ +- Elf64_Quarter e_ehsize; /* sizeof ehdr */ +- Elf64_Quarter e_phentsize; /* Program header entry size */ +- Elf64_Quarter e_phnum; /* Number of program headers */ +- Elf64_Quarter e_shentsize; /* Section header entry size */ +- Elf64_Quarter e_shnum; /* Number of section headers */ +- Elf64_Quarter e_shstrndx; /* String table index */ +-} Elf64_Ehdr; +- +-/* e_type */ +-#define ET_NONE 0 /* No file type */ +-#define ET_REL 1 /* relocatable file */ +-#define ET_EXEC 2 /* executable file */ +-#define ET_DYN 3 /* shared object file */ +-#define ET_CORE 4 /* core file */ +-#define ET_NUM 5 /* number of types */ +-#define ET_LOPROC 0xff00 /* reserved range for processor */ +-#define ET_HIPROC 0xffff /* specific e_type */ +- +-/* e_machine */ +-#define EM_NONE 0 /* No Machine */ +-#define EM_M32 1 /* AT&T WE 32100 */ +-#define EM_SPARC 2 /* SPARC */ +-#define EM_386 3 /* Intel 80386 */ +-#define EM_68K 4 /* Motorola 68000 */ +-#define EM_88K 5 /* Motorola 88000 */ +-#define EM_486 6 /* Intel 80486 - unused? */ +-#define EM_860 7 /* Intel 80860 */ +-#define EM_MIPS 8 /* MIPS R3000 Big-Endian only */ +-/* +- * Don't know if EM_MIPS_RS4_BE, +- * EM_SPARC64, EM_PARISC, +- * or EM_PPC are ABI compliant +- */ +-#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ +-#define EM_SPARC64 11 /* SPARC v9 64-bit unoffical */ +-#define EM_PARISC 15 /* HPPA */ +-#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */ +-#define EM_PPC 20 /* PowerPC */ +-#define EM_PPC64 21 /* PowerPC 64-bit */ +-#define EM_ARM 40 /* Advanced RISC Machines ARM */ +-#define EM_ALPHA 41 /* DEC ALPHA */ +-#define EM_SPARCV9 43 /* SPARC version 9 */ +-#define EM_ALPHA_EXP 0x9026 /* DEC ALPHA */ +-#define EM_IA_64 50 /* Intel Merced */ +-#define EM_X86_64 62 /* AMD x86-64 architecture */ +-#define EM_VAX 75 /* DEC VAX */ +- +-/* Version */ +-#define EV_NONE 0 /* Invalid */ +-#define EV_CURRENT 1 /* Current */ +-#define EV_NUM 2 /* number of versions */ +- +-/* Section Header */ +-typedef struct { +- Elf32_Word sh_name; /* name - index into section header +- string table section */ +- Elf32_Word sh_type; /* type */ +- Elf32_Word sh_flags; /* flags */ +- Elf32_Addr sh_addr; /* address */ +- Elf32_Off sh_offset; /* file offset */ +- Elf32_Word sh_size; /* section size */ +- Elf32_Word sh_link; /* section header table index link */ +- Elf32_Word sh_info; /* extra information */ +- Elf32_Word sh_addralign; /* address alignment */ +- Elf32_Word sh_entsize; /* section entry size */ +-} Elf32_Shdr; +- +-typedef struct { +- Elf64_Half sh_name; /* section name */ +- Elf64_Half sh_type; /* section type */ +- Elf64_Xword sh_flags; /* section flags */ +- Elf64_Addr sh_addr; /* virtual address */ +- Elf64_Off sh_offset; /* file offset */ +- Elf64_Xword sh_size; /* section size */ +- Elf64_Half sh_link; /* link to another */ +- Elf64_Half sh_info; /* misc info */ +- Elf64_Xword sh_addralign; /* memory alignment */ +- Elf64_Xword sh_entsize; /* table entry size */ +-} Elf64_Shdr; +- +-/* Special Section Indexes */ +-#define SHN_UNDEF 0 /* undefined */ +-#define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */ +-#define SHN_LOPROC 0xff00 /* reserved range for processor */ +-#define SHN_HIPROC 0xff1f /* specific section indexes */ +-#define SHN_ABS 0xfff1 /* absolute value */ +-#define SHN_COMMON 0xfff2 /* common symbol */ +-#define SHN_HIRESERVE 0xffff /* upper bounds of reserved indexes */ +- +-/* sh_type */ +-#define SHT_NULL 0 /* inactive */ +-#define SHT_PROGBITS 1 /* program defined information */ +-#define SHT_SYMTAB 2 /* symbol table section */ +-#define SHT_STRTAB 3 /* string table section */ +-#define SHT_RELA 4 /* relocation section with addends*/ +-#define SHT_HASH 5 /* symbol hash table section */ +-#define SHT_DYNAMIC 6 /* dynamic section */ +-#define SHT_NOTE 7 /* note section */ +-#define SHT_NOBITS 8 /* no space section */ +-#define SHT_REL 9 /* relation section without addends */ +-#define SHT_SHLIB 10 /* reserved - purpose unknown */ +-#define SHT_DYNSYM 11 /* dynamic symbol table section */ +-#define SHT_NUM 12 /* number of section types */ +-#define SHT_LOPROC 0x70000000 /* reserved range for processor */ +-#define SHT_HIPROC 0x7fffffff /* specific section header types */ +-#define SHT_LOUSER 0x80000000 /* reserved range for application */ +-#define SHT_HIUSER 0xffffffff /* specific indexes */ +- +-/* Section names */ +-#define ELF_BSS ".bss" /* uninitialized data */ +-#define ELF_DATA ".data" /* initialized data */ +-#define ELF_DEBUG ".debug" /* debug */ +-#define ELF_DYNAMIC ".dynamic" /* dynamic linking information */ +-#define ELF_DYNSTR ".dynstr" /* dynamic string table */ +-#define ELF_DYNSYM ".dynsym" /* dynamic symbol table */ +-#define ELF_FINI ".fini" /* termination code */ +-#define ELF_GOT ".got" /* global offset table */ +-#define ELF_HASH ".hash" /* symbol hash table */ +-#define ELF_INIT ".init" /* initialization code */ +-#define ELF_REL_DATA ".rel.data" /* relocation data */ +-#define ELF_REL_FINI ".rel.fini" /* relocation termination code */ +-#define ELF_REL_INIT ".rel.init" /* relocation initialization code */ +-#define ELF_REL_DYN ".rel.dyn" /* relocaltion dynamic link info */ +-#define ELF_REL_RODATA ".rel.rodata" /* relocation read-only data */ +-#define ELF_REL_TEXT ".rel.text" /* relocation code */ +-#define ELF_RODATA ".rodata" /* read-only data */ +-#define ELF_SHSTRTAB ".shstrtab" /* section header string table */ +-#define ELF_STRTAB ".strtab" /* string table */ +-#define ELF_SYMTAB ".symtab" /* symbol table */ +-#define ELF_TEXT ".text" /* code */ +- +- +-/* Section Attribute Flags - sh_flags */ +-#define SHF_WRITE 0x1 /* Writable */ +-#define SHF_ALLOC 0x2 /* occupies memory */ +-#define SHF_EXECINSTR 0x4 /* executable */ +-#define SHF_MASKPROC 0xf0000000 /* reserved bits for processor */ +- /* specific section attributes */ +- +-/* Symbol Table Entry */ +-typedef struct elf32_sym { +- Elf32_Word st_name; /* name - index into string table */ +- Elf32_Addr st_value; /* symbol value */ +- Elf32_Word st_size; /* symbol size */ +- unsigned char st_info; /* type and binding */ +- unsigned char st_other; /* 0 - no defined meaning */ +- Elf32_Half st_shndx; /* section header index */ +-} Elf32_Sym; +- +-typedef struct { +- Elf64_Half st_name; /* Symbol name index in str table */ +- Elf_Byte st_info; /* type / binding attrs */ +- Elf_Byte st_other; /* unused */ +- Elf64_Quarter st_shndx; /* section index of symbol */ +- Elf64_Xword st_value; /* value of symbol */ +- Elf64_Xword st_size; /* size of symbol */ +-} Elf64_Sym; +- +-/* Symbol table index */ +-#define STN_UNDEF 0 /* undefined */ +- +-/* Extract symbol info - st_info */ +-#define ELF32_ST_BIND(x) ((x) >> 4) +-#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf) +-#define ELF32_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf)) +- +-#define ELF64_ST_BIND(x) ((x) >> 4) +-#define ELF64_ST_TYPE(x) (((unsigned int) x) & 0xf) +-#define ELF64_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf)) +- +-/* Symbol Binding - ELF32_ST_BIND - st_info */ +-#define STB_LOCAL 0 /* Local symbol */ +-#define STB_GLOBAL 1 /* Global symbol */ +-#define STB_WEAK 2 /* like global - lower precedence */ +-#define STB_NUM 3 /* number of symbol bindings */ +-#define STB_LOPROC 13 /* reserved range for processor */ +-#define STB_HIPROC 15 /* specific symbol bindings */ +- +-/* Symbol type - ELF32_ST_TYPE - st_info */ +-#define STT_NOTYPE 0 /* not specified */ +-#define STT_OBJECT 1 /* data object */ +-#define STT_FUNC 2 /* function */ +-#define STT_SECTION 3 /* section */ +-#define STT_FILE 4 /* file */ +-#define STT_NUM 5 /* number of symbol types */ +-#define STT_LOPROC 13 /* reserved range for processor */ +-#define STT_HIPROC 15 /* specific symbol types */ +- +-/* Relocation entry with implicit addend */ +-typedef struct { +- Elf32_Addr r_offset; /* offset of relocation */ +- Elf32_Word r_info; /* symbol table index and type */ +-} Elf32_Rel; +- +-/* Relocation entry with explicit addend */ +-typedef struct { +- Elf32_Addr r_offset; /* offset of relocation */ +- Elf32_Word r_info; /* symbol table index and type */ +- Elf32_Sword r_addend; +-} Elf32_Rela; +- +-/* Extract relocation info - r_info */ +-#define ELF32_R_SYM(i) ((i) >> 8) +-#define ELF32_R_TYPE(i) ((unsigned char) (i)) +-#define ELF32_R_INFO(s,t) (((s) << 8) + (unsigned char)(t)) +- +-typedef struct { +- Elf64_Xword r_offset; /* where to do it */ +- Elf64_Xword r_info; /* index & type of relocation */ +-} Elf64_Rel; +- +-typedef struct { +- Elf64_Xword r_offset; /* where to do it */ +- Elf64_Xword r_info; /* index & type of relocation */ +- Elf64_Sxword r_addend; /* adjustment value */ +-} Elf64_Rela; +- +-#define ELF64_R_SYM(info) ((info) >> 32) +-#define ELF64_R_TYPE(info) ((info) & 0xFFFFFFFF) +-#define ELF64_R_INFO(s,t) (((s) << 32) + (u32)(t)) +- +-/* Program Header */ +-typedef struct { +- Elf32_Word p_type; /* segment type */ +- Elf32_Off p_offset; /* segment offset */ +- Elf32_Addr p_vaddr; /* virtual address of segment */ +- Elf32_Addr p_paddr; /* physical address - ignored? */ +- Elf32_Word p_filesz; /* number of bytes in file for seg. */ +- Elf32_Word p_memsz; /* number of bytes in mem. for seg. */ +- Elf32_Word p_flags; /* flags */ +- Elf32_Word p_align; /* memory alignment */ +-} Elf32_Phdr; +- +-typedef struct { +- Elf64_Half p_type; /* entry type */ +- Elf64_Half p_flags; /* flags */ +- Elf64_Off p_offset; /* offset */ +- Elf64_Addr p_vaddr; /* virtual address */ +- Elf64_Addr p_paddr; /* physical address */ +- Elf64_Xword p_filesz; /* file size */ +- Elf64_Xword p_memsz; /* memory size */ +- Elf64_Xword p_align; /* memory & file alignment */ +-} Elf64_Phdr; +- +-/* Segment types - p_type */ +-#define PT_NULL 0 /* unused */ +-#define PT_LOAD 1 /* loadable segment */ +-#define PT_DYNAMIC 2 /* dynamic linking section */ +-#define PT_INTERP 3 /* the RTLD */ +-#define PT_NOTE 4 /* auxiliary information */ +-#define PT_SHLIB 5 /* reserved - purpose undefined */ +-#define PT_PHDR 6 /* program header */ +-#define PT_NUM 7 /* Number of segment types */ +-#define PT_LOPROC 0x70000000 /* reserved range for processor */ +-#define PT_HIPROC 0x7fffffff /* specific segment types */ +- +-/* Segment flags - p_flags */ +-#define PF_X 0x1 /* Executable */ +-#define PF_W 0x2 /* Writable */ +-#define PF_R 0x4 /* Readable */ +-#define PF_MASKPROC 0xf0000000 /* reserved bits for processor */ +- /* specific segment flags */ +- +-/* Dynamic structure */ +-typedef struct { +- Elf32_Sword d_tag; /* controls meaning of d_val */ +- union { +- Elf32_Word d_val; /* Multiple meanings - see d_tag */ +- Elf32_Addr d_ptr; /* program virtual address */ +- } d_un; +-} Elf32_Dyn; +- +-typedef struct { +- Elf64_Xword d_tag; /* controls meaning of d_val */ +- union { +- Elf64_Addr d_ptr; +- Elf64_Xword d_val; +- } d_un; +-} Elf64_Dyn; +- +-/* Dynamic Array Tags - d_tag */ +-#define DT_NULL 0 /* marks end of _DYNAMIC array */ +-#define DT_NEEDED 1 /* string table offset of needed lib */ +-#define DT_PLTRELSZ 2 /* size of relocation entries in PLT */ +-#define DT_PLTGOT 3 /* address PLT/GOT */ +-#define DT_HASH 4 /* address of symbol hash table */ +-#define DT_STRTAB 5 /* address of string table */ +-#define DT_SYMTAB 6 /* address of symbol table */ +-#define DT_RELA 7 /* address of relocation table */ +-#define DT_RELASZ 8 /* size of relocation table */ +-#define DT_RELAENT 9 /* size of relocation entry */ +-#define DT_STRSZ 10 /* size of string table */ +-#define DT_SYMENT 11 /* size of symbol table entry */ +-#define DT_INIT 12 /* address of initialization func. */ +-#define DT_FINI 13 /* address of termination function */ +-#define DT_SONAME 14 /* string table offset of shared obj */ +-#define DT_RPATH 15 /* string table offset of library +- search path */ +-#define DT_SYMBOLIC 16 /* start sym search in shared obj. */ +-#define DT_REL 17 /* address of rel. tbl. w addends */ +-#define DT_RELSZ 18 /* size of DT_REL relocation table */ +-#define DT_RELENT 19 /* size of DT_REL relocation entry */ +-#define DT_PLTREL 20 /* PLT referenced relocation entry */ +-#define DT_DEBUG 21 /* bugger */ +-#define DT_TEXTREL 22 /* Allow rel. mod. to unwritable seg */ +-#define DT_JMPREL 23 /* add. of PLT's relocation entries */ +-#define DT_BIND_NOW 24 /* Bind now regardless of env setting */ +-#define DT_NUM 25 /* Number used. */ +-#define DT_LOPROC 0x70000000 /* reserved range for processor */ +-#define DT_HIPROC 0x7fffffff /* specific dynamic array tags */ +- +-/* Standard ELF hashing function */ +-unsigned int elf_hash(const unsigned char *name); +- +-/* +- * Note Definitions +- */ +- +-typedef struct { +- u32 namesz; +- u32 descsz; +- u32 type; +-} Elf_Note; /* same format for both 32-bit and 64-bit ELF */ +- +-#if defined(ELFSIZE) +-#define CONCAT(x,y) __CONCAT(x,y) +-#define ELFNAME(x) CONCAT(elf,CONCAT(ELFSIZE,CONCAT(_,x))) +-#define ELFNAME2(x,y) CONCAT(x,CONCAT(_elf,CONCAT(ELFSIZE,CONCAT(_,y)))) +-#define ELFNAMEEND(x) CONCAT(x,CONCAT(_elf,ELFSIZE)) +-#define ELFDEFNNAME(x) CONCAT(ELF,CONCAT(ELFSIZE,CONCAT(_,x))) +-#endif +- +-#if defined(ELFSIZE) && (ELFSIZE == 32) +-#define Elf_Ehdr Elf32_Ehdr +-#define Elf_Phdr Elf32_Phdr +-#define Elf_Shdr Elf32_Shdr +-#define Elf_Sym Elf32_Sym +-#define Elf_Rel Elf32_Rel +-#define Elf_RelA Elf32_Rela +-#define Elf_Dyn Elf32_Dyn +-#define Elf_Word Elf32_Word +-#define Elf_Sword Elf32_Sword +-#define Elf_Addr Elf32_Addr +-#define Elf_Off Elf32_Off +-#define Elf_Nhdr Elf32_Nhdr +- +-#define ELF_R_SYM ELF32_R_SYM +-#define ELF_R_TYPE ELF32_R_TYPE +-#define ELF_R_INFO ELF32_R_INFO +-#define ELFCLASS ELFCLASS32 +- +-#define ELF_ST_BIND ELF32_ST_BIND +-#define ELF_ST_TYPE ELF32_ST_TYPE +-#define ELF_ST_INFO ELF32_ST_INFO +- +-#define AuxInfo Aux32Info +-#elif defined(ELFSIZE) && (ELFSIZE == 64) +-#define Elf_Ehdr Elf64_Ehdr +-#define Elf_Phdr Elf64_Phdr +-#define Elf_Shdr Elf64_Shdr +-#define Elf_Sym Elf64_Sym +-#define Elf_Rel Elf64_Rel +-#define Elf_RelA Elf64_Rela +-#define Elf_Dyn Elf64_Dyn +-#define Elf_Word Elf64_Word +-#define Elf_Sword Elf64_Sword +-#define Elf_Addr Elf64_Addr +-#define Elf_Off Elf64_Off +-#define Elf_Nhdr Elf64_Nhdr +- +-#define ELF_R_SYM ELF64_R_SYM +-#define ELF_R_TYPE ELF64_R_TYPE +-#define ELF_R_INFO ELF64_R_INFO +-#define ELFCLASS ELFCLASS64 +- +-#define ELF_ST_BIND ELF64_ST_BIND +-#define ELF_ST_TYPE ELF64_ST_TYPE +-#define ELF_ST_INFO ELF64_ST_INFO +- +-#define AuxInfo Aux64Info +-#endif ++#include + + struct domain_setup_info; + extern int loadelfimage(struct domain_setup_info *); +Index: build-32-release304-13132/xen/arch/x86/boot/mkelf32.c +=================================================================== +--- build-32-release304-13132.orig/xen/arch/x86/boot/mkelf32.c ++++ build-32-release304-13132/xen/arch/x86/boot/mkelf32.c +@@ -25,7 +25,7 @@ + #define s16 int16_t + #define s32 int32_t + #define s64 int64_t +-#include "../../../include/xen/elf.h" ++#include "../../../include/public/elfstructs.h" + + #define DYNAMICALLY_FILLED 0 + #define RAW_OFFSET 128 diff --git a/libelf-symlink-to-libxc.diff b/libelf-symlink-to-libxc.diff new file mode 100644 index 0000000..0ccc5a8 --- /dev/null +++ b/libelf-symlink-to-libxc.diff @@ -0,0 +1,36 @@ +libelf: add to libxc + +This patch makes libelf available to the tools, by symlinking the source +files and compiling them into libxc. + +Signed-off-by: Gerd Hoffmann +--- + tools/libxc/Makefile | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +Index: build-32-unstable-12621/tools/libxc/Makefile +=================================================================== +--- build-32-unstable-12621.orig/tools/libxc/Makefile ++++ build-32-unstable-12621/tools/libxc/Makefile +@@ -29,6 +29,21 @@ GUEST_SRCS-$(CONFIG_IA64) += xc_linux_bu + GUEST_SRCS-$(CONFIG_MIGRATE) += xc_linux_restore.c xc_linux_save.c + GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c + ++# symlink libelf from xen/common/libelf/ ++LIBELF_SRCS := libelf-tools.c libelf-loader.c ++LIBELF_SRCS += libelf-dominfo.c libelf-relocate.c ++ ++libelf-tools.o: libelf-tools.c libelf-private.h ++libelf-loader.o: libelf-loader.c libelf-private.h ++libelf-dominfo.o: libelf-dominfo.c libelf-private.h ++libelf-relocate.o: libelf-relocate.c libelf-private.h ++ ++$(LIBELF_SRCS) libelf-private.h: ++ ln -s ../../xen/common/libelf/$@ $@ ++ ++# add libelf bits to libxc ++GUEST_SRCS-y += $(LIBELF_SRCS) ++ + -include $(XEN_TARGET_ARCH)/Makefile + + CFLAGS += -Werror -Wmissing-prototypes diff --git a/libelf-use-hvm-build.diff b/libelf-use-hvm-build.diff new file mode 100644 index 0000000..a47a177 --- /dev/null +++ b/libelf-use-hvm-build.diff @@ -0,0 +1,300 @@ +libelf: use for hvm builder. + +This patch switches over the hvm domain builder to libelf +(for loading hvmloader). + +Signed-off-by: Gerd Hoffmann +--- + tools/libxc/xc_hvm_build.c | 220 +++++++++++++-------------------------------- + 1 file changed, 65 insertions(+), 155 deletions(-) + +Index: build-32-unstable-12802/tools/libxc/xc_hvm_build.c +=================================================================== +--- build-32-unstable-12802.orig/tools/libxc/xc_hvm_build.c ++++ build-32-unstable-12802/tools/libxc/xc_hvm_build.c +@@ -2,29 +2,22 @@ + * xc_hvm_build.c + */ + +-#define ELFSIZE 32 + #include + #include +-#include "xg_private.h" +-#include "xc_private.h" +-#include "xc_elf.h" + #include + #include + #include ++ ++#include "xg_private.h" ++#include "xc_private.h" ++ + #include + #include + #include + +-#define SCRATCH_PFN 0xFFFFF ++#include + +-#define HVM_LOADER_ENTR_ADDR 0x00100000 +-static int +-parseelfimage( +- char *elfbase, unsigned long elfsize, struct domain_setup_info *dsi); +-static int +-loadelfimage( +- char *elfbase, int xch, uint32_t dom, unsigned long *parray, +- struct domain_setup_info *dsi); ++#define SCRATCH_PFN 0xFFFFF + + int xc_set_hvm_param( + int handle, domid_t dom, int param, unsigned long value) +@@ -144,6 +137,48 @@ static void build_e820map(void *e820_pag + *(((unsigned char *)e820_page) + E820_MAP_NR_OFFSET) = nr_map; + } + ++static int ++loadelfimage(struct elf_binary *elf, int xch, uint32_t dom, unsigned long *parray) ++{ ++ privcmd_mmap_entry_t *entries = NULL; ++ int pages = (elf->pend - elf->pstart + PAGE_SIZE - 1) >> PAGE_SHIFT; ++ int i, rc = -1; ++ ++ /* map hvmloader address space */ ++ entries = malloc(pages * sizeof(privcmd_mmap_entry_t)); ++ if (NULL == entries) ++ goto err; ++ elf->dest = mmap(NULL, pages << PAGE_SHIFT, PROT_READ | PROT_WRITE, ++ MAP_SHARED, xch, 0); ++ if (MAP_FAILED == elf->dest) ++ goto err; ++ ++ for (i = 0; i < pages; i++) ++ { ++ entries[i].va = (uintptr_t)elf->dest + (i << PAGE_SHIFT); ++ entries[i].mfn = parray[(elf->pstart >> PAGE_SHIFT) + i]; ++ entries[i].npages = 1; ++ } ++ rc = xc_map_foreign_ranges(xch, dom, entries, pages); ++ if (rc < 0) ++ goto err; ++ ++ /* load hvmloader */ ++ elf_load_binary(elf); ++ rc = 0; ++ ++ err: ++ /* cleanup */ ++ if (elf->dest) { ++ munmap(elf->dest, pages << PAGE_SHIFT); ++ elf->dest = NULL; ++ } ++ if (entries) ++ free(entries); ++ ++ return rc; ++} ++ + static int setup_guest(int xc_handle, + uint32_t dom, int memsize, + char *image, unsigned long image_size, +@@ -155,35 +190,35 @@ static int setup_guest(int xc_handle, + struct xen_add_to_physmap xatp; + struct shared_info *shared_info; + void *e820_page; +- struct domain_setup_info dsi; +- uint64_t v_end; ++ struct elf_binary elf; ++ uint64_t v_start, v_end; + int rc; + +- memset(&dsi, 0, sizeof(struct domain_setup_info)); +- +- if ( (parseelfimage(image, image_size, &dsi)) != 0 ) ++ if (0 != elf_init(&elf, image, image_size)) + goto error_out; ++ elf_parse_binary(&elf); ++ v_start = 0; ++ v_end = (unsigned long long)memsize << 20; + +- if ( (dsi.v_kernstart & (PAGE_SIZE - 1)) != 0 ) ++ if ( (elf.pstart & (PAGE_SIZE - 1)) != 0 ) + { + PERROR("Guest OS must load to a page boundary.\n"); + goto error_out; + } + +- v_end = (unsigned long long)memsize << 20; +- + IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n" +- " Loaded HVM loader: %016"PRIx64"->%016"PRIx64"\n" +- " TOTAL: %016"PRIx64"->%016"PRIx64"\n", +- dsi.v_kernstart, dsi.v_kernend, +- dsi.v_start, v_end); +- IPRINTF(" ENTRY ADDRESS: %016"PRIx64"\n", dsi.v_kernentry); ++ " Loaded HVM loader: %016"PRIx64"->%016"PRIx64"\n" ++ " TOTAL: %016"PRIx64"->%016"PRIx64"\n" ++ " ENTRY ADDRESS: %016"PRIx64"\n", ++ elf.pstart, elf.pend, ++ v_start, v_end, ++ elf_uval(&elf, elf.ehdr, e_entry)); + +- if ( (v_end - dsi.v_start) > ((unsigned long long)nr_pages << PAGE_SHIFT) ) ++ if ( (v_end - v_start) > ((unsigned long long)nr_pages << PAGE_SHIFT) ) + { + PERROR("Initial guest OS requires too much space: " + "(%lluMB is greater than %lluMB limit)\n", +- (unsigned long long)(v_end - dsi.v_start) >> 20, ++ (unsigned long long)(v_end - v_start) >> 20, + ((unsigned long long)nr_pages << PAGE_SHIFT) >> 20); + goto error_out; + } +@@ -212,7 +247,7 @@ static int setup_guest(int xc_handle, + goto error_out; + } + +- loadelfimage(image, xc_handle, dom, page_array, &dsi); ++ loadelfimage(&elf, xc_handle, dom, page_array); + + if ( (e820_page = xc_map_foreign_range( + xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, +@@ -256,7 +291,7 @@ static int setup_guest(int xc_handle, + + free(page_array); + +- ctxt->user_regs.eip = dsi.v_kernentry; ++ ctxt->user_regs.eip = elf_uval(&elf, elf.ehdr, e_entry); + + return 0; + +@@ -315,131 +350,6 @@ static inline int is_loadable_phdr(Elf32 + ((phdr->p_flags & (PF_W|PF_X)) != 0)); + } + +-static int parseelfimage(char *elfbase, +- unsigned long elfsize, +- struct domain_setup_info *dsi) +-{ +- Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfbase; +- Elf32_Phdr *phdr; +- Elf32_Shdr *shdr; +- unsigned long kernstart = ~0UL, kernend=0UL; +- char *shstrtab; +- int h; +- +- if ( !IS_ELF(*ehdr) ) +- { +- xc_set_error(XC_INVALID_KERNEL, +- "Kernel image does not have an ELF header."); +- return -EINVAL; +- } +- +- if ( (ehdr->e_phoff + (ehdr->e_phnum * ehdr->e_phentsize)) > elfsize ) +- { +- xc_set_error(XC_INVALID_KERNEL, +- "ELF program headers extend beyond end of image."); +- return -EINVAL; +- } +- +- if ( (ehdr->e_shoff + (ehdr->e_shnum * ehdr->e_shentsize)) > elfsize ) +- { +- xc_set_error(XC_INVALID_KERNEL, +- "ELF section headers extend beyond end of image."); +- return -EINVAL; +- } +- +- /* Find the section-header strings table. */ +- if ( ehdr->e_shstrndx == SHN_UNDEF ) +- { +- xc_set_error(XC_INVALID_KERNEL, +- "ELF image has no section-header strings table (shstrtab)."); +- return -EINVAL; +- } +- shdr = (Elf32_Shdr *)(elfbase + ehdr->e_shoff + +- (ehdr->e_shstrndx*ehdr->e_shentsize)); +- shstrtab = elfbase + shdr->sh_offset; +- +- for ( h = 0; h < ehdr->e_phnum; h++ ) +- { +- phdr = (Elf32_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize)); +- if ( !is_loadable_phdr(phdr) ) +- continue; +- if ( phdr->p_paddr < kernstart ) +- kernstart = phdr->p_paddr; +- if ( (phdr->p_paddr + phdr->p_memsz) > kernend ) +- kernend = phdr->p_paddr + phdr->p_memsz; +- } +- +- if ( (kernstart > kernend) || +- (ehdr->e_entry < kernstart) || +- (ehdr->e_entry > kernend) ) +- { +- xc_set_error(XC_INVALID_KERNEL, +- "Malformed ELF image."); +- return -EINVAL; +- } +- +- dsi->v_start = 0x00000000; +- +- dsi->v_kernstart = kernstart; +- dsi->v_kernend = kernend; +- dsi->v_kernentry = HVM_LOADER_ENTR_ADDR; +- +- dsi->v_end = dsi->v_kernend; +- +- return 0; +-} +- +-static int +-loadelfimage( +- char *elfbase, int xch, uint32_t dom, unsigned long *parray, +- struct domain_setup_info *dsi) +-{ +- Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfbase; +- Elf32_Phdr *phdr; +- int h; +- +- char *va; +- unsigned long pa, done, chunksz; +- +- for ( h = 0; h < ehdr->e_phnum; h++ ) +- { +- phdr = (Elf32_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize)); +- if ( !is_loadable_phdr(phdr) ) +- continue; +- +- for ( done = 0; done < phdr->p_filesz; done += chunksz ) +- { +- pa = (phdr->p_paddr + done) - dsi->v_start; +- if ((va = xc_map_foreign_range( +- xch, dom, PAGE_SIZE, PROT_WRITE, +- parray[pa >> PAGE_SHIFT])) == 0) +- return -1; +- chunksz = phdr->p_filesz - done; +- if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) ) +- chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1)); +- memcpy(va + (pa & (PAGE_SIZE-1)), +- elfbase + phdr->p_offset + done, chunksz); +- munmap(va, PAGE_SIZE); +- } +- +- for ( ; done < phdr->p_memsz; done += chunksz ) +- { +- pa = (phdr->p_paddr + done) - dsi->v_start; +- if ((va = xc_map_foreign_range( +- xch, dom, PAGE_SIZE, PROT_WRITE, +- parray[pa >> PAGE_SHIFT])) == 0) +- return -1; +- chunksz = phdr->p_memsz - done; +- if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) ) +- chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1)); +- memset(va + (pa & (PAGE_SIZE-1)), 0, chunksz); +- munmap(va, PAGE_SIZE); +- } +- } +- +- return 0; +-} +- + /* xc_hvm_build + * + * Create a domain for a virtualized Linux, using files/filenames diff --git a/libelf-use-readnotes.diff b/libelf-use-readnotes.diff new file mode 100644 index 0000000..35c2715 --- /dev/null +++ b/libelf-use-readnotes.diff @@ -0,0 +1,360 @@ +libelf: use for readnotes utility. + +This patch makes the readnotes utility use libelf. + +Signed-off-by: Gerd Hoffmann +--- + tools/xcutils/readnotes.c | 277 +++++++--------------------------------------- + 1 file changed, 45 insertions(+), 232 deletions(-) + +Index: build-32-unstable-12621/tools/xcutils/readnotes.c +=================================================================== +--- build-32-unstable-12621.orig/tools/xcutils/readnotes.c ++++ build-32-unstable-12621/tools/xcutils/readnotes.c +@@ -1,4 +1,3 @@ +-#include + #include + #include + #include +@@ -11,219 +10,35 @@ + #include + #include + +-#include +- +-#define ELFNOTE_NAME(_n_) ((void*)(_n_) + sizeof(*(_n_))) +-#define ELFNOTE_DESC(_n_) (ELFNOTE_NAME(_n_) + (((_n_)->n_namesz+3)&~3)) +-#define ELFNOTE_NEXT(_n_) (ELFNOTE_DESC(_n_) + (((_n_)->n_descsz+3)&~3)) +- +-#ifndef ELFSIZE +-#include +-#if UINT_MAX == ULONG_MAX +-#define ELFSIZE 32 +-#else +-#define ELFSIZE 64 +-#endif +-#endif +- +-#if (ELFSIZE == 32) +-typedef Elf32_Nhdr Elf_Nhdr; +-typedef Elf32_Half Elf_Half; +-typedef Elf32_Word Elf_Word; +-#elif (ELFSIZE == 64) +-typedef Elf64_Nhdr Elf_Nhdr; +-typedef Elf64_Half Elf_Half; +-typedef Elf64_Word Elf_Word; +-#else +-#error "Unknown ELFSIZE" +-#endif +- +-static void print_string_note(const char *prefix, Elf_Nhdr *note) +-{ +- printf("%s: %s\n", prefix, (const char *)ELFNOTE_DESC(note)); +-} +- +-static void print_numeric_note(const char *prefix,Elf_Nhdr *note) +-{ +- switch (note->n_descsz) +- { +- case 4: +- printf("%s: %#010" PRIx32 " (4 bytes)\n", +- prefix, *(uint32_t *)ELFNOTE_DESC(note)); +- break; +- case 8: +- printf("%s: %#018" PRIx64 " (8 bytes)\n", +- prefix, *(uint64_t *)ELFNOTE_DESC(note)); +- break; +- default: +- printf("%s: unknown data size %#lx\n", prefix, +- (unsigned long)note->n_descsz); +- break; +- } +-} +- +-static inline int is_elf(void *image) +-{ +- /* +- * Since we are only accessing the e_ident field we can +- * acccess the bytes directly without needing to figure out +- * which version of Elf*_Ehdr structure to use. +- */ +- const unsigned char *hdr = image; +- return ( hdr[EI_MAG0] == ELFMAG0 && +- hdr[EI_MAG1] == ELFMAG1 && +- hdr[EI_MAG2] == ELFMAG2 && +- hdr[EI_MAG3] == ELFMAG3 ); +-} +- +-static inline unsigned char ehdr_class(void *image) +-{ +- /* +- * Since we are only accessing the e_ident field we can +- * acccess the bytes directly without needing to figure out +- * which version of Elf*_Ehdr structure to use. +- */ +- const unsigned char *hdr = image; +- switch (hdr[EI_CLASS]) +- { +- case ELFCLASS32: +- case ELFCLASS64: +- return hdr[EI_CLASS]; +- default: +- fprintf(stderr, "Unknown ELF class %d\n", hdr[EI_CLASS]); +- exit(1); +- } +-} ++#include + +-static inline Elf_Half ehdr_shnum(void *image) +-{ +- switch (ehdr_class(image)) +- { +- case ELFCLASS32: +- return ((Elf32_Ehdr *)image)->e_shnum; +- case ELFCLASS64: +- return ((Elf64_Ehdr *)image)->e_shnum; +- default: +- exit(1); +- } +-} ++#include + +-static inline Elf_Word shdr_type(void *image, int shnum) ++static void print_string_note(const char *prefix, struct elf_binary *elf, ++ const elf_note *note) + { +- switch (ehdr_class(image)) +- { +- case ELFCLASS32: +- { +- Elf32_Ehdr *ehdr = (Elf32_Ehdr *)image; +- Elf32_Shdr *shdr = (Elf32_Shdr*)(image + ehdr->e_shoff + +- (shnum*ehdr->e_shentsize)); +- return shdr->sh_type; +- } +- case ELFCLASS64: +- { +- Elf64_Ehdr *ehdr = (Elf64_Ehdr *)image; +- Elf64_Shdr *shdr = (Elf64_Shdr*)(image + ehdr->e_shoff + +- (shnum*ehdr->e_shentsize)); +- return shdr->sh_type; +- } +- default: +- exit(1); +- } ++ printf("%s: %s\n", prefix, (char*)elf_note_desc(elf, note)); + } + +-static inline const char *shdr_name(void *image, int shnum) +-{ +- const char *shstrtab; +- +- switch (ehdr_class(image)) +- { +- case ELFCLASS32: +- { +- Elf32_Ehdr *ehdr = (Elf32_Ehdr *)image; +- Elf32_Shdr *shdr; +- /* Find the section-header strings table. */ +- if ( ehdr->e_shstrndx == SHN_UNDEF ) +- return NULL; +- shdr = (Elf32_Shdr *)(image + ehdr->e_shoff + +- (ehdr->e_shstrndx*ehdr->e_shentsize)); +- shstrtab = image + shdr->sh_offset; +- +- shdr= (Elf32_Shdr*)(image + ehdr->e_shoff + +- (shnum*ehdr->e_shentsize)); +- return &shstrtab[shdr->sh_name]; +- } +- case ELFCLASS64: +- { +- Elf64_Ehdr *ehdr = (Elf64_Ehdr *)image; +- Elf64_Shdr *shdr; +- /* Find the section-header strings table. */ +- if ( ehdr->e_shstrndx == SHN_UNDEF ) +- return NULL; +- shdr = (Elf64_Shdr *)(image + ehdr->e_shoff + +- (ehdr->e_shstrndx*ehdr->e_shentsize)); +- shstrtab = image + shdr->sh_offset; +- +- shdr= (Elf64_Shdr*)(image + ehdr->e_shoff + +- (shnum*ehdr->e_shentsize)); +- return &shstrtab[shdr->sh_name]; +- } +- default: +- exit(1); +- } +-} +-static inline void *shdr_start(void *image, int shnum) ++static void print_numeric_note(const char *prefix, struct elf_binary *elf, ++ const elf_note *note) + { +- switch (ehdr_class(image)) +- { +- case ELFCLASS32: +- { +- Elf32_Ehdr *ehdr = (Elf32_Ehdr *)image; +- Elf32_Shdr *shdr = (Elf32_Shdr*)(image + ehdr->e_shoff + +- (shnum*ehdr->e_shentsize)); +- return image + shdr->sh_offset; +- } +- case ELFCLASS64: +- { +- Elf64_Ehdr *ehdr = (Elf64_Ehdr *)image; +- Elf64_Shdr *shdr = (Elf64_Shdr*)(image + ehdr->e_shoff + +- (shnum*ehdr->e_shentsize)); +- return image + shdr->sh_offset; +- } +- default: +- exit(1); +- } +-} ++ uint64_t value = elf_note_numeric(elf, note); ++ int descsz = elf_uval(elf, note, descsz); + +-static inline void *shdr_end(void *image, int shnum) +-{ +- switch (ehdr_class(image)) +- { +- case ELFCLASS32: +- { +- Elf32_Ehdr *ehdr = (Elf32_Ehdr *)image; +- Elf32_Shdr *shdr = (Elf32_Shdr*)(image + ehdr->e_shoff + +- (shnum*ehdr->e_shentsize)); +- return image + shdr->sh_offset + shdr->sh_size; +- } +- case ELFCLASS64: +- { +- Elf64_Ehdr *ehdr = (Elf64_Ehdr *)image; +- Elf64_Shdr *shdr = (Elf64_Shdr*)(image + ehdr->e_shoff + +- (shnum*ehdr->e_shentsize)); +- return image + shdr->sh_offset + shdr->sh_size; +- } +- default: +- exit(1); +- } ++ printf("%s: %#*" PRIx64 " (%d bytes)\n", ++ prefix, 2+2*descsz, value, descsz); + } + + int main(int argc, char **argv) + { + const char *f; +- int fd,h; ++ int fd,h,size,count; + void *image; + struct stat st; +- Elf_Nhdr *note; ++ struct elf_binary elf; ++ const elf_shdr *shdr; ++ const elf_note *note, *end; + + if (argc != 2) + { +@@ -251,76 +66,74 @@ int main(int argc, char **argv) + fprintf(stderr, "Unable to map %s: %s\n", f, strerror(errno)); + return 1; + } ++ size = st.st_size; + +- if ( !is_elf(image) ) ++ if (0 != elf_init(&elf, image, size)) + { + fprintf(stderr, "File %s is not an ELF image\n", f); + return 1; + } ++ elf_set_logfile(&elf, stderr, 0); + +- for ( h=0; h < ehdr_shnum(image); h++) ++ count = elf_shdr_count(&elf); ++ for ( h=0; h < count; h++) + { +- if (shdr_type(image,h) != SHT_NOTE) ++ shdr = elf_shdr_by_index(&elf, h); ++ if (elf_uval(&elf, shdr, sh_type) != SHT_NOTE) + continue; +- for (note = (Elf_Nhdr*)shdr_start(image,h); +- note < (Elf_Nhdr*)shdr_end(image,h); +- note = (Elf_Nhdr*)(ELFNOTE_NEXT(note))) ++ end = elf_section_end(&elf, shdr); ++ for (note = elf_section_start(&elf, shdr); ++ note < end; ++ note = elf_note_next(&elf, note)) + { +- switch(note->n_type) ++ if (0 != strcmp(elf_note_name(&elf, note), "Xen")) ++ continue; ++ switch(elf_uval(&elf, note, type)) + { + case XEN_ELFNOTE_INFO: +- print_string_note("INFO", note); ++ print_string_note("INFO", &elf , note); + break; + case XEN_ELFNOTE_ENTRY: +- print_numeric_note("ENTRY", note); ++ print_numeric_note("ENTRY", &elf , note); + break; + case XEN_ELFNOTE_HYPERCALL_PAGE: +- print_numeric_note("HYPERCALL_PAGE", note); ++ print_numeric_note("HYPERCALL_PAGE", &elf , note); + break; + case XEN_ELFNOTE_VIRT_BASE: +- print_numeric_note("VIRT_BASE", note); ++ print_numeric_note("VIRT_BASE", &elf , note); + break; + case XEN_ELFNOTE_PADDR_OFFSET: +- print_numeric_note("PADDR_OFFSET", note); ++ print_numeric_note("PADDR_OFFSET", &elf , note); + break; + case XEN_ELFNOTE_XEN_VERSION: +- print_string_note("XEN_VERSION", note); ++ print_string_note("XEN_VERSION", &elf , note); + break; + case XEN_ELFNOTE_GUEST_OS: +- print_string_note("GUEST_OS", note); ++ print_string_note("GUEST_OS", &elf , note); + break; + case XEN_ELFNOTE_GUEST_VERSION: +- print_string_note("GUEST_VERSION", note); ++ print_string_note("GUEST_VERSION", &elf , note); + break; + case XEN_ELFNOTE_LOADER: +- print_string_note("LOADER", note); ++ print_string_note("LOADER", &elf , note); + break; + case XEN_ELFNOTE_PAE_MODE: +- print_string_note("PAE_MODE", note); ++ print_string_note("PAE_MODE", &elf , note); + break; + case XEN_ELFNOTE_FEATURES: +- print_string_note("FEATURES", note); ++ print_string_note("FEATURES", &elf , note); + break; + default: +- printf("unknown note type %#lx\n", +- (unsigned long)note->n_type); ++ printf("unknown note type %#x\n", ++ (int)elf_uval(&elf, note, type)); + break; + } + } + } + +- for ( h=0; h < ehdr_shnum(image); h++) +- { +- const char *name = shdr_name(image,h); +- +- if ( name == NULL ) +- continue; +- if ( strcmp(name, "__xen_guest") != 0 ) +- continue; +- +- printf("__xen_guest: %s\n", (const char *)shdr_start(image, h)); +- break; +- } ++ shdr = elf_shdr_by_name(&elf, "__xen_guest"); ++ if (shdr) ++ printf("__xen_guest: %s\n", (char*)elf_section_start(&elf, shdr)); + + return 0; + } diff --git a/libelf-use-xen-dom0.diff b/libelf-use-xen-dom0.diff new file mode 100644 index 0000000..48c3c91 --- /dev/null +++ b/libelf-use-xen-dom0.diff @@ -0,0 +1,722 @@ +libelf: use for x86 dom0 builder. + +This patch switches the x86 dom0 builder over to libelf. + +Signed-off-by: Gerd Hoffmann +--- + xen/arch/ia64/xen/domain.c | 79 +++++------ + xen/arch/x86/domain_build.c | 305 +++++++++++++++----------------------------- + xen/common/Makefile | 4 + 3 files changed, 149 insertions(+), 239 deletions(-) + +Index: build-32-release304-13131/xen/common/Makefile +=================================================================== +--- build-32-release304-13131.orig/xen/common/Makefile ++++ build-32-release304-13131/xen/common/Makefile +@@ -2,8 +2,8 @@ obj-y += acm_ops.o + obj-y += bitmap.o + obj-y += domctl.o + obj-y += domain.o +-obj-y += elf.o +-obj-$(CONFIG_COMPAT) += elf32.o ++#obj-y += elf.o ++#obj-$(CONFIG_COMPAT) += elf32.o + obj-y += event_channel.o + obj-y += grant_table.o + obj-y += kernel.o +Index: build-32-release304-13131/xen/arch/x86/domain_build.c +=================================================================== +--- build-32-release304-13131.orig/xen/arch/x86/domain_build.c ++++ build-32-release304-13131/xen/arch/x86/domain_build.c +@@ -13,7 +13,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -29,7 +28,7 @@ + #include + + #include +-#include ++#include + + extern unsigned long initial_images_nrpages(void); + extern void discard_initial_images(void); +@@ -190,69 +189,12 @@ static void process_dom0_ioports_disable + } + } + +-static const char *feature_names[XENFEAT_NR_SUBMAPS*32] = { +- [XENFEAT_writable_page_tables] = "writable_page_tables", +- [XENFEAT_writable_descriptor_tables] = "writable_descriptor_tables", +- [XENFEAT_auto_translated_physmap] = "auto_translated_physmap", +- [XENFEAT_supervisor_mode_kernel] = "supervisor_mode_kernel", +- [XENFEAT_pae_pgdir_above_4gb] = "pae_pgdir_above_4gb" +-}; +- +-static void parse_features( +- const char *feats, +- uint32_t supported[XENFEAT_NR_SUBMAPS], +- uint32_t required[XENFEAT_NR_SUBMAPS]) +-{ +- const char *end, *p; +- int i, req; +- +- if ( (end = strchr(feats, ',')) == NULL ) +- end = feats + strlen(feats); +- +- while ( feats < end ) +- { +- p = strchr(feats, '|'); +- if ( (p == NULL) || (p > end) ) +- p = end; +- +- req = (*feats == '!'); +- if ( req ) +- feats++; +- +- for ( i = 0; i < XENFEAT_NR_SUBMAPS*32; i++ ) +- { +- if ( feature_names[i] == NULL ) +- continue; +- +- if ( strncmp(feature_names[i], feats, p-feats) == 0 ) +- { +- set_bit(i, supported); +- if ( req ) +- set_bit(i, required); +- break; +- } +- } +- +- if ( i == XENFEAT_NR_SUBMAPS*32 ) +- { +- printk("Unknown kernel feature \"%.*s\".\n", +- (int)(p-feats), feats); +- if ( req ) +- panic("Domain 0 requires an unknown hypervisor feature.\n"); +- } +- +- feats = p; +- if ( *feats == '|' ) +- feats++; +- } +-} +- + int construct_dom0(struct domain *d, + unsigned long _image_start, unsigned long image_len, + unsigned long _initrd_start, unsigned long initrd_len, + char *cmdline) + { +- int i, rc, dom0_pae, xen_pae, order; ++ int i, rc, compatible, compat32, order, machine; + struct cpu_user_regs *regs; + unsigned long pfn, mfn; + unsigned long nr_pages; +@@ -263,9 +205,7 @@ int construct_dom0(struct domain *d, + struct page_info *page = NULL; + start_info_t *si; + struct vcpu *v = d->vcpu[0]; +- const char *p; + unsigned long long value; +- int value_defined; + #if defined(__i386__) + char *image_start = (char *)_image_start; /* use lowmem mappings */ + char *initrd_start = (char *)_initrd_start; /* use lowmem mappings */ +@@ -287,7 +227,10 @@ int construct_dom0(struct domain *d, + * *_start address are page-aligned, except v_start (and v_end) which are + * superpage-aligned. + */ +- struct domain_setup_info dsi; ++ struct elf_binary elf; ++ struct elf_dom_parms parms; ++ unsigned long vkern_start; ++ unsigned long vkern_end; + unsigned long vinitrd_start; + unsigned long vinitrd_end; + unsigned long vphysmap_start; +@@ -298,6 +241,7 @@ int construct_dom0(struct domain *d, + unsigned long vstack_end; + unsigned long vpt_start; + unsigned long vpt_end; ++ unsigned long v_start; + unsigned long v_end; + + /* Machine address of next candidate page-table page. */ +@@ -312,21 +256,71 @@ int construct_dom0(struct domain *d, + BUG_ON(d->vcpu[0] == NULL); + BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags)); + +- memset(&dsi, 0, sizeof(struct domain_setup_info)); +- dsi.image_addr = (unsigned long)image_start; +- dsi.image_len = image_len; +- + printk("*** LOADING DOMAIN 0 ***\n"); + + d->max_pages = ~0U; + + nr_pages = compute_dom0_nr_pages(); + +- rc = parseelfimage(&dsi); ++ if (0 != (rc = elf_init(&elf, image_start, image_len))) ++ return rc; ++#ifdef VERBOSE ++ elf_set_verbose(&elf); ++#endif ++ elf_parse_binary(&elf); ++ if (0 != (elf_xen_parse(&elf, &parms))) ++ return rc; ++ ++ /* compatibility check */ ++ compatible = 0; ++ compat32 = 0; ++ machine = elf_uval(&elf, elf.ehdr, e_machine); ++ switch (CONFIG_PAGING_LEVELS) { ++ case 2: /* x86_32 */ ++ if (parms.pae == PAEKERN_bimodal) ++ parms.pae = PAEKERN_no; ++ printk(" Xen kernel: 32-bit, lsb\n"); ++ if (elf_32bit(&elf) && !parms.pae && machine == EM_386) ++ compatible = 1; ++ break; ++ case 3: /* x86_32p */ ++ if (parms.pae == PAEKERN_bimodal) ++ parms.pae = PAEKERN_extended_cr3; ++ printk(" Xen kernel: 32-bit, PAE, lsb\n"); ++ if (elf_32bit(&elf) && parms.pae && machine == EM_386) ++ compatible = 1; ++ break; ++ case 4: /* x86_64 */ ++#ifndef CONFIG_COMPAT ++ printk(" Xen kernel: 64-bit, lsb\n"); ++#else ++ printk(" Xen kernel: 64-bit, lsb, compat32\n"); ++ if (elf_32bit(&elf) && parms.pae == PAEKERN_bimodal) ++ parms.pae = PAEKERN_extended_cr3; ++ if (elf_32bit(&elf) && parms.pae && machine == EM_386) ++ { ++ compat32 = 1; ++ compatible = 1; ++ } ++#endif ++ if (elf_64bit(&elf) && machine == EM_X86_64) ++ compatible = 1; ++ break; ++ } ++ printk(" Dom0 kernel: %s%s, %s, paddr 0x%" PRIx64 " -> 0x%" PRIx64 "\n", ++ elf_64bit(&elf) ? "64-bit" : "32-bit", ++ parms.pae ? ", PAE" : "", ++ elf_msb(&elf) ? "msb" : "lsb", ++ elf.pstart, elf.pend); ++ ++ if ( !compatible ) ++ { ++ printk("Mismatch between Xen and DOM0 kernel\n"); ++ return -EINVAL; ++ } ++ + #ifdef CONFIG_COMPAT +- if ( rc == -ENOSYS +- && !compat_disabled +- && (rc = parseelf32image(&dsi)) == 0 ) ++ if (compat32) + { + l1_pgentry_t gdt_l1e; + +@@ -348,42 +342,10 @@ int construct_dom0(struct domain *d, + local_flush_tlb_one(GDT_LDT_VIRT_START + FIRST_RESERVED_GDT_BYTE); + } + #endif +- if ( rc != 0) +- { +- if ( rc == -ENOSYS ) +- printk("DOM0 image is not a Xen-compatible Elf image.\n"); +- return rc; +- } +- +- xen_pae = (CONFIG_PAGING_LEVELS == 3) || IS_COMPAT(d); +- if (dsi.pae_kernel == PAEKERN_bimodal) +- dom0_pae = xen_pae; +- else +- dom0_pae = (dsi.pae_kernel != PAEKERN_no); +- if ( dom0_pae != xen_pae ) +- { +- printk("PAE mode mismatch between Xen and DOM0 (xen=%s, dom0=%s)\n", +- xen_pae ? "yes" : "no", dom0_pae ? "yes" : "no"); +- return -EINVAL; +- } +- +- if ( xen_pae && (dsi.pae_kernel == PAEKERN_extended_cr3 || +- dsi.pae_kernel == PAEKERN_bimodal) ) ++ if ( parms.pae == PAEKERN_extended_cr3 ) + set_bit(VMASST_TYPE_pae_extended_cr3, &d->vm_assist); + +-#ifdef CONFIG_COMPAT +- if ( IS_COMPAT(d) ) +- { +- value = xen_elf32note_numeric(&dsi, XEN_ELFNOTE_HV_START_LOW, &value_defined); +- p = xen_elf32note_string(&dsi, XEN_ELFNOTE_FEATURES); +- } +- else +-#endif +- { +- value = xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HV_START_LOW, &value_defined); +- p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES); +- } +- if ( value_defined ) ++ if ( UNSET_ADDR != parms.virt_hv_start_low && elf_32bit(&elf) ) + { + #if CONFIG_PAGING_LEVELS < 4 + unsigned long mask = (1UL << L2_PAGETABLE_SHIFT) - 1; +@@ -393,7 +355,7 @@ int construct_dom0(struct domain *d, + : (1UL << L2_PAGETABLE_SHIFT) - 1; + #endif + +- value = (value + mask) & ~mask; ++ value = (parms.virt_hv_start_low + mask) & ~mask; + #ifdef CONFIG_COMPAT + HYPERVISOR_COMPAT_VIRT_START(d) = max_t(unsigned int, m2p_compat_vstart, value); + d->pa_bitsize = fls((1UL << 32) - HYPERVISOR_COMPAT_VIRT_START(d)) - 1 +@@ -406,21 +368,12 @@ int construct_dom0(struct domain *d, + #endif + panic("Domain 0 expects too high a hypervisor start address.\n"); + } +- if ( p != NULL ) +- { +- parse_features(p, +- dom0_features_supported, +- dom0_features_required); +- printk("Domain 0 kernel supports features = { %08x }.\n", +- dom0_features_supported[0]); +- printk("Domain 0 kernel requires features = { %08x }.\n", +- dom0_features_required[0]); +- if ( dom0_features_required[0] ) ++ ++ if ( parms.f_required[0] /* Huh? -- kraxel */ ) + panic("Domain 0 requires an unsupported hypervisor feature.\n"); +- } + + /* Align load address to 4MB boundary. */ +- dsi.v_start &= ~((1UL<<22)-1); ++ v_start = parms.virt_base & ~((1UL<<22)-1); + + /* + * Why do we need this? The number of page-table frames depends on the +@@ -429,7 +382,9 @@ int construct_dom0(struct domain *d, + * read-only). We have a pair of simultaneous equations in two unknowns, + * which we solve by exhaustive search. + */ +- vinitrd_start = round_pgup(dsi.v_end); ++ vkern_start = parms.virt_kstart; ++ vkern_end = parms.virt_kend; ++ vinitrd_start = round_pgup(vkern_end); + vinitrd_end = vinitrd_start + initrd_len; + vphysmap_start = round_pgup(vinitrd_end); + vphysmap_end = vphysmap_start + (nr_pages * (!IS_COMPAT(d) ? +@@ -449,12 +404,12 @@ int construct_dom0(struct domain *d, + if ( (v_end - vstack_end) < (512UL << 10) ) + v_end += 1UL << 22; /* Add extra 4MB to get >= 512kB padding. */ + #if defined(__i386__) && !defined(CONFIG_X86_PAE) +- if ( (((v_end - dsi.v_start + ((1UL<> ++ if ( (((v_end - v_start + ((1UL<> + L2_PAGETABLE_SHIFT) + 1) <= nr_pt_pages ) + break; + #elif defined(__i386__) && defined(CONFIG_X86_PAE) + /* 5 pages: 1x 3rd + 4x 2nd level */ +- if ( (((v_end - dsi.v_start + ((1UL<> ++ if ( (((v_end - v_start + ((1UL<> + L2_PAGETABLE_SHIFT) + 5) <= nr_pt_pages ) + break; + #elif defined(__x86_64__) +@@ -462,24 +417,24 @@ int construct_dom0(struct domain *d, + (((((_h) + ((1UL<<(_s))-1)) & ~((1UL<<(_s))-1)) - \ + ((_l) & ~((1UL<<(_s))-1))) >> (_s)) + if ( (1 + /* # L4 */ +- NR(dsi.v_start, v_end, L4_PAGETABLE_SHIFT) + /* # L3 */ ++ NR(v_start, v_end, L4_PAGETABLE_SHIFT) + /* # L3 */ + (!IS_COMPAT(d) ? +- NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT) : /* # L2 */ ++ NR(v_start, v_end, L3_PAGETABLE_SHIFT) : /* # L2 */ + 4) + /* # compat L2 */ +- NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT)) /* # L1 */ ++ NR(v_start, v_end, L2_PAGETABLE_SHIFT)) /* # L1 */ + <= nr_pt_pages ) + break; + #endif + } + +- order = get_order_from_bytes(v_end - dsi.v_start); ++ order = get_order_from_bytes(v_end - v_start); + if ( (1UL << order) > nr_pages ) + panic("Domain 0 allocation is too small for kernel image.\n"); + + #ifdef __i386__ + /* Ensure that our low-memory 1:1 mapping covers the allocation. */ + page = alloc_domheap_pages(d, order, +- MEMF_bits(30 + (dsi.v_start >> 31))); ++ MEMF_bits(30 + (v_start >> 31))); + #else + page = alloc_domheap_pages(d, order, 0); + #endif +@@ -502,24 +457,24 @@ int construct_dom0(struct domain *d, + " Page tables: %p->%p\n" + " Boot stack: %p->%p\n" + " TOTAL: %p->%p\n", +- _p(dsi.v_kernstart), _p(dsi.v_kernend), ++ _p(vkern_start), _p(vkern_end), + _p(vinitrd_start), _p(vinitrd_end), + _p(vphysmap_start), _p(vphysmap_end), + _p(vstartinfo_start), _p(vstartinfo_end), + _p(vpt_start), _p(vpt_end), + _p(vstack_start), _p(vstack_end), +- _p(dsi.v_start), _p(v_end)); +- printk(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry)); ++ _p(v_start), _p(v_end)); ++ printk(" ENTRY ADDRESS: %p\n", _p(parms.virt_entry)); + +- if ( ((v_end - dsi.v_start)>>PAGE_SHIFT) > nr_pages ) ++ if ( ((v_end - v_start)>>PAGE_SHIFT) > nr_pages ) + { + printk("Initial guest OS requires too much space\n" + "(%luMB is greater than %luMB limit)\n", +- (v_end-dsi.v_start)>>20, nr_pages>>(20-PAGE_SHIFT)); ++ (v_end-v_start)>>20, nr_pages>>(20-PAGE_SHIFT)); + return -ENOMEM; + } + +- mpt_alloc = (vpt_start - dsi.v_start) + ++ mpt_alloc = (vpt_start - v_start) + + (unsigned long)pfn_to_paddr(alloc_spfn); + + #if defined(__i386__) +@@ -527,7 +482,7 @@ int construct_dom0(struct domain *d, + * Protect the lowest 1GB of memory. We use a temporary mapping there + * from which we copy the kernel and ramdisk images. + */ +- if ( dsi.v_start < (1UL<<30) ) ++ if ( v_start < (1UL<<30) ) + { + printk("Initial loading isn't allowed to lowest 1GB of memory.\n"); + return -EINVAL; +@@ -557,9 +512,9 @@ int construct_dom0(struct domain *d, + l2e_from_page(virt_to_page(d->arch.mm_perdomain_pt) + i, + __PAGE_HYPERVISOR); + +- l2tab += l2_linear_offset(dsi.v_start); ++ l2tab += l2_linear_offset(v_start); + mfn = alloc_spfn; +- for ( count = 0; count < ((v_end-dsi.v_start)>>PAGE_SHIFT); count++ ) ++ for ( count = 0; count < ((v_end-v_start)>>PAGE_SHIFT); count++ ) + { + if ( !((unsigned long)l1tab & (PAGE_SIZE-1)) ) + { +@@ -569,7 +524,7 @@ int construct_dom0(struct domain *d, + l2tab++; + clear_page(l1tab); + if ( count == 0 ) +- l1tab += l1_table_offset(dsi.v_start); ++ l1tab += l1_table_offset(v_start); + } + *l1tab = l1e_from_pfn(mfn, L1_PROT); + l1tab++; +@@ -659,7 +614,7 @@ int construct_dom0(struct domain *d, + + /* Overlap with Xen protected area? */ + if ( !IS_COMPAT(d) ? +- ((dsi.v_start < HYPERVISOR_VIRT_END) && ++ ((v_start < HYPERVISOR_VIRT_END) && + (v_end > HYPERVISOR_VIRT_START)) : + (v_end > HYPERVISOR_COMPAT_VIRT_START(d)) ) + { +@@ -699,9 +654,9 @@ int construct_dom0(struct domain *d, + panic("Not enough RAM for domain 0 hypercall argument translation.\n"); + } + +- l4tab += l4_table_offset(dsi.v_start); ++ l4tab += l4_table_offset(v_start); + mfn = alloc_spfn; +- for ( count = 0; count < ((v_end-dsi.v_start)>>PAGE_SHIFT); count++ ) ++ for ( count = 0; count < ((v_end-v_start)>>PAGE_SHIFT); count++ ) + { + if ( !((unsigned long)l1tab & (PAGE_SIZE-1)) ) + { +@@ -709,14 +664,14 @@ int construct_dom0(struct domain *d, + l1start = l1tab = __va(mpt_alloc); mpt_alloc += PAGE_SIZE; + clear_page(l1tab); + if ( count == 0 ) +- l1tab += l1_table_offset(dsi.v_start); ++ l1tab += l1_table_offset(v_start); + if ( !((unsigned long)l2tab & (PAGE_SIZE-1)) ) + { + maddr_to_page(mpt_alloc)->u.inuse.type_info = PGT_l2_page_table; + l2start = l2tab = __va(mpt_alloc); mpt_alloc += PAGE_SIZE; + clear_page(l2tab); + if ( count == 0 ) +- l2tab += l2_table_offset(dsi.v_start); ++ l2tab += l2_table_offset(v_start); + if ( !((unsigned long)l3tab & (PAGE_SIZE-1)) ) + { + maddr_to_page(mpt_alloc)->u.inuse.type_info = +@@ -724,7 +679,7 @@ int construct_dom0(struct domain *d, + l3start = l3tab = __va(mpt_alloc); mpt_alloc += PAGE_SIZE; + clear_page(l3tab); + if ( count == 0 ) +- l3tab += l3_table_offset(dsi.v_start); ++ l3tab += l3_table_offset(v_start); + *l4tab = l4e_from_paddr(__pa(l3start), L4_PROT); + l4tab++; + } +@@ -837,30 +792,20 @@ int construct_dom0(struct domain *d, + write_ptbase(v); + + /* Copy the OS image and free temporary buffer. */ +-#ifdef CONFIG_COMPAT +- if ( IS_COMPAT(d) ) +- { +- (void)loadelf32image(&dsi); +- value = +- xen_elf32note_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &value_defined); +- } +- else +-#endif +- { +- (void)loadelfimage(&dsi); +- value = +- xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &value_defined); +- } +- if ( value_defined ) ++ elf.dest = (void*)vkern_start; ++ elf_load_binary(&elf); ++ ++ if ( UNSET_ADDR != parms.virt_hypercall ) + { +- if ( (value < dsi.v_start) || (value >= v_end) ) ++ if ( (parms.virt_hypercall < v_start) || ++ (parms.virt_hypercall >= v_end) ) + { + write_ptbase(current); + local_irq_enable(); + printk("Invalid HYPERCALL_PAGE field in ELF notes.\n"); + return -1; + } +- hypercall_page_initialise(d, (void *)(unsigned long)value); ++ hypercall_page_initialise(d, (void *)(unsigned long)parms.virt_hypercall); + } + + /* Copy the initial ramdisk. */ +@@ -883,14 +828,15 @@ int construct_dom0(struct domain *d, + si->mfn_list = vphysmap_start; + sprintf(si->magic, "xen-%i.%i-x86_%d%s", + xen_major_version(), xen_minor_version(), +- !IS_COMPAT(d) ? BITS_PER_LONG : 32, xen_pae ? "p" : ""); ++ elf_64bit(&elf) ? 64 : 32, ++ parms.pae ? "p" : ""); + + /* Write the phys->machine and machine->phys table entries. */ + for ( pfn = 0; pfn < d->tot_pages; pfn++ ) + { + mfn = pfn + alloc_spfn; + #ifndef NDEBUG +-#define REVERSE_START ((v_end - dsi.v_start) >> PAGE_SHIFT) ++#define REVERSE_START ((v_end - v_start) >> PAGE_SHIFT) + if ( pfn > REVERSE_START ) + mfn = alloc_epfn - (pfn - REVERSE_START); + #endif +@@ -971,7 +917,7 @@ int construct_dom0(struct domain *d, + : FLAT_COMPAT_KERNEL_DS; + regs->ss = !IS_COMPAT(d) ? FLAT_KERNEL_SS : FLAT_COMPAT_KERNEL_SS; + regs->cs = !IS_COMPAT(d) ? FLAT_KERNEL_CS : FLAT_COMPAT_KERNEL_CS; +- regs->eip = dsi.v_kernentry; ++ regs->eip = parms.virt_entry; + regs->esp = vstack_end; + regs->esi = vstartinfo_start; + regs->eflags = X86_EFLAGS_IF; +@@ -1042,41 +988,6 @@ int construct_dom0(struct domain *d, + return 0; + } + +-int elf_sanity_check(const Elf_Ehdr *ehdr) +-{ +- if ( !IS_ELF(*ehdr) || +-#if defined(__i386__) +- (ehdr->e_ident[EI_CLASS] != ELFCLASS32) || +- (ehdr->e_machine != EM_386) || +-#elif defined(__x86_64__) +- (ehdr->e_ident[EI_CLASS] != ELFCLASS64) || +- (ehdr->e_machine != EM_X86_64) || +-#endif +- (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) || +- (ehdr->e_type != ET_EXEC) ) +- { +- return 0; +- } +- +- return 1; +-} +- +-#ifdef CONFIG_COMPAT +-int elf32_sanity_check(const Elf32_Ehdr *ehdr) +-{ +- if ( !IS_ELF(*ehdr) || +- (ehdr->e_ident[EI_CLASS] != ELFCLASS32) || +- (ehdr->e_machine != EM_386) || +- (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) || +- (ehdr->e_type != ET_EXEC) ) +- { +- return 0; +- } +- +- return 1; +-} +-#endif +- + /* + * Local variables: + * mode: C +Index: build-32-release304-13131/xen/arch/ia64/xen/domain.c +=================================================================== +--- build-32-release304-13131.orig/xen/arch/ia64/xen/domain.c ++++ build-32-release304-13131/xen/arch/ia64/xen/domain.c +@@ -31,7 +31,7 @@ + #include + #include + #include +-#include ++#include + #include + #include /* for IA64_THREAD_INFO_SIZE */ + #include /* for function declarations */ +@@ -866,38 +866,23 @@ int shadow_mode_control(struct domain *d + #define privify_memory(x,y) do {} while(0) + #endif + +-// see arch/x86/xxx/domain_build.c +-int elf_sanity_check(Elf_Ehdr *ehdr) +-{ +- if (!(IS_ELF(*ehdr))) +- { +- printk("DOM0 image is not a Xen-compatible Elf image.\n"); +- return 0; +- } +- return 1; +-} +- +-static void loaddomainelfimage(struct domain *d, unsigned long image_start) ++static void loaddomainelfimage(struct domain *d, struct elf_binary *elf) + { +- char *elfbase = (char *) image_start; +- Elf_Ehdr ehdr; +- Elf_Phdr phdr; +- int h, filesz, memsz; ++ const elf_phdr *phdr; ++ int h, phnum, filesz, memsz; + unsigned long elfaddr, dom_mpaddr, dom_imva; + struct page_info *p; +- +- memcpy(&ehdr, (void *) image_start, sizeof(Elf_Ehdr)); +- for ( h = 0; h < ehdr.e_phnum; h++ ) { +- memcpy(&phdr, +- elfbase + ehdr.e_phoff + (h*ehdr.e_phentsize), +- sizeof(Elf_Phdr)); +- if ((phdr.p_type != PT_LOAD)) ++ ++ phnum = elf_uval(elf, elf->ehdr, e_phnum); ++ for ( h = 0; h < phnum; h++ ) { ++ phdr = elf_phdr_by_index(elf, h); ++ if (!elf_phdr_is_loadable(elf, phdr)) + continue; + +- filesz = phdr.p_filesz; +- memsz = phdr.p_memsz; +- elfaddr = (unsigned long) elfbase + phdr.p_offset; +- dom_mpaddr = phdr.p_paddr; ++ filesz = elf_uval(elf, phdr, p_filesz); ++ memsz = elf_uval(elf, phdr, p_memsz); ++ elfaddr = (unsigned long) elf->image + elf_uval(elf, phdr, p_offset); ++ dom_mpaddr = elf_uval(elf, phdr, p_paddr); + + while (memsz > 0) { + p = assign_new_domain_page(d,dom_mpaddr); +@@ -917,7 +902,7 @@ static void loaddomainelfimage(struct do + PAGE_SIZE-filesz); + } + //FIXME: This test for code seems to find a lot more than objdump -x does +- if (phdr.p_flags & PF_X) { ++ if (elf_uval(elf, phdr, p_flags) & PF_X) { + privify_memory(dom_imva,PAGE_SIZE); + flush_icache_range(dom_imva, + dom_imva+PAGE_SIZE); +@@ -980,7 +965,8 @@ int construct_dom0(struct domain *d, + struct vcpu *v = d->vcpu[0]; + unsigned long max_pages; + +- struct domain_setup_info dsi; ++ struct elf_binary elf; ++ struct elf_dom_parms parms; + unsigned long p_start; + unsigned long pkern_start; + unsigned long pkern_entry; +@@ -1004,18 +990,31 @@ int construct_dom0(struct domain *d, + BUG_ON(d->vcpu[0] == NULL); + BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags)); + +- memset(&dsi, 0, sizeof(struct domain_setup_info)); +- + printk("*** LOADING DOMAIN 0 ***\n"); + + max_pages = dom0_size / PAGE_SIZE; + d->max_pages = max_pages; + d->tot_pages = 0; +- dsi.image_addr = (unsigned long)image_start; +- dsi.image_len = image_len; +- rc = parseelfimage(&dsi); ++ ++ rc = elf_init(&elf, (void*)image_start, image_len); + if ( rc != 0 ) + return rc; ++#ifdef VERBOSE ++ elf_set_verbose(&elf); ++#endif ++ elf_parse_binary(&elf); ++ if (0 != (elf_xen_parse(&elf, &parms))) ++ return rc; ++ ++ printk(" Dom0 kernel: %s, %s, paddr 0x%" PRIx64 " -> 0x%" PRIx64 "\n", ++ elf_64bit(&elf) ? "64-bit" : "32-bit", ++ elf_msb(&elf) ? "msb" : "lsb", ++ elf.pstart, elf.pend); ++ if (!elf_64bit(&elf) || ++ elf_uval(&elf, elf.ehdr, e_machine) != EM_IA_64) { ++ printk("Incompatible kernel binary\n"); ++ return -1; ++ } + + #ifdef VALIDATE_VT + /* Temp workaround */ +@@ -1034,10 +1033,10 @@ int construct_dom0(struct domain *d, + } + #endif + +- p_start = dsi.v_start; +- pkern_start = dsi.v_kernstart; +- pkern_end = dsi.v_kernend; +- pkern_entry = dsi.v_kernentry; ++ p_start = parms.virt_base; ++ pkern_start = parms.virt_kstart; ++ pkern_end = parms.virt_kend; ++ pkern_entry = parms.virt_entry; + + //printk("p_start=%lx, pkern_start=%lx, pkern_end=%lx, pkern_entry=%lx\n",p_start,pkern_start,pkern_end,pkern_entry); + +@@ -1107,7 +1106,7 @@ int construct_dom0(struct domain *d, + printk ("Cannot allocate dom0 vcpu %d\n", i); + + /* Copy the OS image. */ +- loaddomainelfimage(d,image_start); ++ loaddomainelfimage(d,&elf); + + /* Copy the initial ramdisk. */ + //if ( initrd_len != 0 ) diff --git a/libxc-logging.diff b/libxc-logging.diff new file mode 100644 index 0000000..cb79485 --- /dev/null +++ b/libxc-logging.diff @@ -0,0 +1,111 @@ +debug: log libxc output to /var/log/xen/libxc.log + +sledge hammer patch ;) +--- + tools/libxc/xc_dom_compat_linux.c | 2 ++ + tools/libxc/xc_hvm_build.c | 2 ++ + tools/libxc/xc_linux_build.c | 2 ++ + tools/libxc/xc_private.c | 9 +++++++++ + tools/libxc/xc_private.h | 11 +++++++---- + 5 files changed, 22 insertions(+), 4 deletions(-) + +Index: build-64-release304-13087/tools/libxc/xc_hvm_build.c +=================================================================== +--- build-64-release304-13087.orig/tools/libxc/xc_hvm_build.c ++++ build-64-release304-13087/tools/libxc/xc_hvm_build.c +@@ -310,6 +310,8 @@ static int xc_hvm_build_internal(int xc_ + vcpu_guest_context_t ctxt; + int rc; + ++ log_kraxel(); ++ + if ( (image == NULL) || (image_size == 0) ) + { + ERROR("Image required"); +Index: build-64-release304-13087/tools/libxc/xc_linux_build.c +=================================================================== +--- build-64-release304-13087.orig/tools/libxc/xc_linux_build.c ++++ build-64-release304-13087/tools/libxc/xc_linux_build.c +@@ -1099,6 +1099,8 @@ static int xc_linux_build_internal(int x + unsigned long vstartinfo_start, vkern_entry, vstack_start; + uint32_t features_bitmap[XENFEAT_NR_SUBMAPS] = { 0, }; + ++ log_kraxel(); ++ + if ( features != NULL ) + { + if ( !parse_features(features, features_bitmap, NULL) ) +Index: build-64-release304-13087/tools/libxc/xc_private.c +=================================================================== +--- build-64-release304-13087.orig/tools/libxc/xc_private.c ++++ build-64-release304-13087/tools/libxc/xc_private.c +@@ -88,6 +88,15 @@ void xc_set_error(int code, const char * + error_handler(&last_error); + } + ++FILE *kraxel; ++ ++void log_kraxel(void) ++{ ++ kraxel = fopen("/var/log/xen/libxc.log", "a"); ++ setvbuf(kraxel, NULL, _IONBF, 0); ++ fprintf(kraxel, "--- started ---\n"); ++} ++ + int lock_pages(void *addr, size_t len) + { + int e = 0; +Index: build-64-release304-13087/tools/libxc/xc_private.h +=================================================================== +--- build-64-release304-13087.orig/tools/libxc/xc_private.h ++++ build-64-release304-13087/tools/libxc/xc_private.h +@@ -39,22 +39,25 @@ + + #define DEBUG 1 + #define INFO 1 +-#define PROGRESS 0 ++#define PROGRESS 1 ++ ++extern FILE *kraxel; ++void log_kraxel(void); + + #if INFO +-#define IPRINTF(_f, _a...) printf(_f , ## _a) ++#define IPRINTF(_f, _a...) fprintf(kraxel, _f , ## _a) + #else + #define IPRINTF(_f, _a...) ((void)0) + #endif + + #if DEBUG +-#define DPRINTF(_f, _a...) fprintf(stderr, _f , ## _a) ++#define DPRINTF(_f, _a...) fprintf(kraxel, _f , ## _a) + #else + #define DPRINTF(_f, _a...) ((void)0) + #endif + + #if PROGRESS +-#define PPRINTF(_f, _a...) fprintf(stderr, _f , ## _a) ++#define PPRINTF(_f, _a...) fprintf(kraxel, _f , ## _a) + #else + #define PPRINTF(_f, _a...) + #endif +Index: build-64-release304-13087/tools/libxc/xc_dom_compat_linux.c +=================================================================== +--- build-64-release304-13087.orig/tools/libxc/xc_dom_compat_linux.c ++++ build-64-release304-13087/tools/libxc/xc_dom_compat_linux.c +@@ -74,6 +74,7 @@ int xc_linux_build_mem(int xc_handle, ui + int rc; + + xc_dom_loginit(); ++ log_kraxel(); + dom = xc_dom_allocate(cmdline, features); + if (0 != (rc = xc_dom_kernel_mem(dom, image_buffer, image_size))) + goto out; +@@ -106,6 +107,7 @@ int xc_linux_build(int xc_handle, uint32 + int rc; + + xc_dom_loginit(); ++ log_kraxel(); + dom = xc_dom_allocate(cmdline, features); + if (0 != (rc = xc_dom_kernel_file(dom, image_name))) + goto out; diff --git a/mem-zones.patch b/mem-zones.patch new file mode 100644 index 0000000..69b39cc --- /dev/null +++ b/mem-zones.patch @@ -0,0 +1,244 @@ +Index: xen-3.0.4-testing/xen/common/page_alloc.c +=================================================================== +--- xen-3.0.4-testing.orig/xen/common/page_alloc.c ++++ xen-3.0.4-testing/xen/common/page_alloc.c +@@ -67,16 +67,18 @@ unsigned long max_dma_mfn = (1UL << (CON + static void parse_dma_bits(char *s) + { + unsigned int v = simple_strtol(s, NULL, 0); +- if ( v >= (sizeof(long)*8 + PAGE_SHIFT) ) ++ if ( v >= (BITS_PER_LONG + PAGE_SHIFT) ) + { +- dma_bitsize = sizeof(long)*8 + PAGE_SHIFT; ++ dma_bitsize = BITS_PER_LONG + PAGE_SHIFT; + max_dma_mfn = ~0UL; + } +- else ++ else if ( v > PAGE_SHIFT ) + { + dma_bitsize = v; + max_dma_mfn = (1UL << (dma_bitsize - PAGE_SHIFT)) - 1; + } ++ else ++ printk("Invalid dma_bits value of %u ignored.\n", v); + } + custom_param("dma_bits", parse_dma_bits); + +@@ -293,12 +295,13 @@ unsigned long alloc_boot_pages(unsigned + */ + + #define MEMZONE_XEN 0 +-#define MEMZONE_DOM 1 +-#define MEMZONE_DMADOM 2 +-#define NR_ZONES 3 ++#ifdef PADDR_BITS ++#define NR_ZONES (PADDR_BITS - PAGE_SHIFT) ++#else ++#define NR_ZONES (BITS_PER_LONG - PAGE_SHIFT) ++#endif + +-#define pfn_dom_zone_type(_pfn) \ +- (((_pfn) <= max_dma_mfn) ? MEMZONE_DMADOM : MEMZONE_DOM) ++#define pfn_dom_zone_type(_pfn) (fls(_pfn) - 1) + + static struct list_head heap[NR_ZONES][MAX_NUMNODES][MAX_ORDER+1]; + +@@ -308,15 +311,17 @@ static DEFINE_SPINLOCK(heap_lock); + + /* Allocate 2^@order contiguous pages. */ + static struct page_info *alloc_heap_pages( +- unsigned int zone, unsigned int cpu, unsigned int order) ++ unsigned int zone_lo, unsigned zone_hi, ++ unsigned int cpu, unsigned int order) + { + unsigned int i, j, node = cpu_to_node(cpu), num_nodes = num_online_nodes(); +- unsigned int request = (1UL << order); ++ unsigned int zone, request = (1UL << order); + struct page_info *pg; + + ASSERT(node >= 0); + ASSERT(node < num_nodes); +- ASSERT(zone < NR_ZONES); ++ ASSERT(zone_lo <= zone_hi); ++ ASSERT(zone_hi < NR_ZONES); + + if ( unlikely(order > MAX_ORDER) ) + return NULL; +@@ -329,14 +334,17 @@ static struct page_info *alloc_heap_page + * needless computation on fast-path */ + for ( i = 0; i < num_nodes; i++ ) + { +- /* check if target node can support the allocation */ +- if ( avail[zone][node] >= request ) ++ for ( zone = zone_hi; zone >= zone_lo; --zone ) + { +- /* Find smallest order which can satisfy the request. */ +- for ( j = order; j <= MAX_ORDER; j++ ) ++ /* check if target node can support the allocation */ ++ if ( avail[zone][node] >= request ) + { +- if ( !list_empty(&heap[zone][node][j]) ) +- goto found; ++ /* Find smallest order which can satisfy the request. */ ++ for ( j = order; j <= MAX_ORDER; j++ ) ++ { ++ if ( !list_empty(&heap[zone][node][j]) ) ++ goto found; ++ } + } + } + /* pick next node, wrapping around if needed */ +@@ -461,16 +469,17 @@ void init_heap_pages( + } + + static unsigned long avail_heap_pages( +- int zone, int node) ++ unsigned int zone_lo, unsigned int zone_hi, unsigned int node) + { +- unsigned int i, j, num_nodes = num_online_nodes(); ++ unsigned int i, zone, num_nodes = num_online_nodes(); + unsigned long free_pages = 0; + +- for (i=0; i= NR_ZONES ) ++ zone_hi = NR_ZONES - 1; ++ for ( zone = zone_lo; zone <= zone_hi; zone++ ) ++ for ( i = 0; i < num_nodes; i++ ) ++ if ( (node == -1) || (node == i) ) ++ free_pages += avail[zone][i]; + + return free_pages; + } +@@ -590,7 +599,7 @@ void *alloc_xenheap_pages(unsigned int o + int i; + + local_irq_save(flags); +- pg = alloc_heap_pages(MEMZONE_XEN, smp_processor_id(), order); ++ pg = alloc_heap_pages(MEMZONE_XEN, MEMZONE_XEN, smp_processor_id(), order); + local_irq_restore(flags); + + if ( unlikely(pg == NULL) ) +@@ -635,22 +644,26 @@ void free_xenheap_pages(void *v, unsigne + + void init_domheap_pages(paddr_t ps, paddr_t pe) + { +- unsigned long s_tot, e_tot, s_dma, e_dma, s_nrm, e_nrm; ++ unsigned long s_tot, e_tot; ++ unsigned int zone; + + ASSERT(!in_irq()); + + s_tot = round_pgup(ps) >> PAGE_SHIFT; + e_tot = round_pgdown(pe) >> PAGE_SHIFT; + +- s_dma = min(s_tot, max_dma_mfn + 1); +- e_dma = min(e_tot, max_dma_mfn + 1); +- if ( s_dma < e_dma ) +- init_heap_pages(MEMZONE_DMADOM, mfn_to_page(s_dma), e_dma - s_dma); +- +- s_nrm = max(s_tot, max_dma_mfn + 1); +- e_nrm = max(e_tot, max_dma_mfn + 1); +- if ( s_nrm < e_nrm ) +- init_heap_pages(MEMZONE_DOM, mfn_to_page(s_nrm), e_nrm - s_nrm); ++ zone = fls(s_tot); ++ BUG_ON(zone <= MEMZONE_XEN + 1); ++ for ( --zone; s_tot < e_tot; ++zone ) ++ { ++ unsigned long end = e_tot; ++ ++ BUILD_BUG_ON(NR_ZONES > BITS_PER_LONG); ++ if ( zone < BITS_PER_LONG - 1 && end > 1UL << (zone + 1) ) ++ end = 1UL << (zone + 1); ++ init_heap_pages(zone, mfn_to_page(s_tot), end - s_tot); ++ s_tot = end; ++ } + } + + +@@ -717,17 +730,21 @@ struct page_info *__alloc_domheap_pages( + + if ( !(memflags & MEMF_dma) ) + { +- pg = alloc_heap_pages(MEMZONE_DOM, cpu, order); ++ pg = alloc_heap_pages(dma_bitsize - PAGE_SHIFT, NR_ZONES - 1, cpu, order); + /* Failure? Then check if we can fall back to the DMA pool. */ + if ( unlikely(pg == NULL) && + ((order > MAX_ORDER) || +- (avail_heap_pages(MEMZONE_DMADOM,-1) < ++ (avail_heap_pages(MEMZONE_XEN + 1, ++ dma_bitsize - PAGE_SHIFT - 1, ++ -1) < + (dma_emergency_pool_pages + (1UL << order)))) ) + return NULL; + } + + if ( pg == NULL ) +- if ( (pg = alloc_heap_pages(MEMZONE_DMADOM, cpu, order)) == NULL ) ++ if ( (pg = alloc_heap_pages(MEMZONE_XEN + 1, ++ dma_bitsize - PAGE_SHIFT - 1, ++ cpu, order)) == NULL ) + return NULL; + + mask = pg->u.free.cpumask; +@@ -849,9 +866,14 @@ unsigned long avail_domheap_pages(void) + { + unsigned long avail_nrm, avail_dma; + +- avail_nrm = avail_heap_pages(MEMZONE_DOM,-1); ++ avail_nrm = avail_heap_pages(dma_bitsize - PAGE_SHIFT, ++ NR_ZONES - 1, ++ -1); ++ ++ avail_dma = avail_heap_pages(MEMZONE_XEN + 1, ++ dma_bitsize - PAGE_SHIFT - 1, ++ -1); + +- avail_dma = avail_heap_pages(MEMZONE_DMADOM,-1); + if ( avail_dma > dma_emergency_pool_pages ) + avail_dma -= dma_emergency_pool_pages; + else +@@ -862,18 +884,33 @@ unsigned long avail_domheap_pages(void) + + unsigned long avail_nodeheap_pages(int node) + { +- return avail_heap_pages(-1, node); ++ return avail_heap_pages(0, NR_ZONES - 1, node); + } + + static void pagealloc_keyhandler(unsigned char key) + { ++ unsigned int zone = MEMZONE_XEN; ++ unsigned long total = 0; ++ + printk("Physical memory information:\n"); +- printk(" Xen heap: %lukB free\n" +- " DMA heap: %lukB free\n" +- " Dom heap: %lukB free\n", +- avail_heap_pages(MEMZONE_XEN, -1) << (PAGE_SHIFT-10), +- avail_heap_pages(MEMZONE_DMADOM, -1) <<(PAGE_SHIFT-10), +- avail_heap_pages(MEMZONE_DOM, -1) <<(PAGE_SHIFT-10)); ++ printk(" Xen heap: %lukB free\n", ++ avail_heap_pages(zone, zone, -1) << (PAGE_SHIFT-10)); ++ ++ while ( ++zone < NR_ZONES ) ++ { ++ unsigned long n; ++ ++ if ( zone == dma_bitsize - PAGE_SHIFT ) ++ { ++ printk(" DMA heap: %lukB free\n", total << (PAGE_SHIFT-10)); ++ total = 0; ++ } ++ n = avail_heap_pages(zone, zone, -1); ++ total += n; ++ if ( n ) ++ printk(" heap[%02u]: %lukB free\n", zone, n << (PAGE_SHIFT-10)); ++ } ++ printk(" Dom heap: %lukB free\n", total << (PAGE_SHIFT-10)); + } + + diff --git a/microcode-xen-13079.diff b/microcode-xen-13079.diff new file mode 100644 index 0000000..dabc285 --- /dev/null +++ b/microcode-xen-13079.diff @@ -0,0 +1,61 @@ +# HG changeset patch +# User Kurt Garloff +# Node ID b1752c878a7845d812c9b15e721f401d786394b2 +# Parent 469478194aef6e987f9281efbc0756749be6eb80 +Microcode does not need to have the default size of 2000+48 bytes. +A corresponding patch has gone into Linux 2.6.19; this is the +port to Xen. + +Signed-off-by: Kurt Garloff + +Reference: Patch to linux kernel from Sep 27 2006 +> # User Shaohua Li +> # Node ID 45898b908138b5d93c2cc7353f061ce54af145dc +> # Parent f962eab7b82c9bf1a6da69571046e764f5128395 +> [PATCH] x86 microcode: don't check the size +> +> IA32 manual says if micorcode update's size is 0, then the size is +> default size (2048 bytes). But this doesn't suggest all microcode +> update's size should be above 2048 bytes to me. We actually had a +> microcode update whose size is 1024 bytes. The patch just removed the +> check. +> +> Signed-off-by: Shaohua Li +> Cc: Tigran Aivazian +> Signed-off-by: Andrew Morton +> Signed-off-by: Linus Torvalds +> +> committer: Linus Torvalds 1159370778 -0700 + +diff -r 469478194aef -r b1752c878a78 xen/arch/x86/microcode.c +--- a/xen/arch/x86/microcode.c Mon Dec 18 00:14:40 2006 +0000 ++++ b/xen/arch/x86/microcode.c Sun Dec 24 17:06:23 2006 +0100 +@@ -249,14 +249,14 @@ static int find_matching_ucodes (void) + } + + total_size = get_totalsize(&mc_header); +- if ((cursor + total_size > user_buffer_size) || (total_size < DEFAULT_UCODE_TOTALSIZE)) { ++ if (cursor + total_size > user_buffer_size) { + printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); + error = -EINVAL; + goto out; + } + + data_size = get_datasize(&mc_header); +- if ((data_size + MC_HEADER_SIZE > total_size) || (data_size < DEFAULT_UCODE_DATASIZE)) { ++ if (data_size + MC_HEADER_SIZE > total_size) { + printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); + error = -EINVAL; + goto out; +@@ -459,11 +459,6 @@ int microcode_update(XEN_GUEST_HANDLE(vo + { + int ret; + +- if (len < DEFAULT_UCODE_TOTALSIZE) { +- printk(KERN_ERR "microcode: not enough data\n"); +- return -EINVAL; +- } +- + if (len != (typeof(user_buffer_size))len) { + printk(KERN_ERR "microcode: too much data\n"); + return -E2BIG; diff --git a/mk-xen-rescue-img.sh b/mk-xen-rescue-img.sh deleted file mode 100644 index e7e6210..0000000 --- a/mk-xen-rescue-img.sh +++ /dev/null @@ -1,278 +0,0 @@ -#!/bin/bash -# Shell script to prepare a root FS image based on the Novell/SUSE rescue -# image source. You must have a xen kernel installed for this to work. -# (c) Kurt Garloff , 2005-01-24, GNU GPL -# Maintained by Charles Coffing -# -# TODO: -# - trap SIGINT and clean up -# - can't know that /sbin/depmod will work with this rescue image -# - support domUloader -# - check for disk full in exchange_kernel_modules - -MB_DEFAULT=88 - -usage() -{ - echo "Usage:" - echo " mk-xen-rescue-img.sh source destination [MB [kernelver]]" - echo "Purpose:" - echo " Creates a root filesystem and an associated config file for a Xen-compatible" - echo " Linux virtual machine." - echo "Arguments:" - echo " * 'source' is the source from which to copy files. Normally, this is" - echo " the SUSE rescue image, such as /media/cdrom/boot/x86_64/rescue," - echo " but it could also be an already-mounted root filesystem." - echo " * 'destination' is the pathname of a disk image to be created, based on" - echo " 'source'." - echo " * 'MB' is the size of disk image (default $MB_DEFAULT)." - echo " * 'kernelver' is the version of an installed Xen-compatible Linux kernel" - echo " (from the kernel-xen package) to install in the disk image. If not" - echo " specified, the newest of those currently installed will be selected." - exit 2 -} - -usage_error() -{ - echo "Error: $@" - echo "" - usage -} - -error() -{ - echo "Error: $@" - if [ ! -z "$DST_MNT" ]; then - umount "$DST_MNT" - rmdir "$DST_MNT" - fi - exit 1 -} - -cp_error() -{ - error "Failed to copy files to '$DST'." -} - -# Determine Xen kernel version -get_xen_kernel() -{ - if [ -z "$KVER" ]; then - KVER="`cd /lib/modules && ls -td *-xen/kernel | head -n1 | sed 's@/kernel@@'`" - else - if [ ! -d /lib/modules/$KVER/kernel ]; then - error "/lib/modules/$KVER/kernel does not exist." - fi - fi - if [ -z "$KVER" ]; then - error "You need to have a 'kernel-xen' package installed." - fi -} - -cp_rescue() -{ - local LSRC=$1 - local LDST=$2 - - # The rescue image has empty directories all hard-linked to the same - # thing, probably to conserve inodes. This gives 'cp' heartburn. - # I want hard linked directories to be created separately (i.e., - # dereferenced), but I don't want to dereference soft links. - # 'tar' handles this nicely. - - (cd "$LSRC" && tar --atime-preserve --one-file-system -cf - *) | \ - (cd "$LDST" && tar -xmf -) -} - -# Create FS and copy rescue FS -create_basis_and_mount() -{ - echo "Creating disk image within '$DST'..." - dd if=/dev/zero of="$DST" bs=4096 count=1 2>/dev/null >/dev/null 2>&1 - dd if=/dev/zero of="$DST" bs=1048576 count=0 seek=$MB >/dev/null 2>&1 - /sbin/mke2fs -b 1024 -i 2048 -L xen_rescue -F "$DST" >/dev/null 2>&1 - DST_MNT="$DST".mnt - mkdir -p "$DST_MNT" - mount -o loop "$DST" "$DST_MNT" - if [ $? -ne 0 ]; then - error "Failed to mount destination disk image via loopback." - fi - echo "Copying files from '$SRC'..." - if test -d "$SRC"; then - if [ ! -d "$SRC"/dev ] || [ ! -d "$SRC"/sbin ]; then - error "'$SRC' does not look like a valid root filesystem." - fi - cp_rescue "$SRC" "$DST_MNT" - if [ $? -ne 0 ]; then - cp_error - fi - else - mkdir -p "$DST".src - if test ! -z "`file $SRC | grep gzip`"; then - cp -p "$SRC" "$DST".stage.gz - gunzip -f "$DST".stage.gz || rm -f "$DST".stage.gz - mount -o loop "$DST".stage "$DST".src - if [ $? -ne 0 ]; then - rm "$DST".stage - rmdir "$DST".src - error "Failed to mount the source via loopback." - fi - cp_rescue "$DST".src "$DST_MNT" - if [ $? -ne 0 ]; then - umount "$DST".src - rm "$DST".stage - rmdir "$DST".src - cp_error - fi - umount "$DST".src - rm "$DST".stage - else - mount -o loop "$SRC" "$DST".src - if [ $? -ne 0 ]; then - rmdir "$DST".src - error "Failed to mount the source via loopback." - fi - cp_rescue "$DST".src "$DST_MNT" - if [ $? -ne 0 ]; then - umount "$DST".src - rmdir "$DST".src - cp_error - fi - umount "$DST".src - fi - rmdir "$DST".src - fi -} - -# Save some inodes -remove_some_files() -{ - # these consume an excessive amount of inodes - rm -f "$DST_MNT"/dev/sd[c-z][a-z][0-9]* - # hwclock does not work - rm -f "$DST_MNT"/etc/init.d/boot.d/*boot.clock -} - -xenify_image() -{ - # Xen doesn't yet support virtualizing USB - sed -i "s/^usbfs/#usbfs/" "$DST_MNT"/etc/fstab -} - -# Copy extra files to rescue image -copy_extra_files() -{ - test ! -e "$DST_MNT"/sbin/depmod && cp -p /sbin/depmod "$DST_MNT"/sbin/ - cp -p /usr/share/doc/packages/xen/boot.local.xenU "$DST_MNT"/etc/init.d/boot.local -} - -# Remove kernel modules and replace by ours -exchange_kernel_modules() -{ - echo "Updating kernel within '$DST'..." - KMODDIR=/lib/modules/$KVER/kernel - MNTKVER="`cd "$DST_MNT"/lib/modules && ls -td */kernel 2>/dev/null | sed 's@/kernel@@' 2>/dev/null`" - for dir in $MNTKVER; do - if test "$MNTKVER" != "$KVER"; then - rm -rf "$DST_MNT"/lib/modules/$MNTKVER - fi - done - mkdir -p "$DST_MNT"$KMODDIR - # complete trees - for dir in arch crypto lib net security; do - cp -ax $KMODDIR/$dir "$DST_MNT"$KMODDIR/ - done - mkdir -p "$DST_MNT"$KMODDIR/fs - cp -p $KMODDIR/fs/*.ko "$DST_MNT"$KMODDIR/fs/ - # a selection of FS - for fs in afs autofs autofs4 cifs exportfs ext3 fat jbd jfs msdos ncpfs nfsd nls ntfs reiser4 reiserfs smbfs subfs sysv udf ufs vfat xfs; do - if test -e $KMODDIR/fs/$fs; then - cp -ax $KMODDIR/fs/$fs "$DST_MNT"$KMODDIR/fs/ - fi - done - # some drivers - mkdir -p "$DST_MNT"$KMODDIR/drivers/char - for name in lp.ko n_hdlc.ko raw.ko; do - cp -p $KMODDIR/drivers/char/$name "$DST_MNT"$KMODDIR/drivers/char/ - done - mkdir -p "$DST_MNT"$KMODDIR/drivers/block - for name in umem.ko nbd.ko loop.ko loop_fish2.ko cryptoloop.ko; do - cp -p $KMODDIR/drivers/block/$name "$DST_MNT"$KMODDIR/drivers/block/ - done - mkdir -p "$DST_MNT"$KMODDIR/drivers/base - cp -p $KMODDIR/drivers/base/firmware_class.ko "$DST_MNT"$KMODDIR/drivers/base/ - mkdir -p "$DST_MNT"$KMODDIR/drivers/md - cp -p $KMODDIR/drivers/md/*.ko "$DST_MNT"$KMODDIR/drivers/md/ - mkdir -p "$DST_MNT"$KMODDIR/drivers/xen - for dir in $KMODDIR/drivers/xen/*front; do - cp -ax $dir "$DST_MNT"$KMODDIR/drivers/xen/ - done - if test -e $KMODDIR/kernel; then - mkdir -p "$DST_MNT"$KMODDIR/kernel - cp -ax $KMODDIR/kernel/* "$DST_MNT"$KMODDIR/kernel/ - fi - # Kernel image + System.map - mkdir -p "$DST_MNT"/boot - rm -f "$DST_MNT"/boot/vmlinuz-* "$DST_MNT"/boot/System.map-* "$DST_MNT"/boot/initrd-* - cp -p /boot/vmlinuz-$KVER "$DST_MNT"/boot/ - if test -e /boot/initrd-$KVER-domU; then - cp -p /boot/initrd-$KVER-domU "$DST_MNT"/boot/initrd-$KVER - else - cp -p /boot/initrd-$KVER "$DST_MNT"/boot/ - fi - cp -p /boot/System.map-$KVER "$DST_MNT"/boot/ - depmod -a $KVER -b "$DST_MNT" -F "$DST_MNT"/boot/System.map-$KVER - -} - -# umount and display message -umount_and_msg() -{ - umount "$DST_MNT" - rmdir "$DST_MNT" - DST_MNT= - echo "'$DST' has been prepared successfully." - CFGFILE=/etc/xen/vm/${DST##*/} - if test -e $CFGFILE; then - mv -b $CFGFILE $CFGFILE.save - fi - if test "${DST:0:1}" != "/"; then - DST="`pwd`/$DST" - fi - cp -p /etc/xen/examples/xmexample.rescue $CFGFILE - sed -i "/^disk/s@^.*\$@disk = [ \'file:$DST,hda1,w\' ]@" $CFGFILE - # These next two lines are only applicable if not using domUloader, - # but try anyway. - sed -i "/^kernel/s@^.*\$@kernel = \"/boot/vmlinuz-$KVER\"@" $CFGFILE - sed -i "/^ramdisk/s@^.*\$@ramdisk = \"/boot/initrd-$KVER\"@" $CFGFILE - echo "" - echo "Config file '$CFGFILE' has been created. Please review!" - echo "You may also want to add an IP address to the config file." - echo "Start the domain with 'xm create -c $CFGFILE'." -} - -if test -z "$1" -o -z "$2"; then - usage -fi -SRC=$1 -if [ ! -e "$SRC" ]; then - usage_error "'$SRC' does not exist." -fi -DST=$2 -if [ -e "$DST" ]; then - error "'$DST' already exists." -fi -MB=$MB_DEFAULT -[ ! -z "$3" ] && MB=$3 -KVER=$4 -if [ `id -u` -ne 0 ]; then - usage_error "Please run this script as root." -fi - -get_xen_kernel -create_basis_and_mount -remove_some_files -copy_extra_files -xenify_image -exchange_kernel_modules -umount_and_msg diff --git a/non-flat-pm.patch b/non-flat-pm.patch deleted file mode 100644 index 885068b..0000000 --- a/non-flat-pm.patch +++ /dev/null @@ -1,461 +0,0 @@ -From: Jan Beulich -Bugzilla #214568 - -Index: xen-3.0.3-testing/xen/arch/x86/hvm/platform.c -=================================================================== ---- xen-3.0.3-testing.orig/xen/arch/x86/hvm/platform.c -+++ xen-3.0.3-testing/xen/arch/x86/hvm/platform.c -@@ -883,19 +883,14 @@ void handle_mmio(unsigned long va, unsig - memcpy(regs, guest_cpu_user_regs(), HVM_CONTEXT_STACK_BYTES); - hvm_store_cpu_guest_regs(v, regs, NULL); - -- inst_len = hvm_instruction_length(regs, hvm_guest_x86_mode(v)); -+ inst_addr = hvm_get_segment_base(current, seg_cs) + regs->eip; -+ inst_len = hvm_instruction_length(inst_addr, hvm_guest_x86_mode(v)); - if ( inst_len <= 0 ) - { - printk("handle_mmio: failed to get instruction length\n"); - domain_crash_synchronous(); - } - -- realmode = hvm_realmode(v); -- if (realmode) -- inst_addr = (regs->cs << 4) + regs->eip; -- else -- inst_addr = regs->eip; -- - memset(inst, 0, MAX_INST_LEN); - ret = inst_copy_from_guest(inst, inst_addr, inst_len); - if (ret != inst_len) { -@@ -904,6 +899,7 @@ void handle_mmio(unsigned long va, unsig - } - - init_instruction(&mmio_inst); -+ realmode = hvm_realmode(v); - - if (hvm_decode(realmode, inst, &mmio_inst) == DECODE_failure) { - printk("handle_mmio: failed to decode instruction\n"); -Index: xen-3.0.3-testing/xen/arch/x86/hvm/svm/svm.c -=================================================================== ---- xen-3.0.3-testing.orig/xen/arch/x86/hvm/svm/svm.c -+++ xen-3.0.3-testing/xen/arch/x86/hvm/svm/svm.c -@@ -507,6 +507,24 @@ unsigned long svm_get_ctrl_reg(struct vc - return 0; /* dummy */ - } - -+static unsigned long svm_get_segment_base(struct vcpu *v, enum segment seg) -+{ -+ switch ( seg ) -+ { -+ case seg_cs: return v->arch.hvm_svm.vmcb->cs.base; -+ case seg_ds: return v->arch.hvm_svm.vmcb->ds.base; -+ case seg_es: return v->arch.hvm_svm.vmcb->es.base; -+ case seg_fs: return v->arch.hvm_svm.vmcb->fs.base; -+ case seg_gs: return v->arch.hvm_svm.vmcb->gs.base; -+ case seg_ss: return v->arch.hvm_svm.vmcb->ss.base; -+ case seg_tr: return v->arch.hvm_svm.vmcb->tr.base; -+ case seg_gdtr: return v->arch.hvm_svm.vmcb->gdtr.base; -+ case seg_idtr: return v->arch.hvm_svm.vmcb->idtr.base; -+ case seg_ldtr: return v->arch.hvm_svm.vmcb->ldtr.base; -+ } -+ BUG(); -+ return 0; -+} - - /* Make sure that xen intercepts any FP accesses from current */ - static void svm_stts(struct vcpu *v) -@@ -887,6 +905,7 @@ int start_svm(void) - hvm_funcs.pae_enabled = svm_pae_enabled; - hvm_funcs.guest_x86_mode = svm_guest_x86_mode; - hvm_funcs.get_guest_ctrl_reg = svm_get_ctrl_reg; -+ hvm_funcs.get_segment_base = svm_get_segment_base; - - hvm_funcs.update_host_cr3 = svm_update_host_cr3; - -Index: xen-3.0.3-testing/xen/arch/x86/hvm/vmx/vmx.c -=================================================================== ---- xen-3.0.3-testing.orig/xen/arch/x86/hvm/vmx/vmx.c -+++ xen-3.0.3-testing/xen/arch/x86/hvm/vmx/vmx.c -@@ -610,7 +610,27 @@ static unsigned long vmx_get_ctrl_reg(st - return 0; /* dummy */ - } - -+static unsigned long vmx_get_segment_base(struct vcpu *v, enum segment seg) -+{ -+ unsigned long base; - -+ BUG_ON(v != current); -+ switch ( seg ) -+ { -+ case seg_cs: __vmread(GUEST_CS_BASE, &base); break; -+ case seg_ds: __vmread(GUEST_DS_BASE, &base); break; -+ case seg_es: __vmread(GUEST_ES_BASE, &base); break; -+ case seg_fs: __vmread(GUEST_FS_BASE, &base); break; -+ case seg_gs: __vmread(GUEST_GS_BASE, &base); break; -+ case seg_ss: __vmread(GUEST_SS_BASE, &base); break; -+ case seg_tr: __vmread(GUEST_TR_BASE, &base); break; -+ case seg_gdtr: __vmread(GUEST_GDTR_BASE, &base); break; -+ case seg_idtr: __vmread(GUEST_IDTR_BASE, &base); break; -+ case seg_ldtr: __vmread(GUEST_LDTR_BASE, &base); break; -+ default: BUG(); base = 0; break; -+ } -+ return base; -+} - - /* Make sure that xen intercepts any FP accesses from current */ - static void vmx_stts(struct vcpu *v) -@@ -753,6 +773,7 @@ static void vmx_setup_hvm_funcs(void) - hvm_funcs.pae_enabled = vmx_pae_enabled; - hvm_funcs.guest_x86_mode = vmx_guest_x86_mode; - hvm_funcs.get_guest_ctrl_reg = vmx_get_ctrl_reg; -+ hvm_funcs.get_segment_base = vmx_get_segment_base; - - hvm_funcs.update_host_cr3 = vmx_update_host_cr3; - -Index: xen-3.0.3-testing/xen/include/asm-x86/hvm/hvm.h -=================================================================== ---- xen-3.0.3-testing.orig/xen/include/asm-x86/hvm/hvm.h -+++ xen-3.0.3-testing/xen/include/asm-x86/hvm/hvm.h -@@ -20,6 +20,19 @@ - #ifndef __ASM_X86_HVM_HVM_H__ - #define __ASM_X86_HVM_HVM_H__ - -+enum segment { -+ seg_cs, -+ seg_ss, -+ seg_ds, -+ seg_es, -+ seg_fs, -+ seg_gs, -+ seg_tr, -+ seg_ldtr, -+ seg_gdtr, -+ seg_idtr -+}; -+ - /* - * The hardware virtual machine (HVM) interface abstracts away from the - * x86/x86_64 CPU virtualization assist specifics. Currently this interface -@@ -52,6 +65,7 @@ struct hvm_function_table { - * 1) determine whether the guest is in real or vm8086 mode, - * 2) determine whether paging is enabled, - * 3) return the current guest control-register value -+ * 4) return the current guest segment descriptor base - */ - int (*realmode)(struct vcpu *v); - int (*paging_enabled)(struct vcpu *v); -@@ -59,6 +73,7 @@ struct hvm_function_table { - int (*pae_enabled)(struct vcpu *v); - int (*guest_x86_mode)(struct vcpu *v); - unsigned long (*get_guest_ctrl_reg)(struct vcpu *v, unsigned int num); -+ unsigned long (*get_segment_base)(struct vcpu *v, enum segment seg); - - /* - * Re-set the value of CR3 that Xen runs on when handling VM exits -@@ -157,7 +172,7 @@ hvm_guest_x86_mode(struct vcpu *v) - return hvm_funcs.guest_x86_mode(v); - } - --int hvm_instruction_length(struct cpu_user_regs *regs, int mode); -+int hvm_instruction_length(unsigned long pc, int mode); - - static inline void - hvm_update_host_cr3(struct vcpu *v) -@@ -176,6 +191,12 @@ hvm_get_guest_ctrl_reg(struct vcpu *v, u - return 0; /* force to fail */ - } - -+static inline unsigned long -+hvm_get_segment_base(struct vcpu *v, enum segment seg) -+{ -+ return hvm_funcs.get_segment_base(v, seg); -+} -+ - void hvm_stts(struct vcpu *v); - void hvm_set_guest_time(struct vcpu *v, u64 gtime); - void hvm_do_resume(struct vcpu *v); -Index: xen-3.0.3-testing/xen/arch/x86/hvm/instrlen.c -=================================================================== ---- xen-3.0.3-testing.orig/xen/arch/x86/hvm/instrlen.c -+++ xen-3.0.3-testing/xen/arch/x86/hvm/instrlen.c -@@ -20,7 +20,6 @@ - #include - #include - #include --#include - #include - - /* read from guest memory */ -@@ -195,54 +194,51 @@ static uint8_t twobyte_table[256] = { - }; - - /* -- * insn_fetch - fetch the next 1 to 4 bytes from instruction stream -- * @_type: u8, u16, u32, s8, s16, or s32 -- * @_size: 1, 2, or 4 bytes -+ * insn_fetch - fetch the next byte from instruction stream - */ --#define insn_fetch(_type, _size) \ --({ unsigned long _x, _ptr = _regs.eip; \ -- if ( mode == X86EMUL_MODE_REAL ) _ptr += _regs.cs << 4; \ -- rc = inst_copy_from_guest((unsigned char *)(&(_x)), _ptr, _size); \ -- if ( rc != _size ) goto done; \ -- _regs.eip += (_size); \ -- length += (_size); \ -- (_type)_x; \ -+#define insn_fetch() \ -+({ uint8_t _x; \ -+ if ( inst_copy_from_guest(&_x, pc, 1) != 1 ) { \ -+ DPRINTK("Cannot read from address %lx (eip %lx, mode %d)\n", \ -+ pc, org_pc, mode); \ -+ return -1; \ -+ } \ -+ pc += 1; \ -+ length += 1; \ -+ _x; \ - }) - - /** - * hvm_instruction_length - returns the current instructions length - * -- * @regs: guest register state -+ * @org_pc: guest instruction pointer - * @mode: guest operating mode - * - * EXTERNAL this routine calculates the length of the current instruction -- * pointed to by eip. The guest state is _not_ changed by this routine. -+ * pointed to by org_pc. The guest state is _not_ changed by this routine. - */ --int hvm_instruction_length(struct cpu_user_regs *regs, int mode) -+int hvm_instruction_length(unsigned long org_pc, int mode) - { - uint8_t b, d, twobyte = 0, rex_prefix = 0; - uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0; -- unsigned int op_bytes, ad_bytes, i; -- int rc = 0; -+ unsigned int op_default, op_bytes, ad_default, ad_bytes, i; - int length = 0; - unsigned int tmp; -- -- /* Shadow copy of register state. Committed on successful emulation. */ -- struct cpu_user_regs _regs = *regs; -+ unsigned long pc = org_pc; - - switch ( mode ) - { - case X86EMUL_MODE_REAL: - case X86EMUL_MODE_PROT16: -- op_bytes = ad_bytes = 2; -+ op_bytes = op_default = ad_bytes = ad_default = 2; - break; - case X86EMUL_MODE_PROT32: -- op_bytes = ad_bytes = 4; -+ op_bytes = op_default = ad_bytes = ad_default = 4; - break; - #ifdef __x86_64__ - case X86EMUL_MODE_PROT64: -- op_bytes = 4; -- ad_bytes = 8; -+ op_bytes = op_default = 4; -+ ad_bytes = ad_default = 8; - break; - #endif - default: -@@ -252,16 +248,16 @@ int hvm_instruction_length(struct cpu_us - /* Legacy prefixes. */ - for ( i = 0; i < 8; i++ ) - { -- switch ( b = insn_fetch(uint8_t, 1) ) -+ switch ( b = insn_fetch() ) - { - case 0x66: /* operand-size override */ -- op_bytes ^= 6; /* switch between 2/4 bytes */ -+ op_bytes = op_default ^ 6; /* switch between 2/4 bytes */ - break; - case 0x67: /* address-size override */ - if ( mode == X86EMUL_MODE_PROT64 ) -- ad_bytes ^= 12; /* switch between 4/8 bytes */ -+ ad_bytes = ad_default ^ 12; /* switch between 4/8 bytes */ - else -- ad_bytes ^= 6; /* switch between 2/4 bytes */ -+ ad_bytes = ad_default ^ 6; /* switch between 2/4 bytes */ - break; - case 0x2e: /* CS override */ - case 0x3e: /* DS override */ -@@ -273,21 +269,30 @@ int hvm_instruction_length(struct cpu_us - case 0xf3: /* REP/REPE/REPZ */ - case 0xf2: /* REPNE/REPNZ */ - break; -+#ifdef __x86_64__ -+ case 0x40 ... 0x4f: -+ if ( mode == X86EMUL_MODE_PROT64 ) -+ { -+ rex_prefix = b; -+ continue; -+ } -+ /* FALLTHRU */ -+#endif - default: - goto done_prefixes; - } -+ rex_prefix = 0; - } - done_prefixes: - - /* REX prefix. */ -- if ( (mode == X86EMUL_MODE_PROT64) && ((b & 0xf0) == 0x40) ) -+ if ( rex_prefix ) - { -- rex_prefix = b; -- if ( b & 8 ) -- op_bytes = 8; /* REX.W */ -- modrm_reg = (b & 4) << 1; /* REX.R */ -+ if ( rex_prefix & 8 ) -+ op_bytes = 8; /* REX.W */ -+ modrm_reg = (rex_prefix & 4) << 1; /* REX.R */ - /* REX.B and REX.X do not need to be decoded. */ -- b = insn_fetch(uint8_t, 1); -+ b = insn_fetch(); - } - - /* Opcode byte(s). */ -@@ -298,7 +303,7 @@ done_prefixes: - if ( b == 0x0f ) - { - twobyte = 1; -- b = insn_fetch(uint8_t, 1); -+ b = insn_fetch(); - d = twobyte_table[b]; - } - -@@ -310,7 +315,7 @@ done_prefixes: - /* ModRM and SIB bytes. */ - if ( d & ModRM ) - { -- modrm = insn_fetch(uint8_t, 1); -+ modrm = insn_fetch(); - modrm_mod |= (modrm & 0xc0) >> 6; - modrm_reg |= (modrm & 0x38) >> 3; - modrm_rm |= (modrm & 0x07); -@@ -330,16 +335,16 @@ done_prefixes: - if ( modrm_rm == 6 ) - { - length += 2; -- _regs.eip += 2; /* skip disp16 */ -+ pc += 2; /* skip disp16 */ - } - break; - case 1: - length += 1; -- _regs.eip += 1; /* skip disp8 */ -+ pc += 1; /* skip disp8 */ - break; - case 2: - length += 2; -- _regs.eip += 2; /* skip disp16 */ -+ pc += 2; /* skip disp16 */ - break; - } - } -@@ -350,33 +355,34 @@ done_prefixes: - { - case 0: - if ( (modrm_rm == 4) && -- (((insn_fetch(uint8_t, 1)) & 7) -- == 5) ) -+ ((insn_fetch() & 7) == 5) ) - { - length += 4; -- _regs.eip += 4; /* skip disp32 specified by SIB.base */ -+ pc += 4; /* skip disp32 specified by SIB.base */ - } - else if ( modrm_rm == 5 ) - { - length += 4; -- _regs.eip += 4; /* skip disp32 */ -+ pc += 4; /* skip disp32 */ - } - break; - case 1: - if ( modrm_rm == 4 ) - { -- insn_fetch(uint8_t, 1); -+ length += 1; -+ pc += 1; - } - length += 1; -- _regs.eip += 1; /* skip disp8 */ -+ pc += 1; /* skip disp8 */ - break; - case 2: - if ( modrm_rm == 4 ) - { -- insn_fetch(uint8_t, 1); -+ length += 1; -+ pc += 1; - } - length += 4; -- _regs.eip += 4; /* skip disp32 */ -+ pc += 4; /* skip disp32 */ - break; - } - } -@@ -397,15 +403,12 @@ done_prefixes: - tmp = (d & ByteOp) ? 1 : op_bytes; - if ( tmp == 8 ) tmp = 4; - /* NB. Immediates are sign-extended as necessary. */ -- switch ( tmp ) -- { -- case 1: insn_fetch(int8_t, 1); break; -- case 2: insn_fetch(int16_t, 2); break; -- case 4: insn_fetch(int32_t, 4); break; -- } -+ length += tmp; -+ pc += tmp; - break; - case SrcImmByte: -- insn_fetch(int8_t, 1); -+ length += 1; -+ pc += 1; - break; - } - -@@ -414,13 +417,9 @@ done_prefixes: - - switch ( b ) - { -- case 0xa0 ... 0xa1: /* mov */ -- length += ad_bytes; -- _regs.eip += ad_bytes; /* skip src displacement */ -- break; -- case 0xa2 ... 0xa3: /* mov */ -+ case 0xa0 ... 0xa3: /* mov */ - length += ad_bytes; -- _regs.eip += ad_bytes; /* skip dst displacement */ -+ pc += ad_bytes; /* skip src/dst displacement */ - break; - case 0xf6 ... 0xf7: /* Grp3 */ - switch ( modrm_reg ) -@@ -429,12 +428,8 @@ done_prefixes: - /* Special case in Grp3: test has an immediate source operand. */ - tmp = (d & ByteOp) ? 1 : op_bytes; - if ( tmp == 8 ) tmp = 4; -- switch ( tmp ) -- { -- case 1: insn_fetch(int8_t, 1); break; -- case 2: insn_fetch(int16_t, 2); break; -- case 4: insn_fetch(int32_t, 4); break; -- } -+ length += tmp; -+ pc += tmp; - goto done; - } - break; -@@ -445,6 +440,6 @@ done: - - cannot_emulate: - DPRINTK("Cannot emulate %02x at address %lx (eip %lx, mode %d)\n", -- b, (unsigned long)_regs.eip, (unsigned long)regs->eip, mode); -+ b, pc, org_pc, mode); - return -1; - } diff --git a/npt-fpu-bug.patch b/npt-fpu-bug.patch new file mode 100644 index 0000000..b877320 --- /dev/null +++ b/npt-fpu-bug.patch @@ -0,0 +1,28 @@ +Index: xen-3.0.4-testing/xen/arch/x86/hvm/svm/svm.c +=================================================================== +--- xen-3.0.4-testing.orig/xen/arch/x86/hvm/svm/svm.c ++++ xen-3.0.4-testing/xen/arch/x86/hvm/svm/svm.c +@@ -1745,6 +1745,13 @@ int npt_mov_to_cr(int gpreg, int cr, str + case 0: + vmcb->cr0 = value; + v->arch.hvm_svm.cpu_shadow_cr0 = value; ++ ++ /* TS cleared? Then initialise FPU now. */ ++ if ( !(value & X86_CR0_TS) ) { ++ setup_fpu(v); ++ vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_NM; ++ } ++ + npt_update_guest_paging_mode(v); + break; + case 3: +@@ -1755,8 +1762,8 @@ int npt_mov_to_cr(int gpreg, int cr, str + case 4: /* CR4 */ + vmcb->cr4 = value; + v->arch.hvm_svm.cpu_shadow_cr4 = value; +- npt_update_guest_paging_mode(v); + set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags); ++ npt_update_guest_paging_mode(v); + break; + case 8: + vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4)); diff --git a/npt-windows-bug.patch b/npt-windows-bug.patch new file mode 100644 index 0000000..dc3c872 --- /dev/null +++ b/npt-windows-bug.patch @@ -0,0 +1,302 @@ +Index: xen-3.0.4-testing/xen/arch/x86/domain.c +=================================================================== +--- xen-3.0.4-testing.orig/xen/arch/x86/domain.c ++++ xen-3.0.4-testing/xen/arch/x86/domain.c +@@ -41,6 +41,7 @@ + #include + #include + #include ++#include + #ifdef CONFIG_COMPAT + #include + #endif +@@ -334,6 +335,8 @@ int vcpu_initialise(struct vcpu *v) + + pae_l3_cache_init(&v->arch.pae_l3_cache); + ++ hap_vcpu_init(v); ++ + /* This should move to arch_domain_create(). */ + if ( !is_idle_domain(d) && (v->vcpu_id == 0) ) + pit_init(v, cpu_khz); +@@ -470,6 +473,9 @@ void arch_domain_destroy(struct domain * + hvm_domain_destroy(d); + } + ++ for_each_vcpu ( d, v ) ++ hap_vcpu_destroy(v); ++ + shadow_final_teardown(d); + + free_xenheap_pages( +Index: xen-3.0.4-testing/xen/arch/x86/hvm/hvm.c +=================================================================== +--- xen-3.0.4-testing.orig/xen/arch/x86/hvm/hvm.c ++++ xen-3.0.4-testing/xen/arch/x86/hvm/hvm.c +@@ -49,6 +49,7 @@ + #include + #include + #include ++#include + + int hvm_enabled = 0; + +@@ -339,7 +340,7 @@ static int __hvm_copy(void *buf, paddr_t + count = min_t(int, PAGE_SIZE - (addr & ~PAGE_MASK), todo); + + if ( virt ) +- mfn = get_mfn_from_gpfn(shadow_gva_to_gfn(current, addr)); ++ mfn = get_mfn_from_gpfn(hap_gva_to_gfn(current, addr)); + else + mfn = get_mfn_from_gpfn(addr >> PAGE_SHIFT); + +Index: xen-3.0.4-testing/xen/arch/x86/hvm/platform.c +=================================================================== +--- xen-3.0.4-testing.orig/xen/arch/x86/hvm/platform.c ++++ xen-3.0.4-testing/xen/arch/x86/hvm/platform.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + + #define DECODE_success 1 + #define DECODE_failure 0 +@@ -793,7 +794,7 @@ void send_pio_req(unsigned long port, un + if ( value_is_ptr ) /* get physical address of data */ + { + if ( hvm_paging_enabled(current) ) +- p->data = shadow_gva_to_gpa(current, value); ++ p->data = hap_gva_to_gpa(current, value); + else + p->data = value; /* guest VA == guest PA */ + } +@@ -849,7 +850,7 @@ static void send_mmio_req(unsigned char + if ( value_is_ptr ) + { + if ( hvm_paging_enabled(v) ) +- p->data = shadow_gva_to_gpa(v, value); ++ p->data = hap_gva_to_gpa(v, value); + else + p->data = value; /* guest VA == guest PA */ + } +@@ -965,7 +966,7 @@ void handle_mmio(unsigned long gpa) + if ( ad_size == WORD ) + addr &= 0xFFFF; + addr += hvm_get_segment_base(v, x86_seg_es); +- if ( shadow_gva_to_gpa(v, addr) == gpa ) ++ if ( hap_gva_to_gpa(v, addr) == gpa ) + { + enum x86_segment seg; + +Index: xen-3.0.4-testing/xen/arch/x86/mm/hap/hap.c +=================================================================== +--- xen-3.0.4-testing.orig/xen/arch/x86/mm/hap/hap.c ++++ xen-3.0.4-testing/xen/arch/x86/mm/hap/hap.c +@@ -18,7 +18,21 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +-#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + + /* initialize hardware assisted paging. It checks whether hap option is enabled + * in Xen boot option. +@@ -26,6 +40,20 @@ + int opt_hap_enabled = 0; + boolean_param("hap", opt_hap_enabled); + ++/*************************************************/ ++/* hap functions */ ++/*************************************************/ ++void hap_vcpu_init(struct vcpu *v) ++{ ++ v->arch.hap_activated = 0; /* not activated at the beginning */ ++} ++ ++void hap_vcpu_destroy(struct vcpu *v) ++{ ++ /* nothing to do */ ++} ++ ++ + /* + * Local variables: + * mode: C +Index: xen-3.0.4-testing/xen/arch/x86/mm/hap/npt/npt.c +=================================================================== +--- xen-3.0.4-testing.orig/xen/arch/x86/mm/hap/npt/npt.c ++++ xen-3.0.4-testing/xen/arch/x86/mm/hap/npt/npt.c +@@ -34,6 +34,49 @@ + #include "page-guest32.h" + + extern int opt_hap_enabled; ++ ++/* Forward Declaration */ ++static paddr_t npt_gva_to_gpa_real_mode(struct vcpu *v, unsigned long gva); ++static paddr_t npt_gva_to_gpa_protected_mode(struct vcpu *v, ++ unsigned long gva); ++static paddr_t npt_gva_to_gpa_pae_mode(struct vcpu *v, unsigned long gva); ++static paddr_t npt_gva_to_gpa_long_mode(struct vcpu *v, unsigned long gva); ++static unsigned long npt_gva_to_gfn_real_mode(struct vcpu *v, ++ unsigned long gva); ++static unsigned long npt_gva_to_gfn_protected_mode(struct vcpu *v, ++ unsigned long gva); ++static unsigned long npt_gva_to_gfn_pae_mode(struct vcpu *v, ++ unsigned long gva); ++static unsigned long npt_gva_to_gfn_long_mode(struct vcpu *v, ++ unsigned long gva); ++ ++/*******************************************/ ++/* global variables */ ++/*******************************************/ ++struct hap_vcpu NPT_REAL_MODE_HANDLER = { ++ .guest_page_level = 1, ++ .gva_to_gfn = npt_gva_to_gfn_real_mode, ++ .gva_to_gpa = npt_gva_to_gpa_real_mode ++}; ++ ++struct hap_vcpu NPT_PROTECTED_MODE_HANDLER = { ++ .guest_page_level = 2, ++ .gva_to_gfn = npt_gva_to_gfn_protected_mode, ++ .gva_to_gpa = npt_gva_to_gpa_protected_mode ++}; ++ ++struct hap_vcpu NPT_PAE_MODE_HANDLER = { ++ .guest_page_level = 3, ++ .gva_to_gfn = npt_gva_to_gfn_pae_mode, ++ .gva_to_gpa = npt_gva_to_gpa_pae_mode ++}; ++ ++struct hap_vcpu NPT_LONG_MODE_HANDLER = { ++ .guest_page_level = 4, ++ .gva_to_gfn = npt_gva_to_gfn_long_mode, ++ .gva_to_gpa = npt_gva_to_gpa_long_mode ++}; ++ + /*******************************************/ + /* Platform Specific Functions */ + /*******************************************/ +@@ -350,7 +393,9 @@ void npt_detect(void) + + /* check CPUID for nested paging support */ + cpuid(0x8000000A, &eax, &ebx, &ecx, &edx); +- if ( !(edx & 0x01) && opt_hap_enabled ) { ++ if ( edx & 0x01 ) { ++ } ++ else if ( opt_hap_enabled ) { + printk(" nested paging is not supported by this CPU.\n"); + opt_hap_enabled = 0; /* no nested paging, we disable op_hap_enabled */ + } +@@ -366,23 +411,19 @@ void npt_set_guest_paging_levels(struct + switch(levels) { + case 1: + NPT_PRINTK("Install real mode guest with ID = %d\n", v->vcpu_id); +- v->arch.shadow.mode->gva_to_gpa = &npt_gva_to_gpa_real_mode; +- v->arch.shadow.mode->gva_to_gfn = &npt_gva_to_gfn_real_mode; ++ v->arch.hap_mode = &NPT_REAL_MODE_HANDLER; + break; + case 2: + NPT_PRINTK("Install 32-bit non-PAE guest with ID = %d\n", v->vcpu_id); +- v->arch.shadow.mode->gva_to_gpa = &npt_gva_to_gpa_protected_mode; +- v->arch.shadow.mode->gva_to_gfn = &npt_gva_to_gfn_protected_mode; ++ v->arch.hap_mode = &NPT_PROTECTED_MODE_HANDLER; + break; + case 3: + NPT_PRINTK("Install 32-bit PAE guest with ID = %d\n", v->vcpu_id); +- v->arch.shadow.mode->gva_to_gpa = &npt_gva_to_gpa_pae_mode; +- v->arch.shadow.mode->gva_to_gfn = &npt_gva_to_gfn_pae_mode; ++ v->arch.hap_mode = &NPT_PAE_MODE_HANDLER; + break; + case 4: + NPT_PRINTK("Install 64-bit guest with ID = %d\n", v->vcpu_id); +- v->arch.shadow.mode->gva_to_gpa = &npt_gva_to_gpa_long_mode; +- v->arch.shadow.mode->gva_to_gfn = &npt_gva_to_gfn_long_mode; ++ v->arch.hap_mode = &NPT_LONG_MODE_HANDLER; + break; + default: + printk("Un-supported guest paging level: %d\n", levels); +Index: xen-3.0.4-testing/xen/include/asm-x86/domain.h +=================================================================== +--- xen-3.0.4-testing.orig/xen/include/asm-x86/domain.h ++++ xen-3.0.4-testing/xen/include/asm-x86/domain.h +@@ -208,8 +208,8 @@ struct arch_vcpu + unsigned long shadow_ldt_mapcnt; + + struct shadow_vcpu shadow; +- +- unsigned int hap_activated:1; /* hardware assisted paging */ ++ struct hap_vcpu *hap_mode; /* hardware assisted paging support */ ++ unsigned int hap_activated:1; + } __cacheline_aligned; + + /* shorthands to improve code legibility */ +Index: xen-3.0.4-testing/xen/include/asm-x86/hap.h +=================================================================== +--- xen-3.0.4-testing.orig/xen/include/asm-x86/hap.h ++++ xen-3.0.4-testing/xen/include/asm-x86/hap.h +@@ -26,6 +26,25 @@ + #include + #include + ++/************************************************/ ++/* HAP data structure */ ++/************************************************/ ++struct hap_vcpu { ++ int guest_page_level; ++ ++ /* function pointers */ ++ int (*host_pgfault )(struct vcpu *v, unsigned long va, ++ struct cpu_user_regs *regs); ++ unsigned long (*gva_to_gfn )(struct vcpu *v, unsigned long gva); ++ paddr_t (*gva_to_gpa )(struct vcpu *v, unsigned long gva); ++}; ++ ++/************************************************/ ++/* HAP interface to Xen */ ++/************************************************/ ++void hap_vcpu_init(struct vcpu *v); ++void hap_vcpu_destroy(struct vcpu *v); ++ + static inline unsigned int hap_is_activated(struct vcpu *v) + { + return v->arch.hap_activated; +@@ -41,6 +60,24 @@ static inline void hap_deactivate(struct + v->arch.hap_activated = 0; + } + ++static inline paddr_t hap_gva_to_gpa(struct vcpu *v, unsigned long gva) ++{ ++ if ( v->arch.hap_activated ) ++ return v->arch.hap_mode->gva_to_gpa(v, gva); ++ else ++ return shadow_gva_to_gpa(v, gva); ++} ++ ++static inline unsigned long hap_gva_to_gfn(struct vcpu *v, unsigned long gva) ++{ ++ if ( v->arch.hap_activated ) ++ return v->arch.hap_mode->gva_to_gfn(v, gva); ++ else ++ return shadow_gva_to_gfn(v, gva); ++} ++/************************************************/ ++/* nested paging interface */ ++/************************************************/ + void npt_update_guest_paging_mode(struct vcpu *v); + void npt_detect(void); + #endif diff --git a/npt_part1.patch b/npt_part1.patch new file mode 100644 index 0000000..e59ac12 --- /dev/null +++ b/npt_part1.patch @@ -0,0 +1,1096 @@ +Index: xen-3.0.4-testing/xen/arch/x86/hvm/svm/svm.c +=================================================================== +--- xen-3.0.4-testing.orig/xen/arch/x86/hvm/svm/svm.c ++++ xen-3.0.4-testing/xen/arch/x86/hvm/svm/svm.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -53,7 +54,7 @@ + __asm__ __volatile__ ( "movw %%ax ,%%" STR(name) "" : : "a" (value) ) + + /* External functions. We should move these to some suitable header file(s) */ +- ++extern int opt_hap_enabled; + extern int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip, + int inst_len); + extern asmlinkage void do_IRQ(struct cpu_user_regs *); +@@ -800,6 +801,8 @@ static int svm_vcpu_initialise(struct vc + + v->arch.hvm_svm.saved_irq_vector = -1; + ++ hap_deactivate(v); ++ + if ( (rc = svm_create_vmcb(v)) != 0 ) + { + dprintk(XENLOG_WARNING, +@@ -814,6 +817,7 @@ static int svm_vcpu_initialise(struct vc + static void svm_vcpu_destroy(struct vcpu *v) + { + svm_destroy_vmcb(v); ++ hap_deactivate(v); + } + + static void svm_hvm_inject_exception( +@@ -856,6 +860,7 @@ int start_svm(void) + asidpool_init( cpu ); + printk("AMD SVM Extension is enabled for cpu %d.\n", cpu ); + ++ npt_detect(); + /* Initialize the HSA for this core */ + phys_hsa = (u64) virt_to_maddr(hsa[cpu]); + phys_hsa_lo = (u32) phys_hsa; +@@ -1705,6 +1710,120 @@ static inline int svm_pgbit_test(struct + return v->arch.hvm_svm.cpu_shadow_cr0 & X86_CR0_PG; + } + ++/************************************************/ ++/* nested paging functions */ ++/************************************************/ ++void npt_activate(struct vcpu *v) ++{ ++ struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; ++ struct domain *d = v->domain; ++ ++ vmcb->h_cr3 = pagetable_get_paddr(d->arch.phys_table); ++ /* use guest's CR register values */ ++ vmcb->cr0 = v->arch.hvm_svm.cpu_shadow_cr0; ++ vmcb->cr3 = v->arch.hvm_svm.cpu_cr3; ++ vmcb->cr4 = v->arch.hvm_svm.cpu_shadow_cr4; ++ vmcb->np_enable = 1; /* enable nested paging */ ++ vmcb->g_pat = 0x0007040600070406ULL; /* guest PAT */ ++ vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_PG; ++ npt_update_guest_paging_mode(v); ++ hap_activate(v); ++} ++ ++int npt_mov_to_cr(int gpreg, int cr, struct cpu_user_regs *regs) ++{ ++ unsigned long value; ++ struct vcpu *v = current; ++ struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; ++ struct vlapic *vlapic = vcpu_vlapic(v); ++ ++ ASSERT(vmcb); ++ ++ value = get_reg(gpreg, regs, vmcb); ++ ++ switch (cr) { ++ case 0: ++ vmcb->cr0 = value; ++ v->arch.hvm_svm.cpu_shadow_cr0 = value; ++ npt_update_guest_paging_mode(v); ++ break; ++ case 3: ++ vmcb->cr3 = value; ++ v->arch.hvm_svm.cpu_cr3 = value; ++ set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags); ++ break; ++ case 4: /* CR4 */ ++ vmcb->cr4 = value; ++ v->arch.hvm_svm.cpu_shadow_cr4 = value; ++ npt_update_guest_paging_mode(v); ++ set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags); ++ break; ++ case 8: ++ vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4)); ++ break; ++ default: ++ gdprintk(XENLOG_ERR, "invalid cr: %d\n", cr); ++ domain_crash(v->domain); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++void npt_mov_from_cr(int cr, int gp, struct cpu_user_regs *regs) ++{ ++ unsigned long value = 0; ++ struct vcpu *v = current; ++ struct vmcb_struct *vmcb; ++ struct vlapic *vlapic = vcpu_vlapic(v); ++ ++ vmcb = v->arch.hvm_svm.vmcb; ++ ASSERT(vmcb); ++ ++ switch(cr) ++ { ++ case 0: ++ value = vmcb->cr0; ++ break; ++ case 2: ++ value = vmcb->cr2; ++ break; ++ case 3: ++ value = vmcb->cr3; ++ break; ++ case 4: ++ value = vmcb->cr4; ++ break; ++ case 8: ++ value = (unsigned long)vlapic_get_reg(vlapic, APIC_TASKPRI); ++ value = (value & 0xF0) >> 4; ++ break; ++ default: ++ domain_crash(v->domain); ++ return; ++ } ++ ++ set_reg(gp, value, regs, vmcb); ++} ++ ++int npt_do_nested_page_fault(unsigned long va, struct cpu_user_regs *regs) ++{ ++ struct vcpu *v = current; ++ unsigned long gpa = va; ++ int result = 1; ++ ++ if (mmio_space(gpa)) { ++ handle_mmio(gpa); ++ return 1; ++ } ++ ++ /* P2M table should have been constructed at the beginning */ ++ domain_crash(v->domain); ++ return result; ++} ++/*************************************************/ ++/* end of nested paging functions */ ++/*************************************************/ + + /* + * Write to control registers +@@ -1905,12 +2024,21 @@ static int svm_cr_access(struct vcpu *v, + { + case INSTR_MOV2CR: + gpreg = decode_src_reg(prefix, buffer[index+2]); +- result = mov_to_cr(gpreg, cr, regs); ++ if ( hap_is_activated(v) ) ++ result = npt_mov_to_cr(gpreg, cr, regs); ++ else { ++ result = mov_to_cr(gpreg, cr, regs); ++ if ( opt_hap_enabled && svm_paging_enabled(v) ) ++ npt_activate(v); ++ } + break; + + case INSTR_MOVCR2: + gpreg = decode_src_reg(prefix, buffer[index+2]); +- mov_from_cr(cr, gpreg, regs); ++ if ( hap_is_activated(v) ) ++ npt_mov_from_cr(cr, gpreg, regs); ++ else ++ mov_from_cr(cr, gpreg, regs); + break; + + case INSTR_CLTS: +@@ -2897,6 +3025,19 @@ asmlinkage void svm_vmexit_handler(struc + svm_do_msr_access(v, regs); + break; + ++ case VMEXIT_NPF: ++ { ++ unsigned long gpa; ++ ++ gpa = vmcb->exitinfo2; ++ regs->error_code = vmcb->exitinfo1; ++ ++ if (!(error = npt_do_nested_page_fault(gpa, regs))) ++ domain_crash(v->domain); ++ ++ break; ++ } ++ + case VMEXIT_SHUTDOWN: + gdprintk(XENLOG_ERR, "Guest shutdown exit\n"); + goto exit_and_crash; +Index: xen-3.0.4-testing/xen/arch/x86/mm/Makefile +=================================================================== +--- xen-3.0.4-testing.orig/xen/arch/x86/mm/Makefile ++++ xen-3.0.4-testing/xen/arch/x86/mm/Makefile +@@ -1 +1,2 @@ + subdir-y += shadow ++subdir-y += hap +Index: xen-3.0.4-testing/xen/include/asm-x86/domain.h +=================================================================== +--- xen-3.0.4-testing.orig/xen/include/asm-x86/domain.h ++++ xen-3.0.4-testing/xen/include/asm-x86/domain.h +@@ -206,6 +206,8 @@ struct arch_vcpu + unsigned long shadow_ldt_mapcnt; + + struct shadow_vcpu shadow; ++ ++ unsigned int hap_activated:1; /* hardware assisted paging */ + } __cacheline_aligned; + + /* shorthands to improve code legibility */ +Index: xen-3.0.4-testing/xen/arch/x86/mm/hap/Makefile +=================================================================== +--- /dev/null ++++ xen-3.0.4-testing/xen/arch/x86/mm/hap/Makefile +@@ -0,0 +1,3 @@ ++subdir-y += npt ++ ++obj-y += hap.o +Index: xen-3.0.4-testing/xen/arch/x86/mm/hap/hap.c +=================================================================== +--- /dev/null ++++ xen-3.0.4-testing/xen/arch/x86/mm/hap/hap.c +@@ -0,0 +1,36 @@ ++/****************************************************************************** ++ * arch/x86/mm/hap/hap.c ++ * ++ * hardware assisted paging support ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include ++ ++/* initialize hardware assisted paging. It checks whether hap option is enabled ++ * in Xen boot option. ++ */ ++int opt_hap_enabled = 0; ++boolean_param("hap", opt_hap_enabled); ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ +Index: xen-3.0.4-testing/xen/arch/x86/mm/hap/npt/Makefile +=================================================================== +--- /dev/null ++++ xen-3.0.4-testing/xen/arch/x86/mm/hap/npt/Makefile +@@ -0,0 +1 @@ ++obj-y += npt.o +Index: xen-3.0.4-testing/xen/arch/x86/mm/hap/npt/npt.c +=================================================================== +--- /dev/null ++++ xen-3.0.4-testing/xen/arch/x86/mm/hap/npt/npt.c +@@ -0,0 +1,464 @@ ++/* ++ * npt.c: AMD SVM nested paging implementation for Xen ++ * ++ * Copyright (c) 2006, AMD Corporation (Wei Huang) ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple ++ * Place - Suite 330, Boston, MA 02111-1307 USA. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "private.h" ++#include "page-guest32.h" ++ ++extern int opt_hap_enabled; ++/*******************************************/ ++/* Platform Specific Functions */ ++/*******************************************/ ++ ++/* Translate guest virtual address to guest physical address. Specifically ++ * for real mode guest. ++ */ ++ ++static paddr_t npt_gva_to_gpa_real_mode(struct vcpu *v, unsigned long gva) ++{ ++ HERE_I_AM; ++ return (paddr_t)gva; ++} ++ ++/* Translate guest virtual address to guest physical address. Specifically ++ * for 2-level guest. ++ */ ++static paddr_t npt_gva_to_gpa_protected_mode(struct vcpu *v, unsigned long gva) ++{ ++ unsigned long gcr3 = hvm_get_guest_ctrl_reg(v, 3); ++ int mode = 2; /* two-level guest */ ++ int lev, index; ++ paddr_t gpa = 0; ++ unsigned long gpfn, mfn; ++ int result = 1; ++ l2_pgentry_32_t *l2e; /* guest page entry size is 32-bit */ ++ l1_pgentry_32_t *l1e; ++ ++ HERE_I_AM; ++ ++ gpfn = (gcr3 >> PAGE_SHIFT); ++ for ( lev = mode; lev >= 1; lev-- ) { ++ mfn = get_mfn_from_gpfn( gpfn ); ++ if ( mfn == INVALID_MFN ) { ++ NPT_PRINTK("bad pfn=0x%lx from gva=0x%lx at lev%d\n", gpfn, gva, ++ lev); ++ result = 0; ++ break; ++ } ++ index = (gva >> PT_SHIFT[mode][lev]) & (PT_ENTRIES[mode][lev]-1); ++ ++ if ( lev == 2 ) { ++ l2e = map_domain_page( mfn ); ++ NPT_PRINTK("l2 page table entry is %ulx at index = %d\n", ++ l2e[index].l2, index); ++ if ( !(l2e_get_flags_32(l2e[index]) & _PAGE_PRESENT) ) { ++ NPT_PRINTK("Level 2 entry not present at index = %d\n", index); ++ result = 0; ++ } ++ ++ if ( l2e_get_flags_32(l2e[index]) & _PAGE_PSE ) { /* handle PSE */ ++ NPT_PRINTK("guest page table is PSE\n"); ++ if ( l2e_get_intpte(l2e[index]) & 0x001FE000UL ) { /*[13:20] */ ++ printk("guest physical memory size is too large!\n"); ++ domain_crash(v->domain); ++ } ++ gpa = (l2e_get_intpte(l2e[index]) & PHYSICAL_PAGE_4M_MASK) + ++ (gva & ~PHYSICAL_PAGE_4M_MASK); ++ unmap_domain_page(l2e); ++ break; /* last level page table, return from here */ ++ } ++ else { ++ gpfn = l2e_get_pfn( l2e[index] ); ++ } ++ unmap_domain_page(l2e); ++ } ++ ++ if ( lev == 1 ) { ++ l1e = map_domain_page( mfn ); ++ NPT_PRINTK("l1 page table entry is %ulx at index = %d\n", ++ l1e[index].l1, index); ++ if ( !(l1e_get_flags_32(l1e[index]) & _PAGE_PRESENT) ) { ++ NPT_PRINTK("Level 1 entry not present at index = %d\n", index); ++ result = 0; ++ } ++ gpfn = l1e_get_pfn( l1e[index] ); ++ gpa = (l1e_get_intpte(l1e[index]) & PHYSICAL_PAGE_4K_MASK) + ++ (gva & ~PHYSICAL_PAGE_4K_MASK); ++ unmap_domain_page(l1e); ++ } ++ ++ if ( result != 1 ) /* error happened, jump out */ ++ break; ++ } ++ ++ NPT_PRINTK("result = %d, gva = %lx, gpa = %lx\n", result, gva, gpa); ++ return (paddr_t)gpa; ++} ++ ++/* Translate guest virtual address to guest physical address. Specifically ++ * for 3-level guest. ++ */ ++#if CONFIG_PAGING_LEVELS >= 3 ++static paddr_t npt_gva_to_gpa_pae_mode(struct vcpu *v, unsigned long gva) ++{ ++ unsigned long gcr3 = hvm_get_guest_ctrl_reg(v, 3); ++ int mode = 3; /* three-level guest */ ++ int lev, index; ++ paddr_t gpa = 0; ++ unsigned long gpfn, mfn; ++ int result = 1; ++ l1_pgentry_t *l1e; ++ l2_pgentry_t *l2e; ++ l3_pgentry_t *l3e; ++ ++ HERE_I_AM; ++ ++ NPT_PRINTK("npt_gva_to_gpa:mode = %d, gcr3 = 0x%lx, gva = 0x%lx, " ++ "entry size = %ld\n", mode, gcr3, gva, sizeof(*l3e)); ++ gpfn = (gcr3 >> PAGE_SHIFT); ++ for ( lev = mode; lev >= 1; lev-- ) { ++ mfn = get_mfn_from_gpfn( gpfn ); ++ if ( mfn == INVALID_MFN ) { ++ NPT_PRINTK("bad pfn=0x%lx from gva=0x%lx at lev%d\n", gpfn, gva, ++ lev); ++ result = 0; ++ break; ++ } ++ index = (gva >> PT_SHIFT[mode][lev]) & (PT_ENTRIES[mode][lev]-1); ++ ++ if ( lev == 3 ) { ++ l3e = map_domain_page( mfn ); ++ index += ( ((gcr3 >> 5 ) & 127 ) * 4 ); ++ if ( !(l3e_get_flags(l3e[index]) & _PAGE_PRESENT) ) { ++ NPT_PRINTK("Level 3 entry not present at index = %d\n", index); ++ result = 0; ++ } ++ gpfn = l3e_get_pfn( l3e[index] ); ++ unmap_domain_page(l3e); ++ } ++ ++ if ( lev == 2 ) { ++ l2e = map_domain_page( mfn ); ++ if ( !(l2e_get_flags(l2e[index]) & _PAGE_PRESENT) ) { ++ NPT_PRINTK("Level 2 entry not present at index = %d\n", index); ++ result = 0; ++ } ++ ++ if ( l2e_get_flags(l2e[index]) & _PAGE_PSE ) { /* handle PSE */ ++ NPT_PRINTK("guest page table is PSE\n"); ++ gpa = (l2e_get_intpte(l2e[index]) & PHYSICAL_PAGE_2M_MASK) + ++ (gva & ~PHYSICAL_PAGE_2M_MASK); ++ unmap_domain_page(l2e); ++ break; /* last level page table, jump out from here */ ++ } ++ else { ++ gpfn = l2e_get_pfn(l2e[index]); ++ } ++ unmap_domain_page(l2e); ++ } ++ ++ if ( lev == 1 ) { ++ l1e = map_domain_page( mfn ); ++ if ( !(l1e_get_flags(l1e[index]) & _PAGE_PRESENT) ) { ++ NPT_PRINTK("Level 1 entry not present at index = %d\n", index); ++ result = 0; ++ } ++ gpfn = l1e_get_pfn( l1e[index] ); ++ gpa = (l1e_get_intpte(l1e[index]) & PHYSICAL_PAGE_4K_MASK) + ++ (gva & ~PHYSICAL_PAGE_4K_MASK); ++ unmap_domain_page(l1e); ++ } ++ ++ if ( result != 1 ) /* error happened, jump out */ ++ break; ++ } ++ ++ gpa &= ~PAGE_NX_BIT; /* clear NX bit of guest physical address */ ++ NPT_PRINTK("result = %d, gva = %lx, gpa = %lx\n", result, gva, gpa); ++ return (paddr_t)gpa; ++} ++#else ++static paddr_t npt_gva_to_gpa_pae_mode(struct vcpu *v, unsigned long gva) ++{ ++ HERE_I_AM; ++ printk("guest paging level (3) is greater than host paging level!\n"); ++ domain_crash(v->domain); ++ return 0UL; ++} ++#endif ++ ++/* Translate guest virtual address to guest physical address. Specifically ++ * for 4-level guest. ++ */ ++#if CONFIG_PAGING_LEVELS == 4 ++static paddr_t npt_gva_to_gpa_long_mode(struct vcpu *v, unsigned long gva) ++{ ++ unsigned long gcr3 = hvm_get_guest_ctrl_reg(v, 3); ++ int mode = 4; /* four-level guest */ ++ int lev, index; ++ paddr_t gpa = 0; ++ unsigned long gpfn, mfn; ++ int result = 1; ++ l4_pgentry_t *l4e; ++ l3_pgentry_t *l3e; ++ l2_pgentry_t *l2e; ++ l1_pgentry_t *l1e; ++ ++ HERE_I_AM; ++ ++ NPT_PRINTK("npt_gva_to_gpa:mode = %d, gcr3 = 0x%lx, gva = 0x%lx, " ++ "entry size is = %ld\n", mode, gcr3, gva, sizeof(*l4e)); ++ gpfn = (gcr3 >> PAGE_SHIFT); ++ for ( lev = mode; lev >= 1; lev-- ) { ++ mfn = get_mfn_from_gpfn( gpfn ); ++ if ( mfn == INVALID_MFN ) { ++ NPT_PRINTK("bad pfn=0x%lx from gva=0x%lx at lev%d\n", gpfn, gva, ++ lev); ++ result = 0; ++ break; ++ } ++ index = (gva >> PT_SHIFT[mode][lev]) & (PT_ENTRIES[mode][lev]-1); ++ ++ if ( lev == 4 ) { ++ l4e = map_domain_page( mfn ); ++ if ( !(l4e_get_flags(l4e[index]) & _PAGE_PRESENT) ) { ++ NPT_PRINTK("Level 4 entry not present at index = %d\n", index); ++ result = 0; ++ } ++ gpfn = l4e_get_pfn( l4e[index] ); ++ unmap_domain_page(l4e); ++ } ++ ++ if ( lev == 3 ) { ++ l3e = map_domain_page( mfn ); ++ if ( !(l3e_get_flags(l3e[index]) & _PAGE_PRESENT) ) { ++ NPT_PRINTK("Level 3 entry not present at index = %d\n", index); ++ result = 0; ++ } ++ gpfn = l3e_get_pfn( l3e[index] ); ++ unmap_domain_page(l3e); ++ } ++ ++ if ( lev == 2 ) { ++ l2e = map_domain_page( mfn ); ++ if ( !(l2e_get_flags(l2e[index]) & _PAGE_PRESENT) ) { ++ NPT_PRINTK("Level 2 entry not present at index = %d\n", index); ++ result = 0; ++ } ++ ++ if ( l2e_get_flags(l2e[index]) & _PAGE_PSE ) { /* handle PSE */ ++ NPT_PRINTK("guest page table is PSE\n"); ++ gpa = (l2e_get_intpte(l2e[index]) & PHYSICAL_PAGE_2M_MASK) + ++ (gva & ~PHYSICAL_PAGE_2M_MASK); ++ unmap_domain_page(l2e); ++ break; /* last level page table, jump out from here */ ++ } ++ else { ++ gpfn = l2e_get_pfn(l2e[index]); ++ } ++ unmap_domain_page(l2e); ++ } ++ ++ if ( lev == 1 ) { ++ l1e = map_domain_page( mfn ); ++ if ( !(l1e_get_flags(l1e[index]) & _PAGE_PRESENT) ) { ++ NPT_PRINTK("Level 1 entry not present at index = %d\n", index); ++ result = 0; ++ } ++ gpfn = l1e_get_pfn( l1e[index] ); ++ gpa = (l1e_get_intpte(l1e[index]) & PHYSICAL_PAGE_4K_MASK) + ++ (gva & ~PHYSICAL_PAGE_4K_MASK); ++ unmap_domain_page(l1e); ++ } ++ ++ if ( result != 1 ) /* error happened, jump out */ ++ break; ++ } ++ ++ gpa &= ~PAGE_NX_BIT; /* clear NX bit of guest physical address */ ++ NPT_PRINTK("result = %d, gva = %lx, gpa = %lx\n", result, gva, gpa); ++ return (paddr_t)gpa; ++} ++#else ++static paddr_t npt_gva_to_gpa_long_mode(struct vcpu *v, unsigned long gva) ++{ ++ HERE_I_AM; ++ printk("guest paging level (4) is greater than host paging level!\n"); ++ domain_crash(v->domain); ++ return 0UL; ++} ++#endif ++ ++static unsigned long ++npt_gva_to_gfn_real_mode(struct vcpu *v, unsigned long gva) ++{ ++ return (npt_gva_to_gpa_real_mode(v, gva) >> PAGE_SHIFT); ++} ++ ++static unsigned long ++npt_gva_to_gfn_protected_mode(struct vcpu *v, unsigned long gva) ++{ ++ return (npt_gva_to_gpa_protected_mode(v, gva) >> PAGE_SHIFT); ++} ++ ++static unsigned long ++npt_gva_to_gfn_pae_mode(struct vcpu *v, unsigned long gva) ++{ ++ return (npt_gva_to_gpa_pae_mode(v, gva) >> PAGE_SHIFT); ++} ++ ++static unsigned long ++npt_gva_to_gfn_long_mode(struct vcpu *v, unsigned long gva) ++{ ++ return (npt_gva_to_gpa_long_mode(v, gva) >> PAGE_SHIFT); ++} ++ ++/********************************************/ ++/* AMD NPT Platform Specific Functions */ ++/********************************************/ ++void npt_detect(void) ++{ ++ u32 eax, ebx, ecx, edx; ++ ++ /* check CPUID for nested paging support */ ++ cpuid(0x8000000A, &eax, &ebx, &ecx, &edx); ++ if ( !(edx & 0x01) && opt_hap_enabled ) { ++ printk(" nested paging is not supported by this CPU.\n"); ++ opt_hap_enabled = 0; /* no nested paging, we disable op_hap_enabled */ ++ } ++} ++ ++/*******************************************/ ++/* Public Interface to Xen */ ++/*******************************************/ ++ ++void npt_set_guest_paging_levels(struct vcpu *v, int levels) ++{ ++ HERE_I_AM; ++ switch(levels) { ++ case 1: ++ NPT_PRINTK("Install real mode guest with ID = %d\n", v->vcpu_id); ++ v->arch.shadow.mode->gva_to_gpa = &npt_gva_to_gpa_real_mode; ++ v->arch.shadow.mode->gva_to_gfn = &npt_gva_to_gfn_real_mode; ++ break; ++ case 2: ++ NPT_PRINTK("Install 32-bit non-PAE guest with ID = %d\n", v->vcpu_id); ++ v->arch.shadow.mode->gva_to_gpa = &npt_gva_to_gpa_protected_mode; ++ v->arch.shadow.mode->gva_to_gfn = &npt_gva_to_gfn_protected_mode; ++ break; ++ case 3: ++ NPT_PRINTK("Install 32-bit PAE guest with ID = %d\n", v->vcpu_id); ++ v->arch.shadow.mode->gva_to_gpa = &npt_gva_to_gpa_pae_mode; ++ v->arch.shadow.mode->gva_to_gfn = &npt_gva_to_gfn_pae_mode; ++ break; ++ case 4: ++ NPT_PRINTK("Install 64-bit guest with ID = %d\n", v->vcpu_id); ++ v->arch.shadow.mode->gva_to_gpa = &npt_gva_to_gpa_long_mode; ++ v->arch.shadow.mode->gva_to_gfn = &npt_gva_to_gfn_long_mode; ++ break; ++ default: ++ printk("Un-supported guest paging level: %d\n", levels); ++ domain_crash(v->domain); ++ break; ++ } ++} ++ ++/* dom_init_npt: initialize the resources of nested paging support ++ * return 1 when successful, return 0 when fail ++ */ ++ ++int dom_init_npt(struct domain *d) ++{ ++ u32 eax, ebx, ecx, edx; ++ ++ HERE_I_AM; ++ ++ /* check CPUID for nested paging support first */ ++ cpuid(0x8000000A, &eax, &ebx, &ecx, &edx); ++ if ( !(edx & 0x01) ) { ++ printk("AMD nested paging is not supported ..."); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++/* reclaim the resource */ ++void dom_destroy_npt(struct domain *d) ++{ ++ HERE_I_AM; ++ NPT_PRINTK("dom_destroy_npt() done!\n"); ++} ++ ++/* This method update the guest paging mode based on guest's accesses (both ++ * read and write) to CR registers, as well as to EFER registers. It also ++ * installs corresponding guest handler based on guest' paging levels. ++ */ ++void npt_update_guest_paging_mode(struct vcpu *v) ++{ ++ struct domain *d = v->domain; ++ struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; ++ u64 cr0_value = vmcb->cr0; ++ u64 cr4_value = vmcb->cr4; ++ u64 efer_value = vmcb->efer; ++ ++ HERE_I_AM; ++ ++ npt_lock(d); ++ ++ if ( (cr0_value & X86_CR0_PE) && (cr0_value & X86_CR0_PG)) { ++ if ( (efer_value & EFER_LME) && (cr4_value & X86_CR4_PAE) ) ++ npt_set_guest_paging_levels(v, PAGING_L4); ++ else if ( cr4_value & X86_CR4_PAE) ++ npt_set_guest_paging_levels(v, PAGING_L3); ++ else ++ npt_set_guest_paging_levels(v, PAGING_L2); ++ } ++ else { ++ NPT_PRINTK("paging is turned off by guests\n"); ++ npt_set_guest_paging_levels(v, PAGING_REAL_MODE); ++ } ++ ++ v->arch.shadow.translate_enabled = !!hvm_paging_enabled(v); ++ ++ npt_unlock(d); ++} ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * tab-width: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ ++ +Index: xen-3.0.4-testing/xen/arch/x86/mm/hap/npt/page-guest32.h +=================================================================== +--- /dev/null ++++ xen-3.0.4-testing/xen/arch/x86/mm/hap/npt/page-guest32.h +@@ -0,0 +1,105 @@ ++ ++#ifndef __X86_PAGE_GUEST_H__ ++#define __X86_PAGE_GUEST_H__ ++ ++#ifndef __ASSEMBLY__ ++# include ++#endif ++ ++#define PAGETABLE_ORDER_32 10 ++#define L1_PAGETABLE_ENTRIES_32 (1<> L1_PAGETABLE_SHIFT_32) & (L1_PAGETABLE_ENTRIES_32 - 1)) ++#define l2_table_offset_32(a) \ ++ (((a) >> L2_PAGETABLE_SHIFT_32) & (L2_PAGETABLE_ENTRIES_32 - 1)) ++ ++#define linear_l1_table_32 \ ++ ((l1_pgentry_32_t *)(LINEAR_PT_VIRT_START)) ++ ++#define linear_pg_table_32 linear_l1_table_32 ++ ++#endif /* __X86_PAGE_GUEST_H__ */ ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * tab-width: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ +Index: xen-3.0.4-testing/xen/arch/x86/mm/hap/npt/private.h +=================================================================== +--- /dev/null ++++ xen-3.0.4-testing/xen/arch/x86/mm/hap/npt/private.h +@@ -0,0 +1,165 @@ ++/* ++ * private.h: SVM Nested Paging Related Defintion ++ * Copyright (c) 2006, Wei Huang, AMD Corporation. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple ++ * Place - Suite 330, Boston, MA 02111-1307 USA. ++ * ++ */ ++#ifndef __NPT_PRIVATE_H__ ++#define __NPT_PRIVATE_H__ ++ ++#include ++#include ++ ++/********************************************/ ++/* NPT Debugging Utilities */ ++/********************************************/ ++#define HERE_I_AM \ ++ debugtrace_printk("HERE I AM: %s %s %d\n", __func__, __FILE__, __LINE__) ++#define NPT_PRINTK(_f, _a...) \ ++ debugtrace_printk("npt: %s(): " _f, __func__, ##_a) ++#define NPT_ERROR(_f, _a...) \ ++ printk("npt error: %s(): " _f, __func__, ##_a) ++#define NPT_DEBUG(flag, _f, _a...) \ ++ do { \ ++ debugtrace_printk("npt debug: %s(): " _f, __func__, ##_a); \ ++ } while (0) ++/********************************************/ ++/* NPT Inline Functions and Tools */ ++/********************************************/ ++#define npt_lock(_d) \ ++ do { \ ++ if ( unlikely((_d)->arch.shadow.locker == current->processor) ) \ ++ { \ ++ printk("Error: shadow lock held by %s\n", \ ++ (_d)->arch.shadow.locker_function); \ ++ BUG(); \ ++ } \ ++ spin_lock(&(_d)->arch.shadow.lock); \ ++ ASSERT((_d)->arch.shadow.locker == -1); \ ++ (_d)->arch.shadow.locker = current->processor; \ ++ (_d)->arch.shadow.locker_function = __func__; \ ++ } while (0) ++ ++#define npt_unlock(_d) \ ++ do { \ ++ ASSERT((_d)->arch.shadow.locker == current->processor); \ ++ (_d)->arch.shadow.locker = -1; \ ++ (_d)->arch.shadow.locker_function = "nobody"; \ ++ spin_unlock(&(_d)->arch.shadow.lock); \ ++ } while (0) ++/********************************************/ ++/* Variable Definition */ ++/********************************************/ ++#define NPT_HOST_PAGE_TABLE_FLAGS (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER) & ~_PAGE_DIRTY & ~_PAGE_ACCESSED ++#define NPT_HOST_PAGE_TABLE_MMIO_FLAGS ( _PAGE_PRESENT ) & ~_PAGE_DIRTY & ~_PAGE_ACCESSED ++#if CONFIG_PAGING_LEVELS == 3 ++#define NPT_HOST_PAGE_TABLE_PDPE_FLAGS _PAGE_PRESENT ++#else ++#define NPT_HOST_PAGE_TABLE_PDPE_FLAGS (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER) & ~_PAGE_DIRTY & ~_PAGE_ACCESSED ++#endif ++ ++#if CONFIG_PAGING_LEVELS == 2 ++#define INIT_NUM_OF_NPT_PAGES 1 ++#elif CONFIG_PAGING_LEVELS == 3 ++#define INIT_NUM_OF_NPT_PAGES 1 + L3_PAGETABLE_ENTRIES ++#elif CONFIG_PAGING_LEVELS == 4 ++#define INIT_NUM_OF_NPT_PAGES 1 ++#endif ++ ++/* The following is the max number of host page table pages required. For most ++ * time, we don't use so much. ++ */ ++#if CONFIG_PAGING_LEVELS == 2 ++#define MAX_NUM_OF_NPT_PAGES 1 + L2_PAGETABLE_ENTRIES ++#elif CONFIG_PAGING_LEVELS == 3 ++#define MAX_NUM_OF_NPT_PAGES 1 + L3_PAGETABLE_ENTRIES * (1 + L2_PAGETABLE_ENTRIES) ++#elif CONFIG_PAGING_LEVELS == 4 ++#define MAX_NUM_OF_NPT_PAGES 1 + L4_PAGETABLE_ENTRIES * (1 + L3_PAGETABLE_ENTRIES * (1 + L2_PAGETABLE_ENTRIES)) ++#endif ++ ++ ++ ++/********************************************/ ++/* MISC DEFINITIONS */ ++/********************************************/ ++ ++/* PT_SHIFT describes the amount by which a virtual address is shifted right ++ * to right justify the portion to be used for indexing into a page ++ * table, given the guest memory model (i.e. number of levels) and the level ++ * of the page table being accessed. The idea is from Virtual Iron's code. ++ */ ++static const int PT_SHIFT[][5] = ++ { /* ------ level ------ nr_levels */ ++ /* 1 2 3 4 */ ++ { 0, 0, 0, 0, 0}, /* 0 not used */ ++ { 0, 0, 0, 0, 0}, /* 1 not used */ ++ { 0, 12, 22, 0, 0}, /* 2 */ ++ { 0, 12, 21, 30, 0}, /* 3 */ ++ { 0, 12, 21, 30, 39} /* 4 */ ++ }; ++ ++/* PT_ENTRIES describes the number of entries in a page table, given the ++ * memory model (i.e. number of levels) and the level of the page table ++ * being considered. This idea from Virtual Iron's shadow code*/ ++static const int PT_ENTRIES[][5] = ++ { /* ------ level ------ nr_levels */ ++ /* 1 2 3 4 */ ++ { 0, 0, 0, 0, 0}, /* 0 not used */ ++ { 0, 0, 0, 0, 0}, /* 1 not used */ ++ { 0, 1024, 1024, 0, 0}, /* 2 */ ++ { 0, 512, 512, 4, 0}, /* 3 */ ++ { 0, 512, 512, 512, 512} /* 4 */ ++ }; ++ ++/********************************************/ ++/* PAGING DEFINITION FOR GUEST */ ++/********************************************/ ++#define PHYSICAL_PAGE_4K_SIZE (1UL << 12) ++#define PHYSICAL_PAGE_2M_SIZE (1UL << 21) ++#define PHYSICAL_PAGE_4M_SIZE (1UL << 22) ++#define PHYSICAL_PAGE_4K_MASK ( ~(PHYSICAL_PAGE_4K_SIZE - 1) ) ++#define PHYSICAL_PAGE_2M_MASK ( ~(PHYSICAL_PAGE_2M_SIZE - 1) ) ++#define PHYSICAL_PAGE_4M_MASK ( ~(PHYSICAL_PAGE_4M_SIZE - 1) ) ++#define NPT_GUEST_CR3_SHIFT_NON_PAE 12 /* both legacy mode and long mode */ ++#define NPT_GUEST_CR3_SHIFT_PAE 5 /* PAE mode */ ++ ++#define PAGING_REAL_MODE 1 ++#define PAGING_L2 2 ++#define PAGING_L3 3 ++#define PAGING_L4 4 ++ ++#define PAGE_NX_BIT (1ULL << 63) ++/********************************************/ ++/* MISC. DDFINITIONS */ ++/********************************************/ ++#if CONFIG_PAGING_LEVELS == 2 ++#define NPT_PRI_LONG "08x" ++#define NPT_PRI_ULONG "08ux" ++#else /* CONFIG_PAGING_LEVELS >= 3 */ ++#ifndef __x86_64__ ++#define SH_PRI_LONG "016llx" ++#define NPT_PRI_ULONG "016llux" ++#else ++#define SH_PRI_LONG "016lx" ++#define NPT_PRI_ULONG "016lux" ++#endif ++#endif ++ ++#if CONFIG_PAGING_LEVELS == 2 ++#define NPT_MAX_ORDER 0 /* Only ever need 4k allocations */ ++#else ++#define NPT_MAX_ORDER 2 /* Need up to 16k allocs for 32-bit on PAE/64 */ ++#endif ++#endif /* __SVM_NPT_H__ */ +Index: xen-3.0.4-testing/xen/include/asm-x86/hap.h +=================================================================== +--- /dev/null ++++ xen-3.0.4-testing/xen/include/asm-x86/hap.h +@@ -0,0 +1,56 @@ ++/****************************************************************************** ++ * include/asm-x86/hap.h ++ * hardware assisted paging support ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#ifndef _HAP_H_ ++#define _HAP_H_ ++ ++#include ++#include ++#include ++#include ++#include ++ ++static inline unsigned int hap_is_activated(struct vcpu *v) ++{ ++ return v->arch.hap_activated; ++} ++ ++static inline void hap_activate(struct vcpu *v) ++{ ++ v->arch.hap_activated = 1; ++} ++ ++static inline void hap_deactivate(struct vcpu *v) ++{ ++ v->arch.hap_activated = 0; ++} ++ ++void npt_update_guest_paging_mode(struct vcpu *v); ++void npt_detect(void); ++#endif ++ ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ diff --git a/npt_part2.patch b/npt_part2.patch new file mode 100644 index 0000000..9222727 --- /dev/null +++ b/npt_part2.patch @@ -0,0 +1,13 @@ +Index: xen-3.0.4-testing/xen/arch/x86/mm/shadow/common.c +=================================================================== +--- xen-3.0.4-testing.orig/xen/arch/x86/mm/shadow/common.c ++++ xen-3.0.4-testing/xen/arch/x86/mm/shadow/common.c +@@ -1163,6 +1163,8 @@ p2m_next_level(struct domain *d, mfn_t * + if (type == PGT_l2_page_table) + { + struct vcpu *v; ++ /* for PAE mode, PDPE only have PCD/PWT/P bits available */ ++ *p2m_entry = l1e_from_pfn(mfn_x(mfn), _PAGE_PRESENT); + /* We have written to the p2m l3: need to sync the per-vcpu + * copies of it in the monitor tables */ + p2m_install_entry_in_monitors(d, (l3_pgentry_t *)p2m_entry); diff --git a/pae-guest-linear-pgtable.patch b/pae-guest-linear-pgtable.patch new file mode 100644 index 0000000..438ebb3 --- /dev/null +++ b/pae-guest-linear-pgtable.patch @@ -0,0 +1,83 @@ +Index: 2007-01-31/xen/arch/x86/mm.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/mm.c 2007-01-31 09:43:38.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/mm.c 2007-02-02 16:34:03.000000000 +0100 +@@ -509,7 +509,7 @@ get_linear_pagetable( + return 0; + + /* +- * Make sure that the mapped frame is an already-validated L2 table. ++ * Make sure that the mapped frame is an already-validated root table. + * If so, atomically increment the count (checking for overflow). + */ + page = mfn_to_page(pfn); +@@ -531,6 +531,51 @@ get_linear_pagetable( + } + #endif /* !CONFIG_X86_PAE */ + ++#if defined(CONFIG_X86_PAE) || defined(CONFIG_X86_64) ++static int ++get_l2_linear_pagetable( ++ l2_pgentry_t l2e, unsigned long l2e_pfn, struct domain *d) ++{ ++ unsigned long pfn; ++ ++ if ( (l2e_get_flags(l2e) & _PAGE_RW) ) ++ { ++ MEM_LOG("Attempt to create linear p.t. with write perms"); ++ return 0; ++ } ++ ++ if ( (pfn = l2e_get_pfn(l2e)) != l2e_pfn ) ++ { ++ unsigned long x, y; ++ struct page_info *page; ++ ++ /* Make sure the mapped frame belongs to the correct domain. */ ++ if ( unlikely(!get_page_from_pagenr(pfn, d)) ) ++ return 0; ++ ++ /* ++ * Make sure that the mapped frame is an already-validated L2 table. ++ * If so, atomically increment the count (checking for overflow). ++ */ ++ page = mfn_to_page(pfn); ++ y = page->u.inuse.type_info; ++ do { ++ x = y; ++ if ( unlikely((x & PGT_count_mask) == PGT_count_mask) || ++ unlikely((x & (PGT_type_mask|PGT_validated)) != ++ (PGT_l2_page_table|PGT_validated)) ) ++ { ++ put_page(page); ++ return 0; ++ } ++ } ++ while ( (y = cmpxchg(&page->u.inuse.type_info, x, x + 1)) != x ); ++ } ++ ++ return 1; ++} ++#endif /* !CONFIG_X86_PAE */ ++ + int + get_page_from_l1e( + l1_pgentry_t l1e, struct domain *d) +@@ -607,10 +652,16 @@ get_page_from_l2e( + } + + rc = get_page_and_type_from_pagenr(l2e_get_pfn(l2e), PGT_l1_page_table, d); +-#if CONFIG_PAGING_LEVELS == 2 + if ( unlikely(!rc) ) ++ { ++#if CONFIG_PAGING_LEVELS == 2 + rc = get_linear_pagetable(l2e, pfn, d); ++#else ++ if ( (CONFIG_PAGING_LEVELS == 3 || IS_COMPAT(d)) ) ++ rc = get_l2_linear_pagetable(l2e, pfn, d); + #endif ++ } ++ + return rc; + } + diff --git a/protocol-bimodal.diff b/protocol-bimodal.diff new file mode 100644 index 0000000..411a9de --- /dev/null +++ b/protocol-bimodal.diff @@ -0,0 +1,35 @@ +bimodal: header file with protocol names. + +This patch adds a header file with the protocol names. + +Signed-off-by: Gerd Hoffmann +--- + xen/include/public/io/protocols.h | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +Index: build-32-unstable-13495/xen/include/public/io/protocols.h +=================================================================== +--- /dev/null ++++ build-32-unstable-13495/xen/include/public/io/protocols.h +@@ -0,0 +1,21 @@ ++#ifndef __XEN_PROTOCOLS_H__ ++#define __XEN_PROTOCOLS_H__ ++ ++#define XEN_IO_PROTO_ABI_X86_32 "x86_32-abi" ++#define XEN_IO_PROTO_ABI_X86_64 "x86_64-abi" ++#define XEN_IO_PROTO_ABI_IA64 "ia64-abi" ++#define XEN_IO_PROTO_ABI_POWERPC64 "powerpc64-abi" ++ ++#if defined(__i386__) ++# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_32 ++#elif defined(__x86_64__) ++# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_64 ++#elif defined(__ia64__) ++# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_IA64 ++#elif defined(__powerpc64__) ++# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_POWERPC64 ++#else ++# error arch fixup needed here ++#endif ++ ++#endif diff --git a/pv-driver-build.patch b/pv-driver-build.patch new file mode 100644 index 0000000..b38a96d --- /dev/null +++ b/pv-driver-build.patch @@ -0,0 +1,101 @@ +Index: 2007-01-19/unmodified_drivers/linux-2.6/mkbuildtree +=================================================================== +--- 2007-01-19.orig/unmodified_drivers/linux-2.6/mkbuildtree 2006-12-14 22:49:58.000000000 +0100 ++++ 2007-01-19/unmodified_drivers/linux-2.6/mkbuildtree 2007-01-24 14:48:33.000000000 +0100 +@@ -8,10 +8,12 @@ else + echo "This may be overridden on the command line (i386,x86_64,ia64)." + fi + +-C=$PWD +- +-XEN=$C/../../xen +-XL=$C/../../linux-2.6-xen-sparse ++if [ -n "$XL" -a -d "$XL" ]; then ++ XL=$(cd $XL && pwd) ++else ++ XL=/usr/src/linux ++fi ++cd "$(dirname "$0")" + + for d in $(find ${XL}/drivers/xen/ -maxdepth 1 -type d | sed -e 1d); do + if ! echo $d | egrep -q back; then +@@ -24,14 +26,9 @@ ln -sf ${XL}/drivers/xen/core/features.c + ln -sf ${XL}/drivers/xen/core/xen_proc.c xenbus + ln -sf ${XL}/drivers/xen/core/reboot.c util + +-mkdir -p include +-mkdir -p include/xen +-mkdir -p include/public +-mkdir -p include/asm +-mkdir -p include/asm/xen ++mkdir -p include/asm include/xen + + lndir -silent ${XL}/include/xen include/xen +-ln -nsf ${XEN}/include/public include/xen/interface + + # Need to be quite careful here: we don't want the files we link in to + # risk overriding the native Linux ones (in particular, system.h must +@@ -43,7 +40,8 @@ in + ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/hypercall.h include/asm + ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/synch_bitops.h include/asm + ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/maddr.h include/asm +- ln -sf ${XL}/include/asm-i386 include/asm-i386 ++ mkdir include/asm-i386 ++ lndir -silent ${XL}/include/asm-i386 include/asm-i386 + ;; + i[34567]86) + ln -sf ${XL}/include/asm-i386/mach-xen/asm/hypervisor.h include/asm +@@ -56,6 +54,7 @@ i[34567]86) + ln -sf ${XL}/include/asm-ia64/hypercall.h include/asm + ln -sf ${XL}/include/asm-ia64/synch_bitops.h include/asm + ln -sf ${XL}/include/asm-ia64/maddr.h include/asm ++ mkdir include/asm/xen + ln -sf ${XL}/include/asm-ia64/xen/xcom_hcall.h include/asm/xen + ln -sf ${XL}/include/asm-ia64/xen/xencomm.h include/asm/xen + ln -sf ${XL}/arch/ia64/xen/xcom_mini.c platform-pci +Index: 2007-01-19/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h +=================================================================== +--- 2007-01-19.orig/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h 2006-12-14 22:49:58.000000000 +0100 ++++ 2007-01-19/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h 2007-01-26 10:44:53.000000000 +0100 +@@ -69,4 +69,12 @@ extern char *kasprintf(gfp_t gfp, const + __attribute__ ((format (printf, 2, 3))); + #endif + ++/* ++ * This variable at present is referenced by netfront, but only in code that ++ * is dead when running in hvm guests. To detect potential active uses of it ++ * in the future, don't try to supply a 'valid' value here, so that any ++ * mappings created with it will fault when accessed. ++ */ ++#define __supported_pte_mask ((maddr_t)0) ++ + #endif +Index: 2007-01-19/unmodified_drivers/linux-2.6/overrides.mk +=================================================================== +--- 2007-01-19.orig/unmodified_drivers/linux-2.6/overrides.mk 2006-12-14 22:49:58.000000000 +0100 ++++ 2007-01-19/unmodified_drivers/linux-2.6/overrides.mk 2007-01-23 13:19:27.000000000 +0100 +@@ -4,9 +4,5 @@ + # + # (i.e. we need the native config for things like -mregparm, but + # a Xen kernel to find the right headers) +-EXTRA_CFLAGS += -DCONFIG_VMX -DCONFIG_VMX_GUEST -DCONFIG_X86_XEN +-EXTRA_CFLAGS += -DCONFIG_XEN_SHADOW_MODE -DCONFIG_XEN_SHADOW_TRANSLATE +-EXTRA_CFLAGS += -DCONFIG_XEN_BLKDEV_GRANT -DXEN_EVTCHN_MASK_OPS +-EXTRA_CFLAGS += -DCONFIG_XEN_NETDEV_GRANT_RX -DCONFIG_XEN_NETDEV_GRANT_TX + EXTRA_CFLAGS += -D__XEN_INTERFACE_VERSION__=0x00030202 + EXTRA_CFLAGS += -I$(M)/include -I$(M)/compat-include -DHAVE_XEN_PLATFORM_COMPAT_H +Index: 2007-01-19/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c +=================================================================== +--- 2007-01-19.orig/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c 2006-12-14 22:49:58.000000000 +0100 ++++ 2007-01-19/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c 2007-01-23 12:54:45.000000000 +0100 +@@ -115,7 +115,9 @@ void *kzalloc(size_t size, int flags) + EXPORT_SYMBOL(kzalloc); + #endif + +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) ++#if defined(CONFIG_SUSE_KERNEL) \ ++ ? LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) \ ++ : LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) + /* Simplified asprintf. */ + char *kasprintf(gfp_t gfp, const char *fmt, ...) + { diff --git a/serial-split.patch b/serial-split.patch index a33d4c9..27fc341 100644 --- a/serial-split.patch +++ b/serial-split.patch @@ -1,7 +1,7 @@ -Index: xen-3.0-testing/tools/misc/serial-split/Makefile +Index: xen-3.0.4-testing/tools/misc/serial-split/Makefile =================================================================== --- /dev/null -+++ xen-3.0-testing/tools/misc/serial-split/Makefile ++++ xen-3.0.4-testing/tools/misc/serial-split/Makefile @@ -0,0 +1,20 @@ +CC ?= gcc +CFLAGS ?= -Wall -Os @@ -23,10 +23,10 @@ Index: xen-3.0-testing/tools/misc/serial-split/Makefile + +%.o: %.c Makefile + $(CC) $(CFLAGS) -c -o $@ $< -Index: xen-3.0-testing/tools/misc/serial-split/serial-split.c +Index: xen-3.0.4-testing/tools/misc/serial-split/serial-split.c =================================================================== --- /dev/null -+++ xen-3.0-testing/tools/misc/serial-split/serial-split.c ++++ xen-3.0.4-testing/tools/misc/serial-split/serial-split.c @@ -0,0 +1,422 @@ +/* + * serial-split.c diff --git a/suppress-rdtscp.patch b/suppress-rdtscp.patch new file mode 100644 index 0000000..3ffea38 --- /dev/null +++ b/suppress-rdtscp.patch @@ -0,0 +1,28 @@ +Index: 2007-01-31/xen/arch/x86/traps.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/traps.c 2007-01-31 09:42:07.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/traps.c 2007-02-07 17:03:20.000000000 +0100 +@@ -613,6 +613,11 @@ static int emulate_forced_invalid_op(str + if ( !IS_PRIV(current->domain) ) + clear_bit(X86_FEATURE_MTRR, &d); + } ++ else if ( regs->eax == 0x80000001 ) ++ { ++ /* Modify Feature Information. */ ++ clear_bit(X86_FEATURE_RDTSCP % 32, &d); ++ } + else + { + (void)cpuid_hypervisor_leaves(regs->eax, &a, &b, &c, &d); +Index: 2007-01-31/xen/include/asm-x86/cpufeature.h +=================================================================== +--- 2007-01-31.orig/xen/include/asm-x86/cpufeature.h 2007-01-31 09:28:56.000000000 +0100 ++++ 2007-01-31/xen/include/asm-x86/cpufeature.h 2007-02-07 17:03:20.000000000 +0100 +@@ -49,6 +49,7 @@ + #define X86_FEATURE_MP (1*32+19) /* MP Capable. */ + #define X86_FEATURE_NX (1*32+20) /* Execute Disable */ + #define X86_FEATURE_MMXEXT (1*32+22) /* AMD MMX extensions */ ++#define X86_FEATURE_RDTSCP (1*32+27) /* RDTSCP */ + #define X86_FEATURE_LM (1*32+29) /* Long Mode (x86-64) */ + #define X86_FEATURE_3DNOWEXT (1*32+30) /* AMD 3DNow! extensions */ + #define X86_FEATURE_3DNOW (1*32+31) /* 3DNow! */ diff --git a/svm-update-v_tpr-on-mmio.patch b/svm-update-v_tpr-on-mmio.patch new file mode 100644 index 0000000..4a27524 --- /dev/null +++ b/svm-update-v_tpr-on-mmio.patch @@ -0,0 +1,116 @@ +# HG changeset patch +# User Travis Betak +# Date 1168370530 21600 +# Node ID e822926dd62492282e51c5847a8d85a3d22dda1d +# Parent d401cb96d8a0da5febe737b86f453a88f1f45bb7 +[HVM][SVM] Updated the SVM V_TPR register on MMIO writes to the VLAPIC TPR + +The SVM architecture includes a virtual TPR register. This patch +updates this register on MMIO writes to the HVM Virtual APIC. + +VT does not have this register as far as I know so a stub is added in +the VT code. + +Signed-off-by: Travis Betak + +Index: xen-3.0.4-testing/xen/arch/x86/hvm/svm/svm.c +=================================================================== +--- xen-3.0.4-testing.orig/xen/arch/x86/hvm/svm/svm.c ++++ xen-3.0.4-testing/xen/arch/x86/hvm/svm/svm.c +@@ -503,6 +503,13 @@ void svm_update_guest_cr3(struct vcpu *v + v->arch.hvm_svm.vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3; + } + ++static void svm_update_vtpr(struct vcpu *v, unsigned long value) ++{ ++ struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; ++ ++ vmcb->vintr.fields.tpr = value & 0x0f; ++} ++ + unsigned long svm_get_ctrl_reg(struct vcpu *v, unsigned int num) + { + switch ( num ) +@@ -894,6 +901,8 @@ int start_svm(void) + hvm_funcs.update_host_cr3 = svm_update_host_cr3; + hvm_funcs.update_guest_cr3 = svm_update_guest_cr3; + ++ hvm_funcs.update_vtpr = svm_update_vtpr; ++ + hvm_funcs.stts = svm_stts; + hvm_funcs.set_tsc_offset = svm_set_tsc_offset; + +@@ -1956,6 +1965,7 @@ static int mov_to_cr(int gpreg, int cr, + + case 8: + vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4)); ++ vmcb->vintr.fields.tpr = value & 0x0F; + break; + + default: +Index: xen-3.0.4-testing/xen/arch/x86/hvm/vlapic.c +=================================================================== +--- xen-3.0.4-testing.orig/xen/arch/x86/hvm/vlapic.c ++++ xen-3.0.4-testing/xen/arch/x86/hvm/vlapic.c +@@ -631,6 +631,7 @@ static void vlapic_write(struct vcpu *v, + { + case APIC_TASKPRI: + vlapic_set_reg(vlapic, APIC_TASKPRI, val & 0xff); ++ hvm_update_vtpr(v, (val >> 4) & 0x0f); + break; + + case APIC_EOI: +Index: xen-3.0.4-testing/xen/arch/x86/hvm/vmx/vmx.c +=================================================================== +--- xen-3.0.4-testing.orig/xen/arch/x86/hvm/vmx/vmx.c ++++ xen-3.0.4-testing/xen/arch/x86/hvm/vmx/vmx.c +@@ -738,6 +738,11 @@ static void vmx_inject_exception( + v->arch.hvm_vmx.cpu_cr2 = cr2; + } + ++static void vmx_update_vtpr(struct vcpu *v, unsigned long value) ++{ ++ /* VMX doesn't have a V_TPR field */ ++} ++ + /* Setup HVM interfaces */ + static void vmx_setup_hvm_funcs(void) + { +@@ -763,6 +768,8 @@ static void vmx_setup_hvm_funcs(void) + hvm_funcs.update_host_cr3 = vmx_update_host_cr3; + hvm_funcs.update_guest_cr3 = vmx_update_guest_cr3; + ++ hvm_funcs.update_vtpr = vmx_update_vtpr; ++ + hvm_funcs.stts = vmx_stts; + hvm_funcs.set_tsc_offset = vmx_set_tsc_offset; + +Index: xen-3.0.4-testing/xen/include/asm-x86/hvm/hvm.h +=================================================================== +--- xen-3.0.4-testing.orig/xen/include/asm-x86/hvm/hvm.h ++++ xen-3.0.4-testing/xen/include/asm-x86/hvm/hvm.h +@@ -108,6 +108,11 @@ struct hvm_function_table { + void (*update_guest_cr3)(struct vcpu *v); + + /* ++ * Reflect the virtual APIC's value in the guest's V_TPR register ++ */ ++ void (*update_vtpr)(struct vcpu *v, unsigned long value); ++ ++ /* + * Update specifics of the guest state: + * 1) TS bit in guest cr0 + * 2) TSC offset in guest +@@ -193,6 +198,12 @@ hvm_update_host_cr3(struct vcpu *v) + hvm_funcs.update_host_cr3(v); + } + ++static inline void ++hvm_update_vtpr(struct vcpu *v, unsigned long value) ++{ ++ hvm_funcs.update_vtpr(v, value); ++} ++ + void hvm_update_guest_cr3(struct vcpu *v, unsigned long guest_cr3); + + void hvm_hypercall_page_initialise(struct domain *d, diff --git a/svm_cpuid_ffxsr_13743.patch b/svm_cpuid_ffxsr_13743.patch new file mode 100644 index 0000000..efac3e4 --- /dev/null +++ b/svm_cpuid_ffxsr_13743.patch @@ -0,0 +1,25 @@ +Index: xen-3.0.4-testing/xen/arch/x86/hvm/svm/svm.c +=================================================================== +--- xen-3.0.4-testing.orig/xen/arch/x86/hvm/svm/svm.c ++++ xen-3.0.4-testing/xen/arch/x86/hvm/svm/svm.c +@@ -1085,6 +1085,8 @@ static void svm_vmexit_do_cpuid(struct v + /* So far, we do not support 3DNow for the guest. */ + clear_bit(X86_FEATURE_3DNOW & 31, &edx); + clear_bit(X86_FEATURE_3DNOWEXT & 31, &edx); ++ /* no FFXSR instructions feature. */ ++ clear_bit(X86_FEATURE_FFXSR & 31, &edx); + } + } + else if ( ( input == 0x80000007 ) || ( input == 0x8000000A ) ) +Index: xen-3.0.4-testing/xen/include/asm-x86/cpufeature.h +=================================================================== +--- xen-3.0.4-testing.orig/xen/include/asm-x86/cpufeature.h ++++ xen-3.0.4-testing/xen/include/asm-x86/cpufeature.h +@@ -92,6 +92,7 @@ + #define X86_FEATURE_LAHF_LM (6*32+ 0) /* LAHF/SAHF in long mode */ + #define X86_FEATURE_CMP_LEGACY (6*32+ 1) /* If yes HyperThreading not valid */ + #define X86_FEATURE_SVME (6*32+ 2) /* Secure Virtual Machine */ ++#define X86_FEATURE_FFXSR (6*32+25) /* FFXSR instruction optimizations */ + + #define cpu_has(c, bit) test_bit(bit, (c)->x86_capability) + #define boot_cpu_has(bit) test_bit(bit, boot_cpu_data.x86_capability) diff --git a/tools-add-errors.diff b/tools-add-errors.diff new file mode 100644 index 0000000..c6f9bd1 --- /dev/null +++ b/tools-add-errors.diff @@ -0,0 +1,41 @@ +Add more xc_error_code values. + +XC_INVALID_PARAM + such as asking for features unsupported by either xen or guest kernel. +XC_OUT_OF_MEMORY + no comment ;) + +Signed-off-by: Gerd Hoffmann +--- + tools/libxc/xc_private.c | 4 ++++ + tools/libxc/xenctrl.h | 2 ++ + 2 files changed, 6 insertions(+) + +Index: build-32-unstable-12809/tools/libxc/xenctrl.h +=================================================================== +--- build-32-unstable-12809.orig/tools/libxc/xenctrl.h ++++ build-32-unstable-12809/tools/libxc/xenctrl.h +@@ -691,6 +691,8 @@ typedef enum { + XC_ERROR_NONE = 0, + XC_INTERNAL_ERROR = 1, + XC_INVALID_KERNEL = 2, ++ XC_INVALID_PARAM = 3, ++ XC_OUT_OF_MEMORY = 4, + } xc_error_code; + + #define XC_MAX_ERROR_MSG_LEN 1024 +Index: build-32-unstable-12809/tools/libxc/xc_private.c +=================================================================== +--- build-32-unstable-12809.orig/tools/libxc/xc_private.c ++++ build-32-unstable-12809/tools/libxc/xc_private.c +@@ -45,6 +45,10 @@ const char *xc_error_code_to_desc(int co + return "Internal error"; + case XC_INVALID_KERNEL: + return "Invalid kernel"; ++ case XC_INVALID_PARAM: ++ return "Invalid configuration"; ++ case XC_OUT_OF_MEMORY: ++ return "Out of memory"; + } + + return "Unknown error code"; diff --git a/tools-debug-oldbuilder.diff b/tools-debug-oldbuilder.diff new file mode 100644 index 0000000..176376c --- /dev/null +++ b/tools-debug-oldbuilder.diff @@ -0,0 +1,238 @@ +debug: compile old domain builder too. + +Compile both old and new domain builder into the tools, so both +are available and can be selected at runtime. Nice for a quick +check when things go wrong, to see if the new domain builder is +incompatible with the old one or whenever something else broke. + +Activate with "builder=old" in the config file or as option for +the "xm create" command + +--- + tools/libxc/Makefile | 4 +-- + tools/libxc/xc_linux_build.c | 4 +-- + tools/libxc/xenguest.h | 28 +++++++++++++++++++++ + tools/python/xen/lowlevel/xc/xc.c | 50 +++++++++++++++++++++++++++++++++++++- + tools/python/xen/xend/image.py | 40 ++++++++++++++++++++++++++++++ + 5 files changed, 121 insertions(+), 5 deletions(-) + +Index: build-32-release304-13087/tools/libxc/Makefile +=================================================================== +--- build-32-release304-13087.orig/tools/libxc/Makefile ++++ build-32-release304-13087/tools/libxc/Makefile +@@ -24,8 +24,8 @@ GUEST_SRCS-y := + GUEST_SRCS-y += xc_load_bin.c + GUEST_SRCS-y += xc_load_elf.c + GUEST_SRCS-y += xg_private.c +-#GUEST_SRCS-$(CONFIG_X86) += xc_linux_build.c +-#GUEST_SRCS-$(CONFIG_IA64) += xc_linux_build.c ++GUEST_SRCS-$(CONFIG_X86) += xc_linux_build.c ++GUEST_SRCS-$(CONFIG_IA64) += xc_linux_build.c + GUEST_SRCS-$(CONFIG_MIGRATE) += xc_linux_restore.c xc_linux_save.c + GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c + +Index: build-32-release304-13087/tools/libxc/xc_linux_build.c +=================================================================== +--- build-32-release304-13087.orig/tools/libxc/xc_linux_build.c ++++ build-32-release304-13087/tools/libxc/xc_linux_build.c +@@ -1185,7 +1185,7 @@ static int xc_linux_build_internal(int x + return -1; + } + +-int xc_linux_build_mem(int xc_handle, ++int old_xc_linux_build_mem(int xc_handle, + uint32_t domid, + unsigned int mem_mb, + const char *image_buffer, +@@ -1254,7 +1254,7 @@ int xc_linux_build_mem(int xc_handle, + return sts; + } + +-int xc_linux_build(int xc_handle, ++int old_xc_linux_build(int xc_handle, + uint32_t domid, + unsigned int mem_mb, + const char *image_name, +Index: build-32-release304-13087/tools/libxc/xenguest.h +=================================================================== +--- build-32-release304-13087.orig/tools/libxc/xenguest.h ++++ build-32-release304-13087/tools/libxc/xenguest.h +@@ -59,6 +59,19 @@ int xc_linux_restore(int xc_handle, int + * @parm conole_mfn returned with the mfn of the console page + * @return 0 on success, -1 on failure + */ ++int old_xc_linux_build(int xc_handle, ++ uint32_t domid, ++ unsigned int mem_mb, ++ const char *image_name, ++ const char *ramdisk_name, ++ const char *cmdline, ++ const char *features, ++ unsigned long flags, ++ unsigned int store_evtchn, ++ unsigned long *store_mfn, ++ unsigned int console_evtchn, ++ unsigned long *console_mfn); ++ + int xc_linux_build(int xc_handle, + uint32_t domid, + unsigned int mem_mb, +@@ -91,6 +104,21 @@ int xc_linux_build(int xc_handle, + * @parm conole_mfn returned with the mfn of the console page + * @return 0 on success, -1 on failure + */ ++int old_xc_linux_build_mem(int xc_handle, ++ uint32_t domid, ++ unsigned int mem_mb, ++ const char *image_buffer, ++ unsigned long image_size, ++ const char *initrd_buffer, ++ unsigned long initrd_size, ++ const char *cmdline, ++ const char *features, ++ unsigned long flags, ++ unsigned int store_evtchn, ++ unsigned long *store_mfn, ++ unsigned int console_evtchn, ++ unsigned long *console_mfn); ++ + int xc_linux_build_mem(int xc_handle, + uint32_t domid, + unsigned int mem_mb, +Index: build-32-release304-13087/tools/python/xen/lowlevel/xc/xc.c +=================================================================== +--- build-32-release304-13087.orig/tools/python/xen/lowlevel/xc/xc.c ++++ build-32-release304-13087/tools/python/xen/lowlevel/xc/xc.c +@@ -349,6 +349,43 @@ static PyObject *pyxc_vcpu_getinfo(XcObj + return info_dict; + } + ++static PyObject *pyxc_old_linux_build(XcObject *self, ++ PyObject *args, ++ PyObject *kwds) ++{ ++ uint32_t dom; ++ char *image, *ramdisk = NULL, *cmdline = "", *features = NULL; ++ int flags = 0; ++ int store_evtchn, console_evtchn; ++ unsigned int mem_mb; ++ unsigned long store_mfn = 0; ++ unsigned long console_mfn = 0; ++ ++ static char *kwd_list[] = { "domid", "store_evtchn", "memsize", ++ "console_evtchn", "image", ++ /* optional */ ++ "ramdisk", "cmdline", "flags", ++ "features", NULL }; ++ ++ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssis", kwd_list, ++ &dom, &store_evtchn, &mem_mb, ++ &console_evtchn, &image, ++ /* optional */ ++ &ramdisk, &cmdline, &flags, ++ &features) ) ++ return NULL; ++ ++ if ( old_xc_linux_build(self->xc_handle, dom, mem_mb, image, ++ ramdisk, cmdline, features, flags, ++ store_evtchn, &store_mfn, ++ console_evtchn, &console_mfn) != 0 ) { ++ return pyxc_error_to_exception(); ++ } ++ return Py_BuildValue("{s:i,s:i}", ++ "store_mfn", store_mfn, ++ "console_mfn", console_mfn); ++} ++ + static PyObject *pyxc_linux_build(XcObject *self, + PyObject *args, + PyObject *kwds) +@@ -1093,7 +1130,18 @@ static PyMethodDef pyxc_methods[] = { + " cpumap [int]: Bitmap of CPUs this VCPU can run on\n" + " cpu [int]: CPU that this VCPU is currently bound to\n" }, + +- { "linux_build", ++ { "old_linux_build", ++ (PyCFunction)pyxc_old_linux_build, ++ METH_VARARGS | METH_KEYWORDS, "\n" ++ "Build a new Linux guest OS.\n" ++ " dom [int]: Identifier of domain to build into.\n" ++ " image [str]: Name of kernel image file. May be gzipped.\n" ++ " ramdisk [str, n/a]: Name of ramdisk file, if any.\n" ++ " cmdline [str, n/a]: Kernel parameters, if any.\n\n" ++ " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n" ++ "Returns: [int] 0 on success; -1 on error.\n" }, ++ ++ { "linux_build", + (PyCFunction)pyxc_linux_build, + METH_VARARGS | METH_KEYWORDS, "\n" + "Build a new Linux guest OS.\n" +Index: build-32-release304-13087/tools/python/xen/xend/image.py +=================================================================== +--- build-32-release304-13087.orig/tools/python/xen/xend/image.py ++++ build-32-release304-13087/tools/python/xen/xend/image.py +@@ -181,6 +181,35 @@ class ImageHandler: + pass + + ++class OldLinuxImageHandler(ImageHandler): ++ ++ ostype = "linux" ++ ++ def buildDomain(self): ++ store_evtchn = self.vm.getStorePort() ++ console_evtchn = self.vm.getConsolePort() ++ ++ mem_mb = self.getRequiredInitialReservation() / 1024 ++ ++ log.debug("domid = %d", self.vm.getDomid()) ++ log.debug("memsize = %d", mem_mb) ++ log.debug("image = %s", self.kernel) ++ log.debug("store_evtchn = %d", store_evtchn) ++ log.debug("console_evtchn = %d", console_evtchn) ++ log.debug("cmdline = %s", self.cmdline) ++ log.debug("ramdisk = %s", self.ramdisk) ++ log.debug("vcpus = %d", self.vm.getVCpuCount()) ++ log.debug("features = %s", self.vm.getFeatures()) ++ ++ return xc.old_linux_build(domid = self.vm.getDomid(), ++ memsize = mem_mb, ++ image = self.kernel, ++ store_evtchn = store_evtchn, ++ console_evtchn = console_evtchn, ++ cmdline = self.cmdline, ++ ramdisk = self.ramdisk, ++ features = self.vm.getFeatures()) ++ + class LinuxImageHandler(ImageHandler): + + ostype = "linux" +@@ -625,6 +654,15 @@ class X86_Linux_ImageHandler(LinuxImageH + xc.domain_set_memmap_limit(self.vm.getDomid(), mem_kb) + return LinuxImageHandler.buildDomain(self) + ++class X86_OldLinux_ImageHandler(OldLinuxImageHandler): ++ ++ def buildDomain(self): ++ # set physical mapping limit ++ # add an 8MB slack to balance backend allocations. ++ mem_kb = self.getRequiredInitialReservation() + (8 * 1024) ++ xc.domain_set_memmap_limit(self.vm.getDomid(), mem_kb) ++ return OldLinuxImageHandler.buildDomain(self) ++ + _handlers = { + "powerpc": { + "linux": PPC_LinuxImageHandler, +@@ -632,10 +670,12 @@ _handlers = { + }, + "ia64": { + "linux": LinuxImageHandler, ++ "old": OldLinuxImageHandler, + "hvm": IA64_HVM_ImageHandler, + }, + "x86": { + "linux": X86_Linux_ImageHandler, ++ "old": X86_OldLinux_ImageHandler, + "hvm": X86_HVM_ImageHandler, + }, + } diff --git a/tools-domain-builder-core.diff b/tools-domain-builder-core.diff new file mode 100644 index 0000000..77fd320 --- /dev/null +++ b/tools-domain-builder-core.diff @@ -0,0 +1,3066 @@ +libxc domain builder rewrite, core bits. + +Signed-off-by: Gerd Hoffmann +--- + tools/libxc/Makefile | 14 + tools/libxc/xc_dom.h | 261 +++++++++++++ + tools/libxc/xc_dom_binloader.c | 294 +++++++++++++++ + tools/libxc/xc_dom_boot.c | 592 +++++++++++++++++++++++++++++++ + tools/libxc/xc_dom_core.c | 776 +++++++++++++++++++++++++++++++++++++++++ + tools/libxc/xc_dom_elfloader.c | 283 ++++++++++++++ + tools/libxc/xc_dom_ia64.c | 119 ++++++ + tools/libxc/xc_dom_powerpc64.c | 100 +++++ + tools/libxc/xc_dom_x86.c | 561 +++++++++++++++++++++++++++++ + 9 files changed, 3000 insertions(+) + +Index: build-32-release304-13138/tools/libxc/Makefile +=================================================================== +--- build-32-release304-13138.orig/tools/libxc/Makefile ++++ build-32-release304-13138/tools/libxc/Makefile +@@ -44,6 +44,20 @@ $(LIBELF_SRCS) libelf-private.h: + # add libelf bits to libxc + GUEST_SRCS-y += $(LIBELF_SRCS) + ++# new domain builder ++GUEST_SRCS-y += xc_dom_core.c xc_dom_boot.c ++GUEST_SRCS-y += xc_dom_elfloader.c ++GUEST_SRCS-y += xc_dom_binloader.c ++ ++ifeq ($(CONFIG_POWERPC),y) ++# big endian boxes ++GUEST_SRCS-y += xc_dom_powerpc64.c ++else ++# little endian boxes ++GUEST_SRCS-y += xc_dom_x86.c ++GUEST_SRCS-y += xc_dom_ia64.c ++endif ++ + -include $(XEN_TARGET_ARCH)/Makefile + + CFLAGS += -Werror -Wmissing-prototypes +Index: build-32-release304-13138/tools/libxc/xc_dom.h +=================================================================== +--- /dev/null ++++ build-32-release304-13138/tools/libxc/xc_dom.h +@@ -0,0 +1,261 @@ ++#include ++ ++#define INVALID_P2M_ENTRY ((xen_pfn_t)-1) ++ ++/* --- typedefs and structs ---------------------------------------- */ ++ ++typedef uint64_t xen_vaddr_t; ++typedef uint64_t xen_paddr_t; ++ ++/* FIXME: temporary hack ... */ ++#ifndef PRIpfn ++#define PRIpfn "lx" ++#endif ++ ++struct xc_dom_seg { ++ xen_vaddr_t vstart; ++ xen_vaddr_t vend; ++ xen_pfn_t pfn; ++}; ++ ++struct xc_dom_mem { ++ struct xc_dom_mem *next; ++ void *mmap_ptr; ++ size_t mmap_len; ++ unsigned char memory[0]; ++}; ++ ++struct xc_dom_phys { ++ struct xc_dom_phys *next; ++ void *ptr; ++ xen_pfn_t first; ++ xen_pfn_t count; ++}; ++ ++struct xc_dom_image { ++ /* files */ ++ void *kernel_blob; ++ size_t kernel_size; ++ void *ramdisk_blob; ++ size_t ramdisk_size; ++ ++ /* arguments and parameters */ ++ char *cmdline; ++ uint32_t f_requested[XENFEAT_NR_SUBMAPS]; ++ ++ /* info from (elf) kernel image */ ++ struct elf_dom_parms parms; ++ char *guest_type; ++ ++ /* memory layout */ ++ struct xc_dom_seg kernel_seg; ++ struct xc_dom_seg ramdisk_seg; ++ struct xc_dom_seg p2m_seg; ++ struct xc_dom_seg pgtables_seg; ++ xen_pfn_t start_info_pfn; ++ xen_pfn_t console_pfn; ++ xen_pfn_t xenstore_pfn; ++ xen_pfn_t shared_info_pfn; ++ xen_pfn_t bootstack_pfn; ++ xen_vaddr_t virt_alloc_end; ++ xen_vaddr_t bsd_symtab_start; ++ ++ /* initial page tables */ ++ unsigned int pgtables; ++ unsigned int pg_l4; ++ unsigned int pg_l3; ++ unsigned int pg_l2; ++ unsigned int pg_l1; ++ unsigned int alloc_bootstack; ++ unsigned int extra_pages; ++ xen_vaddr_t virt_pgtab_end; ++ ++ /* other state info */ ++ uint32_t f_active[XENFEAT_NR_SUBMAPS]; ++ xen_pfn_t *p2m_host; ++ void *p2m_guest; ++ ++ /* physical memory */ ++ xen_pfn_t total_pages; ++ struct xc_dom_phys *phys_pages; ++ ++ /* malloc memory pool */ ++ struct xc_dom_mem *memblocks; ++ ++ /* memory footprint stats */ ++ size_t alloc_malloc; ++ size_t alloc_mem_map; ++ size_t alloc_file_map; ++ size_t alloc_domU_map; ++ ++ /* misc xen domain config stuff */ ++ unsigned long flags; ++ unsigned int console_evtchn; ++ unsigned int xenstore_evtchn; ++ xen_pfn_t shared_info_mfn; ++ ++ int guest_xc; ++ domid_t guest_domid; ++ int shadow_enabled; ++ ++ int xen_version; ++ xen_capabilities_info_t xen_caps; ++ ++ /* kernel loader, arch hooks */ ++ struct xc_dom_loader *kernel_loader; ++ void *private_loader; ++ ++ /* kernel loader */ ++ struct xc_dom_arch *arch_hooks; ++}; ++ ++/* --- pluggable kernel loader ------------------------------------- */ ++ ++struct xc_dom_loader { ++ char *name; ++ int (*probe) (struct xc_dom_image * dom); ++ int (*parser) (struct xc_dom_image * dom); ++ int (*loader) (struct xc_dom_image * dom); ++ ++ struct xc_dom_loader *next; ++}; ++ ++#define __init __attribute__ ((constructor)) ++void xc_dom_register_loader(struct xc_dom_loader *loader); ++ ++/* --- arch specific hooks ----------------------------------------- */ ++ ++struct xc_dom_arch { ++ /* pagetable setup */ ++ int (*alloc_magic_pages) (struct xc_dom_image * dom); ++ int (*count_pgtables) (struct xc_dom_image * dom); ++ int (*setup_pgtables) (struct xc_dom_image * dom); ++ ++ /* arch-specific data structs setup */ ++ int (*start_info) (struct xc_dom_image * dom); ++ int (*shared_info) (struct xc_dom_image * dom, void *shared_info); ++ int (*vcpu) (struct xc_dom_image * dom, void *vcpu_ctxt); ++ ++ char *guest_type; ++ int page_shift; ++ int sizeof_pfn; ++ ++ struct xc_dom_arch *next; ++}; ++void xc_dom_register_arch_hooks(struct xc_dom_arch *hooks); ++ ++#define XC_DOM_PAGE_SHIFT(dom) ((dom)->arch_hooks->page_shift) ++#define XC_DOM_PAGE_SIZE(dom) (1 << (dom)->arch_hooks->page_shift) ++ ++/* --- main functions ---------------------------------------------- */ ++ ++struct xc_dom_image *xc_dom_allocate(const char *cmdline, const char *features); ++void xc_dom_release_phys(struct xc_dom_image *dom); ++void xc_dom_release(struct xc_dom_image *dom); ++int xc_dom_mem_init(struct xc_dom_image *dom, unsigned int mem_mb); ++ ++size_t xc_dom_check_gzip(void *blob, size_t ziplen); ++int xc_dom_do_gunzip(void *src, size_t srclen, void *dst, size_t dstlen); ++int xc_dom_try_gunzip(struct xc_dom_image *dom, void **blob, size_t * size); ++ ++int xc_dom_kernel_file(struct xc_dom_image *dom, const char *filename); ++int xc_dom_ramdisk_file(struct xc_dom_image *dom, const char *filename); ++int xc_dom_kernel_mem(struct xc_dom_image *dom, const void *mem, ++ size_t memsize); ++int xc_dom_ramdisk_mem(struct xc_dom_image *dom, const void *mem, ++ size_t memsize); ++ ++int xc_dom_parse_image(struct xc_dom_image *dom); ++int xc_dom_build_image(struct xc_dom_image *dom); ++int xc_dom_update_guest_p2m(struct xc_dom_image *dom); ++ ++int xc_dom_boot_xen_init(struct xc_dom_image *dom, int xc, domid_t domid); ++int xc_dom_boot_mem_init(struct xc_dom_image *dom); ++void *xc_dom_boot_domU_map(struct xc_dom_image *dom, xen_pfn_t pfn, ++ xen_pfn_t count); ++int xc_dom_boot_image(struct xc_dom_image *dom); ++int xc_dom_compat_check(struct xc_dom_image *dom); ++ ++/* --- debugging bits ---------------------------------------------- */ ++ ++extern FILE *xc_dom_logfile; ++ ++void xc_dom_loginit(void); ++int xc_dom_printf(const char *fmt, ...) __attribute__ ((format(printf, 1, 2))); ++int xc_dom_panic_func(const char *file, int line, xc_error_code err, ++ const char *fmt, ...) ++ __attribute__ ((format(printf, 4, 5))); ++#define xc_dom_panic(err, fmt, args...) \ ++ xc_dom_panic_func(__FILE__, __LINE__, err, fmt, ## args) ++#define xc_dom_trace(mark) \ ++ xc_dom_printf("%s:%d: trace %s\n", __FILE__, __LINE__, mark) ++ ++void xc_dom_log_memory_footprint(struct xc_dom_image *dom); ++ ++/* --- simple memory pool ------------------------------------------ */ ++ ++void *xc_dom_malloc(struct xc_dom_image *dom, size_t size); ++void *xc_dom_malloc_page_aligned(struct xc_dom_image *dom, size_t size); ++void *xc_dom_malloc_filemap(struct xc_dom_image *dom, ++ const char *filename, size_t * size); ++char *xc_dom_strdup(struct xc_dom_image *dom, const char *str); ++ ++/* --- alloc memory pool ------------------------------------------- */ ++ ++int xc_dom_alloc_page(struct xc_dom_image *dom, char *name); ++int xc_dom_alloc_segment(struct xc_dom_image *dom, ++ struct xc_dom_seg *seg, char *name, ++ xen_vaddr_t start, xen_vaddr_t size); ++ ++/* --- misc bits --------------------------------------------------- */ ++ ++void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t first, ++ xen_pfn_t count); ++void xc_dom_unmap_one(struct xc_dom_image *dom, xen_pfn_t pfn); ++void xc_dom_unmap_all(struct xc_dom_image *dom); ++ ++static inline void *xc_dom_seg_to_ptr(struct xc_dom_image *dom, ++ struct xc_dom_seg *seg) ++{ ++ xen_vaddr_t segsize = seg->vend - seg->vstart; ++ unsigned int page_size = XC_DOM_PAGE_SIZE(dom); ++ xen_pfn_t pages = (segsize + page_size - 1) / page_size; ++ ++ return xc_dom_pfn_to_ptr(dom, seg->pfn, pages); ++} ++ ++static inline void *xc_dom_vaddr_to_ptr(struct xc_dom_image *dom, ++ xen_vaddr_t vaddr) ++{ ++ unsigned int page_size = XC_DOM_PAGE_SIZE(dom); ++ xen_pfn_t page = (vaddr - dom->parms.virt_base) / page_size; ++ unsigned int offset = (vaddr - dom->parms.virt_base) % page_size; ++ void *ptr = xc_dom_pfn_to_ptr(dom, page, 0); ++ ++ if (!ptr) ++ return NULL; ++ return ptr + offset; ++} ++ ++static inline int xc_dom_feature_translated(struct xc_dom_image *dom) ++{ ++ return elf_xen_feature_get(XENFEAT_auto_translated_physmap, dom->f_active); ++} ++ ++static inline xen_pfn_t xc_dom_p2m_host(struct xc_dom_image *dom, xen_pfn_t pfn) ++{ ++ if (dom->shadow_enabled) ++ return pfn; ++ return dom->p2m_host[pfn]; ++} ++ ++static inline xen_pfn_t xc_dom_p2m_guest(struct xc_dom_image *dom, ++ xen_pfn_t pfn) ++{ ++ if (xc_dom_feature_translated(dom)) ++ return pfn; ++ return dom->p2m_host[pfn]; ++} ++ ++/* --- arch bits --------------------------------------------------- */ ++ +Index: build-32-release304-13138/tools/libxc/xc_dom_boot.c +=================================================================== +--- /dev/null ++++ build-32-release304-13138/tools/libxc/xc_dom_boot.c +@@ -0,0 +1,592 @@ ++/* ++ * Xen domain builder -- xen booter. ++ * ++ * This is the code which actually boots a fresh ++ * prepared domain image as xen guest domain. ++ * ++ * ==> this is the only domain bilder code piece ++ * where xen hypercalls are allowed <== ++ * ++ * This code is licenced under the GPL. ++ * written 2006 by Gerd Hoffmann . ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++ ++#include "xg_private.h" ++#include "xc_dom.h" ++#include ++ ++/* ------------------------------------------------------------------------ */ ++ ++static int setup_hypercall_page(struct xc_dom_image *dom) ++{ ++ DECLARE_DOMCTL; ++ xen_pfn_t pfn; ++ int rc; ++ ++ if (-1 == dom->parms.virt_hypercall) ++ return 0; ++ pfn = (dom->parms.virt_hypercall - dom->parms.virt_base) ++ >> XC_DOM_PAGE_SHIFT(dom); ++ ++ xc_dom_printf("%s: vaddr=0x%" PRIx64 " pfn=0x%" PRIpfn "\n", __FUNCTION__, ++ dom->parms.virt_hypercall, pfn); ++ domctl.cmd = XEN_DOMCTL_hypercall_init; ++ domctl.domain = dom->guest_domid; ++ domctl.u.hypercall_init.gmfn = xc_dom_p2m_guest(dom, pfn); ++ rc = do_domctl(dom->guest_xc, &domctl); ++ if (0 != rc) ++ xc_dom_panic(XC_INTERNAL_ERROR, "%s: HYPERCALL_INIT failed (rc=%d)\n", ++ __FUNCTION__, rc); ++ return rc; ++} ++ ++static int launch_vm(int xc, domid_t domid, void *ctxt) ++{ ++ DECLARE_DOMCTL; ++ int rc; ++ ++ xc_dom_printf("%s: called, ctxt=%p\n", __FUNCTION__, ctxt); ++ memset(&domctl, 0, sizeof(domctl)); ++ domctl.cmd = XEN_DOMCTL_setvcpucontext; ++ domctl.domain = domid; ++ domctl.u.vcpucontext.vcpu = 0; ++ set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt); ++ rc = do_domctl(xc, &domctl); ++ if (0 != rc) ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: SETVCPUCONTEXT failed (rc=%d)\n", __FUNCTION__, rc); ++ return rc; ++} ++ ++static int clear_page(struct xc_dom_image *dom, xen_pfn_t pfn) ++{ ++ xen_pfn_t dst; ++ int rc; ++ ++ if (0 == pfn) ++ return 0; ++ ++ dst = xc_dom_p2m_host(dom, pfn); ++ xc_dom_printf("%s: pfn 0x%" PRIpfn ", mfn 0x%" PRIpfn "\n", ++ __FUNCTION__, pfn, dst); ++ rc = xc_clear_domain_page(dom->guest_xc, dom->guest_domid, dst); ++ if (0 != rc) ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: xc_clear_domain_page failed (pfn 0x%" PRIpfn ++ ", rc=%d)\n", __FUNCTION__, pfn, rc); ++ return rc; ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* arch stuff: x86 bits */ ++ ++#if defined(__i386__) || defined(__x86_64__) ++ ++static int x86_compat(int xc, domid_t domid, char *guest_type) ++{ ++#if defined(XEN_DOMCTL_set_address_size) ++ ++ /* stable api, 3.0.5 final */ ++ static const struct { ++ char *guest; ++ uint32_t size; ++ } types[] = { ++ { "xen-3.0-x86_32p", 32 }, ++ { "xen-3.0-x86_64", 64 }, ++ }; ++ DECLARE_DOMCTL; ++ int i,rc; ++ ++ memset(&domctl, 0, sizeof(domctl)); ++ domctl.domain = domid; ++ domctl.cmd = XEN_DOMCTL_set_address_size; ++ for (i = 0; i < sizeof(types)/sizeof(types[0]); i++) ++ if (0 == strcmp(types[i].guest, guest_type)) ++ domctl.u.address_size.size = types[i].size; ++ if (0 == domctl.u.address_size.size) ++ /* nothing to do */ ++ return 0; ++ ++ xc_dom_printf("%s: guest %s, address size %" PRId32 "\n", __FUNCTION__, ++ guest_type, domctl.u.address_size.size); ++ rc = do_domctl(xc, &domctl); ++ if (0 != rc) ++ xc_dom_printf("%s: warning: failed (rc=%d)\n", ++ __FUNCTION__, rc); ++ return rc; ++ ++#elif defined(XEN_DOMCTL_set_compat) ++ ++ /* temporary, 3.0.4 patches and 3.0.5 initial merge */ ++ static const struct { ++ char *guest; ++ unsigned long cmd; ++ } types[] = { ++ { "xen-3.0-x86_32p", XEN_DOMCTL_set_compat }, ++ { "xen-3.0-x86_64", XEN_DOMCTL_set_native }, ++ }; ++ DECLARE_DOMCTL; ++ int i,rc; ++ ++ memset(&domctl, 0, sizeof(domctl)); ++ domctl.domain = domid; ++ for (i = 0; i < sizeof(types)/sizeof(types[0]); i++) ++ if (0 == strcmp(types[i].guest, guest_type)) ++ domctl.cmd = types[i].cmd; ++ if (0 == domctl.cmd) ++ /* nothing to do */ ++ return 0; ++ ++ xc_dom_printf("%s: guest %s, cmd %d\n", __FUNCTION__, ++ guest_type, domctl.cmd); ++ rc = do_domctl(xc, &domctl); ++ if (0 != rc) ++ xc_dom_printf("%s: warning: failed (rc=%d)\n", ++ __FUNCTION__, rc); ++ return rc; ++ ++#else ++#warn compiling without compat/native switching ++ xc_dom_printf("%s: compiled without compat/native switching\n", __FUNCTION__); ++ return 0; ++#endif ++} ++ ++ ++static int x86_shadow(int xc, domid_t domid) ++{ ++ int rc, mode; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ mode = XEN_DOMCTL_SHADOW_ENABLE_REFCOUNT | ++ XEN_DOMCTL_SHADOW_ENABLE_TRANSLATE; ++ ++ rc = xc_shadow_control(xc, domid, ++ XEN_DOMCTL_SHADOW_OP_ENABLE, ++ NULL, 0, NULL, mode, NULL); ++ if (0 != rc) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: SHADOW_OP_ENABLE (mode=0x%x) failed (rc=%d)\n", ++ __FUNCTION__, mode, rc); ++ return rc; ++ } ++ xc_dom_printf("%s: shadow enabled (mode=0x%x)\n", __FUNCTION__, mode); ++ return rc; ++} ++ ++static int arch_setup_meminit(struct xc_dom_image *dom) ++{ ++ int rc = 0; ++ ++ x86_compat(dom->guest_xc, dom->guest_domid, dom->guest_type); ++ if (xc_dom_feature_translated(dom)) ++ { ++ dom->shadow_enabled = 1; ++ rc = x86_shadow(dom->guest_xc, dom->guest_domid); ++ } ++ return rc; ++} ++ ++static int arch_setup_bootearly(struct xc_dom_image *dom) ++{ ++ xc_dom_printf("%s: doing nothing\n", __FUNCTION__); ++ return 0; ++} ++ ++static int arch_setup_bootlate(struct xc_dom_image *dom) ++{ ++ static const struct { ++ char *guest; ++ unsigned long pgd_type; ++ } types[] = { ++ { "xen-3.0-x86_32", MMUEXT_PIN_L2_TABLE}, ++ { "xen-3.0-x86_32p", MMUEXT_PIN_L3_TABLE}, ++ { "xen-3.0-x86_64", MMUEXT_PIN_L4_TABLE}, ++ }; ++ unsigned long pgd_type = 0; ++ shared_info_t *shared_info; ++ xen_pfn_t shinfo; ++ int i, rc; ++ ++ for (i = 0; i < sizeof(types) / sizeof(types[0]); i++) ++ if (0 == strcmp(types[i].guest, dom->guest_type)) ++ pgd_type = types[i].pgd_type; ++ ++ if (!xc_dom_feature_translated(dom)) ++ { ++ /* paravirtualized guest */ ++ xc_dom_unmap_one(dom, dom->pgtables_seg.pfn); ++ rc = pin_table(dom->guest_xc, pgd_type, ++ xc_dom_p2m_host(dom, dom->pgtables_seg.pfn), ++ dom->guest_domid); ++ if (0 != rc) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: pin_table failed (pfn 0x%" PRIpfn ", rc=%d)\n", ++ __FUNCTION__, dom->pgtables_seg.pfn, rc); ++ return rc; ++ } ++ shinfo = dom->shared_info_mfn; ++ } ++ else ++ { ++ /* paravirtualized guest with auto-translation */ ++ struct xen_add_to_physmap xatp; ++ int i; ++ ++ /* Map shared info frame into guest physmap. */ ++ xatp.domid = dom->guest_domid; ++ xatp.space = XENMAPSPACE_shared_info; ++ xatp.idx = 0; ++ xatp.gpfn = dom->shared_info_pfn; ++ rc = xc_memory_op(dom->guest_xc, XENMEM_add_to_physmap, &xatp); ++ if (rc != 0) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, "%s: mapping shared_info failed " ++ "(pfn=0x%" PRIpfn ", rc=%d)\n", ++ __FUNCTION__, xatp.gpfn, rc); ++ return rc; ++ } ++ ++ /* Map grant table frames into guest physmap. */ ++ for (i = 0;; i++) ++ { ++ xatp.domid = dom->guest_domid; ++ xatp.space = XENMAPSPACE_grant_table; ++ xatp.idx = i; ++ xatp.gpfn = dom->total_pages + i; ++ rc = xc_memory_op(dom->guest_xc, XENMEM_add_to_physmap, &xatp); ++ if (rc != 0) ++ { ++ if (i > 0 && errno == EINVAL) ++ { ++ xc_dom_printf("%s: %d grant tables mapped\n", __FUNCTION__, ++ i); ++ break; ++ } ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: mapping grant tables failed " "(pfn=0x%" ++ PRIpfn ", rc=%d)\n", __FUNCTION__, xatp.gpfn, rc); ++ return rc; ++ } ++ } ++ shinfo = dom->shared_info_pfn; ++ } ++ ++ /* setup shared_info page */ ++ xc_dom_printf("%s: shared_info: pfn 0x%" PRIpfn ", mfn 0x%" PRIpfn "\n", ++ __FUNCTION__, dom->shared_info_pfn, dom->shared_info_mfn); ++ shared_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid, ++ PAGE_SIZE_X86, ++ PROT_READ | PROT_WRITE, ++ shinfo); ++ if (NULL == shared_info) ++ return -1; ++ dom->arch_hooks->shared_info(dom, shared_info); ++ munmap(shared_info, PAGE_SIZE_X86); ++ ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* arch stuff: ia64 */ ++ ++#elif defined(__ia64__) ++ ++static int arch_setup_meminit(struct xc_dom_image *dom) ++{ ++ xc_dom_printf("%s: doing nothing\n", __FUNCTION__); ++ return 0; ++} ++ ++static int arch_setup_bootearly(struct xc_dom_image *dom) ++{ ++ DECLARE_DOMCTL; ++ int rc; ++ ++ xc_dom_printf("%s: setup firmware\n", __FUNCTION__); ++ ++ memset(&domctl, 0, sizeof(domctl)); ++ domctl.cmd = XEN_DOMCTL_arch_setup; ++ domctl.domain = dom->guest_domid; ++ domctl.u.arch_setup.flags = 0; ++ ++ domctl.u.arch_setup.bp = (dom->start_info_pfn << PAGE_SHIFT) ++ + sizeof(start_info_t); ++ /* 3 = start info page, xenstore page and console page */ ++ domctl.u.arch_setup.maxmem = (dom->total_pages - 3) << PAGE_SHIFT; ++ rc = do_domctl(dom->guest_xc, &domctl); ++ return rc; ++} ++ ++static int arch_setup_bootlate(struct xc_dom_image *dom) ++{ ++ unsigned int page_size = XC_DOM_PAGE_SIZE(dom); ++ shared_info_t *shared_info; ++ ++ /* setup shared_info page */ ++ xc_dom_printf("%s: shared_info: mfn 0x%" PRIpfn "\n", ++ __FUNCTION__, dom->shared_info_mfn); ++ shared_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid, ++ page_size, ++ PROT_READ | PROT_WRITE, ++ dom->shared_info_mfn); ++ if (NULL == shared_info) ++ return -1; ++ dom->arch_hooks->shared_info(dom, shared_info); ++ munmap(shared_info, page_size); ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* arch stuff: powerpc */ ++ ++#elif defined(__powerpc64__) ++ ++static int arch_setup_meminit(struct xc_dom_image *dom) ++{ ++ xc_dom_printf("%s: doing nothing\n", __FUNCTION__); ++ return 0; ++} ++ ++static int arch_setup_bootearly(struct xc_dom_image *dom) ++{ ++ xc_dom_printf("%s: doing nothing\n", __FUNCTION__); ++ return 0; ++} ++ ++static int arch_setup_bootlate(struct xc_dom_image *dom) ++{ ++ start_info_t *si = ++ xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1); ++ ++ xc_dom_printf("%s: TODO: setup devtree\n", __FUNCTION__); ++ ++#if 0 ++ load_devtree(dom->guest_xc, ++ dom->guest_domid, ++ dom->p2m_host, ++ devtree, // FIXME ++ devtree_addr, // FIXME ++ dom->ramdisk_seg.vstart, ++ dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart, ++ si, ++ dom->start_info_pfn << PAGE_SHIFT); ++#endif ++ return rc; ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* arch stuff: other */ ++ ++#else ++ ++static int arch_setup_meminit(struct xc_dom_image *dom) ++{ ++ xc_dom_printf("%s: doing nothing\n", __FUNCTION__); ++ return 0; ++} ++ ++static int arch_setup_bootearly(struct xc_dom_image *dom) ++{ ++ xc_dom_printf("%s: doing nothing\n", __FUNCTION__); ++ return 0; ++} ++ ++static int arch_setup_bootlate(struct xc_dom_image *dom) ++{ ++ xc_dom_printf("%s: doing nothing\n", __FUNCTION__); ++ return 0; ++} ++ ++#endif /* arch stuff */ ++ ++/* ------------------------------------------------------------------------ */ ++ ++int xc_dom_compat_check(struct xc_dom_image *dom) ++{ ++ xen_capabilities_info_t xen_caps; ++ char *item, *ptr; ++ int match, found = 0; ++ ++ strcpy(xen_caps, dom->xen_caps); ++ for (item = strtok_r(xen_caps, " ", &ptr); ++ NULL != item; item = strtok_r(NULL, " ", &ptr)) ++ { ++ match = (0 == strcmp(dom->guest_type, item)); ++ xc_dom_printf("%s: supported guest type: %s%s\n", __FUNCTION__, ++ item, match ? " <= matches" : ""); ++ if (match) ++ found++; ++ } ++ if (!found) ++ xc_dom_panic(XC_INVALID_KERNEL, ++ "%s: guest type %s not supported by xen kernel, sorry\n", ++ __FUNCTION__, dom->guest_type); ++ ++ return found; ++} ++ ++int xc_dom_boot_xen_init(struct xc_dom_image *dom, int xc, domid_t domid) ++{ ++ dom->guest_xc = xc; ++ dom->guest_domid = domid; ++ ++ dom->xen_version = xc_version(dom->guest_xc, XENVER_version, NULL); ++ if (xc_version(xc, XENVER_capabilities, &dom->xen_caps) < 0) { ++ xc_dom_panic(XC_INTERNAL_ERROR, "can't get xen capabilities"); ++ return -1; ++ } ++ xc_dom_printf("%s: ver %d.%d, caps %s\n", __FUNCTION__, ++ dom->xen_version >> 16, dom->xen_version & 0xff, ++ dom->xen_caps); ++ return 0; ++} ++ ++int xc_dom_boot_mem_init(struct xc_dom_image *dom) ++{ ++ long rc; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ if (0 != (rc = arch_setup_meminit(dom))) ++ return rc; ++ ++ /* allocate guest memory */ ++ rc = xc_domain_memory_populate_physmap(dom->guest_xc, dom->guest_domid, ++ dom->total_pages, 0, 0, ++ dom->p2m_host); ++ if (0 != rc) ++ { ++ xc_dom_panic(XC_OUT_OF_MEMORY, ++ "%s: can't allocate low memory for domain\n", ++ __FUNCTION__); ++ return rc; ++ } ++ ++ return 0; ++} ++ ++void *xc_dom_boot_domU_map(struct xc_dom_image *dom, xen_pfn_t pfn, ++ xen_pfn_t count) ++{ ++ int page_shift = XC_DOM_PAGE_SHIFT(dom); ++ privcmd_mmap_entry_t *entries; ++ void *ptr; ++ int i, rc; ++ ++ entries = xc_dom_malloc(dom, count * sizeof(privcmd_mmap_entry_t)); ++ if (NULL == entries) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: failed to mmap domU pages 0x%" PRIpfn "+0x%" PRIpfn ++ " [malloc]\n", __FUNCTION__, pfn, count); ++ return NULL; ++ } ++ ++ ptr = mmap(NULL, count << page_shift, PROT_READ | PROT_WRITE, ++ MAP_SHARED, dom->guest_xc, 0); ++ if (MAP_FAILED == ptr) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: failed to mmap domU pages 0x%" PRIpfn "+0x%" PRIpfn ++ " [mmap]\n", __FUNCTION__, pfn, count); ++ return NULL; ++ } ++ ++ for (i = 0; i < count; i++) ++ { ++ entries[i].va = (uintptr_t) ptr + (i << page_shift); ++ entries[i].mfn = xc_dom_p2m_host(dom, pfn + i); ++ entries[i].npages = 1; ++ } ++ ++ rc = xc_map_foreign_ranges(dom->guest_xc, dom->guest_domid, entries, count); ++ if (rc < 0) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: failed to mmap domU pages 0x%" PRIpfn "+0x%" PRIpfn ++ " [xenctl, rc=%d]\n", __FUNCTION__, pfn, count, rc); ++ return NULL; ++ } ++ return ptr; ++} ++ ++int xc_dom_boot_image(struct xc_dom_image *dom) ++{ ++ DECLARE_DOMCTL; ++ void *ctxt; ++ int rc; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ /* misc ia64 stuff*/ ++ if (0 != (rc = arch_setup_bootearly(dom))) ++ return rc; ++ ++ /* collect some info */ ++ domctl.cmd = XEN_DOMCTL_getdomaininfo; ++ domctl.domain = dom->guest_domid; ++ rc = do_domctl(dom->guest_xc, &domctl); ++ if (0 != rc) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: getdomaininfo failed (rc=%d)\n", __FUNCTION__, rc); ++ return rc; ++ } ++ if (domctl.domain != dom->guest_domid) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: Huh? domid mismatch (%d != %d)\n", __FUNCTION__, ++ domctl.domain, dom->guest_domid); ++ return -1; ++ } ++ dom->shared_info_mfn = domctl.u.getdomaininfo.shared_info_frame; ++ ++ /* sanity checks */ ++ if (!xc_dom_compat_check(dom)) ++ return -1; ++ ++ /* initial mm setup */ ++ if (0 != (rc = xc_dom_update_guest_p2m(dom))) ++ return rc; ++ if (dom->arch_hooks->setup_pgtables) ++ if (0 != (rc = dom->arch_hooks->setup_pgtables(dom))) ++ return rc; ++ ++ if (0 != (rc = clear_page(dom, dom->console_pfn))) ++ return rc; ++ if (0 != (rc = clear_page(dom, dom->xenstore_pfn))) ++ return rc; ++ ++ /* start info page */ ++ if (dom->arch_hooks->start_info) ++ dom->arch_hooks->start_info(dom); ++ ++ /* hypercall page */ ++ if (0 != (rc = setup_hypercall_page(dom))) ++ return rc; ++ xc_dom_log_memory_footprint(dom); ++ ++ /* misc x86 stuff */ ++ if (0 != (rc = arch_setup_bootlate(dom))) ++ return rc; ++ ++ /* let the vm run */ ++ ctxt = xc_dom_malloc(dom, PAGE_SIZE * 2 /* FIXME */ ); ++ memset(ctxt, 0, PAGE_SIZE * 2); ++ if (0 != (rc = dom->arch_hooks->vcpu(dom, ctxt))) ++ return rc; ++ xc_dom_unmap_all(dom); ++ rc = launch_vm(dom->guest_xc, dom->guest_domid, ctxt); ++ ++ return rc; ++} +Index: build-32-release304-13138/tools/libxc/xc_dom_core.c +=================================================================== +--- /dev/null ++++ build-32-release304-13138/tools/libxc/xc_dom_core.c +@@ -0,0 +1,776 @@ ++/* ++ * Xen domain builder -- core bits. ++ * ++ * The core code goes here: ++ * - allocate and release domain structs. ++ * - memory management functions. ++ * - misc helper functions. ++ * ++ * This code is licenced under the GPL. ++ * written 2006 by Gerd Hoffmann . ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "xg_private.h" ++#include "xc_dom.h" ++ ++/* ------------------------------------------------------------------------ */ ++/* debugging */ ++ ++FILE *xc_dom_logfile = NULL; ++ ++void xc_dom_loginit(void) ++{ ++ if (xc_dom_logfile) ++ return; ++ xc_dom_logfile = fopen("/var/log/xen/domain-builder-ng.log", "a"); ++ setvbuf(xc_dom_logfile, NULL, _IONBF, 0); ++ xc_dom_printf("### ----- xc domain builder logfile opened -----\n"); ++} ++ ++int xc_dom_printf(const char *fmt, ...) ++{ ++ va_list args; ++ char buf[1024]; ++ int rc; ++ ++ if (!xc_dom_logfile) ++ return 0; ++ ++ va_start(args, fmt); ++ rc = vsnprintf(buf, sizeof(buf), fmt, args); ++ va_end(args); ++ rc = fwrite(buf, rc, 1, xc_dom_logfile); ++ ++ return rc; ++} ++ ++int xc_dom_panic_func(const char *file, int line, xc_error_code err, ++ const char *fmt, ...) ++{ ++ va_list args; ++ FILE *fp = stderr; ++ int rc = 0; ++ char pos[256]; ++ char msg[XC_MAX_ERROR_MSG_LEN]; ++ ++ if (xc_dom_logfile) ++ fp = xc_dom_logfile; ++ ++ snprintf(pos, sizeof(pos), "%s:%d: panic: ", file, line); ++ va_start(args, fmt); ++ vsnprintf(msg, sizeof(msg), fmt, args); ++ va_end(args); ++ xc_set_error(err, "%s", msg); ++ rc = fprintf(fp, "%s%s", pos, msg); ++ return rc; ++} ++ ++static void print_mem(const char *name, size_t mem) ++{ ++ if (mem > 32 * 1024 * 1024) ++ xc_dom_printf("%-24s : %zd MB\n", name, mem / (1024 * 1024)); ++ else if (mem > 32 * 1024) ++ xc_dom_printf("%-24s : %zd kB\n", name, mem / 1024); ++ else ++ xc_dom_printf("%-24s : %zd bytes\n", name, mem); ++} ++ ++void xc_dom_log_memory_footprint(struct xc_dom_image *dom) ++{ ++ xc_dom_printf("domain builder memory footprint\n"); ++ xc_dom_printf(" allocated\n"); ++ print_mem(" malloc", dom->alloc_malloc); ++ print_mem(" anon mmap", dom->alloc_mem_map); ++ xc_dom_printf(" mapped\n"); ++ print_mem(" file mmap", dom->alloc_file_map); ++ print_mem(" domU mmap", dom->alloc_domU_map); ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* simple memory pool */ ++ ++void *xc_dom_malloc(struct xc_dom_image *dom, size_t size) ++{ ++ struct xc_dom_mem *block; ++ ++ block = malloc(sizeof(*block) + size); ++ if (NULL == block) ++ return NULL; ++ memset(block, 0, sizeof(*block) + size); ++ block->next = dom->memblocks; ++ dom->memblocks = block; ++ dom->alloc_malloc += sizeof(*block) + size; ++ if (size > 100 * 1024) ++ print_mem(__FUNCTION__, size); ++ return block->memory; ++} ++ ++void *xc_dom_malloc_page_aligned(struct xc_dom_image *dom, size_t size) ++{ ++ struct xc_dom_mem *block; ++ ++ block = malloc(sizeof(*block)); ++ if (NULL == block) ++ return NULL; ++ memset(block, 0, sizeof(*block)); ++ block->mmap_len = size; ++ block->mmap_ptr = mmap(NULL, block->mmap_len, ++ PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, ++ -1, 0); ++ if (MAP_FAILED == block->mmap_ptr) ++ { ++ free(block); ++ return NULL; ++ } ++ block->next = dom->memblocks; ++ dom->memblocks = block; ++ dom->alloc_malloc += sizeof(*block); ++ dom->alloc_mem_map += block->mmap_len; ++ if (size > 100 * 1024) ++ print_mem(__FUNCTION__, size); ++ return block->mmap_ptr; ++} ++ ++void *xc_dom_malloc_filemap(struct xc_dom_image *dom, ++ const char *filename, size_t * size) ++{ ++ struct xc_dom_mem *block = NULL; ++ int fd = -1; ++ ++ fd = open(filename, O_RDONLY); ++ if (-1 == fd) ++ goto err; ++ ++ lseek(fd, 0, SEEK_SET); ++ *size = lseek(fd, 0, SEEK_END); ++ ++ block = malloc(sizeof(*block)); ++ if (NULL == block) ++ goto err; ++ memset(block, 0, sizeof(*block)); ++ block->mmap_len = *size; ++ block->mmap_ptr = mmap(NULL, block->mmap_len, PROT_READ, MAP_SHARED, fd, 0); ++ if (MAP_FAILED == block->mmap_ptr) ++ goto err; ++ block->next = dom->memblocks; ++ dom->memblocks = block; ++ dom->alloc_malloc += sizeof(*block); ++ dom->alloc_file_map += block->mmap_len; ++ close(fd); ++ if (*size > 100 * 1024) ++ print_mem(__FUNCTION__, *size); ++ return block->mmap_ptr; ++ ++ err: ++ if (-1 != fd) ++ close(fd); ++ if (block) ++ free(block); ++ return NULL; ++} ++ ++static void xc_dom_free_all(struct xc_dom_image *dom) ++{ ++ struct xc_dom_mem *block; ++ ++ while (NULL != (block = dom->memblocks)) ++ { ++ dom->memblocks = block->next; ++ if (block->mmap_ptr) ++ munmap(block->mmap_ptr, block->mmap_len); ++ free(block); ++ } ++} ++ ++char *xc_dom_strdup(struct xc_dom_image *dom, const char *str) ++{ ++ size_t len = strlen(str) + 1; ++ char *nstr = xc_dom_malloc(dom, len); ++ ++ if (NULL == nstr) ++ return NULL; ++ memcpy(nstr, str, len); ++ return nstr; ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* read files, copy memory blocks, with transparent gunzip */ ++ ++size_t xc_dom_check_gzip(void *blob, size_t ziplen) ++{ ++ unsigned char *gzlen; ++ size_t unziplen; ++ ++ if (0 != strncmp(blob, "\037\213", 2)) ++ /* not gzipped */ ++ return 0; ++ ++ gzlen = blob + ziplen - 4; ++ unziplen = gzlen[3] << 24 | gzlen[2] << 16 | gzlen[1] << 8 | gzlen[0]; ++ if (unziplen < ziplen || unziplen > ziplen * 8) ++ { ++ xc_dom_printf ++ ("%s: size (zip %zd, unzip %zd) looks insane, skip gunzip\n", ++ __FUNCTION__, ziplen, unziplen); ++ return 0; ++ } ++ ++ return unziplen + 16; ++} ++ ++int xc_dom_do_gunzip(void *src, size_t srclen, void *dst, size_t dstlen) ++{ ++ z_stream zStream; ++ int rc; ++ ++ memset(&zStream, 0, sizeof(zStream)); ++ zStream.next_in = src; ++ zStream.avail_in = srclen; ++ zStream.next_out = dst; ++ zStream.avail_out = dstlen; ++ rc = inflateInit2(&zStream, (MAX_WBITS + 32)); /* +32 means "handle gzip" */ ++ if (rc != Z_OK) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: inflateInit2 failed (rc=%d)\n", __FUNCTION__, rc); ++ return -1; ++ } ++ rc = inflate(&zStream, Z_FINISH); ++ if (rc != Z_STREAM_END) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: inflate failed (rc=%d)\n", __FUNCTION__, rc); ++ return -1; ++ } ++ ++ xc_dom_printf("%s: unzip ok, 0x%zx -> 0x%zx\n", ++ __FUNCTION__, srclen, dstlen); ++ return 0; ++} ++ ++int xc_dom_try_gunzip(struct xc_dom_image *dom, void **blob, size_t * size) ++{ ++ void *unzip; ++ size_t unziplen; ++ ++ unziplen = xc_dom_check_gzip(*blob, *size); ++ if (0 == unziplen) ++ return 0; ++ ++ unzip = xc_dom_malloc(dom, unziplen); ++ if (NULL == unzip) ++ return -1; ++ ++ if (-1 == xc_dom_do_gunzip(*blob, *size, unzip, unziplen)) ++ return -1; ++ ++ *blob = unzip; ++ *size = unziplen; ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* domain memory */ ++ ++void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t pfn, ++ xen_pfn_t count) ++{ ++ struct xc_dom_phys *phys; ++ unsigned int page_shift = XC_DOM_PAGE_SHIFT(dom); ++ char *mode = "unset"; ++ ++ if (pfn > dom->total_pages) ++ { ++ xc_dom_printf("%s: pfn out of range (0x%" PRIpfn " > 0x%" PRIpfn ")\n", ++ __FUNCTION__, pfn, dom->total_pages); ++ return NULL; ++ } ++ ++ /* already allocated? */ ++ for (phys = dom->phys_pages; NULL != phys; phys = phys->next) ++ { ++ if (pfn >= phys->first + phys->count) ++ continue; ++ if (count) ++ { ++ /* size given: must be completely within the already allocated block */ ++ if (pfn + count <= phys->first) ++ continue; ++ if (pfn < phys->first || pfn + count > phys->first + phys->count) ++ { ++ xc_dom_printf("%s: request overlaps allocated block" ++ " (req 0x%" PRIpfn "+0x%" PRIpfn "," ++ " blk 0x%" PRIpfn "+0x%" PRIpfn ")\n", ++ __FUNCTION__, pfn, count, phys->first, ++ phys->count); ++ return NULL; ++ } ++ } ++ else ++ { ++ /* no size given: block must be allocated already, ++ just hand out a pointer to it */ ++ if (pfn < phys->first) ++ continue; ++ } ++ return phys->ptr + ((pfn - phys->first) << page_shift); ++ } ++ ++ /* allocating is allowed with size specified only */ ++ if (0 == count) ++ { ++ xc_dom_printf("%s: no block found, no size given," ++ " can't malloc (pfn 0x%" PRIpfn ")\n", __FUNCTION__, pfn); ++ return NULL; ++ } ++ ++ /* not found, no overlap => allocate */ ++ phys = xc_dom_malloc(dom, sizeof(*phys)); ++ if (NULL == phys) ++ return NULL; ++ memset(phys, 0, sizeof(*phys)); ++ phys->first = pfn; ++ phys->count = count; ++ ++ if (dom->guest_domid) ++ { ++ mode = "domU mapping"; ++ phys->ptr = xc_dom_boot_domU_map(dom, phys->first, phys->count); ++ if (NULL == phys->ptr) ++ return NULL; ++ dom->alloc_domU_map += phys->count << page_shift; ++ } ++ else ++ { ++ mode = "anonymous memory"; ++ phys->ptr = mmap(NULL, phys->count << page_shift, ++ PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, ++ -1, 0); ++ if (MAP_FAILED == phys->ptr) ++ { ++ xc_dom_panic(XC_OUT_OF_MEMORY, ++ "%s: oom: can't allocate 0x%" PRIpfn " pages\n", ++ __FUNCTION__, count); ++ return NULL; ++ } ++ dom->alloc_mem_map += phys->count << page_shift; ++ } ++ ++#if 1 ++ xc_dom_printf("%s: %s: pfn 0x%" PRIpfn "+0x%" PRIpfn " at %p\n", ++ __FUNCTION__, mode, phys->first, phys->count, phys->ptr); ++#endif ++ phys->next = dom->phys_pages; ++ dom->phys_pages = phys; ++ return phys->ptr; ++} ++ ++int xc_dom_alloc_segment(struct xc_dom_image *dom, ++ struct xc_dom_seg *seg, char *name, ++ xen_vaddr_t start, xen_vaddr_t size) ++{ ++ unsigned int page_size = XC_DOM_PAGE_SIZE(dom); ++ xen_pfn_t pages = (size + page_size - 1) / page_size; ++ void *ptr; ++ ++ if (0 == start) ++ start = dom->virt_alloc_end; ++ ++ if (start & (page_size - 1)) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: segment start isn't page aligned (0x%" PRIx64 ")\n", ++ __FUNCTION__, start); ++ return -1; ++ } ++ if (start < dom->virt_alloc_end) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: segment start too low (0x%" PRIx64 " < 0x%" PRIx64 ++ ")\n", __FUNCTION__, start, dom->virt_alloc_end); ++ return -1; ++ } ++ ++ seg->vstart = start; ++ seg->vend = start + pages * page_size; ++ seg->pfn = (seg->vstart - dom->parms.virt_base) / page_size; ++ dom->virt_alloc_end = seg->vend; ++ ++ xc_dom_printf("%-20s: %-12s : 0x%" PRIx64 " -> 0x%" PRIx64 ++ " (pfn 0x%" PRIpfn " + 0x%" PRIpfn " pages)\n", ++ __FUNCTION__, name, seg->vstart, seg->vend, seg->pfn, pages); ++ ++ /* map and clear pages */ ++ ptr = xc_dom_seg_to_ptr(dom, seg); ++ if (NULL == ptr) ++ return -1; ++ memset(ptr, 0, pages * page_size); ++ ++ return 0; ++} ++ ++int xc_dom_alloc_page(struct xc_dom_image *dom, char *name) ++{ ++ unsigned int page_size = XC_DOM_PAGE_SIZE(dom); ++ xen_vaddr_t start; ++ xen_pfn_t pfn; ++ ++ start = dom->virt_alloc_end; ++ dom->virt_alloc_end += page_size; ++ pfn = (start - dom->parms.virt_base) / page_size; ++ ++ xc_dom_printf("%-20s: %-12s : 0x%" PRIx64 " (pfn 0x%" PRIpfn ")\n", ++ __FUNCTION__, name, start, pfn); ++ return pfn; ++} ++ ++void xc_dom_unmap_one(struct xc_dom_image *dom, xen_pfn_t pfn) ++{ ++ unsigned int page_shift = XC_DOM_PAGE_SHIFT(dom); ++ struct xc_dom_phys *phys, *prev = NULL; ++ ++ for (phys = dom->phys_pages; NULL != phys; phys = phys->next) ++ { ++ if (pfn >= phys->first && pfn < phys->first + phys->count) ++ break; ++ prev = phys; ++ } ++ if (!phys) ++ { ++ xc_dom_printf("%s: Huh? no mapping with pfn 0x%" PRIpfn "\n", ++ __FUNCTION__, pfn); ++ return; ++ } ++ ++ munmap(phys->ptr, phys->count << page_shift); ++ if (prev) ++ prev->next = phys->next; ++ else ++ dom->phys_pages = phys->next; ++} ++ ++void xc_dom_unmap_all(struct xc_dom_image *dom) ++{ ++ while (dom->phys_pages) ++ xc_dom_unmap_one(dom, dom->phys_pages->first); ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* pluggable kernel loaders */ ++ ++static struct xc_dom_loader *first_loader = NULL; ++static struct xc_dom_arch *first_hook = NULL; ++ ++void xc_dom_register_loader(struct xc_dom_loader *loader) ++{ ++ loader->next = first_loader; ++ first_loader = loader; ++} ++ ++static struct xc_dom_loader *xc_dom_find_loader(struct xc_dom_image *dom) ++{ ++ struct xc_dom_loader *loader = first_loader; ++ ++ while (NULL != loader) ++ { ++ xc_dom_printf("%s: trying %s loader ... ", __FUNCTION__, loader->name); ++ if (0 == loader->probe(dom)) ++ { ++ xc_dom_printf("OK\n"); ++ return loader; ++ } ++ xc_dom_printf("failed\n"); ++ loader = loader->next; ++ } ++ xc_dom_panic(XC_INVALID_KERNEL, "%s: no loader found\n", __FUNCTION__); ++ return NULL; ++} ++ ++void xc_dom_register_arch_hooks(struct xc_dom_arch *hooks) ++{ ++ hooks->next = first_hook; ++ first_hook = hooks; ++} ++ ++static struct xc_dom_arch *xc_dom_find_arch_hooks(char *guest_type) ++{ ++ struct xc_dom_arch *hooks = first_hook; ++ ++ while (NULL != hooks) ++ { ++ if (0 == strcmp(hooks->guest_type, guest_type)) ++ return hooks; ++ hooks = hooks->next; ++ } ++ xc_dom_panic(XC_INVALID_KERNEL, ++ "%s: not found (type %s)\n", __FUNCTION__, guest_type); ++ return NULL; ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* public interface */ ++ ++void xc_dom_release(struct xc_dom_image *dom) ++{ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ if (dom->phys_pages) ++ xc_dom_unmap_all(dom); ++ xc_dom_free_all(dom); ++ free(dom); ++} ++ ++struct xc_dom_image *xc_dom_allocate(const char *cmdline, const char *features) ++{ ++ struct xc_dom_image *dom; ++ ++ xc_dom_printf("%s: cmdline=\"%s\", features=\"%s\"\n", ++ __FUNCTION__, cmdline, features); ++ dom = malloc(sizeof(*dom)); ++ if (!dom) ++ goto err; ++ ++ memset(dom, 0, sizeof(*dom)); ++ if (cmdline) ++ dom->cmdline = xc_dom_strdup(dom, cmdline); ++ if (features) ++ elf_xen_parse_features(features, dom->f_requested, NULL); ++ ++ dom->parms.virt_base = UNSET_ADDR; ++ dom->parms.virt_entry = UNSET_ADDR; ++ dom->parms.virt_hypercall = UNSET_ADDR; ++ dom->parms.virt_hv_start_low = UNSET_ADDR; ++ dom->parms.elf_paddr_offset = UNSET_ADDR; ++ ++ dom->alloc_malloc += sizeof(*dom); ++ return dom; ++ ++ err: ++ if (dom) ++ xc_dom_release(dom); ++ return NULL; ++} ++ ++int xc_dom_kernel_file(struct xc_dom_image *dom, const char *filename) ++{ ++ xc_dom_printf("%s: filename=\"%s\"\n", __FUNCTION__, filename); ++ dom->kernel_blob = xc_dom_malloc_filemap(dom, filename, &dom->kernel_size); ++ if (NULL == dom->kernel_blob) ++ return -1; ++ return xc_dom_try_gunzip(dom, &dom->kernel_blob, &dom->kernel_size); ++} ++ ++int xc_dom_ramdisk_file(struct xc_dom_image *dom, const char *filename) ++{ ++ xc_dom_printf("%s: filename=\"%s\"\n", __FUNCTION__, filename); ++ dom->ramdisk_blob = ++ xc_dom_malloc_filemap(dom, filename, &dom->ramdisk_size); ++ if (NULL == dom->ramdisk_blob) ++ return -1; ++// return xc_dom_try_gunzip(dom, &dom->ramdisk_blob, &dom->ramdisk_size); ++ return 0; ++} ++ ++int xc_dom_kernel_mem(struct xc_dom_image *dom, const void *mem, size_t memsize) ++{ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ dom->kernel_blob = (void *)mem; ++ dom->kernel_size = memsize; ++ return xc_dom_try_gunzip(dom, &dom->kernel_blob, &dom->kernel_size); ++} ++ ++int xc_dom_ramdisk_mem(struct xc_dom_image *dom, const void *mem, ++ size_t memsize) ++{ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ dom->ramdisk_blob = (void *)mem; ++ dom->ramdisk_size = memsize; ++// return xc_dom_try_gunzip(dom, &dom->ramdisk_blob, &dom->ramdisk_size); ++ return 0; ++} ++ ++int xc_dom_parse_image(struct xc_dom_image *dom) ++{ ++ int i; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ /* parse kernel image */ ++ dom->kernel_loader = xc_dom_find_loader(dom); ++ if (NULL == dom->kernel_loader) ++ goto err; ++ if (0 != dom->kernel_loader->parser(dom)) ++ goto err; ++ if (NULL == dom->guest_type) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "%s: guest_type not set\n", __FUNCTION__); ++ goto err; ++ } ++ ++ /* check features */ ++ for (i = 0; i < XENFEAT_NR_SUBMAPS; i++) ++ { ++ dom->f_active[i] |= dom->f_requested[i]; /* cmd line */ ++ dom->f_active[i] |= dom->parms.f_required[i]; /* kernel */ ++ if ((dom->f_active[i] & dom->parms.f_supported[i]) != dom->f_active[i]) ++ { ++ xc_dom_panic(XC_INVALID_PARAM, ++ "%s: unsupported feature requested\n", __FUNCTION__); ++ goto err; ++ } ++ } ++ return 0; ++ ++ err: ++ return -1; ++} ++ ++int xc_dom_mem_init(struct xc_dom_image *dom, unsigned int mem_mb) ++{ ++ unsigned int page_shift; ++ xen_pfn_t nr_pages, pfn; ++ ++ dom->arch_hooks = xc_dom_find_arch_hooks(dom->guest_type); ++ if (NULL == dom->arch_hooks) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, "%s: arch hooks not set\n", ++ __FUNCTION__); ++ return -1; ++ } ++ ++ page_shift = XC_DOM_PAGE_SHIFT(dom); ++ nr_pages = mem_mb << (20 - page_shift); ++ ++ xc_dom_printf("%s: mem %d MB, pages 0x%" PRIpfn " pages, %dk each\n", ++ __FUNCTION__, mem_mb, nr_pages, 1 << (page_shift-10)); ++ dom->total_pages = nr_pages; ++ ++ xc_dom_printf("%s: 0x%" PRIpfn " pages\n", ++ __FUNCTION__, dom->total_pages); ++ ++ /* setup initial p2m */ ++ dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * dom->total_pages); ++ for (pfn = 0; pfn < dom->total_pages; pfn++) ++ dom->p2m_host[pfn] = pfn; ++ return 0; ++} ++ ++int xc_dom_update_guest_p2m(struct xc_dom_image *dom) ++{ ++ uint32_t *p2m_32; ++ uint64_t *p2m_64; ++ xen_pfn_t i; ++ ++ if (!dom->p2m_guest) ++ return 0; ++ ++ switch (dom->arch_hooks->sizeof_pfn) ++ { ++ case 4: ++ xc_dom_printf("%s: dst 32bit, pages 0x%" PRIpfn " \n", ++ __FUNCTION__, dom->total_pages); ++ p2m_32 = dom->p2m_guest; ++ for (i = 0; i < dom->total_pages; i++) ++ if (INVALID_P2M_ENTRY != dom->p2m_host[i]) ++ p2m_32[i] = dom->p2m_host[i]; ++ else ++ p2m_32[i] = (uint32_t) - 1; ++ break; ++ case 8: ++ xc_dom_printf("%s: dst 64bit, pages 0x%" PRIpfn " \n", ++ __FUNCTION__, dom->total_pages); ++ p2m_64 = dom->p2m_guest; ++ for (i = 0; i < dom->total_pages; i++) ++ if (INVALID_P2M_ENTRY != dom->p2m_host[i]) ++ p2m_64[i] = dom->p2m_host[i]; ++ else ++ p2m_64[i] = (uint64_t) - 1; ++ break; ++ default: ++ xc_dom_panic(XC_INTERNAL_ERROR, ++ "sizeof_pfn is invalid (is %d, can be 4 or 8)", ++ dom->arch_hooks->sizeof_pfn); ++ return -1; ++ } ++ return 0; ++} ++ ++int xc_dom_build_image(struct xc_dom_image *dom) ++{ ++ unsigned int page_size; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ /* check for arch hooks */ ++ if (NULL == dom->arch_hooks) ++ { ++ xc_dom_panic(XC_INTERNAL_ERROR, "%s: arch hooks not set\n", ++ __FUNCTION__); ++ goto err; ++ } ++ page_size = XC_DOM_PAGE_SIZE(dom); ++ ++ /* 4MB align virtual base address */ ++ dom->parms.virt_base &= ~(((uint64_t)1<<22)-1); ++ ++ /* load kernel */ ++ if (0 != xc_dom_alloc_segment(dom, &dom->kernel_seg, "kernel", ++ dom->kernel_seg.vstart, ++ dom->kernel_seg.vend - ++ dom->kernel_seg.vstart)) ++ goto err; ++ if (0 != dom->kernel_loader->loader(dom)) ++ goto err; ++ ++ /* load ramdisk */ ++ if (dom->ramdisk_blob) ++ { ++ size_t unziplen, ramdisklen; ++ void *ramdiskmap; ++ ++ unziplen = xc_dom_check_gzip(dom->ramdisk_blob, dom->ramdisk_size); ++ ramdisklen = unziplen ? unziplen : dom->ramdisk_size; ++ if (0 != xc_dom_alloc_segment(dom, &dom->ramdisk_seg, "ramdisk", 0, ++ ramdisklen)) ++ goto err; ++ ramdiskmap = xc_dom_seg_to_ptr(dom, &dom->ramdisk_seg); ++ if (unziplen) ++ { ++ if (-1 == xc_dom_do_gunzip(dom->ramdisk_blob, dom->ramdisk_size, ++ ramdiskmap, ramdisklen)) ++ goto err; ++ } ++ else ++ memcpy(ramdiskmap, dom->ramdisk_blob, dom->ramdisk_size); ++ } ++ ++ /* allocate other pages */ ++ if (0 != dom->arch_hooks->alloc_magic_pages(dom)) ++ goto err; ++ if (dom->arch_hooks->count_pgtables) ++ { ++ dom->arch_hooks->count_pgtables(dom); ++ if (dom->pgtables > 0) ++ if (0 != ++ xc_dom_alloc_segment(dom, &dom->pgtables_seg, "page tables", 0, ++ dom->pgtables * page_size)) ++ goto err; ++ } ++ if (dom->alloc_bootstack) ++ dom->bootstack_pfn = xc_dom_alloc_page(dom, "boot stack"); ++ xc_dom_printf("%-20s: virt_alloc_end : 0x%" PRIx64 "\n", ++ __FUNCTION__, dom->virt_alloc_end); ++ xc_dom_printf("%-20s: virt_pgtab_end : 0x%" PRIx64 "\n", ++ __FUNCTION__, dom->virt_pgtab_end); ++ return 0; ++ ++ err: ++ return -1; ++} +Index: build-32-release304-13138/tools/libxc/xc_dom_ia64.c +=================================================================== +--- /dev/null ++++ build-32-release304-13138/tools/libxc/xc_dom_ia64.c +@@ -0,0 +1,119 @@ ++/* ++ * Xen domain builder -- ia64 bits. ++ * ++ * Most architecture-specific code for ia64 goes here. ++ * - fill architecture-specific structs. ++ * ++ * This code is licenced under the GPL. ++ * written 2006 by Gerd Hoffmann . ++ * ++ */ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "xg_private.h" ++#include "xc_dom.h" ++ ++/* ------------------------------------------------------------------------ */ ++ ++static int alloc_magic_pages(struct xc_dom_image *dom) ++{ ++ /* allocate special pages */ ++ dom->console_pfn = dom->total_pages -1; ++ dom->xenstore_pfn = dom->total_pages -2; ++ dom->start_info_pfn = dom->total_pages -3; ++ return 0; ++} ++ ++static int start_info_ia64(struct xc_dom_image *dom) ++{ ++ start_info_ia64_t *start_info = ++ xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1); ++ struct xen_ia64_boot_param_ia64 *bp = ++ (struct xen_ia64_boot_param_ia64 *)(start_info + 1); ++ ++ xc_dom_printf("%s\n", __FUNCTION__); ++ ++ memset(start_info, 0, sizeof(*start_info)); ++ sprintf(start_info->magic, dom->guest_type); ++ start_info->flags = dom->flags; ++ start_info->nr_pages = dom->total_pages; ++ start_info->store_mfn = dom->xenstore_pfn; ++ start_info->store_evtchn = dom->xenstore_evtchn; ++ start_info->console.domU.mfn = dom->console_pfn; ++ start_info->console.domU.evtchn = dom->console_evtchn; ++ ++ if (dom->ramdisk_blob) ++ { ++ start_info->mod_start = dom->ramdisk_seg.vstart; ++ start_info->mod_len = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart; ++ bp->initrd_start = start_info->mod_start; ++ bp->initrd_size = start_info->mod_len; ++ } ++ bp->command_line = (dom->start_info_pfn << PAGE_SHIFT_IA64) ++ + offsetof(start_info_t, cmd_line); ++ if (dom->cmdline) ++ { ++ strncpy((char *)start_info->cmd_line, dom->cmdline, MAX_GUEST_CMDLINE); ++ start_info->cmd_line[MAX_GUEST_CMDLINE - 1] = '\0'; ++ } ++ return 0; ++} ++ ++static int shared_info_ia64(struct xc_dom_image *dom, void *ptr) ++{ ++ shared_info_ia64_t *shared_info = ptr; ++ int i; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ memset(shared_info, 0, sizeof(*shared_info)); ++ for (i = 0; i < MAX_VIRT_CPUS; i++) ++ shared_info->vcpu_info[i].evtchn_upcall_mask = 1; ++ shared_info->arch.start_info_pfn = dom->start_info_pfn; ++ return 0; ++} ++ ++extern unsigned long xc_ia64_fpsr_default(void); ++ ++static int vcpu_ia64(struct xc_dom_image *dom, void *ptr) ++{ ++ vcpu_guest_context_ia64_t *ctxt = ptr; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ /* clear everything */ ++ memset(ctxt, 0, sizeof(*ctxt)); ++ ++ ctxt->flags = 0; ++ ctxt->user_regs.cr_ipsr = 0; /* all necessary bits filled by hypervisor */ ++ ctxt->user_regs.cr_iip = dom->parms.virt_entry; ++ ctxt->user_regs.cr_ifs = (uint64_t) 1 << 63; ++#ifdef __ia64__ /* FIXME */ ++ ctxt->user_regs.ar_fpsr = xc_ia64_fpsr_default(); ++#endif ++ ctxt->user_regs.r28 = (dom->start_info_pfn << PAGE_SHIFT_IA64) ++ + sizeof(start_info_ia64_t); ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++ ++static struct xc_dom_arch xc_dom_arch = { ++ .guest_type = "xen-3.0-ia64", ++ .page_shift = PAGE_SHIFT_IA64, ++ .alloc_magic_pages = alloc_magic_pages, ++ .start_info = start_info_ia64, ++ .shared_info = shared_info_ia64, ++ .vcpu = vcpu_ia64, ++}; ++ ++static void __init register_arch_hooks(void) ++{ ++ xc_dom_register_arch_hooks(&xc_dom_arch); ++} +Index: build-32-release304-13138/tools/libxc/xc_dom_x86.c +=================================================================== +--- /dev/null ++++ build-32-release304-13138/tools/libxc/xc_dom_x86.c +@@ -0,0 +1,561 @@ ++/* ++ * Xen domain builder -- i386 and x86_64 bits. ++ * ++ * Most architecture-specific code for x86 goes here. ++ * - prepare page tables. ++ * - fill architecture-specific structs. ++ * ++ * This code is licenced under the GPL. ++ * written 2006 by Gerd Hoffmann . ++ * ++ */ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "xg_private.h" ++#include "xc_dom.h" ++ ++/* ------------------------------------------------------------------------ */ ++ ++#define bits_to_mask(bits) (((xen_vaddr_t)1 << (bits))-1) ++#define round_down(addr, mask) ((addr) & ~(mask)) ++#define round_up(addr, mask) ((addr) | (mask)) ++ ++static inline unsigned long ++nr_page_tables(xen_vaddr_t start, xen_vaddr_t end, unsigned long bits) ++{ ++ xen_vaddr_t mask = bits_to_mask(bits); ++ int tables; ++ ++ if (0 == bits) ++ return 0; /* unused */ ++ ++ if (8 * sizeof(unsigned long) == bits) ++ { ++ /* must be pgd, need one */ ++ start = 0; ++ end = -1; ++ tables = 1; ++ } ++ else ++ { ++ start = round_down(start, mask); ++ end = round_up(end, mask); ++ tables = ((end - start) >> bits) + 1; ++ } ++ ++ xc_dom_printf("%s: 0x%016" PRIx64 "/%ld: 0x%016" PRIx64 ++ " -> 0x%016" PRIx64 ", %d table(s)\n", ++ __FUNCTION__, mask, bits, start, end, tables); ++ return tables; ++} ++ ++static int count_pgtables(struct xc_dom_image *dom, int pae, ++ int l4_bits, int l3_bits, int l2_bits, int l1_bits) ++{ ++ int pages, extra_pages; ++ xen_vaddr_t try_virt_end; ++ ++ extra_pages = dom->alloc_bootstack ? 1 : 0; ++ extra_pages += dom->extra_pages; ++ extra_pages += 128; /* 512kB padding */ ++ pages = extra_pages; ++ for (;;) ++ { ++ try_virt_end = round_up(dom->virt_alloc_end + pages * PAGE_SIZE_X86, ++ bits_to_mask(22)); /* 4MB alignment */ ++ dom->pg_l4 = ++ nr_page_tables(dom->parms.virt_base, try_virt_end, l4_bits); ++ dom->pg_l3 = ++ nr_page_tables(dom->parms.virt_base, try_virt_end, l3_bits); ++ dom->pg_l2 = ++ nr_page_tables(dom->parms.virt_base, try_virt_end, l2_bits); ++ dom->pg_l1 = ++ nr_page_tables(dom->parms.virt_base, try_virt_end, l1_bits); ++ if (pae && try_virt_end < 0xc0000000) ++ { ++ xc_dom_printf("%s: PAE: extra l2 page table for l3#3\n", __FUNCTION__); ++ dom->pg_l2++; ++ } ++ dom->pgtables = dom->pg_l4 + dom->pg_l3 + dom->pg_l2 + dom->pg_l1; ++ pages = dom->pgtables + extra_pages; ++ if (dom->virt_alloc_end + pages * PAGE_SIZE_X86 <= try_virt_end + 1) ++ break; ++ } ++ dom->virt_pgtab_end = try_virt_end + 1; ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* i386 pagetables */ ++ ++#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED) ++#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) ++#define L3_PROT (_PAGE_PRESENT) ++ ++static int count_pgtables_x86_32(struct xc_dom_image *dom) ++{ ++ return count_pgtables(dom, 0, 0, 0, 32, L2_PAGETABLE_SHIFT_I386); ++} ++ ++static int count_pgtables_x86_32_pae(struct xc_dom_image *dom) ++{ ++ return count_pgtables(dom, 1, 0, 32, ++ L3_PAGETABLE_SHIFT_PAE, L2_PAGETABLE_SHIFT_PAE); ++} ++ ++#define pfn_to_paddr(pfn) ((xen_paddr_t)(pfn) << PAGE_SHIFT_X86) ++ ++static int setup_pgtables_x86_32(struct xc_dom_image *dom) ++{ ++ xen_pfn_t l2pfn = dom->pgtables_seg.pfn; ++ xen_pfn_t l1pfn = dom->pgtables_seg.pfn + dom->pg_l2; ++ l2_pgentry_32_t *l2tab = xc_dom_pfn_to_ptr(dom, l2pfn, 1); ++ l1_pgentry_32_t *l1tab = NULL; ++ unsigned long l2off, l1off; ++ xen_vaddr_t addr; ++ xen_pfn_t pgpfn; ++ ++ for (addr = dom->parms.virt_base; addr < dom->virt_pgtab_end; ++ addr += PAGE_SIZE_X86) ++ { ++ if (NULL == l1tab) ++ { ++ /* get L1 tab, make L2 entry */ ++ l1tab = xc_dom_pfn_to_ptr(dom, l1pfn, 1); ++ l2off = l2_table_offset_i386(addr); ++ l2tab[l2off] = ++ pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT; ++ l1pfn++; ++ } ++ ++ /* make L1 entry */ ++ l1off = l1_table_offset_i386(addr); ++ pgpfn = (addr - dom->parms.virt_base) >> PAGE_SHIFT_X86; ++ l1tab[l1off] = ++ pfn_to_paddr(xc_dom_p2m_guest(dom, pgpfn)) | L1_PROT; ++ if (addr >= dom->pgtables_seg.vstart && addr < dom->pgtables_seg.vend) ++ l1tab[l1off] &= ~_PAGE_RW; /* page tables are r/o */ ++ if (L1_PAGETABLE_ENTRIES_I386 - 1 == l1off) ++ l1tab = NULL; ++ } ++ return 0; ++} ++ ++static int setup_pgtables_x86_32_pae(struct xc_dom_image *dom) ++{ ++ xen_pfn_t l3pfn = dom->pgtables_seg.pfn; ++ xen_pfn_t l2pfn = dom->pgtables_seg.pfn + dom->pg_l3; ++ xen_pfn_t l1pfn = dom->pgtables_seg.pfn + dom->pg_l3 + dom->pg_l2; ++ l3_pgentry_64_t *l3tab = xc_dom_pfn_to_ptr(dom, l3pfn, 1); ++ l2_pgentry_64_t *l2tab = NULL; ++ l1_pgentry_64_t *l1tab = NULL; ++ unsigned long l3off, l2off, l1off; ++ xen_vaddr_t addr; ++ xen_pfn_t pgpfn; ++ ++ for (addr = dom->parms.virt_base; addr < dom->virt_pgtab_end; ++ addr += PAGE_SIZE_X86) ++ { ++ if (NULL == l2tab) ++ { ++ /* get L2 tab, make L3 entry */ ++ l2tab = xc_dom_pfn_to_ptr(dom, l2pfn, 1); ++ l3off = l3_table_offset_pae(addr); ++ l3tab[l3off] = ++ pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT; ++ l2pfn++; ++ } ++ ++ if (NULL == l1tab) ++ { ++ /* get L1 tab, make L2 entry */ ++ l1tab = xc_dom_pfn_to_ptr(dom, l1pfn, 1); ++ l2off = l2_table_offset_pae(addr); ++ l2tab[l2off] = ++ pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT; ++ if (L2_PAGETABLE_ENTRIES_PAE - 1 == l2off) ++ l2tab = NULL; ++ l1pfn++; ++ } ++ ++ /* make L1 entry */ ++ l1off = l1_table_offset_pae(addr); ++ pgpfn = (addr - dom->parms.virt_base) >> PAGE_SHIFT_X86; ++ l1tab[l1off] = ++ pfn_to_paddr(xc_dom_p2m_guest(dom, pgpfn)) | L1_PROT; ++ if (addr >= dom->pgtables_seg.vstart && addr < dom->pgtables_seg.vend) ++ l1tab[l1off] &= ~_PAGE_RW; /* page tables are r/o */ ++ if (L1_PAGETABLE_ENTRIES_PAE - 1 == l1off) ++ l1tab = NULL; ++ } ++ ++ if (dom->virt_pgtab_end <= 0xc0000000) ++ { ++ xc_dom_printf("%s: PAE: extra l2 page table for l3#3\n", __FUNCTION__); ++ l3tab[3] = pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT; ++ } ++ return 0; ++} ++ ++#undef L1_PROT ++#undef L2_PROT ++#undef L3_PROT ++ ++/* ------------------------------------------------------------------------ */ ++/* x86_64 pagetables */ ++ ++static int count_pgtables_x86_64(struct xc_dom_image *dom) ++{ ++ return count_pgtables(dom, 0, ++ L4_PAGETABLE_SHIFT_X86_64 + 9, ++ L4_PAGETABLE_SHIFT_X86_64, ++ L3_PAGETABLE_SHIFT_X86_64, L2_PAGETABLE_SHIFT_X86_64); ++} ++ ++#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED) ++#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) ++#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) ++#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) ++ ++static int setup_pgtables_x86_64(struct xc_dom_image *dom) ++{ ++ xen_pfn_t l4pfn = dom->pgtables_seg.pfn; ++ xen_pfn_t l3pfn = dom->pgtables_seg.pfn + dom->pg_l4; ++ xen_pfn_t l2pfn = dom->pgtables_seg.pfn + dom->pg_l4 + dom->pg_l3; ++ xen_pfn_t l1pfn = ++ dom->pgtables_seg.pfn + dom->pg_l4 + dom->pg_l3 + dom->pg_l2; ++ l4_pgentry_64_t *l4tab = xc_dom_pfn_to_ptr(dom, l4pfn, 1); ++ l3_pgentry_64_t *l3tab = NULL; ++ l2_pgentry_64_t *l2tab = NULL; ++ l1_pgentry_64_t *l1tab = NULL; ++ uint64_t l4off, l3off, l2off, l1off; ++ uint64_t addr; ++ xen_pfn_t pgpfn; ++ ++ for (addr = dom->parms.virt_base; addr < dom->virt_pgtab_end; ++ addr += PAGE_SIZE_X86) ++ { ++ if (NULL == l3tab) ++ { ++ /* get L3 tab, make L4 entry */ ++ l3tab = xc_dom_pfn_to_ptr(dom, l3pfn, 1); ++ l4off = l4_table_offset_x86_64(addr); ++ l4tab[l4off] = ++ pfn_to_paddr(xc_dom_p2m_guest(dom, l3pfn)) | L4_PROT; ++ l3pfn++; ++ } ++ ++ if (NULL == l2tab) ++ { ++ /* get L2 tab, make L3 entry */ ++ l2tab = xc_dom_pfn_to_ptr(dom, l2pfn, 1); ++ l3off = l3_table_offset_x86_64(addr); ++ l3tab[l3off] = ++ pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT; ++ if (L3_PAGETABLE_ENTRIES_X86_64 - 1 == l3off) ++ l3tab = NULL; ++ l2pfn++; ++ } ++ ++ if (NULL == l1tab) ++ { ++ /* get L1 tab, make L2 entry */ ++ l1tab = xc_dom_pfn_to_ptr(dom, l1pfn, 1); ++ l2off = l2_table_offset_x86_64(addr); ++ l2tab[l2off] = ++ pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT; ++ if (L2_PAGETABLE_ENTRIES_X86_64 - 1 == l2off) ++ l2tab = NULL; ++ l1pfn++; ++ } ++ ++ /* make L1 entry */ ++ l1off = l1_table_offset_x86_64(addr); ++ pgpfn = (addr - dom->parms.virt_base) >> PAGE_SHIFT_X86; ++ l1tab[l1off] = ++ pfn_to_paddr(xc_dom_p2m_guest(dom, pgpfn)) | L1_PROT; ++ if (addr >= dom->pgtables_seg.vstart && addr < dom->pgtables_seg.vend) ++ l1tab[l1off] &= ~_PAGE_RW; /* page tables are r/o */ ++ if (L1_PAGETABLE_ENTRIES_X86_64 - 1 == l1off) ++ l1tab = NULL; ++ } ++ return 0; ++} ++ ++#undef L1_PROT ++#undef L2_PROT ++#undef L3_PROT ++#undef L4_PROT ++ ++/* ------------------------------------------------------------------------ */ ++ ++static int alloc_magic_pages(struct xc_dom_image *dom) ++{ ++ size_t p2m_size = dom->total_pages * dom->arch_hooks->sizeof_pfn; ++ ++ /* allocate phys2mach table */ ++ if (0 != xc_dom_alloc_segment(dom, &dom->p2m_seg, "phys2mach", 0, p2m_size)) ++ return -1; ++ dom->p2m_guest = xc_dom_seg_to_ptr(dom, &dom->p2m_seg); ++ ++ /* allocate special pages */ ++ dom->start_info_pfn = xc_dom_alloc_page(dom, "start info"); ++ dom->xenstore_pfn = xc_dom_alloc_page(dom, "xenstore"); ++ dom->console_pfn = xc_dom_alloc_page(dom, "console"); ++ if (xc_dom_feature_translated(dom)) ++ dom->shared_info_pfn = xc_dom_alloc_page(dom, "shared info"); ++ dom->alloc_bootstack = 1; ++ ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++ ++static int start_info_x86_32(struct xc_dom_image *dom) ++{ ++ start_info_x86_32_t *start_info = ++ xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1); ++ xen_pfn_t shinfo = ++ xc_dom_feature_translated(dom) ? dom->shared_info_pfn : dom-> ++ shared_info_mfn; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ sprintf(start_info->magic, dom->guest_type); ++ start_info->nr_pages = dom->total_pages; ++ start_info->shared_info = shinfo << PAGE_SHIFT_X86; ++ start_info->pt_base = dom->pgtables_seg.vstart; ++ start_info->nr_pt_frames = dom->pgtables; ++ start_info->mfn_list = dom->p2m_seg.vstart; ++ ++ start_info->flags = dom->flags; ++ start_info->store_mfn = xc_dom_p2m_guest(dom, dom->xenstore_pfn); ++ start_info->store_evtchn = dom->xenstore_evtchn; ++ start_info->console.domU.mfn = xc_dom_p2m_guest(dom, dom->console_pfn); ++ start_info->console.domU.evtchn = dom->console_evtchn; ++ ++ if (dom->ramdisk_blob) ++ { ++ start_info->mod_start = dom->ramdisk_seg.vstart; ++ start_info->mod_len = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart; ++ } ++ if (dom->cmdline) ++ { ++ strncpy((char *)start_info->cmd_line, dom->cmdline, MAX_GUEST_CMDLINE); ++ start_info->cmd_line[MAX_GUEST_CMDLINE - 1] = '\0'; ++ } ++ return 0; ++} ++ ++static int start_info_x86_64(struct xc_dom_image *dom) ++{ ++ start_info_x86_64_t *start_info = ++ xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1); ++ xen_pfn_t shinfo = ++ xc_dom_feature_translated(dom) ? dom->shared_info_pfn : dom-> ++ shared_info_mfn; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ sprintf(start_info->magic, dom->guest_type); ++ start_info->nr_pages = dom->total_pages; ++ start_info->shared_info = shinfo << PAGE_SHIFT_X86; ++ start_info->pt_base = dom->pgtables_seg.vstart; ++ start_info->nr_pt_frames = dom->pgtables; ++ start_info->mfn_list = dom->p2m_seg.vstart; ++ ++ start_info->flags = dom->flags; ++ start_info->store_mfn = xc_dom_p2m_guest(dom, dom->xenstore_pfn); ++ start_info->store_evtchn = dom->xenstore_evtchn; ++ start_info->console.domU.mfn = xc_dom_p2m_guest(dom, dom->console_pfn); ++ start_info->console.domU.evtchn = dom->console_evtchn; ++ ++ if (dom->ramdisk_blob) ++ { ++ start_info->mod_start = dom->ramdisk_seg.vstart; ++ start_info->mod_len = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart; ++ } ++ if (dom->cmdline) ++ { ++ strncpy((char *)start_info->cmd_line, dom->cmdline, MAX_GUEST_CMDLINE); ++ start_info->cmd_line[MAX_GUEST_CMDLINE - 1] = '\0'; ++ } ++ return 0; ++} ++ ++static int shared_info_x86_32(struct xc_dom_image *dom, void *ptr) ++{ ++ shared_info_x86_32_t *shared_info = ptr; ++ int i; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ memset(shared_info, 0, sizeof(*shared_info)); ++ for (i = 0; i < MAX_VIRT_CPUS; i++) ++ shared_info->vcpu_info[i].evtchn_upcall_mask = 1; ++ return 0; ++} ++ ++static int shared_info_x86_64(struct xc_dom_image *dom, void *ptr) ++{ ++ shared_info_x86_64_t *shared_info = ptr; ++ int i; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ memset(shared_info, 0, sizeof(*shared_info)); ++ for (i = 0; i < MAX_VIRT_CPUS; i++) ++ shared_info->vcpu_info[i].evtchn_upcall_mask = 1; ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++ ++static int vcpu_x86_32(struct xc_dom_image *dom, void *ptr) ++{ ++ vcpu_guest_context_x86_32_t *ctxt = ptr; ++ xen_pfn_t cr3_pfn; ++ int i; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ /* clear everything */ ++ memset(ctxt, 0, sizeof(*ctxt)); ++ ++ /* Virtual IDT is empty at start-of-day. */ ++ for (i = 0; i < 256; i++) ++ { ++ ctxt->trap_ctxt[i].vector = i; ++ ctxt->trap_ctxt[i].cs = FLAT_KERNEL_CS_X86_32; ++ } ++ ++ /* No callback handlers. */ ++ ctxt->event_callback_cs = FLAT_KERNEL_CS_X86_32; ++ ctxt->failsafe_callback_cs = FLAT_KERNEL_CS_X86_32; ++ ++ ctxt->user_regs.ds = FLAT_KERNEL_DS_X86_32; ++ ctxt->user_regs.es = FLAT_KERNEL_DS_X86_32; ++ ctxt->user_regs.fs = FLAT_KERNEL_DS_X86_32; ++ ctxt->user_regs.gs = FLAT_KERNEL_DS_X86_32; ++ ctxt->user_regs.ss = FLAT_KERNEL_SS_X86_32; ++ ctxt->user_regs.cs = FLAT_KERNEL_CS_X86_32; ++ ctxt->user_regs.eip = dom->parms.virt_entry; ++ ctxt->user_regs.esp = ++ dom->parms.virt_base + (dom->bootstack_pfn + 1) * PAGE_SIZE_X86; ++ ctxt->user_regs.esi = ++ dom->parms.virt_base + (dom->start_info_pfn) * PAGE_SIZE_X86; ++ ctxt->user_regs.eflags = 1 << 9; /* Interrupt Enable */ ++ ++ ctxt->kernel_ss = FLAT_KERNEL_SS_X86_32; ++ ctxt->kernel_sp = ++ dom->parms.virt_base + (dom->bootstack_pfn + 1) * PAGE_SIZE_X86; ++ ++ ctxt->flags = VGCF_in_kernel_X86_32; ++ if (dom->parms.pae == 2 /* extended_cr3 */ || ++ dom->parms.pae == 3 /* bimodal */) ++ ctxt->vm_assist |= (1UL << VMASST_TYPE_pae_extended_cr3); ++ ++ cr3_pfn = xc_dom_p2m_guest(dom, dom->pgtables_seg.pfn); ++ ctxt->ctrlreg[3] = xen_pfn_to_cr3_x86_32(cr3_pfn); ++ xc_dom_printf("%s: cr3: pfn 0x%" PRIpfn " mfn 0x%" PRIpfn "\n", ++ __FUNCTION__, dom->pgtables_seg.pfn, cr3_pfn); ++ ++ return 0; ++} ++ ++static int vcpu_x86_64(struct xc_dom_image *dom, void *ptr) ++{ ++ vcpu_guest_context_x86_64_t *ctxt = ptr; ++ xen_pfn_t cr3_pfn; ++ int i; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ /* clear everything */ ++ memset(ctxt, 0, sizeof(*ctxt)); ++ ++ /* Virtual IDT is empty at start-of-day. */ ++ for (i = 0; i < 256; i++) ++ { ++ ctxt->trap_ctxt[i].vector = i; ++ ctxt->trap_ctxt[i].cs = FLAT_KERNEL_CS_X86_64; ++ } ++ ++ ctxt->user_regs.ds = FLAT_KERNEL_DS_X86_64; ++ ctxt->user_regs.es = FLAT_KERNEL_DS_X86_64; ++ ctxt->user_regs.fs = FLAT_KERNEL_DS_X86_64; ++ ctxt->user_regs.gs = FLAT_KERNEL_DS_X86_64; ++ ctxt->user_regs.ss = FLAT_KERNEL_SS_X86_64; ++ ctxt->user_regs.cs = FLAT_KERNEL_CS_X86_64; ++ ctxt->user_regs.rip = dom->parms.virt_entry; ++ ctxt->user_regs.rsp = ++ dom->parms.virt_base + (dom->bootstack_pfn + 1) * PAGE_SIZE_X86; ++ ctxt->user_regs.rsi = ++ dom->parms.virt_base + (dom->start_info_pfn) * PAGE_SIZE_X86; ++ ctxt->user_regs.rflags = 1 << 9; /* Interrupt Enable */ ++ ++ ctxt->kernel_ss = FLAT_KERNEL_SS_X86_64; ++ ctxt->kernel_sp = ++ dom->parms.virt_base + (dom->bootstack_pfn + 1) * PAGE_SIZE_X86; ++ ++ ctxt->flags = VGCF_in_kernel_X86_64; ++ cr3_pfn = xc_dom_p2m_guest(dom, dom->pgtables_seg.pfn); ++ ctxt->ctrlreg[3] = xen_pfn_to_cr3_x86_64(cr3_pfn); ++ xc_dom_printf("%s: cr3: pfn 0x%" PRIpfn " mfn 0x%" PRIpfn "\n", ++ __FUNCTION__, dom->pgtables_seg.pfn, cr3_pfn); ++ ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++ ++static struct xc_dom_arch xc_dom_32 = { ++ .guest_type = "xen-3.0-x86_32", ++ .page_shift = PAGE_SHIFT_X86, ++ .sizeof_pfn = 4, ++ .alloc_magic_pages = alloc_magic_pages, ++ .count_pgtables = count_pgtables_x86_32, ++ .setup_pgtables = setup_pgtables_x86_32, ++ .start_info = start_info_x86_32, ++ .shared_info = shared_info_x86_32, ++ .vcpu = vcpu_x86_32, ++}; ++static struct xc_dom_arch xc_dom_32_pae = { ++ .guest_type = "xen-3.0-x86_32p", ++ .page_shift = PAGE_SHIFT_X86, ++ .sizeof_pfn = 4, ++ .alloc_magic_pages = alloc_magic_pages, ++ .count_pgtables = count_pgtables_x86_32_pae, ++ .setup_pgtables = setup_pgtables_x86_32_pae, ++ .start_info = start_info_x86_32, ++ .shared_info = shared_info_x86_32, ++ .vcpu = vcpu_x86_32, ++}; ++ ++static struct xc_dom_arch xc_dom_64 = { ++ .guest_type = "xen-3.0-x86_64", ++ .page_shift = PAGE_SHIFT_X86, ++ .sizeof_pfn = 8, ++ .alloc_magic_pages = alloc_magic_pages, ++ .count_pgtables = count_pgtables_x86_64, ++ .setup_pgtables = setup_pgtables_x86_64, ++ .start_info = start_info_x86_64, ++ .shared_info = shared_info_x86_64, ++ .vcpu = vcpu_x86_64, ++}; ++ ++static void __init register_arch_hooks(void) ++{ ++ xc_dom_register_arch_hooks(&xc_dom_32); ++ xc_dom_register_arch_hooks(&xc_dom_32_pae); ++ xc_dom_register_arch_hooks(&xc_dom_64); ++} +Index: build-32-release304-13138/tools/libxc/xc_dom_powerpc64.c +=================================================================== +--- /dev/null ++++ build-32-release304-13138/tools/libxc/xc_dom_powerpc64.c +@@ -0,0 +1,100 @@ ++/* ++ * Xen domain builder -- ia64 bits. ++ * ++ * Most architecture-specific code for ia64 goes here. ++ * - fill architecture-specific structs. ++ * ++ * This code is licenced under the GPL. ++ * written 2006 by Gerd Hoffmann . ++ * ++ */ ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "xg_private.h" ++#include "xc_dom.h" ++ ++/* ------------------------------------------------------------------------ */ ++ ++static int alloc_magic_pages(struct xc_dom_image *dom) ++{ ++ /* allocate special pages */ ++ dom->low_top--; /* shared_info */ ++ dom->xenstore_pfn = --dom->low_top; ++ dom->console_pfn = --dom->low_top; ++ dom->start_info_pfn = --dom->low_top; ++ return 0; ++} ++ ++static int start_info(struct xc_dom_image *dom) ++{ ++ start_info_t *si = ++ xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1); ++ ++ xc_dom_printf("%s\n", __FUNCTION__); ++ ++ snprintf(si->magic, sizeof(si->magic), "xen-%d.%d-powerpc64HV", 3, 0); ++ ++ si->nr_pages = dom->total_pages; ++ si->shared_info = (dom->total_pages - 1) << PAGE_SHIFT; ++ si->store_mfn = dom->xenstore_pfn; ++ si->store_evtchn = dom->store_evtchn; ++ si->console.domU.mfn = dom->console_pfn; ++ si->console.domU.evtchn = dom->console_evtchn; ++ return 0; ++} ++ ++static int shared_info(struct xc_dom_image *dom, void *ptr) ++{ ++ shared_info_t *shared_info = ptr; ++ int i; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ memset(shared_info, 0, sizeof(*shared_info)); ++ return 0; ++} ++ ++static int vcpu(struct xc_dom_image *dom, void *ptr) ++{ ++ vcpu_guest_context_t *ctxt = ptr; ++ ++ xc_dom_printf("%s: called\n", __FUNCTION__); ++ ++ /* clear everything */ ++ memset(ctxt, 0, sizeof(*ctxt)); ++ ++ memset(&ctxt->user_regs, 0x55, sizeof(ctxt.user_regs)); ++ ctxt->user_regs.pc = dsi->v_kernentry; ++ ctxt->user_regs.msr = 0; ++ ctxt->user_regs.gprs[1] = 0; /* Linux uses its own stack */ ++ ctxt->user_regs.gprs[3] = devtree_addr; ++ ctxt->user_regs.gprs[4] = kern_addr; ++ ctxt->user_regs.gprs[5] = 0; ++ ++ /* There is a buggy kernel that does not zero the "local_paca", so ++ * we must make sure this register is 0 */ ++ ctxt->user_regs.gprs[13] = 0; ++ ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++ ++static struct xc_dom_arch xc_dom_arch = { ++ .guest_type = "xen-3.0-powerpc64", ++ .page_shift = FIXME, ++ .alloc_magic_pages = alloc_magic_pages, ++ .start_info = start_info, ++ .shared_info = shared_info, ++ .vcpu = vcpu, ++}; ++ ++static void __init register_arch_hooks(void) ++{ ++ xc_dom_register_arch_hooks(&xc_dom_arch); ++} +Index: build-32-release304-13138/tools/libxc/xc_dom_elfloader.c +=================================================================== +--- /dev/null ++++ build-32-release304-13138/tools/libxc/xc_dom_elfloader.c +@@ -0,0 +1,283 @@ ++/* ++ * Xen domain builder -- ELF bits. ++ * ++ * Parse and load ELF kernel images. ++ * ++ * This code is licenced under the GPL. ++ * written 2006 by Gerd Hoffmann . ++ * ++ */ ++#include ++#include ++#include ++ ++#include "xg_private.h" ++#include "xc_dom.h" ++ ++#define XEN_VER "xen-3.0" ++ ++/* ------------------------------------------------------------------------ */ ++ ++static char *xc_dom_guest_type(struct xc_dom_image *dom, ++ struct elf_binary *elf) ++{ ++ uint64_t machine = elf_uval(elf, elf->ehdr, e_machine); ++ ++ switch (machine) { ++ case EM_386: ++ switch (dom->parms.pae) { ++ case 3 /* PAEKERN_bimodal */: ++ if (strstr(dom->xen_caps, "xen-3.0-x86_32p")) ++ return "xen-3.0-x86_32p"; ++ return "xen-3.0-x86_32"; ++ case PAEKERN_extended_cr3: ++ case PAEKERN_yes: ++ return "xen-3.0-x86_32p"; ++ break; ++ case PAEKERN_no: ++ default: ++ return "xen-3.0-x86_32"; ++ } ++ case EM_X86_64: ++ return "xen-3.0-x86_64"; ++ case EM_IA_64: ++ return elf_msb(elf) ? "xen-3.0-ia64be" : "xen-3.0-ia64"; ++ case EM_PPC64: ++ return "xen-3.0-powerpc64"; ++ default: ++ return "xen-3.0-unknown"; ++ } ++} ++ ++/* ------------------------------------------------------------------------ */ ++/* parse elf binary */ ++ ++static int check_elf_kernel(struct xc_dom_image *dom, int verbose) ++{ ++ if (NULL == dom->kernel_blob) ++ { ++ if (verbose) ++ xc_dom_panic(XC_INTERNAL_ERROR, "%s: no kernel image loaded\n", ++ __FUNCTION__); ++ return -EINVAL; ++ } ++ ++ if (!elf_is_elfbinary(dom->kernel_blob)) ++ { ++ if (verbose) ++ xc_dom_panic(XC_INVALID_KERNEL, "%s: kernel is not an ELF image\n", ++ __FUNCTION__); ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static int xc_dom_probe_elf_kernel(struct xc_dom_image *dom) ++{ ++ return check_elf_kernel(dom, 0); ++} ++ ++static int xc_dom_load_elf_symtab(struct xc_dom_image *dom, ++ struct elf_binary *elf, int load) ++{ ++ struct elf_binary syms; ++ const elf_shdr *shdr, *shdr2; ++ xen_vaddr_t symtab, maxaddr; ++ char *hdr; ++ size_t size; ++ int h, count, type, i, tables = 0; ++ ++ if (elf_swap(elf)) { ++ xc_dom_printf("%s: non-native byte order, bsd symtab not supported\n", ++ __FUNCTION__); ++ return 0; ++ } ++ ++ if (load) { ++ if (!dom->bsd_symtab_start) ++ return 0; ++ size = dom->kernel_seg.vend - dom->bsd_symtab_start; ++ hdr = xc_dom_vaddr_to_ptr(dom, dom->bsd_symtab_start); ++ *(int *)hdr = size - sizeof(int); ++ } else { ++ size = sizeof(int) + elf_size(elf, elf->ehdr) + ++ elf_shdr_count(elf) * elf_size(elf, shdr); ++ hdr = xc_dom_malloc(dom, size); ++ if (hdr == NULL) ++ return 0; ++ dom->bsd_symtab_start = elf_round_up(&syms, dom->kernel_seg.vend); ++ } ++ ++ memcpy(hdr + sizeof(int), ++ elf->image, ++ elf_size(elf, elf->ehdr)); ++ memcpy(hdr + sizeof(int) + elf_size(elf, elf->ehdr), ++ elf->image + elf_uval(elf, elf->ehdr, e_shoff), ++ elf_shdr_count(elf) * elf_size(elf, shdr)); ++ if (elf_64bit(elf)) { ++ Elf64_Ehdr *ehdr = (Elf64_Ehdr *)(hdr + sizeof(int)); ++ ehdr->e_phoff = 0; ++ ehdr->e_phentsize = 0; ++ ehdr->e_phnum = 0; ++ ehdr->e_shoff = elf_size(elf, elf->ehdr); ++ ehdr->e_shstrndx = SHN_UNDEF; ++ } else { ++ Elf32_Ehdr *ehdr = (Elf32_Ehdr *)(hdr + sizeof(int)); ++ ehdr->e_phoff = 0; ++ ehdr->e_phentsize = 0; ++ ehdr->e_phnum = 0; ++ ehdr->e_shoff = elf_size(elf, elf->ehdr); ++ ehdr->e_shstrndx = SHN_UNDEF; ++ } ++ if (0 != elf_init(&syms, hdr + sizeof(int), size - sizeof(int))) ++ return -1; ++ if (xc_dom_logfile) ++ elf_set_logfile(&syms, xc_dom_logfile, 1); ++ ++ symtab = dom->bsd_symtab_start + sizeof(int); ++ maxaddr = elf_round_up(&syms, symtab + elf_size(&syms, syms.ehdr) + ++ elf_shdr_count(&syms) * elf_size(&syms, shdr)); ++ ++ xc_dom_printf("%s/%s: bsd_symtab_start=%" PRIx64 ", kernel.end=0x%" PRIx64 ++ " -- symtab=0x%" PRIx64 ", maxaddr=0x%" PRIx64 "\n", ++ __FUNCTION__, load ? "load" : "parse", ++ dom->bsd_symtab_start, dom->kernel_seg.vend, symtab, maxaddr); ++ ++ count = elf_shdr_count(&syms); ++ for (h = 0; h < count; h++) ++ { ++ shdr = elf_shdr_by_index(&syms, h); ++ type = elf_uval(&syms, shdr, sh_type); ++ if (type == SHT_STRTAB) ++ { ++ /* Look for a strtab @i linked to symtab @h. */ ++ for (i = 0; i < count; i++) { ++ shdr2 = elf_shdr_by_index(&syms, i); ++ if ((elf_uval(&syms, shdr2, sh_type) == SHT_SYMTAB) && ++ (elf_uval(&syms, shdr2, sh_link) == h)) ++ break; ++ } ++ /* Skip symtab @h if we found no corresponding strtab @i. */ ++ if (i == count) ++ { ++ if (elf_64bit(&syms)) ++ *(Elf64_Off*)(&shdr->e64.sh_offset) = 0; ++ else ++ *(Elf32_Off*)(&shdr->e32.sh_offset) = 0; ++ continue; ++ } ++ } ++ ++ if ((type == SHT_STRTAB) || (type == SHT_SYMTAB)) ++ { ++ /* Mangled to be based on ELF header location. */ ++ if (elf_64bit(&syms)) ++ *(Elf64_Off*)(&shdr->e64.sh_offset) = maxaddr - symtab; ++ else ++ *(Elf32_Off*)(&shdr->e32.sh_offset) = maxaddr - symtab; ++ size = elf_uval(&syms, shdr, sh_size); ++ maxaddr = elf_round_up(&syms, maxaddr + size); ++ tables++; ++ xc_dom_printf("%s: h=%d %s, size=0x%zx, maxaddr=0x%" PRIx64 "\n", ++ __FUNCTION__, h, ++ type == SHT_SYMTAB ? "symtab" : "strtab", ++ size, maxaddr); ++ ++ if (load) { ++ shdr2 = elf_shdr_by_index(elf, h); ++ memcpy((void*)elf_section_start(&syms, shdr), ++ elf_section_start(elf, shdr2), ++ size); ++ } ++ } ++ ++ /* Name is NULL. */ ++ if (elf_64bit(&syms)) ++ *(Elf64_Half*)(&shdr->e64.sh_name) = 0; ++ else ++ *(Elf32_Word*)(&shdr->e32.sh_name) = 0; ++ } ++ ++ if (0 == tables) ++ { ++ xc_dom_printf("%s: no symbol table present\n", __FUNCTION__); ++ dom->bsd_symtab_start = 0; ++ return 0; ++ } ++ if (!load) ++ dom->kernel_seg.vend = maxaddr; ++ return 0; ++} ++ ++static int xc_dom_parse_elf_kernel(struct xc_dom_image *dom) ++{ ++ struct elf_binary *elf; ++ int rc; ++ ++ rc = check_elf_kernel(dom, 1); ++ if (0 != rc) ++ return rc; ++ ++ elf = xc_dom_malloc(dom, sizeof(*elf)); ++ dom->private_loader = elf; ++ rc = elf_init(elf, dom->kernel_blob, dom->kernel_size); ++ if (xc_dom_logfile) ++ elf_set_logfile(elf, xc_dom_logfile, 1); ++ if (0 != rc) ++ { ++ xc_dom_panic(XC_INVALID_KERNEL, "%s: corrupted ELF image\n", ++ __FUNCTION__); ++ return rc; ++ } ++ ++ /* Find the section-header strings table. */ ++ if (NULL == elf->sec_strtab) ++ { ++ xc_dom_panic(XC_INVALID_KERNEL, "%s: ELF image has no shstrtab\n", ++ __FUNCTION__); ++ return -EINVAL; ++ } ++ ++ /* parse binary and get xen meta info */ ++ elf_parse_binary(elf); ++ if (0 != (rc = elf_xen_parse(elf, &dom->parms))) ++ return rc; ++ ++ /* find kernel segment */ ++ dom->kernel_seg.vstart = dom->parms.virt_kstart; ++ dom->kernel_seg.vend = dom->parms.virt_kend; ++ ++ if (dom->parms.bsd_symtab) ++ xc_dom_load_elf_symtab(dom, elf, 0); ++ ++ dom->guest_type = xc_dom_guest_type(dom, elf); ++ xc_dom_printf("%s: %s: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", ++ __FUNCTION__, dom->guest_type, ++ dom->kernel_seg.vstart, dom->kernel_seg.vend); ++ return 0; ++} ++ ++static int xc_dom_load_elf_kernel(struct xc_dom_image *dom) ++{ ++ struct elf_binary *elf = dom->private_loader; ++ ++ elf->dest = xc_dom_seg_to_ptr(dom, &dom->kernel_seg); ++ elf_load_binary(elf); ++ if (dom->parms.bsd_symtab) ++ xc_dom_load_elf_symtab(dom, elf, 1); ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++ ++static struct xc_dom_loader elf_loader = { ++ .name = "ELF-generic", ++ .probe = xc_dom_probe_elf_kernel, ++ .parser = xc_dom_parse_elf_kernel, ++ .loader = xc_dom_load_elf_kernel, ++}; ++ ++static void __init register_loader(void) ++{ ++ xc_dom_register_loader(&elf_loader); ++} +Index: build-32-release304-13138/tools/libxc/xc_dom_binloader.c +=================================================================== +--- /dev/null ++++ build-32-release304-13138/tools/libxc/xc_dom_binloader.c +@@ -0,0 +1,294 @@ ++/****************************************************************************** ++ * ++ * Loads simple binary images. It's like a .COM file in MS-DOS. No headers are ++ * present. The only requirement is that it must have a xen_bin_image table ++ * somewhere in the first 8192 bytes, starting on a 32-bit aligned address. ++ * Those familiar with the multiboot specification should recognize this, it's ++ * (almost) the same as the multiboot header. ++ * The layout of the xen_bin_image table is: ++ * ++ * Offset Type Name Note ++ * 0 uint32_t magic required ++ * 4 uint32_t flags required ++ * 8 uint32_t checksum required ++ * 12 uint32_t header_addr required ++ * 16 uint32_t load_addr required ++ * 20 uint32_t load_end_addr required ++ * 24 uint32_t bss_end_addr required ++ * 28 uint32_t entry_addr required ++ * ++ * - magic ++ * Magic number identifying the table. For images to be loaded by Xen 3, the ++ * magic value is 0x336ec578 ("xEn3" with the 0x80 bit of the "E" set). ++ * - flags ++ * bit 0: indicates whether the image needs to be loaded on a page boundary ++ * bit 1: reserved, must be 0 (the multiboot spec uses this bit to indicate ++ * that memory info should be passed to the image) ++ * bit 2: reserved, must be 0 (the multiboot spec uses this bit to indicate ++ * that the bootloader should pass video mode info to the image) ++ * bit 16: reserved, must be 1 (the multiboot spec uses this bit to indicate ++ * that the values in the fields header_addr - entry_addr are ++ * valid) ++ * All other bits should be set to 0. ++ * - checksum ++ * When added to "magic" and "flags", the resulting value should be 0. ++ * - header_addr ++ * Contains the virtual address corresponding to the beginning of the ++ * table - the memory location at which the magic value is supposed to be ++ * loaded. This field serves to synchronize the mapping between OS image ++ * offsets and virtual memory addresses. ++ * - load_addr ++ * Contains the virtual address of the beginning of the text segment. The ++ * offset in the OS image file at which to start loading is defined by the ++ * offset at which the table was found, minus (header addr - load addr). ++ * load addr must be less than or equal to header addr. ++ * - load_end_addr ++ * Contains the virtual address of the end of the data segment. ++ * (load_end_addr - load_addr) specifies how much data to load. This implies ++ * that the text and data segments must be consecutive in the OS image. If ++ * this field is zero, the domain builder assumes that the text and data ++ * segments occupy the whole OS image file. ++ * - bss_end_addr ++ * Contains the virtual address of the end of the bss segment. The domain ++ * builder initializes this area to zero, and reserves the memory it occupies ++ * to avoid placing boot modules and other data relevant to the loaded image ++ * in that area. If this field is zero, the domain builder assumes that no bss ++ * segment is present. ++ * - entry_addr ++ * The virtual address at which to start execution of the loaded image. ++ * ++ * Some of the field descriptions were copied from "The Multiboot ++ * Specification", Copyright 1995, 96 Bryan Ford , ++ * Erich Stefan Boleyn Copyright 1999, 2000, 2001, 2002 ++ * Free Software Foundation, Inc. ++ */ ++ ++#include ++#include ++ ++#include "xg_private.h" ++#include "xc_dom.h" ++ ++#define round_pgup(_p) (((_p)+(PAGE_SIZE_X86-1))&PAGE_MASK_X86) ++#define round_pgdown(_p) ((_p)&PAGE_MASK_X86) ++ ++struct xen_bin_image_table ++{ ++ uint32_t magic; ++ uint32_t flags; ++ uint32_t checksum; ++ uint32_t header_addr; ++ uint32_t load_addr; ++ uint32_t load_end_addr; ++ uint32_t bss_end_addr; ++ uint32_t entry_addr; ++}; ++ ++#define XEN_MULTIBOOT_MAGIC3 0x336ec578 ++ ++#define XEN_MULTIBOOT_FLAG_ALIGN4K 0x00000001 ++#define XEN_MULTIBOOT_FLAG_NEEDMEMINFO 0x00000002 ++#define XEN_MULTIBOOT_FLAG_NEEDVIDINFO 0x00000004 ++#define XEN_MULTIBOOT_FLAG_ADDRSVALID 0x00010000 ++#define XEN_MULTIBOOT_FLAG_PAE_SHIFT 14 ++#define XEN_MULTIBOOT_FLAG_PAE_MASK (3 << XEN_MULTIBOOT_FLAG_PAE_SHIFT) ++ ++/* Flags we test for */ ++#define FLAGS_MASK ((~ 0) & (~ XEN_MULTIBOOT_FLAG_ALIGN4K) & \ ++ (~ XEN_MULTIBOOT_FLAG_PAE_MASK)) ++#define FLAGS_REQUIRED XEN_MULTIBOOT_FLAG_ADDRSVALID ++ ++/* --------------------------------------------------------------------- */ ++ ++static struct xen_bin_image_table *find_table(struct xc_dom_image *dom) ++{ ++ struct xen_bin_image_table *table; ++ uint32_t *probe_ptr; ++ uint32_t *probe_end; ++ ++ probe_ptr = dom->kernel_blob; ++ probe_end = dom->kernel_blob + dom->kernel_size - sizeof(*table); ++ if ((void*)probe_end > dom->kernel_blob + 8192) ++ probe_end = dom->kernel_blob + 8192; ++ ++ for (table = NULL; probe_ptr < probe_end; probe_ptr++) ++ { ++ if (XEN_MULTIBOOT_MAGIC3 == *probe_ptr) ++ { ++ table = (struct xen_bin_image_table *) probe_ptr; ++ /* Checksum correct? */ ++ if (0 == table->magic + table->flags + table->checksum) ++ { ++ return table; ++ } ++ } ++ } ++ return NULL; ++} ++ ++static int xc_dom_probe_bin_kernel(struct xc_dom_image *dom) ++{ ++ struct xen_bin_image_table *table; ++ ++ table = find_table(dom); ++ if (!table) ++ return -EINVAL; ++ return 0; ++} ++ ++static int xc_dom_parse_bin_kernel(struct xc_dom_image *dom) ++{ ++ struct xen_bin_image_table *image_info; ++ char *image = dom->kernel_blob; ++ size_t image_size = dom->kernel_size; ++ uint32_t start_addr; ++ uint32_t load_end_addr; ++ uint32_t bss_end_addr; ++ uint32_t pae_flags; ++ ++ image_info = find_table(dom); ++ if (!image_info) ++ return -EINVAL; ++ ++ xc_dom_printf("%s: multiboot header fields\n", __FUNCTION__); ++ xc_dom_printf(" flags: 0x%" PRIx32 "\n", image_info->flags); ++ xc_dom_printf(" header_addr: 0x%" PRIx32 "\n", image_info->header_addr); ++ xc_dom_printf(" load_addr: 0x%" PRIx32 "\n", image_info->load_addr); ++ xc_dom_printf(" load_end_addr: 0x%" PRIx32 "\n", image_info->load_end_addr); ++ xc_dom_printf(" bss_end_addr: 0x%" PRIx32 "\n", image_info->bss_end_addr); ++ xc_dom_printf(" entry_addr: 0x%" PRIx32 "\n", image_info->entry_addr); ++ ++ /* Check the flags */ ++ if ( FLAGS_REQUIRED != (image_info->flags & FLAGS_MASK) ) ++ { ++ xc_dom_panic(XC_INVALID_KERNEL, ++ "%s: xen_bin_image_table flags required " ++ "0x%08" PRIx32 " found 0x%08" PRIx32 "\n", ++ __FUNCTION__, FLAGS_REQUIRED, image_info->flags & FLAGS_MASK); ++ return -EINVAL; ++ } ++ ++ /* Sanity check on the addresses */ ++ if ( image_info->header_addr < image_info->load_addr || ++ ((char *) image_info - image) < ++ (image_info->header_addr - image_info->load_addr) ) ++ { ++ xc_dom_panic(XC_INVALID_KERNEL, "%s: Invalid header_addr.", ++ __FUNCTION__); ++ return -EINVAL; ++ } ++ ++ start_addr = image_info->header_addr - ((char *)image_info - image); ++ load_end_addr = image_info->load_end_addr ?: start_addr + image_size; ++ bss_end_addr = image_info->bss_end_addr ?: load_end_addr; ++ ++ xc_dom_printf("%s: calculated addresses\n", __FUNCTION__); ++ xc_dom_printf(" start_addr: 0x%" PRIx32 "\n", start_addr); ++ xc_dom_printf(" load_end_addr: 0x%" PRIx32 "\n", load_end_addr); ++ xc_dom_printf(" bss_end_addr: 0x%" PRIx32 "\n", bss_end_addr); ++ ++ if ( start_addr + image_size < load_end_addr ) ++ { ++ xc_dom_panic(XC_INVALID_KERNEL, "%s: Invalid load_end_addr.\n", ++ __FUNCTION__); ++ return -EINVAL; ++ } ++ ++ if ( bss_end_addr < load_end_addr) ++ { ++ xc_dom_panic(XC_INVALID_KERNEL, "%s: Invalid bss_end_addr.\n", ++ __FUNCTION__); ++ return -EINVAL; ++ } ++ ++ dom->kernel_seg.vstart = image_info->load_addr; ++ dom->kernel_seg.vend = bss_end_addr; ++ dom->parms.virt_base = start_addr; ++ dom->parms.virt_entry = image_info->entry_addr; ++ ++ pae_flags = image_info->flags & XEN_MULTIBOOT_FLAG_PAE_MASK; ++ switch (pae_flags >> XEN_MULTIBOOT_FLAG_PAE_SHIFT) { ++ case 0: ++ dom->guest_type = "xen-3.0-x86_32"; ++ break; ++ case 1: ++ dom->guest_type = "xen-3.0-x86_32p"; ++ break; ++ case 2: ++ dom->guest_type = "xen-3.0-x86_64"; ++ break; ++ case 3: ++ /* Kernel detects PAE at runtime. So try to figure whenever ++ * xen supports PAE and advertise a PAE-capable kernel in case ++ * it does. */ ++ dom->guest_type = "xen-3.0-x86_32"; ++ if (strstr(dom->xen_caps, "xen-3.0-x86_32p")) { ++ xc_dom_printf("%s: PAE fixup\n", __FUNCTION__); ++ dom->guest_type = "xen-3.0-x86_32p"; ++ dom->parms.pae = 2; ++ } ++ break; ++ } ++ return 0; ++} ++ ++static int xc_dom_load_bin_kernel(struct xc_dom_image *dom) ++{ ++ struct xen_bin_image_table *image_info; ++ char *image = dom->kernel_blob; ++ char *dest; ++ size_t image_size = dom->kernel_size; ++ uint32_t start_addr; ++ uint32_t load_end_addr; ++ uint32_t bss_end_addr; ++ uint32_t skip, text_size, bss_size; ++ uint32_t pae_flags; ++ ++ image_info = find_table(dom); ++ if (!image_info) ++ return -EINVAL; ++ ++ start_addr = image_info->header_addr - ((char *)image_info - image); ++ load_end_addr = image_info->load_end_addr ?: start_addr + image_size; ++ bss_end_addr = image_info->bss_end_addr ?: load_end_addr; ++ ++ /* It's possible that we need to skip the first part of the image */ ++ skip = image_info->load_addr - start_addr; ++ text_size = load_end_addr - image_info->load_addr; ++ bss_size = bss_end_addr - load_end_addr; ++ ++ xc_dom_printf("%s: calculated sizes\n", __FUNCTION__); ++ xc_dom_printf(" skip: 0x%" PRIx32 "\n", skip); ++ xc_dom_printf(" text_size: 0x%" PRIx32 "\n", text_size); ++ xc_dom_printf(" bss_size: 0x%" PRIx32 "\n", bss_size); ++ ++ dest = xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart); ++ memcpy(dest, image + skip, text_size); ++ memset(dest + text_size, 0, bss_size); ++ ++ pae_flags = image_info->flags & XEN_MULTIBOOT_FLAG_PAE_MASK; ++ if (3 == (pae_flags >> XEN_MULTIBOOT_FLAG_PAE_SHIFT) && dom->guest_xc > 0) ++ { ++ } ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++ ++static struct xc_dom_loader bin_loader = { ++ .name = "multiboot-binary", ++ .probe = xc_dom_probe_bin_kernel, ++ .parser = xc_dom_parse_bin_kernel, ++ .loader = xc_dom_load_bin_kernel, ++}; ++ ++static void __init register_loader(void) ++{ ++ xc_dom_register_loader(&bin_loader); ++} ++ ++/* ++ * Local variables: ++ * c-basic-offset: 4 ++ * End: ++ */ diff --git a/tools-domain-builder-header-libxc.diff b/tools-domain-builder-header-libxc.diff new file mode 100644 index 0000000..ac24536 --- /dev/null +++ b/tools-domain-builder-header-libxc.diff @@ -0,0 +1,165 @@ +libxc header fixups. + +Make some arch-specific #defines for page table handling +available unconditionally, add a suffix to avoid name clashes. + +The versions without suffix are defined depending on the +architecture like they used to, so code using them continues +to work. + +Signed-off-by: Gerd Hoffmann +--- + tools/libxc/xg_private.h | 114 +++++++++++++++++++++++++++-------------------- + 1 file changed, 67 insertions(+), 47 deletions(-) + +Index: build-32-unstable-11822/tools/libxc/xg_private.h +=================================================================== +--- build-32-unstable-11822.orig/tools/libxc/xg_private.h ++++ build-32-unstable-11822/tools/libxc/xg_private.h +@@ -46,37 +46,41 @@ unsigned long csum_page (void * page); + #define _PAGE_PSE 0x080 + #define _PAGE_GLOBAL 0x100 + +-#define L1_PAGETABLE_SHIFT_PAE 12 +-#define L2_PAGETABLE_SHIFT_PAE 21 +-#define L3_PAGETABLE_SHIFT_PAE 30 +- +-#define L2_PAGETABLE_SHIFT_I386 22 +- +-#if defined(__i386__) +-#define L1_PAGETABLE_SHIFT 12 +-#define L2_PAGETABLE_SHIFT 22 +-#elif defined(__x86_64__) +-#define L1_PAGETABLE_SHIFT 12 +-#define L2_PAGETABLE_SHIFT 21 +-#define L3_PAGETABLE_SHIFT 30 +-#define L4_PAGETABLE_SHIFT 39 +-#endif ++#define L1_PAGETABLE_SHIFT_I386 12 ++#define L2_PAGETABLE_SHIFT_I386 22 ++#define L1_PAGETABLE_ENTRIES_I386 1024 ++#define L2_PAGETABLE_ENTRIES_I386 1024 + +-#define L1_PAGETABLE_ENTRIES_PAE 512 +-#define L2_PAGETABLE_ENTRIES_PAE 512 +-#define L3_PAGETABLE_ENTRIES_PAE 4 ++#define L1_PAGETABLE_SHIFT_PAE 12 ++#define L2_PAGETABLE_SHIFT_PAE 21 ++#define L3_PAGETABLE_SHIFT_PAE 30 ++#define L1_PAGETABLE_ENTRIES_PAE 512 ++#define L2_PAGETABLE_ENTRIES_PAE 512 ++#define L3_PAGETABLE_ENTRIES_PAE 4 + +-#define L1_PAGETABLE_ENTRIES_I386 1024 +-#define L2_PAGETABLE_ENTRIES_I386 1024 ++#define L1_PAGETABLE_SHIFT_X86_64 12 ++#define L2_PAGETABLE_SHIFT_X86_64 21 ++#define L3_PAGETABLE_SHIFT_X86_64 30 ++#define L4_PAGETABLE_SHIFT_X86_64 39 ++#define L1_PAGETABLE_ENTRIES_X86_64 512 ++#define L2_PAGETABLE_ENTRIES_X86_64 512 ++#define L3_PAGETABLE_ENTRIES_X86_64 512 ++#define L4_PAGETABLE_ENTRIES_X86_64 512 + + #if defined(__i386__) +-#define L1_PAGETABLE_ENTRIES 1024 +-#define L2_PAGETABLE_ENTRIES 1024 ++#define L1_PAGETABLE_SHIFT L1_PAGETABLE_SHIFT_I386 ++#define L2_PAGETABLE_SHIFT L2_PAGETABLE_SHIFT_I386 ++#define L1_PAGETABLE_ENTRIES L1_PAGETABLE_ENTRIES_I386 ++#define L2_PAGETABLE_ENTRIES L2_PAGETABLE_ENTRIES_I386 + #elif defined(__x86_64__) +-#define L1_PAGETABLE_ENTRIES 512 +-#define L2_PAGETABLE_ENTRIES 512 +-#define L3_PAGETABLE_ENTRIES 512 +-#define L4_PAGETABLE_ENTRIES 512 ++#define L1_PAGETABLE_SHIFT L1_PAGETABLE_SHIFT_X86_64 ++#define L2_PAGETABLE_SHIFT L2_PAGETABLE_SHIFT_X86_64 ++#define L3_PAGETABLE_SHIFT L3_PAGETABLE_SHIFT_X86_64 ++#define L4_PAGETABLE_SHIFT L4_PAGETABLE_SHIFT_X86_64 ++#define L1_PAGETABLE_ENTRIES L1_PAGETABLE_ENTRIES_X86_64 ++#define L2_PAGETABLE_ENTRIES L2_PAGETABLE_ENTRIES_X86_64 ++#define L3_PAGETABLE_ENTRIES L3_PAGETABLE_ENTRIES_X86_64 ++#define L4_PAGETABLE_ENTRIES L4_PAGETABLE_ENTRIES_X86_64 + #endif + + typedef uint32_t l1_pgentry_32_t; +@@ -84,13 +88,23 @@ typedef uint32_t l2_pgentry_32_t; + typedef uint64_t l1_pgentry_64_t; + typedef uint64_t l2_pgentry_64_t; + typedef uint64_t l3_pgentry_64_t; +-typedef unsigned long l1_pgentry_t; +-typedef unsigned long l2_pgentry_t; +-#if defined(__x86_64__) +-typedef unsigned long l3_pgentry_t; +-typedef unsigned long l4_pgentry_t; ++typedef uint64_t l4_pgentry_64_t; ++ ++#if defined(__i386__) ++typedef l1_pgentry_32_t l1_pgentry_t; ++typedef l2_pgentry_32_t l2_pgentry_t; ++#elif defined(__x86_64__) ++typedef l1_pgentry_64_t l1_pgentry_t; ++typedef l2_pgentry_64_t l2_pgentry_t; ++typedef l3_pgentry_64_t l3_pgentry_t; ++typedef l4_pgentry_64_t l4_pgentry_t; + #endif + ++#define l1_table_offset_i386(_a) \ ++ (((_a) >> L1_PAGETABLE_SHIFT_I386) & (L1_PAGETABLE_ENTRIES_I386 - 1)) ++#define l2_table_offset_i386(_a) \ ++ (((_a) >> L2_PAGETABLE_SHIFT_I386) & (L2_PAGETABLE_ENTRIES_I386 - 1)) ++ + #define l1_table_offset_pae(_a) \ + (((_a) >> L1_PAGETABLE_SHIFT_PAE) & (L1_PAGETABLE_ENTRIES_PAE - 1)) + #define l2_table_offset_pae(_a) \ +@@ -98,27 +112,33 @@ typedef unsigned long l4_pgentry_t; + #define l3_table_offset_pae(_a) \ + (((_a) >> L3_PAGETABLE_SHIFT_PAE) & (L3_PAGETABLE_ENTRIES_PAE - 1)) + +-#define l1_table_offset_i386(_a) \ +- (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES_I386 - 1)) +-#define l2_table_offset_i386(_a) \ +- (((_a) >> L2_PAGETABLE_SHIFT_I386) & (L2_PAGETABLE_ENTRIES_I386 - 1)) ++#define l1_table_offset_x86_64(_a) \ ++ (((_a) >> L1_PAGETABLE_SHIFT_X86_64) & (L1_PAGETABLE_ENTRIES_X86_64 - 1)) ++#define l2_table_offset_x86_64(_a) \ ++ (((_a) >> L2_PAGETABLE_SHIFT_X86_64) & (L2_PAGETABLE_ENTRIES_X86_64 - 1)) ++#define l3_table_offset_x86_64(_a) \ ++ (((_a) >> L3_PAGETABLE_SHIFT_X86_64) & (L3_PAGETABLE_ENTRIES_X86_64 - 1)) ++#define l4_table_offset_x86_64(_a) \ ++ (((_a) >> L4_PAGETABLE_SHIFT_X86_64) & (L4_PAGETABLE_ENTRIES_X86_64 - 1)) + + #if defined(__i386__) +-#define l1_table_offset(_a) \ +- (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1)) +-#define l2_table_offset(_a) \ +- ((_a) >> L2_PAGETABLE_SHIFT) ++#define l1_table_offset(_a) l1_table_offset_i386(_a) ++#define l2_table_offset(_a) l2_table_offset_i386(_a) + #elif defined(__x86_64__) +-#define l1_table_offset(_a) \ +- (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1)) +-#define l2_table_offset(_a) \ +- (((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1)) +-#define l3_table_offset(_a) \ +- (((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1)) +-#define l4_table_offset(_a) \ +- (((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1)) ++#define l1_table_offset(_a) l1_table_offset_x86_64(_a) ++#define l2_table_offset(_a) l2_table_offset_x86_64(_a) ++#define l3_table_offset(_a) l3_table_offset_x86_64(_a) ++#define l4_table_offset(_a) l4_table_offset_x86_64(_a) + #endif + ++#define PAGE_SHIFT_X86 12 ++#define PAGE_SIZE_X86 (1UL << PAGE_SHIFT_X86) ++#define PAGE_MASK_X86 (~(PAGE_SIZE_X86-1)) ++ ++#define PAGE_SHIFT_IA64 14 ++#define PAGE_SIZE_IA64 (1UL << PAGE_SHIFT_IA64) ++#define PAGE_MASK_IA64 (~(PAGE_SIZE_IA64-1)) ++ + struct domain_setup_info + { + uint64_t v_start; diff --git a/tools-domain-builder-linux.diff b/tools-domain-builder-linux.diff new file mode 100644 index 0000000..51f0513 --- /dev/null +++ b/tools-domain-builder-linux.diff @@ -0,0 +1,164 @@ +libxc domain builder rewrite, linux builder + +use new domain builder for the linux (aka generic elf) loader. + +Signed-off-by: Gerd Hoffmann +--- + tools/libxc/Makefile | 7 +- + tools/libxc/xc_dom_compat_linux.c | 124 ++++++++++++++++++++++++++++++++++++++ + 2 files changed, 129 insertions(+), 2 deletions(-) + +Index: build-32-release304-12901/tools/libxc/xc_dom_compat_linux.c +=================================================================== +--- /dev/null ++++ build-32-release304-12901/tools/libxc/xc_dom_compat_linux.c +@@ -0,0 +1,124 @@ ++/* ++ * Xen domain builder -- compatibility code. ++ * ++ * Replacements for xc_linux_build & friends, ++ * as example code and to make the new builder ++ * usable as drop-in replacement. ++ * ++ * This code is licenced under the GPL. ++ * written 2006 by Gerd Hoffmann . ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++ ++#include "xenctrl.h" ++#include "xg_private.h" ++#include "xc_dom.h" ++ ++/* ------------------------------------------------------------------------ */ ++ ++static int xc_linux_build_internal(struct xc_dom_image *dom, ++ int xc_handle, uint32_t domid, ++ unsigned int mem_mb, ++ unsigned long flags, ++ unsigned int store_evtchn, ++ unsigned long *store_mfn, ++ unsigned int console_evtchn, ++ unsigned long *console_mfn) ++{ ++ int rc; ++ ++ if (0 != (rc = xc_dom_boot_xen_init(dom, xc_handle, domid))) ++ goto out; ++ if (0 != (rc = xc_dom_parse_image(dom))) ++ goto out; ++ if (0 != (rc = xc_dom_mem_init(dom, mem_mb))) ++ goto out; ++ if (0 != (rc = xc_dom_boot_mem_init(dom))) ++ goto out; ++ if (0 != (rc = xc_dom_build_image(dom))) ++ goto out; ++ ++ dom->flags = flags; ++ dom->console_evtchn = console_evtchn; ++ dom->xenstore_evtchn = store_evtchn; ++ rc = xc_dom_boot_image(dom); ++ if (0 != rc) ++ goto out; ++ ++ *console_mfn = xc_dom_p2m_host(dom, dom->console_pfn); ++ *store_mfn = xc_dom_p2m_host(dom, dom->xenstore_pfn); ++ ++ out: ++ return rc; ++} ++ ++int xc_linux_build_mem(int xc_handle, uint32_t domid, ++ unsigned int mem_mb, ++ const char *image_buffer, ++ unsigned long image_size, ++ const char *initrd, ++ unsigned long initrd_len, ++ const char *cmdline, ++ const char *features, ++ unsigned long flags, ++ unsigned int store_evtchn, ++ unsigned long *store_mfn, ++ unsigned int console_evtchn, unsigned long *console_mfn) ++{ ++ struct xc_dom_image *dom; ++ int rc; ++ ++ xc_dom_loginit(); ++ dom = xc_dom_allocate(cmdline, features); ++ if (0 != (rc = xc_dom_kernel_mem(dom, image_buffer, image_size))) ++ goto out; ++ if (initrd) ++ if (0 != (rc = xc_dom_ramdisk_mem(dom, initrd, initrd_len))) ++ goto out; ++ ++ rc = xc_linux_build_internal(dom, xc_handle, domid, ++ mem_mb, flags, ++ store_evtchn, store_mfn, ++ console_evtchn, console_mfn); ++ ++ out: ++ xc_dom_release(dom); ++ return rc; ++} ++ ++int xc_linux_build(int xc_handle, uint32_t domid, ++ unsigned int mem_mb, ++ const char *image_name, ++ const char *initrd_name, ++ const char *cmdline, ++ const char *features, ++ unsigned long flags, ++ unsigned int store_evtchn, ++ unsigned long *store_mfn, ++ unsigned int console_evtchn, unsigned long *console_mfn) ++{ ++ struct xc_dom_image *dom; ++ int rc; ++ ++ xc_dom_loginit(); ++ dom = xc_dom_allocate(cmdline, features); ++ if (0 != (rc = xc_dom_kernel_file(dom, image_name))) ++ goto out; ++ if (initrd_name && strlen(initrd_name)) ++ if (0 != (rc = xc_dom_ramdisk_file(dom, initrd_name))) ++ goto out; ++ ++ rc = xc_linux_build_internal(dom, xc_handle, domid, ++ mem_mb, flags, ++ store_evtchn, store_mfn, ++ console_evtchn, console_mfn); ++ ++ out: ++ xc_dom_release(dom); ++ return rc; ++} +Index: build-32-release304-12901/tools/libxc/Makefile +=================================================================== +--- build-32-release304-12901.orig/tools/libxc/Makefile ++++ build-32-release304-12901/tools/libxc/Makefile +@@ -24,8 +24,8 @@ GUEST_SRCS-y := + GUEST_SRCS-y += xc_load_bin.c + GUEST_SRCS-y += xc_load_elf.c + GUEST_SRCS-y += xg_private.c +-GUEST_SRCS-$(CONFIG_X86) += xc_linux_build.c +-GUEST_SRCS-$(CONFIG_IA64) += xc_linux_build.c ++#GUEST_SRCS-$(CONFIG_X86) += xc_linux_build.c ++#GUEST_SRCS-$(CONFIG_IA64) += xc_linux_build.c + GUEST_SRCS-$(CONFIG_MIGRATE) += xc_linux_restore.c xc_linux_save.c + GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c + +@@ -58,6 +58,9 @@ GUEST_SRCS-y += xc_dom_x86.c + GUEST_SRCS-y += xc_dom_ia64.c + endif + ++GUEST_SRCS-$(CONFIG_X86) += xc_dom_compat_linux.c ++GUEST_SRCS-$(CONFIG_IA64) += xc_dom_compat_linux.c ++ + -include $(XEN_TARGET_ARCH)/Makefile + + CFLAGS += -Werror -Wmissing-prototypes diff --git a/tools-kboot.diff b/tools-kboot.diff new file mode 100644 index 0000000..f7200e7 --- /dev/null +++ b/tools-kboot.diff @@ -0,0 +1,2171 @@ +kexec-based boot loader for xen guests. + +Signed-off-by: Gerd Hoffmann +--- + buildconfigs/linux-defconfig_xenUboot_x86_32 | 874 +++++++++++++++++++++++++++ + buildconfigs/linux-defconfig_xenUboot_x86_64 | 653 ++++++++++++++++++++ + buildconfigs/mk.linux-2.6-xenUboot | 2 + make-kboot | 37 + + tools/kboot/Makefile | 23 + tools/kboot/README | 43 + + tools/kboot/init | 309 +++++++++ + tools/kboot/mkinitramfs | 111 +++ + tools/kboot/select-kernel | 59 + + 9 files changed, 2111 insertions(+) + +Index: build-32-unstable-12542/buildconfigs/linux-defconfig_xenUboot_x86_32 +=================================================================== +--- /dev/null ++++ build-32-unstable-12542/buildconfigs/linux-defconfig_xenUboot_x86_32 +@@ -0,0 +1,874 @@ ++# ++# Automatically generated make config: don't edit ++# Linux kernel version: 2.6.16.29-xenUboot ++# Tue Nov 28 12:43:18 2006 ++# ++CONFIG_X86_32=y ++CONFIG_SEMAPHORE_SLEEPERS=y ++CONFIG_X86=y ++CONFIG_MMU=y ++CONFIG_GENERIC_ISA_DMA=y ++CONFIG_GENERIC_IOMAP=y ++CONFIG_ARCH_MAY_HAVE_PC_FDC=y ++CONFIG_DMI=y ++ ++# ++# Code maturity level options ++# ++CONFIG_EXPERIMENTAL=y ++CONFIG_BROKEN_ON_SMP=y ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++ ++# ++# General setup ++# ++CONFIG_LOCALVERSION="" ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SWAP=y ++CONFIG_SYSVIPC=y ++CONFIG_POSIX_MQUEUE=y ++# CONFIG_BSD_PROCESS_ACCT is not set ++CONFIG_SYSCTL=y ++# CONFIG_AUDIT is not set ++# CONFIG_IKCONFIG is not set ++CONFIG_INITRAMFS_SOURCE="../tools/kboot/kboot.initramfs" ++CONFIG_INITRAMFS_ROOT_UID=0 ++CONFIG_INITRAMFS_ROOT_GID=0 ++CONFIG_UID16=y ++CONFIG_VM86=y ++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ++# CONFIG_EMBEDDED is not set ++CONFIG_KALLSYMS=y ++CONFIG_KALLSYMS_ALL=y ++# CONFIG_KALLSYMS_EXTRA_PASS is not set ++CONFIG_HOTPLUG=y ++CONFIG_PRINTK=y ++CONFIG_BUG=y ++CONFIG_ELF_CORE=y ++CONFIG_BASE_FULL=y ++CONFIG_FUTEX=y ++CONFIG_EPOLL=y ++CONFIG_SHMEM=y ++CONFIG_CC_ALIGN_FUNCTIONS=0 ++CONFIG_CC_ALIGN_LABELS=0 ++CONFIG_CC_ALIGN_LOOPS=0 ++CONFIG_CC_ALIGN_JUMPS=0 ++CONFIG_SLAB=y ++# CONFIG_TINY_SHMEM is not set ++CONFIG_BASE_SMALL=0 ++# CONFIG_SLOB is not set ++ ++# ++# Loadable module support ++# ++# CONFIG_MODULES is not set ++ ++# ++# Block layer ++# ++# CONFIG_LBD is not set ++ ++# ++# IO Schedulers ++# ++CONFIG_IOSCHED_NOOP=y ++# CONFIG_IOSCHED_AS is not set ++# CONFIG_IOSCHED_DEADLINE is not set ++# CONFIG_IOSCHED_CFQ is not set ++# CONFIG_DEFAULT_AS is not set ++# CONFIG_DEFAULT_DEADLINE is not set ++# CONFIG_DEFAULT_CFQ is not set ++CONFIG_DEFAULT_NOOP=y ++CONFIG_DEFAULT_IOSCHED="noop" ++ ++# ++# Processor type and features ++# ++# CONFIG_X86_PC is not set ++CONFIG_X86_XEN=y ++# CONFIG_X86_ELAN is not set ++# CONFIG_X86_VOYAGER is not set ++# CONFIG_X86_NUMAQ is not set ++# CONFIG_X86_SUMMIT is not set ++# CONFIG_X86_BIGSMP is not set ++# CONFIG_X86_VISWS is not set ++# CONFIG_X86_GENERICARCH is not set ++# CONFIG_X86_ES7000 is not set ++# CONFIG_M386 is not set ++# CONFIG_M486 is not set ++# CONFIG_M586 is not set ++# CONFIG_M586TSC is not set ++# CONFIG_M586MMX is not set ++CONFIG_M686=y ++# CONFIG_MPENTIUMII is not set ++# CONFIG_MPENTIUMIII is not set ++# CONFIG_MPENTIUMM is not set ++# CONFIG_MPENTIUM4 is not set ++# CONFIG_MK6 is not set ++# CONFIG_MK7 is not set ++# CONFIG_MK8 is not set ++# CONFIG_MCRUSOE is not set ++# CONFIG_MEFFICEON is not set ++# CONFIG_MWINCHIPC6 is not set ++# CONFIG_MWINCHIP2 is not set ++# CONFIG_MWINCHIP3D is not set ++# CONFIG_MGEODEGX1 is not set ++# CONFIG_MGEODE_LX is not set ++# CONFIG_MCYRIXIII is not set ++# CONFIG_MVIAC3_2 is not set ++CONFIG_X86_GENERIC=y ++CONFIG_X86_CMPXCHG=y ++CONFIG_X86_XADD=y ++CONFIG_X86_L1_CACHE_SHIFT=7 ++CONFIG_RWSEM_XCHGADD_ALGORITHM=y ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++CONFIG_X86_PPRO_FENCE=y ++CONFIG_X86_WP_WORKS_OK=y ++CONFIG_X86_INVLPG=y ++CONFIG_X86_BSWAP=y ++CONFIG_X86_POPAD_OK=y ++CONFIG_X86_CMPXCHG64=y ++CONFIG_X86_GOOD_APIC=y ++CONFIG_X86_INTEL_USERCOPY=y ++CONFIG_X86_USE_PPRO_CHECKSUM=y ++CONFIG_X86_TSC=y ++# CONFIG_SMP is not set ++CONFIG_PREEMPT_NONE=y ++# CONFIG_PREEMPT_VOLUNTARY is not set ++# CONFIG_PREEMPT is not set ++# CONFIG_TOSHIBA is not set ++# CONFIG_I8K is not set ++# CONFIG_X86_REBOOTFIXUPS is not set ++# CONFIG_X86_CPUID is not set ++CONFIG_SWIOTLB=y ++ ++# ++# Firmware Drivers ++# ++# CONFIG_DELL_RBU is not set ++# CONFIG_DCDBAS is not set ++CONFIG_NOHIGHMEM=y ++# CONFIG_HIGHMEM4G is not set ++# CONFIG_HIGHMEM64G is not set ++CONFIG_VMSPLIT_3G=y ++# CONFIG_VMSPLIT_3G_OPT is not set ++# CONFIG_VMSPLIT_2G is not set ++# CONFIG_VMSPLIT_1G is not set ++CONFIG_PAGE_OFFSET=0xC0000000 ++CONFIG_SELECT_MEMORY_MODEL=y ++CONFIG_FLATMEM_MANUAL=y ++# CONFIG_DISCONTIGMEM_MANUAL is not set ++# CONFIG_SPARSEMEM_MANUAL is not set ++CONFIG_FLATMEM=y ++CONFIG_FLAT_NODE_MEM_MAP=y ++# CONFIG_SPARSEMEM_STATIC is not set ++CONFIG_SPLIT_PTLOCK_CPUS=4096 ++# CONFIG_REGPARM is not set ++# CONFIG_SECCOMP is not set ++CONFIG_HZ_100=y ++# CONFIG_HZ_250 is not set ++# CONFIG_HZ_1000 is not set ++CONFIG_HZ=100 ++CONFIG_KEXEC=y ++CONFIG_PHYSICAL_START=0x100000 ++ ++# ++# Bus options (PCI, PCMCIA, EISA, MCA, ISA) ++# ++# CONFIG_PCI is not set ++CONFIG_ISA_DMA_API=y ++# CONFIG_SCx200 is not set ++ ++# ++# PCCARD (PCMCIA/CardBus) support ++# ++# CONFIG_PCCARD is not set ++ ++# ++# PCI Hotplug Support ++# ++ ++# ++# Executable file formats ++# ++CONFIG_BINFMT_ELF=y ++# CONFIG_BINFMT_AOUT is not set ++# CONFIG_BINFMT_MISC is not set ++ ++# ++# Networking ++# ++CONFIG_NET=y ++ ++# ++# Networking options ++# ++# CONFIG_NETDEBUG is not set ++CONFIG_PACKET=y ++CONFIG_PACKET_MMAP=y ++CONFIG_UNIX=y ++# CONFIG_NET_KEY is not set ++CONFIG_INET=y ++# CONFIG_IP_MULTICAST is not set ++# CONFIG_IP_ADVANCED_ROUTER is not set ++CONFIG_IP_FIB_HASH=y ++# CONFIG_IP_PNP is not set ++# CONFIG_NET_IPIP is not set ++# CONFIG_NET_IPGRE is not set ++# CONFIG_ARPD is not set ++# CONFIG_SYN_COOKIES is not set ++# CONFIG_INET_AH is not set ++# CONFIG_INET_ESP is not set ++# CONFIG_INET_IPCOMP is not set ++# CONFIG_INET_TUNNEL is not set ++CONFIG_INET_DIAG=y ++CONFIG_INET_TCP_DIAG=y ++# CONFIG_TCP_CONG_ADVANCED is not set ++CONFIG_TCP_CONG_BIC=y ++# CONFIG_IPV6 is not set ++# CONFIG_NETFILTER is not set ++ ++# ++# DCCP Configuration (EXPERIMENTAL) ++# ++# CONFIG_IP_DCCP is not set ++ ++# ++# SCTP Configuration (EXPERIMENTAL) ++# ++# CONFIG_IP_SCTP is not set ++ ++# ++# TIPC Configuration (EXPERIMENTAL) ++# ++# CONFIG_TIPC is not set ++# CONFIG_ATM is not set ++# CONFIG_BRIDGE is not set ++# CONFIG_VLAN_8021Q is not set ++# CONFIG_DECNET is not set ++# CONFIG_LLC2 is not set ++# CONFIG_IPX is not set ++# CONFIG_ATALK is not set ++# CONFIG_X25 is not set ++# CONFIG_LAPB is not set ++# CONFIG_NET_DIVERT is not set ++# CONFIG_ECONET is not set ++# CONFIG_WAN_ROUTER is not set ++ ++# ++# QoS and/or fair queueing ++# ++# CONFIG_NET_SCHED is not set ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++# CONFIG_HAMRADIO is not set ++# CONFIG_IRDA is not set ++# CONFIG_BT is not set ++# CONFIG_IEEE80211 is not set ++ ++# ++# Device Drivers ++# ++ ++# ++# Generic Driver Options ++# ++CONFIG_STANDALONE=y ++CONFIG_PREVENT_FIRMWARE_BUILD=y ++# CONFIG_FW_LOADER is not set ++# CONFIG_DEBUG_DRIVER is not set ++ ++# ++# Connector - unified userspace <-> kernelspace linker ++# ++# CONFIG_CONNECTOR is not set ++ ++# ++# Memory Technology Devices (MTD) ++# ++# CONFIG_MTD is not set ++ ++# ++# Parallel port support ++# ++# CONFIG_PARPORT is not set ++ ++# ++# Plug and Play support ++# ++ ++# ++# Block devices ++# ++# CONFIG_BLK_DEV_FD is not set ++# CONFIG_BLK_DEV_COW_COMMON is not set ++CONFIG_BLK_DEV_LOOP=y ++# CONFIG_BLK_DEV_CRYPTOLOOP is not set ++# CONFIG_BLK_DEV_NBD is not set ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_COUNT=16 ++CONFIG_BLK_DEV_RAM_SIZE=4096 ++CONFIG_BLK_DEV_INITRD=y ++# CONFIG_CDROM_PKTCDVD is not set ++# CONFIG_ATA_OVER_ETH is not set ++ ++# ++# ATA/ATAPI/MFM/RLL support ++# ++# CONFIG_IDE is not set ++ ++# ++# SCSI device support ++# ++# CONFIG_RAID_ATTRS is not set ++# CONFIG_SCSI is not set ++ ++# ++# Multi-device support (RAID and LVM) ++# ++CONFIG_MD=y ++CONFIG_BLK_DEV_MD=y ++CONFIG_MD_LINEAR=y ++CONFIG_MD_RAID0=y ++CONFIG_MD_RAID1=y ++# CONFIG_MD_RAID10 is not set ++# CONFIG_MD_RAID5 is not set ++# CONFIG_MD_RAID6 is not set ++# CONFIG_MD_MULTIPATH is not set ++# CONFIG_MD_FAULTY is not set ++CONFIG_BLK_DEV_DM=y ++# CONFIG_DM_CRYPT is not set ++# CONFIG_DM_SNAPSHOT is not set ++# CONFIG_DM_MIRROR is not set ++# CONFIG_DM_ZERO is not set ++# CONFIG_DM_MULTIPATH is not set ++ ++# ++# Fusion MPT device support ++# ++# CONFIG_FUSION is not set ++ ++# ++# IEEE 1394 (FireWire) support ++# ++ ++# ++# I2O device support ++# ++ ++# ++# Network device support ++# ++# CONFIG_NETDEVICES is not set ++# CONFIG_DUMMY is not set ++# CONFIG_BONDING is not set ++# CONFIG_EQUALIZER is not set ++# CONFIG_TUN is not set ++ ++# ++# PHY device support ++# ++ ++# ++# Ethernet (10 or 100Mbit) ++# ++# CONFIG_NET_ETHERNET is not set ++ ++# ++# Ethernet (1000 Mbit) ++# ++ ++# ++# Ethernet (10000 Mbit) ++# ++# CONFIG_PPP is not set ++# CONFIG_SLIP is not set ++# CONFIG_SHAPER is not set ++# CONFIG_NETCONSOLE is not set ++# CONFIG_NETPOLL is not set ++# CONFIG_NET_POLL_CONTROLLER is not set ++ ++# ++# ISDN subsystem ++# ++# CONFIG_ISDN is not set ++ ++# ++# Telephony Support ++# ++# CONFIG_PHONE is not set ++ ++# ++# Input device support ++# ++CONFIG_INPUT=y ++ ++# ++# Userland interfaces ++# ++CONFIG_INPUT_MOUSEDEV=y ++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set ++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 ++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 ++# CONFIG_INPUT_JOYDEV is not set ++# CONFIG_INPUT_TSDEV is not set ++# CONFIG_INPUT_EVDEV is not set ++# CONFIG_INPUT_EVBUG is not set ++ ++# ++# Input Device Drivers ++# ++CONFIG_INPUT_KEYBOARD=y ++# CONFIG_KEYBOARD_ATKBD is not set ++# CONFIG_KEYBOARD_SUNKBD is not set ++# CONFIG_KEYBOARD_LKKBD is not set ++# CONFIG_KEYBOARD_XTKBD is not set ++# CONFIG_KEYBOARD_NEWTON is not set ++# CONFIG_INPUT_MOUSE is not set ++# CONFIG_INPUT_JOYSTICK is not set ++# CONFIG_INPUT_TOUCHSCREEN is not set ++# CONFIG_INPUT_MISC is not set ++ ++# ++# Hardware I/O ports ++# ++CONFIG_SERIO=y ++CONFIG_SERIO_I8042=y ++CONFIG_SERIO_SERPORT=y ++# CONFIG_SERIO_CT82C710 is not set ++# CONFIG_SERIO_RAW is not set ++# CONFIG_GAMEPORT is not set ++ ++# ++# Character devices ++# ++CONFIG_VT=y ++CONFIG_VT_CONSOLE=y ++CONFIG_HW_CONSOLE=y ++# CONFIG_SERIAL_NONSTANDARD is not set ++ ++# ++# Serial drivers ++# ++ ++# ++# Non-8250 serial port support ++# ++CONFIG_UNIX98_PTYS=y ++CONFIG_LEGACY_PTYS=y ++CONFIG_LEGACY_PTY_COUNT=32 ++ ++# ++# IPMI ++# ++# CONFIG_IPMI_HANDLER is not set ++ ++# ++# Watchdog Cards ++# ++# CONFIG_WATCHDOG is not set ++# CONFIG_NVRAM is not set ++# CONFIG_RTC is not set ++# CONFIG_GEN_RTC is not set ++# CONFIG_DTLK is not set ++# CONFIG_R3964 is not set ++ ++# ++# Ftape, the floppy tape device driver ++# ++# CONFIG_FTAPE is not set ++# CONFIG_AGP is not set ++# CONFIG_MWAVE is not set ++# CONFIG_CS5535_GPIO is not set ++# CONFIG_RAW_DRIVER is not set ++# CONFIG_HANGCHECK_TIMER is not set ++ ++# ++# TPM devices ++# ++# CONFIG_TCG_TPM is not set ++# CONFIG_TELCLOCK is not set ++ ++# ++# I2C support ++# ++# CONFIG_I2C is not set ++ ++# ++# SPI support ++# ++# CONFIG_SPI is not set ++# CONFIG_SPI_MASTER is not set ++ ++# ++# Dallas's 1-wire bus ++# ++# CONFIG_W1 is not set ++ ++# ++# Hardware Monitoring support ++# ++# CONFIG_HWMON is not set ++# CONFIG_HWMON_VID is not set ++ ++# ++# Misc devices ++# ++ ++# ++# Multimedia Capabilities Port drivers ++# ++ ++# ++# Multimedia devices ++# ++# CONFIG_VIDEO_DEV is not set ++ ++# ++# Digital Video Broadcasting Devices ++# ++# CONFIG_DVB is not set ++ ++# ++# Graphics support ++# ++# CONFIG_FB is not set ++# CONFIG_VIDEO_SELECT is not set ++ ++# ++# Console display driver support ++# ++CONFIG_VGA_CONSOLE=y ++CONFIG_DUMMY_CONSOLE=y ++ ++# ++# Sound ++# ++# CONFIG_SOUND is not set ++ ++# ++# USB support ++# ++# CONFIG_USB_ARCH_HAS_HCD is not set ++# CONFIG_USB_ARCH_HAS_OHCI is not set ++ ++# ++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' ++# ++ ++# ++# USB Gadget Support ++# ++# CONFIG_USB_GADGET is not set ++ ++# ++# MMC/SD Card support ++# ++# CONFIG_MMC is not set ++ ++# ++# InfiniBand support ++# ++ ++# ++# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) ++# ++# CONFIG_EDAC is not set ++ ++# ++# File systems ++# ++CONFIG_EXT2_FS=y ++CONFIG_EXT2_FS_XATTR=y ++CONFIG_EXT2_FS_POSIX_ACL=y ++CONFIG_EXT2_FS_SECURITY=y ++# CONFIG_EXT2_FS_XIP is not set ++CONFIG_EXT3_FS=y ++CONFIG_EXT3_FS_XATTR=y ++CONFIG_EXT3_FS_POSIX_ACL=y ++CONFIG_EXT3_FS_SECURITY=y ++CONFIG_JBD=y ++# CONFIG_JBD_DEBUG is not set ++CONFIG_FS_MBCACHE=y ++CONFIG_REISERFS_FS=y ++# CONFIG_REISERFS_CHECK is not set ++# CONFIG_REISERFS_PROC_INFO is not set ++CONFIG_REISERFS_FS_XATTR=y ++CONFIG_REISERFS_FS_POSIX_ACL=y ++CONFIG_REISERFS_FS_SECURITY=y ++CONFIG_JFS_FS=y ++CONFIG_JFS_POSIX_ACL=y ++CONFIG_JFS_SECURITY=y ++# CONFIG_JFS_DEBUG is not set ++# CONFIG_JFS_STATISTICS is not set ++CONFIG_FS_POSIX_ACL=y ++CONFIG_XFS_FS=y ++# CONFIG_XFS_QUOTA is not set ++CONFIG_XFS_SECURITY=y ++CONFIG_XFS_POSIX_ACL=y ++# CONFIG_XFS_RT is not set ++# CONFIG_OCFS2_FS is not set ++CONFIG_MINIX_FS=y ++# CONFIG_ROMFS_FS is not set ++CONFIG_INOTIFY=y ++# CONFIG_QUOTA is not set ++CONFIG_DNOTIFY=y ++# CONFIG_AUTOFS_FS is not set ++# CONFIG_AUTOFS4_FS is not set ++# CONFIG_FUSE_FS is not set ++ ++# ++# CD-ROM/DVD Filesystems ++# ++CONFIG_ISO9660_FS=y ++CONFIG_JOLIET=y ++CONFIG_ZISOFS=y ++CONFIG_ZISOFS_FS=y ++# CONFIG_UDF_FS is not set ++ ++# ++# DOS/FAT/NT Filesystems ++# ++CONFIG_FAT_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_CODEPAGE=437 ++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" ++# CONFIG_NTFS_FS is not set ++ ++# ++# Pseudo filesystems ++# ++CONFIG_PROC_FS=y ++CONFIG_PROC_KCORE=y ++CONFIG_SYSFS=y ++CONFIG_TMPFS=y ++# CONFIG_HUGETLB_PAGE is not set ++CONFIG_RAMFS=y ++# CONFIG_RELAYFS_FS is not set ++# CONFIG_CONFIGFS_FS is not set ++ ++# ++# Miscellaneous filesystems ++# ++# CONFIG_ADFS_FS is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_HFS_FS is not set ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BFS_FS is not set ++# CONFIG_EFS_FS is not set ++# CONFIG_CRAMFS is not set ++# CONFIG_VXFS_FS is not set ++# CONFIG_HPFS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++CONFIG_SYSV_FS=y ++CONFIG_UFS_FS=y ++ ++# ++# Network File Systems ++# ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3=y ++# CONFIG_NFS_V3_ACL is not set ++CONFIG_NFS_V4=y ++# CONFIG_NFS_DIRECTIO is not set ++# CONFIG_NFSD is not set ++CONFIG_LOCKD=y ++CONFIG_LOCKD_V4=y ++CONFIG_NFS_COMMON=y ++CONFIG_SUNRPC=y ++CONFIG_SUNRPC_GSS=y ++CONFIG_RPCSEC_GSS_KRB5=y ++# CONFIG_RPCSEC_GSS_SPKM3 is not set ++# CONFIG_SMB_FS is not set ++# CONFIG_CIFS is not set ++# CONFIG_NCP_FS is not set ++# CONFIG_CODA_FS is not set ++# CONFIG_AFS_FS is not set ++# CONFIG_9P_FS is not set ++ ++# ++# Partition Types ++# ++CONFIG_PARTITION_ADVANCED=y ++# CONFIG_ACORN_PARTITION is not set ++# CONFIG_OSF_PARTITION is not set ++# CONFIG_AMIGA_PARTITION is not set ++# CONFIG_ATARI_PARTITION is not set ++CONFIG_MAC_PARTITION=y ++CONFIG_MSDOS_PARTITION=y ++CONFIG_BSD_DISKLABEL=y ++CONFIG_MINIX_SUBPARTITION=y ++CONFIG_SOLARIS_X86_PARTITION=y ++CONFIG_UNIXWARE_DISKLABEL=y ++# CONFIG_LDM_PARTITION is not set ++# CONFIG_SGI_PARTITION is not set ++# CONFIG_ULTRIX_PARTITION is not set ++CONFIG_SUN_PARTITION=y ++# CONFIG_KARMA_PARTITION is not set ++CONFIG_EFI_PARTITION=y ++ ++# ++# Native Language Support ++# ++CONFIG_NLS=y ++CONFIG_NLS_DEFAULT="iso8859-1" ++CONFIG_NLS_CODEPAGE_437=y ++# CONFIG_NLS_CODEPAGE_737 is not set ++# CONFIG_NLS_CODEPAGE_775 is not set ++# CONFIG_NLS_CODEPAGE_850 is not set ++# CONFIG_NLS_CODEPAGE_852 is not set ++# CONFIG_NLS_CODEPAGE_855 is not set ++# CONFIG_NLS_CODEPAGE_857 is not set ++# CONFIG_NLS_CODEPAGE_860 is not set ++# CONFIG_NLS_CODEPAGE_861 is not set ++# CONFIG_NLS_CODEPAGE_862 is not set ++# CONFIG_NLS_CODEPAGE_863 is not set ++# CONFIG_NLS_CODEPAGE_864 is not set ++# CONFIG_NLS_CODEPAGE_865 is not set ++# CONFIG_NLS_CODEPAGE_866 is not set ++# CONFIG_NLS_CODEPAGE_869 is not set ++# CONFIG_NLS_CODEPAGE_936 is not set ++# CONFIG_NLS_CODEPAGE_950 is not set ++# CONFIG_NLS_CODEPAGE_932 is not set ++# CONFIG_NLS_CODEPAGE_949 is not set ++# CONFIG_NLS_CODEPAGE_874 is not set ++# CONFIG_NLS_ISO8859_8 is not set ++# CONFIG_NLS_CODEPAGE_1250 is not set ++# CONFIG_NLS_CODEPAGE_1251 is not set ++# CONFIG_NLS_ASCII is not set ++CONFIG_NLS_ISO8859_1=y ++# CONFIG_NLS_ISO8859_2 is not set ++# CONFIG_NLS_ISO8859_3 is not set ++# CONFIG_NLS_ISO8859_4 is not set ++# CONFIG_NLS_ISO8859_5 is not set ++# CONFIG_NLS_ISO8859_6 is not set ++# CONFIG_NLS_ISO8859_7 is not set ++# CONFIG_NLS_ISO8859_9 is not set ++# CONFIG_NLS_ISO8859_13 is not set ++# CONFIG_NLS_ISO8859_14 is not set ++# CONFIG_NLS_ISO8859_15 is not set ++# CONFIG_NLS_KOI8_R is not set ++# CONFIG_NLS_KOI8_U is not set ++# CONFIG_NLS_UTF8 is not set ++ ++# ++# Instrumentation Support ++# ++# CONFIG_PROFILING is not set ++ ++# ++# Kernel hacking ++# ++# CONFIG_PRINTK_TIME is not set ++CONFIG_MAGIC_SYSRQ=y ++CONFIG_DEBUG_KERNEL=y ++CONFIG_LOG_BUF_SHIFT=16 ++CONFIG_DETECT_SOFTLOCKUP=y ++# CONFIG_SCHEDSTATS is not set ++# CONFIG_DEBUG_SLAB is not set ++# CONFIG_DEBUG_MUTEXES is not set ++# CONFIG_DEBUG_SPINLOCK is not set ++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set ++# CONFIG_DEBUG_KOBJECT is not set ++CONFIG_DEBUG_BUGVERBOSE=y ++# CONFIG_DEBUG_INFO is not set ++# CONFIG_DEBUG_FS is not set ++# CONFIG_DEBUG_VM is not set ++CONFIG_FRAME_POINTER=y ++CONFIG_FORCED_INLINING=y ++# CONFIG_RCU_TORTURE_TEST is not set ++CONFIG_EARLY_PRINTK=y ++# CONFIG_DEBUG_STACKOVERFLOW is not set ++# CONFIG_DEBUG_STACK_USAGE is not set ++# CONFIG_DEBUG_PAGEALLOC is not set ++# CONFIG_DEBUG_RODATA is not set ++# CONFIG_4KSTACKS is not set ++ ++# ++# Security options ++# ++# CONFIG_KEYS is not set ++# CONFIG_SECURITY is not set ++ ++# ++# Cryptographic options ++# ++CONFIG_CRYPTO=y ++# CONFIG_CRYPTO_HMAC is not set ++# CONFIG_CRYPTO_NULL is not set ++# CONFIG_CRYPTO_MD4 is not set ++CONFIG_CRYPTO_MD5=y ++# CONFIG_CRYPTO_SHA1 is not set ++# CONFIG_CRYPTO_SHA256 is not set ++# CONFIG_CRYPTO_SHA512 is not set ++# CONFIG_CRYPTO_WP512 is not set ++# CONFIG_CRYPTO_TGR192 is not set ++CONFIG_CRYPTO_DES=y ++# CONFIG_CRYPTO_BLOWFISH is not set ++# CONFIG_CRYPTO_TWOFISH is not set ++# CONFIG_CRYPTO_SERPENT is not set ++# CONFIG_CRYPTO_AES is not set ++# CONFIG_CRYPTO_AES_586 is not set ++# CONFIG_CRYPTO_CAST5 is not set ++# CONFIG_CRYPTO_CAST6 is not set ++# CONFIG_CRYPTO_TEA is not set ++# CONFIG_CRYPTO_ARC4 is not set ++# CONFIG_CRYPTO_KHAZAD is not set ++# CONFIG_CRYPTO_ANUBIS is not set ++# CONFIG_CRYPTO_DEFLATE is not set ++# CONFIG_CRYPTO_MICHAEL_MIC is not set ++# CONFIG_CRYPTO_CRC32C is not set ++# CONFIG_CRYPTO_TEST is not set ++ ++# ++# Hardware crypto devices ++# ++# CONFIG_CRYPTO_DEV_PADLOCK is not set ++CONFIG_XEN=y ++CONFIG_XEN_INTERFACE_VERSION=0x00030203 ++ ++# ++# XEN ++# ++# CONFIG_XEN_PRIVILEGED_GUEST is not set ++CONFIG_XEN_UNPRIVILEGED_GUEST=y ++CONFIG_XEN_PRIVCMD=y ++CONFIG_XEN_XENBUS_DEV=y ++# CONFIG_XEN_BACKEND is not set ++CONFIG_XEN_BLKDEV_FRONTEND=y ++CONFIG_XEN_NETDEV_FRONTEND=y ++CONFIG_XEN_SCRUB_PAGES=y ++CONFIG_XEN_DISABLE_SERIAL=y ++# CONFIG_XEN_SYSFS is not set ++CONFIG_XEN_COMPAT_030002_AND_LATER=y ++# CONFIG_XEN_COMPAT_LATEST_ONLY is not set ++CONFIG_XEN_COMPAT_030002=y ++CONFIG_HAVE_ARCH_ALLOC_SKB=y ++CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y ++CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y ++CONFIG_NO_IDLE_HZ=y ++CONFIG_XEN_UTIL=y ++CONFIG_XEN_BALLOON=y ++CONFIG_XEN_DEVMEM=y ++CONFIG_XEN_SKBUFF=y ++CONFIG_XEN_REBOOT=y ++ ++# ++# Library routines ++# ++# CONFIG_CRC_CCITT is not set ++# CONFIG_CRC16 is not set ++CONFIG_CRC32=y ++# CONFIG_LIBCRC32C is not set ++CONFIG_ZLIB_INFLATE=y ++CONFIG_GENERIC_HARDIRQS=y ++CONFIG_GENERIC_IRQ_PROBE=y ++CONFIG_X86_BIOS_REBOOT=y ++CONFIG_X86_NO_TSS=y ++CONFIG_X86_NO_IDT=y ++CONFIG_KTIME_SCALAR=y +Index: build-32-unstable-12542/buildconfigs/linux-defconfig_xenUboot_x86_64 +=================================================================== +--- /dev/null ++++ build-32-unstable-12542/buildconfigs/linux-defconfig_xenUboot_x86_64 +@@ -0,0 +1,653 @@ ++# ++# Automatically generated make config: don't edit ++# Linux kernel version: 2.6.16.13-xenUboot ++# Tue Aug 15 16:25:30 2006 ++# ++CONFIG_X86_64=y ++CONFIG_64BIT=y ++CONFIG_X86=y ++CONFIG_SEMAPHORE_SLEEPERS=y ++CONFIG_MMU=y ++CONFIG_RWSEM_GENERIC_SPINLOCK=y ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++CONFIG_X86_CMPXCHG=y ++CONFIG_EARLY_PRINTK=y ++CONFIG_GENERIC_ISA_DMA=y ++CONFIG_GENERIC_IOMAP=y ++CONFIG_ARCH_MAY_HAVE_PC_FDC=y ++CONFIG_DMI=y ++ ++# ++# Code maturity level options ++# ++CONFIG_EXPERIMENTAL=y ++CONFIG_BROKEN_ON_SMP=y ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++ ++# ++# General setup ++# ++CONFIG_LOCALVERSION="" ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SWAP=y ++CONFIG_SYSVIPC=y ++# CONFIG_BSD_PROCESS_ACCT is not set ++CONFIG_SYSCTL=y ++# CONFIG_IKCONFIG is not set ++CONFIG_INITRAMFS_SOURCE="../tools/kboot/kboot.initramfs" ++CONFIG_INITRAMFS_ROOT_UID=0 ++CONFIG_INITRAMFS_ROOT_GID=0 ++CONFIG_UID16=y ++CONFIG_VM86=y ++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ++# CONFIG_EMBEDDED is not set ++CONFIG_KALLSYMS=y ++# CONFIG_KALLSYMS_ALL is not set ++# CONFIG_KALLSYMS_EXTRA_PASS is not set ++CONFIG_HOTPLUG=y ++CONFIG_PRINTK=y ++CONFIG_BUG=y ++CONFIG_ELF_CORE=y ++CONFIG_BASE_FULL=y ++CONFIG_FUTEX=y ++CONFIG_EPOLL=y ++CONFIG_SHMEM=y ++CONFIG_CC_ALIGN_FUNCTIONS=0 ++CONFIG_CC_ALIGN_LABELS=0 ++CONFIG_CC_ALIGN_LOOPS=0 ++CONFIG_CC_ALIGN_JUMPS=0 ++CONFIG_SLAB=y ++# CONFIG_TINY_SHMEM is not set ++CONFIG_BASE_SMALL=0 ++# CONFIG_SLOB is not set ++ ++# ++# Loadable module support ++# ++# CONFIG_MODULES is not set ++ ++# ++# Block layer ++# ++# CONFIG_LBD is not set ++ ++# ++# IO Schedulers ++# ++CONFIG_IOSCHED_NOOP=y ++# CONFIG_IOSCHED_AS is not set ++# CONFIG_IOSCHED_DEADLINE is not set ++# CONFIG_IOSCHED_CFQ is not set ++# CONFIG_DEFAULT_AS is not set ++# CONFIG_DEFAULT_DEADLINE is not set ++# CONFIG_DEFAULT_CFQ is not set ++CONFIG_DEFAULT_NOOP=y ++CONFIG_DEFAULT_IOSCHED="noop" ++ ++# ++# Processor type and features ++# ++CONFIG_X86_PC=y ++# CONFIG_X86_VSMP is not set ++# CONFIG_MK8 is not set ++# CONFIG_MPSC is not set ++CONFIG_GENERIC_CPU=y ++CONFIG_X86_64_XEN=y ++CONFIG_X86_NO_TSS=y ++CONFIG_X86_NO_IDT=y ++CONFIG_X86_L1_CACHE_BYTES=128 ++CONFIG_X86_L1_CACHE_SHIFT=7 ++CONFIG_X86_GOOD_APIC=y ++# CONFIG_MICROCODE is not set ++# CONFIG_X86_MSR is not set ++# CONFIG_X86_CPUID is not set ++# CONFIG_X86_XEN_GENAPIC is not set ++# CONFIG_SMP is not set ++CONFIG_PREEMPT_NONE=y ++# CONFIG_PREEMPT_VOLUNTARY is not set ++# CONFIG_PREEMPT is not set ++CONFIG_ARCH_FLATMEM_ENABLE=y ++CONFIG_SELECT_MEMORY_MODEL=y ++CONFIG_FLATMEM_MANUAL=y ++# CONFIG_DISCONTIGMEM_MANUAL is not set ++# CONFIG_SPARSEMEM_MANUAL is not set ++CONFIG_FLATMEM=y ++CONFIG_FLAT_NODE_MEM_MAP=y ++# CONFIG_SPARSEMEM_STATIC is not set ++CONFIG_SPLIT_PTLOCK_CPUS=4096 ++CONFIG_SWIOTLB=y ++CONFIG_KEXEC=y ++# CONFIG_CRASH_DUMP is not set ++CONFIG_PHYSICAL_START=0x100000 ++# CONFIG_SECCOMP is not set ++CONFIG_HZ_100=y ++# CONFIG_HZ_250 is not set ++# CONFIG_HZ_1000 is not set ++CONFIG_HZ=100 ++CONFIG_GENERIC_HARDIRQS=y ++CONFIG_GENERIC_IRQ_PROBE=y ++CONFIG_ISA_DMA_API=y ++ ++# ++# Bus options (PCI etc.) ++# ++# CONFIG_PCI is not set ++# CONFIG_UNORDERED_IO is not set ++ ++# ++# PCCARD (PCMCIA/CardBus) support ++# ++# CONFIG_PCCARD is not set ++ ++# ++# PCI Hotplug Support ++# ++ ++# ++# Executable file formats / Emulations ++# ++CONFIG_BINFMT_ELF=y ++# CONFIG_BINFMT_MISC is not set ++CONFIG_IA32_EMULATION=y ++# CONFIG_IA32_AOUT is not set ++CONFIG_COMPAT=y ++CONFIG_SYSVIPC_COMPAT=y ++ ++# ++# Networking ++# ++# CONFIG_NET is not set ++ ++# ++# Device Drivers ++# ++ ++# ++# Generic Driver Options ++# ++CONFIG_STANDALONE=y ++CONFIG_PREVENT_FIRMWARE_BUILD=y ++# CONFIG_FW_LOADER is not set ++# CONFIG_DEBUG_DRIVER is not set ++ ++# ++# Connector - unified userspace <-> kernelspace linker ++# ++ ++# ++# Memory Technology Devices (MTD) ++# ++# CONFIG_MTD is not set ++ ++# ++# Parallel port support ++# ++# CONFIG_PARPORT is not set ++ ++# ++# Plug and Play support ++# ++ ++# ++# Block devices ++# ++# CONFIG_BLK_DEV_FD is not set ++# CONFIG_BLK_DEV_COW_COMMON is not set ++CONFIG_BLK_DEV_LOOP=y ++# CONFIG_BLK_DEV_CRYPTOLOOP is not set ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_COUNT=16 ++CONFIG_BLK_DEV_RAM_SIZE=4096 ++CONFIG_BLK_DEV_INITRD=y ++# CONFIG_CDROM_PKTCDVD is not set ++ ++# ++# ATA/ATAPI/MFM/RLL support ++# ++# CONFIG_IDE is not set ++ ++# ++# SCSI device support ++# ++# CONFIG_RAID_ATTRS is not set ++# CONFIG_SCSI is not set ++ ++# ++# Multi-device support (RAID and LVM) ++# ++CONFIG_MD=y ++CONFIG_BLK_DEV_MD=y ++CONFIG_MD_LINEAR=y ++CONFIG_MD_RAID0=y ++CONFIG_MD_RAID1=y ++# CONFIG_MD_RAID10 is not set ++# CONFIG_MD_RAID5 is not set ++# CONFIG_MD_RAID6 is not set ++# CONFIG_MD_MULTIPATH is not set ++# CONFIG_MD_FAULTY is not set ++CONFIG_BLK_DEV_DM=y ++# CONFIG_DM_CRYPT is not set ++# CONFIG_DM_SNAPSHOT is not set ++# CONFIG_DM_MIRROR is not set ++# CONFIG_DM_ZERO is not set ++# CONFIG_DM_MULTIPATH is not set ++ ++# ++# Fusion MPT device support ++# ++# CONFIG_FUSION is not set ++ ++# ++# IEEE 1394 (FireWire) support ++# ++ ++# ++# I2O device support ++# ++ ++# ++# ISDN subsystem ++# ++ ++# ++# Telephony Support ++# ++# CONFIG_PHONE is not set ++ ++# ++# Input device support ++# ++CONFIG_INPUT=y ++ ++# ++# Userland interfaces ++# ++CONFIG_INPUT_MOUSEDEV=y ++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set ++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 ++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 ++# CONFIG_INPUT_JOYDEV is not set ++# CONFIG_INPUT_TSDEV is not set ++# CONFIG_INPUT_EVDEV is not set ++# CONFIG_INPUT_EVBUG is not set ++ ++# ++# Input Device Drivers ++# ++CONFIG_INPUT_KEYBOARD=y ++CONFIG_KEYBOARD_ATKBD=y ++# CONFIG_KEYBOARD_SUNKBD is not set ++# CONFIG_KEYBOARD_LKKBD is not set ++# CONFIG_KEYBOARD_XTKBD is not set ++# CONFIG_KEYBOARD_NEWTON is not set ++# CONFIG_INPUT_MOUSE is not set ++# CONFIG_INPUT_JOYSTICK is not set ++# CONFIG_INPUT_TOUCHSCREEN is not set ++# CONFIG_INPUT_MISC is not set ++ ++# ++# Hardware I/O ports ++# ++CONFIG_SERIO=y ++CONFIG_SERIO_I8042=y ++CONFIG_SERIO_SERPORT=y ++# CONFIG_SERIO_CT82C710 is not set ++CONFIG_SERIO_LIBPS2=y ++# CONFIG_SERIO_RAW is not set ++# CONFIG_GAMEPORT is not set ++ ++# ++# Character devices ++# ++CONFIG_VT=y ++CONFIG_VT_CONSOLE=y ++CONFIG_HW_CONSOLE=y ++# CONFIG_SERIAL_NONSTANDARD is not set ++ ++# ++# Serial drivers ++# ++ ++# ++# Non-8250 serial port support ++# ++CONFIG_UNIX98_PTYS=y ++CONFIG_LEGACY_PTYS=y ++CONFIG_LEGACY_PTY_COUNT=32 ++ ++# ++# IPMI ++# ++# CONFIG_IPMI_HANDLER is not set ++ ++# ++# Watchdog Cards ++# ++# CONFIG_WATCHDOG is not set ++# CONFIG_NVRAM is not set ++# CONFIG_RTC is not set ++# CONFIG_GEN_RTC is not set ++# CONFIG_DTLK is not set ++# CONFIG_R3964 is not set ++ ++# ++# Ftape, the floppy tape device driver ++# ++# CONFIG_FTAPE is not set ++# CONFIG_AGP is not set ++# CONFIG_MWAVE is not set ++# CONFIG_RAW_DRIVER is not set ++# CONFIG_HANGCHECK_TIMER is not set ++ ++# ++# TPM devices ++# ++# CONFIG_TCG_TPM is not set ++# CONFIG_TELCLOCK is not set ++ ++# ++# I2C support ++# ++# CONFIG_I2C is not set ++ ++# ++# SPI support ++# ++# CONFIG_SPI is not set ++# CONFIG_SPI_MASTER is not set ++ ++# ++# Dallas's 1-wire bus ++# ++# CONFIG_W1 is not set ++ ++# ++# Hardware Monitoring support ++# ++# CONFIG_HWMON is not set ++# CONFIG_HWMON_VID is not set ++ ++# ++# Misc devices ++# ++ ++# ++# Multimedia Capabilities Port drivers ++# ++ ++# ++# Multimedia devices ++# ++# CONFIG_VIDEO_DEV is not set ++ ++# ++# Digital Video Broadcasting Devices ++# ++ ++# ++# Graphics support ++# ++# CONFIG_FB is not set ++# CONFIG_VIDEO_SELECT is not set ++ ++# ++# Console display driver support ++# ++CONFIG_VGA_CONSOLE=y ++CONFIG_DUMMY_CONSOLE=y ++ ++# ++# Sound ++# ++# CONFIG_SOUND is not set ++ ++# ++# USB support ++# ++# CONFIG_USB_ARCH_HAS_HCD is not set ++# CONFIG_USB_ARCH_HAS_OHCI is not set ++ ++# ++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' ++# ++ ++# ++# USB Gadget Support ++# ++# CONFIG_USB_GADGET is not set ++ ++# ++# MMC/SD Card support ++# ++# CONFIG_MMC is not set ++ ++# ++# InfiniBand support ++# ++ ++# ++# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) ++# ++# CONFIG_EDAC is not set ++ ++# ++# Firmware Drivers ++# ++# CONFIG_DELL_RBU is not set ++# CONFIG_DCDBAS is not set ++ ++# ++# File systems ++# ++CONFIG_EXT2_FS=y ++CONFIG_EXT2_FS_XATTR=y ++CONFIG_EXT2_FS_POSIX_ACL=y ++CONFIG_EXT2_FS_SECURITY=y ++# CONFIG_EXT2_FS_XIP is not set ++CONFIG_EXT3_FS=y ++CONFIG_EXT3_FS_XATTR=y ++CONFIG_EXT3_FS_POSIX_ACL=y ++CONFIG_EXT3_FS_SECURITY=y ++CONFIG_JBD=y ++# CONFIG_JBD_DEBUG is not set ++CONFIG_FS_MBCACHE=y ++CONFIG_REISERFS_FS=y ++# CONFIG_REISERFS_CHECK is not set ++# CONFIG_REISERFS_PROC_INFO is not set ++CONFIG_REISERFS_FS_XATTR=y ++CONFIG_REISERFS_FS_POSIX_ACL=y ++CONFIG_REISERFS_FS_SECURITY=y ++CONFIG_JFS_FS=y ++CONFIG_JFS_POSIX_ACL=y ++CONFIG_JFS_SECURITY=y ++# CONFIG_JFS_DEBUG is not set ++# CONFIG_JFS_STATISTICS is not set ++CONFIG_FS_POSIX_ACL=y ++CONFIG_XFS_FS=y ++# CONFIG_XFS_QUOTA is not set ++CONFIG_XFS_SECURITY=y ++CONFIG_XFS_POSIX_ACL=y ++# CONFIG_XFS_RT is not set ++CONFIG_MINIX_FS=y ++# CONFIG_ROMFS_FS is not set ++CONFIG_INOTIFY=y ++# CONFIG_QUOTA is not set ++CONFIG_DNOTIFY=y ++# CONFIG_AUTOFS_FS is not set ++# CONFIG_AUTOFS4_FS is not set ++# CONFIG_FUSE_FS is not set ++ ++# ++# CD-ROM/DVD Filesystems ++# ++CONFIG_ISO9660_FS=y ++CONFIG_JOLIET=y ++CONFIG_ZISOFS=y ++CONFIG_ZISOFS_FS=y ++# CONFIG_UDF_FS is not set ++ ++# ++# DOS/FAT/NT Filesystems ++# ++CONFIG_FAT_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_CODEPAGE=437 ++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" ++# CONFIG_NTFS_FS is not set ++ ++# ++# Pseudo filesystems ++# ++CONFIG_PROC_FS=y ++CONFIG_PROC_KCORE=y ++CONFIG_SYSFS=y ++CONFIG_TMPFS=y ++# CONFIG_HUGETLB_PAGE is not set ++CONFIG_RAMFS=y ++# CONFIG_RELAYFS_FS is not set ++# CONFIG_CONFIGFS_FS is not set ++ ++# ++# Miscellaneous filesystems ++# ++# CONFIG_ADFS_FS is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_HFS_FS is not set ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BFS_FS is not set ++# CONFIG_EFS_FS is not set ++# CONFIG_CRAMFS is not set ++# CONFIG_VXFS_FS is not set ++# CONFIG_HPFS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_SYSV_FS is not set ++# CONFIG_UFS_FS is not set ++ ++# ++# Partition Types ++# ++# CONFIG_PARTITION_ADVANCED is not set ++CONFIG_MSDOS_PARTITION=y ++ ++# ++# Native Language Support ++# ++CONFIG_NLS=y ++CONFIG_NLS_DEFAULT="iso8859-1" ++CONFIG_NLS_CODEPAGE_437=y ++# CONFIG_NLS_CODEPAGE_737 is not set ++# CONFIG_NLS_CODEPAGE_775 is not set ++# CONFIG_NLS_CODEPAGE_850 is not set ++# CONFIG_NLS_CODEPAGE_852 is not set ++# CONFIG_NLS_CODEPAGE_855 is not set ++# CONFIG_NLS_CODEPAGE_857 is not set ++# CONFIG_NLS_CODEPAGE_860 is not set ++# CONFIG_NLS_CODEPAGE_861 is not set ++# CONFIG_NLS_CODEPAGE_862 is not set ++# CONFIG_NLS_CODEPAGE_863 is not set ++# CONFIG_NLS_CODEPAGE_864 is not set ++# CONFIG_NLS_CODEPAGE_865 is not set ++# CONFIG_NLS_CODEPAGE_866 is not set ++# CONFIG_NLS_CODEPAGE_869 is not set ++# CONFIG_NLS_CODEPAGE_936 is not set ++# CONFIG_NLS_CODEPAGE_950 is not set ++# CONFIG_NLS_CODEPAGE_932 is not set ++# CONFIG_NLS_CODEPAGE_949 is not set ++# CONFIG_NLS_CODEPAGE_874 is not set ++# CONFIG_NLS_ISO8859_8 is not set ++# CONFIG_NLS_CODEPAGE_1250 is not set ++# CONFIG_NLS_CODEPAGE_1251 is not set ++# CONFIG_NLS_ASCII is not set ++CONFIG_NLS_ISO8859_1=y ++# CONFIG_NLS_ISO8859_2 is not set ++# CONFIG_NLS_ISO8859_3 is not set ++# CONFIG_NLS_ISO8859_4 is not set ++# CONFIG_NLS_ISO8859_5 is not set ++# CONFIG_NLS_ISO8859_6 is not set ++# CONFIG_NLS_ISO8859_7 is not set ++# CONFIG_NLS_ISO8859_9 is not set ++# CONFIG_NLS_ISO8859_13 is not set ++# CONFIG_NLS_ISO8859_14 is not set ++# CONFIG_NLS_ISO8859_15 is not set ++# CONFIG_NLS_KOI8_R is not set ++# CONFIG_NLS_KOI8_U is not set ++# CONFIG_NLS_UTF8 is not set ++ ++# ++# Instrumentation Support ++# ++# CONFIG_PROFILING is not set ++ ++# ++# Kernel hacking ++# ++# CONFIG_PRINTK_TIME is not set ++CONFIG_MAGIC_SYSRQ=y ++CONFIG_DEBUG_KERNEL=y ++CONFIG_LOG_BUF_SHIFT=16 ++CONFIG_DETECT_SOFTLOCKUP=y ++# CONFIG_SCHEDSTATS is not set ++# CONFIG_DEBUG_SLAB is not set ++# CONFIG_DEBUG_MUTEXES is not set ++# CONFIG_DEBUG_SPINLOCK is not set ++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set ++# CONFIG_DEBUG_KOBJECT is not set ++# CONFIG_DEBUG_INFO is not set ++# CONFIG_DEBUG_FS is not set ++# CONFIG_DEBUG_VM is not set ++CONFIG_FRAME_POINTER=y ++CONFIG_FORCED_INLINING=y ++# CONFIG_RCU_TORTURE_TEST is not set ++# CONFIG_DEBUG_RODATA is not set ++ ++# ++# Security options ++# ++# CONFIG_KEYS is not set ++# CONFIG_SECURITY is not set ++ ++# ++# Cryptographic options ++# ++# CONFIG_CRYPTO is not set ++ ++# ++# Hardware crypto devices ++# ++CONFIG_XEN=y ++CONFIG_XEN_INTERFACE_VERSION=0x00030202 ++ ++# ++# XEN ++# ++# CONFIG_XEN_PRIVILEGED_GUEST is not set ++CONFIG_XEN_UNPRIVILEGED_GUEST=y ++CONFIG_XEN_PRIVCMD=y ++CONFIG_XEN_XENBUS_DEV=y ++# CONFIG_XEN_BACKEND is not set ++CONFIG_XEN_BLKDEV_FRONTEND=y ++CONFIG_XEN_SCRUB_PAGES=y ++CONFIG_XEN_DISABLE_SERIAL=y ++# CONFIG_XEN_SYSFS is not set ++CONFIG_XEN_COMPAT_030002_AND_LATER=y ++# CONFIG_XEN_COMPAT_LATEST_ONLY is not set ++CONFIG_XEN_COMPAT_030002=y ++CONFIG_HAVE_ARCH_ALLOC_SKB=y ++CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y ++CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y ++CONFIG_NO_IDLE_HZ=y ++CONFIG_XEN_UTIL=y ++CONFIG_XEN_BALLOON=y ++CONFIG_XEN_DEVMEM=y ++CONFIG_XEN_REBOOT=y ++ ++# ++# Library routines ++# ++# CONFIG_CRC_CCITT is not set ++# CONFIG_CRC16 is not set ++# CONFIG_CRC32 is not set ++# CONFIG_LIBCRC32C is not set ++CONFIG_ZLIB_INFLATE=y +Index: build-32-unstable-12542/buildconfigs/mk.linux-2.6-xenUboot +=================================================================== +--- /dev/null ++++ build-32-unstable-12542/buildconfigs/mk.linux-2.6-xenUboot +@@ -0,0 +1,2 @@ ++EXTRAVERSION = xenUboot ++include buildconfigs/mk.linux-2.6-xen +Index: build-32-unstable-12542/tools/kboot/Makefile +=================================================================== +--- /dev/null ++++ build-32-unstable-12542/tools/kboot/Makefile +@@ -0,0 +1,23 @@ ++# ++# tools/kboot/Makefile ++# ++# This file is subject to the terms and conditions of the GNU General ++# Public License. See the file "COPYING" in the main directory of ++# this archive for more details. ++# ++# Copyright (C) 2005 by Christian Limpach ++# ++ ++XEN_ROOT = ../.. ++include $(XEN_ROOT)/tools/Rules.mk ++ ++.PHONY: all clean ++all: kboot.initramfs ++ ++clean: ++ rm -f kboot.initramfs ++ rm -f *~ ++ ++kboot.initramfs: mkinitramfs init select-kernel ../xcutils/xc_kexec ++ sh ./mkinitramfs | tee $@ ++ +Index: build-32-unstable-12542/tools/kboot/README +=================================================================== +--- /dev/null ++++ build-32-unstable-12542/tools/kboot/README +@@ -0,0 +1,43 @@ ++ ++This is a simple kexec-based boot loader ++======================================== ++ ++Files ++----- ++ ++init this is the /init script for the initramfs ++ ++select-kernel this script searches for bootable xen kernels ++ in a directory (/boot by default). ++ ++mkinitramfs this script generates a file list. It can ++ be passed to CONFIG_INITRAMFS_SOURCE when ++ building a linux kernel. That way you get ++ a linux kernel with the boot loader initramfs ++ compiled in. ++ ++Usage ++----- ++ ++The script gets it arguments from the kernel command line. ++You can use 'extra = "..."' in the domain config file to ++specify them. It recognises the following arguments: ++ ++root= root filesystem (default: /dev/xvda1). ++boot= /boot filesystem (default: none). ++kernel= kernel to boot. If not specified the script ++ inspects /boot and presents a menu in case ++ multiple xen kernels are found. ++ramdisk= ramdisk (initrd) to boot. If not specified ++ the script looks for one matching the kernel ++ file name. ++ ++Any unknown arguments are passed through to the kexec'ed ++kernel. Same goes for the root= argument. ++ ++ ++enjoy, ++ Gerd ++ ++-- ++Gerd Hoffmann +Index: build-32-unstable-12542/tools/kboot/init +=================================================================== +--- /dev/null ++++ build-32-unstable-12542/tools/kboot/init +@@ -0,0 +1,309 @@ ++#!/bin/sh ++ ++ ++######################################################################## ++# messages ++ ++function msg() { ++ local str="$*" ++ echo "### kboot: $str" ++} ++ ++function dmsg() { ++ local str="$*" ++ test "$debug" = "" && return ++ echo "### kboot debug: $str" ++} ++ ++function banner() { ++ local str="$*" ++ /bin/figlet -f /xen.flf "$str" >/dev/null ++} ++ ++ ++######################################################################## ++# helper functions ++ ++function init_storage_linux() { ++ # activate raid ++ if test -x /bin/mdrun && grep -q mdp /proc/devices; then ++ msg "raid support available, activating" ++ mdrun ++ fi ++ ++ # activate lvm ++ if test -x /bin/lvm && grep -q device-mapper /proc/misc; then ++ msg "lvm support available, activating" ++ lvm vgscan --mknodes ++ lvm vgchange -a y ++ if test "$debug" != ""; then ++ dmsg "physical volumes" ++ lvm pvscan ++ dmsg "logical volumes" ++ lvm lvscan ++ fi ++ fi ++} ++ ++function init_network_dhcp() { ++ if test -x /bin/dhcpcd -a -x /bin/ip &&\ ++ ip link ls 2>/dev/null | grep -q eth0; then ++ msg "network support available" ++ msg "activating eth0 using dhcp (15s max) ..." ++ dhcpcd -t 15 eth0 ++ if test "$?" = "0"; then ++ eval "$(grep IPADDR /var/lib/dhcpcd/dhcpcd-eth0.info)" ++ echo "... worked ok: $IPADDR" ++ else ++ echo "... FAILED" ++ fi ++ fi ++} ++ ++function try_mount() { ++ local dev="$1" ++ local dir="$2" ++ ++ if mount | grep -q " ${dir} "; then ++ msg "$dir already mounted" ++ return 0 ++ fi ++ if mount | grep -q "^${dev} "; then ++ msg "$dev already mounted" ++ return 0 ++ fi ++ mount -t auto -o ro $dev $dir ++ if test "$?" = "0"; then ++ msg "mounted $dev at $dir" ++ return 0 ++ else ++ msg "mounting $dev failed" ++ return 1 ++ fi ++} ++ ++function mount_root_boot() { ++ # mount filesystems ++ try_mount "$root" "/root" || return 1 ++ if test "$boot" != ""; then ++ try_mount "$boot" "/root/boot" || return 1 ++ fi ++} ++ ++function linux_find_kernel() { ++ if test "$kernel" != ""; then ++ return ++ fi ++ kernel="/boot/$(select-kernel /root/boot)" ++} ++ ++function linux_find_ramdisk() { ++ if test "$ramdisk" != ""; then ++ return ++ fi ++ ++ for file in \ ++ /root${kernel//vmlinuz/initrd} \ ++ /root${kernel//vmlinuz/initrd}.gz \ ++ /root${kernel//vmlinuz/initrd}.img \ ++ ; do ++ if test -f "$file"; then ++ ramdisk="${file#/root}" ++ break ++ fi ++ done ++ if test "$ramdisk" != ""; then ++ msg "no ramdisk specified, using $ramdisk" ++ fi ++} ++ ++function solaris_find_kernel() { ++ local solaris="" ++ ++ if test "$kernel" != ""; then ++ return ++ fi ++ ++ case "$(uname -m)" in ++ x86_64) ++ solaris="/platform/i86xen/kernel/amd64/unix" ++ ;; ++ i586 | i686) ++ solaris="/platform/i86xen/kernel/unix" ++ ;; ++ esac ++ ++ if test -f "/root$solaris"; then ++ kernel="$solaris" ++ ramdisk="/platform/i86pc/boot_archive" ++ fi ++} ++ ++function netware_find_kernel() { ++ if test "$kernel" != ""; then ++ return ++ fi ++ ++ for file in \ ++ /nwserver/xnloader.sys \ ++ /NWSERVER/XNLOADER.SYS \ ++ /startup/xnloader.sys \ ++ /STARTUP/XNLOADER.SYS \ ++ ; do ++ test -f "/root${file}" || continue ++ msg "netware loader found: $file" ++ kernel="$file" ++ break; ++ done ++} ++ ++ ++######################################################################## ++# main ++ ++# setup ++export PATH="/sbin:/bin" ++export PS1="kboot panic shell \w# " ++trap "echo; exec /bin/sh" EXIT ++ ++# hello world ++exec < /dev/console > /dev/console 2>&1 ++banner "xen mini kboot" ++ ++# mount pseudo filesystems ++mount -v -t proc proc /proc ++mount -v -t sysfs sysfs /sys ++ ++# defaults for arguments ++root="/dev/xvda1" # root filesystem ++boot="" # /boot filesystem (if present) ++kernel="" # kernel to boot ++ramdisk="" # ramdisk to boot ++debug="" # debug mode ++ ++# parse arguments ++cmdline="" ++for cmd in $(cat /proc/cmdline); do ++ case "$cmd" in ++ root=*) ++ root="${cmd#root=}" ++ ;; ++ boot=*) ++ boot="${cmd#boot=}" ++ ;; ++ kernel=*) ++ kernel="${cmd#kernel=}" ++ ;; ++ ramdisk=*) ++ ramdisk="${cmd#ramdisk=}" ++ ;; ++ debug=*) ++ debug="${cmd#debug=}" ++ ;; ++ *) ++ cmdline="$cmdline $cmd" ++ ;; ++ esac ++done ++cmdline="$cmdline root=$root" ++ ++# create block device nodes ++while read major minor blocks name; do ++ case "$name" in ++ xvd* | hd* | sd*) ++ dmsg "blkdev: /dev/$name, major $major, minor $minor" ++ mknod /dev/$name b $major $minor ++ ;; ++ esac ++done < /proc/partitions ++ ++# mount rootfs (and /boot if specified) ++mount_root_boot ++if test "$?" != "0"; then ++ msg "trying to activate raid and lvm first" ++ init_storage_linux; ++ mount_root_boot || exit 1 ++fi ++ ++# activate network device ++# not (yet?) fetching kernels this way, this is ++# only for testing network device handover ... ++init_network_dhcp; ++ ++# figure rootfs type ++set -- $(mount | grep " /root ") ++rootfstype="$5" ++ ++# find kernel if unspecified ++if test "${kernel}" = ""; then ++ case "$rootfstype" in ++ minix | ext2 | ext3 | reiserfs | xfs) ++ linux_find_kernel ++ ;; ++ ufs) ++ solaris_find_kernel ++ ;; ++ vfat) ++ netware_find_kernel ++ ;; ++ *) ++ msg "no kernel location guess for fs \"$rootfstype\"" ++ ;; ++ esac ++fi ++if test ! -f "/root${kernel}"; then ++ msg "ERROR: kernel \"$kernel\" doesn't exist" ++ exit 1 ++fi ++ ++# OS tweaks ++case "$kernel" in ++*/xnloader.sys | */XNLOADER.SYS ) ++ guestos="Netware" ++ ramdisk="" ++ cmdline="" ++ ;; ++*/unix) ++ guestos="Solaris"; ++ cmdline="$cmdline $kernel" ++ ;; ++*linu[xz]*) ++ guestos="Linux" ++ linux_find_ramdisk ++ ;; ++*) ++ guestos="Unknown" ++ ;; ++esac ++ ++# print configuration ++msg "using this boot configuration:" ++msg " root : $root" ++msg " boot : $boot" ++msg " kernel : $kernel" ++msg " ramdisk: $ramdisk" ++msg " cmdline: $cmdline" ++ ++# load kernel & ramdisk ++kexec="-l " ++if test "$debug" != ""; then ++ kexec="$kexec -d" ++ echo 9 > /proc/sysrq-trigger ++fi ++if test "$kernel" != ""; then ++ kexec="$kexec -k /root${kernel}" ++fi ++if test "$ramdisk" != ""; then ++ kexec="$kexec -i /root${ramdisk}" ++fi ++dmsg "run: xc_kexec $kexec -c \"${cmdline}\"" ++xc_kexec $kexec -c "${cmdline}" || exit 1 ++ ++# cleanup ++msg "cleaning up" ++umount -av ++ ++# go! ++msg "bye ..." ++banner "boot $guestos" ++xc_kexec -e +Index: build-32-unstable-12542/tools/kboot/mkinitramfs +=================================================================== +--- /dev/null ++++ build-32-unstable-12542/tools/kboot/mkinitramfs +@@ -0,0 +1,111 @@ ++#!/bin/sh ++ ++# config ++binaries="bash mount umount cat mknod mkdir" # required: some shell bits ++binaries="$binaries xc_kexec" # required: kexec stuff ++binaries="$binaries ls rm grep dialog clear" # required by select-kernel ++binaries="$binaries resize" # required by select-kernel ++binaries="$binaries dmesg free ps" # nice for diagnostics ++binaries="$binaries uname sed cp touch mktemp" # some scripts need this ++binaries="$binaries pidofproc logger" # some scripts need this ++ ++optbin="mdrun mdadm lvm" # optional stuff ++optbin="$optbin dhcpcd ip modify_resolvconf" # optional stuff ++ ++############################################################################ ++ ++# setup ++XEN_ROOT=$(pwd | sed -e 's|/[^/]*/[^/]*$||') ++export PATH="${XEN_ROOT}/tools/xcutils:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin" ++export LD_LIBRARY_PATH="${XEN_ROOT}/tools/libxc" ++ ++# use lib64? ++if ldd /bin/sh | grep -qe '/lib64/'; then ++ LIB="/lib64" ++else ++ LIB="/lib" ++fi ++ ++# static filelist entries ++cat <&2 ++} ++ ++# check kernels ++klist="" ++kcount="1" ++for kernel in $(ls -t $kdir/vmlinu[xz]* 2>/dev/null); do ++ msg "checking $kernel ..." ++ type="$(xc_kexec -t -k $kernel)" ++ case "$type" in ++ xen-3.0-x86_32 | xen-3.0-x86_32p | xen-3.0-x86_64) ++ # yes, this is a xen kernel ++ msg "... $type, ok" ++ klist="$klist ${kcount} ${kernel#$kdir/}" ++ eval "kernel${kcount}=${kernel#$kdir/}" ++ kcount=$(( $kcount + 1 )) ++ ;; ++ *) ++ msg "... $type, ignore" ++ continue ++ ;; ++ esac ++done ++if test "$kcount" = "1"; then ++ msg "no xen kernel found in $kdir" ++ exit 1 ++fi ++ ++if test "$kcount" = "2"; then ++ # only one kernel ++ msg "one xen kernel found in $kdir, using it" ++ kernelnr=1 ++else ++ # present menu to pick kernel ++ export TERM=vt100 ++ eval $(resize) ++ kernelnr=$(dialog --stdout --timeout 10 \ ++ --menu "xen kboot -- kernel menu (10s timeout)" \ ++ 20 60 12 $klist) ++ clear >&2 ++ if test "$kernelnr" = ""; then ++ # timeout, also quit via ESC, pick first then ++ kernelnr=1 ++ fi ++fi ++ ++# print result ++eval "kernelname=\${kernel$kernelnr}" ++msg "using $kernelname" ++echo "$kernelname" ++ +Index: build-32-unstable-12542/make-kboot +=================================================================== +--- /dev/null ++++ build-32-unstable-12542/make-kboot +@@ -0,0 +1,37 @@ ++#!/bin/sh ++ ++test -f .buildenv && source .buildenv ++set -ex ++ ++# update tools ++make -C tools/libxc ++make -C tools/xcutils/helper ++make -C tools/xcutils ++make -C tools/kboot ++ ++# update kernel ++ks=$(echo linux-2.6*-xenUboot) ++if test ! -d "$ks"; then ++ make CONFIGMODE=oldconfig linux-2.6-xenUboot-config ++ ks=$(echo linux-2.6*-xenUboot) ++fi ++if ! grep -q tools/kboot/kboot.initramfs $ks/.config; then ++ # fixup configuration if needed ++ src="$(pwd)/tools/kboot/kboot.initramfs" ++ sed -i.kboot \ ++ -e "/KEXEC/s|.*|CONFIG_KEXEC=y|" \ ++ -e "/INITRAMFS_SOURCE/s|=.*|=\"$src\"|" \ ++ "$ks/.config" ++ make -C "$ks" oldconfig ++fi ++make -C "$ks" ++ ++# copy boot loader ++cp $ks/vmlinuz ../kboot/vmlinuz-xen-kboot.${BTYPE-default} ++cp tools/kboot/README ../kboot/README.vmlinuz-xen-kboot ++ ++# create assembler listings ++objdump -d $ks/vmlinux > vmlinux-xenUboot.asm ++objdump -dr tools/xcutils/helper/helper.elf > helper.asm ++objdump -t tools/xcutils/helper/helper.elf | grep ^0 | sort > helper.sym ++ diff --git a/tools-readnotes-gunzip.diff b/tools-readnotes-gunzip.diff new file mode 100644 index 0000000..4d1a5a6 --- /dev/null +++ b/tools-readnotes-gunzip.diff @@ -0,0 +1,46 @@ +Support transparant gunzipping in the readnotes utility. + +Signed-off-by: Gerd Hoffmann +--- + tools/xcutils/readnotes.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +Index: build-32-release304-13138/tools/xcutils/readnotes.c +=================================================================== +--- build-32-release304-13138.orig/tools/xcutils/readnotes.c ++++ build-32-release304-13138/tools/xcutils/readnotes.c +@@ -11,6 +11,7 @@ + #include + + #include ++#include /* gunzip bits */ + + #include + +@@ -33,8 +34,8 @@ static void print_numeric_note(const cha + int main(int argc, char **argv) + { + const char *f; +- int fd,h,size,count; +- void *image; ++ int fd,h,size,usize,count; ++ void *image,*tmp; + struct stat st; + struct elf_binary elf; + const elf_shdr *shdr; +@@ -68,6 +69,15 @@ int main(int argc, char **argv) + } + size = st.st_size; + ++ usize = xc_dom_check_gzip(image, st.st_size); ++ if (usize) ++ { ++ tmp = malloc(usize); ++ xc_dom_do_gunzip(image, st.st_size, tmp, usize); ++ image = tmp; ++ size = usize; ++ } ++ + if (0 != elf_init(&elf, image, size)) + { + fprintf(stderr, "File %s is not an ELF image\n", f); diff --git a/tools-xc_kexec.diff b/tools-xc_kexec.diff new file mode 100644 index 0000000..8cbaa89 --- /dev/null +++ b/tools-xc_kexec.diff @@ -0,0 +1,5135 @@ +xc_kexec utility, for domU kexec support. + +Signed-off-by: Gerd Hoffmann +--- + tools/xcutils/Makefile | 10 + tools/xcutils/helper/Makefile | 39 + + tools/xcutils/helper/console.c | 69 ++ + tools/xcutils/helper/ctype.c | 35 + + tools/xcutils/helper/ctype.h | 54 + + tools/xcutils/helper/helper.h | 107 +++ + tools/xcutils/helper/main.c | 651 +++++++++++++++++++ + tools/xcutils/helper/make-offsets.c | 28 + tools/xcutils/helper/printk.c | 1051 ++++++++++++++++++++++++++++++++ + tools/xcutils/helper/string.c | 601 ++++++++++++++++++ + tools/xcutils/helper/vsprintf.c | 842 +++++++++++++++++++++++++ + tools/xcutils/helper/x86_32/div64.h | 48 + + tools/xcutils/helper/x86_32/entry.S | 49 + + tools/xcutils/helper/x86_32/hypercall.h | 360 ++++++++++ + tools/xcutils/helper/x86_64/div64.h | 58 + + tools/xcutils/helper/x86_64/entry.S | 50 + + tools/xcutils/helper/x86_64/hypercall.h | 355 ++++++++++ + tools/xcutils/kexec-syscall.h | 80 ++ + tools/xcutils/xc_kexec.c | 503 +++++++++++++++ + 19 files changed, 4988 insertions(+), 2 deletions(-) + +Index: build-32-release304-12901/tools/xcutils/Makefile +=================================================================== +--- build-32-release304-12901.orig/tools/xcutils/Makefile ++++ build-32-release304-12901/tools/xcutils/Makefile +@@ -15,14 +15,14 @@ PROGRAMS_INSTALL_DIR = /usr/$(LIBDIR)/xe + + INCLUDES += -I $(XEN_LIBXC) + +-CFLAGS += -Werror -fno-strict-aliasing ++CFLAGS += -g -O0 -Werror -fno-strict-aliasing + CFLAGS += $(INCLUDES) + + # Make gcc generate dependencies. + CFLAGS += -Wp,-MD,.$(@F).d + PROG_DEP = .*.d + +-PROGRAMS = xc_restore xc_save readnotes ++PROGRAMS = xc_restore xc_save readnotes xc_kexec + + LDLIBS = -L$(XEN_LIBXC) -lxenguest -lxenctrl + +@@ -35,6 +35,11 @@ build: $(PROGRAMS) + $(PROGRAMS): %: %.o + $(CC) $(CFLAGS) $^ $(LDLIBS) -o $@ + ++xc_kexec.o: xc_kexec.c helper/blob.h ++ ++helper/blob.h: ++ make -C helper ++ + .PHONY: install + install: build + [ -d $(DESTDIR)$(PROGRAMS_INSTALL_DIR) ] || \ +@@ -46,5 +51,6 @@ install: build + clean: + $(RM) *.o $(PROGRAMS) + $(RM) $(PROG_DEP) ++ make -C helper clean + + -include $(PROG_DEP) +Index: build-32-release304-12901/tools/xcutils/helper/Makefile +=================================================================== +--- /dev/null ++++ build-32-release304-12901/tools/xcutils/helper/Makefile +@@ -0,0 +1,39 @@ ++ ++XEN_ROOT = ../../.. ++include $(XEN_ROOT)/tools/Rules.mk ++ ++OBJS := $(XEN_TARGET_ARCH)/entry.o ++OBJS += main.o console.o vsprintf.o string.o ctype.o ++ ++CFLAGS += -g -I$(XEN_ROOT)/tools/libxc -I$(XEN_TARGET_ARCH) ++ ++ifeq ($(XEN_TARGET_ARCH),x86_32) ++HLP_LDFLAGS := -melf_i386 ++endif ++ ++HLP_LDFLAGS += --section-start .text=0x10000 ++HLP_LDFLAGS += --section-start .data=0x20000 ++HLP_LDFLAGS += --emit-relocs ++ ++##################### ++# rules ++ ++all: blob.h ++ ++clean: ++ rm -rf helper.elf blob.h ++ rm -rf $(OBJS) *~ ++ ++helper.elf: $(OBJS) ++ ld $(HLP_LDFLAGS) -o $@ $^ ++ ++blob.h: helper.elf ++ hexdump -v -e '1/1 "0x%02x,\n"' $< > $@ ++ ++$(XEN_TARGET_ARCH)/offsets.h: make-offsets ++ ./make-offsets > $@ ++ ++##################### ++# dependencies ++ ++$(XEN_TARGET_ARCH)/entry.o: $(XEN_TARGET_ARCH)/entry.S $(XEN_TARGET_ARCH)/offsets.h +Index: build-32-release304-12901/tools/xcutils/helper/console.c +=================================================================== +--- /dev/null ++++ build-32-release304-12901/tools/xcutils/helper/console.c +@@ -0,0 +1,69 @@ ++#include ++ ++#include ++#include ++#include "hypercall.h" ++ ++#include "helper.h" ++ ++static inline int notify_remote_via_evtchn(int port) ++{ ++ struct evtchn_send send; ++ send.port = port; ++ return HYPERVISOR_event_channel_op(EVTCHNOP_send, &send); ++} ++ ++static inline struct xencons_interface *xencons_interface(void) ++{ ++ return (void*)(console_page); ++} ++ ++static int xencons_ring_send(const char *data, unsigned len) ++{ ++ int sent = 0; ++ struct xencons_interface *intf = xencons_interface(); ++ XENCONS_RING_IDX cons, prod; ++ ++ cons = intf->out_cons; ++ prod = intf->out_prod; ++ mb(); ++ ++ while ((sent < len) && ((prod - cons) < sizeof(intf->out))) ++ intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++]; ++ ++ wmb(); ++ intf->out_prod = prod; ++ ++ if (0 != notify_remote_via_evtchn(console_evtchn)) ++ return -1; ++ return sent; ++} ++ ++int printk(const char *fmt, ...) ++{ ++ va_list args; ++ int r; ++ ++ va_start(args, fmt); ++ r = vprintk(fmt, args); ++ va_end(args); ++ ++ return r; ++} ++ ++int vprintk(const char *fmt, va_list args) ++{ ++ static char printk_buf[1024]; ++ static char prefix[] = "printk: "; ++ int printed_len; ++ ++ /* Emit the output into the temporary buffer */ ++ printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args); ++ if (xencons_ring_send(printk_buf, printed_len) < 0) { ++ /* shouldn't happen, but better have a fallback ;) */ ++ HYPERVISOR_console_io(CONSOLEIO_write, strlen(prefix), prefix); ++ HYPERVISOR_console_io(CONSOLEIO_write, printed_len, printk_buf); ++ } ++ ++ return printed_len; ++} +Index: build-32-release304-12901/tools/xcutils/helper/ctype.c +=================================================================== +--- /dev/null ++++ build-32-release304-12901/tools/xcutils/helper/ctype.c +@@ -0,0 +1,35 @@ ++/* ++ * linux/lib/ctype.c ++ * ++ * Copyright (C) 1991, 1992 Linus Torvalds ++ */ ++ ++#include "helper.h" ++ ++unsigned char _ctype[] = { ++_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ ++_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ ++_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ ++_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ ++_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ ++_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ ++_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ ++_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ ++_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ ++_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ ++_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ ++_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ ++_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ ++_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ ++_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ ++_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ ++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ ++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ ++_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */ ++_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */ ++_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */ ++_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */ ++_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */ ++_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */ ++ ++EXPORT_SYMBOL(_ctype); +Index: build-32-release304-12901/tools/xcutils/helper/ctype.h +=================================================================== +--- /dev/null ++++ build-32-release304-12901/tools/xcutils/helper/ctype.h +@@ -0,0 +1,54 @@ ++#ifndef _LINUX_CTYPE_H ++#define _LINUX_CTYPE_H ++ ++/* ++ * NOTE! This ctype does not handle EOF like the standard C ++ * library is required to. ++ */ ++ ++#define _U 0x01 /* upper */ ++#define _L 0x02 /* lower */ ++#define _D 0x04 /* digit */ ++#define _C 0x08 /* cntrl */ ++#define _P 0x10 /* punct */ ++#define _S 0x20 /* white space (space/lf/tab) */ ++#define _X 0x40 /* hex digit */ ++#define _SP 0x80 /* hard space (0x20) */ ++ ++extern unsigned char _ctype[]; ++ ++#define __ismask(x) (_ctype[(int)(unsigned char)(x)]) ++ ++#define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0) ++#define isalpha(c) ((__ismask(c)&(_U|_L)) != 0) ++#define iscntrl(c) ((__ismask(c)&(_C)) != 0) ++#define isdigit(c) ((__ismask(c)&(_D)) != 0) ++#define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0) ++#define islower(c) ((__ismask(c)&(_L)) != 0) ++#define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0) ++#define ispunct(c) ((__ismask(c)&(_P)) != 0) ++#define isspace(c) ((__ismask(c)&(_S)) != 0) ++#define isupper(c) ((__ismask(c)&(_U)) != 0) ++#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0) ++ ++#define isascii(c) (((unsigned char)(c))<=0x7f) ++#define toascii(c) (((unsigned char)(c))&0x7f) ++ ++static inline unsigned char __tolower(unsigned char c) ++{ ++ if (isupper(c)) ++ c -= 'A'-'a'; ++ return c; ++} ++ ++static inline unsigned char __toupper(unsigned char c) ++{ ++ if (islower(c)) ++ c -= 'a'-'A'; ++ return c; ++} ++ ++#define tolower(c) __tolower(c) ++#define toupper(c) __toupper(c) ++ ++#endif +Index: build-32-release304-12901/tools/xcutils/helper/helper.h +=================================================================== +--- /dev/null ++++ build-32-release304-12901/tools/xcutils/helper/helper.h +@@ -0,0 +1,107 @@ ++#include ++#include ++#include ++#include ++ ++#if defined(__i386__) ++typedef unsigned int size_t; ++typedef int ptrdiff_t; ++#define BITS_PER_LONG 32 ++#elif defined(__x86_64__) ++typedef unsigned long size_t; ++typedef long ptrdiff_t; ++#define BITS_PER_LONG 64 ++#else ++#error fixme please: unknown arch ++#endif ++ ++/* from linux */ ++#include "ctype.h" ++#include "div64.h" ++ ++/* some stuff to compile linux kernel sources almost unmodified */ ++#define unlikely(x) (x) ++#define WARN_ON(x) ++#define BUG_ON(x) ++#define EXPORT_SYMBOL(x) ++ ++#ifndef PAGE_SHIFT ++# define PAGE_SHIFT 12 ++# define PAGE_SIZE (1< ++#include "hypercall.h" ++ ++#include "helper.h" ++#undef machine_to_phys_mapping ++ ++/* filled by xc_kexec */ ++unsigned long debug_level = 0; ++unsigned long virt_base; ++unsigned long virt_hypercall; ++unsigned long console_evtchn; ++#if defined(__i386__) ++unsigned long pae_paging; ++#endif ++struct vcpu_guest_context vcpu; ++ ++/* passed by trampoline in %esi */ ++struct start_info *old_info; ++ ++/* my data */ ++static struct start_info *new_info; ++static xen_pfn_t *phys_to_machine_mapping; ++static xen_pfn_t *machine_to_phys_mapping; ++static void (*start_kernel)(void); ++ ++/* magic pages */ ++page_t console_page; ++page_t xenstore_page; ++static page_t shared_info_page; ++static struct shared_info *shared_info = (void*)shared_info_page; ++ ++#define dprintk if (debug_level >= 1) printk ++ ++/* ------------------------------------------------------------------ */ ++ ++static unsigned char xen_features[XENFEAT_NR_SUBMAPS * 32]; ++#define xen_feature(flag) (xen_features[flag]) ++ ++static void setup_xen_features(void) ++{ ++ xen_feature_info_t fi; ++ int i, j; ++ ++ for (i = 0; i < XENFEAT_NR_SUBMAPS; i++) { ++ fi.submap_idx = i; ++ if (HYPERVISOR_xen_version(XENVER_get_features, &fi) < 0) ++ break; ++ for (j=0; j<32; j++) ++ xen_features[i*32+j] = !!(fi.submap & 1< ++#include ++static void xenstore_debug(void) ++{ ++ struct xenstore_domain_interface *xs = (void*)xenstore_page; ++ ++ printk("xs: req %4d -> %4d\r\n", xs->req_cons, xs->req_prod); ++ printk("xs: rsp %4d -> %4d\r\n", xs->rsp_cons, xs->rsp_prod); ++ if (xs->req_cons != xs->req_prod) ++ return; ++ if (xs->rsp_cons != xs->rsp_prod) ++ return; ++ ++ memset(xenstore_page, 0, PAGE_SIZE); ++ wmb(); ++ printk("xs: debug fixup [zero page] done\r\n"); ++} ++#endif ++ ++/* ------------------------------------------------------------------ */ ++ ++#define INVALID_P2M_ENTRY (~0UL) ++#define FOREIGN_FRAME_BIT (1UL<<31) ++#define pfn_to_mfn(pfn) (phys_to_machine_mapping[pfn] & ~FOREIGN_FRAME_BIT) ++#define mfn_to_pfn(mfn) (machine_to_phys_mapping[mfn]) ++#define set_phys_to_machine(pfn, mfn) (phys_to_machine_mapping[pfn] = mfn) ++#define phys_to_machine_mapping_valid(pfn) (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY) ++ ++void xen_machphys_update(unsigned long mfn, unsigned long pfn) ++{ ++ mmu_update_t u; ++ int rc; ++ ++ u.ptr = ((unsigned long long)mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE; ++ u.val = pfn; ++ rc = HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF); ++ if (0 == rc) ++ return; ++ printk("Oops: HYPERVISOR_mmu_update: rc=%d\r\n",rc); ++} ++ ++static void swap_pages_p2m(unsigned long pfn1, unsigned long pfn2) ++{ ++ unsigned long mfn1, mfn2; ++ ++ mfn1 = phys_to_machine_mapping_valid(pfn1) ++ ? pfn_to_mfn(pfn1) : INVALID_P2M_ENTRY; ++ mfn2 = phys_to_machine_mapping_valid(pfn2) ++ ? pfn_to_mfn(pfn2) : INVALID_P2M_ENTRY; ++ dprintk("%s: pfn %5lx / mfn %5lx <=> pfn %5lx / mfn %5lx\r\n", ++ __FUNCTION__, pfn1, mfn1, pfn2, mfn2); ++ ++ if (mfn1 != INVALID_P2M_ENTRY) ++ xen_machphys_update(mfn1, INVALID_P2M_ENTRY); ++ if (mfn2 != INVALID_P2M_ENTRY) ++ xen_machphys_update(mfn2, INVALID_P2M_ENTRY); ++ ++ set_phys_to_machine(pfn2, mfn1); ++ if (mfn1 != INVALID_P2M_ENTRY) ++ xen_machphys_update(mfn1, pfn2); ++ ++ set_phys_to_machine(pfn1, mfn2); ++ if (mfn2 != INVALID_P2M_ENTRY) ++ xen_machphys_update(mfn2, pfn1); ++} ++ ++static void plug_holes_p2m(void) ++{ ++ unsigned long pfns = shared_info->arch.max_pfn; ++ unsigned long take, give; ++ int count = 0; ++ ++ take = 0; ++ give = pfns-1; ++ ++ for (;;) { ++ while (take < give && phys_to_machine_mapping_valid(take)) ++ take++; ++ for (; take < give; give--) { ++ if (!phys_to_machine_mapping_valid(give)) ++ continue; ++ break; ++ } ++ if (take >= give) ++ break; ++ swap_pages_p2m(give--,take++); ++ count++; ++ } ++ if (!phys_to_machine_mapping_valid(take)) ++ take--; ++ ++ new_info->nr_pages = take+1; ++ dprintk("%s: %d swaps, nr_pages is 0x%lx (0x%lx max)\r\n", ++ __FUNCTION__, count, new_info->nr_pages, pfns); ++} ++ ++static void fillup_memory_p2m(void) ++{ ++ struct xen_memory_reservation reservation = { ++ .address_bits = 0, ++ .extent_order = 0, ++ .nr_extents = 1, ++ .domid = DOMID_SELF, ++ }; ++ unsigned long pfns = shared_info->arch.max_pfn; ++ unsigned long pfn, mfn; ++ int rc, count = 0; ++ ++ for (pfn = new_info->nr_pages; pfn < pfns; count++, pfn++) { ++ set_xen_guest_handle(reservation.extent_start, &mfn); ++ rc = HYPERVISOR_memory_op(XENMEM_populate_physmap, ++ &reservation); ++ if (1 != rc) ++ break; ++ xen_machphys_update(mfn, pfn); ++ set_phys_to_machine(pfn, mfn); ++ } ++ ++ new_info->nr_pages = pfn; ++ printk("%s: got %d pages, nr_pages is 0x%lx (0x%lx max)\r\n", ++ __FUNCTION__, count, new_info->nr_pages, pfns); ++} ++ ++#define P2M_ENTRIES (PAGE_SIZE/sizeof(xen_pfn_t)) ++#define mfn_to_addr(mfn) ((void*)(mfn_to_pfn(mfn) << PAGE_SHIFT)) ++ ++static void p2m_copy(void) ++{ ++ xen_pfn_t *mfn_lol = NULL, *mfn_list = NULL; ++ unsigned int off_lol = 0, off_list = 0; ++ xen_pfn_t pfn; ++ ++ phys_to_machine_mapping = (unsigned long*)(new_info->mfn_list - virt_base); ++ for (pfn = 0; pfn < shared_info->arch.max_pfn; pfn += P2M_ENTRIES) { ++ if (0 == pfn) { ++ mfn_lol = mfn_to_addr(shared_info->arch.pfn_to_mfn_frame_list_list); ++ off_lol = 0; ++ } ++ if (0 == (pfn % (P2M_ENTRIES * P2M_ENTRIES))) { ++ mfn_list = mfn_to_addr(mfn_lol[off_lol++]); ++ off_list = 0; ++ } ++ memcpy(phys_to_machine_mapping + pfn, ++ mfn_to_addr(mfn_list[off_list++]), ++ PAGE_SIZE); ++ } ++} ++ ++static void xen_tlb_flush(void) ++{ ++ struct mmuext_op op; ++ op.cmd = MMUEXT_TLB_FLUSH_LOCAL; ++ HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF); ++} ++ ++/* ------------------------------------------------------------------ */ ++ ++#if defined(__i386__) ++ ++static void map_page_32(page_t page, unsigned long mfn, unsigned long flags) ++{ ++ unsigned long vaddr = (unsigned long)page; ++ uint32_t *pgd = (void*)old_info->pt_base; ++ uint32_t *pte; ++ unsigned long pfn; ++ int pgd_off, pte_off; ++ ++ pgd_off = (vaddr >> 22) & (1024-1); ++ pte_off = (vaddr >> 12) & (1024-1); ++ ++ pfn = mfn_to_pfn(pgd[pgd_off] >> PAGE_SHIFT); ++ pte = (void*)(pfn << PAGE_SHIFT); ++ ++ pte[pte_off] = (mfn << PAGE_SHIFT) | flags; ++} ++ ++static void map_virt_base_32(void) ++{ ++ mmu_update_t u; ++ xen_pfn_t pgd_mfn = pfn_to_mfn(old_info->pt_base >> PAGE_SHIFT); ++ uint32_t *pgd_ma = (void*)(pgd_mfn << PAGE_SHIFT); ++ uint32_t *pgd = (void*)old_info->pt_base; ++ uint32_t pgd_virt = virt_base >> 22; ++ uint32_t pgd_low = 0; ++ ++ if (pgd_virt << 22 != virt_base) { ++ printk("%s: warning: virt_base is not at pgd entry border,\r\n" ++ " that will work only if old and new kernel have\r\n" ++ " an identical virt_base.\r\n", __FUNCTION__); ++ return; ++ } ++ ++ for (;;) { ++ if (!(pgd[pgd_low] & _PAGE_PRESENT)) ++ return; ++ u.ptr = (unsigned long)(pgd_ma + pgd_virt); ++ u.val = pgd[pgd_low]; ++ if (HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF) < 0) { ++ printk("%s: mmu_update failed [l2 0x%x -> 0x%x]\r\n", ++ __FUNCTION__, pgd_low, pgd_virt); ++ return; ++ } ++ pgd_virt++; ++ pgd_low++; ++ } ++} ++ ++static void map_page_pae(page_t page, unsigned long mfn, unsigned long flags) ++{ ++ unsigned long vaddr = (unsigned long)page; ++ uint64_t *pgd = (void*)old_info->pt_base; ++ uint64_t *pmd; ++ uint64_t *pte; ++ unsigned long pfn; ++ int pgd_off, pmd_off, pte_off; ++ ++ pgd_off = (vaddr >> 30) & (4-1); ++ pmd_off = (vaddr >> 21) & (512-1); ++ pte_off = (vaddr >> 12) & (512-1); ++ ++ pfn = mfn_to_pfn(pgd[pgd_off] >> PAGE_SHIFT); ++ pmd = (void*)(pfn << PAGE_SHIFT); ++ pfn = mfn_to_pfn(pmd[pmd_off] >> PAGE_SHIFT); ++ pte = (void*)(pfn << PAGE_SHIFT); ++ ++ pte[pte_off] = (mfn << PAGE_SHIFT) | flags; ++} ++ ++static void map_virt_base_pae(void) ++{ ++ mmu_update_t u; ++ xen_pfn_t pgd_mfn = pfn_to_mfn(old_info->pt_base >> PAGE_SHIFT); ++ uint64_t *pgd_ma = (void*)(pgd_mfn << PAGE_SHIFT); ++ uint64_t *pgd = (void*)old_info->pt_base; ++ int i; ++ ++ for (i = 1; i <= 2; i++) { ++ u.ptr = (unsigned long)(pgd_ma + i); ++ u.val = pgd[0]; ++ if (HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF) < 0) { ++ printk("%s: mmu_update failed [l3 0 -> %d]\r\n", ++ __FUNCTION__, i); ++ return; ++ } ++ } ++} ++ ++static void map_page(page_t page, unsigned long mfn, unsigned long flags) ++{ ++ if (pae_paging) ++ map_page_pae(page, mfn, flags); ++ else ++ map_page_32(page, mfn, flags); ++ xen_tlb_flush(); ++ wmb(); ++} ++ ++static void map_virt_base(void) ++{ ++ if (pae_paging) ++ map_virt_base_pae(); ++ else ++ map_virt_base_32(); ++ xen_tlb_flush(); ++ wmb(); ++} ++ ++static void fixup_pagetables_32(void) ++{ ++ uint32_t *pgd = (void*)new_info->pt_base - virt_base; ++ uint32_t *pte; ++ uint32_t flg; ++ unsigned long pfn; ++ int l2, l1; ++ ++ dprintk("%s: pgd at 0x%p\r\n", __FUNCTION__, pgd); ++ for (l2 = 0; l2 < 1024; l2++) { ++ if (!pgd[l2] & 1) ++ continue; ++ flg = pgd[l2] & (PAGE_SIZE-1); ++ pfn = pgd[l2] >> PAGE_SHIFT; ++ pgd[l2] = (pfn_to_mfn(pfn) << PAGE_SHIFT) | flg; ++ ++#if 1 ++ /* Dirty hack alert: Add identity map for first 4MB, ++ * so we don't kill ourself when activating the new ++ * kernel's page tables. May have the side effect of ++ * killing the kernel later. */ ++ if (!pgd[0]) ++ pgd[0] = pgd[l2]; ++#endif ++ ++ pte = (void*)(pfn << PAGE_SHIFT); ++ dprintk("%s: pte at 0x%p\r\n", __FUNCTION__, pte); ++ for (l1 = 0; l1 < 1024; l1++) { ++ if (!pte[l1] & 1) ++ continue; ++ flg = pte[l1] & (PAGE_SIZE-1); ++ pfn = pte[l1] >> PAGE_SHIFT; ++ pte[l1] = (pfn_to_mfn(pfn) << PAGE_SHIFT) | flg; ++ } ++ } ++} ++ ++static void fixup_pagetables_pae(void) ++{ ++ uint64_t *pgd = (void*)new_info->pt_base - virt_base; ++ uint64_t *pmd; ++ uint64_t *pte; ++ uint64_t flg; ++ unsigned long pfn; ++ int l3, l2, l1; ++ ++ dprintk("%s: pgd at 0x%p\r\n", __FUNCTION__, pgd); ++ for (l3 = 0; l3 < 4; l3++) { ++ if (!pgd[l3] & 1) ++ continue; ++ flg = pgd[l3] & (PAGE_SIZE-1); ++ pfn = pgd[l3] >> PAGE_SHIFT; ++ pgd[l3] = (pfn_to_mfn(pfn) << PAGE_SHIFT) | flg; ++ ++ pmd = (void*)(pfn << PAGE_SHIFT); ++ dprintk("%s: pmd at 0x%p\r\n", __FUNCTION__, pmd); ++ for (l2 = 0; l2 < 512; l2++) { ++ if (!pmd[l2] & 1) ++ continue; ++ flg = pmd[l2] & (PAGE_SIZE-1); ++ pfn = pmd[l2] >> PAGE_SHIFT; ++ pmd[l2] = (pfn_to_mfn(pfn) << PAGE_SHIFT) | flg; ++ ++ pte = (void*)(pfn << PAGE_SHIFT); ++ dprintk("%s: pte at 0x%p\r\n", __FUNCTION__, pte); ++ for (l1 = 0; l1 < 512; l1++) { ++ if (!pte[l1] & 1) ++ continue; ++ flg = pte[l1] & (PAGE_SIZE-1); ++ pfn = pte[l1] >> PAGE_SHIFT; ++ pte[l1] = (pfn_to_mfn(pfn) << PAGE_SHIFT) | flg; ++ } ++ } ++ } ++} ++ ++static void fixup_pagetables(void) ++{ ++ if (pae_paging) ++ fixup_pagetables_pae(); ++ else ++ fixup_pagetables_32(); ++} ++ ++#endif /* i386 */ ++ ++#if defined(__x86_64__) ++ ++static void map_page(page_t page, unsigned long mfn, unsigned long flags) ++{ ++ unsigned long vaddr = (unsigned long)page; ++ uint64_t *pgd = (void*)old_info->pt_base; ++ uint64_t *pud; ++ uint64_t *pmd; ++ uint64_t *pte; ++ xen_pfn_t pfn; ++ int pgd_off, pud_off, pmd_off, pte_off; ++ ++ pgd_off = (vaddr >> 39) & (512-1); ++ pud_off = (vaddr >> 30) & (512-1); ++ pmd_off = (vaddr >> 21) & (512-1); ++ pte_off = (vaddr >> 12) & (512-1); ++ ++ pfn = mfn_to_pfn(pgd[pgd_off] >> PAGE_SHIFT); ++ pud = (void*)(pfn << PAGE_SHIFT); ++ pfn = mfn_to_pfn(pud[pud_off] >> PAGE_SHIFT); ++ pmd = (void*)(pfn << PAGE_SHIFT); ++ pfn = mfn_to_pfn(pmd[pmd_off] >> PAGE_SHIFT); ++ pte = (void*)(pfn << PAGE_SHIFT); ++ ++ pte[pte_off] = (mfn << PAGE_SHIFT) | flags; ++ ++ xen_tlb_flush(); ++ wmb(); ++} ++ ++static void map_virt_base(void) ++{ ++ mmu_update_t u; ++ xen_pfn_t pgd_mfn = pfn_to_mfn(old_info->pt_base >> PAGE_SHIFT); ++ uint64_t *pgd_ma = (void*)(pgd_mfn << PAGE_SHIFT); ++ uint64_t *pgd = (void*)old_info->pt_base; ++ uint64_t pgd_virt = (virt_base >> 39); ++ uint64_t pgd_low = 0; ++ ++ if (pgd_virt << 39 != virt_base) { ++ printk("%s: warning: virt_base is not at pgd entry border,\r\n" ++ " that will work only if old and new kernel have\r\n" ++ " an identical virt_base.\r\n", __FUNCTION__); ++ return; ++ } ++ ++ for (;;) { ++ if (!(pgd[pgd_low] & _PAGE_PRESENT)) ++ break; ++ u.ptr = (unsigned long)(pgd_ma + pgd_virt); ++ u.val = pgd[pgd_low]; ++ printk("%s: ptr 0x%" PRIx64" val 0x%" PRIx64"\r\n", ++ __FUNCTION__, u.ptr, u.val); ++ if (HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF) < 0) { ++ printk("%s: mmu_update failed [l4 0x%lx -> 0x%lx]\r\n", ++ __FUNCTION__, pgd_low, pgd_virt); ++ break; ++ } ++ pgd_virt++; ++ pgd_low++; ++ } ++ xen_tlb_flush(); ++ wmb(); ++} ++ ++static void fixup_pagetables(void) ++{ ++ uint64_t *pgd = (void*)new_info->pt_base - virt_base; ++ uint64_t *pud; ++ uint64_t *pmd; ++ uint64_t *pte; ++ uint64_t flg; ++ unsigned long pfn; ++ int l4, l3, l2, l1; ++ ++ dprintk("%s: pgd at 0x%p\r\n", __FUNCTION__, pgd); ++ for (l4 = 0; l4 < 512; l4++) { ++ if (!pgd[l4] & 1) ++ continue; ++ flg = pgd[l4] & (PAGE_SIZE-1); ++ pfn = pgd[l4] >> PAGE_SHIFT; ++ pgd[l4] = (pfn_to_mfn(pfn) << PAGE_SHIFT) | flg; ++ ++ pud = (void*)(pfn << PAGE_SHIFT); ++ dprintk("%s: pud at 0x%p\r\n", __FUNCTION__, pud); ++ for (l3 = 0; l3 < 512; l3++) { ++ if (!pud[l3] & 1) ++ continue; ++ flg = pud[l3] & (PAGE_SIZE-1); ++ pfn = pud[l3] >> PAGE_SHIFT; ++ pud[l3] = (pfn_to_mfn(pfn) << PAGE_SHIFT) | flg; ++ ++ pmd = (void*)(pfn << PAGE_SHIFT); ++ dprintk("%s: pmd at 0x%p\r\n", __FUNCTION__, pmd); ++ for (l2 = 0; l2 < 512; l2++) { ++ if (!pmd[l2] & 1) ++ continue; ++ flg = pmd[l2] & (PAGE_SIZE-1); ++ pfn = pmd[l2] >> PAGE_SHIFT; ++ pmd[l2] = (pfn_to_mfn(pfn) << PAGE_SHIFT) | flg; ++ ++ pte = (void*)(pfn << PAGE_SHIFT); ++ dprintk("%s: pte at 0x%p\r\n", __FUNCTION__, pte); ++ for (l1 = 0; l1 < 512; l1++) { ++ if (!pte[l1] & 1) ++ continue; ++ flg = pte[l1] & (PAGE_SIZE-1); ++ pfn = pte[l1] >> PAGE_SHIFT; ++ pte[l1] = (pfn_to_mfn(pfn) << PAGE_SHIFT) | flg; ++ } ++ } ++ } ++ } ++} ++ ++#endif /* x86_64 */ ++ ++/* ------------------------------------------------------------------ */ ++ ++static void print_start_info(char *name, struct start_info *info) ++{ ++ if (!debug_level) ++ return; ++ printk("%s start_info page @ %p\r\n", name, info); ++ printk(" magic \"%s\"\r\n", info->magic); ++ printk(" nr_pages 0x%lx\r\n", info->nr_pages); ++ printk(" shared_info 0x%lx\r\n", info->shared_info); ++ printk(" flags 0x%x\r\n", info->flags); ++ printk(" store_mfn 0x%lx\r\n", info->store_mfn); ++ printk(" store_evtchn %d\r\n", info->store_evtchn); ++ printk(" console.mfn 0x%lx\r\n", info->console.domU.mfn); ++ printk(" console.evtchn %d\r\n", info->console.domU.evtchn); ++ printk(" pt_base 0x%lx\r\n", info->pt_base); ++ printk(" nr_pt_frames 0x%lx\r\n", info->nr_pt_frames); ++ printk(" mfn_list 0x%lx\r\n", info->mfn_list); ++ printk(" mod_start 0x%lx\r\n", info->mod_start); ++ printk(" mod_len 0x%lx\r\n", info->mod_len); ++ printk(" cmd_line \"%s\"\r\n", info->cmd_line); ++ printk("\r\n"); ++} ++ ++void start_helper(void) ++{ ++ int shadow_translated; ++ unsigned long cr3_mfn; ++ ++ /* find m2p map */ ++#if defined(__i386__) ++ if (pae_paging) { ++ machine_to_phys_mapping = (xen_pfn_t*)0xf5800000; ++ } else { ++ machine_to_phys_mapping = (xen_pfn_t*)0xfc000000; ++ } ++#endif ++#if defined(__x86_64__) ++ machine_to_phys_mapping = ((xen_pfn_t*)HYPERVISOR_VIRT_START); ++#endif ++ ++ /* map magic pages */ ++ map_page(console_page, old_info->console.domU.mfn, ++ _PAGE_PRESENT | _PAGE_RW); ++ map_page(xenstore_page, old_info->store_mfn, ++ _PAGE_PRESENT | _PAGE_RW); ++ map_page(shared_info_page, old_info->shared_info >> PAGE_SHIFT, ++ _PAGE_PRESENT | _PAGE_RW); ++ ++ /* setup console, say hello world */ ++ console_evtchn = old_info->console.domU.evtchn; ++ printk("\r\nHello world from xen kexec helper\r\n\r\n"); ++ ++ /* print old start info page */ ++ print_start_info("old", old_info); ++ ++ /* figure and print some info */ ++ setup_xen_features(); ++ shadow_translated = xen_feature(XENFEAT_auto_translated_physmap); ++ dprintk("shadow_translated is %s\r\n", ++ shadow_translated ? "on" : "off"); ++#if defined(__i386__) ++ dprintk("pae paging is %s\r\n", ++ pae_paging ? "on" : "off"); ++#endif ++ dprintk("virtual base is 0x%lx\r\n", virt_base); ++ if (-1 != virt_hypercall) ++ dprintk("hypercall page at is 0x%lx\r\n", virt_hypercall); ++ dprintk("kernel entry point is 0x%lx\r\n", (unsigned long)vcpu.user_regs.eip); ++ dprintk("start_info page is 0x%lx\r\n", (unsigned long)vcpu.user_regs.esi); ++ dprintk("kernel boot stack is 0x%lx\r\n", (unsigned long)vcpu.user_regs.esp); ++ dprintk("\r\n"); ++ ++// xenstore_debug(); ++ ++ /* fixup new start info page */ ++ new_info = (struct start_info*)(vcpu.user_regs.esi - virt_base); ++ new_info->shared_info = old_info->shared_info; ++ new_info->store_mfn = old_info->store_mfn; ++ new_info->store_evtchn = old_info->store_evtchn; ++ new_info->console.domU.mfn = old_info->console.domU.mfn; ++ new_info->console.domU.evtchn = old_info->console.domU.evtchn; ++ ++ if (shadow_translated) { ++ printk("TODO: handle magic pages\r\n"); ++ cr3_mfn = (new_info->pt_base - virt_base) >> PAGE_SHIFT; ++ } else { ++ /* copy p2m table to final place */ ++ dprintk("copy p2m map\r\n"); ++ p2m_copy(); ++ ++ /* move magic pages, page order is important here: ++ * start_info, xenstore, console */ ++ dprintk("setup magic pages: xenstore and console\r\n"); ++ swap_pages_p2m(mfn_to_pfn(new_info->store_mfn), ++ ((unsigned long)new_info >> PAGE_SHIFT)+1); ++ swap_pages_p2m(mfn_to_pfn(new_info->console.domU.mfn), ++ ((unsigned long)new_info >> PAGE_SHIFT)+2); ++ ++ if (-1 != virt_hypercall) { ++ dprintk("setup hypercall page\r\n"); ++ memcpy((void*)(virt_hypercall - virt_base), ++ hypercall_page, PAGE_SIZE); ++ } ++ ++ dprintk("setup main memory\r\n"); ++ plug_holes_p2m(); ++ fillup_memory_p2m(); ++ ++ dprintk("mirror lowmem at virt_base [0x%lx]\r\n", virt_base); ++ map_virt_base(); ++ start_kernel = _start_kernel + virt_base; ++ ++ dprintk("setup new kernel's page tables\r\n"); ++ fixup_pagetables(); ++ cr3_mfn = pfn_to_mfn((new_info->pt_base - virt_base) >> PAGE_SHIFT); ++ } ++ printk("\r\n"); ++ ++ /* print new start info page */ ++ print_start_info("new", new_info); ++ ++ /* boot kernel */ ++ vcpu.ctrlreg[3] = cr3_mfn << PAGE_SHIFT; ++ printk("All done, bye folks, trying to boot the kernel ...\r\n"); ++ printk("\r\n"); ++ start_kernel(); ++} +Index: build-32-release304-12901/tools/xcutils/helper/make-offsets.c +=================================================================== +--- /dev/null ++++ build-32-release304-12901/tools/xcutils/helper/make-offsets.c +@@ -0,0 +1,28 @@ ++#include ++#include ++ ++#define vcpu_off(name,elem) printf("#define vcpu_%s 0x%lx\n", name, \ ++ (unsigned long)offsetof(struct vcpu_guest_context, elem)) ++ ++int main(int argc, char **argv) ++{ ++ vcpu_off("eax", user_regs.eax); ++ vcpu_off("ebx", user_regs.ebx); ++ vcpu_off("ecx", user_regs.ecx); ++ vcpu_off("edx", user_regs.edx); ++ vcpu_off("esi", user_regs.esi); ++ vcpu_off("edi", user_regs.edi); ++ vcpu_off("ebp", user_regs.ebp); ++ vcpu_off("esp", user_regs.esp); ++ ++ vcpu_off("cs", user_regs.cs); ++ vcpu_off("ds", user_regs.ds); ++ vcpu_off("es", user_regs.es); ++ vcpu_off("fs", user_regs.fs); ++ vcpu_off("gs", user_regs.gs); ++ vcpu_off("ss", user_regs.ss); ++ ++ vcpu_off("eip", user_regs.eip); ++ vcpu_off("cr3", ctrlreg[3]); ++ return 0; ++} +Index: build-32-release304-12901/tools/xcutils/helper/printk.c +=================================================================== +--- /dev/null ++++ build-32-release304-12901/tools/xcutils/helper/printk.c +@@ -0,0 +1,1051 @@ ++/* ++ * linux/kernel/printk.c ++ * ++ * Copyright (C) 1991, 1992 Linus Torvalds ++ * ++ * Modified to make sys_syslog() more flexible: added commands to ++ * return the last 4k of kernel messages, regardless of whether ++ * they've been read or not. Added option to suppress kernel printk's ++ * to the console. Added hook for sending the console messages ++ * elsewhere, in preparation for a serial line console (someday). ++ * Ted Ts'o, 2/11/93. ++ * Modified for sysctl support, 1/8/97, Chris Horn. ++ * Fixed SMP synchronization, 08/08/99, Manfred Spraul ++ * manfreds@colorfullife.com ++ * Rewrote bits to get rid of console_lock ++ * 01Mar01 Andrew Morton ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include /* For in_interrupt() */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) ++ ++/* printk's without a loglevel use this.. */ ++#define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */ ++ ++/* We show everything that is MORE important than this.. */ ++#define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */ ++#define DEFAULT_CONSOLE_LOGLEVEL 7 /* anything MORE serious than KERN_DEBUG */ ++ ++DECLARE_WAIT_QUEUE_HEAD(log_wait); ++ ++int console_printk[4] = { ++ DEFAULT_CONSOLE_LOGLEVEL, /* console_loglevel */ ++ DEFAULT_MESSAGE_LOGLEVEL, /* default_message_loglevel */ ++ MINIMUM_CONSOLE_LOGLEVEL, /* minimum_console_loglevel */ ++ DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */ ++}; ++ ++EXPORT_SYMBOL(console_printk); ++ ++/* ++ * Low lever drivers may need that to know if they can schedule in ++ * their unblank() callback or not. So let's export it. ++ */ ++int oops_in_progress; ++EXPORT_SYMBOL(oops_in_progress); ++ ++/* ++ * console_sem protects the console_drivers list, and also ++ * provides serialisation for access to the entire console ++ * driver system. ++ */ ++static DECLARE_MUTEX(console_sem); ++struct console *console_drivers; ++/* ++ * This is used for debugging the mess that is the VT code by ++ * keeping track if we have the console semaphore held. It's ++ * definitely not the perfect debug tool (we don't know if _WE_ ++ * hold it are racing, but it helps tracking those weird code ++ * path in the console code where we end up in places I want ++ * locked without the console sempahore held ++ */ ++static int console_locked; ++ ++/* ++ * logbuf_lock protects log_buf, log_start, log_end, con_start and logged_chars ++ * It is also used in interesting ways to provide interlocking in ++ * release_console_sem(). ++ */ ++static DEFINE_SPINLOCK(logbuf_lock); ++ ++#define LOG_BUF_MASK (log_buf_len-1) ++#define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK]) ++ ++/* ++ * The indices into log_buf are not constrained to log_buf_len - they ++ * must be masked before subscripting ++ */ ++static unsigned long log_start; /* Index into log_buf: next char to be read by syslog() */ ++static unsigned long con_start; /* Index into log_buf: next char to be sent to consoles */ ++static unsigned long log_end; /* Index into log_buf: most-recently-written-char + 1 */ ++ ++/* ++ * Array of consoles built from command line options (console=) ++ */ ++struct console_cmdline ++{ ++ char name[8]; /* Name of the driver */ ++ int index; /* Minor dev. to use */ ++ char *options; /* Options for the driver */ ++}; ++ ++#define MAX_CMDLINECONSOLES 8 ++ ++static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES]; ++static int selected_console = -1; ++static int preferred_console = -1; ++ ++/* Flag: console code may call schedule() */ ++static int console_may_schedule; ++ ++#ifdef CONFIG_PRINTK ++ ++static char __log_buf[__LOG_BUF_LEN]; ++static char *log_buf = __log_buf; ++static int log_buf_len = __LOG_BUF_LEN; ++static unsigned long logged_chars; /* Number of chars produced since last read+clear operation */ ++ ++/* ++ * Setup a list of consoles. Called from init/main.c ++ */ ++static int __init console_setup(char *str) ++{ ++ char name[sizeof(console_cmdline[0].name)]; ++ char *s, *options; ++ int idx; ++ ++ /* ++ * Decode str into name, index, options. ++ */ ++ if (str[0] >= '0' && str[0] <= '9') { ++ strcpy(name, "ttyS"); ++ strncpy(name + 4, str, sizeof(name) - 5); ++ } else ++ strncpy(name, str, sizeof(name) - 1); ++ name[sizeof(name) - 1] = 0; ++ if ((options = strchr(str, ',')) != NULL) ++ *(options++) = 0; ++#ifdef __sparc__ ++ if (!strcmp(str, "ttya")) ++ strcpy(name, "ttyS0"); ++ if (!strcmp(str, "ttyb")) ++ strcpy(name, "ttyS1"); ++#endif ++ for (s = name; *s; s++) ++ if ((*s >= '0' && *s <= '9') || *s == ',') ++ break; ++ idx = simple_strtoul(s, NULL, 10); ++ *s = 0; ++ ++ add_preferred_console(name, idx, options); ++ return 1; ++} ++ ++__setup("console=", console_setup); ++ ++static int __init log_buf_len_setup(char *str) ++{ ++ unsigned long size = memparse(str, &str); ++ unsigned long flags; ++ ++ if (size) ++ size = roundup_pow_of_two(size); ++ if (size > log_buf_len) { ++ unsigned long start, dest_idx, offset; ++ char *new_log_buf; ++ ++ new_log_buf = alloc_bootmem(size); ++ if (!new_log_buf) { ++ printk(KERN_WARNING "log_buf_len: allocation failed\n"); ++ goto out; ++ } ++ ++ spin_lock_irqsave(&logbuf_lock, flags); ++ log_buf_len = size; ++ log_buf = new_log_buf; ++ ++ offset = start = min(con_start, log_start); ++ dest_idx = 0; ++ while (start != log_end) { ++ log_buf[dest_idx] = __log_buf[start & (__LOG_BUF_LEN - 1)]; ++ start++; ++ dest_idx++; ++ } ++ log_start -= offset; ++ con_start -= offset; ++ log_end -= offset; ++ spin_unlock_irqrestore(&logbuf_lock, flags); ++ ++ printk(KERN_NOTICE "log_buf_len: %d\n", log_buf_len); ++ } ++out: ++ return 1; ++} ++ ++__setup("log_buf_len=", log_buf_len_setup); ++ ++/* ++ * Commands to do_syslog: ++ * ++ * 0 -- Close the log. Currently a NOP. ++ * 1 -- Open the log. Currently a NOP. ++ * 2 -- Read from the log. ++ * 3 -- Read all messages remaining in the ring buffer. ++ * 4 -- Read and clear all messages remaining in the ring buffer ++ * 5 -- Clear ring buffer. ++ * 6 -- Disable printk's to console ++ * 7 -- Enable printk's to console ++ * 8 -- Set level of messages printed to console ++ * 9 -- Return number of unread characters in the log buffer ++ * 10 -- Return size of the log buffer ++ */ ++int do_syslog(int type, char __user *buf, int len) ++{ ++ unsigned long i, j, limit, count; ++ int do_clear = 0; ++ char c; ++ int error = 0; ++ ++ error = security_syslog(type); ++ if (error) ++ return error; ++ ++ switch (type) { ++ case 0: /* Close log */ ++ break; ++ case 1: /* Open log */ ++ break; ++ case 2: /* Read from log */ ++ error = -EINVAL; ++ if (!buf || len < 0) ++ goto out; ++ error = 0; ++ if (!len) ++ goto out; ++ if (!access_ok(VERIFY_WRITE, buf, len)) { ++ error = -EFAULT; ++ goto out; ++ } ++ error = wait_event_interruptible(log_wait, ++ (log_start - log_end)); ++ if (error) ++ goto out; ++ i = 0; ++ spin_lock_irq(&logbuf_lock); ++ while (!error && (log_start != log_end) && i < len) { ++ c = LOG_BUF(log_start); ++ log_start++; ++ spin_unlock_irq(&logbuf_lock); ++ error = __put_user(c,buf); ++ buf++; ++ i++; ++ cond_resched(); ++ spin_lock_irq(&logbuf_lock); ++ } ++ spin_unlock_irq(&logbuf_lock); ++ if (!error) ++ error = i; ++ break; ++ case 4: /* Read/clear last kernel messages */ ++ do_clear = 1; ++ /* FALL THRU */ ++ case 3: /* Read last kernel messages */ ++ error = -EINVAL; ++ if (!buf || len < 0) ++ goto out; ++ error = 0; ++ if (!len) ++ goto out; ++ if (!access_ok(VERIFY_WRITE, buf, len)) { ++ error = -EFAULT; ++ goto out; ++ } ++ count = len; ++ if (count > log_buf_len) ++ count = log_buf_len; ++ spin_lock_irq(&logbuf_lock); ++ if (count > logged_chars) ++ count = logged_chars; ++ if (do_clear) ++ logged_chars = 0; ++ limit = log_end; ++ /* ++ * __put_user() could sleep, and while we sleep ++ * printk() could overwrite the messages ++ * we try to copy to user space. Therefore ++ * the messages are copied in reverse. ++ */ ++ for (i = 0; i < count && !error; i++) { ++ j = limit-1-i; ++ if (j + log_buf_len < log_end) ++ break; ++ c = LOG_BUF(j); ++ spin_unlock_irq(&logbuf_lock); ++ error = __put_user(c,&buf[count-1-i]); ++ cond_resched(); ++ spin_lock_irq(&logbuf_lock); ++ } ++ spin_unlock_irq(&logbuf_lock); ++ if (error) ++ break; ++ error = i; ++ if (i != count) { ++ int offset = count-error; ++ /* buffer overflow during copy, correct user buffer. */ ++ for (i = 0; i < error; i++) { ++ if (__get_user(c,&buf[i+offset]) || ++ __put_user(c,&buf[i])) { ++ error = -EFAULT; ++ break; ++ } ++ cond_resched(); ++ } ++ } ++ break; ++ case 5: /* Clear ring buffer */ ++ logged_chars = 0; ++ break; ++ case 6: /* Disable logging to console */ ++ console_loglevel = minimum_console_loglevel; ++ break; ++ case 7: /* Enable logging to console */ ++ console_loglevel = default_console_loglevel; ++ break; ++ case 8: /* Set level of messages printed to console */ ++ error = -EINVAL; ++ if (len < 1 || len > 8) ++ goto out; ++ if (len < minimum_console_loglevel) ++ len = minimum_console_loglevel; ++ console_loglevel = len; ++ error = 0; ++ break; ++ case 9: /* Number of chars in the log buffer */ ++ error = log_end - log_start; ++ break; ++ case 10: /* Size of the log buffer */ ++ error = log_buf_len; ++ break; ++ default: ++ error = -EINVAL; ++ break; ++ } ++out: ++ return error; ++} ++ ++asmlinkage long sys_syslog(int type, char __user *buf, int len) ++{ ++ return do_syslog(type, buf, len); ++} ++ ++/* ++ * Call the console drivers on a range of log_buf ++ */ ++static void __call_console_drivers(unsigned long start, unsigned long end) ++{ ++ struct console *con; ++ ++ for (con = console_drivers; con; con = con->next) { ++ if ((con->flags & CON_ENABLED) && con->write) ++ con->write(con, &LOG_BUF(start), end - start); ++ } ++} ++ ++/* ++ * Write out chars from start to end - 1 inclusive ++ */ ++static void _call_console_drivers(unsigned long start, ++ unsigned long end, int msg_log_level) ++{ ++ if (msg_log_level < console_loglevel && ++ console_drivers && start != end) { ++ if ((start & LOG_BUF_MASK) > (end & LOG_BUF_MASK)) { ++ /* wrapped write */ ++ __call_console_drivers(start & LOG_BUF_MASK, ++ log_buf_len); ++ __call_console_drivers(0, end & LOG_BUF_MASK); ++ } else { ++ __call_console_drivers(start, end); ++ } ++ } ++} ++ ++/* ++ * Call the console drivers, asking them to write out ++ * log_buf[start] to log_buf[end - 1]. ++ * The console_sem must be held. ++ */ ++static void call_console_drivers(unsigned long start, unsigned long end) ++{ ++ unsigned long cur_index, start_print; ++ static int msg_level = -1; ++ ++ if (((long)(start - end)) > 0) ++ BUG(); ++ ++ cur_index = start; ++ start_print = start; ++ while (cur_index != end) { ++ if (msg_level < 0 && ((end - cur_index) > 2) && ++ LOG_BUF(cur_index + 0) == '<' && ++ LOG_BUF(cur_index + 1) >= '0' && ++ LOG_BUF(cur_index + 1) <= '7' && ++ LOG_BUF(cur_index + 2) == '>') { ++ msg_level = LOG_BUF(cur_index + 1) - '0'; ++ cur_index += 3; ++ start_print = cur_index; ++ } ++ while (cur_index != end) { ++ char c = LOG_BUF(cur_index); ++ ++ cur_index++; ++ if (c == '\n') { ++ if (msg_level < 0) { ++ /* ++ * printk() has already given us loglevel tags in ++ * the buffer. This code is here in case the ++ * log buffer has wrapped right round and scribbled ++ * on those tags ++ */ ++ msg_level = default_message_loglevel; ++ } ++ _call_console_drivers(start_print, cur_index, msg_level); ++ msg_level = -1; ++ start_print = cur_index; ++ break; ++ } ++ } ++ } ++ _call_console_drivers(start_print, end, msg_level); ++} ++ ++static void emit_log_char(char c) ++{ ++ LOG_BUF(log_end) = c; ++ log_end++; ++ if (log_end - log_start > log_buf_len) ++ log_start = log_end - log_buf_len; ++ if (log_end - con_start > log_buf_len) ++ con_start = log_end - log_buf_len; ++ if (logged_chars < log_buf_len) ++ logged_chars++; ++} ++ ++/* ++ * Zap console related locks when oopsing. Only zap at most once ++ * every 10 seconds, to leave time for slow consoles to print a ++ * full oops. ++ */ ++static void zap_locks(void) ++{ ++ static unsigned long oops_timestamp; ++ ++ if (time_after_eq(jiffies, oops_timestamp) && ++ !time_after(jiffies, oops_timestamp + 30 * HZ)) ++ return; ++ ++ oops_timestamp = jiffies; ++ ++ /* If a crash is occurring, make sure we can't deadlock */ ++ spin_lock_init(&logbuf_lock); ++ /* And make sure that we print immediately */ ++ init_MUTEX(&console_sem); ++} ++ ++#if defined(CONFIG_PRINTK_TIME) ++static int printk_time = 1; ++#else ++static int printk_time = 0; ++#endif ++ ++static int __init printk_time_setup(char *str) ++{ ++ if (*str) ++ return 0; ++ printk_time = 1; ++ return 1; ++} ++ ++__setup("time", printk_time_setup); ++ ++__attribute__((weak)) unsigned long long printk_clock(void) ++{ ++ return sched_clock(); ++} ++ ++/** ++ * printk - print a kernel message ++ * @fmt: format string ++ * ++ * This is printk. It can be called from any context. We want it to work. ++ * ++ * We try to grab the console_sem. If we succeed, it's easy - we log the output and ++ * call the console drivers. If we fail to get the semaphore we place the output ++ * into the log buffer and return. The current holder of the console_sem will ++ * notice the new output in release_console_sem() and will send it to the ++ * consoles before releasing the semaphore. ++ * ++ * One effect of this deferred printing is that code which calls printk() and ++ * then changes console_loglevel may break. This is because console_loglevel ++ * is inspected when the actual printing occurs. ++ * ++ * See also: ++ * printf(3) ++ */ ++ ++asmlinkage int printk(const char *fmt, ...) ++{ ++ va_list args; ++ int r; ++ ++ va_start(args, fmt); ++ r = vprintk(fmt, args); ++ va_end(args); ++ ++ return r; ++} ++ ++/* cpu currently holding logbuf_lock */ ++static volatile unsigned int printk_cpu = UINT_MAX; ++ ++asmlinkage int vprintk(const char *fmt, va_list args) ++{ ++ unsigned long flags; ++ int printed_len; ++ char *p; ++ static char printk_buf[1024]; ++ static int log_level_unknown = 1; ++ ++ preempt_disable(); ++ if (unlikely(oops_in_progress) && printk_cpu == smp_processor_id()) ++ /* If a crash is occurring during printk() on this CPU, ++ * make sure we can't deadlock */ ++ zap_locks(); ++ ++ /* This stops the holder of console_sem just where we want him */ ++ spin_lock_irqsave(&logbuf_lock, flags); ++ printk_cpu = smp_processor_id(); ++ ++ /* Emit the output into the temporary buffer */ ++ printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args); ++ ++ /* ++ * Copy the output into log_buf. If the caller didn't provide ++ * appropriate log level tags, we insert them here ++ */ ++ for (p = printk_buf; *p; p++) { ++ if (log_level_unknown) { ++ /* log_level_unknown signals the start of a new line */ ++ if (printk_time) { ++ int loglev_char; ++ char tbuf[50], *tp; ++ unsigned tlen; ++ unsigned long long t; ++ unsigned long nanosec_rem; ++ ++ /* ++ * force the log level token to be ++ * before the time output. ++ */ ++ if (p[0] == '<' && p[1] >='0' && ++ p[1] <= '7' && p[2] == '>') { ++ loglev_char = p[1]; ++ p += 3; ++ printed_len += 3; ++ } else { ++ loglev_char = default_message_loglevel ++ + '0'; ++ } ++ t = printk_clock(); ++ nanosec_rem = do_div(t, 1000000000); ++ tlen = sprintf(tbuf, ++ "<%c>[%5lu.%06lu] ", ++ loglev_char, ++ (unsigned long)t, ++ nanosec_rem/1000); ++ ++ for (tp = tbuf; tp < tbuf + tlen; tp++) ++ emit_log_char(*tp); ++ printed_len += tlen - 3; ++ } else { ++ if (p[0] != '<' || p[1] < '0' || ++ p[1] > '7' || p[2] != '>') { ++ emit_log_char('<'); ++ emit_log_char(default_message_loglevel ++ + '0'); ++ emit_log_char('>'); ++ } ++ printed_len += 3; ++ } ++ log_level_unknown = 0; ++ if (!*p) ++ break; ++ } ++ emit_log_char(*p); ++ if (*p == '\n') ++ log_level_unknown = 1; ++ } ++ ++ if (!cpu_online(smp_processor_id())) { ++ /* ++ * Some console drivers may assume that per-cpu resources have ++ * been allocated. So don't allow them to be called by this ++ * CPU until it is officially up. We shouldn't be calling into ++ * random console drivers on a CPU which doesn't exist yet.. ++ */ ++ printk_cpu = UINT_MAX; ++ spin_unlock_irqrestore(&logbuf_lock, flags); ++ goto out; ++ } ++ if (!down_trylock(&console_sem)) { ++ console_locked = 1; ++ /* ++ * We own the drivers. We can drop the spinlock and let ++ * release_console_sem() print the text ++ */ ++ printk_cpu = UINT_MAX; ++ spin_unlock_irqrestore(&logbuf_lock, flags); ++ console_may_schedule = 0; ++ release_console_sem(); ++ } else { ++ /* ++ * Someone else owns the drivers. We drop the spinlock, which ++ * allows the semaphore holder to proceed and to call the ++ * console drivers with the output which we just produced. ++ */ ++ printk_cpu = UINT_MAX; ++ spin_unlock_irqrestore(&logbuf_lock, flags); ++ } ++out: ++ preempt_enable(); ++ return printed_len; ++} ++EXPORT_SYMBOL(printk); ++EXPORT_SYMBOL(vprintk); ++ ++#else ++ ++asmlinkage long sys_syslog(int type, char __user *buf, int len) ++{ ++ return 0; ++} ++ ++int do_syslog(int type, char __user *buf, int len) ++{ ++ return 0; ++} ++ ++static void call_console_drivers(unsigned long start, unsigned long end) ++{ ++} ++ ++#endif ++ ++/** ++ * add_preferred_console - add a device to the list of preferred consoles. ++ * @name: device name ++ * @idx: device index ++ * @options: options for this console ++ * ++ * The last preferred console added will be used for kernel messages ++ * and stdin/out/err for init. Normally this is used by console_setup ++ * above to handle user-supplied console arguments; however it can also ++ * be used by arch-specific code either to override the user or more ++ * commonly to provide a default console (ie from PROM variables) when ++ * the user has not supplied one. ++ */ ++int __init add_preferred_console(char *name, int idx, char *options) ++{ ++ struct console_cmdline *c; ++ int i; ++ ++ /* ++ * See if this tty is not yet registered, and ++ * if we have a slot free. ++ */ ++ for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++) ++ if (strcmp(console_cmdline[i].name, name) == 0 && ++ console_cmdline[i].index == idx) { ++ selected_console = i; ++ return 0; ++ } ++ if (i == MAX_CMDLINECONSOLES) ++ return -E2BIG; ++ selected_console = i; ++ c = &console_cmdline[i]; ++ memcpy(c->name, name, sizeof(c->name)); ++ c->name[sizeof(c->name) - 1] = 0; ++ c->options = options; ++ c->index = idx; ++ return 0; ++} ++ ++/** ++ * acquire_console_sem - lock the console system for exclusive use. ++ * ++ * Acquires a semaphore which guarantees that the caller has ++ * exclusive access to the console system and the console_drivers list. ++ * ++ * Can sleep, returns nothing. ++ */ ++void acquire_console_sem(void) ++{ ++ if (in_interrupt()) ++ BUG(); ++ down(&console_sem); ++ console_locked = 1; ++ console_may_schedule = 1; ++} ++EXPORT_SYMBOL(acquire_console_sem); ++ ++int try_acquire_console_sem(void) ++{ ++ if (down_trylock(&console_sem)) ++ return -1; ++ console_locked = 1; ++ console_may_schedule = 0; ++ return 0; ++} ++EXPORT_SYMBOL(try_acquire_console_sem); ++ ++int is_console_locked(void) ++{ ++ return console_locked; ++} ++EXPORT_SYMBOL(is_console_locked); ++ ++/** ++ * release_console_sem - unlock the console system ++ * ++ * Releases the semaphore which the caller holds on the console system ++ * and the console driver list. ++ * ++ * While the semaphore was held, console output may have been buffered ++ * by printk(). If this is the case, release_console_sem() emits ++ * the output prior to releasing the semaphore. ++ * ++ * If there is output waiting for klogd, we wake it up. ++ * ++ * release_console_sem() may be called from any context. ++ */ ++void release_console_sem(void) ++{ ++ unsigned long flags; ++ unsigned long _con_start, _log_end; ++ unsigned long wake_klogd = 0; ++ ++ for ( ; ; ) { ++ spin_lock_irqsave(&logbuf_lock, flags); ++ wake_klogd |= log_start - log_end; ++ if (con_start == log_end) ++ break; /* Nothing to print */ ++ _con_start = con_start; ++ _log_end = log_end; ++ con_start = log_end; /* Flush */ ++ spin_unlock(&logbuf_lock); ++ call_console_drivers(_con_start, _log_end); ++ local_irq_restore(flags); ++ } ++ console_locked = 0; ++ console_may_schedule = 0; ++ up(&console_sem); ++ spin_unlock_irqrestore(&logbuf_lock, flags); ++ if (wake_klogd && !oops_in_progress && waitqueue_active(&log_wait)) ++ wake_up_interruptible(&log_wait); ++} ++EXPORT_SYMBOL(release_console_sem); ++ ++/** ++ * console_conditional_schedule - yield the CPU if required ++ * ++ * If the console code is currently allowed to sleep, and ++ * if this CPU should yield the CPU to another task, do ++ * so here. ++ * ++ * Must be called within acquire_console_sem(). ++ */ ++void __sched console_conditional_schedule(void) ++{ ++ if (console_may_schedule) ++ cond_resched(); ++} ++EXPORT_SYMBOL(console_conditional_schedule); ++ ++void console_print(const char *s) ++{ ++ printk(KERN_EMERG "%s", s); ++} ++EXPORT_SYMBOL(console_print); ++ ++void console_unblank(void) ++{ ++ struct console *c; ++ ++ /* ++ * console_unblank can no longer be called in interrupt context unless ++ * oops_in_progress is set to 1.. ++ */ ++ if (oops_in_progress) { ++ if (down_trylock(&console_sem) != 0) ++ return; ++ } else ++ acquire_console_sem(); ++ ++ console_locked = 1; ++ console_may_schedule = 0; ++ for (c = console_drivers; c != NULL; c = c->next) ++ if ((c->flags & CON_ENABLED) && c->unblank) ++ c->unblank(); ++ release_console_sem(); ++} ++ ++/* ++ * Return the console tty driver structure and its associated index ++ */ ++struct tty_driver *console_device(int *index) ++{ ++ struct console *c; ++ struct tty_driver *driver = NULL; ++ ++ acquire_console_sem(); ++ for (c = console_drivers; c != NULL; c = c->next) { ++ if (!c->device) ++ continue; ++ driver = c->device(c, index); ++ if (driver) ++ break; ++ } ++ release_console_sem(); ++ return driver; ++} ++ ++/* ++ * Prevent further output on the passed console device so that (for example) ++ * serial drivers can disable console output before suspending a port, and can ++ * re-enable output afterwards. ++ */ ++void console_stop(struct console *console) ++{ ++ acquire_console_sem(); ++ console->flags &= ~CON_ENABLED; ++ release_console_sem(); ++} ++EXPORT_SYMBOL(console_stop); ++ ++void console_start(struct console *console) ++{ ++ acquire_console_sem(); ++ console->flags |= CON_ENABLED; ++ release_console_sem(); ++} ++EXPORT_SYMBOL(console_start); ++ ++/* ++ * The console driver calls this routine during kernel initialization ++ * to register the console printing procedure with printk() and to ++ * print any messages that were printed by the kernel before the ++ * console driver was initialized. ++ */ ++void register_console(struct console *console) ++{ ++ int i; ++ unsigned long flags; ++ ++ if (preferred_console < 0) ++ preferred_console = selected_console; ++ ++ /* ++ * See if we want to use this console driver. If we ++ * didn't select a console we take the first one ++ * that registers here. ++ */ ++ if (preferred_console < 0) { ++ if (console->index < 0) ++ console->index = 0; ++ if (console->setup == NULL || ++ console->setup(console, NULL) == 0) { ++ console->flags |= CON_ENABLED | CON_CONSDEV; ++ preferred_console = 0; ++ } ++ } ++ ++ /* ++ * See if this console matches one we selected on ++ * the command line. ++ */ ++ for (i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; ++ i++) { ++ if (strcmp(console_cmdline[i].name, console->name) != 0) ++ continue; ++ if (console->index >= 0 && ++ console->index != console_cmdline[i].index) ++ continue; ++ if (console->index < 0) ++ console->index = console_cmdline[i].index; ++ if (console->setup && ++ console->setup(console, console_cmdline[i].options) != 0) ++ break; ++ console->flags |= CON_ENABLED; ++ console->index = console_cmdline[i].index; ++ if (i == selected_console) { ++ console->flags |= CON_CONSDEV; ++ preferred_console = selected_console; ++ } ++ break; ++ } ++ ++ if (!(console->flags & CON_ENABLED)) ++ return; ++ ++ if (console_drivers && (console_drivers->flags & CON_BOOT)) { ++ unregister_console(console_drivers); ++ console->flags &= ~CON_PRINTBUFFER; ++ } ++ ++ /* ++ * Put this console in the list - keep the ++ * preferred driver at the head of the list. ++ */ ++ acquire_console_sem(); ++ if ((console->flags & CON_CONSDEV) || console_drivers == NULL) { ++ console->next = console_drivers; ++ console_drivers = console; ++ if (console->next) ++ console->next->flags &= ~CON_CONSDEV; ++ } else { ++ console->next = console_drivers->next; ++ console_drivers->next = console; ++ } ++ if (console->flags & CON_PRINTBUFFER) { ++ /* ++ * release_console_sem() will print out the buffered messages ++ * for us. ++ */ ++ spin_lock_irqsave(&logbuf_lock, flags); ++ con_start = log_start; ++ spin_unlock_irqrestore(&logbuf_lock, flags); ++ } ++ release_console_sem(); ++} ++EXPORT_SYMBOL(register_console); ++ ++int unregister_console(struct console *console) ++{ ++ struct console *a, *b; ++ int res = 1; ++ ++ acquire_console_sem(); ++ if (console_drivers == console) { ++ console_drivers=console->next; ++ res = 0; ++ } else if (console_drivers) { ++ for (a=console_drivers->next, b=console_drivers ; ++ a; b=a, a=b->next) { ++ if (a == console) { ++ b->next = a->next; ++ res = 0; ++ break; ++ } ++ } ++ } ++ ++ /* If last console is removed, we re-enable picking the first ++ * one that gets registered. Without that, pmac early boot console ++ * would prevent fbcon from taking over. ++ * ++ * If this isn't the last console and it has CON_CONSDEV set, we ++ * need to set it on the next preferred console. ++ */ ++ if (console_drivers == NULL) ++ preferred_console = selected_console; ++ else if (console->flags & CON_CONSDEV) ++ console_drivers->flags |= CON_CONSDEV; ++ ++ release_console_sem(); ++ return res; ++} ++EXPORT_SYMBOL(unregister_console); ++ ++/** ++ * tty_write_message - write a message to a certain tty, not just the console. ++ * @tty: the destination tty_struct ++ * @msg: the message to write ++ * ++ * This is used for messages that need to be redirected to a specific tty. ++ * We don't put it into the syslog queue right now maybe in the future if ++ * really needed. ++ */ ++void tty_write_message(struct tty_struct *tty, char *msg) ++{ ++ if (tty && tty->driver->write) ++ tty->driver->write(tty, msg, strlen(msg)); ++ return; ++} ++ ++/* ++ * printk rate limiting, lifted from the networking subsystem. ++ * ++ * This enforces a rate limit: not more than one kernel message ++ * every printk_ratelimit_jiffies to make a denial-of-service ++ * attack impossible. ++ */ ++int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst) ++{ ++ static DEFINE_SPINLOCK(ratelimit_lock); ++ static unsigned long toks = 10 * 5 * HZ; ++ static unsigned long last_msg; ++ static int missed; ++ unsigned long flags; ++ unsigned long now = jiffies; ++ ++ spin_lock_irqsave(&ratelimit_lock, flags); ++ toks += now - last_msg; ++ last_msg = now; ++ if (toks > (ratelimit_burst * ratelimit_jiffies)) ++ toks = ratelimit_burst * ratelimit_jiffies; ++ if (toks >= ratelimit_jiffies) { ++ int lost = missed; ++ ++ missed = 0; ++ toks -= ratelimit_jiffies; ++ spin_unlock_irqrestore(&ratelimit_lock, flags); ++ if (lost) ++ printk(KERN_WARNING "printk: %d messages suppressed.\n", lost); ++ return 1; ++ } ++ missed++; ++ spin_unlock_irqrestore(&ratelimit_lock, flags); ++ return 0; ++} ++EXPORT_SYMBOL(__printk_ratelimit); ++ ++/* minimum time in jiffies between messages */ ++int printk_ratelimit_jiffies = 5 * HZ; ++ ++/* number of messages we send before ratelimiting */ ++int printk_ratelimit_burst = 10; ++ ++int printk_ratelimit(void) ++{ ++ return __printk_ratelimit(printk_ratelimit_jiffies, ++ printk_ratelimit_burst); ++} ++EXPORT_SYMBOL(printk_ratelimit); +Index: build-32-release304-12901/tools/xcutils/helper/string.c +=================================================================== +--- /dev/null ++++ build-32-release304-12901/tools/xcutils/helper/string.c +@@ -0,0 +1,601 @@ ++/* ++ * linux/lib/string.c ++ * ++ * Copyright (C) 1991, 1992 Linus Torvalds ++ */ ++ ++/* ++ * stupid library routines.. The optimized versions should generally be found ++ * as inline code in ++ * ++ * These are buggy as well.. ++ * ++ * * Fri Jun 25 1999, Ingo Oeser ++ * - Added strsep() which will replace strtok() soon (because strsep() is ++ * reentrant and should be faster). Use only strsep() in new code, please. ++ * ++ * * Sat Feb 09 2002, Jason Thomas , ++ * Matthew Hawkins ++ * - Kissed strtok() goodbye ++ */ ++ ++#include "helper.h" ++ ++#ifndef __HAVE_ARCH_STRNICMP ++/** ++ * strnicmp - Case insensitive, length-limited string comparison ++ * @s1: One string ++ * @s2: The other string ++ * @len: the maximum number of characters to compare ++ */ ++int strnicmp(const char *s1, const char *s2, size_t len) ++{ ++ /* Yes, Virginia, it had better be unsigned */ ++ unsigned char c1, c2; ++ ++ c1 = c2 = 0; ++ if (len) { ++ do { ++ c1 = *s1; ++ c2 = *s2; ++ s1++; ++ s2++; ++ if (!c1) ++ break; ++ if (!c2) ++ break; ++ if (c1 == c2) ++ continue; ++ c1 = tolower(c1); ++ c2 = tolower(c2); ++ if (c1 != c2) ++ break; ++ } while (--len); ++ } ++ return (int)c1 - (int)c2; ++} ++EXPORT_SYMBOL(strnicmp); ++#endif ++ ++#ifndef __HAVE_ARCH_STRCPY ++/** ++ * strcpy - Copy a %NUL terminated string ++ * @dest: Where to copy the string to ++ * @src: Where to copy the string from ++ */ ++#undef strcpy ++char *strcpy(char *dest, const char *src) ++{ ++ char *tmp = dest; ++ ++ while ((*dest++ = *src++) != '\0') ++ /* nothing */; ++ return tmp; ++} ++EXPORT_SYMBOL(strcpy); ++#endif ++ ++#ifndef __HAVE_ARCH_STRNCPY ++/** ++ * strncpy - Copy a length-limited, %NUL-terminated string ++ * @dest: Where to copy the string to ++ * @src: Where to copy the string from ++ * @count: The maximum number of bytes to copy ++ * ++ * The result is not %NUL-terminated if the source exceeds ++ * @count bytes. ++ * ++ * In the case where the length of @src is less than that of ++ * count, the remainder of @dest will be padded with %NUL. ++ * ++ */ ++char *strncpy(char *dest, const char *src, size_t count) ++{ ++ char *tmp = dest; ++ ++ while (count) { ++ if ((*tmp = *src) != 0) ++ src++; ++ tmp++; ++ count--; ++ } ++ return dest; ++} ++EXPORT_SYMBOL(strncpy); ++#endif ++ ++#ifndef __HAVE_ARCH_STRLCPY ++/** ++ * strlcpy - Copy a %NUL terminated string into a sized buffer ++ * @dest: Where to copy the string to ++ * @src: Where to copy the string from ++ * @size: size of destination buffer ++ * ++ * Compatible with *BSD: the result is always a valid ++ * NUL-terminated string that fits in the buffer (unless, ++ * of course, the buffer size is zero). It does not pad ++ * out the result like strncpy() does. ++ */ ++size_t strlcpy(char *dest, const char *src, size_t size) ++{ ++ size_t ret = strlen(src); ++ ++ if (size) { ++ size_t len = (ret >= size) ? size - 1 : ret; ++ memcpy(dest, src, len); ++ dest[len] = '\0'; ++ } ++ return ret; ++} ++EXPORT_SYMBOL(strlcpy); ++#endif ++ ++#ifndef __HAVE_ARCH_STRCAT ++/** ++ * strcat - Append one %NUL-terminated string to another ++ * @dest: The string to be appended to ++ * @src: The string to append to it ++ */ ++#undef strcat ++char *strcat(char *dest, const char *src) ++{ ++ char *tmp = dest; ++ ++ while (*dest) ++ dest++; ++ while ((*dest++ = *src++) != '\0') ++ ; ++ return tmp; ++} ++EXPORT_SYMBOL(strcat); ++#endif ++ ++#ifndef __HAVE_ARCH_STRNCAT ++/** ++ * strncat - Append a length-limited, %NUL-terminated string to another ++ * @dest: The string to be appended to ++ * @src: The string to append to it ++ * @count: The maximum numbers of bytes to copy ++ * ++ * Note that in contrast to strncpy, strncat ensures the result is ++ * terminated. ++ */ ++char *strncat(char *dest, const char *src, size_t count) ++{ ++ char *tmp = dest; ++ ++ if (count) { ++ while (*dest) ++ dest++; ++ while ((*dest++ = *src++) != 0) { ++ if (--count == 0) { ++ *dest = '\0'; ++ break; ++ } ++ } ++ } ++ return tmp; ++} ++EXPORT_SYMBOL(strncat); ++#endif ++ ++#ifndef __HAVE_ARCH_STRLCAT ++/** ++ * strlcat - Append a length-limited, %NUL-terminated string to another ++ * @dest: The string to be appended to ++ * @src: The string to append to it ++ * @count: The size of the destination buffer. ++ */ ++size_t strlcat(char *dest, const char *src, size_t count) ++{ ++ size_t dsize = strlen(dest); ++ size_t len = strlen(src); ++ size_t res = dsize + len; ++ ++ /* This would be a bug */ ++ BUG_ON(dsize >= count); ++ ++ dest += dsize; ++ count -= dsize; ++ if (len >= count) ++ len = count-1; ++ memcpy(dest, src, len); ++ dest[len] = 0; ++ return res; ++} ++EXPORT_SYMBOL(strlcat); ++#endif ++ ++#ifndef __HAVE_ARCH_STRCMP ++/** ++ * strcmp - Compare two strings ++ * @cs: One string ++ * @ct: Another string ++ */ ++#undef strcmp ++int strcmp(const char *cs, const char *ct) ++{ ++ signed char __res; ++ ++ while (1) { ++ if ((__res = *cs - *ct++) != 0 || !*cs++) ++ break; ++ } ++ return __res; ++} ++EXPORT_SYMBOL(strcmp); ++#endif ++ ++#ifndef __HAVE_ARCH_STRNCMP ++/** ++ * strncmp - Compare two length-limited strings ++ * @cs: One string ++ * @ct: Another string ++ * @count: The maximum number of bytes to compare ++ */ ++int strncmp(const char *cs, const char *ct, size_t count) ++{ ++ signed char __res = 0; ++ ++ while (count) { ++ if ((__res = *cs - *ct++) != 0 || !*cs++) ++ break; ++ count--; ++ } ++ return __res; ++} ++EXPORT_SYMBOL(strncmp); ++#endif ++ ++#ifndef __HAVE_ARCH_STRCHR ++/** ++ * strchr - Find the first occurrence of a character in a string ++ * @s: The string to be searched ++ * @c: The character to search for ++ */ ++char *strchr(const char *s, int c) ++{ ++ for (; *s != (char)c; ++s) ++ if (*s == '\0') ++ return NULL; ++ return (char *)s; ++} ++EXPORT_SYMBOL(strchr); ++#endif ++ ++#ifndef __HAVE_ARCH_STRRCHR ++/** ++ * strrchr - Find the last occurrence of a character in a string ++ * @s: The string to be searched ++ * @c: The character to search for ++ */ ++char *strrchr(const char *s, int c) ++{ ++ const char *p = s + strlen(s); ++ do { ++ if (*p == (char)c) ++ return (char *)p; ++ } while (--p >= s); ++ return NULL; ++} ++EXPORT_SYMBOL(strrchr); ++#endif ++ ++#ifndef __HAVE_ARCH_STRNCHR ++/** ++ * strnchr - Find a character in a length limited string ++ * @s: The string to be searched ++ * @count: The number of characters to be searched ++ * @c: The character to search for ++ */ ++char *strnchr(const char *s, size_t count, int c) ++{ ++ for (; count-- && *s != '\0'; ++s) ++ if (*s == (char)c) ++ return (char *)s; ++ return NULL; ++} ++EXPORT_SYMBOL(strnchr); ++#endif ++ ++#ifndef __HAVE_ARCH_STRLEN ++/** ++ * strlen - Find the length of a string ++ * @s: The string to be sized ++ */ ++size_t strlen(const char *s) ++{ ++ const char *sc; ++ ++ for (sc = s; *sc != '\0'; ++sc) ++ /* nothing */; ++ return sc - s; ++} ++EXPORT_SYMBOL(strlen); ++#endif ++ ++#ifndef __HAVE_ARCH_STRNLEN ++/** ++ * strnlen - Find the length of a length-limited string ++ * @s: The string to be sized ++ * @count: The maximum number of bytes to search ++ */ ++size_t strnlen(const char *s, size_t count) ++{ ++ const char *sc; ++ ++ for (sc = s; count-- && *sc != '\0'; ++sc) ++ /* nothing */; ++ return sc - s; ++} ++EXPORT_SYMBOL(strnlen); ++#endif ++ ++#ifndef __HAVE_ARCH_STRSPN ++/** ++ * strspn - Calculate the length of the initial substring of @s which only ++ * contain letters in @accept ++ * @s: The string to be searched ++ * @accept: The string to search for ++ */ ++size_t strspn(const char *s, const char *accept) ++{ ++ const char *p; ++ const char *a; ++ size_t count = 0; ++ ++ for (p = s; *p != '\0'; ++p) { ++ for (a = accept; *a != '\0'; ++a) { ++ if (*p == *a) ++ break; ++ } ++ if (*a == '\0') ++ return count; ++ ++count; ++ } ++ return count; ++} ++ ++EXPORT_SYMBOL(strspn); ++#endif ++ ++/** ++ * strcspn - Calculate the length of the initial substring of @s which does ++ * not contain letters in @reject ++ * @s: The string to be searched ++ * @reject: The string to avoid ++ */ ++size_t strcspn(const char *s, const char *reject) ++{ ++ const char *p; ++ const char *r; ++ size_t count = 0; ++ ++ for (p = s; *p != '\0'; ++p) { ++ for (r = reject; *r != '\0'; ++r) { ++ if (*p == *r) ++ return count; ++ } ++ ++count; ++ } ++ return count; ++} ++EXPORT_SYMBOL(strcspn); ++ ++#ifndef __HAVE_ARCH_STRPBRK ++/** ++ * strpbrk - Find the first occurrence of a set of characters ++ * @cs: The string to be searched ++ * @ct: The characters to search for ++ */ ++char *strpbrk(const char *cs, const char *ct) ++{ ++ const char *sc1, *sc2; ++ ++ for (sc1 = cs; *sc1 != '\0'; ++sc1) { ++ for (sc2 = ct; *sc2 != '\0'; ++sc2) { ++ if (*sc1 == *sc2) ++ return (char *)sc1; ++ } ++ } ++ return NULL; ++} ++EXPORT_SYMBOL(strpbrk); ++#endif ++ ++#ifndef __HAVE_ARCH_STRSEP ++/** ++ * strsep - Split a string into tokens ++ * @s: The string to be searched ++ * @ct: The characters to search for ++ * ++ * strsep() updates @s to point after the token, ready for the next call. ++ * ++ * It returns empty tokens, too, behaving exactly like the libc function ++ * of that name. In fact, it was stolen from glibc2 and de-fancy-fied. ++ * Same semantics, slimmer shape. ;) ++ */ ++char *strsep(char **s, const char *ct) ++{ ++ char *sbegin = *s; ++ char *end; ++ ++ if (sbegin == NULL) ++ return NULL; ++ ++ end = strpbrk(sbegin, ct); ++ if (end) ++ *end++ = '\0'; ++ *s = end; ++ return sbegin; ++} ++EXPORT_SYMBOL(strsep); ++#endif ++ ++#ifndef __HAVE_ARCH_MEMSET ++/** ++ * memset - Fill a region of memory with the given value ++ * @s: Pointer to the start of the area. ++ * @c: The byte to fill the area with ++ * @count: The size of the area. ++ * ++ * Do not use memset() to access IO space, use memset_io() instead. ++ */ ++void *memset(void *s, int c, size_t count) ++{ ++ char *xs = s; ++ ++ while (count--) ++ *xs++ = c; ++ return s; ++} ++EXPORT_SYMBOL(memset); ++#endif ++ ++#ifndef __HAVE_ARCH_MEMCPY ++/** ++ * memcpy - Copy one area of memory to another ++ * @dest: Where to copy to ++ * @src: Where to copy from ++ * @count: The size of the area. ++ * ++ * You should not use this function to access IO space, use memcpy_toio() ++ * or memcpy_fromio() instead. ++ */ ++void *memcpy(void *dest, const void *src, size_t count) ++{ ++ char *tmp = dest; ++ const char *s = src; ++ ++ while (count--) ++ *tmp++ = *s++; ++ return dest; ++} ++EXPORT_SYMBOL(memcpy); ++#endif ++ ++#ifndef __HAVE_ARCH_MEMMOVE ++/** ++ * memmove - Copy one area of memory to another ++ * @dest: Where to copy to ++ * @src: Where to copy from ++ * @count: The size of the area. ++ * ++ * Unlike memcpy(), memmove() copes with overlapping areas. ++ */ ++void *memmove(void *dest, const void *src, size_t count) ++{ ++ char *tmp; ++ const char *s; ++ ++ if (dest <= src) { ++ tmp = dest; ++ s = src; ++ while (count--) ++ *tmp++ = *s++; ++ } else { ++ tmp = dest; ++ tmp += count; ++ s = src; ++ s += count; ++ while (count--) ++ *--tmp = *--s; ++ } ++ return dest; ++} ++EXPORT_SYMBOL(memmove); ++#endif ++ ++#ifndef __HAVE_ARCH_MEMCMP ++/** ++ * memcmp - Compare two areas of memory ++ * @cs: One area of memory ++ * @ct: Another area of memory ++ * @count: The size of the area. ++ */ ++#undef memcmp ++int memcmp(const void *cs, const void *ct, size_t count) ++{ ++ const unsigned char *su1, *su2; ++ int res = 0; ++ ++ for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) ++ if ((res = *su1 - *su2) != 0) ++ break; ++ return res; ++} ++EXPORT_SYMBOL(memcmp); ++#endif ++ ++#ifndef __HAVE_ARCH_MEMSCAN ++/** ++ * memscan - Find a character in an area of memory. ++ * @addr: The memory area ++ * @c: The byte to search for ++ * @size: The size of the area. ++ * ++ * returns the address of the first occurrence of @c, or 1 byte past ++ * the area if @c is not found ++ */ ++void *memscan(void *addr, int c, size_t size) ++{ ++ unsigned char *p = addr; ++ ++ while (size) { ++ if (*p == c) ++ return (void *)p; ++ p++; ++ size--; ++ } ++ return (void *)p; ++} ++EXPORT_SYMBOL(memscan); ++#endif ++ ++#ifndef __HAVE_ARCH_STRSTR ++/** ++ * strstr - Find the first substring in a %NUL terminated string ++ * @s1: The string to be searched ++ * @s2: The string to search for ++ */ ++char *strstr(const char *s1, const char *s2) ++{ ++ int l1, l2; ++ ++ l2 = strlen(s2); ++ if (!l2) ++ return (char *)s1; ++ l1 = strlen(s1); ++ while (l1 >= l2) { ++ l1--; ++ if (!memcmp(s1, s2, l2)) ++ return (char *)s1; ++ s1++; ++ } ++ return NULL; ++} ++EXPORT_SYMBOL(strstr); ++#endif ++ ++#ifndef __HAVE_ARCH_MEMCHR ++/** ++ * memchr - Find a character in an area of memory. ++ * @s: The memory area ++ * @c: The byte to search for ++ * @n: The size of the area. ++ * ++ * returns the address of the first occurrence of @c, or %NULL ++ * if @c is not found ++ */ ++void *memchr(const void *s, int c, size_t n) ++{ ++ const unsigned char *p = s; ++ while (n-- != 0) { ++ if ((unsigned char)c == *p++) { ++ return (void *)(p - 1); ++ } ++ } ++ return NULL; ++} ++EXPORT_SYMBOL(memchr); ++#endif +Index: build-32-release304-12901/tools/xcutils/helper/vsprintf.c +=================================================================== +--- /dev/null ++++ build-32-release304-12901/tools/xcutils/helper/vsprintf.c +@@ -0,0 +1,842 @@ ++/* ++ * linux/lib/vsprintf.c ++ * ++ * Copyright (C) 1991, 1992 Linus Torvalds ++ */ ++ ++/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ ++/* ++ * Wirzenius wrote this portably, Torvalds fucked it up :-) ++ */ ++ ++/* ++ * Fri Jul 13 2001 Crutcher Dunnavant ++ * - changed to provide snprintf and vsnprintf functions ++ * So Feb 1 16:51:32 CET 2004 Juergen Quade ++ * - scnprintf and vscnprintf ++ */ ++ ++#include "helper.h" ++ ++/** ++ * simple_strtoul - convert a string to an unsigned long ++ * @cp: The start of the string ++ * @endp: A pointer to the end of the parsed string will be placed here ++ * @base: The number base to use ++ */ ++unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base) ++{ ++ unsigned long result = 0,value; ++ ++ if (!base) { ++ base = 10; ++ if (*cp == '0') { ++ base = 8; ++ cp++; ++ if ((toupper(*cp) == 'X') && isxdigit(cp[1])) { ++ cp++; ++ base = 16; ++ } ++ } ++ } else if (base == 16) { ++ if (cp[0] == '0' && toupper(cp[1]) == 'X') ++ cp += 2; ++ } ++ while (isxdigit(*cp) && ++ (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) { ++ result = result*base + value; ++ cp++; ++ } ++ if (endp) ++ *endp = (char *)cp; ++ return result; ++} ++ ++EXPORT_SYMBOL(simple_strtoul); ++ ++/** ++ * simple_strtol - convert a string to a signed long ++ * @cp: The start of the string ++ * @endp: A pointer to the end of the parsed string will be placed here ++ * @base: The number base to use ++ */ ++long simple_strtol(const char *cp,char **endp,unsigned int base) ++{ ++ if(*cp=='-') ++ return -simple_strtoul(cp+1,endp,base); ++ return simple_strtoul(cp,endp,base); ++} ++ ++EXPORT_SYMBOL(simple_strtol); ++ ++/** ++ * simple_strtoull - convert a string to an unsigned long long ++ * @cp: The start of the string ++ * @endp: A pointer to the end of the parsed string will be placed here ++ * @base: The number base to use ++ */ ++unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base) ++{ ++ unsigned long long result = 0,value; ++ ++ if (!base) { ++ base = 10; ++ if (*cp == '0') { ++ base = 8; ++ cp++; ++ if ((toupper(*cp) == 'X') && isxdigit(cp[1])) { ++ cp++; ++ base = 16; ++ } ++ } ++ } else if (base == 16) { ++ if (cp[0] == '0' && toupper(cp[1]) == 'X') ++ cp += 2; ++ } ++ while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp) ++ ? toupper(*cp) : *cp)-'A'+10) < base) { ++ result = result*base + value; ++ cp++; ++ } ++ if (endp) ++ *endp = (char *)cp; ++ return result; ++} ++ ++EXPORT_SYMBOL(simple_strtoull); ++ ++/** ++ * simple_strtoll - convert a string to a signed long long ++ * @cp: The start of the string ++ * @endp: A pointer to the end of the parsed string will be placed here ++ * @base: The number base to use ++ */ ++long long simple_strtoll(const char *cp,char **endp,unsigned int base) ++{ ++ if(*cp=='-') ++ return -simple_strtoull(cp+1,endp,base); ++ return simple_strtoull(cp,endp,base); ++} ++ ++static int skip_atoi(const char **s) ++{ ++ int i=0; ++ ++ while (isdigit(**s)) ++ i = i*10 + *((*s)++) - '0'; ++ return i; ++} ++ ++#define ZEROPAD 1 /* pad with zero */ ++#define SIGN 2 /* unsigned/signed long */ ++#define PLUS 4 /* show plus */ ++#define SPACE 8 /* space if plus */ ++#define LEFT 16 /* left justified */ ++#define SPECIAL 32 /* 0x */ ++#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ ++ ++static char * number(char * buf, char * end, unsigned long long num, int base, int size, int precision, int type) ++{ ++ char c,sign,tmp[66]; ++ const char *digits; ++ static const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; ++ static const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; ++ int i; ++ ++ digits = (type & LARGE) ? large_digits : small_digits; ++ if (type & LEFT) ++ type &= ~ZEROPAD; ++ if (base < 2 || base > 36) ++ return NULL; ++ c = (type & ZEROPAD) ? '0' : ' '; ++ sign = 0; ++ if (type & SIGN) { ++ if ((signed long long) num < 0) { ++ sign = '-'; ++ num = - (signed long long) num; ++ size--; ++ } else if (type & PLUS) { ++ sign = '+'; ++ size--; ++ } else if (type & SPACE) { ++ sign = ' '; ++ size--; ++ } ++ } ++ if (type & SPECIAL) { ++ if (base == 16) ++ size -= 2; ++ else if (base == 8) ++ size--; ++ } ++ i = 0; ++ if (num == 0) ++ tmp[i++]='0'; ++ else while (num != 0) ++ tmp[i++] = digits[do_div(num,base)]; ++ if (i > precision) ++ precision = i; ++ size -= precision; ++ if (!(type&(ZEROPAD+LEFT))) { ++ while(size-->0) { ++ if (buf <= end) ++ *buf = ' '; ++ ++buf; ++ } ++ } ++ if (sign) { ++ if (buf <= end) ++ *buf = sign; ++ ++buf; ++ } ++ if (type & SPECIAL) { ++ if (base==8) { ++ if (buf <= end) ++ *buf = '0'; ++ ++buf; ++ } else if (base==16) { ++ if (buf <= end) ++ *buf = '0'; ++ ++buf; ++ if (buf <= end) ++ *buf = digits[33]; ++ ++buf; ++ } ++ } ++ if (!(type & LEFT)) { ++ while (size-- > 0) { ++ if (buf <= end) ++ *buf = c; ++ ++buf; ++ } ++ } ++ while (i < precision--) { ++ if (buf <= end) ++ *buf = '0'; ++ ++buf; ++ } ++ while (i-- > 0) { ++ if (buf <= end) ++ *buf = tmp[i]; ++ ++buf; ++ } ++ while (size-- > 0) { ++ if (buf <= end) ++ *buf = ' '; ++ ++buf; ++ } ++ return buf; ++} ++ ++/** ++ * vsnprintf - Format a string and place it in a buffer ++ * @buf: The buffer to place the result into ++ * @size: The size of the buffer, including the trailing null space ++ * @fmt: The format string to use ++ * @args: Arguments for the format string ++ * ++ * The return value is the number of characters which would ++ * be generated for the given input, excluding the trailing ++ * '\0', as per ISO C99. If you want to have the exact ++ * number of characters written into @buf as return value ++ * (not including the trailing '\0'), use vscnprintf. If the ++ * return is greater than or equal to @size, the resulting ++ * string is truncated. ++ * ++ * Call this function if you are already dealing with a va_list. ++ * You probably want snprintf instead. ++ */ ++int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) ++{ ++ int len; ++ unsigned long long num; ++ int i, base; ++ char *str, *end, c; ++ const char *s; ++ ++ int flags; /* flags to number() */ ++ ++ int field_width; /* width of output field */ ++ int precision; /* min. # of digits for integers; max ++ number of chars for from string */ ++ int qualifier; /* 'h', 'l', or 'L' for integer fields */ ++ /* 'z' support added 23/7/1999 S.H. */ ++ /* 'z' changed to 'Z' --davidm 1/25/99 */ ++ /* 't' added for ptrdiff_t */ ++ ++ /* Reject out-of-range values early */ ++ if (unlikely((int) size < 0)) { ++ /* There can be only one.. */ ++ static int warn = 1; ++ WARN_ON(warn); ++ warn = 0; ++ return 0; ++ } ++ ++ str = buf; ++ end = buf + size - 1; ++ ++ if (end < buf - 1) { ++ end = ((void *) -1); ++ size = end - buf + 1; ++ } ++ ++ for (; *fmt ; ++fmt) { ++ if (*fmt != '%') { ++ if (str <= end) ++ *str = *fmt; ++ ++str; ++ continue; ++ } ++ ++ /* process flags */ ++ flags = 0; ++ repeat: ++ ++fmt; /* this also skips first '%' */ ++ switch (*fmt) { ++ case '-': flags |= LEFT; goto repeat; ++ case '+': flags |= PLUS; goto repeat; ++ case ' ': flags |= SPACE; goto repeat; ++ case '#': flags |= SPECIAL; goto repeat; ++ case '0': flags |= ZEROPAD; goto repeat; ++ } ++ ++ /* get field width */ ++ field_width = -1; ++ if (isdigit(*fmt)) ++ field_width = skip_atoi(&fmt); ++ else if (*fmt == '*') { ++ ++fmt; ++ /* it's the next argument */ ++ field_width = va_arg(args, int); ++ if (field_width < 0) { ++ field_width = -field_width; ++ flags |= LEFT; ++ } ++ } ++ ++ /* get the precision */ ++ precision = -1; ++ if (*fmt == '.') { ++ ++fmt; ++ if (isdigit(*fmt)) ++ precision = skip_atoi(&fmt); ++ else if (*fmt == '*') { ++ ++fmt; ++ /* it's the next argument */ ++ precision = va_arg(args, int); ++ } ++ if (precision < 0) ++ precision = 0; ++ } ++ ++ /* get the conversion qualifier */ ++ qualifier = -1; ++ if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || ++ *fmt =='Z' || *fmt == 'z' || *fmt == 't') { ++ qualifier = *fmt; ++ ++fmt; ++ if (qualifier == 'l' && *fmt == 'l') { ++ qualifier = 'L'; ++ ++fmt; ++ } ++ } ++ ++ /* default base */ ++ base = 10; ++ ++ switch (*fmt) { ++ case 'c': ++ if (!(flags & LEFT)) { ++ while (--field_width > 0) { ++ if (str <= end) ++ *str = ' '; ++ ++str; ++ } ++ } ++ c = (unsigned char) va_arg(args, int); ++ if (str <= end) ++ *str = c; ++ ++str; ++ while (--field_width > 0) { ++ if (str <= end) ++ *str = ' '; ++ ++str; ++ } ++ continue; ++ ++ case 's': ++ s = va_arg(args, char *); ++ if ((unsigned long)s < PAGE_SIZE) ++ s = ""; ++ ++ len = strnlen(s, precision); ++ ++ if (!(flags & LEFT)) { ++ while (len < field_width--) { ++ if (str <= end) ++ *str = ' '; ++ ++str; ++ } ++ } ++ for (i = 0; i < len; ++i) { ++ if (str <= end) ++ *str = *s; ++ ++str; ++s; ++ } ++ while (len < field_width--) { ++ if (str <= end) ++ *str = ' '; ++ ++str; ++ } ++ continue; ++ ++ case 'p': ++ if (field_width == -1) { ++ field_width = 2*sizeof(void *); ++ flags |= ZEROPAD; ++ } ++ str = number(str, end, ++ (unsigned long) va_arg(args, void *), ++ 16, field_width, precision, flags); ++ continue; ++ ++ ++ case 'n': ++ /* FIXME: ++ * What does C99 say about the overflow case here? */ ++ if (qualifier == 'l') { ++ long * ip = va_arg(args, long *); ++ *ip = (str - buf); ++ } else if (qualifier == 'Z' || qualifier == 'z') { ++ size_t * ip = va_arg(args, size_t *); ++ *ip = (str - buf); ++ } else { ++ int * ip = va_arg(args, int *); ++ *ip = (str - buf); ++ } ++ continue; ++ ++ case '%': ++ if (str <= end) ++ *str = '%'; ++ ++str; ++ continue; ++ ++ /* integer number formats - set up the flags and "break" */ ++ case 'o': ++ base = 8; ++ break; ++ ++ case 'X': ++ flags |= LARGE; ++ case 'x': ++ base = 16; ++ break; ++ ++ case 'd': ++ case 'i': ++ flags |= SIGN; ++ case 'u': ++ break; ++ ++ default: ++ if (str <= end) ++ *str = '%'; ++ ++str; ++ if (*fmt) { ++ if (str <= end) ++ *str = *fmt; ++ ++str; ++ } else { ++ --fmt; ++ } ++ continue; ++ } ++ if (qualifier == 'L') ++ num = va_arg(args, long long); ++ else if (qualifier == 'l') { ++ num = va_arg(args, unsigned long); ++ if (flags & SIGN) ++ num = (signed long) num; ++ } else if (qualifier == 'Z' || qualifier == 'z') { ++ num = va_arg(args, size_t); ++ } else if (qualifier == 't') { ++ num = va_arg(args, ptrdiff_t); ++ } else if (qualifier == 'h') { ++ num = (unsigned short) va_arg(args, int); ++ if (flags & SIGN) ++ num = (signed short) num; ++ } else { ++ num = va_arg(args, unsigned int); ++ if (flags & SIGN) ++ num = (signed int) num; ++ } ++ str = number(str, end, num, base, ++ field_width, precision, flags); ++ } ++ if (str <= end) ++ *str = '\0'; ++ else if (size > 0) ++ /* don't write out a null byte if the buf size is zero */ ++ *end = '\0'; ++ /* the trailing null byte doesn't count towards the total ++ * ++str; ++ */ ++ return str-buf; ++} ++ ++EXPORT_SYMBOL(vsnprintf); ++ ++/** ++ * vscnprintf - Format a string and place it in a buffer ++ * @buf: The buffer to place the result into ++ * @size: The size of the buffer, including the trailing null space ++ * @fmt: The format string to use ++ * @args: Arguments for the format string ++ * ++ * The return value is the number of characters which have been written into ++ * the @buf not including the trailing '\0'. If @size is <= 0 the function ++ * returns 0. ++ * ++ * Call this function if you are already dealing with a va_list. ++ * You probably want scnprintf instead. ++ */ ++int vscnprintf(char *buf, size_t size, const char *fmt, va_list args) ++{ ++ int i; ++ ++ i=vsnprintf(buf,size,fmt,args); ++ return (i >= size) ? (size - 1) : i; ++} ++ ++EXPORT_SYMBOL(vscnprintf); ++ ++/** ++ * snprintf - Format a string and place it in a buffer ++ * @buf: The buffer to place the result into ++ * @size: The size of the buffer, including the trailing null space ++ * @fmt: The format string to use ++ * @...: Arguments for the format string ++ * ++ * The return value is the number of characters which would be ++ * generated for the given input, excluding the trailing null, ++ * as per ISO C99. If the return is greater than or equal to ++ * @size, the resulting string is truncated. ++ */ ++int snprintf(char * buf, size_t size, const char *fmt, ...) ++{ ++ va_list args; ++ int i; ++ ++ va_start(args, fmt); ++ i=vsnprintf(buf,size,fmt,args); ++ va_end(args); ++ return i; ++} ++ ++EXPORT_SYMBOL(snprintf); ++ ++/** ++ * scnprintf - Format a string and place it in a buffer ++ * @buf: The buffer to place the result into ++ * @size: The size of the buffer, including the trailing null space ++ * @fmt: The format string to use ++ * @...: Arguments for the format string ++ * ++ * The return value is the number of characters written into @buf not including ++ * the trailing '\0'. If @size is <= 0 the function returns 0. If the return is ++ * greater than or equal to @size, the resulting string is truncated. ++ */ ++ ++int scnprintf(char * buf, size_t size, const char *fmt, ...) ++{ ++ va_list args; ++ int i; ++ ++ va_start(args, fmt); ++ i = vsnprintf(buf, size, fmt, args); ++ va_end(args); ++ return (i >= size) ? (size - 1) : i; ++} ++EXPORT_SYMBOL(scnprintf); ++ ++/** ++ * vsprintf - Format a string and place it in a buffer ++ * @buf: The buffer to place the result into ++ * @fmt: The format string to use ++ * @args: Arguments for the format string ++ * ++ * The function returns the number of characters written ++ * into @buf. Use vsnprintf or vscnprintf in order to avoid ++ * buffer overflows. ++ * ++ * Call this function if you are already dealing with a va_list. ++ * You probably want sprintf instead. ++ */ ++int vsprintf(char *buf, const char *fmt, va_list args) ++{ ++ return vsnprintf(buf, INT_MAX, fmt, args); ++} ++ ++EXPORT_SYMBOL(vsprintf); ++ ++/** ++ * sprintf - Format a string and place it in a buffer ++ * @buf: The buffer to place the result into ++ * @fmt: The format string to use ++ * @...: Arguments for the format string ++ * ++ * The function returns the number of characters written ++ * into @buf. Use snprintf or scnprintf in order to avoid ++ * buffer overflows. ++ */ ++int sprintf(char * buf, const char *fmt, ...) ++{ ++ va_list args; ++ int i; ++ ++ va_start(args, fmt); ++ i=vsnprintf(buf, INT_MAX, fmt, args); ++ va_end(args); ++ return i; ++} ++ ++EXPORT_SYMBOL(sprintf); ++ ++/** ++ * vsscanf - Unformat a buffer into a list of arguments ++ * @buf: input buffer ++ * @fmt: format of buffer ++ * @args: arguments ++ */ ++int vsscanf(const char * buf, const char * fmt, va_list args) ++{ ++ const char *str = buf; ++ char *next; ++ char digit; ++ int num = 0; ++ int qualifier; ++ int base; ++ int field_width; ++ int is_sign = 0; ++ ++ while(*fmt && *str) { ++ /* skip any white space in format */ ++ /* white space in format matchs any amount of ++ * white space, including none, in the input. ++ */ ++ if (isspace(*fmt)) { ++ while (isspace(*fmt)) ++ ++fmt; ++ while (isspace(*str)) ++ ++str; ++ } ++ ++ /* anything that is not a conversion must match exactly */ ++ if (*fmt != '%' && *fmt) { ++ if (*fmt++ != *str++) ++ break; ++ continue; ++ } ++ ++ if (!*fmt) ++ break; ++ ++fmt; ++ ++ /* skip this conversion. ++ * advance both strings to next white space ++ */ ++ if (*fmt == '*') { ++ while (!isspace(*fmt) && *fmt) ++ fmt++; ++ while (!isspace(*str) && *str) ++ str++; ++ continue; ++ } ++ ++ /* get field width */ ++ field_width = -1; ++ if (isdigit(*fmt)) ++ field_width = skip_atoi(&fmt); ++ ++ /* get conversion qualifier */ ++ qualifier = -1; ++ if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || ++ *fmt == 'Z' || *fmt == 'z') { ++ qualifier = *fmt++; ++ if (unlikely(qualifier == *fmt)) { ++ if (qualifier == 'h') { ++ qualifier = 'H'; ++ fmt++; ++ } else if (qualifier == 'l') { ++ qualifier = 'L'; ++ fmt++; ++ } ++ } ++ } ++ base = 10; ++ is_sign = 0; ++ ++ if (!*fmt || !*str) ++ break; ++ ++ switch(*fmt++) { ++ case 'c': ++ { ++ char *s = (char *) va_arg(args,char*); ++ if (field_width == -1) ++ field_width = 1; ++ do { ++ *s++ = *str++; ++ } while (--field_width > 0 && *str); ++ num++; ++ } ++ continue; ++ case 's': ++ { ++ char *s = (char *) va_arg(args, char *); ++ if(field_width == -1) ++ field_width = INT_MAX; ++ /* first, skip leading white space in buffer */ ++ while (isspace(*str)) ++ str++; ++ ++ /* now copy until next white space */ ++ while (*str && !isspace(*str) && field_width--) { ++ *s++ = *str++; ++ } ++ *s = '\0'; ++ num++; ++ } ++ continue; ++ case 'n': ++ /* return number of characters read so far */ ++ { ++ int *i = (int *)va_arg(args,int*); ++ *i = str - buf; ++ } ++ continue; ++ case 'o': ++ base = 8; ++ break; ++ case 'x': ++ case 'X': ++ base = 16; ++ break; ++ case 'i': ++ base = 0; ++ case 'd': ++ is_sign = 1; ++ case 'u': ++ break; ++ case '%': ++ /* looking for '%' in str */ ++ if (*str++ != '%') ++ return num; ++ continue; ++ default: ++ /* invalid format; stop here */ ++ return num; ++ } ++ ++ /* have some sort of integer conversion. ++ * first, skip white space in buffer. ++ */ ++ while (isspace(*str)) ++ str++; ++ ++ digit = *str; ++ if (is_sign && digit == '-') ++ digit = *(str + 1); ++ ++ if (!digit ++ || (base == 16 && !isxdigit(digit)) ++ || (base == 10 && !isdigit(digit)) ++ || (base == 8 && (!isdigit(digit) || digit > '7')) ++ || (base == 0 && !isdigit(digit))) ++ break; ++ ++ switch(qualifier) { ++ case 'H': /* that's 'hh' in format */ ++ if (is_sign) { ++ signed char *s = (signed char *) va_arg(args,signed char *); ++ *s = (signed char) simple_strtol(str,&next,base); ++ } else { ++ unsigned char *s = (unsigned char *) va_arg(args, unsigned char *); ++ *s = (unsigned char) simple_strtoul(str, &next, base); ++ } ++ break; ++ case 'h': ++ if (is_sign) { ++ short *s = (short *) va_arg(args,short *); ++ *s = (short) simple_strtol(str,&next,base); ++ } else { ++ unsigned short *s = (unsigned short *) va_arg(args, unsigned short *); ++ *s = (unsigned short) simple_strtoul(str, &next, base); ++ } ++ break; ++ case 'l': ++ if (is_sign) { ++ long *l = (long *) va_arg(args,long *); ++ *l = simple_strtol(str,&next,base); ++ } else { ++ unsigned long *l = (unsigned long*) va_arg(args,unsigned long*); ++ *l = simple_strtoul(str,&next,base); ++ } ++ break; ++ case 'L': ++ if (is_sign) { ++ long long *l = (long long*) va_arg(args,long long *); ++ *l = simple_strtoll(str,&next,base); ++ } else { ++ unsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*); ++ *l = simple_strtoull(str,&next,base); ++ } ++ break; ++ case 'Z': ++ case 'z': ++ { ++ size_t *s = (size_t*) va_arg(args,size_t*); ++ *s = (size_t) simple_strtoul(str,&next,base); ++ } ++ break; ++ default: ++ if (is_sign) { ++ int *i = (int *) va_arg(args, int*); ++ *i = (int) simple_strtol(str,&next,base); ++ } else { ++ unsigned int *i = (unsigned int*) va_arg(args, unsigned int*); ++ *i = (unsigned int) simple_strtoul(str,&next,base); ++ } ++ break; ++ } ++ num++; ++ ++ if (!next) ++ break; ++ str = next; ++ } ++ return num; ++} ++ ++EXPORT_SYMBOL(vsscanf); ++ ++/** ++ * sscanf - Unformat a buffer into a list of arguments ++ * @buf: input buffer ++ * @fmt: formatting of buffer ++ * @...: resulting arguments ++ */ ++int sscanf(const char * buf, const char * fmt, ...) ++{ ++ va_list args; ++ int i; ++ ++ va_start(args,fmt); ++ i = vsscanf(buf,fmt,args); ++ va_end(args); ++ return i; ++} ++ ++EXPORT_SYMBOL(sscanf); +Index: build-32-release304-12901/tools/xcutils/helper/x86_32/div64.h +=================================================================== +--- /dev/null ++++ build-32-release304-12901/tools/xcutils/helper/x86_32/div64.h +@@ -0,0 +1,48 @@ ++#ifndef __I386_DIV64 ++#define __I386_DIV64 ++ ++/* ++ * do_div() is NOT a C function. It wants to return ++ * two values (the quotient and the remainder), but ++ * since that doesn't work very well in C, what it ++ * does is: ++ * ++ * - modifies the 64-bit dividend _in_place_ ++ * - returns the 32-bit remainder ++ * ++ * This ends up being the most efficient "calling ++ * convention" on x86. ++ */ ++#define do_div(n,base) ({ \ ++ unsigned long __upper, __low, __high, __mod, __base; \ ++ __base = (base); \ ++ asm("":"=a" (__low), "=d" (__high):"A" (n)); \ ++ __upper = __high; \ ++ if (__high) { \ ++ __upper = __high % (__base); \ ++ __high = __high / (__base); \ ++ } \ ++ asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (__base), "0" (__low), "1" (__upper)); \ ++ asm("":"=A" (n):"a" (__low),"d" (__high)); \ ++ __mod; \ ++}) ++ ++/* ++ * (long)X = ((long long)divs) / (long)div ++ * (long)rem = ((long long)divs) % (long)div ++ * ++ * Warning, this will do an exception if X overflows. ++ */ ++#define div_long_long_rem(a,b,c) div_ll_X_l_rem(a,b,c) ++ ++static inline long ++div_ll_X_l_rem(long long divs, long div, long *rem) ++{ ++ long dum2; ++ __asm__("divl %2":"=a"(dum2), "=d"(*rem) ++ : "rm"(div), "A"(divs)); ++ ++ return dum2; ++ ++} ++#endif +Index: build-32-release304-12901/tools/xcutils/helper/x86_32/entry.S +=================================================================== +--- /dev/null ++++ build-32-release304-12901/tools/xcutils/helper/x86_32/entry.S +@@ -0,0 +1,49 @@ ++#include "offsets.h" ++ ++/* --- stack -------------------------------------------------------- */ ++ ++ .data ++stack_bottom: ++ .fill 4096,1,0 ++stack_top: ++ ++/* --- text --------------------------------------------------------- */ ++ ++ .text ++ .globl _start,_start_kernel,BUG,hypercall_page ++ ++_start: ++ movl %esi, old_info ++ lea stack_top,%esp ++ jmp start_helper ++ ++_start_kernel: ++ movl vcpu+vcpu_ebx,%ebx /* load registers */ ++ movl vcpu+vcpu_ecx,%ecx ++ movl vcpu+vcpu_edx,%edx ++ movl vcpu+vcpu_esi,%esi ++ movl vcpu+vcpu_edi,%edi ++ movl vcpu+vcpu_ebp,%ebp ++ movl vcpu+vcpu_esp,%esp /* using new kernels boot stack now */ ++ ++ movl vcpu+vcpu_eip,%eax /* push entry point */ ++ push %eax ++ movl vcpu+vcpu_eax,%eax /* push eax */ ++ push %eax ++ movl vcpu+vcpu_cr3,%eax /* activate new pagetables */ ++ movl %eax,%cr3 ++ pop %eax /* reload eax */ ++ ret /* jump to new kernel */ ++ ++BUG: ++ /* crash the domain, make xen dump registers */ ++ ud2 ++ jmp BUG ++ ++/* --- hypercall page ----------------------------------------------- */ ++ ++ .align 4096 ++hypercall_page: ++ nop ++ .align 4096 ++hypercall_end: +Index: build-32-release304-12901/tools/xcutils/helper/x86_32/hypercall.h +=================================================================== +--- /dev/null ++++ build-32-release304-12901/tools/xcutils/helper/x86_32/hypercall.h +@@ -0,0 +1,360 @@ ++/****************************************************************************** ++ * hypercall.h ++ * ++ * Linux-specific hypervisor handling. ++ * ++ * Copyright (c) 2002-2004, K A Fraser ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License 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 ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ++ * IN THE SOFTWARE. ++ */ ++ ++#ifndef __HYPERCALL_H__ ++#define __HYPERCALL_H__ ++ ++#include /* memcpy() */ ++ ++#define __STR(x) #x ++#define STR(x) __STR(x) ++ ++#define _hypercall0(type, name) \ ++({ \ ++ long __res; \ ++ asm volatile ( \ ++ "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ ++ : "=a" (__res) \ ++ : \ ++ : "memory" ); \ ++ (type)__res; \ ++}) ++ ++#define _hypercall1(type, name, a1) \ ++({ \ ++ long __res, __ign1; \ ++ asm volatile ( \ ++ "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ ++ : "=a" (__res), "=b" (__ign1) \ ++ : "1" ((long)(a1)) \ ++ : "memory" ); \ ++ (type)__res; \ ++}) ++ ++#define _hypercall2(type, name, a1, a2) \ ++({ \ ++ long __res, __ign1, __ign2; \ ++ asm volatile ( \ ++ "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ ++ : "=a" (__res), "=b" (__ign1), "=c" (__ign2) \ ++ : "1" ((long)(a1)), "2" ((long)(a2)) \ ++ : "memory" ); \ ++ (type)__res; \ ++}) ++ ++#define _hypercall3(type, name, a1, a2, a3) \ ++({ \ ++ long __res, __ign1, __ign2, __ign3; \ ++ asm volatile ( \ ++ "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ ++ : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ ++ "=d" (__ign3) \ ++ : "1" ((long)(a1)), "2" ((long)(a2)), \ ++ "3" ((long)(a3)) \ ++ : "memory" ); \ ++ (type)__res; \ ++}) ++ ++#define _hypercall4(type, name, a1, a2, a3, a4) \ ++({ \ ++ long __res, __ign1, __ign2, __ign3, __ign4; \ ++ asm volatile ( \ ++ "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ ++ : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ ++ "=d" (__ign3), "=S" (__ign4) \ ++ : "1" ((long)(a1)), "2" ((long)(a2)), \ ++ "3" ((long)(a3)), "4" ((long)(a4)) \ ++ : "memory" ); \ ++ (type)__res; \ ++}) ++ ++#define _hypercall5(type, name, a1, a2, a3, a4, a5) \ ++({ \ ++ long __res, __ign1, __ign2, __ign3, __ign4, __ign5; \ ++ asm volatile ( \ ++ "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ ++ : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ ++ "=d" (__ign3), "=S" (__ign4), "=D" (__ign5) \ ++ : "1" ((long)(a1)), "2" ((long)(a2)), \ ++ "3" ((long)(a3)), "4" ((long)(a4)), \ ++ "5" ((long)(a5)) \ ++ : "memory" ); \ ++ (type)__res; \ ++}) ++ ++static inline int ++HYPERVISOR_set_trap_table( ++ trap_info_t *table) ++{ ++ return _hypercall1(int, set_trap_table, table); ++} ++ ++static inline int ++HYPERVISOR_mmu_update( ++ mmu_update_t *req, int count, int *success_count, domid_t domid) ++{ ++ return _hypercall4(int, mmu_update, req, count, success_count, domid); ++} ++ ++static inline int ++HYPERVISOR_mmuext_op( ++ struct mmuext_op *op, int count, int *success_count, domid_t domid) ++{ ++ return _hypercall4(int, mmuext_op, op, count, success_count, domid); ++} ++ ++static inline int ++HYPERVISOR_set_gdt( ++ unsigned long *frame_list, int entries) ++{ ++ return _hypercall2(int, set_gdt, frame_list, entries); ++} ++ ++static inline int ++HYPERVISOR_stack_switch( ++ unsigned long ss, unsigned long esp) ++{ ++ return _hypercall2(int, stack_switch, ss, esp); ++} ++ ++static inline int ++HYPERVISOR_set_callbacks( ++ unsigned long event_selector, unsigned long event_address, ++ unsigned long failsafe_selector, unsigned long failsafe_address) ++{ ++ return _hypercall4(int, set_callbacks, ++ event_selector, event_address, ++ failsafe_selector, failsafe_address); ++} ++ ++static inline int ++HYPERVISOR_fpu_taskswitch( ++ int set) ++{ ++ return _hypercall1(int, fpu_taskswitch, set); ++} ++ ++static inline int ++HYPERVISOR_sched_op_compat( ++ int cmd, unsigned long arg) ++{ ++ return _hypercall2(int, sched_op_compat, cmd, arg); ++} ++ ++static inline int ++HYPERVISOR_sched_op( ++ int cmd, void *arg) ++{ ++ return _hypercall2(int, sched_op, cmd, arg); ++} ++ ++#if 0 ++static inline long ++HYPERVISOR_set_timer_op( ++ u64 timeout) ++{ ++ unsigned long timeout_hi = (unsigned long)(timeout>>32); ++ unsigned long timeout_lo = (unsigned long)timeout; ++ return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi); ++} ++ ++static inline int ++HYPERVISOR_dom0_op( ++ dom0_op_t *dom0_op) ++{ ++ dom0_op->interface_version = DOM0_INTERFACE_VERSION; ++ return _hypercall1(int, dom0_op, dom0_op); ++} ++#endif ++ ++static inline int ++HYPERVISOR_set_debugreg( ++ int reg, unsigned long value) ++{ ++ return _hypercall2(int, set_debugreg, reg, value); ++} ++ ++static inline unsigned long ++HYPERVISOR_get_debugreg( ++ int reg) ++{ ++ return _hypercall1(unsigned long, get_debugreg, reg); ++} ++ ++#if 0 ++static inline int ++HYPERVISOR_update_descriptor( ++ u64 ma, u64 desc) ++{ ++ return _hypercall4(int, update_descriptor, ma, ma>>32, desc, desc>>32); ++} ++#endif ++ ++static inline int ++HYPERVISOR_memory_op( ++ unsigned int cmd, void *arg) ++{ ++ return _hypercall2(int, memory_op, cmd, arg); ++} ++ ++static inline int ++HYPERVISOR_multicall( ++ void *call_list, int nr_calls) ++{ ++ return _hypercall2(int, multicall, call_list, nr_calls); ++} ++ ++#if 0 ++static inline int ++HYPERVISOR_update_va_mapping( ++ unsigned long va, pte_t new_val, unsigned long flags) ++{ ++ unsigned long pte_hi = 0; ++#ifdef CONFIG_X86_PAE ++ pte_hi = new_val.pte_high; ++#endif ++ return _hypercall4(int, update_va_mapping, va, ++ new_val.pte_low, pte_hi, flags); ++} ++#endif ++ ++static inline int ++HYPERVISOR_event_channel_op( ++ int cmd, void *arg) ++{ ++ int rc = _hypercall2(int, event_channel_op, cmd, arg); ++ /* FIXME: handle -ENOSYS */ ++ return rc; ++} ++ ++static inline int ++HYPERVISOR_acm_op( ++ int cmd, void *arg) ++{ ++ return _hypercall2(int, acm_op, cmd, arg); ++} ++ ++static inline int ++HYPERVISOR_xen_version( ++ int cmd, void *arg) ++{ ++ return _hypercall2(int, xen_version, cmd, arg); ++} ++ ++static inline int ++HYPERVISOR_console_io( ++ int cmd, int count, char *str) ++{ ++ return _hypercall3(int, console_io, cmd, count, str); ++} ++ ++static inline int ++HYPERVISOR_physdev_op( ++ int cmd, void *arg) ++{ ++ int rc = _hypercall2(int, physdev_op, cmd, arg); ++ /* FIXME: handle -ENOSYS */ ++ return rc; ++} ++ ++static inline int ++HYPERVISOR_grant_table_op( ++ unsigned int cmd, void *uop, unsigned int count) ++{ ++ return _hypercall3(int, grant_table_op, cmd, uop, count); ++} ++ ++#if 0 ++static inline int ++HYPERVISOR_update_va_mapping_otherdomain( ++ unsigned long va, pte_t new_val, unsigned long flags, domid_t domid) ++{ ++ unsigned long pte_hi = 0; ++#ifdef CONFIG_X86_PAE ++ pte_hi = new_val.pte_high; ++#endif ++ return _hypercall5(int, update_va_mapping_otherdomain, va, ++ new_val.pte_low, pte_hi, flags, domid); ++} ++#endif ++ ++static inline int ++HYPERVISOR_vm_assist( ++ unsigned int cmd, unsigned int type) ++{ ++ return _hypercall2(int, vm_assist, cmd, type); ++} ++ ++static inline int ++HYPERVISOR_vcpu_op( ++ int cmd, int vcpuid, void *extra_args) ++{ ++ return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args); ++} ++ ++static inline int ++HYPERVISOR_suspend( ++ unsigned long srec) ++{ ++ struct sched_shutdown sched_shutdown = { ++ .reason = SHUTDOWN_suspend ++ }; ++ ++ int rc = _hypercall3(int, sched_op, SCHEDOP_shutdown, ++ &sched_shutdown, srec); ++ /* FIXME: handle -ENOSYS */ ++ return rc; ++} ++ ++static inline int ++HYPERVISOR_nmi_op( ++ unsigned long op, void *arg) ++{ ++ return _hypercall2(int, nmi_op, op, arg); ++} ++ ++static inline int ++HYPERVISOR_callback_op( ++ int cmd, void *arg) ++{ ++ return _hypercall2(int, callback_op, cmd, arg); ++} ++ ++static inline int ++HYPERVISOR_xenoprof_op( ++ int op, void *arg) ++{ ++ return _hypercall2(int, xenoprof_op, op, arg); ++} ++ ++ ++#endif /* __HYPERCALL_H__ */ +Index: build-32-release304-12901/tools/xcutils/helper/x86_64/div64.h +=================================================================== +--- /dev/null ++++ build-32-release304-12901/tools/xcutils/helper/x86_64/div64.h +@@ -0,0 +1,58 @@ ++#ifndef _ASM_GENERIC_DIV64_H ++#define _ASM_GENERIC_DIV64_H ++/* ++ * Copyright (C) 2003 Bernardo Innocenti ++ * Based on former asm-ppc/div64.h and asm-m68knommu/div64.h ++ * ++ * The semantics of do_div() are: ++ * ++ * uint32_t do_div(uint64_t *n, uint32_t base) ++ * { ++ * uint32_t remainder = *n % base; ++ * *n = *n / base; ++ * return remainder; ++ * } ++ * ++ * NOTE: macro parameter n is evaluated multiple times, ++ * beware of side effects! ++ */ ++ ++#include ++#include ++ ++#if BITS_PER_LONG == 64 ++ ++# define do_div(n,base) ({ \ ++ uint32_t __base = (base); \ ++ uint32_t __rem; \ ++ __rem = ((uint64_t)(n)) % __base; \ ++ (n) = ((uint64_t)(n)) / __base; \ ++ __rem; \ ++ }) ++ ++#elif BITS_PER_LONG == 32 ++ ++extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor); ++ ++/* The unnecessary pointer compare is there ++ * to check for type safety (n must be 64bit) ++ */ ++# define do_div(n,base) ({ \ ++ uint32_t __base = (base); \ ++ uint32_t __rem; \ ++ (void)(((typeof((n)) *)0) == ((uint64_t *)0)); \ ++ if (likely(((n) >> 32) == 0)) { \ ++ __rem = (uint32_t)(n) % __base; \ ++ (n) = (uint32_t)(n) / __base; \ ++ } else \ ++ __rem = __div64_32(&(n), __base); \ ++ __rem; \ ++ }) ++ ++#else /* BITS_PER_LONG == ?? */ ++ ++# error do_div() does not yet support the C64 ++ ++#endif /* BITS_PER_LONG */ ++ ++#endif /* _ASM_GENERIC_DIV64_H */ +Index: build-32-release304-12901/tools/xcutils/helper/x86_64/entry.S +=================================================================== +--- /dev/null ++++ build-32-release304-12901/tools/xcutils/helper/x86_64/entry.S +@@ -0,0 +1,50 @@ ++#include "offsets.h" ++ ++/* --- stack -------------------------------------------------------- */ ++ ++ .data ++stack_bottom: ++ .fill 4096,1,0 ++stack_top: ++ ++/* --- text --------------------------------------------------------- */ ++ ++ .text ++ .globl _start,_start_kernel,hypercall_page,BUG ++ ++_start: ++ /* setup stack */ ++ movq %rsi, old_info ++ lea stack_top,%rsp ++ jmp start_helper ++ ++_start_kernel: ++ movq vcpu+vcpu_ebx,%rbx /* load registers */ ++ movq vcpu+vcpu_ecx,%rcx ++ movq vcpu+vcpu_edx,%rdx ++ movq vcpu+vcpu_esi,%rsi ++ movq vcpu+vcpu_edi,%rdi ++ movq vcpu+vcpu_ebp,%rbp ++ movq vcpu+vcpu_esp,%rsp /* using new kernels boot stack now */ ++ ++ movq vcpu+vcpu_eip,%rax ++ push %rax ++ movq vcpu+vcpu_eax,%rax ++ push %rax ++ movq vcpu+vcpu_cr3,%rax ++ movq %rax,%cr3 /* activate new pagetables */ ++ pop %rax /* load rax */ ++ ret /* jump to new kernel */ ++ ++BUG: ++ /* crash the domain, make xen dump registers */ ++ ud2 ++ jmp BUG ++ ++/* --- hypercall page ----------------------------------------------- */ ++ ++ .align 4096 ++hypercall_page: ++ nop ++ .align 4096 ++hypercall_end: +Index: build-32-release304-12901/tools/xcutils/helper/x86_64/hypercall.h +=================================================================== +--- /dev/null ++++ build-32-release304-12901/tools/xcutils/helper/x86_64/hypercall.h +@@ -0,0 +1,355 @@ ++/****************************************************************************** ++ * hypercall.h ++ * ++ * Linux-specific hypervisor handling. ++ * ++ * Copyright (c) 2002-2004, K A Fraser ++ * ++ * 64-bit updates: ++ * Benjamin Liu ++ * Jun Nakajima ++ * ++ * 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 ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ++ * IN THE SOFTWARE. ++ */ ++ ++#ifndef __HYPERCALL_H__ ++#define __HYPERCALL_H__ ++ ++#include /* memcpy() */ ++ ++#define __STR(x) #x ++#define STR(x) __STR(x) ++ ++#define _hypercall0(type, name) \ ++({ \ ++ long __res; \ ++ asm volatile ( \ ++ "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ ++ : "=a" (__res) \ ++ : \ ++ : "memory" ); \ ++ (type)__res; \ ++}) ++ ++#define _hypercall1(type, name, a1) \ ++({ \ ++ long __res, __ign1; \ ++ asm volatile ( \ ++ "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ ++ : "=a" (__res), "=D" (__ign1) \ ++ : "1" ((long)(a1)) \ ++ : "memory" ); \ ++ (type)__res; \ ++}) ++ ++#define _hypercall2(type, name, a1, a2) \ ++({ \ ++ long __res, __ign1, __ign2; \ ++ asm volatile ( \ ++ "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ ++ : "=a" (__res), "=D" (__ign1), "=S" (__ign2) \ ++ : "1" ((long)(a1)), "2" ((long)(a2)) \ ++ : "memory" ); \ ++ (type)__res; \ ++}) ++ ++#define _hypercall3(type, name, a1, a2, a3) \ ++({ \ ++ long __res, __ign1, __ign2, __ign3; \ ++ asm volatile ( \ ++ "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ ++ : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \ ++ "=d" (__ign3) \ ++ : "1" ((long)(a1)), "2" ((long)(a2)), \ ++ "3" ((long)(a3)) \ ++ : "memory" ); \ ++ (type)__res; \ ++}) ++ ++#define _hypercall4(type, name, a1, a2, a3, a4) \ ++({ \ ++ long __res, __ign1, __ign2, __ign3; \ ++ asm volatile ( \ ++ "movq %7,%%r10; " \ ++ "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ ++ : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \ ++ "=d" (__ign3) \ ++ : "1" ((long)(a1)), "2" ((long)(a2)), \ ++ "3" ((long)(a3)), "g" ((long)(a4)) \ ++ : "memory", "r10" ); \ ++ (type)__res; \ ++}) ++ ++#define _hypercall5(type, name, a1, a2, a3, a4, a5) \ ++({ \ ++ long __res, __ign1, __ign2, __ign3; \ ++ asm volatile ( \ ++ "movq %7,%%r10; movq %8,%%r8; " \ ++ "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ ++ : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \ ++ "=d" (__ign3) \ ++ : "1" ((long)(a1)), "2" ((long)(a2)), \ ++ "3" ((long)(a3)), "g" ((long)(a4)), \ ++ "g" ((long)(a5)) \ ++ : "memory", "r10", "r8" ); \ ++ (type)__res; \ ++}) ++ ++static inline int ++HYPERVISOR_set_trap_table( ++ trap_info_t *table) ++{ ++ return _hypercall1(int, set_trap_table, table); ++} ++ ++static inline int ++HYPERVISOR_mmu_update( ++ mmu_update_t *req, int count, int *success_count, domid_t domid) ++{ ++ return _hypercall4(int, mmu_update, req, count, success_count, domid); ++} ++ ++static inline int ++HYPERVISOR_mmuext_op( ++ struct mmuext_op *op, int count, int *success_count, domid_t domid) ++{ ++ return _hypercall4(int, mmuext_op, op, count, success_count, domid); ++} ++ ++static inline int ++HYPERVISOR_set_gdt( ++ unsigned long *frame_list, int entries) ++{ ++ return _hypercall2(int, set_gdt, frame_list, entries); ++} ++ ++static inline int ++HYPERVISOR_stack_switch( ++ unsigned long ss, unsigned long esp) ++{ ++ return _hypercall2(int, stack_switch, ss, esp); ++} ++ ++static inline int ++HYPERVISOR_set_callbacks( ++ unsigned long event_address, unsigned long failsafe_address, ++ unsigned long syscall_address) ++{ ++ return _hypercall3(int, set_callbacks, ++ event_address, failsafe_address, syscall_address); ++} ++ ++static inline int ++HYPERVISOR_fpu_taskswitch( ++ int set) ++{ ++ return _hypercall1(int, fpu_taskswitch, set); ++} ++ ++static inline int ++HYPERVISOR_sched_op_compat( ++ int cmd, unsigned long arg) ++{ ++ return _hypercall2(int, sched_op_compat, cmd, arg); ++} ++ ++static inline int ++HYPERVISOR_sched_op( ++ int cmd, void *arg) ++{ ++ return _hypercall2(int, sched_op, cmd, arg); ++} ++ ++#if 0 ++static inline long ++HYPERVISOR_set_timer_op( ++ u64 timeout) ++{ ++ return _hypercall1(long, set_timer_op, timeout); ++} ++ ++static inline int ++HYPERVISOR_dom0_op( ++ dom0_op_t *dom0_op) ++{ ++ dom0_op->interface_version = DOM0_INTERFACE_VERSION; ++ return _hypercall1(int, dom0_op, dom0_op); ++} ++#endif ++ ++static inline int ++HYPERVISOR_set_debugreg( ++ int reg, unsigned long value) ++{ ++ return _hypercall2(int, set_debugreg, reg, value); ++} ++ ++static inline unsigned long ++HYPERVISOR_get_debugreg( ++ int reg) ++{ ++ return _hypercall1(unsigned long, get_debugreg, reg); ++} ++ ++static inline int ++HYPERVISOR_update_descriptor( ++ unsigned long ma, unsigned long word) ++{ ++ return _hypercall2(int, update_descriptor, ma, word); ++} ++ ++static inline int ++HYPERVISOR_memory_op( ++ unsigned int cmd, void *arg) ++{ ++ return _hypercall2(int, memory_op, cmd, arg); ++} ++ ++static inline int ++HYPERVISOR_multicall( ++ void *call_list, int nr_calls) ++{ ++ return _hypercall2(int, multicall, call_list, nr_calls); ++} ++ ++#if 0 ++static inline int ++HYPERVISOR_update_va_mapping( ++ unsigned long va, pte_t new_val, unsigned long flags) ++{ ++ return _hypercall3(int, update_va_mapping, va, new_val.pte, flags); ++} ++#endif ++ ++static inline int ++HYPERVISOR_event_channel_op( ++ int cmd, void *arg) ++{ ++ int rc = _hypercall2(int, event_channel_op, cmd, arg); ++ return rc; ++} ++ ++static inline int ++HYPERVISOR_acm_op( ++ int cmd, void *arg) ++{ ++ return _hypercall2(int, acm_op, cmd, arg); ++} ++ ++static inline int ++HYPERVISOR_xen_version( ++ int cmd, void *arg) ++{ ++ return _hypercall2(int, xen_version, cmd, arg); ++} ++ ++static inline int ++HYPERVISOR_console_io( ++ int cmd, int count, char *str) ++{ ++ return _hypercall3(int, console_io, cmd, count, str); ++} ++ ++static inline int ++HYPERVISOR_physdev_op( ++ int cmd, void *arg) ++{ ++ int rc = _hypercall2(int, physdev_op, cmd, arg); ++ return rc; ++} ++ ++static inline int ++HYPERVISOR_grant_table_op( ++ unsigned int cmd, void *uop, unsigned int count) ++{ ++ return _hypercall3(int, grant_table_op, cmd, uop, count); ++} ++ ++#if 0 ++static inline int ++HYPERVISOR_update_va_mapping_otherdomain( ++ unsigned long va, pte_t new_val, unsigned long flags, domid_t domid) ++{ ++ return _hypercall4(int, update_va_mapping_otherdomain, va, ++ new_val.pte, flags, domid); ++} ++#endif ++ ++static inline int ++HYPERVISOR_vm_assist( ++ unsigned int cmd, unsigned int type) ++{ ++ return _hypercall2(int, vm_assist, cmd, type); ++} ++ ++static inline int ++HYPERVISOR_vcpu_op( ++ int cmd, int vcpuid, void *extra_args) ++{ ++ return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args); ++} ++ ++static inline int ++HYPERVISOR_set_segment_base( ++ int reg, unsigned long value) ++{ ++ return _hypercall2(int, set_segment_base, reg, value); ++} ++ ++static inline int ++HYPERVISOR_suspend( ++ unsigned long srec) ++{ ++ struct sched_shutdown sched_shutdown = { ++ .reason = SHUTDOWN_suspend ++ }; ++ ++ int rc = _hypercall3(int, sched_op, SCHEDOP_shutdown, ++ &sched_shutdown, srec); ++ return rc; ++} ++ ++static inline int ++HYPERVISOR_nmi_op( ++ unsigned long op, void *arg) ++{ ++ return _hypercall2(int, nmi_op, op, arg); ++} ++ ++static inline int ++HYPERVISOR_callback_op( ++ int cmd, void *arg) ++{ ++ return _hypercall2(int, callback_op, cmd, arg); ++} ++ ++static inline int ++HYPERVISOR_xenoprof_op( ++ int op, void *arg) ++{ ++ return _hypercall2(int, xenoprof_op, op, arg); ++} ++ ++#endif /* __HYPERCALL_H__ */ +Index: build-32-release304-12901/tools/xcutils/kexec-syscall.h +=================================================================== +--- /dev/null ++++ build-32-release304-12901/tools/xcutils/kexec-syscall.h +@@ -0,0 +1,80 @@ ++#ifndef KEXEC_SYSCALL_H ++#define KEXEC_SYSCALL_H ++ ++#define __LIBRARY__ ++#include ++#include ++#include ++ ++#define LINUX_REBOOT_MAGIC1 0xfee1dead ++#define LINUX_REBOOT_MAGIC2 672274793 ++#define LINUX_REBOOT_MAGIC2A 85072278 ++#define LINUX_REBOOT_MAGIC2B 369367448 ++ ++#define LINUX_REBOOT_CMD_RESTART 0x01234567 ++#define LINUX_REBOOT_CMD_HALT 0xCDEF0123 ++#define LINUX_REBOOT_CMD_CAD_ON 0x89ABCDEF ++#define LINUX_REBOOT_CMD_CAD_OFF 0x00000000 ++#define LINUX_REBOOT_CMD_POWER_OFF 0x4321FEDC ++#define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4 ++#define LINUX_REBOOT_CMD_EXEC_KERNEL 0x18273645 ++#define LINUX_REBOOT_CMD_KEXEC_OLD 0x81726354 ++#define LINUX_REBOOT_CMD_KEXEC_OLD2 0x18263645 ++#define LINUX_REBOOT_CMD_KEXEC 0x45584543 ++ ++#ifdef __i386__ ++#define __NR_kexec_load 283 ++#endif ++#ifdef __ia64__ ++#define __NR_kexec_load 1268 ++#endif ++#ifdef __powerpc64__ ++#define __NR_kexec_load 268 ++#endif ++#ifdef __powerpc__ ++#define __NR_kexec_load 268 ++#endif ++#ifdef __x86_64__ ++#define __NR_kexec_load 246 ++#endif ++#ifdef __s390x__ ++#define __NR_kexec_load 277 ++#endif ++#ifdef __s390__ ++#define __NR_kexec_load 277 ++#endif ++#ifndef __NR_kexec_load ++#error Unknown processor architecture. Needs a kexec_load syscall number. ++#endif ++ ++struct kexec_segment; ++ ++static inline long kexec_load(void *entry, unsigned long nr_segments, ++ struct kexec_segment *segments, unsigned long flags) ++{ ++ return (long) syscall(__NR_kexec_load, entry, nr_segments, segments, flags); ++} ++ ++static inline long kexec_reboot(void) ++{ ++ return (long) syscall(__NR_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_KEXEC, 0); ++} ++ ++ ++#define KEXEC_ON_CRASH 0x00000001 ++#define KEXEC_ARCH_MASK 0xffff0000 ++ ++/* These values match the ELF architecture values. ++ * Unless there is a good reason that should continue to be the case. ++ */ ++#define KEXEC_ARCH_DEFAULT ( 0 << 16) ++#define KEXEC_ARCH_386 ( 3 << 16) ++#define KEXEC_ARCH_X86_64 (62 << 16) ++#define KEXEC_ARCH_PPC (20 << 16) ++#define KEXEC_ARCH_PPC64 (21 << 16) ++#define KEXEC_ARCH_IA_64 (50 << 16) ++#define KEXEC_ARCH_S390 (22 << 16) ++ ++#define KEXEC_MAX_SEGMENTS 16 ++ ++#endif /* KEXEC_SYSCALL_H */ +Index: build-32-release304-12901/tools/xcutils/xc_kexec.c +=================================================================== +--- /dev/null ++++ build-32-release304-12901/tools/xcutils/xc_kexec.c +@@ -0,0 +1,503 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "kexec-syscall.h" ++ ++/* ------------------------------------------------------------------ */ ++ ++static unsigned long debug_level; ++ ++static char hypercall_page[PAGE_SIZE]; ++static unsigned long max_pfn; ++static unsigned long xen_start_info; ++static start_info_t start_info; ++ ++/* -------------------------------------------------------------------------------- */ ++ ++static unsigned long kernel_find_symbol(char *name) ++{ ++ FILE *file; ++ char line[256], type, symbol[256]; ++ unsigned long addr, retval = 0; ++ ++ file = fopen("/proc/kallsyms", "r"); ++ if (NULL == file) { ++ perror("open /proc/kallsyms"); ++ exit(1); ++ } ++ while (NULL != fgets(line, sizeof(line), file)) { ++ if (3 != sscanf(line, "%lx %c %127s", &addr, &type, symbol)) { ++ fprintf(stderr,"parse error: %s\n", line); ++ exit(1); ++ } ++ if (0 == strcmp(name, symbol)) { ++ retval = addr; ++ break; ++ } ++ } ++ fclose(file); ++ return retval; ++} ++ ++static int kernel_core_read(void *dest, off_t start, size_t size) ++{ ++ FILE *file; ++ int rc; ++ ++ file = fopen("/proc/kcore", "r"); ++ if (NULL == file) { ++ perror("open /proc/kcore"); ++ exit(1); ++ } ++ rc = fseek(file, start, SEEK_SET); ++ if (rc < 0) ++ goto out; ++ rc = fread(dest, 1, size, file); ++ fclose(file); ++ ++ out: ++ return rc; ++} ++ ++static off_t kernel_core_offset(unsigned long addr) ++{ ++ static void *core_header = NULL; ++ static struct elf_binary elf; ++ const elf_phdr *phdr; ++ uint64_t p_type; ++ uint64_t p_vaddr; ++ uint64_t p_offset; ++ uint64_t p_filesz; ++ off_t offset = 0; ++ int h; ++ ++ if (NULL == core_header) { ++ core_header = malloc(PAGE_SIZE); ++ if (PAGE_SIZE != kernel_core_read(core_header, 0, PAGE_SIZE)) ++ goto out; ++ elf_init(&elf, core_header, PAGE_SIZE); ++ } ++ ++ for (h = 0; h < elf_uval(&elf, elf.ehdr, e_phnum); h++) { ++ phdr = elf_phdr_by_index(&elf, h); ++ p_type = elf_uval(&elf, phdr, p_type); ++ p_vaddr = elf_uval(&elf, phdr, p_vaddr); ++ p_offset = elf_uval(&elf, phdr, p_offset); ++ p_filesz = elf_uval(&elf, phdr, p_filesz); ++ if (p_type != PT_LOAD) ++ continue; ++ if (addr > p_vaddr && addr < p_vaddr + p_filesz) ++ offset = p_offset + (addr - p_vaddr); ++ } ++ ++ out: ++ return offset; ++} ++ ++static int kernel_core_by_addr(void *dest, unsigned long addr, size_t size) ++{ ++ off_t offset; ++ int rc = 0; ++ ++ offset = kernel_core_offset(addr); ++ if (0 == addr) { ++ fprintf(stderr, "%s: addr 0x%lx not in /proc/kcore\n", ++ __FUNCTION__, addr); ++ goto out; ++ } ++ rc = kernel_core_read(dest, offset, size); ++ if (debug_level) ++ fprintf(stderr, "%s: vaddr %lx, offset %lx, %d bytes\n", ++ __FUNCTION__, addr, (unsigned long)offset, rc); ++ ++ out: ++ return rc; ++} ++ ++static int kernel_core_by_name(void *dest, char *name, size_t size) ++{ ++ unsigned long addr; ++ off_t offset; ++ int rc = 0; ++ ++ addr = kernel_find_symbol(name); ++ if (0 == addr) { ++ fprintf(stderr, "%s: can't find symbol \"%s\" in /proc/kallsyms\n", ++ __FUNCTION__, name); ++ fprintf(stderr, "%s: try CONFIG_KALLSYMS_ALL=y\n", __FUNCTION__); ++ goto out; ++ } ++ ++ offset = kernel_core_offset(addr); ++ if (0 == addr) { ++ fprintf(stderr, "%s: symbol \"%s\" (0x%lx) not in /proc/kcore\n", ++ __FUNCTION__, name, addr); ++ goto out; ++ } ++ rc = kernel_core_read(dest, offset, size); ++ if (debug_level) ++ fprintf(stderr, "%s: vaddr %lx, offset %lx, %d bytes (%s)\n", ++ __FUNCTION__, addr, (unsigned long)offset, rc, name); ++ ++ out: ++ return rc; ++} ++ ++/* ------------------------------------------------------------------ */ ++ ++struct kexec_segment { ++ const void *buf; ++ size_t bufsz; ++ const void *mem; ++ size_t memsz; ++}; ++ ++struct kexec_segment segments[KEXEC_MAX_SEGMENTS]; ++static unsigned int nsegments; ++static void *entry; ++ ++static void kexec_add_segment(struct xc_dom_image *dom, ++ struct xc_dom_seg *xc_seg, ++ struct kexec_segment *kseg) ++{ ++ if (0 == xc_seg->vend - xc_seg->vstart) ++ return; ++ ++ kseg->buf = xc_dom_seg_to_ptr(dom, xc_seg); ++ kseg->bufsz = xc_seg->vend - xc_seg->vstart; ++ kseg->mem = (void*)(xc_seg->pfn << PAGE_SHIFT); ++ kseg->memsz = kseg->bufsz; ++ if (debug_level) ++ fprintf(stderr," kexec segment: 0x%08lx-0x%08lx (+0x%08lx)\n", ++ (unsigned long)kseg->mem, ++ (unsigned long)(kseg->mem+kseg->memsz-1), ++ (unsigned long)kseg->memsz); ++} ++ ++static void kexec_add_page(struct xc_dom_image *dom, xen_pfn_t pfn, ++ struct kexec_segment *kseg) ++{ ++ if (0 == pfn) ++ return; ++ ++ kseg->buf = xc_dom_pfn_to_ptr(dom, pfn, 1); ++ kseg->bufsz = PAGE_SIZE; ++ kseg->mem = (void*)(pfn << PAGE_SHIFT); ++ kseg->memsz = kseg->bufsz; ++ if (debug_level) ++ fprintf(stderr," kexec page : 0x%08lx-0x%08lx\n", ++ (unsigned long)kseg->mem, ++ (unsigned long)(kseg->mem+kseg->memsz-1)); ++} ++ ++/* ------------------------------------------------------------------ */ ++ ++static const char helper_blob[] = { ++#include "helper/blob.h" ++}; ++ ++static void helper_parse(struct xc_dom_image *dom, ++ struct elf_binary *elf) ++{ ++ if (debug_level) ++ fprintf(stderr, "%s\n", __FUNCTION__); ++ elf_init(elf, helper_blob, sizeof(helper_blob)); ++ if (debug_level) ++ elf_set_logfile(elf, stderr, debug_level); ++ elf_parse_binary(elf); ++ elf->pstart = elf->pstart & PAGE_MASK; ++ elf->pend = (elf->pend + PAGE_SIZE - 1) & PAGE_MASK; ++ ++ dom->extra_pages = (elf->pend - elf->pstart) >> PAGE_SHIFT; ++} ++ ++static void *helper_load(struct xc_dom_image *dom, ++ struct elf_binary *elf) ++{ ++ struct xc_dom_seg seg; ++ uint64_t entry; ++ ++ if (debug_level) ++ fprintf(stderr, "%s\n", __FUNCTION__); ++ ++ xc_dom_alloc_segment(dom, &seg, "kexec", 0, elf->pend - elf->pstart); ++ elf->dest = xc_dom_seg_to_ptr(dom, &seg); ++ elf->reloc_offset = seg.vstart - dom->parms.virt_base - elf->pstart; ++ if (debug_level) ++ fprintf(stderr,"%s: relocation offset: 0x%" PRIx64 "\n", ++ __FUNCTION__, elf->reloc_offset); ++ ++ if (NULL == elf->dest) ++ goto err; ++ elf_load_binary(elf); ++ if (-1 == elf_reloc(elf)) ++ goto err; ++ kexec_add_segment(dom, &seg, &segments[nsegments++]); ++ ++ entry = elf_uval(elf, elf->ehdr, e_entry); ++ return (void*)((intptr_t)(entry + elf->reloc_offset)); ++ ++ err: ++ exit(1); ++} ++ ++static void* ptr_symbol(struct elf_binary *elf, const char *symbol) ++{ ++ unsigned long addr; ++ ++ addr = elf_lookup_addr(elf, symbol); ++ if (-1 == addr) ++ exit(1); ++ return elf_get_ptr(elf, addr); ++} ++ ++static void helper_pass_info(struct xc_dom_image *dom, struct elf_binary *elf) ++{ ++ struct vcpu_guest_context ctxt; ++ struct vcpu_guest_context *vcpu; ++ unsigned long *addr; ++ void *page; ++ ++ if (debug_level) ++ fprintf(stderr, "%s\n", __FUNCTION__); ++ dom->arch_hooks->vcpu(dom, &ctxt); ++ vcpu = ptr_symbol(elf, "vcpu"); ++ *vcpu = ctxt; ++ addr = ptr_symbol(elf, "virt_base"); ++ *addr = dom->parms.virt_base; ++ addr = ptr_symbol(elf, "virt_hypercall"); ++ *addr = dom->parms.virt_hypercall; ++#if defined(__i386__) ++ addr = ptr_symbol(elf, "pae_paging"); ++ *addr = dom->parms.pae; ++#endif ++ addr = ptr_symbol(elf, "debug_level"); ++ *addr = debug_level; ++ page = ptr_symbol(elf, "hypercall_page"); ++ memcpy(page, hypercall_page, PAGE_SIZE); ++} ++ ++/* ------------------------------------------------------------------ */ ++ ++static char *kernel_name = "/boot/vmlinuz-xen"; ++static char *ramdisk_name; ++static char *cmdline; ++static char *features; // = "auto_translated_physmap"; ++static int do_exec = 0; ++static int do_load = 1; ++static int do_type = 0; ++ ++static void usage(FILE *fp) ++{ ++ fprintf(fp, ++ "\n" ++ "This is a xen kexec loader.\n" ++ "\n" ++ "usage: xen-kexec [ options ]\n" ++ "options:\n" ++ " -h print this text\n" ++ " -d enable debug messages\n" ++ " -e boot loaded kernel [%s]\n" ++ " -l load kernel [%s]\n" ++ " -k kernel image [%s]\n" ++ " -i initrd [%s]\n" ++ " -c kernel command line [%s]\n" ++ " -f xen features [%s]\n" ++ " -t print kernel type\n" ++ "\n" ++ "(c) 2006 Gerd Hoffmann \n", ++ do_exec ? "yes" : "no", ++ do_load ? "yes" : "no", ++ kernel_name, ramdisk_name, ++ cmdline ? : "-", ++ features ? : "-"); ++} ++ ++static void print_type(char *filename) ++{ ++ struct xc_dom_image *dom; ++ ++ dom = xc_dom_allocate(cmdline, features); ++ if (0 != xc_dom_kernel_file(dom, filename)) { ++ fprintf(stderr, "can't open %s: %s\n", filename, strerror(errno)); ++ goto done; ++ } ++ if (0 != xc_dom_parse_image(dom)) { ++ printf("unknown-kernel\n"); ++ goto done; ++ } ++#if defined(__i386__) || defined(__x86_64__) ++ if (NULL == dom->parms.elf_note_start && NULL == dom->parms.guest_info) { ++ printf("other-elf-kernel\n"); ++ goto done; ++ } ++#endif ++ printf("%s\n", dom->guest_type); ++ ++ done: ++ xc_dom_release(dom); ++} ++ ++int main(int argc, char *argv[]) ++{ ++ struct xc_dom_image *dom = NULL; ++ struct elf_binary helper; ++ int fd,rc,c,xc; ++ ++ /* figure defaults */ ++ fd = open("/proc/cmdline", O_RDONLY); ++ if (-1 != fd) { ++ cmdline = malloc(1024); ++ rc = read(fd,cmdline,1024); ++ cmdline[rc-1] = 0; ++ close(fd); ++ } ++ ++ /* parse args */ ++ for (;;) { ++ if (-1 == (c = getopt(argc, argv, "hdletk:i:c:f:"))) ++ break; ++ switch (c) { ++ case 'k': ++ kernel_name = optarg; ++ break; ++ case 'i': ++ if (strlen(optarg)) ++ ramdisk_name = optarg; ++ else ++ ramdisk_name = NULL; ++ break; ++ case 'c': ++ cmdline = optarg; ++ break; ++ case 'f': ++ features = optarg; ++ break; ++ case 'd': ++ debug_level++; ++ break; ++ ++ case 'e': ++ do_exec = 1; ++ do_load = 0; ++ do_type = 0; ++ break; ++ case 'l': ++ do_exec = 0; ++ do_load = 1; ++ do_type = 0; ++ break; ++ case 't': ++ do_exec = 0; ++ do_load = 0; ++ do_type = 1; ++ break; ++ ++ case 'h': ++ usage(stdout); ++ exit(0); ++ default: ++ usage(stderr); ++ exit(1); ++ } ++ } ++ ++ if (do_exec) { ++ kexec_reboot(); ++ perror("kexec_reboot"); ++ exit(1); ++ } ++ ++ /* logging */ ++ if (debug_level) ++ xc_dom_logfile = stderr; ++ ++ if (do_type) { ++ print_type(kernel_name); ++ exit(0); ++ } ++ ++ if (!do_load) ++ exit(0); ++ ++ xc = xc_interface_open(); ++ if (-1 == xc) ++ exit(1); ++ ++ /* get info from kernel */ ++ if (kernel_core_by_name(hypercall_page, "hypercall_page", PAGE_SIZE) <= 0) ++ goto out; ++ if (kernel_core_by_name(&max_pfn, "max_pfn", sizeof(max_pfn)) <= 0) ++ goto out; ++ if (kernel_core_by_name(&xen_start_info, "xen_start_info", sizeof(xen_start_info)) <= 0) ++ goto out; ++ if (kernel_core_by_addr(&start_info, xen_start_info, sizeof(start_info)) <= 0) ++ goto out; ++ ++ /* build image */ ++ dom = xc_dom_allocate(cmdline, features); ++ dom->xen_version = xc_version(xc, XENVER_version, NULL); ++ strcpy(dom->xen_caps, start_info.magic); ++ ++ if (0 != (rc = xc_dom_kernel_file(dom, kernel_name))) ++ goto out; ++ if (ramdisk_name && strlen(ramdisk_name)) ++ if (0 != (rc = xc_dom_ramdisk_file(dom, ramdisk_name))) ++ goto out; ++ if (0 != (rc = xc_dom_parse_image(dom))) ++ goto out; ++ if (0 != strcmp(start_info.magic, dom->guest_type)) { ++ fprintf(stderr,"incompatible kernel (need guest_type \"%s\")\n", ++ start_info.magic); ++ goto out; ++ } ++ helper_parse(dom, &helper); ++ ++ if (0 != (rc = xc_dom_mem_init(dom, max_pfn >> (20 - PAGE_SHIFT)))) ++ goto out; ++ if (0 != (rc = xc_dom_build_image(dom))) ++ goto out; ++ entry = helper_load(dom, &helper); ++ if (0 != (rc = dom->arch_hooks->setup_pgtables(dom))) ++ goto out; ++ dom->arch_hooks->start_info(dom); ++ ++ /* setup kexec structs */ ++ kexec_add_segment(dom, &dom->kernel_seg, &segments[nsegments++]); ++ kexec_add_segment(dom, &dom->ramdisk_seg, &segments[nsegments++]); ++ kexec_add_segment(dom, &dom->p2m_seg, &segments[nsegments++]); ++ kexec_add_page(dom, dom->start_info_pfn, &segments[nsegments++]); ++ kexec_add_segment(dom, &dom->pgtables_seg, &segments[nsegments++]); ++ ++ dom->flags = start_info.flags; ++ dom->console_evtchn = start_info.console.domU.evtchn; ++ dom->xenstore_evtchn = start_info.store_evtchn; ++ ++ /* setup helper code */ ++ helper_pass_info(dom, &helper); ++ ++ rc = kexec_load(entry, nsegments, segments, 0); ++ if (0 != rc) { ++ perror("kexec_load"); ++ exit(1); ++ } ++ if (debug_level) ++ fprintf(stderr,"kexec_load ok [%p]\n", entry); ++ ++ xc_dom_release(dom); ++ exit(0); ++ ++ out: ++ if (dom) ++ xc_dom_release(dom); ++ exit(1); ++} diff --git a/vgacon-50-lines.patch b/vgacon-50-lines.patch new file mode 100644 index 0000000..698eaa4 --- /dev/null +++ b/vgacon-50-lines.patch @@ -0,0 +1,44 @@ +Index: xen-3.0.4-testing/xen/drivers/video/vga.c +=================================================================== +--- xen-3.0.4-testing.orig/xen/drivers/video/vga.c ++++ xen-3.0.4-testing/xen/drivers/video/vga.c +@@ -557,7 +557,7 @@ static int vga_load_font(const struct fo + + static int vgacon_enabled = 0; + static int vgacon_keep = 0; +-static int vgacon_lines = 25; ++static int vgacon_lines = 50; + static const struct font_desc *font; + + static int xpos, ypos; +@@ -609,6 +609,8 @@ void vga_init(void) + vgacon_keep = 1; + else if ( strncmp(p, "text-80x", 8) == 0 ) + vgacon_lines = simple_strtoul(p + 8, NULL, 10); ++ else if ( strncmp(p, "text", 4) == 0 && p[4] != '-' ) ++ vgacon_lines = 0; + } + + video = setup_vga(); +@@ -625,17 +627,18 @@ void vga_init(void) + case 34: + font = &font_vga_8x14; + break; ++ default: ++ vgacon_lines = 50; + case 43: + case 50: + case 60: + font = &font_vga_8x8; + break; +- default: +- vgacon_lines = 25; ++ case 0: + break; + } + +- if ( (font != NULL) && (vga_load_font(font, vgacon_lines) < 0) ) ++ if ( (font == NULL) || (vga_load_font(font, vgacon_lines) < 0) ) + { + vgacon_lines = 25; + font = NULL; diff --git a/vgacon-keep.patch b/vgacon-keep.patch new file mode 100644 index 0000000..2aa6bad --- /dev/null +++ b/vgacon-keep.patch @@ -0,0 +1,113 @@ +Index: 2007-01-08/xen/drivers/video/vga.c +=================================================================== +--- 2007-01-08.orig/xen/drivers/video/vga.c 2007-01-11 17:41:46.000000000 +0100 ++++ 2007-01-08/xen/drivers/video/vga.c 2007-01-11 17:42:35.000000000 +0100 +@@ -556,7 +556,6 @@ static int vga_load_font(const struct fo + */ + + static int vgacon_enabled = 0; +-static int vgacon_keep = 0; + static int vgacon_lines = 50; + static const struct font_desc *font; + +@@ -576,13 +575,16 @@ string_param("vga", opt_vga); + void vga_init(void) + { + char *p; ++ int keep = 0; + + for ( p = opt_vga; p != NULL; p = strchr(p, ',') ) + { + if ( *p == ',' ) + p++; + if ( strncmp(p, "keep", 4) == 0 ) +- vgacon_keep = 1; ++ keep = 1; ++ else if ( strncmp(p, "yield", 5) == 0 ) ++ keep = -1; + else if ( strncmp(p, "text-80x", 8) == 0 ) + vgacon_lines = simple_strtoul(p + 8, NULL, 10); + else if ( strncmp(p, "text", 4) == 0 && p[4] != '-' ) +@@ -627,21 +629,48 @@ void vga_init(void) + /* Disable cursor. */ + vga_wcrt(vgabase, VGA_CRTC_CURSOR_START, 0x20); + +- vgacon_enabled = 1; ++ vgacon_enabled = 3 + keep; + } + + void vga_endboot(void) + { ++ static const char *const str[] = ++ { ++ "relinquishing", ++ "auto-sensing", ++ "keeping" ++ }; ++ + if ( !vgacon_enabled ) + return; + +- if ( !vgacon_keep ) +- vgacon_enabled = 0; ++ vgacon_enabled -= 2; ++ BUG_ON(vgacon_enabled < 0 || vgacon_enabled > 2); + +- printk("Xen is %s VGA console.\n", +- vgacon_keep ? "keeping" : "relinquishing"); ++ printk("Xen is %s VGA console.\n", str[vgacon_enabled]); + } + ++static int gfx_vga(void) ++{ ++ unsigned char idx, data; ++ ++ idx = vga_r(vgabase, VGA_GFX_I); ++ data = vga_rgfx(vgabase, VGA_GFX_MISC); ++ vga_w(vgabase, VGA_GFX_I, idx); ++ ++ if ( data & 0x01 ) ++ return 1; ++ ++ /* Unfortunately many cards don't reflect their mode in the GDC ++ * miscellaneous register, bit 0 (and even fewer reflect it in the ++ * ATC mode control register, bit 0). Therefore we further check ++ * horizontal display width against our original setting. */ ++ idx = vga_r(vgabase, VGA_CRT_IC); ++ data = vga_rcrt(vgabase, VGA_CRTC_H_DISP); ++ vga_w(vgabase, VGA_CRT_IC, idx); ++ ++ return data != COLUMNS - 1; ++} + + static void put_newline(void) + { +@@ -659,14 +688,25 @@ static void put_newline(void) + + void vga_putchar(int c) + { +- if ( !vgacon_enabled ) ++ static int vga_in_gfx = -1; ++ ++ switch ( vgacon_enabled ) ++ { ++ case 0: + return; ++ case 1: ++ if ( vga_in_gfx < 0 ) ++ vga_in_gfx = gfx_vga(); ++ break; ++ } + + if ( c == '\n' ) + { +- put_newline(); ++ if ( vga_in_gfx <= 0 ) ++ put_newline(); ++ vga_in_gfx = -1; + } +- else ++ else if ( vga_in_gfx <= 0 ) + { + if ( xpos >= COLUMNS ) + put_newline(); diff --git a/x86-extra-trap-info.patch b/x86-extra-trap-info.patch new file mode 100644 index 0000000..553baf9 --- /dev/null +++ b/x86-extra-trap-info.patch @@ -0,0 +1,89 @@ +Index: 2006-12-05/xen/arch/x86/x86_32/entry.S +=================================================================== +--- 2006-12-05.orig/xen/arch/x86/x86_32/entry.S 2006-12-01 10:44:36.000000000 +0100 ++++ 2006-12-05/xen/arch/x86/x86_32/entry.S 2006-12-08 14:24:54.000000000 +0100 +@@ -382,21 +382,33 @@ nvm86_3:/* Rewrite our stack frame and r + movb $0,TRAPBOUNCE_flags(%edx) + ret + .section __ex_table,"a" +- .long FLT6,domain_crash_synchronous , FLT7,domain_crash_synchronous +- .long FLT8,domain_crash_synchronous , FLT9,domain_crash_synchronous +- .long FLT10,domain_crash_synchronous , FLT11,domain_crash_synchronous +- .long FLT12,domain_crash_synchronous , FLT13,domain_crash_synchronous +- .long FLT14,domain_crash_synchronous , FLT15,domain_crash_synchronous +- .long FLT16,domain_crash_synchronous , FLT17,domain_crash_synchronous +- .long FLT18,domain_crash_synchronous , FLT19,domain_crash_synchronous +- .long FLT20,domain_crash_synchronous , FLT21,domain_crash_synchronous +- .long FLT22,domain_crash_synchronous , FLT23,domain_crash_synchronous +- .long FLT24,domain_crash_synchronous , FLT25,domain_crash_synchronous ++ .long FLT6,domain_crash_synchronous , FLT7,domain_crash_page_fault ++ .long FLT8,domain_crash_page_fault_4 , FLT9,domain_crash_page_fault_8 ++ .long FLT10,domain_crash_page_fault_12, FLT11,domain_crash_page_fault ++ .long FLT12,domain_crash_page_fault_4 , FLT13,domain_crash_synchronous ++ .long FLT14,domain_crash_page_fault , FLT15,domain_crash_page_fault_4 ++ .long FLT16,domain_crash_page_fault_8 , FLT17,domain_crash_page_fault ++ .long FLT18,domain_crash_page_fault , FLT19,domain_crash_page_fault_4 ++ .long FLT20,domain_crash_page_fault_8 , FLT21,domain_crash_page_fault_12 ++ .long FLT22,domain_crash_page_fault , FLT23,domain_crash_page_fault_4 ++ .long FLT24,domain_crash_page_fault_8 , FLT25,domain_crash_page_fault_12 + .previous + ++.section .rodata,"a" + domain_crash_synchronous_string: + .asciz "domain_crash_sync called from entry.S (%lx)\n" ++.previous + ++domain_crash_page_fault_12: ++ addl $4,%esi ++domain_crash_page_fault_8: ++ addl $4,%esi ++domain_crash_page_fault_4: ++ addl $4,%esi ++domain_crash_page_fault: ++ pushl %esi ++ call show_page_walk ++ addl $4,%esp + domain_crash_synchronous: + pushl $domain_crash_synchronous_string + call printk +Index: 2006-12-05/xen/arch/x86/x86_64/entry.S +=================================================================== +--- 2006-12-05.orig/xen/arch/x86/x86_64/entry.S 2006-12-01 10:44:36.000000000 +0100 ++++ 2006-12-05/xen/arch/x86/x86_64/entry.S 2006-12-08 14:24:54.000000000 +0100 +@@ -308,17 +308,30 @@ FLT13: movq %rax,(%rsi) + movb $0,TRAPBOUNCE_flags(%rdx) + ret + .section __ex_table,"a" +- .quad FLT2,domain_crash_synchronous , FLT3,domain_crash_synchronous +- .quad FLT4,domain_crash_synchronous , FLT5,domain_crash_synchronous +- .quad FLT6,domain_crash_synchronous , FLT7,domain_crash_synchronous +- .quad FLT8,domain_crash_synchronous , FLT9,domain_crash_synchronous +- .quad FLT10,domain_crash_synchronous , FLT11,domain_crash_synchronous +- .quad FLT12,domain_crash_synchronous , FLT13,domain_crash_synchronous ++ .quad FLT2,domain_crash_page_fault_32, FLT3,domain_crash_page_fault_24 ++ .quad FLT4,domain_crash_page_fault_8 , FLT5,domain_crash_page_fault_16 ++ .quad FLT6,domain_crash_page_fault , FLT7,domain_crash_page_fault ++ .quad FLT8,domain_crash_page_fault_24, FLT9,domain_crash_page_fault_16 ++ .quad FLT10,domain_crash_page_fault_8 , FLT11,domain_crash_page_fault ++ .quad FLT12,domain_crash_page_fault_8 , FLT13,domain_crash_page_fault + .previous + ++.section .rodata,"a" + domain_crash_synchronous_string: + .asciz "domain_crash_sync called from entry.S\n" ++.previous + ++domain_crash_page_fault_32: ++ addq $8,%rsi ++domain_crash_page_fault_24: ++ addq $8,%rsi ++domain_crash_page_fault_16: ++ addq $8,%rsi ++domain_crash_page_fault_8: ++ addq $8,%rsi ++domain_crash_page_fault: ++ movq %rsi,%rdi ++ call show_page_walk + domain_crash_synchronous: + # Get out of the guest-save area of the stack. + GET_GUEST_REGS(%rax) diff --git a/x86-mm-simplify.patch b/x86-mm-simplify.patch new file mode 100644 index 0000000..3e58bd2 --- /dev/null +++ b/x86-mm-simplify.patch @@ -0,0 +1,56 @@ +Replace mfn_to_page(lXe_get_pfn()) by lXe_get_page(). + +However, what I got surprised by while looking for all of these is that +ptwr_emulated_update() uses gmfn_to_mfn() on the pte loaded from the +emulation context, while ptwr_do_page_fault() doesn't on the pte stored +into that context. Shouldn't these two be symmetric? + +Index: 2007-01-08/xen/arch/x86/mm.c +=================================================================== +--- 2007-01-08.orig/xen/arch/x86/mm.c 2007-01-11 15:33:22.000000000 +0100 ++++ 2007-01-08/xen/arch/x86/mm.c 2007-01-12 17:25:55.000000000 +0100 +@@ -794,7 +794,7 @@ static void put_page_from_l2e(l2_pgentry + { + if ( (l2e_get_flags(l2e) & _PAGE_PRESENT) && + (l2e_get_pfn(l2e) != pfn) ) +- put_page_and_type(mfn_to_page(l2e_get_pfn(l2e))); ++ put_page_and_type(l2e_get_page(l2e)); + } + + +@@ -803,7 +803,7 @@ static void put_page_from_l3e(l3_pgentry + { + if ( (l3e_get_flags(l3e) & _PAGE_PRESENT) && + (l3e_get_pfn(l3e) != pfn) ) +- put_page_and_type(mfn_to_page(l3e_get_pfn(l3e))); ++ put_page_and_type(l3e_get_page(l3e)); + } + #endif + +@@ -812,7 +812,7 @@ static void put_page_from_l4e(l4_pgentry + { + if ( (l4e_get_flags(l4e) & _PAGE_PRESENT) && + (l4e_get_pfn(l4e) != pfn) ) +- put_page_and_type(mfn_to_page(l4e_get_pfn(l4e))); ++ put_page_and_type(l4e_get_page(l4e)); + } + #endif + +@@ -3365,7 +3365,6 @@ int ptwr_do_page_fault(struct vcpu *v, u + struct cpu_user_regs *regs) + { + struct domain *d = v->domain; +- unsigned long pfn; + struct page_info *page; + l1_pgentry_t pte; + struct ptwr_emulate_ctxt ptwr_ctxt; +@@ -3379,8 +3378,7 @@ int ptwr_do_page_fault(struct vcpu *v, u + guest_get_eff_l1e(v, addr, &pte); + if ( !(l1e_get_flags(pte) & _PAGE_PRESENT) ) + goto bail; +- pfn = l1e_get_pfn(pte); +- page = mfn_to_page(pfn); ++ page = l1e_get_page(pte); + + /* We are looking only for read-only mappings of p.t. pages. */ + if ( ((l1e_get_flags(pte) & (_PAGE_PRESENT|_PAGE_RW)) != _PAGE_PRESENT) || diff --git a/x86-ptwr_emulate.patch b/x86-ptwr_emulate.patch new file mode 100644 index 0000000..3da0f92 --- /dev/null +++ b/x86-ptwr_emulate.patch @@ -0,0 +1,33 @@ +Index: 2007-01-31/xen/arch/x86/mm.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/mm.c 2007-01-31 09:42:10.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/mm.c 2007-01-31 09:43:38.000000000 +0100 +@@ -3248,14 +3248,15 @@ static int ptwr_emulated_update( + { + if ( (CONFIG_PAGING_LEVELS == 3 || IS_COMPAT(d)) && + (bytes == 4) && ++ (addr & 4) && + !do_cmpxchg && + (l1e_get_flags(nl1e) & _PAGE_PRESENT) ) + { + /* +- * If this is a half-write to a PAE PTE then we assume that the +- * guest has simply got the two writes the wrong way round. We +- * zap the PRESENT bit on the assumption the bottom half will be +- * written immediately after we return to the guest. ++ * If this is an upper half write to a PAE PTE then we assume ++ * that the guest has simply got the two writes the wrong way ++ * round. We zap the PRESENT bit on the assumption the bottom ++ * half will be written immediately after we return to the guest. + */ + MEM_LOG("ptwr_emulate: fixing up invalid PAE PTE %"PRIpte, + l1e_get_intpte(nl1e)); +@@ -3387,7 +3388,7 @@ int ptwr_do_page_fault(struct vcpu *v, u + (page_get_owner(page) != d) ) + goto bail; + +- ptwr_ctxt.ctxt.regs = guest_cpu_user_regs(); ++ ptwr_ctxt.ctxt.regs = regs; + ptwr_ctxt.ctxt.mode = !IS_COMPAT(d) ? X86EMUL_MODE_HOST : X86EMUL_MODE_PROT32; + ptwr_ctxt.cr2 = addr; + ptwr_ctxt.pte = pte; diff --git a/x86_emulate.patch b/x86_emulate.patch new file mode 100644 index 0000000..bc8c966 --- /dev/null +++ b/x86_emulate.patch @@ -0,0 +1,554 @@ +Index: 2007-01-31/xen/arch/x86/mm.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/mm.c 2006-12-15 16:33:59.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/mm.c 2007-01-31 09:28:56.000000000 +0100 +@@ -3245,6 +3245,7 @@ static int ptwr_emulated_cmpxchg( + container_of(ctxt, struct ptwr_emulate_ctxt, ctxt)); + } + ++#ifdef __i386__ + static int ptwr_emulated_cmpxchg8b( + enum x86_segment seg, + unsigned long offset, +@@ -3260,13 +3261,16 @@ static int ptwr_emulated_cmpxchg8b( + offset, ((u64)old_hi << 32) | old, ((u64)new_hi << 32) | new, 8, 1, + container_of(ctxt, struct ptwr_emulate_ctxt, ctxt)); + } ++#endif + + static struct x86_emulate_ops ptwr_emulate_ops = { + .read = ptwr_emulated_read, + .insn_fetch = ptwr_emulated_read, + .write = ptwr_emulated_write, + .cmpxchg = ptwr_emulated_cmpxchg, +- .cmpxchg8b = ptwr_emulated_cmpxchg8b ++#ifdef __i386__ ++ .cmpxchg2 = ptwr_emulated_cmpxchg8b ++#endif + }; + + /* Write page fault handler: check if guest is trying to modify a PTE. */ +Index: 2007-01-31/xen/arch/x86/mm/shadow/common.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/mm/shadow/common.c 2007-01-08 14:16:35.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/mm/shadow/common.c 2007-01-31 09:28:56.000000000 +0100 +@@ -276,6 +276,7 @@ hvm_emulate_cmpxchg(enum x86_segment seg + v, addr, old, new, bytes, sh_ctxt); + } + ++#ifdef __i386__ + static int + hvm_emulate_cmpxchg8b(enum x86_segment seg, + unsigned long offset, +@@ -299,13 +300,31 @@ hvm_emulate_cmpxchg8b(enum x86_segment s + return v->arch.shadow.mode->x86_emulate_cmpxchg8b( + v, addr, old_lo, old_hi, new_lo, new_hi, sh_ctxt); + } ++#endif ++ ++static unsigned int ++hvm_stack_word_size(struct x86_emulate_ctxt *ctxt) ++{ ++#ifdef __x86_64__ ++ if ( ctxt->mode == X86EMUL_MODE_PROT64 ) ++ return 8; ++#endif ++ ++ return hvm_get_seg_reg(x86_seg_ss, ++ container_of(ctxt, ++ struct sh_emulate_ctxt, ++ ctxt))->attr.fields.db ? 4 : 2; ++} + + static struct x86_emulate_ops hvm_shadow_emulator_ops = { + .read = hvm_emulate_read, + .insn_fetch = hvm_emulate_insn_fetch, + .write = hvm_emulate_write, + .cmpxchg = hvm_emulate_cmpxchg, +- .cmpxchg8b = hvm_emulate_cmpxchg8b, ++#ifdef __i386__ ++ .cmpxchg2 = hvm_emulate_cmpxchg8b, ++#endif ++ .stksz = hvm_stack_word_size + }; + + static int +@@ -356,6 +375,7 @@ pv_emulate_cmpxchg(enum x86_segment seg, + v, offset, old, new, bytes, sh_ctxt); + } + ++#ifdef __i386__ + static int + pv_emulate_cmpxchg8b(enum x86_segment seg, + unsigned long offset, +@@ -371,13 +391,16 @@ pv_emulate_cmpxchg8b(enum x86_segment se + return v->arch.shadow.mode->x86_emulate_cmpxchg8b( + v, offset, old_lo, old_hi, new_lo, new_hi, sh_ctxt); + } ++#endif + + static struct x86_emulate_ops pv_shadow_emulator_ops = { + .read = pv_emulate_read, + .insn_fetch = pv_emulate_read, + .write = pv_emulate_write, + .cmpxchg = pv_emulate_cmpxchg, +- .cmpxchg8b = pv_emulate_cmpxchg8b, ++#ifdef __i386__ ++ .cmpxchg2 = pv_emulate_cmpxchg8b, ++#endif + }; + + struct x86_emulate_ops *shadow_init_emulation( +Index: 2007-01-31/xen/arch/x86/mm/shadow/multi.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/mm/shadow/multi.c 2007-01-31 09:19:50.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/mm/shadow/multi.c 2007-01-31 09:28:56.000000000 +0100 +@@ -3914,7 +3914,8 @@ sh_x86_emulate_cmpxchg(struct vcpu *v, u + return rv; + } + +-int ++#ifdef __i386__ ++static int + sh_x86_emulate_cmpxchg8b(struct vcpu *v, unsigned long vaddr, + unsigned long old_lo, unsigned long old_hi, + unsigned long new_lo, unsigned long new_hi, +@@ -3950,6 +3951,7 @@ sh_x86_emulate_cmpxchg8b(struct vcpu *v, + shadow_audit_tables(v); + return rv; + } ++#endif + + + /**************************************************************************/ +@@ -4237,7 +4239,9 @@ struct shadow_paging_mode sh_paging_mode + .detach_old_tables = sh_detach_old_tables, + .x86_emulate_write = sh_x86_emulate_write, + .x86_emulate_cmpxchg = sh_x86_emulate_cmpxchg, ++#ifdef __i386__ + .x86_emulate_cmpxchg8b = sh_x86_emulate_cmpxchg8b, ++#endif + .make_monitor_table = sh_make_monitor_table, + .destroy_monitor_table = sh_destroy_monitor_table, + .guest_map_l1e = sh_guest_map_l1e, +Index: 2007-01-31/xen/arch/x86/x86_emulate.c +=================================================================== +--- 2007-01-31.orig/xen/arch/x86/x86_emulate.c 2006-12-13 11:15:54.000000000 +0100 ++++ 2007-01-31/xen/arch/x86/x86_emulate.c 2007-01-31 09:28:56.000000000 +0100 +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #undef cmpxchg + #endif + #include +@@ -371,7 +372,10 @@ do{ __asm__ __volatile__ ( + /* Fetch next part of the instruction being emulated. */ + #define insn_fetch_bytes(_size) \ + ({ unsigned long _x; \ +- rc = ops->insn_fetch(x86_seg_cs, _regs.eip, &_x, (_size), ctxt); \ ++ if ( _regs.eip - ctxt->regs->eip < 16 - (_size) ) \ ++ rc = ops->insn_fetch(x86_seg_cs, _regs.eip, &_x, (_size), ctxt); \ ++ else \ ++ goto cannot_emulate; \ + if ( rc != 0 ) \ + goto done; \ + _regs.eip += (_size); \ +@@ -385,6 +389,14 @@ do{ __asm__ __volatile__ ( + (__ea & ((1UL << (ad_bytes << 3)) - 1))); \ + }) + ++#define truncate_sp() \ ++({ \ ++ if ( !stksz ) \ ++ stksz = !ops->stksz ? ad_default : ops->stksz(ctxt); \ ++ ((stksz == sizeof(unsigned long)) ? _regs.esp : \ ++ (_regs.esp & ((1UL << (stksz << 3)) - 1))); \ ++}) ++ + /* Update address held in a register, based on addressing mode. */ + #define register_address_increment(reg, inc) \ + do { \ +@@ -396,6 +408,18 @@ do { + (((reg) + _inc) & ((1UL << (ad_bytes << 3)) - 1)); \ + } while (0) + ++#define sp_increment(inc) \ ++do { \ ++ int _inc = (inc); /* signed type ensures sign extension to long */ \ ++ if ( !stksz ) \ ++ stksz = !ops->stksz ? ad_default : ops->stksz(ctxt); \ ++ if ( stksz == sizeof(unsigned long) ) \ ++ _regs.esp += _inc; \ ++ else \ ++ _regs.esp = (_regs.esp & ~((1UL << (stksz << 3)) - 1)) | \ ++ ((_regs.esp + _inc) & ((1UL << (stksz << 3)) - 1)); \ ++} while (0) ++ + void * + decode_register( + uint8_t modrm_reg, struct cpu_user_regs *regs, int highbyte_regs) +@@ -446,7 +470,8 @@ x86_emulate_memop( + + uint8_t b, d, sib, sib_index, sib_base, twobyte = 0, rex_prefix = 0; + uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0; +- unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0, i; ++ unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0; ++ unsigned int op_default, ad_default, stksz = 0; + int rc = 0; + struct operand src, dst; + int mode = ctxt->mode; +@@ -458,15 +483,15 @@ x86_emulate_memop( + { + case X86EMUL_MODE_REAL: + case X86EMUL_MODE_PROT16: +- op_bytes = ad_bytes = 2; ++ op_default = op_bytes = ad_default = ad_bytes = 2; + break; + case X86EMUL_MODE_PROT32: +- op_bytes = ad_bytes = 4; ++ op_default = op_bytes = ad_default = ad_bytes = 4; + break; + #ifdef __x86_64__ + case X86EMUL_MODE_PROT64: +- op_bytes = 4; +- ad_bytes = 8; ++ op_default = op_bytes = 4; ++ ad_default = ad_bytes = 8; + break; + #endif + default: +@@ -474,18 +499,18 @@ x86_emulate_memop( + } + + /* Legacy prefixes. */ +- for ( i = 0; i < 8; i++ ) ++ for ( ; ; ) + { + switch ( b = insn_fetch_type(uint8_t) ) + { + case 0x66: /* operand-size override */ +- op_bytes ^= 6; /* switch between 2/4 bytes */ ++ op_bytes = op_default ^ 6; /* switch between 2/4 bytes */ + break; + case 0x67: /* address-size override */ + if ( mode == X86EMUL_MODE_PROT64 ) +- ad_bytes ^= 12; /* switch between 4/8 bytes */ ++ ad_bytes = ad_default ^ 12; /* switch between 4/8 bytes */ + else +- ad_bytes ^= 6; /* switch between 2/4 bytes */ ++ ad_bytes = ad_default ^ 6; /* switch between 2/4 bytes */ + break; + case 0x2e: /* CS override */ + ea_seg = x86_seg_cs; +@@ -508,25 +533,29 @@ x86_emulate_memop( + case 0xf0: /* LOCK */ + lock_prefix = 1; + break; ++ case 0xf2: /* REPNE/REPNZ */ + case 0xf3: /* REP/REPE/REPZ */ + rep_prefix = 1; + break; +- case 0xf2: /* REPNE/REPNZ */ +- break; ++#ifdef __x86_64__ ++ case 0x40 ... 0x4f: ++ if ( mode == X86EMUL_MODE_PROT64 ) ++ { ++ rex_prefix = b; ++ continue; ++ } ++ /* FALLTHRU */ ++#endif + default: + goto done_prefixes; + } ++ rex_prefix = 0; + } + done_prefixes: + + /* REX prefix. */ +- if ( (mode == X86EMUL_MODE_PROT64) && ((b & 0xf0) == 0x40) ) +- { +- rex_prefix = b; +- if ( b & 8 ) /* REX.W */ +- op_bytes = 8; +- b = insn_fetch_type(uint8_t); +- } ++ if ( rex_prefix & 8 ) /* REX.W */ ++ op_bytes = 8; + + /* Opcode byte(s). */ + d = opcode_table[b]; +@@ -598,7 +627,16 @@ x86_emulate_memop( + if ( (modrm_mod == 0) && ((sib_base & 7) == 5) ) + ea_off += insn_fetch_type(int32_t); + else ++ { + ea_off += *(long *)decode_register(sib_base, &_regs, 0); ++ if ( sib_base == 4 && !twobyte && b == 0x8f ) ++ { ++ /* POP to an address with esp as base register. */ ++ if ( mode == X86EMUL_MODE_PROT64 && op_bytes == 4 ) ++ op_bytes = 8; ++ ea_off += op_bytes; ++ } ++ } + } + else + { +@@ -841,12 +879,12 @@ x86_emulate_memop( + break; + case 0x8f: /* pop (sole member of Grp1a) */ + /* 64-bit mode: POP always pops a 64-bit operand. */ +- if ( mode == X86EMUL_MODE_PROT64 ) ++ if ( mode == X86EMUL_MODE_PROT64 && dst.bytes == 4 ) + dst.bytes = 8; +- if ( (rc = ops->read(x86_seg_ss, truncate_ea(_regs.esp), ++ if ( (rc = ops->read(x86_seg_ss, truncate_sp(), + &dst.val, dst.bytes, ctxt)) != 0 ) + goto done; +- register_address_increment(_regs.esp, dst.bytes); ++ sp_increment(dst.bytes); + break; + case 0xc0 ... 0xc1: grp2: /* Grp2 */ + switch ( modrm_reg & 7 ) +@@ -917,15 +955,15 @@ x86_emulate_memop( + break; + case 6: /* push */ + /* 64-bit mode: PUSH always pushes a 64-bit operand. */ +- if ( mode == X86EMUL_MODE_PROT64 ) ++ if ( mode == X86EMUL_MODE_PROT64 && dst.bytes == 4 ) + { + dst.bytes = 8; + if ( (rc = ops->read(dst.mem_seg, dst.mem_off, + &dst.val, 8, ctxt)) != 0 ) + goto done; + } +- register_address_increment(_regs.esp, -dst.bytes); +- if ( (rc = ops->write(x86_seg_ss, truncate_ea(_regs.esp), ++ sp_increment(-dst.bytes); ++ if ( (rc = ops->write(x86_seg_ss, truncate_sp(), + dst.val, dst.bytes, ctxt)) != 0 ) + goto done; + dst.val = dst.orig_val; /* skanky: disable writeback */ +@@ -975,7 +1013,7 @@ x86_emulate_memop( + special_insn: + if ( twobyte ) + goto twobyte_special_insn; +- if ( rep_prefix ) ++ if ( rep_prefix && (b & ~3) != 0xa0 ) + { + if ( _regs.ecx == 0 ) + { +@@ -1119,6 +1157,7 @@ x86_emulate_memop( + case 1: goto bts; + case 2: goto btr; + case 3: goto btc; ++ default: goto cannot_emulate; + } + break; + case 0xbe ... 0xbf: /* movsx */ +@@ -1146,56 +1185,65 @@ x86_emulate_memop( + case 0x0d: /* GrpP (prefetch) */ + case 0x18: /* Grp16 (prefetch/nop) */ + break; +- case 0xc7: /* Grp9 (cmpxchg8b) */ +-#if defined(__i386__) +- { +- unsigned long old_lo, old_hi; +- if ( ((rc = ops->read(ea_seg, ea_off+0, &old_lo, 4, ctxt)) != 0) || +- ((rc = ops->read(ea_seg, ea_off+4, &old_hi, 4, ctxt)) != 0) ) +- goto done; +- if ( (old_lo != _regs.eax) || (old_hi != _regs.edx) ) +- { +- _regs.eax = old_lo; +- _regs.edx = old_hi; +- _regs.eflags &= ~EFLG_ZF; +- } +- else if ( ops->cmpxchg8b == NULL ) +- { +- rc = X86EMUL_UNHANDLEABLE; +- goto done; +- } +- else ++ case 0xc7: /* Grp9 (cmpxchg{8,16}b) */ ++#ifdef __x86_64__ ++ if ( op_bytes != 8 ) + { +- if ( (rc = ops->cmpxchg8b(ea_seg, ea_off, old_lo, old_hi, +- _regs.ebx, _regs.ecx, ctxt)) != 0 ) ++ unsigned long old, new; ++ if ( (rc = ops->read(ea_seg, ea_off, &old, 8, ctxt)) != 0 ) + goto done; +- _regs.eflags |= EFLG_ZF; +- } +- break; +- } +-#elif defined(__x86_64__) +- { +- unsigned long old, new; +- if ( (rc = ops->read(ea_seg, ea_off, &old, 8, ctxt)) != 0 ) +- goto done; +- if ( ((uint32_t)(old>>0) != (uint32_t)_regs.eax) || +- ((uint32_t)(old>>32) != (uint32_t)_regs.edx) ) +- { +- _regs.eax = (uint32_t)(old>>0); +- _regs.edx = (uint32_t)(old>>32); +- _regs.eflags &= ~EFLG_ZF; ++ if ( ((uint32_t)(old>>0) != (uint32_t)_regs.eax) || ++ ((uint32_t)(old>>32) != (uint32_t)_regs.edx) ) ++ { ++ _regs.eax = (uint32_t)(old>>0); ++ _regs.edx = (uint32_t)(old>>32); ++ _regs.eflags &= ~EFLG_ZF; ++ } ++ else ++ { ++ new = (_regs.ecx<<32)|(uint32_t)_regs.ebx; ++ if ( (rc = ops->cmpxchg(ea_seg, ea_off, old, new, 8, ctxt)) != 0 ) ++ goto done; ++ _regs.eflags |= EFLG_ZF; ++ } + } + else ++#endif + { +- new = (_regs.ecx<<32)|(uint32_t)_regs.ebx; +- if ( (rc = ops->cmpxchg(ea_seg, ea_off, old, new, 8, ctxt)) != 0 ) ++ unsigned long old_lo, old_hi; ++ if ( ((rc = ops->read(ea_seg, ea_off, &old_lo, ++ sizeof(old_lo), ctxt)) != 0) || ++ ((rc = ops->read(ea_seg, ea_off+sizeof(old_lo), &old_hi, ++ sizeof(old_hi), ctxt)) != 0) ) ++ goto done; ++ if ( (old_lo != _regs.eax) || (old_hi != _regs.edx) ) ++ { ++ _regs.eax = old_lo; ++ _regs.edx = old_hi; ++ _regs.eflags &= ~EFLG_ZF; ++ } ++ else if ( ops->cmpxchg2 == NULL ) ++ { ++ rc = X86EMUL_UNHANDLEABLE; + goto done; +- _regs.eflags |= EFLG_ZF; ++ } ++#ifdef __x86_64__ ++ else if ( !cpu_has_cmpxchg16b ) ++ { ++ rc = X86EMUL_UNHANDLEABLE; ++ goto done; ++ } ++#endif ++ else ++ { ++ if ( (rc = ops->cmpxchg2(ea_seg, ea_off, old_lo, old_hi, ++ _regs.ebx, _regs.ecx, ctxt)) != 0 ) ++ goto done; ++ _regs.eflags |= EFLG_ZF; ++ } + } + break; + } +-#endif +- } + goto writeback; + + cannot_emulate: +Index: 2007-01-31/xen/include/asm-x86/cpufeature.h +=================================================================== +--- 2007-01-31.orig/xen/include/asm-x86/cpufeature.h 2006-12-13 11:15:56.000000000 +0100 ++++ 2007-01-31/xen/include/asm-x86/cpufeature.h 2007-01-31 09:28:56.000000000 +0100 +@@ -118,6 +118,7 @@ + #define cpu_has_cyrix_arr boot_cpu_has(X86_FEATURE_CYRIX_ARR) + #define cpu_has_centaur_mcr boot_cpu_has(X86_FEATURE_CENTAUR_MCR) + #define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLSH) ++#define cpu_has_cmpxchg16b 0 + #else /* __x86_64__ */ + #define cpu_has_vme 0 + #define cpu_has_de 1 +@@ -140,6 +141,7 @@ + #define cpu_has_cyrix_arr 0 + #define cpu_has_centaur_mcr 0 + #define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLSH) ++#define cpu_has_cmpxchg16b boot_cpu_has(X86_FEATURE_CX16) + #endif + + #endif /* __ASM_I386_CPUFEATURE_H */ +Index: 2007-01-31/xen/include/asm-x86/shadow.h +=================================================================== +--- 2007-01-31.orig/xen/include/asm-x86/shadow.h 2007-01-08 14:16:35.000000000 +0100 ++++ 2007-01-31/xen/include/asm-x86/shadow.h 2007-01-31 09:28:56.000000000 +0100 +@@ -273,12 +273,14 @@ struct shadow_paging_mode { + unsigned long new, + unsigned int bytes, + struct sh_emulate_ctxt *sh_ctxt); ++#ifdef __i386__ + int (*x86_emulate_cmpxchg8b )(struct vcpu *v, unsigned long va, + unsigned long old_lo, + unsigned long old_hi, + unsigned long new_lo, + unsigned long new_hi, + struct sh_emulate_ctxt *sh_ctxt); ++#endif + mfn_t (*make_monitor_table )(struct vcpu *v); + void (*destroy_monitor_table )(struct vcpu *v, mfn_t mmfn); + void * (*guest_map_l1e )(struct vcpu *v, unsigned long va, +Index: 2007-01-31/xen/include/asm-x86/x86_emulate.h +=================================================================== +--- 2007-01-31.orig/xen/include/asm-x86/x86_emulate.h 2006-12-13 11:15:56.000000000 +0100 ++++ 2007-01-31/xen/include/asm-x86/x86_emulate.h 2007-01-31 09:28:56.000000000 +0100 +@@ -39,8 +39,9 @@ enum x86_segment { + * some out-of-band mechanism, unknown to the emulator. The memop signals + * failure by returning X86EMUL_PROPAGATE_FAULT to the emulator, which will + * then immediately bail. +- * 2. Valid access sizes are 1, 2, 4 and 8 bytes. On x86/32 systems only +- * cmpxchg8b_emulated need support 8-byte accesses. ++ * 2. Valid access sizes are 1, 2, 4, 8, and 16 bytes. On x86/32 systems only ++ * cmpxchg2_emulated need support 8-byte accesses. On x86/64 systems only ++ * cmpxchg2_emulated need support 16-byte accesses. + * 3. The emulator cannot handle 64-bit mode emulation on an x86/32 system. + */ + /* Access completed successfully: continue emulation as normal. */ +@@ -110,16 +111,17 @@ struct x86_emulate_ops + struct x86_emulate_ctxt *ctxt); + + /* +- * cmpxchg8b: Emulate an atomic (LOCKed) CMPXCHG8B operation. ++ * cmpxchg2: Emulate an atomic (LOCKed) CMPXCHG{8,16}B operation. + * @old: [IN ] Value expected to be current at @addr. + * @new: [IN ] Value to write to @addr. + * NOTES: +- * 1. This function is only ever called when emulating a real CMPXCHG8B. +- * 2. This function is *never* called on x86/64 systems. +- * 2. Not defining this function (i.e., specifying NULL) is equivalent ++ * 1. This function is only ever called when emulating a real CMPXCHG{8,16}B. ++ * 2. This function is *never* called on x86/64 systems for emulating ++ * CMPXCHG8B. ++ * 3. Not defining this function (i.e., specifying NULL) is equivalent + * to defining a function that always returns X86EMUL_UNHANDLEABLE. + */ +- int (*cmpxchg8b)( ++ int (*cmpxchg2)( + enum x86_segment seg, + unsigned long offset, + unsigned long old_lo, +@@ -127,6 +129,16 @@ struct x86_emulate_ops + unsigned long new_lo, + unsigned long new_hi, + struct x86_emulate_ctxt *ctxt); ++ ++ /* ++ * stksz: Determine the item size of the guest stack. ++ * NOTE: ++ * Not defining this function (i.e., specifying NULL) is equivalent ++ * to defining a function that returns the default address size of ++ * the execution mode (X86EMUL_MODE_xxx). ++ */ ++ unsigned int (*stksz)( ++ struct x86_emulate_ctxt *ctxt); + }; + + struct cpu_user_regs; diff --git a/xen-3.0.3-testing-src.tar.bz2 b/xen-3.0.3-testing-src.tar.bz2 deleted file mode 100644 index c0991cb..0000000 --- a/xen-3.0.3-testing-src.tar.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:50d18f4e082110db27a98ffcd39d98cc12058a6dd89c58a378ce283fa911ba89 -size 4580110 diff --git a/xen-3.0.4-testing-src.tar.bz2 b/xen-3.0.4-testing-src.tar.bz2 new file mode 100644 index 0000000..12b629f --- /dev/null +++ b/xen-3.0.4-testing-src.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed27830300bd6d68d35737d3e8deefe815115f2d165574c8a1f527ee8ec6a606 +size 5383589 diff --git a/xen-bonding.diff b/xen-bonding.diff index 6efc264..945fb6b 100644 --- a/xen-bonding.diff +++ b/xen-bonding.diff @@ -1,8 +1,8 @@ -Index: xen-unstable/tools/examples/network-bridge +Index: xen-3.0.4-testing/tools/examples/network-bridge =================================================================== ---- xen-unstable.orig/tools/examples/network-bridge -+++ xen-unstable/tools/examples/network-bridge -@@ -145,6 +145,21 @@ antispoofing () { +--- xen-3.0.4-testing.orig/tools/examples/network-bridge ++++ xen-3.0.4-testing/tools/examples/network-bridge +@@ -143,6 +143,21 @@ antispoofing () { iptables -A FORWARD -m physdev --physdev-in ${vif0} -j ACCEPT } @@ -24,7 +24,7 @@ Index: xen-unstable/tools/examples/network-bridge # Usage: show_status dev bridge # Print ifconfig and routes. show_status () { -@@ -187,10 +202,11 @@ using loopback.nloopbacks= on the dom +@@ -185,10 +200,11 @@ using loopback.nloopbacks= on the dom create_bridge ${bridge} @@ -38,9 +38,9 @@ Index: xen-unstable/tools/examples/network-bridge transfer_addrs ${netdev} ${vdev} ifdown ${netdev} ip link set ${netdev} name ${pdev} -@@ -205,6 +221,13 @@ using loopback.nloopbacks= on the dom +@@ -203,6 +219,13 @@ using loopback.nloopbacks= on the dom add_to_bridge2 ${bridge} ${pdev} - ip link set ${netdev} up + ip link set ${netdev} up ifup ${hwddev} + elif [ "$BONDING_MASTER" = yes ]; then + ip link set ${bridge} arp on @@ -52,7 +52,7 @@ Index: xen-unstable/tools/examples/network-bridge else # old style without ${vdev} transfer_addrs ${netdev} ${bridge} -@@ -243,6 +266,10 @@ op_stop () { +@@ -241,6 +264,10 @@ op_stop () { ip link set ${pdev} name ${netdev} ifup ${netdev} else diff --git a/xen-bootloader-dryrun.diff b/xen-bootloader-dryrun.diff new file mode 100644 index 0000000..373f14e --- /dev/null +++ b/xen-bootloader-dryrun.diff @@ -0,0 +1,22 @@ +Index: xen-3.0.4-testing/tools/python/xen/xend/XendBootloader.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendBootloader.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendBootloader.py +@@ -22,7 +22,7 @@ from XendLogging import log + from XendError import VmError + + def bootloader(blexec, disk, quiet = False, blargs = '', kernel = '', +- ramdisk = '', kernel_args = ''): ++ ramdisk = '', kernel_args = '', dryrun = False): + """Run the boot loader executable on the given disk and return a + config image. + @param blexec Binary to use as the boot loader +@@ -55,6 +55,8 @@ def bootloader(blexec, disk, quiet = Fal + args = [ blexec ] + if quiet: + args.append("-q") ++ if dryrun: ++ args.append("--dryrun") + args.append("--output=%s" % fifo) + if blargs: + args.extend(shlex.split(blargs)) diff --git a/xen-bootloader-nohang.diff b/xen-bootloader-nohang.diff new file mode 100644 index 0000000..88e4940 --- /dev/null +++ b/xen-bootloader-nohang.diff @@ -0,0 +1,32 @@ +Index: xen-3.0.4-testing/tools/python/xen/xend/XendBootloader.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendBootloader.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendBootloader.py +@@ -70,20 +70,18 @@ def bootloader(blexec, disk, quiet = Fal + + while True: + try: +- r = os.open(fifo, os.O_RDONLY) ++ r = os.open(fifo, os.O_RDONLY, os.O_NONBLOCK) + except OSError, e: + if e.errno == errno.EINTR: + continue + break + ret = "" +- while True: +- select.select([r], [], []) +- s = os.read(r, 1024) +- ret = ret + s +- if len(s) == 0: +- break +- +- os.waitpid(child, 0) ++ while os.waitpid(child, os.WNOHANG) == (0, 0): ++ # Large timeout, because crashed bootloader is a corner case ++ if select.select([r], [], [], 5.0)[0]: ++ s = os.read(r, 1024) ++ ret = ret + s ++ + os.close(r) + os.unlink(fifo) + diff --git a/xen-bootloader-tidy.diff b/xen-bootloader-tidy.diff new file mode 100644 index 0000000..d3363aa --- /dev/null +++ b/xen-bootloader-tidy.diff @@ -0,0 +1,13 @@ +Index: xen-3.0.4-testing/tools/python/xen/xend/XendDomainInfo.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendDomainInfo.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendDomainInfo.py +@@ -1589,7 +1589,7 @@ class XendDomainInfo: + log.info("Unmounting %s from %s." % + (fn, BOOTLOADER_LOOPBACK_DEVICE)) + +- dom0.destroyDevice('tap', '/dev/xvdp') ++ dom0.destroyDevice('tap', BOOTLOADER_LOOPBACK_DEVICE) + + break + diff --git a/xen-changeset.diff b/xen-changeset.diff index 2da4d7e..41b26ba 100644 --- a/xen-changeset.diff +++ b/xen-changeset.diff @@ -1,20 +1,17 @@ -Index: xen-3.0.3-testing/xen/Makefile +Index: xen-3.0.4-testing/xen/Makefile =================================================================== ---- xen-3.0.3-testing.orig/xen/Makefile -+++ xen-3.0.3-testing/xen/Makefile -@@ -3,6 +3,7 @@ - export XEN_VERSION = 3 - export XEN_SUBVERSION = 0 - export XEN_EXTRAVERSION ?= .3-0 +--- xen-3.0.4-testing.orig/xen/Makefile ++++ xen-3.0.4-testing/xen/Makefile +@@ -1,3 +1,4 @@ +export XEN_CHANGESET = unavailable - export XEN_FULLVERSION = $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION) - -include xen-version - + # This is the correct place to edit the build version. + # All other places this is stored (eg. compile.h) should be autogenerated. + export XEN_VERSION = 3 @@ -103,7 +104,7 @@ include/xen/compile.h: include/xen/compi -e 's/@@version@@/$(XEN_VERSION)/g' \ -e 's/@@subversion@@/$(XEN_SUBVERSION)/g' \ -e 's/@@extraversion@@/$(XEN_EXTRAVERSION)/g' \ -- -e 's!@@changeset@@!$(shell ((hg parents || head -n 7 ../ChangeLog || echo date: unavailable) | awk '{FS="changeset:[ ]+"}/^changeset/{CS=$$2};{FS="date:[ ]+"}/^date/{D=$$2}; END {print D, CS}') 2>/dev/null)!g' \ +- -e 's!@@changeset@@!$(shell ((hg parents --template "{date|date} {rev}:{node|short}" >/dev/null && hg parents --template "{date|date} {rev}:{node|short}") || echo "unavailable") 2>/dev/null)!g' \ + -e 's!@@changeset@@!$(XEN_CHANGESET)!g' \ < include/xen/compile.h.in > $@.new tools/figlet/figlet -d tools/figlet Xen $(XEN_FULLVERSION) >> $@.new diff --git a/xen-config.diff b/xen-config.diff new file mode 100644 index 0000000..b24fae5 --- /dev/null +++ b/xen-config.diff @@ -0,0 +1,14 @@ +Index: xen-unstable/Config.mk +=================================================================== +--- xen-unstable.orig/Config.mk ++++ xen-unstable/Config.mk +@@ -70,7 +70,7 @@ ACM_DEFAULT_SECURITY_POLICY ?= ACM_NULL_ + # Optional components + XENSTAT_XENTOP ?= y + VTPM_TOOLS ?= n +-LIBXENAPI_BINDINGS ?= n +-XENFB_TOOLS ?= n ++LIBXENAPI_BINDINGS ?= y ++XENFB_TOOLS ?= y + + -include $(XEN_ROOT)/.config diff --git a/xen-console.diff b/xen-console.diff deleted file mode 100644 index f2288bc..0000000 --- a/xen-console.diff +++ /dev/null @@ -1,63 +0,0 @@ -Subject: video mode detection (161541) - -Charles, attached the promised patch for replacing xen-console.diff. Jan - -Index: xen-unstable/xen/drivers/video/vga.c -=================================================================== ---- xen-unstable.orig/xen/drivers/video/vga.c -+++ xen-unstable/xen/drivers/video/vga.c -@@ -573,6 +573,30 @@ string_param("vga", opt_vga); - #define ATTRIBUTE 7 - #define VIDEO_SIZE (COLUMNS * LINES * 2) - -+static int gfx_vga(void) -+{ -+ unsigned char idx, data; -+ -+ idx = inb(0x3ce); -+ outb(0x06, 0x3ce); -+ data = inb(0x3cf); -+ outb(idx, 0x3ce); -+ -+ if ( data & 0x01 ) -+ return 1; -+ -+ /* Unfortunately many cards don't reflect their mode in the GDC -+ * miscellaneous register, bit 0 (and even fewer reflect it in the -+ * ATC mode control register, bit 0). Therefore we further check -+ * horizontal display width against our original setting. */ -+ idx = inb(0x3d4); -+ outb(0x01, 0x3d4); -+ data = inb(0x3d5); -+ outb(idx, 0x3d4); -+ -+ return data != COLUMNS - 1; -+} -+ - void vga_init(void) - { - char *p; -@@ -656,14 +680,21 @@ static void put_newline(void) - - void vga_putchar(int c) - { -+ static int vga_in_gfx = -1; -+ - if ( !vgacon_enabled ) - return; - -+ if ( vga_in_gfx < 0 ) -+ vga_in_gfx = gfx_vga(); -+ - if ( c == '\n' ) - { -- put_newline(); -+ if ( vga_in_gfx <= 0 ) -+ put_newline(); -+ vga_in_gfx = -1; - } -- else -+ else if ( vga_in_gfx <= 0 ) - { - if ( xpos >= COLUMNS ) - put_newline(); diff --git a/xen-destdir.diff b/xen-destdir.diff index d3ff556..a70280c 100644 --- a/xen-destdir.diff +++ b/xen-destdir.diff @@ -1,8 +1,8 @@ -Index: xen-3.0.3-testing/docs/Makefile +Index: xen-3.0.4-testing/docs/Makefile =================================================================== ---- xen-3.0.3-testing.orig/docs/Makefile -+++ xen-3.0.3-testing/docs/Makefile -@@ -12,8 +12,8 @@ LATEX2HTML := latex2html +--- xen-3.0.4-testing.orig/docs/Makefile ++++ xen-3.0.4-testing/docs/Makefile +@@ -13,8 +13,8 @@ LATEX2HTML := latex2html DOXYGEN := doxygen POD2MAN := pod2man @@ -13,11 +13,37 @@ Index: xen-3.0.3-testing/docs/Makefile DOC_MAN5SRC := $(wildcard man/*.pod.5) DOC_MAN1SRC := $(wildcard man/*.pod.1) -Index: xen-3.0.3-testing/tools/xentrace/Makefile +@@ -87,13 +87,13 @@ distclean: clean + .PHONY: install + install: all + rm -rf $(DESTDIR)$(pkgdocdir) +- $(INSTALL_DIR) $(DESTDIR)$(pkgdocdir) ++ $(INSTALL_DIR) $(DESTDIR)$(pkgdocdir)/html + cp -dR ps $(DESTDIR)$(pkgdocdir) + cp -dR pdf $(DESTDIR)$(pkgdocdir) ++ cp -dR html.done/* $(DESTDIR)$(pkgdocdir)/html + $(INSTALL_DIR) $(DESTDIR)$(mandir) + cp -dR man1 $(DESTDIR)$(mandir) + cp -dR man5 $(DESTDIR)$(mandir) +- [ ! -d html ] || cp -dR html $(DESTDIR)$(pkgdocdir) + + pdf/%.pdf: ps/%.ps + $(INSTALL_DIR) $(@D) +@@ -117,3 +117,9 @@ html/%/index.html: src/%.tex + $(LATEX2HTML) -split 0 -show_section_numbers -toc_depth 3 -nonavigation \ + -numbered_footnotes -local_icons -noinfo -math -dir $(@D) \ + $< 1>/dev/null 2>/dev/null ++ rm -rf html.done/$*/ ++ mkdir -p html.done/$*/ ++ cp html/$*/*.html html/$*/*.css html/$*/*.png html.done/$*/ ++ ln -sf $*.html html.done/$*/index.html ++ rm -rf html/ ++ +Index: xen-3.0.4-testing/tools/xentrace/Makefile =================================================================== ---- xen-3.0.3-testing.orig/tools/xentrace/Makefile -+++ xen-3.0.3-testing/tools/xentrace/Makefile -@@ -43,14 +43,14 @@ install: build +--- xen-3.0.4-testing.orig/tools/xentrace/Makefile ++++ xen-3.0.4-testing/tools/xentrace/Makefile +@@ -38,14 +38,14 @@ install: build [ -d $(DESTDIR)/usr/bin ] || $(INSTALL_DIR) $(DESTDIR)/usr/bin [ -z "$(LIBBIN)" ] || [ -d $(DESTDIR)/usr/$(LIBDIR)/xen/bin ] || \ $(INSTALL_DIR) $(DESTDIR)/usr/$(LIBDIR)/xen/bin @@ -38,11 +64,11 @@ Index: xen-3.0.3-testing/tools/xentrace/Makefile .PHONY: clean clean: -Index: xen-3.0.3-testing/tools/examples/Makefile +Index: xen-3.0.4-testing/tools/examples/Makefile =================================================================== ---- xen-3.0.3-testing.orig/tools/examples/Makefile -+++ xen-3.0.3-testing/tools/examples/Makefile -@@ -43,18 +43,6 @@ XEN_HOTPLUG_SCRIPTS = xen-backend.agent +--- xen-3.0.4-testing.orig/tools/examples/Makefile ++++ xen-3.0.4-testing/tools/examples/Makefile +@@ -38,18 +38,6 @@ XEN_HOTPLUG_SCRIPTS = xen-backend.agent UDEV_RULES_DIR = /etc/udev UDEV_RULES = xen-backend.rules @@ -61,7 +87,7 @@ Index: xen-3.0.3-testing/tools/examples/Makefile .PHONY: all all: -@@ -62,15 +50,15 @@ all: +@@ -57,15 +45,15 @@ all: build: .PHONY: install @@ -80,7 +106,7 @@ Index: xen-3.0.3-testing/tools/examples/Makefile .PHONY: install-configs install-configs: $(XEN_CONFIGS) -@@ -111,9 +99,7 @@ install-udev: +@@ -106,9 +94,7 @@ install-udev: $(INSTALL_DIR) $(DESTDIR)$(UDEV_RULES_DIR)/rules.d for i in $(UDEV_RULES); \ do \ @@ -91,10 +117,10 @@ Index: xen-3.0.3-testing/tools/examples/Makefile done .PHONY: clean -Index: xen-3.0.3-testing/tools/security/Makefile +Index: xen-3.0.4-testing/tools/security/Makefile =================================================================== ---- xen-3.0.3-testing.orig/tools/security/Makefile -+++ xen-3.0.3-testing/tools/security/Makefile +--- xen-3.0.4-testing.orig/tools/security/Makefile ++++ xen-3.0.4-testing/tools/security/Makefile @@ -73,9 +73,9 @@ install: all $(ACM_CONFIG_FILE) $(INSTALL_DIR) -p $(DESTDIR)$(ACM_SECGEN_CGIDIR) $(INSTALL_PROG) -p $(ACM_INST_CGI) $(DESTDIR)$(ACM_SECGEN_CGIDIR) @@ -107,45 +133,41 @@ Index: xen-3.0.3-testing/tools/security/Makefile endif else .PHONY: all -Index: xen-3.0.3-testing/tools/pygrub/Makefile +Index: xen-3.0.4-testing/tools/pygrub/Makefile =================================================================== ---- xen-3.0.3-testing.orig/tools/pygrub/Makefile -+++ xen-3.0.3-testing/tools/pygrub/Makefile +--- xen-3.0.4-testing.orig/tools/pygrub/Makefile ++++ xen-3.0.4-testing/tools/pygrub/Makefile @@ -15,7 +15,7 @@ install: all - $(INSTALL_DIR) -p $(DESTDIR)/var/lib/xen + $(INSTALL_DIR) -p $(DESTDIR)/var/run/xend/boot else install: all -- CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)" -+ CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)" --prefix="/usr" - $(INSTALL_DIR) -p $(DESTDIR)/var/lib/xen +- CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)" ++ CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)" --prefix="/usr" + $(INSTALL_DIR) -p $(DESTDIR)/var/run/xend/boot endif -Index: xen-3.0.3-testing/tools/python/Makefile +Index: xen-3.0.4-testing/tools/python/Makefile =================================================================== ---- xen-3.0.3-testing.orig/tools/python/Makefile -+++ xen-3.0.3-testing/tools/python/Makefile +--- xen-3.0.4-testing.orig/tools/python/Makefile ++++ xen-3.0.4-testing/tools/python/Makefile @@ -14,7 +14,7 @@ install: all - CFLAGS="$(CFLAGS)" python setup.py install --home="$(DESTDIR)/usr" --prefix="" --force + CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --home="$(DESTDIR)/usr" --prefix="" --force else install: all -- CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)" --force -+ CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)" --prefix="/usr" --force +- CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)" --force ++ CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)" --prefix="/usr" --force endif .PHONY: test -Index: xen-3.0.3-testing/xen/Makefile +Index: xen-3.0.4-testing/tools/Makefile =================================================================== ---- xen-3.0.3-testing.orig/xen/Makefile -+++ xen-3.0.3-testing/xen/Makefile -@@ -31,8 +31,11 @@ _install: $(TARGET).gz - $(INSTALL_DATA) $(TARGET)-syms $(DESTDIR)/boot/$(notdir $(TARGET))-syms-$(XEN_FULLVERSION) - [ -d $(DESTDIR)/usr/include/xen/io ] || \ - $(INSTALL_DIR) $(DESTDIR)/usr/include/xen/io -+ [ -d $(DESTDIR)/usr/include/xen/hvm ] || \ -+ $(INSTALL_DIR) $(DESTDIR)/usr/include/xen/hvm - $(INSTALL_DATA) include/public/*.h $(DESTDIR)/usr/include/xen - $(INSTALL_DATA) include/public/io/*.h $(DESTDIR)/usr/include/xen/io -+ $(INSTALL_DATA) include/public/hvm/*.h $(DESTDIR)/usr/include/xen/hvm - $(INSTALL_DATA) include/public/COPYING $(DESTDIR)/usr/include/xen +--- xen-3.0.4-testing.orig/tools/Makefile ++++ xen-3.0.4-testing/tools/Makefile +@@ -25,7 +25,6 @@ SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen + # These don't cross-compile + ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH)) + SUBDIRS-y += python +-SUBDIRS-y += pygrub + endif - .PHONY: _debug + .PHONY: all diff --git a/xen-docs.diff b/xen-docs.diff deleted file mode 100644 index 92479fd..0000000 --- a/xen-docs.diff +++ /dev/null @@ -1,30 +0,0 @@ -Index: xen-3.0.3-testing/docs/Makefile -=================================================================== ---- xen-3.0.3-testing.orig/docs/Makefile -+++ xen-3.0.3-testing/docs/Makefile -@@ -86,13 +86,13 @@ distclean: clean - .PHONY: install - install: all - rm -rf $(DESTDIR)$(pkgdocdir) -- $(INSTALL_DIR) $(DESTDIR)$(pkgdocdir) -+ $(INSTALL_DIR) $(DESTDIR)$(pkgdocdir)/html - cp -dR ps $(DESTDIR)$(pkgdocdir) - cp -dR pdf $(DESTDIR)$(pkgdocdir) -+ cp -dR html.done/* $(DESTDIR)$(pkgdocdir)/html - $(INSTALL_DIR) $(DESTDIR)$(mandir) - cp -dR man1 $(DESTDIR)$(mandir) - cp -dR man5 $(DESTDIR)$(mandir) -- [ ! -d html ] || cp -dR html $(DESTDIR)$(pkgdocdir) - - pdf/%.pdf: ps/%.ps - $(INSTALL_DIR) $(@D) -@@ -116,3 +116,9 @@ html/%/index.html: src/%.tex - $(LATEX2HTML) -split 0 -show_section_numbers -toc_depth 3 -nonavigation \ - -numbered_footnotes -local_icons -noinfo -math -dir $(@D) \ - $< 1>/dev/null 2>/dev/null -+ rm -rf html.done/$*/ -+ mkdir -p html.done/$*/ -+ cp html/$*/*.html html/$*/*.css html/$*/*.png html.done/$*/ -+ ln -sf $*.html html.done/$*/index.html -+ rm -rf html/ -+ diff --git a/xen-domUloader-pygrub.diff b/xen-domUloader-pygrub.diff deleted file mode 100644 index e07578e..0000000 --- a/xen-domUloader-pygrub.diff +++ /dev/null @@ -1,16 +0,0 @@ -Index: xen-unstable/tools/pygrub/src/pygrub -=================================================================== ---- xen-unstable.orig/tools/pygrub/src/pygrub -+++ xen-unstable/tools/pygrub/src/pygrub -@@ -432,9 +432,9 @@ if __name__ == "__main__": - print >> sys.stderr, "Usage: %s [-q|--quiet] [--output=] [--entry=] " %(sys.argv[0],) - - try: -- opts, args = getopt.gnu_getopt(sys.argv[1:], 'qh::', -+ opts, args = getopt.gnu_getopt(sys.argv[1:], 'qvh::', - ["quiet", "help", "output=", "entry=", -- "isconfig"]) -+ "isconfig", "root=", "disks=", "verbose="]) - except getopt.GetoptError: - usage() - sys.exit(1) diff --git a/xen-domUloader.diff b/xen-domUloader.diff index 7c86621..d389c1e 100644 --- a/xen-domUloader.diff +++ b/xen-domUloader.diff @@ -1,18 +1,89 @@ -Index: xen-3.0.3-testing/tools/python/xen/xm/create.py +Index: xen-3.0.4-testing/tools/python/xen/xend/XendDomainInfo.py =================================================================== ---- xen-3.0.3-testing.orig/tools/python/xen/xm/create.py -+++ xen-3.0.3-testing/tools/python/xen/xm/create.py -@@ -126,7 +126,7 @@ gopts.var('bootloader', val='FILE', - use="Path to bootloader.") +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendDomainInfo.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendDomainInfo.py +@@ -41,7 +41,7 @@ from xen.xend import balloon, sxp, uuid, + from xen.xend import XendRoot, XendNode, XendConfig - gopts.var('bootargs', val='NAME', -- fn=set_value, default=None, -+ fn=set_value, default='', - use="Arguments to pass to boot loader") + from xen.xend.XendConfig import scrub_password +-from xen.xend.XendBootloader import bootloader ++from xen.xend.XendBootloader import bootloader, bootfilter + from xen.xend.XendError import XendError, VmError + from xen.xend.XendDevices import XendDevices + from xen.xend.xenstore.xstransact import xstransact, complete +@@ -1556,13 +1556,17 @@ class XendDomainInfo: + if not devtype or not devinfo or devtype not in ('vbd', 'tap'): + continue + disk = None ++ vdisk = None + for param in devinfo: + if param[0] == 'uname': + disk = param[1] +- break ++ elif param[0] == 'dev': ++ vdisk = param[1] - gopts.var('bootentry', val='NAME', -@@ -649,16 +649,17 @@ def run_bootloader(vals, config_image): - err("Bootloader isn't executable") + if disk is None: + continue ++ if not bootfilter(blexec, bootloader_args, vdisk): ++ continue + fn = blkdev_uname_to_file(disk) + mounted = devtype == 'tap' and not os.stat(fn).st_rdev + if mounted: +Index: xen-3.0.4-testing/tools/python/xen/xend/XendBootloader.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendBootloader.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendBootloader.py +@@ -14,6 +14,7 @@ + + import os, select, errno, stat + import random ++import re + import shlex + from xen.xend import sxp + +@@ -97,3 +98,26 @@ def bootloader(blexec, disk, quiet = Fal + pin.input_eof() + blcfg = pin.val + return blcfg ++ ++def bootfilter(bootloader, bootloader_args, vdisk): ++ """Is this virtual disk ok to boot from?""" ++ if vdisk.endswith(':disk'): ++ vdisk = vdisk[:-5] # temporary work-around for bug 237414 ++ if bootloader.endswith('domUloader.py'): ++ for arg in bootloader_args.split(): ++ if arg.startswith('--entry='): ++ m = re.match(r'^([hsx]v?d[a-z])[0-9]*:[^,]*(,[^,]*)?$', arg[8:]) ++ if m: ++ return vdisk == m.group(1) or vdisk == m.group(2) ++ return True ++ ++def bootselector(bootloader, bootloader_args, disks): ++ """Returns the desired disk to boot from. ++ @param disks List of (pdev, vdev, ...) tuples. ++ """ ++ if bootloader.endswith('domUloader.py'): ++ for disk in disks: ++ if bootfilter(bootloader, bootloader_args, disk[1]): ++ return disk ++ return disks[0] ++ +Index: xen-3.0.4-testing/tools/python/xen/xm/create.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/python/xen/xm/create.py ++++ xen-3.0.4-testing/tools/python/xen/xm/create.py +@@ -29,7 +29,7 @@ import xmlrpclib + from xen.xend import sxp + from xen.xend import PrettyPrint + import xen.xend.XendClient +-from xen.xend.XendBootloader import bootloader ++from xen.xend.XendBootloader import bootloader, bootselector + from xen.util import blkif + from xen.util import security + +@@ -710,14 +710,15 @@ def run_bootloader(vals, config_image): + err("Bootloader '%s' isn't executable" % vals.bootloader) if len(vals.disk) < 1: err("No disks configured and boot loader requested") - (uname, dev, mode, backend) = vals.disk[0] @@ -22,102 +93,10 @@ Index: xen-3.0.3-testing/tools/python/xen/xm/create.py warn("The bootentry option is deprecated. Use bootargs and pass " "--entry= directly.") vals.bootargs = "--entry=%s" %(vals.bootentry,) -+ if vals.root: -+ vals.bootargs += " --root=%s" % vals.root.split()[0] -+ vals.bootargs += " --disks=\"%s\"" % str(vals.disk) -- return bootloader(vals.bootloader, file, not vals.console_autoconnect, -- vals.bootargs, config_image) -+ return bootloader(vals.bootloader, not vals.console_autoconnect, -+ vals.dryrun, vals.bootargs, config_image) ++ bootdisk = bootselector(vals.bootloader, vals.bootargs, vals.disk) ++ uname = bootdisk[0] ++ file = blkif.blkdev_uname_to_file(uname) + return bootloader(vals.bootloader, file, not vals.console_autoconnect, + vals.bootargs, config_image) - def make_config(vals): - """Create the domain configuration. -Index: xen-3.0.3-testing/tools/python/xen/xend/XendBootloader.py -=================================================================== ---- xen-3.0.3-testing.orig/tools/python/xen/xend/XendBootloader.py -+++ xen-3.0.3-testing/tools/python/xen/xend/XendBootloader.py -@@ -20,11 +20,9 @@ import shlex - from XendLogging import log - from XendError import VmError - --def bootloader(blexec, disk, quiet = 0, blargs = None, imgcfg = None): -- """Run the boot loader executable on the given disk and return a -- config image. -+def bootloader(blexec, quiet = 0, dryrun = 0, blargs = None, imgcfg = None): -+ """Run the boot loader executable and return a config image. - @param blexec Binary to use as the boot loader -- @param disk Disk to run the boot loader on. - @param quiet Run in non-interactive mode, just booting the default. - @param blargs Arguments to pass to the bootloader.""" - -@@ -32,10 +30,6 @@ def bootloader(blexec, disk, quiet = 0, - msg = "Bootloader isn't executable" - log.error(msg) - raise VmError(msg) -- if not os.access(disk, os.R_OK): -- msg = "Disk isn't accessible" -- log.error(msg) -- raise VmError(msg) - - while True: - fifo = "/var/lib/xen/xenbl.%s" %(random.randint(0, 32000),) -@@ -48,10 +42,11 @@ def bootloader(blexec, disk, quiet = 0, - args = [ blexec ] - if quiet: - args.append("-q") -+ if dryrun: -+ args.append("--dryrun") - args.append("--output=%s" %(fifo,)) - if blargs is not None: - args.extend(shlex.split(blargs)) -- args.append(disk) - - try: - os.execvp(args[0], args) -@@ -68,6 +63,7 @@ def bootloader(blexec, disk, quiet = 0, - continue - break - ret = "" -+ # TODO: Add timeout, cleanup and raise VmError if it occurs - while 1: - select.select([r], [], []) - s = os.read(r, 1024) -Index: xen-3.0.3-testing/tools/python/xen/xend/XendDomainInfo.py -=================================================================== ---- xen-3.0.3-testing.orig/tools/python/xen/xend/XendDomainInfo.py -+++ xen-3.0.3-testing/tools/python/xen/xend/XendDomainInfo.py -@@ -1743,18 +1743,27 @@ class XendDomainInfo: - if not self.info['bootloader']: - return - blcfg = None -- # FIXME: this assumes that we want to use the first disk device -+ """This code is currently unneeded, but will be used -+ again when boot device selection is more dynamic. -+ vbds = [] - for (n,c) in self.info['device']: - if not n or not c or not(n in ["vbd", "tap"]): - continue - disk = sxp.child_value(c, "uname") - if disk is None: - continue -- fn = blkdev_uname_to_file(disk) -- blcfg = bootloader(self.info['bootloader'], fn, 1, -- self.info['bootloader_args'], -- self.info['image']) -- break -+ vbds.append([sxp.child_value(c, "uname"), -+ sxp.child_value(c, "dev"), -+ sxp.child_value(c, "mode"), -+ sxp.child_value(c, "backend")]) -+ if vbds: -+ bootargs = self.info['bootloader_args'] + \ -+ " --disks=\"%s\"" % str(vbds) -+ if self.info['root']: -+ bootargs += " --root=%s" % self.info['root'].split()[0] -+ """ -+ blcfg = bootloader(self.info['bootloader'], 1, 0, -+ self.info['bootloader_args'], self.info['image']) - if blcfg is None: - msg = "Had a bootloader specified, but can't find disk" - log.error(msg) diff --git a/xen-generate-foreign-headers.diff b/xen-generate-foreign-headers.diff new file mode 100644 index 0000000..4fd8d76 --- /dev/null +++ b/xen-generate-foreign-headers.diff @@ -0,0 +1,406 @@ +Generate headers with arch-specific structs. + +This patch adds a script to generate headers with arch-specific +structs which can be included on any architecture. Can be used +to deal with structs of "foreign" architectures, needed for +32-on-64 support for example. + +Signed-off-by: Gerd Hoffmann +--- + tools/Rules.mk | 2 + xen/Makefile | 5 + xen/include/public/foreign/Makefile | 30 +++++ + xen/include/public/foreign/mkchecker.py | 58 +++++++++++ + xen/include/public/foreign/mkheader.py | 153 ++++++++++++++++++++++++++++++ + xen/include/public/foreign/reference.size | 17 +++ + xen/include/public/foreign/structs.py | 49 +++++++++ + 7 files changed, 314 insertions(+) + +Index: xen-3.0.4-testing/xen/include/public/foreign/Makefile +=================================================================== +--- /dev/null ++++ xen-3.0.4-testing/xen/include/public/foreign/Makefile +@@ -0,0 +1,37 @@ ++XEN_ROOT := ../../../.. ++include $(XEN_ROOT)/tools/Rules.mk ++ ++architectures := x86_32 x86_64 ia64 ++headers := $(patsubst %, %.h, $(architectures)) ++scripts := $(wildcard *.py) ++ ++.PHONY: all clean check-headers ++all: $(headers) check-headers ++ ++clean: ++ rm -f $(headers) ++ rm -f checker checker.c $(XEN_TARGET_ARCH).size ++ rm -f *.pyc *.o *~ ++ ++check-headers: checker ++ifeq ($(CROSS_COMPILE),) ++ ./checker > $(XEN_TARGET_ARCH).size ++ diff -u reference.size $(XEN_TARGET_ARCH).size ++else ++ @echo "cross build: skipping check" ++endif ++ ++x86_32.h: ../arch-x86/xen-x86_32.h ../arch-x86/xen.h ../xen.h $(scripts) ++ python mkheader.py $* $@ $(filter %.h,$^) ++ ++x86_64.h: ../arch-x86/xen-x86_64.h ../arch-x86/xen.h ../xen.h $(scripts) ++ python mkheader.py $* $@ $(filter %.h,$^) ++ ++ia64.h: ../arch-ia64.h ../xen.h $(scripts) ++ python mkheader.py $* $@ $(filter %.h,$^) ++ ++checker: checker.c $(headers) ++ $(HOSTCC) -o $@ $< ++ ++checker.c: $(scripts) ++ python mkchecker.py $(XEN_TARGET_ARCH) $@ $(architectures) +Index: xen-3.0.4-testing/xen/include/public/foreign/mkheader.py +=================================================================== +--- /dev/null ++++ xen-3.0.4-testing/xen/include/public/foreign/mkheader.py +@@ -0,0 +1,153 @@ ++#!/usr/bin/python ++ ++import sys, re; ++from structs import structs, defines; ++ ++# command line arguments ++arch = sys.argv[1]; ++outfile = sys.argv[2]; ++infiles = sys.argv[3:]; ++ ++ ++########################################################################### ++# configuration #2: architecture information ++ ++inttypes = {}; ++header = {}; ++footer = {}; ++ ++# x86_32 ++inttypes["x86_32"] = { ++ "unsigned long" : "uint32_t", ++ "long" : "uint32_t", ++ "xen_pfn_t" : "uint32_t", ++}; ++header["x86_32"] = """ ++#define __i386___X86_32 1 ++#pragma pack(push, 4) ++"""; ++footer["x86_32"] = """ ++#pragma pack(pop) ++"""; ++ ++# x86_64 ++inttypes["x86_64"] = { ++ "unsigned long" : "__align8__ uint64_t", ++ "long" : "__align8__ uint64_t", ++ "xen_pfn_t" : "__align8__ uint64_t", ++}; ++header["x86_64"] = """ ++#ifdef __GNUC__ ++# define __DECL_REG(name) union { uint64_t r ## name, e ## name; } ++# define __align8__ __attribute__((aligned (8))) ++#else ++# define __DECL_REG(name) uint64_t r ## name ++# define __align8__ FIXME ++#endif ++#define __x86_64___X86_64 1 ++"""; ++ ++# ia64 ++inttypes["ia64"] = { ++ "unsigned long" : "__align8__ uint64_t", ++ "long" : "__align8__ uint64_t", ++ "xen_pfn_t" : "__align8__ uint64_t", ++ "long double" : "__align16__ ldouble_t", ++}; ++header["ia64"] = """ ++#define __align8__ __attribute__((aligned (8))) ++#define __align16__ __attribute__((aligned (16))) ++typedef unsigned char ldouble_t[16]; ++"""; ++ ++ ++########################################################################### ++# main ++ ++input = ""; ++output = ""; ++fileid = re.sub("[-.]", "_", "__FOREIGN_%s__" % outfile.upper()); ++ ++# read input header files ++for name in infiles: ++ f = open(name, "r"); ++ input += f.read(); ++ f.close(); ++ ++# add header ++output += """ ++/* ++ * public xen defines and struct for %s ++ * generated by %s -- DO NOT EDIT ++ */ ++ ++#ifndef %s ++#define %s 1 ++ ++""" % (arch, sys.argv[0], fileid, fileid) ++ ++if arch in header: ++ output += header[arch]; ++ output += "\n"; ++ ++# add defines to output ++for line in re.findall("#define[^\n]+", input): ++ for define in defines: ++ regex = "#define\s+%s\\b" % define; ++ match = re.search(regex, line); ++ if None == match: ++ continue; ++ if define.upper()[0] == define[0]: ++ replace = define + "_" + arch.upper(); ++ else: ++ replace = define + "_" + arch; ++ regex = "\\b%s\\b" % define; ++ output += re.sub(regex, replace, line) + "\n"; ++output += "\n"; ++ ++# delete defines, comments, empty lines ++input = re.sub("#define[^\n]+\n", "", input); ++input = re.compile("/\*(.*?)\*/", re.S).sub("", input) ++input = re.compile("\n\s*\n", re.S).sub("\n", input); ++ ++# add structs to output ++for struct in structs: ++ regex = "struct\s+%s\s*\{(.*?)\n\};" % struct; ++ match = re.search(regex, input, re.S) ++ if None == match: ++ output += "#define %s_has_no_%s 1\n" % (arch, struct); ++ else: ++ output += "struct %s_%s {%s\n};\n" % (struct, arch, match.group(1)); ++ output += "typedef struct %s_%s %s_%s_t;\n" % (struct, arch, struct, arch); ++ output += "\n"; ++ ++# add footer ++if arch in footer: ++ output += footer[arch]; ++ output += "\n"; ++output += "#endif /* %s */\n" % fileid; ++ ++# replace: defines ++for define in defines: ++ if define.upper()[0] == define[0]: ++ replace = define + "_" + arch.upper(); ++ else: ++ replace = define + "_" + arch; ++ output = re.sub("\\b%s\\b" % define, replace, output); ++ ++# replace: structs + struct typedefs ++for struct in structs: ++ output = re.sub("\\b(struct\s+%s)\\b" % struct, "\\1_%s" % arch, output); ++ output = re.sub("\\b(%s)_t\\b" % struct, "\\1_%s_t" % arch, output); ++ ++# replace: integer types ++integers = inttypes[arch].keys(); ++integers.sort(lambda a, b: cmp(len(b),len(a))); ++for type in integers: ++ output = re.sub("\\b%s\\b" % type, inttypes[arch][type], output); ++ ++# print results ++f = open(outfile, "w"); ++f.write(output); ++f.close; ++ +Index: xen-3.0.4-testing/xen/include/public/foreign/structs.py +=================================================================== +--- /dev/null ++++ xen-3.0.4-testing/xen/include/public/foreign/structs.py +@@ -0,0 +1,52 @@ ++# configuration: what needs translation ++ ++structs = [ "start_info", ++ "trap_info", ++ "pt_fpreg", ++ "cpu_user_regs", ++ "xen_ia64_boot_param", ++ "ia64_tr_entry", ++ "vcpu_extra_regs", ++ "vcpu_guest_context", ++ "arch_vcpu_info", ++ "vcpu_time_info", ++ "vcpu_info", ++ "arch_shared_info", ++ "shared_info" ]; ++ ++defines = [ "__i386__", ++ "__x86_64__", ++ ++ "FLAT_RING1_CS", ++ "FLAT_RING1_DS", ++ "FLAT_RING1_SS", ++ ++ "FLAT_RING3_CS64", ++ "FLAT_RING3_DS64", ++ "FLAT_RING3_SS64", ++ "FLAT_KERNEL_CS64", ++ "FLAT_KERNEL_DS64", ++ "FLAT_KERNEL_SS64", ++ ++ "FLAT_KERNEL_CS", ++ "FLAT_KERNEL_DS", ++ "FLAT_KERNEL_SS", ++ ++ # x86_{32,64} ++ "_VGCF_i387_valid", ++ "VGCF_i387_valid", ++ "_VGCF_in_kernel", ++ "VGCF_in_kernel", ++ "_VGCF_failsafe_disables_events", ++ "VGCF_failsafe_disables_events", ++ "_VGCF_syscall_disables_events", ++ "VGCF_syscall_disables_events", ++ ++ # ia64 ++ "VGCF_EXTRA_REGS", ++ ++ # all archs ++ "xen_pfn_to_cr3", ++ "MAX_VIRT_CPUS", ++ "MAX_GUEST_CMDLINE" ]; ++ +Index: xen-3.0.4-testing/xen/include/public/foreign/reference.size +=================================================================== +--- /dev/null ++++ xen-3.0.4-testing/xen/include/public/foreign/reference.size +@@ -0,0 +1,17 @@ ++ ++structs | x86_32 x86_64 ia64 ++ ++start_info | 1104 1152 1152 ++trap_info | 8 16 - ++pt_fpreg | - - 16 ++cpu_user_regs | 68 200 496 ++xen_ia64_boot_param | - - 96 ++ia64_tr_entry | - - 32 ++vcpu_extra_regs | - - 536 ++vcpu_guest_context | 2800 5168 1056 ++arch_vcpu_info | 24 16 0 ++vcpu_time_info | 32 32 32 ++vcpu_info | 64 64 48 ++arch_shared_info | 268 280 272 ++shared_info | 2584 3368 4384 ++ +Index: xen-3.0.4-testing/xen/Makefile +=================================================================== +--- xen-3.0.4-testing.orig/xen/Makefile ++++ xen-3.0.4-testing/xen/Makefile +@@ -36,10 +36,13 @@ _install: $(TARGET).gz + $(INSTALL_DIR) $(DESTDIR)/usr/include/xen/hvm + [ -d $(DESTDIR)/usr/include/xen/io ] || \ + $(INSTALL_DIR) $(DESTDIR)/usr/include/xen/io ++ [ -d $(DESTDIR)/usr/include/xen/foreign ] || \ ++ $(INSTALL_DIR) $(DESTDIR)/usr/include/xen/foreign + $(INSTALL_DATA) include/public/*.h $(DESTDIR)/usr/include/xen + $(INSTALL_DATA) include/public/arch-x86/*.h $(DESTDIR)/usr/include/xen/arch-x86 + $(INSTALL_DATA) include/public/hvm/*.h $(DESTDIR)/usr/include/xen/hvm + $(INSTALL_DATA) include/public/io/*.h $(DESTDIR)/usr/include/xen/io ++ $(INSTALL_DATA) include/public/foreign/*.h $(DESTDIR)/usr/include/xen/foreign + $(INSTALL_DATA) include/public/COPYING $(DESTDIR)/usr/include/xen + + .PHONY: _debug +@@ -49,6 +52,7 @@ _debug: + .PHONY: _clean + _clean: delete-unfresh-files + $(MAKE) -C tools clean ++ $(MAKE) -C include/public/foreign clean + $(MAKE) -f $(BASEDIR)/Rules.mk -C include clean + $(MAKE) -f $(BASEDIR)/Rules.mk -C common clean + $(MAKE) -f $(BASEDIR)/Rules.mk -C drivers clean +@@ -68,6 +72,7 @@ $(TARGET).gz: $(TARGET) + + $(TARGET): delete-unfresh-files + $(MAKE) -C tools ++ $(MAKE) -C include/public/foreign + $(MAKE) -f $(BASEDIR)/Rules.mk include/xen/compile.h + $(MAKE) -f $(BASEDIR)/Rules.mk include/xen/acm_policy.h + [ -e include/asm ] || ln -sf asm-$(TARGET_ARCH) include/asm +Index: xen-3.0.4-testing/xen/include/public/foreign/mkchecker.py +=================================================================== +--- /dev/null ++++ xen-3.0.4-testing/xen/include/public/foreign/mkchecker.py +@@ -0,0 +1,58 @@ ++#!/usr/bin/python ++ ++import sys; ++from structs import structs; ++ ++# command line arguments ++arch = sys.argv[1]; ++outfile = sys.argv[2]; ++archs = sys.argv[3:]; ++ ++f = open(outfile, "w"); ++f.write(''' ++/* ++ * sanity checks for generated foreign headers: ++ * - verify struct sizes ++ * ++ * generated by %s -- DO NOT EDIT ++ */ ++#include ++#include ++#include ++#include ++#include "../xen.h" ++'''); ++ ++for a in archs: ++ f.write('#include "%s.h"\n' % a); ++ ++f.write('int main(int argc, char *argv[])\n{\n'); ++ ++f.write('\tprintf("\\n");'); ++f.write('printf("%-20s |", "structs");\n'); ++for a in archs: ++ f.write('\tprintf("%%8s", "%s");\n' % a); ++f.write('\tprintf("\\n");'); ++ ++f.write('\tprintf("\\n");'); ++for struct in structs: ++ f.write('\tprintf("%%-20s |", "%s");\n' % struct); ++ for a in archs: ++ if a == arch: ++ s = struct; # native ++ else: ++ s = struct + "_" + a; ++ f.write('#ifdef %s_has_no_%s\n' % (a, struct)); ++ f.write('\tprintf("%8s", "-");\n'); ++ f.write("#else\n"); ++ f.write('\tprintf("%%8zd", sizeof(struct %s));\n' % s); ++ f.write("#endif\n"); ++ ++ f.write('\tprintf("\\n");\n\n'); ++ ++f.write('\tprintf("\\n");\n'); ++f.write('\texit(0);\n'); ++f.write('}\n'); ++ ++f.close(); ++ +Index: xen-3.0.4-testing/tools/Rules.mk +=================================================================== +--- xen-3.0.4-testing.orig/tools/Rules.mk ++++ xen-3.0.4-testing/tools/Rules.mk +@@ -52,5 +52,7 @@ mk-symlinks-xen: + ( cd xen/io && ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . ) + mkdir -p xen/arch-x86 + ( cd xen/arch-x86 && ln -sf ../../$(XEN_ROOT)/xen/include/public/arch-x86/*.h . ) ++ mkdir -p xen/foreign ++ ( cd xen/foreign && ln -sf ../../$(XEN_ROOT)/xen/include/public/foreign/*.h . ) + + mk-symlinks: mk-symlinks-xen mk-symlinks-$(XEN_OS) diff --git a/xen-hvm-default-bridge.diff b/xen-hvm-default-bridge.diff index e62a67c..a8cc97a 100644 --- a/xen-hvm-default-bridge.diff +++ b/xen-hvm-default-bridge.diff @@ -1,8 +1,8 @@ -Index: xen-3.0.3-testing/tools/examples/xend-config.sxp +Index: xen-3.0.4-testing/tools/examples/xend-config.sxp =================================================================== ---- xen-3.0.3-testing.orig/tools/examples/xend-config.sxp -+++ xen-3.0.3-testing/tools/examples/xend-config.sxp -@@ -76,7 +76,8 @@ +--- xen-3.0.4-testing.orig/tools/examples/xend-config.sxp ++++ xen-3.0.4-testing/tools/examples/xend-config.sxp +@@ -116,7 +116,8 @@ # # (network-script 'network-bridge netdev=eth1') # @@ -12,10 +12,10 @@ Index: xen-3.0.3-testing/tools/examples/xend-config.sxp # # (network-script 'network-bridge bridge=') # -Index: xen-3.0.3-testing/tools/ioemu/vl.c +Index: xen-3.0.4-testing/tools/ioemu/vl.c =================================================================== ---- xen-3.0.3-testing.orig/tools/ioemu/vl.c -+++ xen-3.0.3-testing/tools/ioemu/vl.c +--- xen-3.0.4-testing.orig/tools/ioemu/vl.c ++++ xen-3.0.4-testing/tools/ioemu/vl.c @@ -89,7 +89,6 @@ #include "exec-all.h" @@ -24,7 +24,7 @@ Index: xen-3.0.3-testing/tools/ioemu/vl.c //#define DEBUG_UNUSED_IOPORT //#define DEBUG_IOPORT -@@ -3773,10 +3772,10 @@ int net_client_init(const char *str) +@@ -3779,10 +3778,10 @@ int net_client_init(const char *str) if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) { pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT); } @@ -39,33 +39,33 @@ Index: xen-3.0.3-testing/tools/ioemu/vl.c } } else #endif -Index: xen-3.0.3-testing/tools/python/xen/xend/image.py +Index: xen-3.0.4-testing/tools/python/xen/xend/image.py =================================================================== ---- xen-3.0.3-testing.orig/tools/python/xen/xend/image.py -+++ xen-3.0.3-testing/tools/python/xen/xend/image.py -@@ -339,13 +339,16 @@ class HVMImageHandler(ImageHandler): - mac = sxp.child_value(info, 'mac') - if mac == None: - mac = randomMAC() -- bridge = sxp.child_value(info, 'bridge', 'xenbr0') -+ bridge = sxp.child_value(info, 'bridge', None) - model = sxp.child_value(info, 'model', 'rtl8139') - ret.append("-net") - ret.append("nic,vlan=%d,macaddr=%s,model=%s" % - (nics, mac, model)) - ret.append("-net") -- ret.append("tap,vlan=%d,bridge=%s" % (nics, bridge)) -+ net = "tap,vlan=%d" % (nics,) -+ if bridge: -+ net += ",bridge=%s" % (bridge,) -+ ret.append(net) +--- xen-3.0.4-testing.orig/tools/python/xen/xend/image.py ++++ xen-3.0.4-testing/tools/python/xen/xend/image.py +@@ -419,13 +419,16 @@ class HVMImageHandler(ImageHandler): + mac = devinfo.get('mac') + if mac is None: + mac = randomMAC() +- bridge = devinfo.get('bridge', 'xenbr0') ++ bridge = devinfo.get('bridge', None) + model = devinfo.get('model', 'rtl8139') + ret.append("-net") + ret.append("nic,vlan=%d,macaddr=%s,model=%s" % + (nics, mac, model)) + ret.append("-net") +- ret.append("tap,vlan=%d,bridge=%s" % (nics, bridge)) ++ net = "tap,vlan=%d" % (nics,) ++ if bridge: ++ net += ",bridge=%s" % (bridge,) ++ ret.append(net) + return ret - def configVNC(self, config): -Index: xen-3.0.3-testing/tools/ioemu/target-i386-dm/qemu-ifup +Index: xen-3.0.4-testing/tools/ioemu/target-i386-dm/qemu-ifup =================================================================== ---- xen-3.0.3-testing.orig/tools/ioemu/target-i386-dm/qemu-ifup -+++ xen-3.0.3-testing/tools/ioemu/target-i386-dm/qemu-ifup +--- xen-3.0.4-testing.orig/tools/ioemu/target-i386-dm/qemu-ifup ++++ xen-3.0.4-testing/tools/ioemu/target-i386-dm/qemu-ifup @@ -1,10 +1,11 @@ #!/bin/sh diff --git a/xen-hvm-default-pae.diff b/xen-hvm-default-pae.diff index 51eb1c7..e418583 100644 --- a/xen-hvm-default-pae.diff +++ b/xen-hvm-default-pae.diff @@ -1,15 +1,15 @@ PAE must be on for 64-on-64 to work at all. -Index: xen-3.0.3-testing/tools/python/xen/xend/image.py +Index: xen-3.0.4-testing/tools/python/xen/xend/image.py =================================================================== ---- xen-3.0.3-testing.orig/tools/python/xen/xend/image.py -+++ xen-3.0.3-testing/tools/python/xen/xend/image.py -@@ -263,7 +263,7 @@ class HVMImageHandler(ImageHandler): +--- xen-3.0.4-testing.orig/tools/python/xen/xend/image.py ++++ xen-3.0.4-testing/tools/python/xen/xend/image.py +@@ -334,7 +334,7 @@ class HVMImageHandler(ImageHandler): self.dmargs += self.configVNC(imageConfig) -- self.pae = int(sxp.child_value(imageConfig, 'pae', 0)) -+ self.pae = int(sxp.child_value(imageConfig, 'pae', 1)) - - self.acpi = int(sxp.child_value(imageConfig, 'acpi', 0)) - self.apic = int(sxp.child_value(imageConfig, 'apic', 0)) +- self.pae = imageConfig['hvm'].get('pae', 0) ++ self.pae = imageConfig['hvm'].get('pae', 1) + self.apic = imageConfig['hvm'].get('apic', 0) + self.acpi = imageConfig['hvm']['devices'].get('acpi', 0) + diff --git a/xen-hvm-netfront.diff b/xen-hvm-netfront.diff index 0bf601d..5c525b5 100644 --- a/xen-hvm-netfront.diff +++ b/xen-hvm-netfront.diff @@ -1,8 +1,8 @@ -Index: xen-3.0.3-testing/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c +Index: xen-3.0.4-testing/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c =================================================================== ---- xen-3.0.3-testing.orig/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c -+++ xen-3.0.3-testing/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c -@@ -275,6 +275,13 @@ static int __devinit netfront_probe(stru +--- xen-3.0.4-testing.orig/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c ++++ xen-3.0.4-testing/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c +@@ -282,6 +282,13 @@ static int __devinit netfront_probe(stru int err; struct net_device *netdev; struct netfront_info *info; diff --git a/xen-io-register-context.diff b/xen-io-register-context.diff deleted file mode 100644 index e27b037..0000000 --- a/xen-io-register-context.diff +++ /dev/null @@ -1,680 +0,0 @@ -From: Jan Beulich -Bugzilla #192150 - -Index: xen-unstable/xen/arch/x86/domain_build.c -=================================================================== ---- xen-unstable.orig/xen/arch/x86/domain_build.c -+++ xen-unstable/xen/arch/x86/domain_build.c -@@ -33,6 +33,11 @@ - extern unsigned long initial_images_nrpages(void); - extern void discard_initial_images(void); - -+/* I/O-port Xen-enforced or admin-specified access control. */ -+struct rangeset *ioport_caps = NULL; -+/* I/O-port admin-specified non-special access requirements. */ -+struct rangeset *ioport_emul = NULL; -+ - static long dom0_nrpages; - - /* -@@ -64,6 +69,12 @@ integer_param("dom0_max_vcpus", opt_dom0 - static unsigned int opt_dom0_shadow; - boolean_param("dom0_shadow", opt_dom0_shadow); - -+static char opt_ioports_noemul[200] = ""; -+string_param("ioports_noemul", opt_ioports_noemul); -+ -+static char opt_ioports_disable[200] = ""; -+string_param("ioports_disable", opt_ioports_disable); -+ - static char opt_dom0_ioports_disable[200] = ""; - string_param("dom0_ioports_disable", opt_dom0_ioports_disable); - -@@ -103,10 +114,10 @@ static struct page_info *alloc_chunk(str - return page; - } - --static void process_dom0_ioports_disable(void) -+static void process_ioports(char *opt) - { - unsigned long io_from, io_to; -- char *t, *u, *s = opt_dom0_ioports_disable; -+ char *t, *u, *s = opt; - - if ( *s == '\0' ) - return; -@@ -118,7 +129,9 @@ static void process_dom0_ioports_disable - { - parse_error: - printk("Invalid ioport range <%s> " -- "in dom0_ioports_disable, skipping\n", t); -+ "in %sioports_%s, skipping\n", t, -+ opt == opt_dom0_ioports_disable ? "dom0_" : "", -+ opt != opt_ioports_noemul ? "disable" : "noemul"); - continue; - } - -@@ -132,11 +145,26 @@ static void process_dom0_ioports_disable - if ( (*u != '\0') || (io_to < io_from) || (io_to >= 65536) ) - goto parse_error; - -- printk("Disabling dom0 access to ioport range %04lx-%04lx\n", -- io_from, io_to); -+ if ( opt != opt_ioports_noemul ) -+ { -+ printk("Disabling %saccess to ioport range %04lx-%04lx\n", -+ opt != opt_ioports_disable ? "dom0 " : "", -+ io_from, io_to); - -- if ( ioports_deny_access(dom0, io_from, io_to) != 0 ) -- BUG(); -+ if ( opt == opt_ioports_disable -+ && ioports_deny_access_all(io_from, io_to) != 0 ) -+ BUG(); -+ if ( ioports_deny_access(dom0, io_from, io_to) != 0 ) -+ BUG(); -+ } -+ else -+ { -+ printk("Setting non-emulated access for ioport range %04lx-%04lx\n", -+ io_from, io_to); -+ -+ if ( ioports_set_noemul(io_from, io_to) != 0 ) -+ BUG(); -+ } - } - } - -@@ -812,6 +840,13 @@ int construct_dom0(struct domain *d, - - rc = 0; - -+ /* Command-line I/O ranges. */ -+ ioport_caps = rangeset_new(NULL, -+ "global I/O Port access control", -+ RANGESETF_prettyprint_hex); -+ BUG_ON(!ioport_caps); -+ rc |= ioports_permit_access_all(0, 0xFFFF); -+ - /* DOM0 is permitted full I/O capabilities. */ - rc |= ioports_permit_access(dom0, 0, 0xFFFF); - rc |= iomem_permit_access(dom0, 0UL, ~0UL); -@@ -821,15 +856,20 @@ int construct_dom0(struct domain *d, - * Modify I/O port access permissions. - */ - /* Master Interrupt Controller (PIC). */ -+ rc |= ioports_deny_access_all(0x20, 0x21); - rc |= ioports_deny_access(dom0, 0x20, 0x21); - /* Slave Interrupt Controller (PIC). */ -+ rc |= ioports_deny_access_all(0xA0, 0xA1); - rc |= ioports_deny_access(dom0, 0xA0, 0xA1); - /* Interval Timer (PIT). */ -+ rc |= ioports_deny_access_all(0x40, 0x43); - rc |= ioports_deny_access(dom0, 0x40, 0x43); - /* PIT Channel 2 / PC Speaker Control. */ -+ rc |= ioports_deny_access_all(0x61, 0x61); - rc |= ioports_deny_access(dom0, 0x61, 0x61); - /* Command-line I/O ranges. */ -- process_dom0_ioports_disable(); -+ process_ioports(opt_ioports_disable); -+ process_ioports(opt_dom0_ioports_disable); - - /* - * Modify I/O memory access permissions. -@@ -848,6 +888,14 @@ int construct_dom0(struct domain *d, - rc |= iomem_deny_access(dom0, mfn, mfn); - } - -+ /* Command-line I/O ranges requiring full register context access. */ -+ ioport_emul = rangeset_new(NULL, -+ "I/O Port emulation control", -+ RANGESETF_prettyprint_hex); -+ BUG_ON(!ioport_emul); -+ rc |= ioports_set_emul(0, 0xFFFF); -+ process_ioports(opt_ioports_noemul); -+ - BUG_ON(rc != 0); - - return 0; -Index: xen-unstable/xen/arch/x86/sysctl.c -=================================================================== ---- xen-unstable.orig/xen/arch/x86/sysctl.c -+++ xen-unstable/xen/arch/x86/sysctl.c -@@ -57,6 +57,23 @@ long arch_do_sysctl( - } - break; - -+ case XEN_SYSCTL_ioport_emulation: -+ { -+ unsigned int fp = sysctl->u.ioport_emulation.first_port; -+ unsigned int np = sysctl->u.ioport_emulation.nr_ports; -+ -+ ret = -EINVAL; -+ if ( (fp + np) > 65536 ) -+ break; -+ -+ if ( np == 0 ) -+ ret = 0; -+ else if ( sysctl->u.ioport_emulation.emulate ) -+ ret = ioports_set_emul(fp, fp + np - 1); -+ else -+ ret = ioports_set_noemul(fp, fp + np - 1); -+ } -+ break; - - default: - ret = -ENOSYS; -Index: xen-unstable/xen/arch/x86/traps.c -=================================================================== ---- xen-unstable.orig/xen/arch/x86/traps.c -+++ xen-unstable/xen/arch/x86/traps.c -@@ -1002,9 +1002,20 @@ static inline int admin_io_okay( - return ioports_access_permitted(v->domain, port, port + bytes - 1); - } - -+typedef unsigned long io_emul_stub_t(struct cpu_user_regs *) __attribute__((__regparm__(1))); -+long io_emul_stub_offset = 0, io_emul_insn_offset = 0; -+ -+/* Can the I/O access be carried out without full register context? */ -+static inline int normal_io_okay( -+ unsigned int port, unsigned int bytes) -+{ -+ return ioports_emul(port, port + bytes - 1); -+} -+ - /* Check admin limits. Silently fail the access if it is disallowed. */ - static inline unsigned char inb_user( -- unsigned int port, struct vcpu *v, struct cpu_user_regs *regs) -+ unsigned int port, io_emul_stub_t *stub, -+ struct vcpu *v, struct cpu_user_regs *regs) - { - /* - * Allow read access to port 0x61. Bit 4 oscillates with period 30us, and -@@ -1014,18 +1025,54 @@ static inline unsigned char inb_user( - * but there's not really a good reason to do so. - */ - if ( admin_io_okay(port, 1, v, regs) || (port == 0x61) ) -- return inb(port); -+ return !stub || normal_io_okay(port, 1) ? inb(port) : stub(regs); - return ~0; - } --//#define inb_user(_p, _d, _r) (admin_io_okay(_p, 1, _d, _r) ? inb(_p) : ~0) --#define inw_user(_p, _d, _r) (admin_io_okay(_p, 2, _d, _r) ? inw(_p) : ~0) --#define inl_user(_p, _d, _r) (admin_io_okay(_p, 4, _d, _r) ? inl(_p) : ~0) --#define outb_user(_v, _p, _d, _r) \ -- (admin_io_okay(_p, 1, _d, _r) ? outb(_v, _p) : ((void)0)) --#define outw_user(_v, _p, _d, _r) \ -- (admin_io_okay(_p, 2, _d, _r) ? outw(_v, _p) : ((void)0)) --#define outl_user(_v, _p, _d, _r) \ -- (admin_io_okay(_p, 4, _d, _r) ? outl(_v, _p) : ((void)0)) -+ -+static inline unsigned short inw_user( -+ unsigned int port, io_emul_stub_t *stub, -+ struct vcpu *v, struct cpu_user_regs *regs) -+{ -+ if ( admin_io_okay(port, 2, v, regs) ) -+ return !stub || normal_io_okay(port, 2) ? inw(port) : stub(regs); -+ return ~0; -+} -+ -+static inline unsigned int inl_user( -+ unsigned int port, io_emul_stub_t *stub, -+ struct vcpu *v, struct cpu_user_regs *regs) -+{ -+ if ( admin_io_okay(port, 4, v, regs) ) -+ return !stub || normal_io_okay(port, 4) ? inl(port) : stub(regs); -+ return ~0; -+} -+ -+static inline void outb_user( -+ unsigned char value, unsigned int port, -+ io_emul_stub_t *stub, -+ struct vcpu *v, struct cpu_user_regs *regs) -+{ -+ if ( admin_io_okay(port, 1, v, regs) ) -+ !stub || normal_io_okay(port, 1) ? outb(value, port) : (void)stub(regs); -+} -+ -+static inline void outw_user( -+ unsigned short value, unsigned int port, -+ io_emul_stub_t *stub, -+ struct vcpu *v, struct cpu_user_regs *regs) -+{ -+ if ( admin_io_okay(port, 2, v, regs) ) -+ !stub || normal_io_okay(port, 2) ? outw(value, port) : (void)stub(regs); -+} -+ -+static inline void outl_user( -+ unsigned int value, unsigned int port, -+ io_emul_stub_t *stub, -+ struct vcpu *v, struct cpu_user_regs *regs) -+{ -+ if ( admin_io_okay(port, 4, v, regs) ) -+ !stub || normal_io_okay(port, 4) ? outl(value, port) : (void)stub(regs); -+} - - /* Instruction fetch with error handling. */ - #define insn_fetch(_type, _size, cs, eip) \ -@@ -1046,6 +1093,8 @@ static int emulate_privileged_op(struct - u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0; - unsigned int port, i, op_bytes = 4, data, rc; - u32 l, h; -+ io_emul_stub_t *stub; -+ char *insn; - - /* Legacy prefixes. */ - for ( i = 0; i < 8; i++ ) -@@ -1103,13 +1152,13 @@ static int emulate_privileged_op(struct - switch ( op_bytes ) - { - case 1: -- data = (u8)inb_user((u16)regs->edx, v, regs); -+ data = (u8)inb_user((u16)regs->edx, NULL, v, regs); - break; - case 2: -- data = (u16)inw_user((u16)regs->edx, v, regs); -+ data = (u16)inw_user((u16)regs->edx, NULL, v, regs); - break; - case 4: -- data = (u32)inl_user((u16)regs->edx, v, regs); -+ data = (u32)inl_user((u16)regs->edx, NULL, v, regs); - break; - } - if ( (rc = copy_to_user((void *)regs->edi, &data, op_bytes)) != 0 ) -@@ -1135,13 +1184,13 @@ static int emulate_privileged_op(struct - switch ( op_bytes ) - { - case 1: -- outb_user((u8)data, (u16)regs->edx, v, regs); -+ outb_user((u8)data, (u16)regs->edx, NULL, v, regs); - break; - case 2: -- outw_user((u16)data, (u16)regs->edx, v, regs); -+ outw_user((u16)data, (u16)regs->edx, NULL, v, regs); - break; - case 4: -- outl_user((u32)data, (u16)regs->edx, v, regs); -+ outl_user((u32)data, (u16)regs->edx, NULL, v, regs); - break; - } - regs->esi += (int)((regs->eflags & EF_DF) ? -op_bytes : op_bytes); -@@ -1159,27 +1208,33 @@ static int emulate_privileged_op(struct - } - - /* I/O Port and Interrupt Flag instructions. */ -+ insn = (char *)get_stack_bottom(); -+ stub = (io_emul_stub_t *)(insn + io_emul_stub_offset); -+ insn += io_emul_insn_offset; -+ *insn++ = op_bytes != 2 ? 0x90 : 0x66; -+ *insn++ = opcode; - switch ( opcode ) - { - case 0xe4: /* IN imm8,%al */ - op_bytes = 1; - case 0xe5: /* IN imm8,%eax */ - port = insn_fetch(u8, 1, cs, eip); -+ *insn = port; - exec_in: - if ( !guest_io_okay(port, op_bytes, v, regs) ) - goto fail; - switch ( op_bytes ) - { - case 1: -- regs->eax &= ~0xffUL; -- regs->eax |= (u8)inb_user(port, v, regs); -+ res = regs->eax & ~0xffUL; -+ regs->eax = res | (u8)inb_user(port, stub, v, regs); - break; - case 2: -- regs->eax &= ~0xffffUL; -- regs->eax |= (u16)inw_user(port, v, regs); -+ res = regs->eax & ~0xffffUL; -+ regs->eax = res | (u16)inw_user(port, stub, v, regs); - break; - case 4: -- regs->eax = (u32)inl_user(port, v, regs); -+ regs->eax = (u32)inl_user(port, stub, v, regs); - break; - } - goto done; -@@ -1188,25 +1243,27 @@ static int emulate_privileged_op(struct - op_bytes = 1; - case 0xed: /* IN %dx,%eax */ - port = (u16)regs->edx; -+ *insn = 0x90; - goto exec_in; - - case 0xe6: /* OUT %al,imm8 */ - op_bytes = 1; - case 0xe7: /* OUT %eax,imm8 */ - port = insn_fetch(u8, 1, cs, eip); -+ *insn = port; - exec_out: - if ( !guest_io_okay(port, op_bytes, v, regs) ) - goto fail; - switch ( op_bytes ) - { - case 1: -- outb_user((u8)regs->eax, port, v, regs); -+ outb_user((u8)regs->eax, port, stub, v, regs); - break; - case 2: -- outw_user((u16)regs->eax, port, v, regs); -+ outw_user((u16)regs->eax, port, stub, v, regs); - break; - case 4: -- outl_user((u32)regs->eax, port, v, regs); -+ outl_user((u32)regs->eax, port, stub, v, regs); - break; - } - goto done; -@@ -1215,6 +1272,7 @@ static int emulate_privileged_op(struct - op_bytes = 1; - case 0xef: /* OUT %eax,%dx */ - port = (u16)regs->edx; -+ *insn = 0x90; - goto exec_out; - - case 0xfa: /* CLI */ -Index: xen-unstable/xen/arch/x86/x86_32/Makefile -=================================================================== ---- xen-unstable.orig/xen/arch/x86/x86_32/Makefile -+++ xen-unstable/xen/arch/x86/x86_32/Makefile -@@ -1,5 +1,6 @@ - obj-y += domain_page.o - obj-y += entry.o -+obj-y += io.o - obj-y += mm.o - obj-y += seg_fixup.o - obj-y += traps.o -Index: xen-unstable/xen/arch/x86/x86_32/io.S -=================================================================== ---- /dev/null -+++ xen-unstable/xen/arch/x86/x86_32/io.S -@@ -0,0 +1,42 @@ -+/* -+ * Special (full-context) I/O handling routines. -+ * -+ * Copyright (c) 2006, Novell, Inc. -+ */ -+ -+#include -+#include -+ -+ENTRY(save_host_restore_guest) -+ movl (%esp), %ecx -+ movl %eax, (%esp) -+ movl UREGS_edx(%eax), %edx -+ pushl %ebx -+ movl UREGS_ebx(%eax), %ebx -+ pushl %ebp -+ movl UREGS_ebp(%eax), %ebp -+ pushl %esi -+ movl UREGS_esi(%eax), %esi -+ pushl %edi -+ movl UREGS_edi(%eax), %edi -+ pushl %ecx -+ movl UREGS_ecx(%eax), %ecx -+ movl UREGS_eax(%eax), %eax -+ ret -+ -+ENTRY(save_guest_restore_host) -+ pushl %edx -+ movl 5*4(%esp), %edx -+ movl %eax, UREGS_eax(%edx) -+ popl UREGS_edx(%edx) -+ movl %edi, UREGS_edi(%edx) -+ popl %edi -+ movl %esi, UREGS_esi(%edx) -+ popl %esi -+ movl %ebp, UREGS_ebp(%edx) -+ popl %ebp -+ movl %ebx, UREGS_ebx(%edx) -+ popl %ebx -+ movl %ecx, UREGS_ecx(%edx) -+ popl %ecx -+ ret -Index: xen-unstable/xen/arch/x86/x86_32/traps.c -=================================================================== ---- xen-unstable.orig/xen/arch/x86/x86_32/traps.c -+++ xen-unstable/xen/arch/x86/x86_32/traps.c -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -250,6 +251,7 @@ fastcall void smp_deferred_nmi(struct cp - void __init percpu_traps_init(void) - { - struct tss_struct *tss = &doublefault_tss; -+ char *stack_bottom, *stack; - asmlinkage int hypercall(void); - - if ( smp_processor_id() != 0 ) -@@ -283,6 +285,28 @@ void __init percpu_traps_init(void) - (unsigned long)tss, 235, 9); - - set_task_gate(TRAP_double_fault, __DOUBLEFAULT_TSS_ENTRY<<3); -+ -+ /* -+ * Stub for full-context I/O emulation. -+ */ -+ stack_bottom = (char *)get_stack_bottom(); -+ stack = (char *)((unsigned long)stack_bottom & ~(STACK_SIZE - 1)); -+ if ( !io_emul_stub_offset ) -+ io_emul_stub_offset = stack - stack_bottom; -+ else -+ BUG_ON(io_emul_stub_offset != stack - stack_bottom); -+ /* call save_host_restore_guest */ -+ stack[0] = 0xe8; -+ *(s32*)&stack[1] = (char *)save_host_restore_guest - &stack[5]; -+ stack += 5; -+ if ( !io_emul_insn_offset ) -+ io_emul_insn_offset = stack - stack_bottom; -+ else -+ BUG_ON(io_emul_insn_offset != stack - stack_bottom); -+ stack += 3; /* operand size prefix, opcode, immediate */ -+ /* jmp save_guest_restore_host */ -+ stack[0] = 0xe9; -+ *(s32*)&stack[1] = (char *)save_guest_restore_host - &stack[5]; - } - - void init_int80_direct_trap(struct vcpu *v) -Index: xen-unstable/xen/arch/x86/x86_64/Makefile -=================================================================== ---- xen-unstable.orig/xen/arch/x86/x86_64/Makefile -+++ xen-unstable/xen/arch/x86/x86_64/Makefile -@@ -1,3 +1,4 @@ - obj-y += entry.o -+obj-y += io.o - obj-y += mm.o - obj-y += traps.o -Index: xen-unstable/xen/arch/x86/x86_64/io.S -=================================================================== ---- /dev/null -+++ xen-unstable/xen/arch/x86/x86_64/io.S -@@ -0,0 +1,62 @@ -+/* -+ * Special (full-context) I/O handling routines. -+ * -+ * Copyright (c) 2006, Novell, Inc. -+ */ -+ -+#include -+#include -+ -+ENTRY(save_host_restore_guest) -+ movq (%rsp), %rcx -+ movq %rdi, (%rsp) -+ movq UREGS_rdx(%rdi), %rdx -+ pushq %rbx -+ movq UREGS_rax(%rdi), %rax -+ movq UREGS_rbx(%rdi), %rbx -+ pushq %rbp -+ movq UREGS_rsi(%rdi), %rsi -+ movq UREGS_rbp(%rdi), %rbp -+ pushq %r12 -+ movq UREGS_r8(%rdi), %r8 -+ movq UREGS_r12(%rdi), %r12 -+ pushq %r13 -+ movq UREGS_r9(%rdi), %r9 -+ movq UREGS_r13(%rdi), %r13 -+ pushq %r14 -+ movq UREGS_r10(%rdi), %r10 -+ movq UREGS_r14(%rdi), %r14 -+ pushq %r15 -+ movq UREGS_r11(%rdi), %r11 -+ movq UREGS_r15(%rdi), %r15 -+ pushq %rcx -+ movq UREGS_rcx(%rdi), %rcx -+ movq UREGS_rdi(%rdi), %rdi -+ ret -+ -+ENTRY(save_guest_restore_host) -+ pushq %rdi -+ movq 7*8(%rsp), %rdi -+ movq %rax, UREGS_rax(%rdi) -+ popq UREGS_rdi(%rdi) -+ movq %r15, UREGS_r15(%rdi) -+ movq %r11, UREGS_r11(%rdi) -+ popq %r15 -+ movq %r14, UREGS_r14(%rdi) -+ movq %r10, UREGS_r10(%rdi) -+ popq %r14 -+ movq %r13, UREGS_r13(%rdi) -+ movq %r9, UREGS_r9(%rdi) -+ popq %r13 -+ movq %r12, UREGS_r12(%rdi) -+ movq %r8, UREGS_r8(%rdi) -+ popq %r12 -+ movq %rbp, UREGS_rbp(%rdi) -+ movq %rsi, UREGS_rsi(%rdi) -+ popq %rbp -+ movq %rbx, UREGS_rbx(%rdi) -+ movq %rdx, UREGS_rdx(%rdi) -+ popq %rbx -+ movq %rcx, UREGS_rcx(%rdi) -+ popq %rcx -+ ret -Index: xen-unstable/xen/arch/x86/x86_64/traps.c -=================================================================== ---- xen-unstable.orig/xen/arch/x86/x86_64/traps.c -+++ xen-unstable/xen/arch/x86/x86_64/traps.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -337,6 +338,29 @@ void __init percpu_traps_init(void) - - wrmsr(MSR_STAR, 0, (FLAT_RING3_CS32<<16) | __HYPERVISOR_CS); - wrmsr(MSR_SYSCALL_MASK, EF_VM|EF_RF|EF_NT|EF_DF|EF_IE|EF_TF, 0U); -+ -+ /* -+ * Stub for full-context I/O emulation. -+ */ -+ -+ /* Skip the compatibility-mode entry trampoline. */ -+ stack += 26; -+ if ( !io_emul_stub_offset ) -+ io_emul_stub_offset = stack - stack_bottom; -+ else -+ BUG_ON(io_emul_stub_offset != stack - stack_bottom); -+ /* call save_host_restore_guest */ -+ stack[0] = 0xe8; -+ *(s32*)&stack[1] = (char *)save_host_restore_guest - &stack[5]; -+ stack += 5; -+ if ( !io_emul_insn_offset ) -+ io_emul_insn_offset = stack - stack_bottom; -+ else -+ BUG_ON(io_emul_insn_offset != stack - stack_bottom); -+ stack += 3; /* operand size prefix, opcode, immediate */ -+ /* jmp save_guest_restore_host */ -+ stack[0] = 0xe9; -+ *(s32*)&stack[1] = (char *)save_guest_restore_host - &stack[5]; - } - - static long register_guest_callback(struct callback_register *reg) -Index: xen-unstable/xen/include/asm-x86/io.h -=================================================================== ---- xen-unstable.orig/xen/include/asm-x86/io.h -+++ xen-unstable/xen/include/asm-x86/io.h -@@ -50,4 +50,10 @@ __OUT(b,"b",char) - __OUT(w,"w",short) - __OUT(l,,int) - -+struct cpu_user_regs; -+void save_host_restore_guest(struct cpu_user_regs *) __attribute__((__regparm__(1))); -+unsigned long save_guest_restore_host(unsigned long) __attribute__((__regparm__(1))); -+ -+extern long io_emul_stub_offset, io_emul_insn_offset; -+ - #endif -Index: xen-unstable/xen/include/asm-x86/iocap.h -=================================================================== ---- xen-unstable.orig/xen/include/asm-x86/iocap.h -+++ xen-unstable/xen/include/asm-x86/iocap.h -@@ -7,6 +7,15 @@ - #ifndef __X86_IOCAP_H__ - #define __X86_IOCAP_H__ - -+extern struct rangeset *ioport_caps, *ioport_emul; -+ -+#define ioports_permit_access_all(s, e) \ -+ rangeset_add_range(ioport_caps, s, e) -+#define ioports_deny_access_all(s, e) \ -+ rangeset_remove_range(ioport_caps, s, e) -+#define ioports_any_access_permitted(s, e) \ -+ rangeset_contains_range(ioport_caps, s, e) -+ - #define ioports_permit_access(d, s, e) \ - rangeset_add_range((d)->arch.ioport_caps, s, e) - #define ioports_deny_access(d, s, e) \ -@@ -14,6 +23,13 @@ - #define ioports_access_permitted(d, s, e) \ - rangeset_contains_range((d)->arch.ioport_caps, s, e) - -+#define ioports_set_emul(s, e) \ -+ rangeset_add_range(ioport_emul, s, e) -+#define ioports_set_noemul(s, e) \ -+ rangeset_remove_range(ioport_emul, s, e) -+#define ioports_emul(s, e) \ -+ rangeset_contains_range(ioport_emul, s, e) -+ - #define cache_flush_permitted(d) \ - (!rangeset_is_empty((d)->iomem_caps)) - -Index: xen-unstable/xen/include/public/sysctl.h -=================================================================== ---- xen-unstable.orig/xen/include/public/sysctl.h -+++ xen-unstable/xen/include/public/sysctl.h -@@ -122,6 +122,15 @@ struct xen_sysctl_getdomaininfolist { - typedef struct xen_sysctl_getdomaininfolist xen_sysctl_getdomaininfolist_t; - DEFINE_XEN_GUEST_HANDLE(xen_sysctl_getdomaininfolist_t); - -+#define XEN_SYSCTL_ioport_emulation 7 -+struct xen_sysctl_ioport_emulation { -+ uint32_t first_port; /* first port int range */ -+ uint32_t nr_ports; /* size of port range */ -+ uint8_t emulate; /* emulate access to range? */ -+}; -+typedef struct xen_sysctl_ioport_emulation xen_sysctl_ioport_emulation_t; -+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_ioport_emulation_t); -+ - struct xen_sysctl { - uint32_t cmd; - uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */ -@@ -132,6 +141,7 @@ struct xen_sysctl { - struct xen_sysctl_sched_id sched_id; - struct xen_sysctl_perfc_op perfc_op; - struct xen_sysctl_getdomaininfolist getdomaininfolist; -+ struct xen_sysctl_ioport_emulation ioport_emulation; - uint8_t pad[128]; - } u; - }; diff --git a/xen-ioapic-ack-default.diff b/xen-ioapic-ack-default.diff index bb722bb..55d9227 100644 --- a/xen-ioapic-ack-default.diff +++ b/xen-ioapic-ack-default.diff @@ -1,11 +1,11 @@ Change default IO-APIC ack mode for single IO-APIC systems to old-style. Jan -Index: xen-unstable/xen/arch/x86/io_apic.c +Index: xen-3.0.4-testing/xen/arch/x86/io_apic.c =================================================================== ---- xen-unstable.orig/xen/arch/x86/io_apic.c -+++ xen-unstable/xen/arch/x86/io_apic.c -@@ -1342,7 +1342,7 @@ static unsigned int startup_level_ioapic +--- xen-3.0.4-testing.orig/xen/arch/x86/io_apic.c ++++ xen-3.0.4-testing/xen/arch/x86/io_apic.c +@@ -1339,7 +1339,7 @@ static unsigned int startup_level_ioapic return 0; /* don't check for pending */ } @@ -14,7 +14,7 @@ Index: xen-unstable/xen/arch/x86/io_apic.c static void setup_ioapic_ack(char *s) { if ( !strcmp(s, "old") ) -@@ -1779,6 +1779,8 @@ void __init setup_IO_APIC(void) +@@ -1776,6 +1776,8 @@ void __init setup_IO_APIC(void) else io_apic_irqs = ~PIC_IRQS; diff --git a/xen-keymap.diff b/xen-keymap.diff deleted file mode 100644 index 5c5bb81..0000000 --- a/xen-keymap.diff +++ /dev/null @@ -1,47 +0,0 @@ -Index: xen-3.0.3-testing/tools/python/xen/xm/create.py -=================================================================== ---- xen-3.0.3-testing.orig/tools/python/xen/xm/create.py -+++ xen-3.0.3-testing/tools/python/xen/xm/create.py -@@ -428,6 +428,10 @@ gopts.var('sdl', val='', - fn=set_value, default=None, - use="""Should the device model use SDL?""") - -+gopts.var('keymap', val='', -+ fn=set_value, default=None, -+ use="""Keyboard mapping for SDL/VNC""") -+ - gopts.var('display', val='DISPLAY', - fn=set_value, default=None, - use="X11 display to use") -@@ -639,7 +643,7 @@ def configure_hvm(config_image, vals): - 'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'soundhw', - 'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'vnclisten', - 'sdl', 'display', 'xauthority', -- 'acpi', 'apic', 'usb', 'usbdevice' ] -+ 'acpi', 'apic', 'usb', 'usbdevice', 'keymap' ] - for a in args: - if (vals.__dict__[a]): - config_image.append([a, vals.__dict__[a]]) -Index: xen-3.0.3-testing/tools/python/xen/xend/image.py -=================================================================== ---- xen-3.0.3-testing.orig/tools/python/xen/xend/image.py -+++ xen-3.0.3-testing/tools/python/xen/xend/image.py -@@ -352,6 +352,10 @@ class HVMImageHandler(ImageHandler): - if nographic: - ret.append('-nographic') - return ret -+ keymap = sxp.child_value(config, 'keymap') -+ if not keymap: -+ keymap = "en-us" -+ ret += ['-k', keymap] - if vnc: - vncdisplay = sxp.child_value(config, 'vncdisplay', - int(self.vm.getDomid())) -@@ -360,7 +364,6 @@ class HVMImageHandler(ImageHandler): - ret += ['-vncunused'] - else: - ret += ['-vnc', '%d' % vncdisplay] -- ret += ['-k', 'en-us'] - vnclisten = sxp.child_value(config, 'vnclisten') - if not(vnclisten): - vnclisten = xen.xend.XendRoot.instance().get_vnclisten_address() diff --git a/xen-localtime.patch b/xen-localtime.patch new file mode 100644 index 0000000..4ffab17 --- /dev/null +++ b/xen-localtime.patch @@ -0,0 +1,14 @@ +Fix usage of localtime parameter in PV guest configuration +Signed-off-by: Bruce Rogers + +--- a/tools/python/xen/xend/XendDomainInfo.py 2007-01-20 08:19:11.877589448 -0700 ++++ b/tools/python/xen/xend/XendDomainInfo.py 2007-01-20 09:20:59.805618252 -0700 +@@ -1361,7 +1361,7 @@ + self.info['image'], + self.info['devices']) + +- localtime = self.info.get('localtime', False) ++ localtime = self.info.get('platform_localtime', False) + if localtime: + xc.domain_set_time_offset(self.domid) + diff --git a/xen-lost-mouse.diff b/xen-lost-mouse.diff index a13cb15..1baa502 100644 --- a/xen-lost-mouse.diff +++ b/xen-lost-mouse.diff @@ -5,16 +5,16 @@ SIGKILL causes atexit to not be called, so mouse SDL cleanup wasn't performed, so mouse wasn't released. -Index: xen-unstable/tools/python/xen/xend/image.py +Index: xen-3.0.4-testing/tools/python/xen/xend/image.py =================================================================== ---- xen-unstable.orig/tools/python/xen/xend/image.py -+++ xen-unstable/tools/python/xen/xend/image.py -@@ -412,7 +412,7 @@ class HVMImageHandler(ImageHandler): - import signal - if not self.pid: - return -- os.kill(self.pid, signal.SIGKILL) -+ os.kill(self.pid, signal.SIGTERM) - os.waitpid(self.pid, 0) - self.pid = 0 - +--- xen-3.0.4-testing.orig/tools/python/xen/xend/image.py ++++ xen-3.0.4-testing/tools/python/xen/xend/image.py +@@ -502,7 +502,7 @@ class HVMImageHandler(ImageHandler): + self.unregister_reboot_feature_watch(); + if self.pid: + try: +- os.kill(self.pid, signal.SIGKILL) ++ os.kill(self.pid, signal.SIGTERM) + except OSError, exn: + log.exception(exn) + try: diff --git a/xen-lowmem-emergency-pool.diff b/xen-lowmem-emergency-pool.diff index 197473c..822882e 100644 --- a/xen-lowmem-emergency-pool.diff +++ b/xen-lowmem-emergency-pool.diff @@ -1,7 +1,7 @@ -Index: xen-unstable/xen/arch/x86/x86_32/mm.c +Index: xen-3.0.4-testing/xen/arch/x86/x86_32/mm.c =================================================================== ---- xen-unstable.orig/xen/arch/x86/x86_32/mm.c -+++ xen-unstable/xen/arch/x86/x86_32/mm.c +--- xen-3.0.4-testing.orig/xen/arch/x86/x86_32/mm.c ++++ xen-3.0.4-testing/xen/arch/x86/x86_32/mm.c @@ -62,6 +62,8 @@ l2_pgentry_t *virt_to_xen_l2e(unsigned l return &idle_pg_table_l2[l2_linear_offset(v)]; } @@ -11,37 +11,49 @@ Index: xen-unstable/xen/arch/x86/x86_32/mm.c void __init paging_init(void) { void *ioremap_pt; -@@ -129,6 +131,20 @@ void __init setup_idle_pagetable(void) - l2e_from_page(virt_to_page(idle_vcpu[0]->domain-> - arch.mm_perdomain_pt) + i, - __PAGE_HYPERVISOR); +@@ -130,6 +132,20 @@ void __init setup_idle_pagetable(void) + l2e_from_page(virt_to_page(idle_vcpu[0]->domain-> + arch.mm_perdomain_pt) + i, + __PAGE_HYPERVISOR)); + + /* + * Size the lowmem_emergency_pool based on the total memory on the box + * This pool is needed only on 32 bit PAE configurations (4g to 16g). + */ + if (lowmem_emergency_pool_pages) -+ return; ++ return; + + if (total_pages > (4 * 1024 * 1024)) -+ lowmem_emergency_pool_pages = 12000; ++ lowmem_emergency_pool_pages = 12000; + else if (total_pages > (2 * 1024 * 1024)) -+ lowmem_emergency_pool_pages = 8000; ++ lowmem_emergency_pool_pages = 8000; + else if (total_pages > (1 * 1024 * 1024) || max_page >= (1 * 1024 * 1024)) -+ lowmem_emergency_pool_pages = 4000; ++ lowmem_emergency_pool_pages = 4000; } void __init zap_low_mappings(l2_pgentry_t *base) -Index: xen-unstable/xen/common/page_alloc.c +Index: xen-3.0.4-testing/xen/common/page_alloc.c =================================================================== ---- xen-unstable.orig/xen/common/page_alloc.c -+++ xen-unstable/xen/common/page_alloc.c -@@ -47,7 +47,7 @@ string_param("badpage", opt_badpage); - * allocation requests. Ordinary requests will not fall back to the - * lowmem emergency pool. - */ --static unsigned long lowmem_emergency_pool_pages; +--- xen-3.0.4-testing.orig/xen/common/page_alloc.c ++++ xen-3.0.4-testing/xen/common/page_alloc.c +@@ -46,6 +46,20 @@ static char opt_badpage[100] = ""; + string_param("badpage", opt_badpage); + + /* ++ * Amount of memory to reserve in a low-memory (<4GB) pool for specific ++ * allocation requests. Ordinary requests will not fall back to the ++ * lowmem emergency pool. ++ */ +unsigned long lowmem_emergency_pool_pages; - static void parse_lowmem_emergency_pool(char *s) - { - unsigned long long bytes; ++static void parse_lowmem_emergency_pool(char *s) ++{ ++ unsigned long long bytes; ++ bytes = parse_size_and_unit(s, NULL); ++ lowmem_emergency_pool_pages = bytes >> PAGE_SHIFT; ++} ++custom_param("lowmem_emergency_pool", parse_lowmem_emergency_pool); ++ ++/* + * Bit width of the DMA heap. + */ + unsigned int dma_bitsize = CONFIG_DMA_BITSIZE; diff --git a/xen-man-permissions.patch b/xen-man-permissions.patch index 3d0efe9..dc61d30 100644 --- a/xen-man-permissions.patch +++ b/xen-man-permissions.patch @@ -1,7 +1,7 @@ -Index: xen-3.0.3-testing/tools/ioemu/Makefile +Index: xen-3.0.4-testing/tools/ioemu/Makefile =================================================================== ---- xen-3.0.3-testing.orig/tools/ioemu/Makefile -+++ xen-3.0.3-testing/tools/ioemu/Makefile +--- xen-3.0.4-testing.orig/tools/ioemu/Makefile ++++ xen-3.0.4-testing/tools/ioemu/Makefile @@ -68,7 +68,7 @@ install-doc: $(DOCS) $(INSTALL) -m 644 qemu-doc.html qemu-tech.html "$(DESTDIR)$(docdir)" ifndef CONFIG_WIN32 diff --git a/xen-man-xm-bad-char.diff b/xen-man-xm-bad-char.diff index 2c61c7b..be92d1b 100644 --- a/xen-man-xm-bad-char.diff +++ b/xen-man-xm-bad-char.diff @@ -1,7 +1,7 @@ -Index: xen-3.0.3-testing/docs/man/xm.pod.1 +Index: xen-3.0.4-testing/docs/man/xm.pod.1 =================================================================== ---- xen-3.0.3-testing.orig/docs/man/xm.pod.1 -+++ xen-3.0.3-testing/docs/man/xm.pod.1 +--- xen-3.0.4-testing.orig/docs/man/xm.pod.1 ++++ xen-3.0.4-testing/docs/man/xm.pod.1 @@ -554,29 +554,29 @@ B I diff --git a/xen-max-free-mem.diff b/xen-max-free-mem.diff index 560f6d7..65ccb2b 100644 --- a/xen-max-free-mem.diff +++ b/xen-max-free-mem.diff @@ -1,8 +1,8 @@ -Index: xen-3.0.3-testing/tools/python/xen/xend/XendNode.py +Index: xen-3.0.4-testing/tools/python/xen/xend/XendNode.py =================================================================== ---- xen-3.0.3-testing.orig/tools/python/xen/xend/XendNode.py -+++ xen-3.0.3-testing/tools/python/xen/xend/XendNode.py -@@ -59,9 +59,34 @@ class XendNode: +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendNode.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendNode.py +@@ -159,9 +159,34 @@ class XendNode: info['cores_per_socket'] * info['threads_per_core']) info['cpu_mhz'] = info['cpu_khz'] / 1000 @@ -40,7 +40,7 @@ Index: xen-3.0.3-testing/tools/python/xen/xend/XendNode.py ITEM_ORDER = ['nr_cpus', 'nr_nodes', -@@ -72,6 +97,9 @@ class XendNode: +@@ -172,6 +197,9 @@ class XendNode: 'hw_caps', 'total_memory', 'free_memory', @@ -50,10 +50,10 @@ Index: xen-3.0.3-testing/tools/python/xen/xend/XendNode.py ] return [[k, info[k]] for k in ITEM_ORDER] -Index: xen-3.0.3-testing/tools/python/xen/xend/balloon.py +Index: xen-3.0.4-testing/tools/python/xen/xend/balloon.py =================================================================== ---- xen-3.0.3-testing.orig/tools/python/xen/xend/balloon.py -+++ xen-3.0.3-testing/tools/python/xen/xend/balloon.py +--- xen-3.0.4-testing.orig/tools/python/xen/xend/balloon.py ++++ xen-3.0.4-testing/tools/python/xen/xend/balloon.py @@ -43,6 +43,8 @@ SLEEP_TIME_GROWTH = 0.1 # label actually shown in the PROC_XEN_BALLOON file. labels = { 'current' : 'Current allocation', @@ -87,13 +87,13 @@ Index: xen-3.0.3-testing/tools/python/xen/xend/balloon.py def free(need_mem): """Balloon out memory from the privileged domain so that there is the specified required amount (in KiB) free. -Index: xen-3.0.3-testing/tools/python/xen/xend/XendDomainInfo.py +Index: xen-3.0.4-testing/tools/python/xen/xend/XendDomainInfo.py =================================================================== ---- xen-3.0.3-testing.orig/tools/python/xen/xend/XendDomainInfo.py -+++ xen-3.0.3-testing/tools/python/xen/xend/XendDomainInfo.py -@@ -1005,6 +1005,27 @@ class XendDomainInfo: +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendDomainInfo.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendDomainInfo.py +@@ -540,6 +540,27 @@ class XendDomainInfo: + return sxprs - ## public: + def capAndSetMemoryTarget(self, target): + """Potentially lowers the requested target to the largest possible @@ -118,12 +118,12 @@ Index: xen-3.0.3-testing/tools/python/xen/xend/XendDomainInfo.py + def setMemoryTarget(self, target): """Set the memory target of this domain. - @param target In MiB. -Index: xen-3.0.3-testing/tools/python/xen/xend/server/SrvDomain.py + @param target: In MiB. +Index: xen-3.0.4-testing/tools/python/xen/xend/server/SrvDomain.py =================================================================== ---- xen-3.0.3-testing.orig/tools/python/xen/xend/server/SrvDomain.py -+++ xen-3.0.3-testing/tools/python/xen/xend/server/SrvDomain.py -@@ -147,7 +147,7 @@ class SrvDomain(SrvDir): +--- xen-3.0.4-testing.orig/tools/python/xen/xend/server/SrvDomain.py ++++ xen-3.0.4-testing/tools/python/xen/xend/server/SrvDomain.py +@@ -169,7 +169,7 @@ class SrvDomain(SrvDir): def op_mem_target_set(self, _, req): diff --git a/xen-messages.diff b/xen-messages.diff index 0bcc0c8..cccb5c1 100644 --- a/xen-messages.diff +++ b/xen-messages.diff @@ -1,11 +1,18 @@ -Index: xen-unstable/tools/misc/xend +Index: xen-3.0.4-testing/tools/misc/xend =================================================================== ---- xen-unstable.orig/tools/misc/xend -+++ xen-unstable/tools/misc/xend -@@ -64,14 +64,7 @@ def check_logging(): - try: - import logging - except ImportError: +--- xen-3.0.4-testing.orig/tools/misc/xend ++++ xen-3.0.4-testing/tools/misc/xend +@@ -60,22 +60,6 @@ def hline(): + def msg(message): + print >>sys.stderr, "*" * 3, message + +-def check_logging(): +- """Check python logging is installed and raise an error if not. +- Logging is standard from Python 2.3 on. +- """ +- try: +- import logging +- except ImportError: - hline() - msg("Python logging is not installed.") - msg("Use 'make install-logging' at the xen root to install.") @@ -14,20 +21,28 @@ Index: xen-unstable/tools/misc/xend - msg("http://www.red-dove.com/python_logging.html") - hline() - raise CheckError("logging is not installed") -+ raise CheckError("logging is not installed; try Python 2.3 or later") - +- def check_user(): """Check that the effective user id is 0 (root). -Index: xen-unstable/tools/python/xen/xend/XendDomain.py + """ +@@ -102,7 +86,6 @@ def start_blktapctrl(): + + def main(): + try: +- check_logging() + check_user() + except CheckError: + sys.exit(1) +Index: xen-3.0.4-testing/tools/python/xen/xend/XendDomain.py =================================================================== ---- xen-unstable.orig/tools/python/xen/xend/XendDomain.py -+++ xen-unstable/tools/python/xen/xend/XendDomain.py -@@ -467,6 +467,8 @@ class XendDomain: +--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendDomain.py ++++ xen-3.0.4-testing/tools/python/xen/xend/XendDomain.py +@@ -780,6 +780,8 @@ class XendDomain: - if dominfo.getDomid() == PRIV_DOMAIN: - raise XendError("Cannot save privileged domain %s" % domid) + if dominfo.getDomid() == DOM0_ID: + raise XendError("Cannot save privileged domain %s" % domname) + if dominfo.readVm('image/ostype') == "hvm": + raise XendError("Cannot save fully virtualized domains") - fd = os.open(dst, os.O_WRONLY | os.O_CREAT | os.O_TRUNC) - try: + if dominfo.state != DOM_STATE_RUNNING: + raise XendError("Cannot suspend domain that is not running.") diff --git a/xen-network-bridge.diff b/xen-network-bridge.diff index 1f028cf..c136f36 100644 --- a/xen-network-bridge.diff +++ b/xen-network-bridge.diff @@ -1,7 +1,7 @@ -Index: xen-3.0.3-testing/tools/examples/network-bridge +Index: xen-3.0.4-testing/tools/examples/network-bridge =================================================================== ---- xen-3.0.3-testing.orig/tools/examples/network-bridge -+++ xen-3.0.3-testing/tools/examples/network-bridge +--- xen-3.0.4-testing.orig/tools/examples/network-bridge ++++ xen-3.0.4-testing/tools/examples/network-bridge @@ -69,23 +69,6 @@ pdev="p${netdev}" vdev="veth${vifnum}" vif0="vif0.${vifnum}" @@ -74,10 +74,10 @@ Index: xen-3.0.3-testing/tools/examples/network-bridge else transfer_routes ${bridge} ${netdev} ip link set ${bridge} down -Index: xen-3.0.3-testing/tools/examples/xen-network-common.sh +Index: xen-3.0.4-testing/tools/examples/xen-network-common.sh =================================================================== ---- xen-3.0.3-testing.orig/tools/examples/xen-network-common.sh -+++ xen-3.0.3-testing/tools/examples/xen-network-common.sh +--- xen-3.0.4-testing.orig/tools/examples/xen-network-common.sh ++++ xen-3.0.4-testing/tools/examples/xen-network-common.sh @@ -16,57 +16,33 @@ # diff --git a/xen-no-dummy-nfs-ip.diff b/xen-no-dummy-nfs-ip.diff index 5ed5cc5..2c8b3e2 100644 --- a/xen-no-dummy-nfs-ip.diff +++ b/xen-no-dummy-nfs-ip.diff @@ -1,8 +1,8 @@ -Index: xen-unstable/tools/python/xen/xm/create.py +Index: xen-3.0.4-testing/tools/python/xen/xm/create.py =================================================================== ---- xen-unstable.orig/tools/python/xen/xm/create.py -+++ xen-unstable/tools/python/xen/xm/create.py -@@ -808,9 +808,8 @@ def preprocess_access_control(vals): +--- xen-3.0.4-testing.orig/tools/python/xen/xm/create.py ++++ xen-3.0.4-testing/tools/python/xen/xm/create.py +@@ -868,9 +868,8 @@ def preprocess_access_control(vals): def preprocess_ip(vals): if vals.ip or vals.dhcp != 'off': diff --git a/xen-poweroff.diff b/xen-poweroff.diff deleted file mode 100644 index eb98fc7..0000000 --- a/xen-poweroff.diff +++ /dev/null @@ -1,57 +0,0 @@ -diff -uNrp xen-2.0-testing/xen/arch/x86/acpi.c xen-2.0-testing.pwroff/xen/arch/x86/acpi.c ---- xen-2.0-testing/xen/arch/x86/acpi.c 2005-03-01 04:45:17.000000000 +0100 -+++ xen-2.0-testing.pwroff/xen/arch/x86/acpi.c 2005-03-01 15:48:13.011511087 +0100 -@@ -719,3 +719,13 @@ acpi_sleep_done: - - #endif /*CONFIG_ACPI_SLEEP*/ - -+int acpi_poweroff() -+{ -+ if (acpi_enter_sleep_state_prep (ACPI_STATE_S5) == AE_OK) { -+ __asm__ __volatile__ ( "cli" ); -+ acpi_enter_sleep_state (ACPI_STATE_S5); -+ __asm__ __volatile__ ( "sti" ); -+ acpi_leave_sleep_state (ACPI_STATE_S5); -+ } -+ return 1; -+} -diff -uNrp xen-2.0-testing/xen/arch/x86/domain.c xen-2.0-testing.pwroff/xen/arch/x86/domain.c ---- xen-2.0-testing/xen/arch/x86/domain.c 2005-03-01 04:45:18.000000000 +0100 -+++ xen-2.0-testing.pwroff/xen/arch/x86/domain.c 2005-03-01 15:48:26.133212475 +0100 -@@ -34,6 +34,7 @@ - #include - #include - #include -+#include - - /* opt_noreboot: If true, machine will need manual reset on error. */ - static int opt_noreboot = 0; -@@ -186,6 +187,7 @@ void machine_restart(char * __unused) - - void __attribute__((noreturn)) __machine_halt(void *unused) - { -+ acpi_poweroff(); - for ( ; ; ) - __asm__ __volatile__ ( "cli; hlt" ); - } -diff -uNrp xen-2.0-testing/xen/drivers/acpi/acpi_ksyms.c xen-2.0-testing.pwroff/xen/drivers/acpi/acpi_ksyms.c ---- xen-2.0-testing/xen/drivers/acpi/acpi_ksyms.c 2005-03-01 04:45:17.000000000 +0100 -+++ xen-2.0-testing.pwroff/xen/drivers/acpi/acpi_ksyms.c 2005-03-01 15:36:50.941976570 +0100 -@@ -87,6 +87,7 @@ EXPORT_SYMBOL(acpi_get_register); - EXPORT_SYMBOL(acpi_set_register); - EXPORT_SYMBOL(acpi_enter_sleep_state); - EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios); -+EXPORT_SYMBOL(acpi_leave_sleep_state); - EXPORT_SYMBOL(acpi_get_system_info); - EXPORT_SYMBOL(acpi_get_devices); - -diff -uNrp xen-2.0-testing/xen/include/asm-x86/acpi.h xen-2.0-testing.pwroff/xen/include/asm-x86/acpi.h ---- xen-2.0-testing/xen/include/asm-x86/acpi.h 2005-03-01 04:45:21.000000000 +0100 -+++ xen-2.0-testing.pwroff/xen/include/asm-x86/acpi.h 2005-03-01 15:49:22.719299798 +0100 -@@ -163,4 +163,6 @@ extern void acpi_reserve_bootmem(void); - - #endif /*CONFIG_ACPI_SLEEP*/ - -+extern int acpi_poweroff(void); -+ - #endif /*_ASM_ACPI_H*/ diff --git a/xen-pvfb-2.patch b/xen-pvfb-2.patch deleted file mode 100644 index 6822249..0000000 --- a/xen-pvfb-2.patch +++ /dev/null @@ -1,1122 +0,0 @@ -Index: xen-unstable/tools/Makefile -=================================================================== ---- xen-unstable.orig/tools/Makefile -+++ xen-unstable/tools/Makefile -@@ -18,6 +18,7 @@ SUBDIRS-$(VTPM_TOOLS) += vtpm - SUBDIRS-y += xenstat - SUBDIRS-y += libaio - SUBDIRS-y += blktap -+SUBDIRS-y += xenfb - - # These don't cross-compile - ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH)) -Index: xen-unstable/tools/xenfb/Makefile -=================================================================== ---- /dev/null -+++ xen-unstable/tools/xenfb/Makefile -@@ -0,0 +1,36 @@ -+XEN_ROOT=../.. -+include $(XEN_ROOT)/tools/Rules.mk -+ -+CFLAGS += -g -Wall -+CFLAGS += -I$(XEN_LIBXC) -I$(XEN_XENSTORE) -I$(XEN_ROOT)/linux-2.6-xen-sparse/include -+LDFLAGS += -L$(XEN_LIBXC) -L$(XEN_XENSTORE) -+ -+INSTALL = install -+INSTALL_PROG = $(INSTALL) -m0755 -+INSTALL_DIR = $(INSTALL) -d -m0755 -+ -+.PHONY: all -+all: build -+ -+.PHONY: build -+build: mk-symlinks -+ $(MAKE) vncfb sdlfb -+ -+install: all -+ $(INSTALL_DIR) -p $(DESTDIR)/usr/$(LIBDIR)/xen/bin -+ $(INSTALL_PROG) vncfb $(DESTDIR)/usr/$(LIBDIR)/xen/bin/xen-vncfb -+ $(INSTALL_PROG) sdlfb $(DESTDIR)/usr/$(LIBDIR)/xen/bin/xen-sdlfb -+ -+sdlfb: sdlfb.o xenfb.o -+ -+sdlfb.o: CFLAGS += $(shell sdl-config --cflags) -+sdlfb: LDLIBS += $(shell sdl-config --libs) -lxenctrl -lxenstore -+ -+clean: -+ $(RM) *.o *~ vncfb sdlfb -+ -+keymapping.o: CFLAGS += $(shell pkg-config --cflags gtk+-2.0) -+ -+vncfb: vncfb.o xenfb.o keymapping.o -+vncfb.o: CFLAGS += $(shell libvncserver-config --cflags) -+vncfb: LDLIBS += $(shell libvncserver-config --libs) -lxenctrl -lxenstore -Index: xen-unstable/tools/xenfb/keymapping.c -=================================================================== ---- /dev/null -+++ xen-unstable/tools/xenfb/keymapping.c -@@ -0,0 +1,141 @@ -+#include -+#include -+#include -+ -+uint32_t gdk_linux_mapping[0x10000] = { -+ [GDK_a] = KEY_A, -+ [GDK_b] = KEY_B, -+ [GDK_c] = KEY_C, -+ [GDK_d] = KEY_D, -+ [GDK_e] = KEY_E, -+ [GDK_f] = KEY_F, -+ [GDK_g] = KEY_G, -+ [GDK_h] = KEY_H, -+ [GDK_i] = KEY_I, -+ [GDK_j] = KEY_J, -+ [GDK_k] = KEY_K, -+ [GDK_l] = KEY_L, -+ [GDK_m] = KEY_M, -+ [GDK_n] = KEY_N, -+ [GDK_o] = KEY_O, -+ [GDK_p] = KEY_P, -+ [GDK_q] = KEY_Q, -+ [GDK_r] = KEY_R, -+ [GDK_s] = KEY_S, -+ [GDK_t] = KEY_T, -+ [GDK_u] = KEY_U, -+ [GDK_v] = KEY_V, -+ [GDK_w] = KEY_W, -+ [GDK_x] = KEY_X, -+ [GDK_y] = KEY_Y, -+ [GDK_z] = KEY_Z, -+ [GDK_A] = KEY_A, -+ [GDK_B] = KEY_B, -+ [GDK_C] = KEY_C, -+ [GDK_D] = KEY_D, -+ [GDK_E] = KEY_E, -+ [GDK_F] = KEY_F, -+ [GDK_G] = KEY_G, -+ [GDK_H] = KEY_H, -+ [GDK_I] = KEY_I, -+ [GDK_J] = KEY_J, -+ [GDK_K] = KEY_K, -+ [GDK_L] = KEY_L, -+ [GDK_M] = KEY_M, -+ [GDK_N] = KEY_N, -+ [GDK_O] = KEY_O, -+ [GDK_P] = KEY_P, -+ [GDK_Q] = KEY_Q, -+ [GDK_R] = KEY_R, -+ [GDK_S] = KEY_S, -+ [GDK_T] = KEY_T, -+ [GDK_U] = KEY_U, -+ [GDK_V] = KEY_V, -+ [GDK_W] = KEY_W, -+ [GDK_X] = KEY_X, -+ [GDK_Y] = KEY_Y, -+ [GDK_Z] = KEY_Z, -+ [GDK_0] = KEY_0, -+ [GDK_1] = KEY_1, -+ [GDK_2] = KEY_2, -+ [GDK_3] = KEY_3, -+ [GDK_4] = KEY_4, -+ [GDK_5] = KEY_5, -+ [GDK_6] = KEY_6, -+ [GDK_7] = KEY_7, -+ [GDK_8] = KEY_8, -+ [GDK_9] = KEY_9, -+ [GDK_Return] = KEY_ENTER, -+ [GDK_BackSpace] = KEY_BACKSPACE, -+ [GDK_Tab] = KEY_TAB, -+ [GDK_Pause] = KEY_PAUSE, -+ [GDK_Delete] = KEY_DELETE, -+ [GDK_slash] = KEY_SLASH, -+ [GDK_minus] = KEY_MINUS, -+ [GDK_equal] = KEY_EQUAL, -+ [GDK_Escape] = KEY_ESC, -+ [GDK_braceleft] = KEY_LEFTBRACE, -+ [GDK_braceright] = KEY_RIGHTBRACE, -+ [GDK_bracketleft] = KEY_LEFTMETA, -+ [GDK_bracketright] = KEY_RIGHTMETA, -+ [GDK_Control_L] = KEY_LEFTCTRL, -+ [GDK_Control_R] = KEY_RIGHTCTRL, -+ [GDK_Shift_L] = KEY_LEFTSHIFT, -+ [GDK_Shift_R] = KEY_RIGHTSHIFT, -+ [GDK_Alt_L] = KEY_LEFTALT, -+ [GDK_Alt_R] = KEY_RIGHTALT, -+ [GDK_semicolon] = KEY_SEMICOLON, -+ [GDK_apostrophe] = KEY_APOSTROPHE, -+ [GDK_grave] = KEY_GRAVE, -+ [GDK_backslash] = KEY_BACKSLASH, -+ [GDK_comma] = KEY_COMMA, -+ [GDK_period] = KEY_DOT, -+ [GDK_space] = KEY_SPACE, -+ [GDK_Caps_Lock] = KEY_CAPSLOCK, -+ [GDK_Num_Lock] = KEY_NUMLOCK, -+ [GDK_Scroll_Lock] = KEY_SCROLLLOCK, -+ [GDK_Sys_Req] = KEY_SYSRQ, -+ [GDK_Linefeed] = KEY_LINEFEED, -+ [GDK_Home] = KEY_HOME, -+ [GDK_Pause] = KEY_PAUSE, -+ [GDK_F1] = KEY_F1, -+ [GDK_F2] = KEY_F2, -+ [GDK_F3] = KEY_F3, -+ [GDK_F4] = KEY_F4, -+ [GDK_F5] = KEY_F5, -+ [GDK_F6] = KEY_F6, -+ [GDK_F7] = KEY_F7, -+ [GDK_F8] = KEY_F8, -+ [GDK_F9] = KEY_F9, -+ [GDK_F10] = KEY_F10, -+ [GDK_F11] = KEY_F11, -+ [GDK_F12] = KEY_F12, -+ [GDK_Up] = KEY_UP, -+ [GDK_Page_Up] = KEY_PAGEUP, -+ [GDK_Left] = KEY_LEFT, -+ [GDK_Right] = KEY_RIGHT, -+ [GDK_End] = KEY_END, -+ [GDK_Down] = KEY_DOWN, -+ [GDK_Page_Down] = KEY_PAGEDOWN, -+ [GDK_Insert] = KEY_INSERT, -+ [GDK_colon] = KEY_SEMICOLON, -+ [GDK_quotedbl] = KEY_APOSTROPHE, -+ [GDK_less] = KEY_COMMA, -+ [GDK_greater] = KEY_DOT, -+ [GDK_question] = KEY_SLASH, -+ [GDK_bar] = KEY_BACKSLASH, -+ [GDK_asciitilde] = KEY_GRAVE, -+ [GDK_exclam] = KEY_1, -+ [GDK_at] = KEY_2, -+ [GDK_numbersign] = KEY_3, -+ [GDK_dollar] = KEY_4, -+ [GDK_percent] = KEY_5, -+ [GDK_asciicircum] = KEY_6, -+ [GDK_ampersand] = KEY_7, -+ [GDK_asterisk] = KEY_8, -+ [GDK_parenleft] = KEY_9, -+ [GDK_parenright] = KEY_0, -+ [GDK_underscore] = KEY_MINUS, -+ [GDK_plus] = KEY_EQUAL, -+}; -+ -Index: xen-unstable/tools/xenfb/sdlfb.c -=================================================================== ---- /dev/null -+++ xen-unstable/tools/xenfb/sdlfb.c -@@ -0,0 +1,191 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "xenfb.h" -+ -+struct data -+{ -+ SDL_Surface *dst; -+ SDL_Surface *src; -+}; -+ -+void sdl_update(struct xenfb *xenfb, int x, int y, int width, int height) -+{ -+ struct data *data = xenfb->user_data; -+ SDL_Rect r = { x, y, width, height }; -+ SDL_BlitSurface(data->src, &r, data->dst, &r); -+ SDL_UpdateRect(data->dst, x, y, width, height); -+} -+ -+int sdl2linux[1024] = { -+ [SDLK_a] = KEY_A, -+ [SDLK_b] = KEY_B, -+ [SDLK_c] = KEY_C, -+ [SDLK_d] = KEY_D, -+ [SDLK_e] = KEY_E, -+ [SDLK_f] = KEY_F, -+ [SDLK_g] = KEY_G, -+ [SDLK_h] = KEY_H, -+ [SDLK_i] = KEY_I, -+ [SDLK_j] = KEY_J, -+ [SDLK_k] = KEY_K, -+ [SDLK_l] = KEY_L, -+ [SDLK_m] = KEY_M, -+ [SDLK_n] = KEY_N, -+ [SDLK_o] = KEY_O, -+ [SDLK_p] = KEY_P, -+ [SDLK_q] = KEY_Q, -+ [SDLK_r] = KEY_R, -+ [SDLK_s] = KEY_S, -+ [SDLK_t] = KEY_T, -+ [SDLK_u] = KEY_U, -+ [SDLK_v] = KEY_V, -+ [SDLK_w] = KEY_W, -+ [SDLK_x] = KEY_X, -+ [SDLK_y] = KEY_Y, -+ [SDLK_z] = KEY_Z, -+ [SDLK_0] = KEY_0, -+ [SDLK_1] = KEY_1, -+ [SDLK_2] = KEY_2, -+ [SDLK_3] = KEY_3, -+ [SDLK_4] = KEY_4, -+ [SDLK_5] = KEY_5, -+ [SDLK_6] = KEY_6, -+ [SDLK_7] = KEY_7, -+ [SDLK_8] = KEY_8, -+ [SDLK_9] = KEY_9, -+ [SDLK_SPACE] = KEY_SPACE, -+ [SDLK_RETURN] = KEY_ENTER, -+ [SDLK_PERIOD] = KEY_DOT, -+ [SDLK_SLASH] = KEY_SLASH, -+ [SDLK_BACKSPACE] = KEY_BACKSPACE, -+ [SDLK_TAB] = KEY_TAB, -+ [SDLK_LSHIFT] = KEY_LEFTSHIFT, -+ [SDLK_RSHIFT] = KEY_RIGHTSHIFT, -+ [SDLK_LALT] = KEY_LEFTALT, -+ [SDLK_RALT] = KEY_RIGHTALT, -+}; -+ -+static struct option options[] = { -+ { "domid", 1, NULL, 'd' }, -+ { "title", 1, NULL, 't' }, -+}; -+ -+int main(int argc, char **argv) -+{ -+ struct xenfb *xenfb; -+ int fd; -+ int domid = -1; -+ char * title = NULL; -+ fd_set readfds; -+ struct data data; -+ SDL_Rect r; -+ struct timeval tv = { 0, 500 }; -+ int do_quit = 0; -+ int opt; -+ -+ while ((opt = getopt_long(argc, argv, "d:t:", options, -+ NULL)) != -1) { -+ switch (opt) { -+ case 'd': -+ domid = strtol(optarg, NULL, 10); -+ break; -+ case 't': -+ title = strdup(optarg); -+ break; -+ } -+ } -+ if (optind != argc) { -+ fprintf(stderr, "Invalid options!\n"); -+ exit(1); -+ } -+ if (domid == -1) { -+ fprintf(stderr, "Domain ID must be specified!\n"); -+ exit(1); -+ } -+ -+ xenfb = xenfb_new(); -+ if (xenfb == NULL) -+ return 1; -+ -+ if (!xenfb_attach_dom(xenfb, domid)) -+ return 1; -+ -+ SDL_Init(SDL_INIT_VIDEO); -+ -+ fd = xenfb_get_fileno(xenfb); -+ -+ data.dst = SDL_SetVideoMode(xenfb->width, xenfb->height, xenfb->depth, -+ SDL_SWSURFACE); -+ -+ data.src = SDL_CreateRGBSurfaceFrom(xenfb->pixels, -+ xenfb->width, xenfb->height, -+ xenfb->depth, xenfb->row_stride, -+ 0xFF0000, 0xFF00, 0xFF, 0); -+ -+ if (title == NULL) -+ title = strdup("xen-sdlfb"); -+ SDL_WM_SetCaption(title, title); -+ -+ r.x = r.y = 0; -+ r.w = xenfb->width; -+ r.h = xenfb->height; -+ SDL_BlitSurface(data.src, &r, data.dst, &r); -+ SDL_UpdateRect(data.dst, 0, 0, xenfb->width, xenfb->height); -+ -+ xenfb->update = sdl_update; -+ xenfb->user_data = &data; -+ -+ FD_ZERO(&readfds); -+ FD_SET(fd, &readfds); -+ -+ SDL_ShowCursor(0); -+ -+ while (!do_quit && select(fd + 1, &readfds, NULL, NULL, &tv) != -1) { -+ SDL_Event event; -+ -+ while (SDL_PollEvent(&event)) { -+ switch (event.type) { -+ case SDL_KEYDOWN: -+ case SDL_KEYUP: -+ xenfb_send_key(xenfb, -+ event.type == SDL_KEYDOWN, -+ sdl2linux[event.key.keysym.sym]); -+ break; -+ case SDL_MOUSEMOTION: { -+ int x, y; -+ Uint8 button; -+ -+ button = SDL_GetRelativeMouseState(&x, &y); -+ xenfb_send_motion(xenfb, x, y); -+ } break; -+ case SDL_MOUSEBUTTONDOWN: -+ case SDL_MOUSEBUTTONUP: -+ xenfb_send_button(xenfb, -+ event.type==SDL_MOUSEBUTTONDOWN, -+ 3 - event.button.button); -+ break; -+ case SDL_QUIT: -+ do_quit = 1; -+ break; -+ } -+ } -+ if (FD_ISSET(fd, &readfds)) -+ xenfb_on_incoming(xenfb); -+ -+ FD_ZERO(&readfds); -+ FD_SET(fd, &readfds); -+ -+ tv = (struct timeval){0, 500}; -+ } -+ -+ xenfb_delete(xenfb); -+ -+ SDL_Quit(); -+ -+ return 0; -+} -Index: xen-unstable/tools/xenfb/vncfb.c -=================================================================== ---- /dev/null -+++ xen-unstable/tools/xenfb/vncfb.c -@@ -0,0 +1,245 @@ -+#define _GNU_SOURCE -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "xenfb.h" -+ -+static void on_kbd_event(rfbBool down, rfbKeySym keycode, rfbClientPtr cl) -+{ -+ extern uint32_t gdk_linux_mapping[0x10000]; -+ rfbScreenInfoPtr server = cl->screen; -+ struct xenfb *xenfb = server->screenData; -+ xenfb_send_key(xenfb, down, gdk_linux_mapping[keycode & 0xFFFF]); -+} -+ -+static void on_ptr_event(int buttonMask, int x, int y, rfbClientPtr cl) -+{ -+ static int last_x = -1, last_y = -1; -+ static int last_button = -1; -+ rfbScreenInfoPtr server = cl->screen; -+ struct xenfb *xenfb = server->screenData; -+ -+ if (last_button != -1) { -+ int i; -+ -+ for (i = 0; i < 8; i++) { -+ if ((last_button & (1 << i)) != -+ (buttonMask & (1 << i))) { -+ printf("%d %d\n", buttonMask & (1 << i), i); -+ xenfb_send_button(xenfb, buttonMask & (1 << i), -+ 2 - i); -+ } -+ } -+ } -+ -+ if (last_x != -1) -+ xenfb_send_motion(xenfb, x - last_x, y - last_y); -+ -+ last_button = buttonMask; -+ -+ last_x = x; -+ last_y = y; -+} -+ -+static void xenstore_write_vncport(int port, int domid) -+{ -+ char *buf = NULL, *path; -+ char *portstr = NULL; -+ struct xs_handle *xsh = NULL; -+ -+ xsh = xs_daemon_open(); -+ if (xsh == NULL) -+ return; -+ -+ path = xs_get_domain_path(xsh, domid); -+ if (path == NULL) { -+ fprintf(stderr, "xs_get_domain_path() error\n"); -+ goto out; -+ } -+ -+ buf = malloc(256); -+ if (snprintf(buf, 256, "%s/console/vnc-port", path) == -1) -+ goto out; -+ -+ portstr = malloc(10); -+ if (snprintf(portstr, 10, "%d", port) == -1) -+ goto out; -+ -+ if (xs_write(xsh, XBT_NULL, buf, portstr, strlen(portstr)) == 0) -+ fprintf(stderr, "xs_write() vncport failed\n"); -+ -+ out: -+ free(portstr); -+ free(buf); -+} -+ -+ -+static void vnc_update(struct xenfb *xenfb, int x, int y, int w, int h) -+{ -+ rfbScreenInfoPtr server = xenfb->user_data; -+ rfbMarkRectAsModified(server, x, y, x + w, y + h); -+} -+ -+static int vnc_start_viewer(int port) -+{ -+ int pid; -+ char s[16]; -+ -+ snprintf(s, 16, ":%d", port); -+ switch (pid = fork()) { -+ case -1: -+ fprintf(stderr, "vncviewer failed fork\n"); -+ exit(1); -+ -+ case 0: /* child */ -+ execlp("vncviewer", "vncviewer", s, NULL); -+ fprintf(stderr, "vncviewer execlp failed\n"); -+ exit(1); -+ -+ default: -+ return pid; -+ } -+} -+ -+static struct option options[] = { -+ { "domid", 1, NULL, 'd' }, -+ { "vncport", 1, NULL, 'p' }, -+ { "title", 1, NULL, 't' }, -+ { "unused", 0, NULL, 'u' }, -+ { "listen", 1, NULL, 'l' }, -+ { "vncviewer", 0, NULL, 'v' }, -+}; -+ -+int main(int argc, char **argv) -+{ -+ rfbScreenInfoPtr server; -+ char *fake_argv[7] = { "vncfb", "-rfbport", "5901", -+ "-desktop", "xen-vncfb", -+ "-listen", "0.0.0.0" }; -+ int fake_argc = sizeof(fake_argv) / sizeof(fake_argv[0]); -+ int domid = -1, port = -1; -+ char * title = NULL; -+ char * listen = NULL; -+ struct xenfb *xenfb; -+ fd_set readfds; -+ int fd; -+ char buffer[1024]; -+ int opt; -+ bool unused = FALSE; -+ bool viewer = FALSE; -+ -+ while ((opt = getopt_long(argc, argv, "d:p:t:u", options, -+ NULL)) != -1) { -+ switch (opt) { -+ case 'd': -+ domid = strtol(optarg, NULL, 10); -+ break; -+ case 'p': -+ port = strtol(optarg, NULL, 10); -+ break; -+ case 't': -+ title = strdup(optarg); -+ break; -+ case 'u': -+ unused = TRUE; -+ break; -+ case 'l': -+ listen = strdup(optarg); -+ break; -+ case 'v': -+ viewer = TRUE; -+ break; -+ //case 'l': -+ // listen = strdup(optarg); -+ // break; -+ } -+ } -+ if (optind != argc) { -+ fprintf(stderr, "Invalid options!\n"); -+ exit(1); -+ } -+ if (domid == -1) { -+ fprintf(stderr, "Domain ID must be specified!\n"); -+ exit(1); -+ } -+ -+ if (port == -1) -+ port = 5900 + domid; -+ snprintf(buffer, sizeof(buffer), "%d", port); -+ fake_argv[2] = buffer; -+ -+ if (title != NULL) -+ fake_argv[4] = title; -+ -+ if (listen != NULL) -+ fake_argv[6] = listen; -+ -+ if (listen != NULL) -+ fake_argv[6] = listen; -+ -+ xenfb = xenfb_new(); -+ if (xenfb == NULL) { -+ fprintf(stderr, "Could not create framebuffer (%s)\n", -+ strerror(errno)); -+ exit(1); -+ } -+ -+ if (!xenfb_attach_dom(xenfb, domid)) { -+ fprintf(stderr, "Could not connect to domain (%s)\n", -+ strerror(errno)); -+ exit(1); -+ } -+ -+ server = rfbGetScreen(&fake_argc, fake_argv, -+ xenfb->width, xenfb->height, -+ 8, 3, xenfb->depth / 8); -+ if (server == NULL) { -+ fprintf(stderr, "Could not create VNC server\n"); -+ exit(1); -+ } -+ -+ xenfb->user_data = server; -+ xenfb->update = vnc_update; -+ -+ if (unused) -+ server->autoPort = TRUE; -+ -+ server->serverFormat.redShift = 16; -+ server->serverFormat.greenShift = 8; -+ server->serverFormat.blueShift = 0; -+ server->kbdAddEvent = on_kbd_event; -+ server->ptrAddEvent = on_ptr_event; -+ server->frameBuffer = (char *)xenfb->pixels; -+ server->screenData = xenfb; -+ rfbInitServer(server); -+ -+ rfbRunEventLoop(server, -1, TRUE); -+ -+ fd = xenfb_get_fileno(xenfb); -+ -+ FD_ZERO(&readfds); -+ FD_SET(fd, &readfds); -+ -+ xenstore_write_vncport(server->port, domid); -+ -+ if (viewer) -+ vnc_start_viewer(server->port); -+ -+ while (select(fd + 1, &readfds, NULL, NULL, NULL) != -1) { -+ if (FD_ISSET(fd, &readfds)) { -+ xenfb_on_incoming(xenfb); -+ } -+ -+ FD_ZERO(&readfds); -+ FD_SET(fd, &readfds); -+ } -+ -+ rfbScreenCleanup(server); -+ xenfb_delete(xenfb); -+ -+ return 0; -+} -Index: xen-unstable/tools/xenfb/xenfb.c -=================================================================== ---- /dev/null -+++ xen-unstable/tools/xenfb/xenfb.c -@@ -0,0 +1,434 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "xenfb.h" -+ -+// FIXME defend against malicous backend? -+ -+struct xenfb_private -+{ -+ struct xenfb pub; -+ int domid; -+ unsigned long fbdev_mfn, kbd_mfn; -+ int fbdev_evtchn, kbd_evtchn; -+ evtchn_port_t fbdev_port, kbd_port; -+ int evt_xch; -+ int xc; -+ unsigned char *fb; -+ struct xenfb_page *fb_info; -+ struct xenkbd_info *kbd_info; -+ unsigned long *fbmfns; -+ int n_fbmfns, n_fbdirs; -+}; -+ -+struct xenfb *xenfb_new(void) -+{ -+ struct xenfb_private *xenfb = malloc(sizeof(*xenfb)); -+ -+ if (xenfb == NULL) -+ return NULL; -+ -+ memset(xenfb, 0, sizeof(*xenfb)); -+ -+ xenfb->domid = -1; -+ -+ xenfb->evt_xch = xc_evtchn_open(); -+ if (xenfb->evt_xch == -1) { -+ int serrno = errno; -+ free(xenfb); -+ errno = serrno; -+ return NULL; -+ } -+ -+ xenfb->xc = xc_interface_open(); -+ if (xenfb->xc == -1) { -+ int serrno = errno; -+ xc_evtchn_close(xenfb->evt_xch); -+ free(xenfb); -+ errno = serrno; -+ return NULL; -+ } -+ -+ return &xenfb->pub; -+} -+ -+int xenfb_get_fileno(struct xenfb *xenfb_pub) -+{ -+ struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub; -+ -+ return xc_evtchn_fd(xenfb->evt_xch); -+} -+ -+static void xenfb_detach_dom(struct xenfb_private *xenfb) -+{ -+ xenfb->domid = -1; -+ munmap(xenfb->fb, xenfb->fb_info->mem_length); -+ munmap(xenfb->fb_info, XC_PAGE_SIZE); -+ munmap(xenfb->kbd_info, XC_PAGE_SIZE); -+ xc_evtchn_unbind(xenfb->evt_xch, xenfb->fbdev_port); -+ xc_evtchn_unbind(xenfb->evt_xch, xenfb->kbd_port); -+} -+ -+void xenfb_delete(struct xenfb *xenfb_pub) -+{ -+ struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub; -+ if (xenfb->domid != -1) -+ xenfb_detach_dom(xenfb); -+ free(xenfb); -+} -+ -+static int xenfb_fb_event(struct xenfb_private *xenfb, union xenfb_in_event *event) -+{ -+ uint32_t prod; -+ struct xenfb_page *info = xenfb->fb_info; -+ -+ prod = info->in_prod; -+ if (prod - info->in_cons == XENFB_IN_RING_LEN) { -+ errno = EAGAIN; -+ return -1; -+ } -+ -+ mb(); /* ensure ring space available */ -+ XENFB_IN_RING_REF(info, prod) = *event; -+ wmb(); /* ensure ring contents visible */ -+ info->in_prod = prod + 1; -+ return xc_evtchn_notify(xenfb->evt_xch, xenfb->fbdev_port); -+} -+ -+static int xenfb_kbd_event(struct xenfb_private *xenfb, union xenkbd_in_event *event) -+{ -+ uint32_t prod; -+ struct xenkbd_info *info = xenfb->kbd_info; -+ -+ prod = info->in_prod; -+ if (prod - info->in_cons == XENKBD_IN_RING_LEN) { -+ errno = EAGAIN; -+ return -1; -+ } -+ -+ mb(); /* ensure ring space available */ -+ XENKBD_IN_RING_REF(info, prod) = *event; -+ wmb(); /* ensure ring contents visible */ -+ info->in_prod = prod + 1; -+ return xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd_port); -+} -+ -+static char *xenfb_path_in_dom(struct xs_handle *h, -+ unsigned domid, const char *path, -+ char *buffer, size_t size) -+{ -+ char *domp = xs_get_domain_path(h, domid); -+ int n = snprintf(buffer, size, "%s/%s", domp, path); -+ free(domp); -+ if (n >= size) -+ return NULL; -+ return buffer; -+} -+ -+static int xenfb_xs_scanf1(struct xs_handle *xsh, unsigned domid, -+ const char *path, const char *fmt, -+ void *dest) -+{ -+ char buffer[1024]; -+ char *p; -+ int ret; -+ -+ p = xenfb_path_in_dom(xsh, domid, path, buffer, sizeof(buffer)); -+ p = xs_read(xsh, XBT_NULL, p, NULL); -+ if (!p) -+ return -ENOENT; -+ ret = sscanf(p, fmt, dest); -+ free(p); -+ if (ret != 1) -+ return -EDOM; -+ return 0; -+} -+ -+bool xenfb_attach_dom(struct xenfb *xenfb_pub, int domid) -+{ -+ struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub; -+ char buffer[1024]; -+ struct xs_handle *xsh; -+ unsigned dummy; -+ int ret; -+ char *p, **vec; -+ union xenfb_in_event event; -+ -+ if (xenfb->domid != -1) { -+ xenfb_detach_dom(xenfb); -+ if (domid == -1) -+ return true; -+ } -+ -+ xsh = xs_daemon_open_readonly(); -+ if (!xsh) -+ goto error; -+ -+ p = xenfb_path_in_dom(xsh, domid, "vfb", buffer, sizeof(buffer)); -+ if (!xs_watch(xsh, p, "")) -+ goto error; -+ p = xenfb_path_in_dom(xsh, domid, "vkbd", buffer, sizeof(buffer)); -+ if (!xs_watch(xsh, p, "")) -+ goto error; -+ -+ for (;;) { -+ ret = xenfb_xs_scanf1(xsh, domid, "vfb/page-ref", "%lu", -+ &xenfb->fbdev_mfn); -+ if (ret == -ENOENT || ret == -EAGAIN) -+ goto wait; -+ if (ret < 0) -+ goto error; -+ ret = xenfb_xs_scanf1(xsh, domid, "vfb/event-channel", "%u", -+ &xenfb->fbdev_evtchn); -+ if (ret == -ENOENT || ret == -EAGAIN) -+ goto wait; -+ if (ret < 0) -+ goto error; -+ ret = xenfb_xs_scanf1(xsh, domid, "vkbd/page-ref", "%lu", -+ &xenfb->kbd_mfn); -+ if (ret == -ENOENT || ret == -EAGAIN) -+ goto wait; -+ if (ret < 0) -+ goto error; -+ ret = xenfb_xs_scanf1(xsh, domid, "vkbd/event-channel", "%u", -+ &xenfb->kbd_evtchn); -+ if (ret == -ENOENT || ret == -EAGAIN) -+ goto wait; -+ if (ret < 0) -+ goto error; -+ break; -+ -+ wait: -+ printf("Waiting...\n"); -+ vec = xs_read_watch(xsh, &dummy); -+ if (!vec) -+ goto error; -+ free(vec); -+ } -+ xs_daemon_close(xsh); -+ xsh = NULL; -+ -+ xenfb->fbdev_port = xc_evtchn_bind_interdomain(xenfb->evt_xch, domid, -+ xenfb->fbdev_evtchn); -+ if (xenfb->fbdev_port == -1) -+ goto error; -+ -+ xenfb->kbd_port = xc_evtchn_bind_interdomain(xenfb->evt_xch, domid, -+ xenfb->kbd_evtchn); -+ if (xenfb->kbd_port == -1) -+ goto error_fbdev; -+ -+ xenfb->fb_info = xc_map_foreign_range(xenfb->xc, domid, XC_PAGE_SIZE, -+ PROT_READ | PROT_WRITE, -+ xenfb->fbdev_mfn); -+ if (xenfb->fb_info == NULL) -+ goto error_kbd; -+ -+ xenfb->kbd_info = xc_map_foreign_range(xenfb->xc, domid, XC_PAGE_SIZE, -+ PROT_READ | PROT_WRITE, -+ xenfb->kbd_mfn); -+ if (xenfb->kbd_info == NULL) -+ goto error_fbinfo; -+ -+ xenfb->n_fbmfns = (xenfb->fb_info->mem_length + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE; -+ xenfb->n_fbdirs = xenfb->n_fbmfns * sizeof(unsigned long); -+ xenfb->n_fbdirs = (xenfb->n_fbdirs + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE; -+ -+ xenfb->fbmfns = xc_map_foreign_batch(xenfb->xc, domid, PROT_READ, xenfb->fb_info->pd, xenfb->n_fbdirs); -+ if (xenfb->fbmfns == NULL) -+ goto error_kbdinfo; -+ -+ xenfb->fb = xc_map_foreign_batch(xenfb->xc, domid, PROT_READ | PROT_WRITE, xenfb->fbmfns, xenfb->n_fbmfns); -+ if (xenfb->fb == NULL) -+ goto error_fbmfns; -+ -+ event.type = XENFB_TYPE_SET_EVENTS; -+ event.set_events.flags = XENFB_FLAG_UPDATE; -+ if (xenfb_fb_event(xenfb, &event)) -+ goto error_fb; -+ -+ munmap(xenfb->fbmfns, xenfb->n_fbdirs * XC_PAGE_SIZE); -+ -+ xenfb->domid = domid; -+ -+ xenfb->pub.pixels = xenfb->fb; -+ -+ xenfb->pub.row_stride = xenfb->fb_info->line_length; -+ xenfb->pub.depth = xenfb->fb_info->depth; -+ xenfb->pub.width = xenfb->fb_info->width; -+ xenfb->pub.height = xenfb->fb_info->height; -+ -+ return true; -+ -+ error_fb: -+ printf("%d\n", __LINE__); -+ { -+ int serrno = errno; -+ munmap(xenfb->fb, xenfb->fb_info->mem_length); -+ errno = serrno; -+ } -+ error_fbmfns: -+ printf("%d\n", __LINE__); -+ { -+ int serrno = errno; -+ munmap(xenfb->fbmfns, xenfb->n_fbdirs * XC_PAGE_SIZE); -+ errno = serrno; -+ } -+ error_kbdinfo: -+ printf("%d\n", __LINE__); -+ { -+ int serrno = errno; -+ munmap(xenfb->kbd_info, XC_PAGE_SIZE); -+ errno = serrno; -+ } -+ error_fbinfo: -+ printf("%d\n", __LINE__); -+ { -+ int serrno = errno; -+ munmap(xenfb->fb_info, XC_PAGE_SIZE); -+ errno = serrno; -+ } -+ error_kbd: -+ printf("%d\n", __LINE__); -+ { -+ int serrno = errno; -+ xc_evtchn_unbind(xenfb->evt_xch, xenfb->kbd_port); -+ errno = serrno; -+ } -+ error_fbdev: -+ printf("%d\n", __LINE__); -+ { -+ int serrno = errno; -+ xc_evtchn_unbind(xenfb->evt_xch, xenfb->fbdev_port); -+ errno = serrno; -+ } -+ error: -+ printf("%d\n", __LINE__); -+ if (xsh) { -+ int serrno = errno; -+ xs_daemon_close(xsh); -+ errno = serrno; -+ } -+ -+ return false; -+} -+ -+static void xenfb_update(struct xenfb_private *xenfb, int x, int y, int width, int height) -+{ -+ if (xenfb->pub.update) -+ xenfb->pub.update(&xenfb->pub, x, y, width, height); -+} -+ -+static void xenfb_on_fb_event(struct xenfb_private *xenfb) -+{ -+ uint32_t prod, cons; -+ struct xenfb_page *info = xenfb->fb_info; -+ -+ prod = info->out_prod; -+ rmb(); /* ensure we see ring contents up to prod */ -+ for (cons = info->out_cons; cons != prod; cons++) { -+ union xenfb_out_event *event = &XENFB_OUT_RING_REF(info, cons); -+ -+ switch (event->type) { -+ case XENFB_TYPE_UPDATE: -+ xenfb_update(xenfb, event->update.x, event->update.y, event->update.width, event->update.height); -+ break; -+ } -+ } -+ mb(); /* ensure we're done with ring contents */ -+ info->out_cons = cons; -+ // FIXME need to notify? -+} -+ -+static void xenfb_on_kbd_event(struct xenfb_private *xenfb) -+{ -+ uint32_t prod, cons; -+ struct xenkbd_info *info = xenfb->kbd_info; -+ -+ prod = info->out_prod; -+ rmb(); /* ensure we see ring contents up to prod */ -+ for (cons = info->out_cons; cons != prod; cons++) { -+ union xenkbd_out_event *event = &XENKBD_OUT_RING_REF(info, cons); -+ -+ switch (event->type) { -+ default: -+ break; -+ } -+ } -+ mb(); /* ensure we're done with ring contents */ -+ info->out_cons = cons; -+ // FIXME need to notify? -+} -+ -+int xenfb_on_incoming(struct xenfb *xenfb_pub) -+{ -+ struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub; -+ evtchn_port_t port; -+ -+ port = xc_evtchn_pending(xenfb->evt_xch); -+ if (port == -1) -+ return -1; -+ -+ if (port == xenfb->fbdev_port) { -+ xenfb_on_fb_event(xenfb); -+ } else if (port == xenfb->kbd_port) { -+ xenfb_on_kbd_event(xenfb); -+ } -+ -+ if (xc_evtchn_unmask(xenfb->evt_xch, port) == -1) -+ return -1; -+ -+ return 0; -+} -+ -+int xenfb_send_key(struct xenfb *xenfb_pub, bool down, int keycode) -+{ -+ struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub; -+ union xenkbd_in_event event; -+ -+ event.type = XENKBD_TYPE_KEY; -+ event.key.pressed = down ? 1 : 0; -+ event.key.keycode = keycode; -+ -+ return xenfb_kbd_event(xenfb, &event); -+} -+ -+int xenfb_send_motion(struct xenfb *xenfb_pub, int rel_x, int rel_y) -+{ -+ struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub; -+ union xenkbd_in_event event; -+ -+ event.type = XENKBD_TYPE_MOTION; -+ event.motion.rel_x = rel_x; -+ event.motion.rel_y = rel_y; -+ -+ return xenfb_kbd_event(xenfb, &event); -+} -+ -+int xenfb_send_button(struct xenfb *xenfb_pub, bool down, int button) -+{ -+ struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub; -+ union xenkbd_in_event event; -+ -+ event.type = XENKBD_TYPE_BUTTON; -+ event.button.pressed = down ? 1 : 0; -+ event.button.button = button; -+ -+ return xenfb_kbd_event(xenfb, &event); -+} -Index: xen-unstable/tools/xenfb/xenfb.h -=================================================================== ---- /dev/null -+++ xen-unstable/tools/xenfb/xenfb.h -@@ -0,0 +1,33 @@ -+#ifndef _XENFB_H_ -+#define _XENFB_H_ -+ -+#include -+#include -+ -+struct xenfb -+{ -+ uint8_t *pixels; -+ -+ int row_stride; -+ int depth; -+ int width; -+ int height; -+ -+ void *user_data; -+ -+ void (*update)(struct xenfb *xenfb, int x, int y, int width, int height); -+}; -+ -+struct xenfb *xenfb_new(void); -+void xenfb_delete(struct xenfb *xenfb); -+ -+bool xenfb_attach_dom(struct xenfb *xenfb, int domid); -+ -+int xenfb_get_fileno(struct xenfb *xenfb); -+int xenfb_on_incoming(struct xenfb *xenfb); -+ -+int xenfb_send_key(struct xenfb *xenfb, bool down, int keycode); -+int xenfb_send_motion(struct xenfb *xenfb, int rel_x, int rel_y); -+int xenfb_send_button(struct xenfb *xenfb, bool down, int button); -+ -+#endif diff --git a/xen-pvfb-3.patch b/xen-pvfb-3.patch deleted file mode 100644 index 365328e..0000000 --- a/xen-pvfb-3.patch +++ /dev/null @@ -1,129 +0,0 @@ -Index: xen-unstable/tools/python/xen/xend/image.py -=================================================================== ---- xen-unstable.orig/tools/python/xen/xend/image.py -+++ xen-unstable/tools/python/xen/xend/image.py -@@ -20,8 +20,10 @@ - import os, string - import re - import math -+import signal - - import xen.lowlevel.xc -+import xen.util.auxbin - from xen.xend import sxp - from xen.xend.XendError import VmError - from xen.xend.XendLogging import log -@@ -205,6 +207,68 @@ class LinuxImageHandler(ImageHandler): - ramdisk = self.ramdisk, - features = self.vm.getFeatures()) - -+ def configure(self, imageConfig, deviceConfig): -+ ImageHandler.configure(self, imageConfig, deviceConfig) -+ -+ self.pid = 0 -+ log.info("configuring linux guest") -+ -+ # set up the graphics bits. -+ # FIXME: this is much like what we do for HVM, should it be -+ # for all image types now? -+ self.display = sxp.child_value(imageConfig, 'display') -+ self.xauthority = sxp.child_value(imageConfig, 'xauthority') -+ self.vncconsole = sxp.child_value(imageConfig, 'vncconsole') -+ self.vnc = sxp.child_value(imageConfig, 'vnc') -+ self.sdl = sxp.child_value(imageConfig, 'sdl') -+ if self.vnc: -+ self.vncdisplay = sxp.child_value(imageConfig, 'vncdisplay', -+ int(self.vm.getDomid())) -+ self.vncunused = sxp.child_value(imageConfig, 'vncunused') -+ self.vnclisten = sxp.child_value(imageConfig, 'vnclisten') -+ if self.vnc or self.sdl: -+ log.info("setting use_graphics") -+ self.vm.writeDom("console/use_graphics", "1") -+ else: -+ self.vm.writeDom("console/use_graphics", "0") -+ -+ def createDeviceModel(self): -+ if self.pid: -+ return -+ # Execute device model (for us, it's just the fb frontend) -+ if not self.vnc and not self.sdl: -+ return -+ -+ if self.vnc: -+ args = [xen.util.auxbin.pathTo("xen-vncfb")] -+ if self.vncunused: -+ args += ['--unused'] -+ elif self.vncdisplay: -+ args += [ "--vncport", "%d" %(5900 + self.vncdisplay,) ] -+ if self.vnclisten: -+ args += [ "--listen", self.vnclisten ] -+ if self.vncconsole: -+ args += [ "--vncviewer" ] -+ elif self.sdl: -+ args = [xen.util.auxbin.pathTo("xen-sdlfb")] -+ args = args + [ "--domid", "%d" % self.vm.getDomid(), -+ "--title", self.vm.info['name'] ] -+ env = dict(os.environ) -+ if self.display: -+ env['DISPLAY'] = self.display -+ if self.xauthority: -+ env['XAUTHORITY'] = self.xauthority -+ log.info("spawning video: %s", args) -+ self.pid = os.spawnve(os.P_NOWAIT, args[0], args, env) -+ log.info("device model pid: %d", self.pid) -+ -+ def destroy(self): -+ if not self.pid: -+ return -+ os.kill(self.pid, signal.SIGKILL) -+ os.waitpid(self.pid, 0) -+ self.pid = 0 -+ - class PPC_LinuxImageHandler(LinuxImageHandler): - - ostype = "linux" -@@ -382,7 +446,6 @@ class HVMImageHandler(ImageHandler): - - def destroy(self): - self.unregister_shutdown_watch(); -- import signal - if not self.pid: - return - os.kill(self.pid, signal.SIGKILL) -Index: xen-unstable/tools/python/xen/xm/create.py -=================================================================== ---- xen-unstable.orig/tools/python/xen/xm/create.py -+++ xen-unstable/tools/python/xen/xm/create.py -@@ -481,6 +481,8 @@ def configure_image(vals): - - if vals.builder == 'hvm': - configure_hvm(config_image, vals) -+ -+ configure_graphics(config_image, vals) - - return config_image - -@@ -627,14 +629,21 @@ def configure_vifs(config_devs, vals): - map(f, d.keys()) - config_devs.append(['device', config_vif]) - -+def configure_graphics(config_image, vals): -+ """Create the config for graphic consoles. -+ """ -+ args = [ 'vnc', 'vncdisplay', 'vncconsole', 'vncunused', -+ 'sdl', 'display', 'xauthority' ] -+ for a in args: -+ if (vals.__dict__[a]): -+ config_image.append([a, vals.__dict__[a]]) - - def configure_hvm(config_image, vals): - """Create the config for HVM devices. - """ - args = [ 'device_model', 'pae', 'vcpus', 'boot', 'fda', 'fdb', - 'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'soundhw', -- 'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'sdl', 'display', -- 'acpi', 'apic', 'xauthority', 'usb', 'usbdevice' ] -+ 'acpi', 'apic', 'usb', 'usbdevice' ] - for a in args: - if (vals.__dict__[a]): - config_image.append([a, vals.__dict__[a]]) diff --git a/xen-python25-warnings.diff b/xen-python25-warnings.diff deleted file mode 100644 index 8432632..0000000 --- a/xen-python25-warnings.diff +++ /dev/null @@ -1,152 +0,0 @@ -Index: xen-3.0.3-testing/tools/python/xen/lowlevel/xc/xc.c -=================================================================== ---- xen-3.0.3-testing.orig/tools/python/xen/lowlevel/xc/xc.c -+++ xen-3.0.3-testing/tools/python/xen/lowlevel/xc/xc.c -@@ -23,6 +23,13 @@ - #define PyMODINIT_FUNC DL_EXPORT(void) - #endif - -+/* Needed for Python versions earlier than 2.5, due to PEP353 */ -+#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) -+typedef int Py_ssize_t; -+#define PY_SSIZE_T_MAX INT_MAX -+#define PY_SSIZE_T_MIN INT_MIN -+#endif -+ - #define PKG "xen.lowlevel.xc" - #define CLS "xc" - -@@ -65,9 +72,12 @@ static PyObject *pyxc_domain_create(XcOb - PyObject *args, - PyObject *kwds) - { -- uint32_t dom = 0; -- int ret, i; -- uint32_t ssidref = 0; -+ uint32_t dom; -+ Py_ssize_t _dom = 0; -+ uint32_t ssidref; -+ Py_ssize_t _ssidref = 0; -+ Py_ssize_t i; -+ int ret; - PyObject *pyhandle = NULL; - xen_domain_handle_t handle = { - 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, -@@ -76,8 +86,10 @@ static PyObject *pyxc_domain_create(XcOb - static char *kwd_list[] = { "dom", "ssidref", "handle", NULL }; - - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiO", kwd_list, -- &dom, &ssidref, &pyhandle)) -+ &_dom, &_ssidref, &pyhandle)) - return NULL; -+ dom = Py_SAFE_DOWNCAST(_dom, Py_ssize_t, uint32_t); -+ ssidref = Py_SAFE_DOWNCAST(_ssidref, Py_ssize_t, uint32_t); - - if ( pyhandle != NULL ) - { -@@ -140,7 +152,8 @@ static PyObject *pyxc_vcpu_setaffinity(X - PyObject *kwds) - { - uint32_t dom; -- int vcpu = 0, i; -+ int vcpu = 0; -+ Py_ssize_t i; - uint64_t cpumap = ~0ULL; - PyObject *cpulist = NULL; - -@@ -186,7 +199,7 @@ static PyObject *pyxc_domain_setcpuweigh - - static PyObject *pyxc_domain_sethandle(XcObject *self, PyObject *args) - { -- int i; -+ Py_ssize_t i; - uint32_t dom; - PyObject *pyhandle; - xen_domain_handle_t handle; -Index: xen-3.0.3-testing/tools/python/xen/lowlevel/xs/xs.c -=================================================================== ---- xen-3.0.3-testing.orig/tools/python/xen/lowlevel/xs/xs.c -+++ xen-3.0.3-testing/tools/python/xen/lowlevel/xs/xs.c -@@ -21,6 +21,13 @@ - - #include - -+/* Needed for Python versions earlier than 2.5, due to PEP353 */ -+#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) -+typedef int Py_ssize_t; -+#define PY_SSIZE_T_MAX INT_MAX -+#define PY_SSIZE_T_MIN INT_MIN -+#endif -+ - #include - #include - #include -@@ -320,6 +327,7 @@ static PyObject *xspy_set_permissions(Xs - int i, result; - struct xs_permissions *xsperms = NULL; - int xsperms_n; -+ Py_ssize_t _xsperms_n; - PyObject *tuple0 = NULL; - - xs_transaction_t th; -@@ -336,7 +344,9 @@ static PyObject *xspy_set_permissions(Xs - xs_set_error(EINVAL); - goto exit; - } -- xsperms_n = PyList_Size(perms); -+ _xsperms_n = PyList_Size(perms); -+ /* Should never overflow an int, since xs interface uses int */ -+ xsperms_n = Py_SAFE_DOWNCAST(_xsperms_n, Py_ssize_t, int); - xsperms = calloc(xsperms_n, sizeof(struct xs_permissions)); - if (!xsperms) { - xs_set_error(ENOMEM); -@@ -393,7 +403,7 @@ static PyObject *xspy_watch(XsHandle *se - PyObject *token; - char token_str[MAX_STRLEN(unsigned long) + 1]; - int result; -- int i; -+ Py_ssize_t i; - - if (!xh) - return NULL; -@@ -439,7 +449,7 @@ static PyObject *xspy_read_watch(XsHandl - PyObject *val = NULL; - char **xsval; - PyObject *token; -- int i; -+ Py_ssize_t i; - unsigned int num; - - if (!xh) -@@ -658,7 +668,7 @@ static PyObject *xspy_release_domain(XsH - static PyObject *xspy_close(XsHandle *self) - { - struct xs_handle *xh = xshandle(self); -- int i; -+ Py_ssize_t i; - - if (!xh) - return NULL; -@@ -716,7 +726,7 @@ static PyObject *xspy_get_domain_path(Xs - */ - static void remove_watch(XsHandle *self, PyObject *token) - { -- int i; -+ Py_ssize_t i; - - for (i = 0; i < PyList_Size(self->watches); i++) { - if (PyList_GetItem(self->watches, i) == token) { -Index: xen-3.0.3-testing/tools/Makefile -=================================================================== ---- xen-3.0.3-testing.orig/tools/Makefile -+++ xen-3.0.3-testing/tools/Makefile -@@ -22,7 +22,8 @@ SUBDIRS-y += blktap - # These don't cross-compile - ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH)) - SUBDIRS-y += python --SUBDIRS-y += pygrub -+# pygrub is unsupported by SUSE, and does not build cleanly with Python 2.5 -+#SUBDIRS-y += pygrub - endif - - .PHONY: all diff --git a/xen-rpmoptflags.diff b/xen-rpmoptflags.diff index 7b9b587..6972535 100644 --- a/xen-rpmoptflags.diff +++ b/xen-rpmoptflags.diff @@ -1,46 +1,19 @@ -Index: xen-3.0.3-testing/tools/firmware/hvmloader/Makefile +Index: xen-unstable/tools/blktap/drivers/Makefile =================================================================== ---- xen-3.0.3-testing.orig/tools/firmware/hvmloader/Makefile -+++ xen-3.0.3-testing/tools/firmware/hvmloader/Makefile -@@ -37,7 +37,8 @@ CFLAGS += $(call test-gcc-flag,$(CC),-f - CFLAGS += $(call test-gcc-flag,$(CC),-fno-stack-protector-all) - - OBJCOPY = objcopy --CFLAGS += $(DEFINES) -I. $(XENINC) -fno-builtin -O2 -msoft-float -+# Optimizations cause problems on 64 bit. Investigate. -+CFLAGS += $(DEFINES) -I. $(XENINC) -fno-builtin -O0 -msoft-float - LDFLAGS = -m32 -nostdlib -Wl,-N -Wl,-Ttext -Wl,$(LOADADDR) - - SRCS = hvmloader.c acpi_madt.c mp_tables.c util.c smbios.c -Index: xen-3.0.3-testing/tools/blktap/drivers/Makefile -=================================================================== ---- xen-3.0.3-testing.orig/tools/blktap/drivers/Makefile -+++ xen-3.0.3-testing/tools/blktap/drivers/Makefile -@@ -10,7 +10,6 @@ QCOW_UTIL = img2qcow qcow2raw qcow-cr - INSTALL_DIR = /usr/sbin +--- xen-unstable.orig/tools/blktap/drivers/Makefile ++++ xen-unstable/tools/blktap/drivers/Makefile +@@ -8,7 +8,6 @@ QCOW_UTIL = img2qcow qcow2raw qcow-cr + INST_DIR = /usr/sbin LIBAIO_DIR = ../../libaio/src -CFLAGS += -Werror CFLAGS += -Wno-unused CFLAGS += -fno-strict-aliasing CFLAGS += -I $(XEN_LIBXC) -I $(LIBAIO_DIR) -Index: xen-3.0.3-testing/tools/console/Makefile +Index: xen-unstable/tools/ioemu/Makefile =================================================================== ---- xen-3.0.3-testing.orig/tools/console/Makefile -+++ xen-3.0.3-testing/tools/console/Makefile -@@ -9,7 +9,7 @@ INSTALL = install - INSTALL_PROG = $(INSTALL) -m0755 - INSTALL_DIR = $(INSTALL) -d -m0755 - --CFLAGS += -Werror -g -+CFLAGS += -Werror - - CFLAGS += -I $(XEN_LIBXC) - CFLAGS += -I $(XEN_XENSTORE) -Index: xen-3.0.3-testing/tools/ioemu/Makefile -=================================================================== ---- xen-3.0.3-testing.orig/tools/ioemu/Makefile -+++ xen-3.0.3-testing/tools/ioemu/Makefile +--- xen-unstable.orig/tools/ioemu/Makefile ++++ xen-unstable/tools/ioemu/Makefile @@ -8,7 +8,7 @@ include $(XEN_ROOT)/tools/Rules.mk .PHONY: all clean distclean dvi info install install-doc tar tarbin \ speed test test2 html dvi info @@ -50,29 +23,16 @@ Index: xen-3.0.3-testing/tools/ioemu/Makefile ifdef CONFIG_DARWIN CFLAGS+= -mdynamic-no-pic endif -Index: xen-3.0.3-testing/tools/xenstore/Makefile +Index: xen-unstable/Config.mk =================================================================== ---- xen-3.0.3-testing.orig/tools/xenstore/Makefile -+++ xen-3.0.3-testing/tools/xenstore/Makefile -@@ -11,7 +11,7 @@ INSTALL_PROG = $(INSTALL) -m0755 - INSTALL_DIR = $(INSTALL) -d -m0755 - - PROFILE=#-pg --BASECFLAGS=-Wall -g -Werror -+BASECFLAGS=-Wall -Werror - # Make gcc generate dependencies. - BASECFLAGS += -Wp,-MD,.$(@F).d - PROG_DEP = .*.d -Index: xen-3.0.3-testing/Config.mk -=================================================================== ---- xen-3.0.3-testing.orig/Config.mk -+++ xen-3.0.3-testing/Config.mk -@@ -10,7 +10,7 @@ XEN_TARGET_X86_PAE ?= n +--- xen-unstable.orig/Config.mk ++++ xen-unstable/Config.mk +@@ -13,7 +13,7 @@ CONFIG_$(XEN_OS) := y # Tools to run on system hosting the build HOSTCC = gcc -HOSTCFLAGS = -Wall -Werror -Wstrict-prototypes -O2 -fomit-frame-pointer +HOSTCFLAGS:= -Wall -Werror -Wstrict-prototypes $(RPM_OPT_FLAGS) - AS = $(CROSS_COMPILE)as - LD = $(CROSS_COMPILE)ld + DISTDIR ?= $(XEN_ROOT)/dist + DESTDIR ?= / diff --git a/xen-tightvnc-args.diff b/xen-tightvnc-args.diff index 2d9fdf5..4ce2e1b 100644 --- a/xen-tightvnc-args.diff +++ b/xen-tightvnc-args.diff @@ -1,8 +1,8 @@ -Index: xen-unstable/tools/python/xen/xm/create.py +Index: xen-3.0.4-testing/tools/python/xen/xm/create.py =================================================================== ---- xen-unstable.orig/tools/python/xen/xm/create.py -+++ xen-unstable/tools/python/xen/xm/create.py -@@ -902,8 +902,7 @@ def spawn_vnc(display): +--- xen-3.0.4-testing.orig/tools/python/xen/xm/create.py ++++ xen-3.0.4-testing/tools/python/xen/xm/create.py +@@ -962,8 +962,7 @@ def spawn_vnc(display): returns the port that the vncviewer is listening on and sets the global vncpid. On failure, returns 0. Note that vncviewer is daemonized. """ diff --git a/xen-vm-install.diff b/xen-vm-install.diff new file mode 100644 index 0000000..f9b0b0d --- /dev/null +++ b/xen-vm-install.diff @@ -0,0 +1,12 @@ +Index: xen-unstable/tools/Makefile +=================================================================== +--- xen-unstable.orig/tools/Makefile ++++ xen-unstable/tools/Makefile +@@ -25,6 +25,7 @@ SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen + # These don't cross-compile + ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH)) + SUBDIRS-y += python ++SUBDIRS-y += xen-vm-install + endif + + .PHONY: all diff --git a/xen-vm-install.tar.bz2 b/xen-vm-install.tar.bz2 new file mode 100644 index 0000000..241bd71 --- /dev/null +++ b/xen-vm-install.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e21bb469ef2d4b66eb11a50b923a0ba23140a1b88ccd73041f408580f81819d1 +size 59577 diff --git a/xen-warnings.diff b/xen-warnings.diff index d47cf08..679c49c 100644 --- a/xen-warnings.diff +++ b/xen-warnings.diff @@ -1,7 +1,7 @@ -Index: xen-3.0.3-testing/xen/tools/symbols.c +Index: xen-unstable/xen/tools/symbols.c =================================================================== ---- xen-3.0.3-testing.orig/xen/tools/symbols.c -+++ xen-3.0.3-testing/xen/tools/symbols.c +--- xen-unstable.orig/xen/tools/symbols.c ++++ xen-unstable/xen/tools/symbols.c @@ -120,7 +120,8 @@ read_symbol(FILE *in, struct sym_entry * if (rc != 3) { if (rc != EOF) { @@ -12,10 +12,10 @@ Index: xen-3.0.3-testing/xen/tools/symbols.c } return -1; } -Index: xen-3.0.3-testing/tools/misc/miniterm/miniterm.c +Index: xen-unstable/tools/misc/miniterm/miniterm.c =================================================================== ---- xen-3.0.3-testing.orig/tools/misc/miniterm/miniterm.c -+++ xen-3.0.3-testing/tools/misc/miniterm/miniterm.c +--- xen-unstable.orig/tools/misc/miniterm/miniterm.c ++++ xen-unstable/tools/misc/miniterm/miniterm.c @@ -157,7 +157,7 @@ int main(int argc, char **argv) case 0: close(1); /* stdout not needed */ diff --git a/xen-xm-top-needs-root.diff b/xen-xm-top-needs-root.diff index 5da0793..03654ae 100644 --- a/xen-xm-top-needs-root.diff +++ b/xen-xm-top-needs-root.diff @@ -1,11 +1,11 @@ From: Charles Coffing Upstream: no -Index: xen-unstable/tools/python/xen/xm/main.py +Index: xen-3.0.4-testing/tools/python/xen/xm/main.py =================================================================== ---- xen-unstable.orig/tools/python/xen/xm/main.py -+++ xen-unstable/tools/python/xen/xm/main.py -@@ -1018,6 +1018,10 @@ def xm_sysrq(args): +--- xen-3.0.4-testing.orig/tools/python/xen/xm/main.py ++++ xen-3.0.4-testing/tools/python/xen/xm/main.py +@@ -1312,6 +1312,10 @@ def xm_sysrq(args): def xm_top(args): arg_check(args, "top", 0) diff --git a/xen-xmexample-nbd.diff b/xen-xmexample-nbd.diff index 0139a32..ab8af5e 100644 --- a/xen-xmexample-nbd.diff +++ b/xen-xmexample-nbd.diff @@ -2,7 +2,7 @@ Index: xen-unstable/tools/examples/Makefile =================================================================== --- xen-unstable.orig/tools/examples/Makefile +++ xen-unstable/tools/examples/Makefile -@@ -17,7 +17,7 @@ XEN_CONFIGS = xend-config.sxp +@@ -12,7 +12,7 @@ XEN_CONFIGS = xend-config.sxp XEN_CONFIGS += xmexample1 XEN_CONFIGS += xmexample2 XEN_CONFIGS += xmexample.hvm diff --git a/xen-xmexample.diff b/xen-xmexample.diff index 4c70933..05a3314 100644 --- a/xen-xmexample.diff +++ b/xen-xmexample.diff @@ -1,10 +1,10 @@ Change various example paths in the config files to match SUSE. -Index: xen-unstable/tools/examples/xmexample1 +Index: xen-3.0.4-testing/tools/examples/xmexample1 =================================================================== ---- xen-unstable.orig/tools/examples/xmexample1 -+++ xen-unstable/tools/examples/xmexample1 -@@ -7,11 +7,14 @@ +--- xen-3.0.4-testing.orig/tools/examples/xmexample1 ++++ xen-3.0.4-testing/tools/examples/xmexample1 +@@ -7,11 +7,13 @@ #============================================================================ #---------------------------------------------------------------------------- @@ -18,13 +18,12 @@ Index: xen-unstable/tools/examples/xmexample1 +ramdisk = "/boot/initrd-xen" + +# Or use domUloader instead of kernel/ramdisk to get kernel from domU FS -+#bootloader = "/usr/lib/xen/boot/domUlaoder.py" ++#bootloader = "/usr/lib/xen/boot/domUloader.py" +#bootentry = "hda2:/vmlinuz-xen,/initrd-xen" -+#bootentry = "/boot/vmlinuz-xen,/boot/initrd-xen" # The domain build function. Default is 'linux'. #builder='linux' -@@ -96,7 +99,7 @@ disk = [ 'phy:hda1,hda1,w' ] +@@ -96,7 +98,7 @@ disk = [ 'phy:hda1,hda1,w' ] #hostname= "vm%d" % vmid # Set root device. @@ -33,7 +32,7 @@ Index: xen-unstable/tools/examples/xmexample1 # Root device for nfs. #root = "/dev/nfs" -@@ -105,8 +108,8 @@ root = "/dev/hda1 ro" +@@ -105,8 +107,8 @@ root = "/dev/hda1 ro" # Root directory on the nfs server. #nfs_root = '/full/path/to/root/directory' @@ -44,11 +43,11 @@ Index: xen-unstable/tools/examples/xmexample1 #---------------------------------------------------------------------------- # Configure the behaviour when a domain exits. There are three 'reasons' -Index: xen-unstable/tools/examples/xmexample2 +Index: xen-3.0.4-testing/tools/examples/xmexample2 =================================================================== ---- xen-unstable.orig/tools/examples/xmexample2 -+++ xen-unstable/tools/examples/xmexample2 -@@ -35,11 +35,14 @@ xm_vars.var('vmid', +--- xen-3.0.4-testing.orig/tools/examples/xmexample2 ++++ xen-3.0.4-testing/tools/examples/xmexample2 +@@ -35,11 +35,13 @@ xm_vars.var('vmid', xm_vars.check() #---------------------------------------------------------------------------- @@ -62,13 +61,12 @@ Index: xen-unstable/tools/examples/xmexample2 +ramdisk = "/boot/initrd-xen" + +# Or use domUloader instead of kernel/ramdisk to get kernel from domU FS -+#bootloader = "/usr/lib/xen/boot/domUlaoder.py" ++#bootloader = "/usr/lib/xen/boot/domUloader.py" +#bootentry = "hda2:/vmlinuz-xen,/initrd-xen" -+#bootentry = "/boot/vmlinuz-xen,/boot/initrd-xen" # The domain build function. Default is 'linux'. #builder='linux' -@@ -132,7 +135,7 @@ disk = [ 'phy:sda%d,sda1,w' % (7+vmid), +@@ -132,7 +134,7 @@ disk = [ 'phy:sda%d,sda1,w' % (7+vmid), #hostname= "vm%d" % vmid # Set root device. @@ -77,7 +75,7 @@ Index: xen-unstable/tools/examples/xmexample2 # Root device for nfs. #root = "/dev/nfs" -@@ -141,8 +144,8 @@ root = "/dev/sda1 ro" +@@ -141,8 +143,8 @@ root = "/dev/sda1 ro" # Root directory on the nfs server. #nfs_root = '/full/path/to/root/directory' @@ -88,11 +86,11 @@ Index: xen-unstable/tools/examples/xmexample2 #---------------------------------------------------------------------------- # Configure the behaviour when a domain exits. There are three 'reasons' -Index: xen-unstable/tools/examples/xmexample3 +Index: xen-3.0.4-testing/tools/examples/xmexample3 =================================================================== ---- xen-unstable.orig/tools/examples/xmexample3 -+++ xen-unstable/tools/examples/xmexample3 -@@ -35,11 +35,14 @@ xm_vars.var('vmid', +--- xen-3.0.4-testing.orig/tools/examples/xmexample3 ++++ xen-3.0.4-testing/tools/examples/xmexample3 +@@ -35,11 +35,13 @@ xm_vars.var('vmid', xm_vars.check() #---------------------------------------------------------------------------- @@ -106,17 +104,16 @@ Index: xen-unstable/tools/examples/xmexample3 +ramdisk = "/boot/initrd-xen" + +# Or use domUloader instead of kernel/ramdisk to get kernel from domU FS -+#bootloader = "/usr/lib/xen/boot/domUlaoder.py" ++#bootloader = "/usr/lib/xen/boot/domUloader.py" +#bootentry = "hda2:/vmlinuz-xen,/initrd-xen" -+#bootentry = "/boot/vmlinuz-xen,/boot/initrd-xen" # The domain build function. Default is 'linux'. #builder='linux' -Index: xen-unstable/tools/examples/xmexample.hvm +Index: xen-3.0.4-testing/tools/examples/xmexample.hvm =================================================================== ---- xen-unstable.orig/tools/examples/xmexample.hvm -+++ xen-unstable/tools/examples/xmexample.hvm -@@ -70,7 +70,7 @@ vif = [ 'type=ioemu, bridge=xenbr0' ] +--- xen-3.0.4-testing.orig/tools/examples/xmexample.hvm ++++ xen-3.0.4-testing/tools/examples/xmexample.hvm +@@ -71,7 +71,7 @@ vif = [ 'type=ioemu, bridge=xenbr0' ] # and MODE is r for read-only, w for read-write. #disk = [ 'phy:hda1,hda1,r' ] @@ -125,10 +122,10 @@ Index: xen-unstable/tools/examples/xmexample.hvm #---------------------------------------------------------------------------- # Configure the behaviour when a domain exits. There are three 'reasons' -Index: xen-unstable/docs/man/xmdomain.cfg.pod.5 +Index: xen-3.0.4-testing/docs/man/xmdomain.cfg.pod.5 =================================================================== ---- xen-unstable.orig/docs/man/xmdomain.cfg.pod.5 -+++ xen-unstable/docs/man/xmdomain.cfg.pod.5 +--- xen-3.0.4-testing.orig/docs/man/xmdomain.cfg.pod.5 ++++ xen-3.0.4-testing/docs/man/xmdomain.cfg.pod.5 @@ -38,13 +38,13 @@ file. The kernel image for the domain. The format of the parameter is the @@ -164,10 +161,10 @@ Index: xen-unstable/docs/man/xmdomain.cfg.pod.5 at hda1, which is the root filesystem. =item I -Index: xen-unstable/docs/man/xm.pod.1 +Index: xen-3.0.4-testing/docs/man/xm.pod.1 =================================================================== ---- xen-unstable.orig/docs/man/xm.pod.1 -+++ xen-unstable/docs/man/xm.pod.1 +--- xen-3.0.4-testing.orig/docs/man/xm.pod.1 ++++ xen-3.0.4-testing/docs/man/xm.pod.1 @@ -102,8 +102,8 @@ soon as it is run. =item I diff --git a/xen.changes b/xen.changes index 169ec07..2ef955b 100644 --- a/xen.changes +++ b/xen.changes @@ -1,7 +1,184 @@ ------------------------------------------------------------------- -Fri Feb 2 00:49:57 CET 2007 - ro@suse.de +Thu Feb 8 16:54:59 MST 2007 - ccoffing@novell.com -- added -fno-stack-protector to CFLAGS for now, link fails +- Update vm-install: + + Allow specifing disk (and disk size) vs. cdrom from CLI + + Add missing -M/--max-memory parameter to CLI to match GUI + + #241528: Display error if user selects FV OS but hw lacks VT + + Move all consistency checks out of Options class, since CLI + options may be processed in a "bad" order + + Fix infinite loops when info is missing from background jobs + + --background implies --no-auto-console + + Don't let user close progress window + + Fix bug in qemu slowness work-around, reported by Jan Albrecht + + Do disk.validate() when clicking "OK" on disks page + + #238959: Probe for removable media via /sys/block + + Output VNC info for backgrounded job + + Fix method of waiting for VM to exit when --no-autoconsole + + #239582: Use extracted kernel-xen/initrd-xen if present + +------------------------------------------------------------------- +Tue Feb 6 12:02:47 CET 2007 - ro@suse.de + +- disable commented out buildreq for kernel for the moment + to workaround endless rebuild + +------------------------------------------------------------------- +Tue Feb 6 10:30:33 MST 2007 - ccoffing@novell.com + +- xm-test should clean up xenstore better (#180138) + +------------------------------------------------------------------- +Thu Feb 1 12:07:59 MST 2007 - ccoffing@novell.com + +- Implement better job support for CIM (#241197) +- Temporary fix to allow PV VMs to reboot (#237414) +- Delete PYTHONOPTIMIZE for good; callers don't set it. + +------------------------------------------------------------------- +Wed Jan 31 08:51:05 MST 2007 - ccoffing@novell.com + +- Update xen-3.0.4 (changeset 13138); includes migration bugfix. + +------------------------------------------------------------------- +Tue Jan 30 07:43:09 MST 2007 - ccoffing@novell.com + +- Enable building KMP. +- Fix xendomains to work with managed domains. (#238781) + +------------------------------------------------------------------- +Thu Jan 25 09:16:10 MST 2007 - ccoffing@novell.com + +- Various bug fixes of 32on64, from Jan and Keir. +- Gerd's fix for domain builder with > 4 GB RAM (#233761) +- Update xen-vm-install: + #234331, #239007: CD/DVDs should always be marked read-only + #238458: Work-around qemu slowness bug + #239196: Support SLED + #239275: Fix .desktop file + #240064: Clean up VMs better after failed install + +------------------------------------------------------------------- +Tue Jan 23 09:11:29 MST 2007 - ccoffing@novell.com + +- Update xen-vm-install: + #237370: Can now install 32pae SLES 10 on x86_64 hypervisor + #237396: Be able to use an existing disk, bypass OS installation + Fix handling of user's extra_args +- Patch from Jan to enable building PV drivers KMP for FV SUSE. + Currently conditionalized. +- Drop unused patches xen-io-register-context.diff and + xen-console.diff + +------------------------------------------------------------------- +Sat Jan 20 09:44:00 MST 2007 - brogers@novell.com + +- Fix handling of localtime config file parameter for PV guests + (#234376) + +------------------------------------------------------------------- +Fri Jan 19 14:40:01 MST 2007 - ccoffing@novell.com + +- Update xen-vm-install (NIC UI work; do not require tcp port bz + #236517; integrate with virt-manager) + +------------------------------------------------------------------- +Wed Jan 17 14:14:17 MST 2007 - ccoffing@novell.com + +- Update xen-vm-install (more disk UI work; support NetWare + response files and licenses) + +------------------------------------------------------------------- +Tue Jan 16 16:36:14 MST 2007 - ccoffing@novell.com + +- Major fixes to xen-vm-install (adding disks in the UI now works, + and fixed several CLI exceptions) +- Microcode does not need to be exactly 2048 bytes (changeset + 13079; Kurt) + +------------------------------------------------------------------- +Fri Jan 12 17:09:56 MST 2007 - ccoffing@novell.com + +- Include script to clone SLES 10 domU, from coolsolutions (fate + #301742) +- Updated patches from Gerd and Jan, including PAE > 4 gig fix, + updated VGA console patch. +- Updated xen-vm-install with finalized strings and desktop file. + +------------------------------------------------------------------- +Thu Jan 11 08:40:18 MST 2007 - ccoffing@novell.com + +- Include xen-unstable patches for HVM save/restore and 32-on-64 + HVM. +- Update to xen-3.0.4-1 (changeset 13132). + +------------------------------------------------------------------- +Wed Jan 10 16:27:50 MST 2007 - ccoffing@novell.com + +- Update xen-vm-install and domUloader to support NetWare. +- Include AMD's nested page table patches. + +------------------------------------------------------------------- +Mon Jan 8 09:36:40 MST 2007 - ccoffing@novell.com + +- Update to xen-3.0.4 (changeset 13129). +- Fix from upstream for mis-emulation of x86-64 pop. + +------------------------------------------------------------------- +Fri Jan 5 10:58:48 MST 2007 - carnold@novell.com + +- Many patches from Jan Beulich and Gerd Hoffmann in support of + 32 on 64 pv guests. These patches apply to both the hypervisor + and the tools. + +------------------------------------------------------------------- +Fri Dec 22 10:40:06 MST 2006 - ccoffing@novell.com + +- Do not require authentication on XenAPI socket, since CIMOM does + not support authentication. Socket is only accessible to root. + +------------------------------------------------------------------- +Wed Dec 20 09:07:41 MST 2006 - ccoffing@novell.com + +- Update to xen-3.0.4 (changeset 13100). +- Update xen-vm-install tools. +- Include Jim's 2 xen-tools patches for CIM provider issues. + +------------------------------------------------------------------- +Mon Dec 18 14:59:01 MST 2006 - ccoffing@novell.com + +- Update to xen-3.0.4-rc3 (changeset 13087). +- Fix line terminators in block-iscsi (#228864) +- Make domUloader work with blktap support in xend. + +------------------------------------------------------------------- +Fri Dec 15 10:22:29 MST 2006 - ccoffing@novell.com + +- Update to xen-3.0.4-rc2 (changeset 13067). + +------------------------------------------------------------------- +Thu Dec 14 14:54:19 MST 2006 - ccoffing@novell.com + +- Update to xen-3.0.4-rc1 (changeset 12901). + +------------------------------------------------------------------- +Wed Dec 13 12:53:00 MST 2006 - brogers@novell.com + +- Patch for loading bimodal PAE kernel to suuport NetWare + +------------------------------------------------------------------- +Thu Dec 7 10:33:58 MST 2006 - ccoffing@novell.com + +- Update to xen-unstable (changeset 12757). +- Enable LIBXENAPI_BINDINGS and XENFB_TOOLS. +- Enable unix domain socket for xend; needed by tools. + +------------------------------------------------------------------- +Tue Dec 5 15:12:12 MST 2006 - ccoffing@novell.com + +- Update to xen-unstable (changeset 12734; feature freeze for + 3.0.4) +- Make /etc/xen mode 0700 to protect vnc passwords. ------------------------------------------------------------------- Mon Nov 27 18:07:41 MST 2006 - ccoffing@novell.com @@ -12,8 +189,8 @@ Mon Nov 27 18:07:41 MST 2006 - ccoffing@novell.com ------------------------------------------------------------------- Wed Nov 22 11:26:06 MST 2006 - ccoffing@novell.com -- Include Jan's patch, which accounts for selectors in protected - mode with a non-zero base. Fixes some HVM crashes. (#214568) +- Series of patches from Jan to address selectors with non-zero- + bases and other related issues in HVM. (#214568) - Default pae=1, otherwise 64 bit HVM does not work at all. (#217160) @@ -30,7 +207,7 @@ Thu Nov 16 13:16:09 MST 2006 - ccoffing@novell.com PFN is > 2 GB. (#220418) ------------------------------------------------------------------- -Tue Nov 14 14:20:09 MST 2006 - kallan@novell.com +Mon Nov 13 20:40:09 MST 2006 - kallan@novell.com - Backport changesets 11847, 11888, 1189[6-9], 119[00-18], 11974, 1203[0-2], and 12205 from xen-unstable so that the PV drivers @@ -42,6 +219,7 @@ Tue Nov 14 14:20:09 MST 2006 - kallan@novell.com ------------------------------------------------------------------- Thu Nov 9 10:10:09 MST 2006 - ccoffing@novell.com +- Add xen-vm-install. - Default bridge correctly for HVM guests. (#219092) ------------------------------------------------------------------- @@ -52,14 +230,13 @@ Wed Nov 8 11:26:02 CET 2006 - aj@suse.de ------------------------------------------------------------------- Tue Nov 7 08:43:01 MST 2006 - ccoffing@novell.com -- Fix some 64 bit issues in Python 2.5 introduced by PEP353. - Update name of blktap.ko in xend init script. (#215384) - Remove some extraneous bad chars in xm manpage. (#218440) - Update logrotate.conf. -- Update spec file. +- Update spec file. ------------------------------------------------------------------- -Tue Nov 01 11:16:05 MST 2006 - kallan@novell.com +Wed Nov 01 11:16:05 MST 2006 - kallan@novell.com - Backport xen-unstable changesets 12040 to address spurious interrupts with PV drivers in HVM guests. @@ -83,6 +260,8 @@ Mon Oct 16 12:58:46 MDT 2006 - ccoffing@novell.com - Fix several possible type errors when running domUloader. - Remove pygrub. Was broken on reiserfs and never had ext2 support, so it is useless. (#173384) +- First attempt at moving domUloader to blktap. Still disabled + due to block-detach failing. ------------------------------------------------------------------- Fri Oct 13 10:29:18 MDT 2006 - ccoffing@novell.com diff --git a/xen.spec b/xen.spec index fe9db46..bc49f10 100644 --- a/xen.spec +++ b/xen.spec @@ -1,5 +1,5 @@ # -# spec file for package xen (Version 3.0.3_11774) +# spec file for package xen (Version 3.0.4_13138) # # Copyright (c) 2007 SUSE LINUX Products GmbH, Nuernberg, Germany. # This file and all modifications and additions to the pristine @@ -11,119 +11,178 @@ # norootforbuild Name: xen -BuildRequires: LibVNCServer SDL-devel autoconf automake bin86 dev86 glibc-devel-32bit latex2html libjpeg-devel libreiserfs-devel openssl openssl-devel python-devel te_ams te_latex tetex transfig %define xvers 3.0 %define xvermaj 3 -%define changeset 11774 -%define with_pvfb 0 -%define xen_build_dir xen-3.0.3-testing -Version: 3.0.3_11774 -Release: 31 +%define changeset 13138 +%define xen_build_dir xen-3.0.4-testing +%define with_install 1 +%if %sles_version +%define with_kmp 1 +%else +# openSUSE 10.3 kernel is not yet ready... +%define with_kmp 0 +%endif +BuildRequires: LibVNCServer SDL-devel autoconf automake bin86 curl-devel dev86 latex2html libjpeg-devel libxml2-devel openssl openssl-devel python-devel te_ams te_latex tetex transfig +%ifarch x86_64 +BuildRequires: glibc-32bit glibc-devel-32bit +%endif +%if %{?with_kmp}0 +BuildRequires: kernel-source kernel-syms xorg-x11 +%endif +Version: 3.0.4_13138 +Release: 1 License: GNU General Public License (GPL) Group: System/Kernel Autoreqprov: on PreReq: %insserv_prereq %fillup_prereq Summary: Xen Virtualization: Hypervisor (aka VMM aka Microkernel) -Source: xen-3.0.3-testing-src.tar.bz2 +Source0: xen-3.0.4-testing-src.tar.bz2 +Source1: xen-vm-install.tar.bz2 Source2: README.SuSE Source3: boot.xen Source4: boot.local.xenU -Source5: mk-xen-rescue-img.sh -Source6: init.xend -Source7: init.xendomains -Source8: logrotate.xend.conf -Source9: domUloader.py -Source10: xmexample.domUloader -Source11: xmexample.rescue -Source12: block-nbd -Source13: xmexample.nbd -Source14: block-iscsi -Source15: xmexample.iscsi -Patch1: xen-destdir.diff -Patch2: serial-split.patch -Patch3: xen-warnings.diff +Source5: init.xend +Source6: init.xendomains +Source7: logrotate.xend.conf +Source8: domUloader.py +Source9: xmexample.domUloader +Source10: block-nbd +Source11: xmexample.nbd +Source12: block-iscsi +Source13: xmexample.iscsi +Source14: xmclone.sh +Patch0: xen-config.diff +Patch1: xend-config.diff +Patch2: xen-destdir.diff +Patch3: xen-vm-install.diff Patch4: xen-rpmoptflags.diff -Patch5: xen-docs.diff -Patch6: xen-xmexample.diff -Patch7: xen-xmexample-nbd.diff -Patch8: xen-changeset.diff -Patch9: xen-domUloader.diff -Patch10: xen-domUloader-pygrub.diff -Patch11: xen-messages.diff -Patch12: xen-network-bridge.diff -Patch13: xen-no-dummy-nfs-ip.diff -Patch14: xen-config-defaults.diff -Patch15: xen-xm-top-needs-root.diff -Patch16: xen-tightvnc-args.diff -Patch17: xen-max-free-mem.diff -Patch18: xen-bonding.diff -Patch19: xen-ioapic-ack-default.diff -Patch20: xen-lost-mouse.diff -Patch21: xen-paths.diff -Patch22: xen-lowmem-emergency-pool.diff -Patch23: xen-console.diff -Patch24: block-losetup-retry.diff -Patch25: block-sync.diff -Patch26: xen-io-register-context.diff -Patch27: xen-keymap.diff -Patch28: xen-man-permissions.patch -Patch29: xen-man-xm-bad-char.diff -Patch30: xen-python25-warnings.diff +Patch5: xen-warnings.diff +Patch6: xen-changeset.diff +Patch7: xen-paths.diff +Patch8: xen-xmexample.diff +Patch9: xen-xmexample-nbd.diff +Patch10: xen-bootloader-nohang.diff +Patch11: xen-bootloader-dryrun.diff +Patch12: xen-bootloader-tidy.diff +Patch13: xen-domUloader.diff +Patch14: xen-messages.diff +Patch15: xen-network-bridge.diff +Patch16: xen-no-dummy-nfs-ip.diff +Patch17: serial-split.patch +Patch18: xen-xm-top-needs-root.diff +Patch19: xen-tightvnc-args.diff +Patch20: xen-max-free-mem.diff +Patch21: xen-bonding.diff +Patch22: xen-ioapic-ack-default.diff +Patch23: xen-lost-mouse.diff +Patch24: xen-lowmem-emergency-pool.diff +Patch26: block-losetup-retry.diff +Patch27: block-sync.diff +Patch29: xen-man-permissions.patch +Patch30: xen-man-xm-bad-char.diff Patch31: xen-hvm-default-bridge.diff Patch32: xen-hvm-netfront.diff Patch33: xend-xmlrpc-large-ints.diff Patch34: xen-hvm-default-pae.diff -Patch35: non-flat-pm.patch -## Upstream (or upstream soon): -Patch100: xen-pvfb-2.patch -Patch101: xen-pvfb-3.patch -Patch102: xu-11841-svm-interrupt-delivery.diff -Patch103: xu-11842-svm-interrupt-delivery.diff -Patch104: xu-11843-svm-no-double-nmi.diff -Patch105: xu-11847-pv-hvm.diff -Patch106: xu-11888-pv-hvm.diff -Patch107: xu-11896-pv-hvm.diff -Patch108: xu-11897-pv-hvm.diff -Patch109: xu-11898-pv-hvm.diff -Patch110: xu-11899-pv-hvm.diff -Patch111: xu-11900-pv-hvm.diff -Patch112: xu-11901-pv-hvm.diff -Patch113: xu-11902-pv-hvm.diff -Patch114: xu-11903-pv-hvm.diff -Patch115: xu-11904-pv-hvm.diff -Patch116: xu-11905-pv-hvm.diff -Patch117: xu-11906-pv-hvm.diff -Patch118: xu-11907-pv-hvm.diff -Patch119: xu-11908-pv-hvm.diff -Patch120: xu-11909-pv-hvm.diff -Patch121: xu-11910-pv-hvm.diff -Patch122: xu-11911-pv-hvm.diff -Patch123: xu-11912-pv-hvm.diff -Patch124: xu-11913-pv-hvm.diff -Patch125: xu-11914-pv-hvm.diff -Patch126: xu-11915-pv-hvm.diff -Patch127: xu-11916-pv-hvm.diff -Patch128: xu-11917-pv-hvm.diff -Patch129: xu-11918-pv-hvm.diff -Patch130: xu-11974-pv-hvm.diff -Patch131: xu-12012-hvm-smp-timer.diff -Patch132: xu-12013-hvm-ioapic.diff -Patch133: xu-12030-pv-hvm.diff -Patch134: xu-12031-pv-hvm.diff -Patch135: xu-12032-pv-hvm.diff -Patch136: xu-12040-pv-spurious-interrupt.diff -Patch137: xu-12205-pv-hvm.diff -Patch138: xu-12278-hvm-interrupt-race.diff -## Debugging: -Patch200: xen-enable-hvm-debug.diff -## Future / need to be re-ported: -Patch300: xen-poweroff.diff +Patch35: xend-config-devname.patch +Patch36: xend-config-ramdisk.patch +Patch37: xm-test-cleanup.diff +## Jan's patches begin here +Patch100: x86-extra-trap-info.patch +Patch101: x86_emulate.patch +# 32on64 patches +Patch102: 32on64-base.patch +Patch103: 32on64-hypercall.patch +Patch104: 32on64-interface.patch +Patch105: 32on64-startup.patch +Patch106: 32on64-shared.patch +Patch107: 32on64-m2p.patch +Patch108: 32on64-emul.patch +Patch109: 32on64-memop.patch +Patch110: 32on64-mmuop.patch +Patch111: 32on64-physdevop.patch +Patch112: 32on64-vcpuop.patch +Patch113: 32on64-settrap.patch +Patch114: 32on64-multicall.patch +Patch115: 32on64-schedop.patch +Patch116: 32on64-gnttabop.patch +Patch117: 32on64-pltop.patch +Patch118: 32on64-acmop.patch +Patch119: 32on64-xenoprof.patch +Patch120: 32on64-sysctl.patch +Patch121: 32on64-domctl.patch +Patch122: 32on64-trace.patch +Patch123: 32on64-kexec.patch +Patch124: 32on64-hvm.patch +Patch125: 32on64-shadow.patch +# Additional patches +Patch130: xxx_heap_pages-static.patch +Patch131: mem-zones.patch +Patch132: domheap-no-dma.patch +Patch133: 32on64-per-domain-pa-bits.patch +Patch134: 32on64-fixes.patch +Patch135: 32on64-call-gates.patch +Patch136: emul-privop-lock.patch +Patch137: hide-asm-labels.patch +Patch138: bug.patch +Patch139: x86-mm-simplify.patch +Patch140: vgacon-50-lines.patch +Patch141: vgacon-keep.patch +Patch142: x86-ptwr_emulate.patch +Patch143: pae-guest-linear-pgtable.patch +Patch144: suppress-rdtscp.patch +## Gerd's patches begin here +# fix cross-build for tools +Patch150: cross-build-fix.diff +# network script fixup +Patch151: bridge-hostonly.diff +# foreign arch headers +Patch152: xen-generate-foreign-headers.diff +# common ELF parser code +Patch153: libelf-add-to-xenkernel.diff +Patch154: libelf-use-xen-dom0.diff +Patch155: libelf-symlink-to-libxc.diff +Patch156: libelf-use-hvm-build.diff +Patch157: libelf-use-readnotes.diff +# domain builder rewrite +Patch158: tools-add-errors.diff +Patch159: tools-domain-builder-header-libxc.diff +Patch160: tools-domain-builder-core.diff +Patch161: tools-domain-builder-linux.diff +Patch162: tools-readnotes-gunzip.diff +# bimodal driver bits +Patch163: protocol-bimodal.diff +Patch164: fbback-bimodal.diff +Patch165: blktools-bimodal.diff +# libxc debugging bits +Patch166: tools-debug-oldbuilder.diff +Patch167: libxc-logging.diff +# guest kexec, kboot +Patch168: tools-xc_kexec.diff +Patch169: tools-kboot.diff +# AMD nested page table patches +Patch200: npt_part1.patch +Patch201: npt_part2.patch +Patch202: npt-windows-bug.patch +Patch203: npt-fpu-bug.patch +# Upstream bug fixes +Patch210: microcode-xen-13079.diff +Patch211: xen-localtime.patch +Patch212: svm-update-v_tpr-on-mmio.patch +Patch213: svm_cpuid_ffxsr_13743.patch +# pv driver building +Patch250: pv-driver-build.patch +# Misc unused patches / need to be re-ported: +Patch300: xen-enable-hvm-debug.diff Patch301: xen-removable.diff URL: http://www.cl.cam.ac.uk/Research/SRG/netos/xen/ Prefix: /usr BuildRoot: %{_tmppath}/%{name}-%{version}-build ExclusiveArch: %ix86 x86_64 ia64 %define pysite %(python -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib()") +%if %{?with_kmp}0 +%suse_kernel_module_package -n xen um xen xenpae +%endif %description Xen is a virtual machine monitor for x86 that supports execution of @@ -182,7 +241,7 @@ Authors: %package libs Summary: Xen Virtualization: Libraries Group: System/Kernel -Requires: xen >= 3.0.3_10000 +Requires: xen >= 3.0.4_10000 AutoReqProv: on %description libs @@ -231,8 +290,11 @@ Authors: %package tools Summary: Xen Virtualization: Control tools for domain 0 Group: System/Kernel -Requires: xen-libs >= 3.0.3_10000 -Requires: python python-xml bridge-utils multipath-tools +Requires: xen-libs >= 3.0.4_10000 +Requires: bridge-utils multipath-tools python python-xml +%if %{?with_install}0 +Requires: python-urlgrabber +%endif AutoReqProv: on %description tools @@ -284,7 +346,7 @@ Authors: %package tools-ioemu Summary: Xen Virtualization: BIOS and device emulation for unmodified guests Group: System/Kernel -Requires: xen-tools >= 3.0.3_10000 +Requires: xen-tools >= 3.0.4_10000 AutoReqProv: on %description tools-ioemu @@ -382,6 +444,53 @@ Authors: -------- Ian Pratt +%if %{?with_kmp}0 +%package KMP +Group: System/Kernel +Summary: Xen para-virtual device drivers for fully virtualized guests + +%description KMP +Xen para-virtual device drivers for fully virtualized guests + +Xen is a virtual machine monitor for x86 that supports execution of +multiple guest operating systems with unprecedented levels of +performance and resource isolation. + +This package contains the libraries and header files needed to create +tools to control virtual machines. + +Modern computers are sufficiently powerful to use virtualization to +present the illusion of many smaller virtual machines (VMs), each +running a separate operating system instance. Successful partitioning +of a machine to support the concurrent execution of multiple operating +systems poses several challenges. Firstly, virtual machines must be +isolated from one another: It is not acceptable for the execution of +one to adversely affect the performance of another. This is +particularly true when virtual machines are owned by mutually +untrusting users. Secondly, it is necessary to support a variety of +different operating systems to accommodate the heterogeneity of popular +applications. Thirdly, the performance overhead introduced by +virtualization should be small. + +Xen uses a technique called paravirtualization: The guest OS is +modified, mainly to enhance performance. + +The Xen hypervisor (microkernel) does not provide device drivers for +your hardware (except for CPU and memory). This job is left to the +kernel that's running in domain 0. Thus the domain 0 kernel is +privileged; it has full hardware access. It's started immediately after +Xen starts up. Other domains have no access to the hardware; instead +they use virtual interfaces that are provided by Xen (with the help of +the domain 0 kernel). + +Xen does support booting other Operating Systems; ports of NetBSD +(Christian Limpach), FreeBSD (Kip Macy), and Plan 9 (Ron Minnich) +exist. A port of Windows XP was developed for an earlier version of +Xen, but is not available for release due to license restrictions. + + + +%endif %package doc-html Summary: Xen Virtualization: HTML documentation Group: Documentation/HTML @@ -439,11 +548,48 @@ Authors: %prep %setup -q -n %xen_build_dir -# Apply upstream patches first... -%if %{?with_pvfb}0 +%setup -q -c -n %xen_build_dir/tools -D -T -a 1 +cd .. +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%if %{?with_install}0 +%patch3 -p1 +%endif +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch26 -p1 +%patch27 -p1 +%patch29 -p1 +%patch30 -p1 +%patch31 -p1 +%patch32 -p1 +%patch33 -p1 +%patch34 -p1 +%patch35 -p1 +%patch36 -p1 +%patch37 -p1 %patch100 -p1 %patch101 -p1 -%endif %patch102 -p1 %patch103 -p1 %patch104 -p1 @@ -468,10 +614,6 @@ Authors: %patch123 -p1 %patch124 -p1 %patch125 -p1 -%patch126 -p1 -%patch127 -p1 -%patch128 -p1 -%patch129 -p1 %patch130 -p1 %patch131 -p1 %patch132 -p1 @@ -481,57 +623,68 @@ Authors: %patch136 -p1 %patch137 -p1 %patch138 -p1 -# Now our patches... -%patch1 -p1 -%patch2 -p1 -%patch3 -p1 -%patch4 -p1 -%patch5 -p1 -%patch6 -p1 -%patch7 -p1 -%patch8 -p1 -%patch9 -p1 -#%patch10 -p1 -%patch11 -p1 -%patch12 -p1 -%patch13 -p1 -%patch14 -p1 -%patch15 -p1 -%patch16 -p1 -%patch17 -p1 -%patch18 -p1 -%patch19 -p1 -%patch20 -p1 -%patch21 -p1 -%patch22 -p1 -%patch23 -p1 -%patch24 -p1 -%patch25 -p1 -%patch26 -p1 -%patch27 -p1 -%patch28 -p1 -%patch29 -p1 -%patch30 -p1 -%patch31 -p1 -%patch32 -p1 -%patch33 -p1 -%patch34 -p1 -%patch35 -p1 +%patch139 -p1 +%patch140 -p1 +%patch141 -p1 +%patch142 -p1 +%patch143 -p1 +%patch144 -p1 +%patch150 -p1 +%patch151 -p1 +%patch152 -p1 +%patch153 -p1 +%patch154 -p1 +%patch155 -p1 +%patch156 -p1 +%patch157 -p1 +%patch158 -p1 +%patch159 -p1 +%patch160 -p1 +%patch161 -p1 +%patch162 -p1 +%patch163 -p1 +%patch164 -p1 +%patch165 -p1 +%patch166 -p1 +%patch167 -p1 +%patch168 -p1 +%patch169 -p1 +%patch200 -p1 +%patch201 -p1 +%patch202 -p1 +%patch203 -p1 +%patch210 -p1 +%patch211 -p1 +%patch212 -p1 +%patch213 -p1 +%patch250 -p1 XEN_EXTRAVERSION=%version-%release XEN_EXTRAVERSION=${XEN_EXTRAVERSION#%{xvers}} sed -i "s/XEN_EXTRAVERSION[ ]*.=.*\$/XEN_EXTRAVERSION = $XEN_EXTRAVERSION/" xen/Makefile sed -i "s/XEN_CHANGESET[ ]*=.*\$/XEN_CHANGESET = %{changeset}/" xen/Makefile -# Unmaintained; remove to avoid spurious Python PEP353 warnings -rm -rf tools/pygrub %build -test ! -z "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != "/" && rm -rf $RPM_BUILD_ROOT -export CFLAGS="$RPM_OPT_FLAGS -fno-stack-protector" +cd .. +export CFLAGS="$RPM_OPT_FLAGS" export RPM_OPT_FLAGS +make -C xen/include/public/foreign make tools docs +%if %{?with_kmp}0 +# pv driver modules +mkdir -p obj +for flavor in %flavors_to_build; do + rm -rf obj/$flavor + cp -r unmodified_drivers/linux-2.6 obj/$flavor + obj/$flavor/mkbuildtree + make -C /usr/src/linux-obj/%_target_cpu/$flavor modules \ + M=$PWD/obj/$flavor +done +%endif %install -export CFLAGS="$RPM_OPT_FLAGS -fno-stack-protector" +test ! -z "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != "/" && rm -rf $RPM_BUILD_ROOT +cd .. +export CFLAGS="$RPM_OPT_FLAGS" export RPM_OPT_FLAGS install_xen() { @@ -566,65 +719,78 @@ make -C xen clean make -C xen install pae=n debug=n crash_debug=n DESTDIR=$RPM_BUILD_ROOT install_xen make -C xen clean +export CFLAGS="$RPM_OPT_FLAGS" +export RPM_OPT_FLAGS +make -C xen/include/public/foreign # tools export XEN_PYTHON_NATIVE_INSTALL=1 -export PYTHONOPTIMIZE=1 -mkdir -p $RPM_BUILD_ROOT/%pysite/xen +#export PYTHONOPTIMIZE=1 make -C tools install \ DESTDIR=$RPM_BUILD_ROOT MANDIR=%{_mandir} +%if %{?with_install}0 +ln -s /usr/bin/vm-install $RPM_BUILD_ROOT/usr/sbin/xen-vm-install +%endif make -C tools/misc/serial-split install \ DESTDIR=$RPM_BUILD_ROOT MANDIR=%{_mandir} %ifarch x86_64 mkdir -p $RPM_BUILD_ROOT/usr/lib/xen/bin/ ln -s %{_libdir}/xen/bin/qemu-dm $RPM_BUILD_ROOT/usr/lib/xen/bin/qemu-dm -%if %{?with_pvfb}0 ln -s %{_libdir}/xen/bin/xen-sdlfb $RPM_BUILD_ROOT/usr/lib/xen/bin/xen-sdlfb ln -s %{_libdir}/xen/bin/xen-vncfb $RPM_BUILD_ROOT/usr/lib/xen/bin/xen-vncfb %endif +%if %{?with_kmp}0 +# pv driver modules +export INSTALL_MOD_PATH=$RPM_BUILD_ROOT +export INSTALL_MOD_DIR=updates +for flavor in %flavors_to_build; do + make -C /usr/src/linux-obj/%_target_cpu/$flavor modules_install \ + M=$PWD/obj/$flavor +done %endif # docs -mkdir -p $RPM_BUILD_ROOT/%{_defaultdocdir}/xen -sh ./docs/check_pkgs \ - && make -C docs install \ - DESTDIR=$RPM_BUILD_ROOT MANDIR=%{_mandir} \ - DOCDIR=%{_defaultdocdir}/xen \ - || true +make -C docs install \ + DESTDIR=$RPM_BUILD_ROOT MANDIR=%{_mandir} \ + DOCDIR=%{_defaultdocdir}/xen for name in COPYING %SOURCE2 %SOURCE3; do - cp -p $name $RPM_BUILD_ROOT/%{_defaultdocdir}/xen/ + install -m 644 $name $RPM_BUILD_ROOT/%{_defaultdocdir}/xen/ done mkdir -p $RPM_BUILD_ROOT/%{_defaultdocdir}/xen/misc for name in vtpm.txt crashdb.txt sedf_scheduler_mini-HOWTO.txt; do - cp -p docs/misc/$name $RPM_BUILD_ROOT/%{_defaultdocdir}/xen/misc/ + install -m 644 docs/misc/$name $RPM_BUILD_ROOT/%{_defaultdocdir}/xen/misc/ done # init scripts mkdir -p $RPM_BUILD_ROOT/etc/init.d -install %SOURCE6 $RPM_BUILD_ROOT/etc/init.d/xend +install %SOURCE5 $RPM_BUILD_ROOT/etc/init.d/xend ln -s /etc/init.d/xend $RPM_BUILD_ROOT/usr/sbin/rcxend -install %SOURCE7 $RPM_BUILD_ROOT/etc/init.d/xendomains +install %SOURCE6 $RPM_BUILD_ROOT/etc/init.d/xendomains ln -s /etc/init.d/xendomains $RPM_BUILD_ROOT/usr/sbin/rcxendomains # example config mkdir -p $RPM_BUILD_ROOT/etc/xen/{vm,examples} mv $RPM_BUILD_ROOT/etc/xen/xmexample* $RPM_BUILD_ROOT/etc/xen/examples rm $RPM_BUILD_ROOT/etc/xen/examples/*nbd -install -m644 %SOURCE10 %SOURCE11 %SOURCE13 %SOURCE15 $RPM_BUILD_ROOT/etc/xen/examples/ -# scripts -install -m755 %SOURCE4 %SOURCE5 $RPM_BUILD_ROOT/%{_defaultdocdir}/xen/ +install -m644 %SOURCE9 %SOURCE11 %SOURCE13 $RPM_BUILD_ROOT/etc/xen/examples/ +# sample scripts +install -m755 %SOURCE4 %SOURCE14 $RPM_BUILD_ROOT/%{_defaultdocdir}/xen/ rm $RPM_BUILD_ROOT/etc/xen/scripts/block-*nbd -install -m755 %SOURCE12 %SOURCE14 $RPM_BUILD_ROOT/etc/xen/scripts/ +install -m755 %SOURCE10 %SOURCE12 $RPM_BUILD_ROOT/etc/xen/scripts/ # logrotate -install -m644 -D %SOURCE8 $RPM_BUILD_ROOT/etc/logrotate.d/xend +install -m644 -D %SOURCE7 $RPM_BUILD_ROOT/etc/logrotate.d/xend # directories mkdir -p $RPM_BUILD_ROOT/var/lib/xenstored mkdir -p $RPM_BUILD_ROOT/var/lib/xen/images +mkdir -p $RPM_BUILD_ROOT/var/lib/xen/jobs mkdir -p $RPM_BUILD_ROOT/var/lib/xen/save mkdir -p $RPM_BUILD_ROOT/var/lib/xen/xend-db/domain mkdir -p $RPM_BUILD_ROOT/var/lib/xen/xend-db/migrate mkdir -p $RPM_BUILD_ROOT/var/lib/xen/xend-db/vnet +%if %{?with_install}0 +mkdir -p $RPM_BUILD_ROOT/var/lib/xen/vm-install +%endif mkdir -p $RPM_BUILD_ROOT/var/log/xen mkdir -p $RPM_BUILD_ROOT/var/run/xenstored ln -s /var/lib/xen/images $RPM_BUILD_ROOT/etc/xen/images # Bootloader -install -m755 %SOURCE9 $RPM_BUILD_ROOT/usr/lib/xen/boot/ +install -m755 %SOURCE8 $RPM_BUILD_ROOT/usr/lib/xen/boot/ # udev support mv $RPM_BUILD_ROOT/etc/udev/rules.d/xen-backend.rules $RPM_BUILD_ROOT/etc/udev/rules.d/40-xen.rules # Clean up unpackaged files @@ -666,8 +832,9 @@ rm -f $RPM_BUILD_ROOT/%pysite/*.egg-info %files libs %defattr(-,root,root) +%{_libdir}/fs/ +%{_libdir}/libfsimage* %{_libdir}/libxen*.so.* -%{_libdir}/libxenstore.so %files tools %defattr(-,root,root) @@ -684,6 +851,13 @@ rm -f $RPM_BUILD_ROOT/%pysite/*.egg-info /usr/sbin/rcxendomains /usr/sbin/xen* /usr/sbin/xm +%if %{?with_install}0 +/usr/bin/vm-install* +%{_datadir}/xen/install +%dir /var/lib/xen/vm-install +%dir %{_datadir}/applications/YaST2 +%{_datadir}/applications/YaST2/xen-vm-install.desktop +%endif %dir %{_libdir}/xen %dir %{_libdir}/xen/bin %ifarch x86_64 @@ -693,11 +867,8 @@ rm -f $RPM_BUILD_ROOT/%pysite/*.egg-info %dir /usr/lib/xen/boot %{_libdir}/libblktap.so* %{_libdir}/xen/bin/readnotes -%if %{?with_pvfb}0 %{_libdir}/xen/bin/xen-sdlfb %{_libdir}/xen/bin/xen-vncfb -%endif -#%{_libdir}/xen/bin/xc_kexec %{_libdir}/xen/bin/xc_restore %{_libdir}/xen/bin/xc_save %{_libdir}/xen/bin/xenconsole @@ -719,18 +890,18 @@ rm -f $RPM_BUILD_ROOT/%pysite/*.egg-info %config /etc/init.d/xend %config /etc/logrotate.d/xend /var/adm/fillup-templates/sysconfig.xendomains -%dir /etc/xen +%dir %attr(700,root,root) /etc/xen %config /etc/xen/* %dir /etc/udev %dir /etc/udev/rules.d /etc/udev/rules.d/40-xen.rules %dir %{_defaultdocdir}/xen %{_defaultdocdir}/xen/COPYING -%attr(644,root,root) %{_defaultdocdir}/xen/README.SuSE -%{_defaultdocdir}/xen/mk-xen-rescue-img.sh -%attr(644,root,root) %{_defaultdocdir}/xen/boot.xen -%attr(644,root,root) %{_defaultdocdir}/xen/boot.local.xenU +%{_defaultdocdir}/xen/README.SuSE +%{_defaultdocdir}/xen/boot.xen +%{_defaultdocdir}/xen/boot.local.xenU %{_defaultdocdir}/xen/misc +%{_defaultdocdir}/xen/xmclone.sh %dir %pysite/xen %pysite/xen/* @@ -745,10 +916,11 @@ rm -f $RPM_BUILD_ROOT/%pysite/*.egg-info %{_libdir}/xen/bin/qemu-dm %ifarch x86_64 /usr/lib/xen/bin/qemu-dm -%if %{?with_pvfb}0 /usr/lib/xen/bin/xen-sdlfb /usr/lib/xen/bin/xen-vncfb -%endif +/usr/lib64/xen/bin/xc_kexec +%else +/usr/lib/xen/bin/xc_kexec %endif /usr/lib/xen/boot/hvmloader @@ -756,21 +928,13 @@ rm -f $RPM_BUILD_ROOT/%pysite/*.egg-info %defattr(-,root,root) %{_libdir}/libblktap.a %{_libdir}/libxen*.a -%{_libdir}/libxenc*.so -%{_libdir}/libxeng*.so -%dir /usr/include/xen -%dir /usr/include/xen/io -%dir /usr/include/xen/hvm -%dir /usr/include/xen/linux +%{_libdir}/libxen*.so +/usr/include/xen/ /usr/include/blktaplib.h +/usr/include/fsimage* /usr/include/xen*.h /usr/include/xs.h /usr/include/xs_lib.h -/usr/include/xen/COPYING -/usr/include/xen/*.h -/usr/include/xen/io/*.h -/usr/include/xen/hvm/*.h -/usr/include/xen/linux/*.h /usr/bin/serial-split /usr/bin/xenperf @@ -804,14 +968,119 @@ rm -f $RPM_BUILD_ROOT/%pysite/*.egg-info %{insserv_cleanup} %changelog -n xen -* Fri Feb 02 2007 - ro@suse.de -- added -fno-stack-protector to CFLAGS for now, link fails +* Thu Feb 08 2007 - ccoffing@novell.com +- Update vm-install: + + Allow specifing disk (and disk size) vs. cdrom from CLI + + Add missing -M/--max-memory parameter to CLI to match GUI + + #241528: Display error if user selects FV OS but hw lacks VT + + Move all consistency checks out of Options class, since CLI + options may be processed in a "bad" order + + Fix infinite loops when info is missing from background jobs + + --background implies --no-auto-console + + Don't let user close progress window + + Fix bug in qemu slowness work-around, reported by Jan Albrecht + + Do disk.validate() when clicking "OK" on disks page + + #238959: Probe for removable media via /sys/block + + Output VNC info for backgrounded job + + Fix method of waiting for VM to exit when --no-autoconsole + + #239582: Use extracted kernel-xen/initrd-xen if present +* Tue Feb 06 2007 - ro@suse.de +- disable commented out buildreq for kernel for the moment + to workaround endless rebuild +* Tue Feb 06 2007 - ccoffing@novell.com +- xm-test should clean up xenstore better (#180138) +* Thu Feb 01 2007 - ccoffing@novell.com +- Implement better job support for CIM (#241197) +- Temporary fix to allow PV VMs to reboot (#237414) +- Delete PYTHONOPTIMIZE for good; callers don't set it. +* Wed Jan 31 2007 - ccoffing@novell.com +- Update xen-3.0.4 (changeset 13138); includes migration bugfix. +* Tue Jan 30 2007 - ccoffing@novell.com +- Enable building KMP. +- Fix xendomains to work with managed domains. (#238781) +* Thu Jan 25 2007 - ccoffing@novell.com +- Various bug fixes of 32on64, from Jan and Keir. +- Gerd's fix for domain builder with > 4 GB RAM (#233761) +- Update xen-vm-install: + [#234331], #239007: CD/DVDs should always be marked read-only + [#238458]: Work-around qemu slowness bug + [#239196]: Support SLED + [#239275]: Fix .desktop file + [#240064]: Clean up VMs better after failed install +* Tue Jan 23 2007 - ccoffing@novell.com +- Update xen-vm-install: + [#237370]: Can now install 32pae SLES 10 on x86_64 hypervisor + [#237396]: Be able to use an existing disk, bypass OS installation + Fix handling of user's extra_args +- Patch from Jan to enable building PV drivers KMP for FV SUSE. + Currently conditionalized. +- Drop unused patches xen-io-register-context.diff and + xen-console.diff +* Sat Jan 20 2007 - brogers@novell.com +- Fix handling of localtime config file parameter for PV guests + (#234376) +* Fri Jan 19 2007 - ccoffing@novell.com +- Update xen-vm-install (NIC UI work; do not require tcp port bz + [#236517]; integrate with virt-manager) +* Wed Jan 17 2007 - ccoffing@novell.com +- Update xen-vm-install (more disk UI work; support NetWare + response files and licenses) +* Tue Jan 16 2007 - ccoffing@novell.com +- Major fixes to xen-vm-install (adding disks in the UI now works, + and fixed several CLI exceptions) +- Microcode does not need to be exactly 2048 bytes (changeset + 13079; Kurt) +* Fri Jan 12 2007 - ccoffing@novell.com +- Include script to clone SLES 10 domU, from coolsolutions (fate + [#301742]) +- Updated patches from Gerd and Jan, including PAE > 4 gig fix, + updated VGA console patch. +- Updated xen-vm-install with finalized strings and desktop file. +* Thu Jan 11 2007 - ccoffing@novell.com +- Include xen-unstable patches for HVM save/restore and 32-on-64 + HVM. +- Update to xen-3.0.4-1 (changeset 13132). +* Wed Jan 10 2007 - ccoffing@novell.com +- Update xen-vm-install and domUloader to support NetWare. +- Include AMD's nested page table patches. +* Mon Jan 08 2007 - ccoffing@novell.com +- Update to xen-3.0.4 (changeset 13129). +- Fix from upstream for mis-emulation of x86-64 pop. +* Fri Jan 05 2007 - carnold@novell.com +- Many patches from Jan Beulich and Gerd Hoffmann in support of + 32 on 64 pv guests. These patches apply to both the hypervisor + and the tools. +* Fri Dec 22 2006 - ccoffing@novell.com +- Do not require authentication on XenAPI socket, since CIMOM does + not support authentication. Socket is only accessible to root. +* Wed Dec 20 2006 - ccoffing@novell.com +- Update to xen-3.0.4 (changeset 13100). +- Update xen-vm-install tools. +- Include Jim's 2 xen-tools patches for CIM provider issues. +* Mon Dec 18 2006 - ccoffing@novell.com +- Update to xen-3.0.4-rc3 (changeset 13087). +- Fix line terminators in block-iscsi (#228864) +- Make domUloader work with blktap support in xend. +* Fri Dec 15 2006 - ccoffing@novell.com +- Update to xen-3.0.4-rc2 (changeset 13067). +* Thu Dec 14 2006 - ccoffing@novell.com +- Update to xen-3.0.4-rc1 (changeset 12901). +* Wed Dec 13 2006 - brogers@novell.com +- Patch for loading bimodal PAE kernel to suuport NetWare +* Thu Dec 07 2006 - ccoffing@novell.com +- Update to xen-unstable (changeset 12757). +- Enable LIBXENAPI_BINDINGS and XENFB_TOOLS. +- Enable unix domain socket for xend; needed by tools. +* Tue Dec 05 2006 - ccoffing@novell.com +- Update to xen-unstable (changeset 12734; feature freeze for + 3.0.4) +- Make /etc/xen mode 0700 to protect vnc passwords. * Mon Nov 27 2006 - ccoffing@novell.com - Fix how bootloader is called by the xend during restarts. (#223850) * Wed Nov 22 2006 - ccoffing@novell.com -- Include Jan's patch, which accounts for selectors in protected - mode with a non-zero base. Fixes some HVM crashes. (#214568) +- Series of patches from Jan to address selectors with non-zero- + bases and other related issues in HVM. (#214568) - Default pae=1, otherwise 64 bit HVM does not work at all. (#217160) * Fri Nov 17 2006 - ccoffing@novell.com @@ -820,7 +1089,7 @@ rm -f $RPM_BUILD_ROOT/%pysite/*.egg-info - Fix some problems in the xen-hvm-default-bridge patch. (#219092) - xmlrpc isn't 64-bit clean, causing xend to get exceptions when PFN is > 2 GB. (#220418) -* Tue Nov 14 2006 - kallan@novell.com +* Mon Nov 13 2006 - kallan@novell.com - Backport changesets 11847, 11888, 1189[6-9], 119[00-18], 11974, 1203[0-2], and 12205 from xen-unstable so that the PV drivers can compile on older kernels such as sles9 and rhel4 @@ -828,11 +1097,11 @@ rm -f $RPM_BUILD_ROOT/%pysite/*.egg-info type device. This allows both PV and FV drivers to exist at same time in the FV guest. * Thu Nov 09 2006 - ccoffing@novell.com +- Add xen-vm-install. - Default bridge correctly for HVM guests. (#219092) * Wed Nov 08 2006 - aj@suse.de - Set correct permissions on man files. * Tue Nov 07 2006 - ccoffing@novell.com -- Fix some 64 bit issues in Python 2.5 introduced by PEP353. - Update name of blktap.ko in xend init script. (#215384) - Remove some extraneous bad chars in xm manpage. (#218440) - Update logrotate.conf. @@ -851,6 +1120,8 @@ rm -f $RPM_BUILD_ROOT/%pysite/*.egg-info - Fix several possible type errors when running domUloader. - Remove pygrub. Was broken on reiserfs and never had ext2 support, so it is useless. (#173384) +- First attempt at moving domUloader to blktap. Still disabled + due to block-detach failing. * Fri Oct 13 2006 - ccoffing@novell.com - Update to xen-3.0.3-testing changeset 11760 (rc4). * Tue Oct 10 2006 - ccoffing@novell.com diff --git a/xend-config-devname.patch b/xend-config-devname.patch new file mode 100644 index 0000000..2871e49 --- /dev/null +++ b/xend-config-devname.patch @@ -0,0 +1,27 @@ +# HG changeset patch +# User jfehlig@jfehlig2.provo.novell.com +# Date 1166568442 25200 +# Node ID 72a013bc923efa47b3262849cd5611a16353abc5 +# Parent 057f7c4dbed1c75a3fbe446d346cee04cff31497 +Remove ':disk' suffix from dev entry in dev_info dictionary in XendConfig.py. + +The suffix was added regardless of device type so it doesn't appear to add any semantics. Additionally, clients would be forced to strip this suffix from the device name since something like 'hda:disk" is not a device name. + +Signed-off-by: Jim Fehlig + +diff -r 057f7c4dbed1 -r 72a013bc923e tools/python/xen/xend/XendConfig.py +--- a/tools/python/xen/xend/XendConfig.py Tue Dec 19 12:00:11 2006 +0000 ++++ b/tools/python/xen/xend/XendConfig.py Tue Dec 19 15:47:22 2006 -0700 +@@ -970,10 +970,10 @@ class XendConfig(dict): + elif dev_type in ('vbd', 'tap'): + if dev_type == 'vbd': + dev_info['uname'] = cfg_xenapi.get('image', '') +- dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device') ++ dev_info['dev'] = cfg_xenapi.get('device') + elif dev_type == 'tap': + dev_info['uname'] = 'tap:qcow:%s' % cfg_xenapi.get('image') +- dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device') ++ dev_info['dev'] = cfg_xenapi.get('device') + + dev_info['driver'] = cfg_xenapi.get('driver') + dev_info['VDI'] = cfg_xenapi.get('VDI', '') diff --git a/xend-config-ramdisk.patch b/xend-config-ramdisk.patch new file mode 100644 index 0000000..a06945b --- /dev/null +++ b/xend-config-ramdisk.patch @@ -0,0 +1,21 @@ +# HG changeset patch +# User jfehlig@jfehlig2.provo.novell.com +# Date 1166572407 25200 +# Node ID d7fd9bc007cd6d4b704a28e24883d63469d30b28 +# Parent 057f7c4dbed1c75a3fbe446d346cee04cff31497 +Recent changes to the grub/cmdline definition in XenAPI introduced PV_bootloader, PV_kernel, PV_ramdisk, etc. This patch fixes one of the kernel_initrc -> PV_ramdisk conversions that was missed in XendConfig.py. + +Signed-off-by: Jim Fehlig + +diff -r 057f7c4dbed1 -r d7fd9bc007cd tools/python/xen/xend/XendConfig.py +--- a/tools/python/xen/xend/XendConfig.py Tue Dec 19 12:00:11 2006 +0000 ++++ b/tools/python/xen/xend/XendConfig.py Tue Dec 19 16:53:27 2006 -0700 +@@ -139,7 +139,7 @@ XENAPI_CFG_TYPES = { + 'tpm_backend': int, + 'PV_bootloader': str, + 'PV_kernel': str, +- 'PV_initrd': str, ++ 'PV_ramdisk': str, + 'PV_args': str, + 'PV_bootloader_args': str, + 'HVM_boot': str, diff --git a/xen-config-defaults.diff b/xend-config.diff similarity index 52% rename from xen-config-defaults.diff rename to xend-config.diff index a1158a5..1b7aaed 100644 --- a/xen-config-defaults.diff +++ b/xend-config.diff @@ -1,7 +1,7 @@ -Index: xen-unstable/tools/examples/init.d/sysconfig.xendomains +Index: xen-3.0.4-testing/tools/examples/init.d/sysconfig.xendomains =================================================================== ---- xen-unstable.orig/tools/examples/init.d/sysconfig.xendomains -+++ xen-unstable/tools/examples/init.d/sysconfig.xendomains +--- xen-3.0.4-testing.orig/tools/examples/init.d/sysconfig.xendomains ++++ xen-3.0.4-testing/tools/examples/init.d/sysconfig.xendomains @@ -98,7 +98,6 @@ XENDOMAINS_RESTORE=true # Note that the script tries to be clever if both RESTORE and AUTO are # set: It will first restore saved domains and then only start domains @@ -21,13 +21,29 @@ Index: xen-unstable/tools/examples/init.d/sysconfig.xendomains ## Type: integer ## Default: 300 -Index: xen-unstable/tools/examples/xend-config.sxp +Index: xen-3.0.4-testing/tools/examples/xend-config.sxp =================================================================== ---- xen-unstable.orig/tools/examples/xend-config.sxp -+++ xen-unstable/tools/examples/xend-config.sxp -@@ -19,7 +19,6 @@ +--- xen-3.0.4-testing.orig/tools/examples/xend-config.sxp ++++ xen-3.0.4-testing/tools/examples/xend-config.sxp +@@ -46,16 +46,19 @@ + # (xen-api-server ((9363 pam '^localhost$ example\\.com$') + # (unix none))) + # +-# Default: +-# (xen-api-server ((unix))) ++ ++# Until the CIMOM supports authentication, do not require authentication on ++# the unix socket. The socket is restricted to root via file permissions. ++(xen-api-server ((unix none))) + + + #(xend-http-server no) +-#(xend-unix-server no) ++(xend-unix-server yes) #(xend-tcp-xmlrpc-server no) #(xend-unix-xmlrpc-server yes) ++# Only enable xend-relocation-server on trusted networks. Currently ++# lacks encryption and authentication. #(xend-relocation-server no) -(xend-relocation-server yes) diff --git a/xend-xmlrpc-large-ints.diff b/xend-xmlrpc-large-ints.diff index c0579a6..314712b 100644 --- a/xend-xmlrpc-large-ints.diff +++ b/xend-xmlrpc-large-ints.diff @@ -16,25 +16,19 @@ PFNs once we clean up the XML-RPC interface. Signed-off-by: Anthony Liguori -Index: xen-3.0.3-testing/tools/python/xen/util/xmlrpclib2.py +Index: xen-3.0.4-testing/tools/python/xen/util/xmlrpclib2.py =================================================================== ---- xen-3.0.3-testing.orig/tools/python/xen/util/xmlrpclib2.py -+++ xen-3.0.3-testing/tools/python/xen/util/xmlrpclib2.py -@@ -25,10 +25,11 @@ import types - import fcntl - - from httplib import HTTPConnection, HTTP --from xmlrpclib import Transport -+from xmlrpclib import Transport, Fault +--- xen-3.0.4-testing.orig/tools/python/xen/util/xmlrpclib2.py ++++ xen-3.0.4-testing/tools/python/xen/util/xmlrpclib2.py +@@ -29,6 +29,7 @@ from httplib import HTTPConnection, HTTP from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler import SocketServer --import xmlrpclib, socket, os, stat -+import xmlrpclib, socket, os, stat, string -+from types import * + import xmlrpclib, socket, os, stat ++from xmlrpclib import Fault - from xen.xend.XendLogging import log + import mkdir -@@ -48,6 +49,9 @@ except ImportError: +@@ -68,6 +69,9 @@ def stringify(value): # # It assumes that the RPC handler is /RPC2. This probably needs to be improved @@ -44,7 +38,7 @@ Index: xen-3.0.3-testing/tools/python/xen/util/xmlrpclib2.py # We're forced to subclass the RequestHandler class so that we can work around # some bugs in Keep-Alive handling and also enabled it by default class XMLRPCRequestHandler(SimpleXMLRPCRequestHandler): -@@ -127,6 +131,67 @@ class ServerProxy(xmlrpclib.ServerProxy) +@@ -157,6 +161,67 @@ class ServerProxy(xmlrpclib.ServerProxy) return conv_string(response) @@ -112,7 +106,7 @@ Index: xen-3.0.3-testing/tools/python/xen/util/xmlrpclib2.py # This is a base XML-RPC server for TCP. It sets allow_reuse_address to # true, and has an improved marshaller that logs and serializes exceptions. -@@ -174,15 +239,15 @@ class TCPXMLRPCServer(SocketServer.Threa +@@ -208,15 +273,15 @@ class TCPXMLRPCServer(SocketServer.Threa response = repr(response)[1:-1] response = (response,) diff --git a/xm-test-cleanup.diff b/xm-test-cleanup.diff new file mode 100644 index 0000000..0331d3b --- /dev/null +++ b/xm-test-cleanup.diff @@ -0,0 +1,14 @@ +Index: xen-3.0.4-testing/tools/xm-test/tests/save/01_save_basic_pos.py +=================================================================== +--- xen-3.0.4-testing.orig/tools/xm-test/tests/save/01_save_basic_pos.py ++++ xen-3.0.4-testing/tools/xm-test/tests/save/01_save_basic_pos.py +@@ -35,3 +35,9 @@ if s != 0: + # Make sure it's gone + if isDomainRunning(domain.getName()): + FAIL("Domain still running after save!") ++ ++# Clean up ++try: ++ s, o = traceCommand("xm delete %s" % domain.getName(), timeout=30) ++except: ++ pass diff --git a/xmclone.sh b/xmclone.sh new file mode 100644 index 0000000..83b2530 --- /dev/null +++ b/xmclone.sh @@ -0,0 +1,579 @@ +#!/bin/sh +################################################################################ +# xmclone by Bob Brandt # +# based on XenClone by Glen Davis # +# Clone a SLES10 domU # +################################################################################ + +################################################################################ +# Defaults # +# # +VERSION=0.3 +XEN_CONFIGS=/etc/xen/vm/ +XEN_BASE=/xen/ +SOURCE= +DESTINATION= +DUPLICATE=0 +HOSTNAME= +IP= +MAC= +################################################################################ + + +################################################################################ +# Subroutines used in this script # +# # +# Display the usage information for this script # +usage() +{ + echo -e "\nUsage: ${0##*/} [-h|?|--help] [-v|--version] [-c dir] [-b dir] [-d]" + echo -e " [-n hostname] [-i address] [-m address]" + echo -e " SourcedomU NewdomU\n" + echo -e "Clones a domU, and gives a new Host name, MAC address and possibly IP address." + echo -e "Once finished the new domU should boot without any additional configuration." + echo -e "Currently works with single NIC, and basic bridge setup. Tested with cloning" + echo -e "a SLES10 install created from the SLES10 YaST Xen module.\n" + echo -e " -h, -?, --help Display this help message." + echo -e " -v, --version Display the version of this program." + echo -e " -c XEN configuration directory which defaults to:" + echo -e " $XEN_CONFIGS" + echo -e " -b XEN image base directory which defaults to:" + echo -e " $XEN_BASE" + echo -e " -d Only Duplicate, do not modify attributes." + echo -e " -n Hostname to be used, if not specified the NewdomU name" + echo -e " will be used." + echo -e " -i IP address to be used, if not specified the IP address" + echo -e " will not be changed." + echo -e " -m MAC address to be used, if not specified a psuedo-random" + echo -e " address will be used based on the ip address with the" + echo -e " format: 00:16:AA:BB:CC:DD" + echo -e " Where AA,BB,CC,DD are the Hex octals of the IP address." + echo -e "From XENSource Networking WIKI (http://wiki.xensource.com/xenwiki/XenNetworking)" + echo -e "Virtualised network interfaces in domains are given Ethernet MAC addresses. When" + echo -e "choosing MAC addresses to use, ensure you choose a unicast address. That is, one" + echo -e "with the low bit of the first octet set to zero. For example, an address" + echo -e "starting aa: is OK but ab: is not." + echo -e 'It is best to keep to the range of addresses declared to be "locally assigned"' + echo -e "(rather than allocated globally to hardware vendors). These have the second" + echo -e "lowest bit set to one in the first octet. For example, aa: is OK, a8: isn't.\n" + echo -e "Exit status is 0 if OK, 1 if minor problems, 2 if serious trouble.\n" +} +# Display the version information for this script # +version() +{ + echo -e "${0##*/} (XEN vm clone utility) $VERSION" + echo -e "This is free software. You may redistribute copies of it under the terms of" + echo -e "the GNU General Public License ." + echo -e "There is NO WARRANTY, to the extent permitted by law.\n" + echo -e "Written by Bob Brandt, based on work by Glen Davis." +} +# Find/Replace text within a file # +replace() +{ + SearchText=$1 + ReplaceText=$2 + File=$3 + if sed "s/$SearchText/$ReplaceText/g" "$File" > "$File.temporary" && sleep 1 + then + if mv -f "$File.temporary" "$File" && sleep 1 + then + return 0 + fi + fi + return 1 +} +################################################################################ + + +################################################################################ +# Make sure the user is root # +# # +if [ `id -u` -ne 0 ]; then + echo -e "You must be root to run this script!\n" + exit 1 +fi +################################################################################ + + +################################################################################ +# Process the parameters # +# # +# Must look for double -- arguments before getopts +if [ "$1" = "--version" ]; then + version + exit 0; +fi +if [ "$1" = "--help" ]; then + usage + exit 0; +fi +while getopts ":hvc:b:dn:i:m:" opt; do + case $opt in + h | \? ) + usage + exit 0;; + v ) + version + exit 0;; + c ) XEN_CONFIGS=$OPTARG;; + b ) XEN_BASE=$OPTARG;; + d ) DUPLICATE=1;; + n ) HOSTNAME=$OPTARG;; + i ) IP=$OPTARG;; + m ) MAC=$OPTARG;; + esac +done +shift $(($OPTIND-1)) + +SOURCE=$1 +DESTINATION=$2 +################################################################################ + + +################################################################################ +# Verify the Source and Destination parameters # +# # +# The source and destination should be relative directory names without trailing /'s +# If the source does have a full path, use that path as the XEN_BASE +# Otherwise remove all but the last part of the path for both source and destination +SOURCEDIR=${SOURCE%/*} +SOURCEBASE=${SOURCE##*/} +if [ "$SOURCEDIR" != "$SOURCEBASE" ]; then + XEN_BASE=$SOURCEDIR"/" + SOURCE=$SOURCEBASE +fi +SOURCE=${SOURCE##*/} +DESTINATION=${DESTINATION##*/} +################################################################################ + + +################################################################################ +# Verify the XEN Config and Source parameters # +# # +# Directories should have a / after them # +if [ "$XEN_CONFIGS" != "" ]; then + XEN_CONFIGS="${XEN_CONFIGS%/}/" +fi +if [ "$XEN_BASE" != "" ]; then + XEN_BASE="${XEN_BASE%/}/" +fi +# Verify the validity of each agrument ask the user if there is a problem +while [ ! -d "$XEN_CONFIGS" ]; do + echo -e "\nThe $XEN_CONFIGS directory does not exist. Please enter a valid directory." + read -p "XEN Configuration Directory? " XEN_CONFIGS +done +while [ ! -d "$XEN_BASE" ]; do + echo -e "\nThe $XEN_BASE directory does not exist. Please enter a valid directory." + read -p "XEN Image Base Directory? " XEN_BASE +done +################################################################################ + + +################################################################################ +# Verify that actual image and configuration file exist # +# # +while [ ! -d "$XEN_BASE$SOURCE" ] || [ ! -f "$XEN_CONFIGS$SOURCE" ]; do + if [ ! -d "$XEN_BASE$SOURCE" ]; then + echo -e "The directory $XEN_BASE$SOURCE is invalid, please select another." + FILES= + tmpFILES=`ls $XEN_BASE` + + for FILE in $tmpFILES; do + # If the Entry is a Directory + if [ -d "$XEN_BASE$FILE" ]; then + # And if that Directory is not empty + if [ "`ls $XEN_BASE$FILE`" != "" ]; then + FILES="$FILES $XEN_BASE$FILE" + fi + fi + done + if [ "$FILES" = "" ]; then + echo -e "There are no directories beneath $XEN_BASE" + exit 1 + else + echo -e "Directories beneath $XEN_BASE" + select FILE in $FILES; do + if [ "$FILE" ]; then + SOURCE=${FILE##*/} + break + else + echo -e "Invalid Selection." + fi + done + fi + fi + + if [ ! -f "$XEN_CONFIGS$SOURCE" ]; then + echo -e "\nThe $XEN_CONFIGS$SOURCE file does not exist. Please select a valid file." + FILES= + tmpFILES=`ls $XEN_CONFIGS` + + for FILE in $tmpFILES; do + # If the Entry is a File + if [ -f "$XEN_CONFIGS$FILE" ]; then + FILES="$FILES $XEN_CONFIGS$FILE" + fi + done + if [ "$FILES" = "" ]; then + echo -e "There are no files beneath $XEN_CONFIGS" + exit 1 + else + echo -e "Files beneath $XEN_CONFIGS" + select FILE in $FILES; do + if [ "$FILE" ]; then + SOURCE=${FILE##*/} + break + else + echo -e "Invalid Selection." + fi + done + fi + fi +done +################################################################################ + + +################################################################################ +# That the destination location does not already have a image or config file # +# # +while [ "$DESTINATION" == "" ]; do + echo -e "\nYou have not specified a Destination." + read -p "New Destination? " DESTINATION +done + +while [ -d "$XEN_BASE$DESTINATION" ] || [ -f "$XEN_CONFIGS$DESTINATION" ]; do + if [ -d "$XEN_BASE$DESTINATION" ]; then + echo -e "The image location $XEN_BASE$DESTINATION already exists!" + read -p "Please select a new Destination? " DESTINATION + fi + if [ -f "$XEN_CONFIGS$DESTINATION" ]; then + echo -e "The configuration file $XEN_CONFIGS$DESTINATION already exists!" + read -p "Please select a new Destination? " DESTINATION + fi +done +################################################################################ + + +################################################################################ +# Verify the network parameters (if Duplicate Only was not selected) # +# # +if [ "$DUPLICATE" == "0" ]; then + if [ "$HOSTNAME" == "" ]; then + echo -e "\nYou have not entered a Host Name. If you wish to, enter one now." + read -p "New Host Name? (Default: $DESTINATION) " HOSTNAME + fi + if [ "$HOSTNAME" == "" ]; then + HOSTNAME=$DESTINATION + fi + + if [ "$IP" == "" ]; then + echo -e "\nYou have not specified an IP Address. If you wish to change the IP address, enter one now." + read -p "New IP Address? " IP + fi + while [ "$IP" != "" ] && [ "${IP/*.*.*.*/ok}" != "ok" ]; do + echo -e "\nThe IP Address you specified is invalid. If you wish, enter a new one now." + read -p "New IP Address? " IP + if [ "$IP" == "" ]; then + break + fi + done + + if [ "$MAC" == "" ]; then + newMAC="" + newMACtext="(format 01:23:45:67:89:AB)" + # If the IP Address is specified and the MAC isn't, generate one. + if [ "$IP" != "" ]; then + octal1=${IP%%.*} + IP=${IP#*.} + octal2=${IP%%.*} + IP=${IP#*.} + octal3=${IP%%.*} + octal4=${IP#*.} + IP="$octal1.$octal2.$octal3.$octal4" + octal1="00"`echo $octal1 16 o p | dc` + octal2="00"`echo $octal2 16 o p | dc` + octal3="00"`echo $octal3 16 o p | dc` + octal4="00"`echo $octal4 16 o p | dc` + newMAC="00:16:"${octal1:(-2)}":"${octal2:(-2)}":"${octal3:(-2)}":"${octal4:(-2)} + newMACtext="(default $newMAC)" + fi + echo -e "\nYou have not specified a MAC Address. If you wish to change the MAC address, enter one now." + read -p "New MAC Address? $newMACtext " MAC + if [ "$MAC" == "" ]; then + MAC=$newMAC + fi + fi + + while [ "$MAC" != "" ] && [ "${MAC/[0123456789abcdefABCDEF][0123456789abcdefABCDEF]:[0123456789abcdefABCDEF][0123456789abcdefABCDEF]:[0123456789abcdefABCDEF][0123456789abcdefABCDEF]:[0123456789abcdefABCDEF][0123456789abcdefABCDEF]:[0123456789abcdefABCDEF][0123456789abcdefABCDEF]:[0123456789abcdefABCDEF][0123456789abcdefABCDEF]/ok}" != "ok" ]; do + echo -e "\nThe MAC Address you specified is invalid. If you wish, enter a new one now." + read -p "New MAC Address? (format 01:23:45:67:89:AB) " MAC + if [ "$MAC" == "" ]; then + break + fi + done +else + HOSTNAME= + IP= + MAC= +fi +################################################################################ + + +################################################################################ +# Make sure that the source VM is not running # +# # +xmid=`xm list | grep $SOURCE | cut -c34-36` +if [ "$xmid" != "" ]; then + echo -e "domU $SOURCE is currently running on Xen, please shutdown before cloning." + echo -e "The command \"xm shutdown $xmid -w\" will shutdown the domU" + exit 1 +fi +################################################################################ + + +################################################################################ +# Copy the XEN Config file # +# # +SOURCECONFIG="$XEN_CONFIGS$SOURCE" +DESTCONFIG="$XEN_CONFIGS$DESTINATION" +echo -e "Copying Configuration files" +if ! cp -fv "$SOURCECONFIG" "$DESTCONFIG" +then + echo -e "The Config file $SOURCECONFIG was unable to be copied to $DESTCONFIG" + exit 1 +fi +################################################################################ + + +################################################################################ +# Edit newly copied configuration file # +# # +echo -e "Editing config file ($DESTCONFIG), correcting the new domU Name." +if ! replace $SOURCE $DESTINATION $DESTCONFIG +then + echo -e "Unable to change the domU name in $DESTCONFIG from $SOURCE to $DESTINATION" + exit 1 +fi + +if [ "$DUPLICATE" == "0" ] && [ "$MAC" != "" ]; then + # Get the vif line in the config file + oldMAC=`grep "vif = " $DESTCONFIG` + # extract everything between the square brackets + oldMAC=${oldMAC#*[} + oldMAC=${oldMAC%*]} + # using the single quotes as delimiters, get the second field (this script can only deal with one adapter!) + oldMAC=`echo "$oldMAC" | cut -f2 -d\'` + # remove the mac= from the beginning + oldMAC=${oldMAC#mac=*} + + if ! replace $oldMAC $MAC $DESTCONFIG + then + echo -e "Unable to change the MAC address in $DESTCONFIG from ($oldMAC) to ($MAC)" + exit 1 + fi +fi +################################################################################ + + +################################################################################ +# Create and Copy image directory # +# # +SOURCEXEN="$XEN_BASE$SOURCE/" +DESTXEN="$XEN_BASE$DESTINATION/" +echo -e "Creating the new image directory $DESTXEN" +if ! mkdir -pv --mode=775 "$DESTXEN" +then + echo -e "Unable to create the directory $DESTXEN" + exit 1 +fi +echo -e "Copying complete image. (This may take a few minutes!)" + +if ! cp -fv --sparse=never $SOURCEXEN* $DESTXEN +then + echo -e "Unable to copy the images from $SOURCEXEN to $DESTXEN" + exit 1 +fi +################################################################################ + + +# The rest of the document only applies if we are change the values within the image +if [ "$DUPLICATE" == "0" ] && [ "$MAC" != "" ]; then + ############################################################################ + # Mount the newly copied image file # + # # + # Find a temporary directory name + tmpdir="/mnt/xentmp" + declare -i a=0 + while [ -d "$tmpdir$a" ]; do + a=a+1 + done + tmpdir="$tmpdir$a" + if ! mkdir -pv "$tmpdir" + then + echo -e "Unable to create $tmpdir Directory." + exit 1 + fi + + # Get the vif line in the config file + DISKIMAGE=`grep "disk = " $DESTCONFIG` + # extract everything between the square brackets + DISKIMAGE=${DISKIMAGE#*[} + DISKIMAGE=${DISKIMAGE%*]} + # extract the first entry that is a file + DISKIMAGE=${DISKIMAGE#*file:*} + # remove the end of the entry + DISKIMAGE=${DISKIMAGE%,w*} + # using the comma as delimiter, get the second field (this script assumes that the first file entry is the boot disk!) + DISKIMAGE=`echo "$DISKIMAGE" | cut -f2 -d\,` + + # Get the vif line in the config file + PARTITION=`grep "bootentry = " $DESTCONFIG` + # using the single quotes as delimiters, extract the data + PARTITION=`echo "$PARTITION" | cut -f2 -d\'` + # using the comma as delimiter, extra the boot partition information + PARTITION=`echo "$PARTITION" | cut -f1 -d\,` + PARTITION=${PARTITION%:*} + PARTITION=${PARTITION#$DISKIMAGE*} + + if ! lomount -diskimage "$DESTXEN$DISKIMAGE" -partition $PARTITION "$tmpdir" + then + echo -e "Unable to mount newly copied image $DESTXEN$DISKIMAGE at $tmpdir" + exit 1 + fi + ############################################################################ + + + ############################################################################ + # Change the Network Configuration in the mounted image file # + # # + sleep 1 + pushd "$tmpdir" + if [ "$MAC" != "" ]; then + echo -e "Changing the Network configuration in the newly copied image." + cd "$tmpdir/etc/sysconfig/network/" + sleep 1 + # Make a backup of the old eth config files in ./othether directory + if mkdir -pv ./oldether/ + then + cp -fv ifcfg-eth* ./oldether/ + fi + + # Find the ifcfg-ethMACADDRESS file in the newly copied image + ETH0=`ls | grep ifcfg-eth | cut -f1` + if [ "$ETH0" = "" ]; then + echo -e "Unable to find ethernet file in image file" + exit 1 + fi + # Rename the file to ifcfg-eth0 (if it has not already been done. + # Then delete all the other config files + if [ "$ETH0" != "ifcfg-eth0" ]; then + if mv -f "$ETH0" ifcfg-eth0 + then + rm -fv ifcfg-eth-id* + fi + fi + + # Make sure that the ifcfg-eth0 file exists, since everything depends on it! + if [ ! -f "ifcfg-eth0" ]; then + echo -e "Unable to create /etc/sysconfig/network/ifcfg-eth0 file!" + exit 1 + fi + + # The 30-net_persistent_names.rules file controls which interface to use. + # Be removing the SUBSYSTEM line, we force the system to recreate it. + cd "$tmpdir/etc/udev/rules.d/" + cp -fv 30-net_persistent_names.rules 30-net_persistent_names.rules.old + grep -v SUBSYSTEM 30-net_persistent_names.rules > 30-net_persistent_names.rules.tmp + if ! mv -f 30-net_persistent_names.rules.tmp 30-net_persistent_names.rules + then + echo -e "Unable to modify the /etc/udev/rules.d/30-net_persistent_names.rules file." + exit 1 + fi + fi + ############################################################################ + + + ############################################################################ + # Change the IP Address in the mounted image file # + # # + if [ "$IP" != "" ]; then + + echo -e "Modify the IP Address of the new domU." + cd "$tmpdir/etc/sysconfig/network/" + sleep 1 + + # Make sure that the ifcfg-eth0 file exists, since everything depends on it! + if [ ! -f "ifcfg-eth0" ]; then + echo -e "Unable to find /etc/sysconfig/network/ifcfg-eth0 file!" + exit 1 + fi + + # Make a copy every line of the ifcfg-eth0 file except the IPADDR line. + grep -v IPADDR ifcfg-eth0 > ifcfg-eth0.xentmp + sleep 1 + + # Then add a new IPADDR line with the new IP address + echo 'IPADDR="'$IP'"' >> ifcfg-eth0.xentmp + sleep 1 + + if ! mv ifcfg-eth0.xentmp ifcfg-eth0 + then + echo -e "unable to modify the IP address in /etc/sysconfig/network/ifcfg-eth0" + exit 1 + fi + + fi + ############################################################################ + + + ############################################################################ + # Change the HOSTNAME and hosts files in the mounted image file # + # # + if [ "$HOSTNAME" != "" ]; then + echo -e "Changing HOSTNAME file to $HOSTNAME." + cd "$tmpdir/etc" + # using the period as a delimter, select the first column for the hostname + oldHOSTNAME=`cat "$tmpdir/etc/HOSTNAME" | cut -f1 -d\.` + sleep 1 + + if ! replace $oldHOSTNAME $HOSTNAME HOSTNAME + then + echo -e "Unable to change the HOSTNAME from $oldHOSTNAME to $HOSTNAME" + exit 1 + fi + FQDN=`cat HOSTNAME` + + echo -e "Changing hosts file." + + cp -fv hosts hosts.old + if grep -v $oldHOSTNAME hosts > hosts.xentmp + then + echo "$IP\t$FQDN\t$HOSTNAME" >> hosts.xentmp + fi + + if [ ! -f hosts.xentmp ]; then + echo -e "Unable to change the hosts file" + exit 1 + fi + if ! mv -f hosts.xentmp hosts + then + echo -e "Unable to change the hosts file" + exit 1 + fi + fi + ############################################################################ + + + ############################################################################ + # Umount image file and remove temporary directory # + # # + popd > /dev/null + sleep 1 + umount "$tmpdir" + sleep 1 + rm -r "$tmpdir" + ############################################################################ +fi + +echo -e "Clone is complete. domU $DESTCONFIG is ready to start!" +exit 0 diff --git a/xmexample.rescue b/xmexample.rescue deleted file mode 100644 index 1fd54f9..0000000 --- a/xmexample.rescue +++ /dev/null @@ -1,85 +0,0 @@ -# -*- mode: python; -*- -#============================================================================ -# Python configuration setup for 'xm create'. -# This script sets the parameters used when a domain is created using 'xm create'. -# You use a separate script for each domain you want to create, or -# you can set the parameters for the domain on the xm command line. -#============================================================================ - -#---------------------------------------------------------------------------- -# Kernel image file and (optional) ramdisk (initrd). -kernel = "/boot/vmlinuz-xen" -ramdisk = "/boot/initrd-xen" - -# Or use domUloader instead of kernel/ramdisk to get kernel from domU FS -#bootloader = "/usr/lib/xen/boot/domUloader.py" -#bootentry = "hda2:/vmlinuz-xen,/initrd-xen" -#bootentry = "/boot/vmlinuz-xen,/boot/initrd-xen" - -# The domain build function. Default is 'linux'. -#builder='linux' - -# Initial memory allocation (in megabytes) for the new domain. -memory = 64 - -# A name for your domain. All domains must have different names. -name = "Rescue" - -# Which CPU to start domain on? -#cpu = -1 # leave to Xen to pick - -#---------------------------------------------------------------------------- -# Define network interfaces. - -# Optionally define mac and/or bridge for the network interfaces. -# Random MACs are assigned if not given. -vif = [ '' ] - -#---------------------------------------------------------------------------- -# Define the disk devices you want the domain to have access to, and -# what you want them accessible as. -# Each disk entry is of the form phy:UNAME,DEV,MODE -# where UNAME is the device, DEV is the device name the domain will see, -# and MODE is r for read-only, w for read-write. -disk = [ 'file:/var/lib/xen/images/rescue,hda1,w' ] - -#---------------------------------------------------------------------------- -# Set the kernel command line for the new domain. -# You only need to define the IP parameters and hostname if the domain's -# IP config doesn't, e.g. in ifcfg-eth0 or via DHCP. -# You can use 'extra' to set the runlevel and custom environment -# variables used by custom rc scripts (e.g. VMID=, usr= ). - -# Set if you want dhcp to allocate the IP address. -#dhcp = "dhcp" -# Set ip -#ip = "192.168.222.9/27" -# Set netmask. -#netmask = "255.255.255.192" -# Set default gateway. -#gateway = "192.168.222.1" -# Set the hostname. -#hostname= "rescue" - -# Set root device, see disk def above. -root = "/dev/hda1 rw" - -# Root device for nfs. -#root = "/dev/nfs" -# The nfs server. -#nfs_server = '169.254.1.0' -# Root directory on the nfs server. -#nfs_root = '/full/path/to/root/directory' - -# Sets runlevel 3. -extra = "1" - -#---------------------------------------------------------------------------- -# Set according to whether you want the domain restarted when it exits. -# The default is 'onreboot', which restarts the domain when it shuts down -# with exit code reboot. -# Other values are 'always', and 'never'. - -#restart = 'onreboot' - -#============================================================================ diff --git a/xu-11841-svm-interrupt-delivery.diff b/xu-11841-svm-interrupt-delivery.diff deleted file mode 100644 index 27a5850..0000000 --- a/xu-11841-svm-interrupt-delivery.diff +++ /dev/null @@ -1,75 +0,0 @@ -# HG changeset patch -# User kfraser@localhost.localdomain -# Date Fri Oct 20 10:09:55 2006 +0100 -# Node ID 2fbf11ad58f37313350e71f98f2eadb8ac37a8e4 -# parent: 02506a7443155611d6bbf03e49fbf193e96d24db -[HVM][SVM] Fix 1/2 to interrupt delivery logic. - -This patch uses the VINTR intercept to signal the hypervisor when a -guest can take an interrupt. When guest's interrupts are masked by -EFLAGS.IF or the guests are in an interrupt shadow, we create a 'fake' -virtual interrupt to inject while also enabling the VINTR intercept. -When the guest _can_ take interrupts, the hypervisor will #VMEXIT -on VINTR. The VINTR exit handler then clears the VINTR intercept bit -and clears the V_IRQ bit so that svm_intr_assist() can inject a -legitimate interrupt. - -Signed-off-by: Travis Betak -Signed-off-by: Wei Huang -Signed-off-by: Tom Woller - -Index: xen-3.0.3-testing/xen/arch/x86/hvm/svm/intr.c -=================================================================== ---- xen-3.0.3-testing.orig/xen/arch/x86/hvm/svm/intr.c -+++ xen-3.0.3-testing/xen/arch/x86/hvm/svm/intr.c -@@ -43,7 +43,7 @@ - * to be suitable for SVM. - */ - --static inline int svm_inject_extint(struct vcpu *v, int trap, int error_code) -+static inline int svm_inject_extint(struct vcpu *v, int trap) - { - struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; - vintr_t intr; -@@ -87,6 +87,16 @@ asmlinkage void svm_intr_assist(void) - re_injecting = 1; - } - -+ /* -+ * create a 'fake' virtual interrupt on to intercept as soon -+ * as the guest _can_ take interrupts -+ */ -+ if (irq_masked(vmcb->rflags) || vmcb->interrupt_shadow) { -+ vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR; -+ svm_inject_extint(v, 0x0); /* actual vector doesn't really matter */ -+ return; -+ } -+ - /* Guest's interrputs masked? */ - rflags = vmcb->rflags; - if (irq_masked(rflags)) { -@@ -146,7 +156,7 @@ asmlinkage void svm_intr_assist(void) - } - /* let's inject this interrupt */ - TRACE_3D(TRC_VMX_INT, v->domain->domain_id, intr_vector, 0); -- svm_inject_extint(v, intr_vector, VMX_DELIVER_NO_ERROR_CODE); -+ svm_inject_extint(v, intr_vector); - hvm_interrupt_post(v, intr_vector, intr_type); - break; - case APIC_DM_SMI: -Index: xen-3.0.3-testing/xen/arch/x86/hvm/svm/svm.c -=================================================================== ---- xen-3.0.3-testing.orig/xen/arch/x86/hvm/svm/svm.c -+++ xen-3.0.3-testing/xen/arch/x86/hvm/svm/svm.c -@@ -2802,6 +2802,11 @@ asmlinkage void svm_vmexit_handler(struc - svm_inject_exception(v, TRAP_double_fault, 1, 0); - break; - -+ case VMEXIT_VINTR: -+ vmcb->vintr.fields.irq = 0; -+ vmcb->general1_intercepts &= ~GENERAL1_INTERCEPT_VINTR; -+ break; -+ - case VMEXIT_INTR: - break; - diff --git a/xu-11842-svm-interrupt-delivery.diff b/xu-11842-svm-interrupt-delivery.diff deleted file mode 100644 index 44c0aa5..0000000 --- a/xu-11842-svm-interrupt-delivery.diff +++ /dev/null @@ -1,121 +0,0 @@ -# HG changeset patch -# User kfraser@localhost.localdomain -# Date Fri Oct 20 10:10:36 2006 +0100 -# Node ID c436ab500c9988f3a295f66b690ad7a98c16b54f -# parent: 2fbf11ad58f37313350e71f98f2eadb8ac37a8e4 -[HVM][SVM] Fix 2/2 to nterrupt delivery logic. - -Add flag to indicate that an exception event needs injecting, and to -delay the ext interrupt injection. -Remove unnecessary check of RFLAGS.IF for ExtInt injection. - -Signed-off-by: Travis Betak -Signed-off-by: Wei Huang -Signed-off-by: Tom Woller - -Index: xen-3.0.3-testing/xen/arch/x86/hvm/svm/intr.c -=================================================================== ---- xen-3.0.3-testing.orig/xen/arch/x86/hvm/svm/intr.c -+++ xen-3.0.3-testing/xen/arch/x86/hvm/svm/intr.c -@@ -62,7 +62,7 @@ static inline int svm_inject_extint(stru - // printf( "IRQ = %d\n", trap ); - return 0; - } -- -+ - asmlinkage void svm_intr_assist(void) - { - struct vcpu *v = current; -@@ -74,7 +74,6 @@ asmlinkage void svm_intr_assist(void) - int intr_type = APIC_DM_EXTINT; - int intr_vector = -1; - int re_injecting = 0; -- unsigned long rflags; - - ASSERT(vmcb); - -@@ -82,12 +81,19 @@ asmlinkage void svm_intr_assist(void) - /* Previous Interrupt delivery caused this Intercept? */ - if (vmcb->exitintinfo.fields.v && (vmcb->exitintinfo.fields.type == 0)) { - v->arch.hvm_svm.saved_irq_vector = vmcb->exitintinfo.fields.vector; --// printk("Injecting PF#: saving IRQ from ExitInfo\n"); - vmcb->exitintinfo.bytes = 0; - re_injecting = 1; - } - - /* -+ * If event requires injecting then do not inject int. -+ */ -+ if (unlikely(v->arch.hvm_svm.inject_event)) { -+ v->arch.hvm_svm.inject_event = 0; -+ return; -+ } -+ -+ /* - * create a 'fake' virtual interrupt on to intercept as soon - * as the guest _can_ take interrupts - */ -@@ -97,14 +103,6 @@ asmlinkage void svm_intr_assist(void) - return; - } - -- /* Guest's interrputs masked? */ -- rflags = vmcb->rflags; -- if (irq_masked(rflags)) { -- HVM_DBG_LOG(DBG_LEVEL_1, "Guest IRQs masked: rflags: %lx", rflags); -- /* bail out, we won't be injecting an interrupt this time */ -- return; -- } -- - /* Previous interrupt still pending? */ - if (vmcb->vintr.fields.irq) { - // printk("Re-injecting IRQ from Vintr\n"); -@@ -157,7 +155,6 @@ asmlinkage void svm_intr_assist(void) - /* let's inject this interrupt */ - TRACE_3D(TRC_VMX_INT, v->domain->domain_id, intr_vector, 0); - svm_inject_extint(v, intr_vector); -- hvm_interrupt_post(v, intr_vector, intr_type); - break; - case APIC_DM_SMI: - case APIC_DM_NMI: -@@ -168,6 +165,7 @@ asmlinkage void svm_intr_assist(void) - BUG(); - break; - } -+ hvm_interrupt_post(v, intr_vector, intr_type); - } - } - -Index: xen-3.0.3-testing/xen/arch/x86/hvm/svm/svm.c -=================================================================== ---- xen-3.0.3-testing.orig/xen/arch/x86/hvm/svm/svm.c -+++ xen-3.0.3-testing/xen/arch/x86/hvm/svm/svm.c -@@ -196,6 +196,7 @@ static inline void svm_inject_exception( - ASSERT(vmcb->eventinj.fields.v == 0); - - vmcb->eventinj = event; -+ v->arch.hvm_svm.inject_event=1; - } - - static void stop_svm(void) -@@ -2589,7 +2590,7 @@ asmlinkage void svm_vmexit_handler(struc - save_svm_cpu_user_regs(v, regs); - - vmcb->tlb_control = 1; -- -+ v->arch.hvm_svm.inject_event = 0; - - if (exit_reason == VMEXIT_INVALID) - { -Index: xen-3.0.3-testing/xen/include/asm-x86/hvm/svm/vmcb.h -=================================================================== ---- xen-3.0.3-testing.orig/xen/include/asm-x86/hvm/svm/vmcb.h -+++ xen-3.0.3-testing/xen/include/asm-x86/hvm/svm/vmcb.h -@@ -484,6 +484,7 @@ struct arch_svm_struct { - u32 *msrpm; - u64 vmexit_tsc; /* tsc read at #VMEXIT. for TSC_OFFSET */ - int saved_irq_vector; -+ u32 inject_event; - u32 launch_core; - u32 asid_core; - diff --git a/xu-11843-svm-no-double-nmi.diff b/xu-11843-svm-no-double-nmi.diff deleted file mode 100644 index 6da9ae1..0000000 --- a/xu-11843-svm-no-double-nmi.diff +++ /dev/null @@ -1,33 +0,0 @@ -# HG changeset patch -# User kfraser@localhost.localdomain -# Date Fri Oct 20 10:11:45 2006 +0100 -# Node ID 899836e04387bec0fc9f7c080e03ca9c4b9b11fd -# parent: c436ab500c9988f3a295f66b690ad7a98c16b54f -[HVM][SVM] Avoid double-execution of NMI handler. - -Remove the do_nmi() call from the vmexit logic, as the NMI is held -pending and will be handled in the context of the host when the STGI -instruction is executed. - -Signed-off-by: Tom Woller - -Index: xen-3.0.3-testing/xen/arch/x86/hvm/svm/svm.c -=================================================================== ---- xen-3.0.3-testing.orig/xen/arch/x86/hvm/svm/svm.c -+++ xen-3.0.3-testing/xen/arch/x86/hvm/svm/svm.c -@@ -54,7 +54,6 @@ - - /* External functions. We should move these to some suitable header file(s) */ - --extern void do_nmi(struct cpu_user_regs *, unsigned long); - extern int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip, - int inst_len); - extern uint32_t vlapic_update_ppr(struct vlapic *vlapic); -@@ -2730,7 +2729,6 @@ asmlinkage void svm_vmexit_handler(struc - break; - - case VMEXIT_NMI: -- do_nmi(regs, 0); - break; - - case VMEXIT_SMI: diff --git a/xu-11847-pv-hvm.diff b/xu-11847-pv-hvm.diff deleted file mode 100644 index 61426cc..0000000 --- a/xu-11847-pv-hvm.diff +++ /dev/null @@ -1,74 +0,0 @@ -# HG changeset patch -# User kfraser@localhost.localdomain -# Date Fri Oct 20 10:58:15 2006 +0100 -# Node ID dde8c8038e174ecd8a3ee2f289008465b036d5f8 -# parent: 16f1f8ac89024de4a2d5399411d703e281f40c49 -Allow default target architecture of PV-on-HVM drivers to be overridden. -Signed-off-by: Travis Betak - ---- a/unmodified_drivers/linux-2.6/mkbuildtree Fri Oct 20 10:48:34 2006 +0100 -+++ b/unmodified_drivers/linux-2.6/mkbuildtree Fri Oct 20 10:58:15 2006 +0100 -@@ -1,4 +1,12 @@ - #! /bin/sh -+ -+if [ $1 ]; then -+ uname="$1" -+else -+ uname=`uname -m` -+ echo "Defaulting to this machine's architecture, $uname, for linking." -+ echo "This may be overridden on the command line (i386,x86_64,ia64)." -+fi - - C=$PWD - -@@ -26,30 +34,29 @@ ln -sf ${XEN}/include/public include/xen - # Need to be quite careful here: we don't want the files we link in to - # risk overriding the native Linux ones (in particular, system.h must - # be native and not xenolinux). --uname=`uname -m` - case "$uname" - in - "x86_64") -- ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/hypervisor.h include/asm -- ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/hypercall.h include/asm -- ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/synch_bitops.h include/asm -- ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/maddr.h include/asm -- ln -sf ${XL}/include/asm-i386 include/asm-i386 -- ;; -+ ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/hypervisor.h include/asm -+ ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/hypercall.h include/asm -+ ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/synch_bitops.h include/asm -+ ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/maddr.h include/asm -+ ln -sf ${XL}/include/asm-i386 include/asm-i386 -+ ;; - i[34567]86) -- ln -sf ${XL}/include/asm-i386/mach-xen/asm/hypervisor.h include/asm -- ln -sf ${XL}/include/asm-i386/mach-xen/asm/hypercall.h include/asm -- ln -sf ${XL}/include/asm-i386/mach-xen/asm/synch_bitops.h include/asm -- ln -sf ${XL}/include/asm-i386/mach-xen/asm/maddr.h include/asm -- ;; -+ ln -sf ${XL}/include/asm-i386/mach-xen/asm/hypervisor.h include/asm -+ ln -sf ${XL}/include/asm-i386/mach-xen/asm/hypercall.h include/asm -+ ln -sf ${XL}/include/asm-i386/mach-xen/asm/synch_bitops.h include/asm -+ ln -sf ${XL}/include/asm-i386/mach-xen/asm/maddr.h include/asm -+ ;; - "ia64") -- ln -sf ${XL}/include/asm-ia64/hypervisor.h include/asm -- ln -sf ${XL}/include/asm-ia64/hypercall.h include/asm -- ln -sf ${XL}/include/asm-ia64/synch_bitops.h include/asm -- ln -sf ${XL}/include/asm-ia64/maddr.h include/asm -- ;; -+ ln -sf ${XL}/include/asm-ia64/hypervisor.h include/asm -+ ln -sf ${XL}/include/asm-ia64/hypercall.h include/asm -+ ln -sf ${XL}/include/asm-ia64/synch_bitops.h include/asm -+ ln -sf ${XL}/include/asm-ia64/maddr.h include/asm -+ ;; - *) -- echo unknown architecture $uname -- exit 1 -- ;; -+ echo unknown architecture $uname -+ exit 1 -+ ;; - esac - diff --git a/xu-11888-pv-hvm.diff b/xu-11888-pv-hvm.diff deleted file mode 100644 index 29fa92b..0000000 --- a/xu-11888-pv-hvm.diff +++ /dev/null @@ -1,45 +0,0 @@ -# HG changeset patch -# User kfraser@localhost.localdomain -# Date Wed Oct 25 10:59:00 2006 +0100 -# Node ID ffbd9e4668a6cfd3c936c7344c194afe368f2642 -# parent: 4be49a3be040f0951a9be971e9b4cf0a399589ec -[BLOCK] blkback: Fix potential grant entry leaks on error - -As it stands grant entries for the actual data are mapped in bulk. -If one of the earlier entries fail to be mapped, it can cause all -subsequent entries to be leaked if they were successfully mapped. - -This patch changes it so that we will continue to reap grant entries -even when an error is detected. - -Signed-off-by: Herbert Xu - ---- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Wed Oct 25 10:56:50 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Wed Oct 25 10:59:00 2006 +0100 -@@ -392,16 +392,24 @@ static void dispatch_rw_block_io(blkif_t - for (i = 0; i < nseg; i++) { - if (unlikely(map[i].status != 0)) { - DPRINTK("invalid buffer -- could not remap it\n"); -- goto fail_flush; -+ map[i].handle = BLKBACK_INVALID_HANDLE; -+ ret |= 1; - } - - pending_handle(pending_req, i) = map[i].handle; -+ -+ if (ret) -+ continue; -+ - set_phys_to_machine(__pa(vaddr( - pending_req, i)) >> PAGE_SHIFT, - FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT)); - seg[i].buf = map[i].dev_bus_addr | - (req->seg[i].first_sect << 9); - } -+ -+ if (ret) -+ goto fail_flush; - - if (vbd_translate(&preq, blkif, operation) != 0) { - DPRINTK("access denied: %s of [%llu,%llu] on dev=%04x\n", - diff --git a/xu-11896-pv-hvm.diff b/xu-11896-pv-hvm.diff deleted file mode 100644 index a205daf..0000000 --- a/xu-11896-pv-hvm.diff +++ /dev/null @@ -1,65 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID e715360e82f8d8aa72356fc77df7f4e564a97062 -# parent: 041507e2754cda7a21bb878f703daee47cbe843e -[LINUX] PV-on-HVM: Directly include headers which are used in various -files rather than relying on them being included indirectly. - -This is required because these headers are not pulled in indirectly on -older kernels. - -Signed-off-by: Ian Campbell - ---- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Wed Oct 25 12:30:08 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Wed Oct 25 13:58:30 2006 +0100 -@@ -40,6 +40,7 @@ - #include - #include - #include -+#include - - #include "xenbus_comms.h" - ---- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Wed Oct 25 12:30:08 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Wed Oct 25 13:58:30 2006 +0100 -@@ -42,6 +42,7 @@ - #include - #include - #include -+#include - - #include - #include ---- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Wed Oct 25 12:30:08 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Wed Oct 25 13:58:30 2006 +0100 -@@ -42,6 +42,8 @@ - #include - #include - #include -+#include -+#include - #include - #include "xenbus_comms.h" - ---- a/linux-2.6-xen-sparse/include/xen/xenbus.h Wed Oct 25 12:30:08 2006 +0100 -+++ b/linux-2.6-xen-sparse/include/xen/xenbus.h Wed Oct 25 13:58:30 2006 +0100 -@@ -38,6 +38,7 @@ - #include - #include - #include -+#include - #include - #include - #include ---- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c Wed Oct 25 12:30:08 2006 +0100 -+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c Wed Oct 25 13:58:30 2006 +0100 -@@ -33,6 +33,7 @@ - #include - #include - #include -+#include - #include - #include - - diff --git a/xu-11897-pv-hvm.diff b/xu-11897-pv-hvm.diff deleted file mode 100644 index b6344f6..0000000 --- a/xu-11897-pv-hvm.diff +++ /dev/null @@ -1,40 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID 266aef9b0386b0742e05893e24e09375b31bf835 -# parent: e715360e82f8d8aa72356fc77df7f4e564a97062 -PV-on-HVM: Include a Makefile in each subdirectory to maintain -compatability with kernels from before Kbuild files were introduced. - -This follows best practice as described in -Documentation/kbuild/modules.txt - -Signed-off-by: Ian Campbell -Signed-off-by: K. Y. Srinivasan -Signed-off-by: Tsunehisa Doi - ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/unmodified_drivers/linux-2.6/blkfront/Makefile Wed Oct 25 13:58:30 2006 +0100 -@@ -0,0 +1,3 @@ -+ifneq ($(KERNELRELEASE),) -+include $(src)/Kbuild -+endif ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/unmodified_drivers/linux-2.6/netfront/Makefile Wed Oct 25 13:58:30 2006 +0100 -@@ -0,0 +1,3 @@ -+ifneq ($(KERNELRELEASE),) -+include $(src)/Kbuild -+endif ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/unmodified_drivers/linux-2.6/platform-pci/Makefile Wed Oct 25 13:58:30 2006 +0100 -@@ -0,0 +1,3 @@ -+ifneq ($(KERNELRELEASE),) -+include $(src)/Kbuild -+endif ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/unmodified_drivers/linux-2.6/xenbus/Makefile Wed Oct 25 13:58:30 2006 +0100 -@@ -0,0 +1,3 @@ -+ifneq ($(KERNELRELEASE),) -+include $(src)/Kbuild -+endif - diff --git a/xu-11898-pv-hvm.diff b/xu-11898-pv-hvm.diff deleted file mode 100644 index 15298fa..0000000 --- a/xu-11898-pv-hvm.diff +++ /dev/null @@ -1,764 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID 47cc7392741ad120a0c5745f7aeaf00a1aefd538 -# parent: 266aef9b0386b0742e05893e24e09375b31bf835 -[LINUX] Move xenbus backend probing into a separate source file and -only build it when CONFIG_XEN_BACKEND is set. - -This removes unused code from frontend only configurations and also -makes PV-on-HVM drivers on older kernels simpler by removing code -which would otherwise require extra code in the compatability shim. - -Signed-off-by: Ian Campbell - ---- a/linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile Wed Oct 25 13:58:30 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/Makefile Wed Oct 25 13:58:30 2006 +0100 -@@ -9,4 +9,5 @@ xenbus-objs += xenbus_comms.o - xenbus-objs += xenbus_comms.o - xenbus-objs += xenbus_xs.o - xenbus-objs += xenbus_probe.o -+obj-$(CONFIG_XEN_BACKEND) += xenbus_probe_backend.o - obj-$(CONFIG_XEN_XENBUS_DEV) += xenbus_dev.o ---- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Wed Oct 25 13:58:30 2006 +0100 -@@ -56,6 +56,7 @@ - #include - - #include "xenbus_comms.h" -+#include "xenbus_probe.h" - - int xen_store_evtchn; - struct xenstore_domain_interface *xen_store_interface; -@@ -68,12 +69,7 @@ static void wait_for_devices(struct xenb - static void wait_for_devices(struct xenbus_driver *xendrv); - - static int xenbus_probe_frontend(const char *type, const char *name); --static int xenbus_uevent_backend(struct device *dev, char **envp, -- int num_envp, char *buffer, int buffer_size); --static int xenbus_probe_backend(const char *type, const char *domid); -- --static int xenbus_dev_probe(struct device *_dev); --static int xenbus_dev_remove(struct device *_dev); -+ - static void xenbus_dev_shutdown(struct device *_dev); - - /* If something in array of ids matches this device, return it. */ -@@ -87,7 +83,7 @@ match_device(const struct xenbus_device_ - return NULL; - } - --static int xenbus_match(struct device *_dev, struct device_driver *_drv) -+int xenbus_match(struct device *_dev, struct device_driver *_drv) - { - struct xenbus_driver *drv = to_xenbus_driver(_drv); - -@@ -96,17 +92,6 @@ static int xenbus_match(struct device *_ - - return match_device(drv->ids, to_xenbus_device(_dev)) != NULL; - } -- --struct xen_bus_type --{ -- char *root; -- unsigned int levels; -- int (*get_bus_id)(char bus_id[BUS_ID_SIZE], const char *nodename); -- int (*probe)(const char *type, const char *dir); -- struct bus_type bus; -- struct device dev; --}; -- - - /* device// => - */ - static int frontend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename) -@@ -144,7 +129,7 @@ static void free_otherend_watch(struct x - } - - --static int read_otherend_details(struct xenbus_device *xendev, -+int read_otherend_details(struct xenbus_device *xendev, - char *id_node, char *path_node) - { - int err = xenbus_gather(XBT_NIL, xendev->nodename, -@@ -174,12 +159,6 @@ static int read_backend_details(struct x - static int read_backend_details(struct xenbus_device *xendev) - { - return read_otherend_details(xendev, "backend-id", "backend"); --} -- -- --static int read_frontend_details(struct xenbus_device *xendev) --{ -- return read_otherend_details(xendev, "frontend-id", "frontend"); - } - - -@@ -201,106 +180,6 @@ static struct xen_bus_type xenbus_fronte - }, - }; - --/* backend/// => -- */ --static int backend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename) --{ -- int domid, err; -- const char *devid, *type, *frontend; -- unsigned int typelen; -- -- type = strchr(nodename, '/'); -- if (!type) -- return -EINVAL; -- type++; -- typelen = strcspn(type, "/"); -- if (!typelen || type[typelen] != '/') -- return -EINVAL; -- -- devid = strrchr(nodename, '/') + 1; -- -- 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_NIL, frontend, "")) -- err = -ENOENT; -- -- kfree(frontend); -- -- if (err) -- return err; -- -- if (snprintf(bus_id, BUS_ID_SIZE, -- "%.*s-%i-%s", typelen, type, domid, devid) >= BUS_ID_SIZE) -- return -ENOSPC; -- return 0; --} -- --static struct xen_bus_type xenbus_backend = { -- .root = "backend", -- .levels = 3, /* backend/type// */ -- .get_bus_id = backend_bus_id, -- .probe = xenbus_probe_backend, -- .bus = { -- .name = "xen-backend", -- .match = xenbus_match, -- .probe = xenbus_dev_probe, -- .remove = xenbus_dev_remove, --// .shutdown = xenbus_dev_shutdown, -- .uevent = xenbus_uevent_backend, -- }, -- .dev = { -- .bus_id = "xen-backend", -- }, --}; -- --static int xenbus_uevent_backend(struct device *dev, char **envp, -- int num_envp, char *buffer, int buffer_size) --{ -- struct xenbus_device *xdev; -- struct xenbus_driver *drv; -- int i = 0; -- int length = 0; -- -- DPRINTK(""); -- -- if (dev == NULL) -- return -ENODEV; -- -- xdev = to_xenbus_device(dev); -- if (xdev == NULL) -- return -ENODEV; -- -- /* stuff we want to pass to /sbin/hotplug */ -- add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, -- "XENBUS_TYPE=%s", xdev->devicetype); -- -- add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, -- "XENBUS_PATH=%s", xdev->nodename); -- -- add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, -- "XENBUS_BASE_PATH=%s", xenbus_backend.root); -- -- /* terminate, set to next free slot, shrink available space */ -- envp[i] = NULL; -- envp = &envp[i]; -- num_envp -= i; -- buffer = &buffer[length]; -- buffer_size -= length; -- -- if (dev->driver) { -- drv = to_xenbus_driver(dev->driver); -- if (drv && drv->uevent) -- return drv->uevent(xdev, envp, num_envp, buffer, -- buffer_size); -- } -- -- return 0; --} -- - static void otherend_changed(struct xenbus_watch *watch, - const char **vec, unsigned int len) - { -@@ -360,7 +239,7 @@ static int watch_otherend(struct xenbus_ - } - - --static int xenbus_dev_probe(struct device *_dev) -+int xenbus_dev_probe(struct device *_dev) - { - struct xenbus_device *dev = to_xenbus_device(_dev); - struct xenbus_driver *drv = to_xenbus_driver(_dev->driver); -@@ -407,7 +286,7 @@ fail: - return -ENODEV; - } - --static int xenbus_dev_remove(struct device *_dev) -+int xenbus_dev_remove(struct device *_dev) - { - struct xenbus_device *dev = to_xenbus_device(_dev); - struct xenbus_driver *drv = to_xenbus_driver(_dev->driver); -@@ -445,8 +324,8 @@ static void xenbus_dev_shutdown(struct d - put_device(&dev->dev); - } - --static int xenbus_register_driver_common(struct xenbus_driver *drv, -- struct xen_bus_type *bus) -+int xenbus_register_driver_common(struct xenbus_driver *drv, -+ struct xen_bus_type *bus) - { - int ret; - -@@ -476,14 +355,6 @@ int xenbus_register_frontend(struct xenb - return 0; - } - EXPORT_SYMBOL_GPL(xenbus_register_frontend); -- --int xenbus_register_backend(struct xenbus_driver *drv) --{ -- drv->read_otherend_details = read_frontend_details; -- -- return xenbus_register_driver_common(drv, &xenbus_backend); --} --EXPORT_SYMBOL_GPL(xenbus_register_backend); - - void xenbus_unregister_driver(struct xenbus_driver *drv) - { -@@ -596,9 +467,9 @@ DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | - DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL); - - --static int xenbus_probe_node(struct xen_bus_type *bus, -- const char *type, -- const char *nodename) -+int xenbus_probe_node(struct xen_bus_type *bus, -+ const char *type, -+ const char *nodename) - { - int err; - struct xenbus_device *xendev; -@@ -668,55 +539,6 @@ static int xenbus_probe_frontend(const c - return err; - } - --/* backend/// */ --static int xenbus_probe_backend_unit(const char *dir, -- const char *type, -- const char *name) --{ -- char *nodename; -- int err; -- -- nodename = kasprintf("%s/%s", dir, name); -- if (!nodename) -- return -ENOMEM; -- -- DPRINTK("%s\n", nodename); -- -- err = xenbus_probe_node(&xenbus_backend, type, nodename); -- kfree(nodename); -- return err; --} -- --/* backend// */ --static int xenbus_probe_backend(const char *type, const char *domid) --{ -- char *nodename; -- int err = 0; -- char **dir; -- unsigned int i, dir_n = 0; -- -- DPRINTK(""); -- -- nodename = kasprintf("%s/%s/%s", xenbus_backend.root, type, domid); -- if (!nodename) -- return -ENOMEM; -- -- dir = xenbus_directory(XBT_NIL, nodename, "", &dir_n); -- if (IS_ERR(dir)) { -- kfree(nodename); -- return PTR_ERR(dir); -- } -- -- for (i = 0; i < dir_n; i++) { -- err = xenbus_probe_backend_unit(nodename, type, dir[i]); -- if (err) -- break; -- } -- kfree(dir); -- kfree(nodename); -- return err; --} -- - static int xenbus_probe_device_type(struct xen_bus_type *bus, const char *type) - { - int err = 0; -@@ -737,7 +559,7 @@ static int xenbus_probe_device_type(stru - return err; - } - --static int xenbus_probe_devices(struct xen_bus_type *bus) -+int xenbus_probe_devices(struct xen_bus_type *bus) - { - int err = 0; - char **dir; -@@ -779,7 +601,7 @@ static int strsep_len(const char *str, c - return (len == 0) ? i : -ERANGE; - } - --static void dev_changed(const char *node, struct xen_bus_type *bus) -+void dev_changed(const char *node, struct xen_bus_type *bus) - { - int exists, rootlen; - struct xenbus_device *dev; -@@ -824,23 +646,10 @@ static void frontend_changed(struct xenb - dev_changed(vec[XS_WATCH_PATH], &xenbus_frontend); - } - --static void backend_changed(struct xenbus_watch *watch, -- const char **vec, unsigned int len) --{ -- DPRINTK(""); -- -- dev_changed(vec[XS_WATCH_PATH], &xenbus_backend); --} -- - /* We watch for devices appearing and vanishing. */ - static struct xenbus_watch fe_watch = { - .node = "device", - .callback = frontend_changed, --}; -- --static struct xenbus_watch be_watch = { -- .node = "backend", -- .callback = backend_changed, - }; - - static int suspend_dev(struct device *dev, void *data) -@@ -913,7 +722,7 @@ void xenbus_suspend(void) - DPRINTK(""); - - bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev); -- bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, suspend_dev); -+ xenbus_backend_suspend(suspend_dev); - xs_suspend(); - } - EXPORT_SYMBOL_GPL(xenbus_suspend); -@@ -923,7 +732,7 @@ void xenbus_resume(void) - xb_init_comms(); - xs_resume(); - bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev); -- bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, resume_dev); -+ xenbus_backend_resume(resume_dev); - } - EXPORT_SYMBOL_GPL(xenbus_resume); - -@@ -956,13 +765,10 @@ void xenbus_probe(void *unused) - { - BUG_ON((xenstored_ready <= 0)); - -- /* Enumerate devices in xenstore. */ -+ /* Enumerate devices in xenstore and watch for changes. */ - xenbus_probe_devices(&xenbus_frontend); -- xenbus_probe_devices(&xenbus_backend); -- -- /* Watch for changes. */ - register_xenbus_watch(&fe_watch); -- register_xenbus_watch(&be_watch); -+ xenbus_backend_probe_and_watch(); - - /* Notify others that xenstore is up */ - notifier_call_chain(&xenstore_chain, 0, NULL); -@@ -1021,7 +827,7 @@ static int __init xenbus_probe_init(void - - /* Register ourselves with the kernel bus subsystem */ - bus_register(&xenbus_frontend.bus); -- bus_register(&xenbus_backend.bus); -+ xenbus_backend_bus_register(); - - /* - * Domain0 doesn't have a store_evtchn or store_mfn yet. -@@ -1092,7 +898,7 @@ static int __init xenbus_probe_init(void - - /* Register ourselves with the kernel device subsystem */ - device_register(&xenbus_frontend.dev); -- device_register(&xenbus_backend.dev); -+ xenbus_backend_device_register(); - - if (!is_initial_xendomain()) - xenbus_probe(NULL); ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.h Wed Oct 25 13:58:30 2006 +0100 -@@ -0,0 +1,77 @@ -+/****************************************************************************** -+ * xenbus_probe.h -+ * -+ * Talks to Xen Store to figure out what devices we have. -+ * -+ * Copyright (C) 2005 Rusty Russell, IBM Corporation -+ * Copyright (C) 2005 XenSource Ltd. -+ * -+ * 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 -+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ */ -+ -+#ifndef _XENBUS_PROBE_H -+#define _XENBUS_PROBE_H -+ -+#ifdef CONFIG_XEN_BACKEND -+extern void xenbus_backend_suspend(int (*fn)(struct device *, void *)); -+extern void xenbus_backend_resume(int (*fn)(struct device *, void *)); -+extern void xenbus_backend_probe_and_watch(void); -+extern void xenbus_backend_bus_register(void); -+extern void xenbus_backend_device_register(void); -+#else -+static inline void xenbus_backend_suspend(int (*fn)(struct device *, void *)) {} -+static inline void xenbus_backend_resume(int (*fn)(struct device *, void *)) {} -+static inline void xenbus_backend_probe_and_watch(void) {} -+static inline void xenbus_backend_bus_register(void) {} -+static inline void xenbus_backend_device_register(void) {} -+#endif -+ -+struct xen_bus_type -+{ -+ char *root; -+ unsigned int levels; -+ int (*get_bus_id)(char bus_id[BUS_ID_SIZE], const char *nodename); -+ int (*probe)(const char *type, const char *dir); -+ struct bus_type bus; -+ struct device dev; -+}; -+ -+extern int xenbus_match(struct device *_dev, struct device_driver *_drv); -+extern int xenbus_dev_probe(struct device *_dev); -+extern int xenbus_dev_remove(struct device *_dev); -+extern int xenbus_register_driver_common(struct xenbus_driver *drv, -+ struct xen_bus_type *bus); -+extern int xenbus_probe_node(struct xen_bus_type *bus, -+ const char *type, -+ const char *nodename); -+extern int xenbus_probe_devices(struct xen_bus_type *bus); -+ -+extern void dev_changed(const char *node, struct xen_bus_type *bus); -+ -+/* Simplified asprintf. Probably belongs in lib */ -+extern char *kasprintf(const char *fmt, ...); -+ -+#endif -+ ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe_backend.c Wed Oct 25 13:58:30 2006 +0100 -@@ -0,0 +1,271 @@ -+/****************************************************************************** -+ * Talks to Xen Store to figure out what devices we have (backend half). -+ * -+ * Copyright (C) 2005 Rusty Russell, IBM Corporation -+ * Copyright (C) 2005 Mike Wray, Hewlett-Packard -+ * Copyright (C) 2005, 2006 XenSource Ltd -+ * -+ * 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 -+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ */ -+ -+#define DPRINTK(fmt, args...) \ -+ pr_debug("xenbus_probe (%s:%d) " fmt ".\n", \ -+ __FUNCTION__, __LINE__, ##args) -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "xenbus_comms.h" -+#include "xenbus_probe.h" -+ -+#ifdef HAVE_XEN_PLATFORM_COMPAT_H -+#include -+#endif -+ -+static int xenbus_uevent_backend(struct device *dev, char **envp, -+ int num_envp, char *buffer, int buffer_size); -+static int xenbus_probe_backend(const char *type, const char *domid); -+ -+extern int read_otherend_details(struct xenbus_device *xendev, -+ char *id_node, char *path_node); -+ -+static int read_frontend_details(struct xenbus_device *xendev) -+{ -+ return read_otherend_details(xendev, "frontend-id", "frontend"); -+} -+ -+/* backend/// => -- */ -+static int backend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename) -+{ -+ int domid, err; -+ const char *devid, *type, *frontend; -+ unsigned int typelen; -+ -+ type = strchr(nodename, '/'); -+ if (!type) -+ return -EINVAL; -+ type++; -+ typelen = strcspn(type, "/"); -+ if (!typelen || type[typelen] != '/') -+ return -EINVAL; -+ -+ devid = strrchr(nodename, '/') + 1; -+ -+ 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_NIL, frontend, "")) -+ err = -ENOENT; -+ kfree(frontend); -+ -+ if (err) -+ return err; -+ -+ if (snprintf(bus_id, BUS_ID_SIZE, -+ "%.*s-%i-%s", typelen, type, domid, devid) >= BUS_ID_SIZE) -+ return -ENOSPC; -+ return 0; -+} -+ -+static struct xen_bus_type xenbus_backend = { -+ .root = "backend", -+ .levels = 3, /* backend/type// */ -+ .get_bus_id = backend_bus_id, -+ .probe = xenbus_probe_backend, -+ .bus = { -+ .name = "xen-backend", -+ .match = xenbus_match, -+ .probe = xenbus_dev_probe, -+ .remove = xenbus_dev_remove, -+// .shutdown = xenbus_dev_shutdown, -+ .uevent = xenbus_uevent_backend, -+ }, -+ .dev = { -+ .bus_id = "xen-backend", -+ }, -+}; -+ -+static int xenbus_uevent_backend(struct device *dev, char **envp, -+ int num_envp, char *buffer, int buffer_size) -+{ -+ struct xenbus_device *xdev; -+ struct xenbus_driver *drv; -+ int i = 0; -+ int length = 0; -+ -+ DPRINTK(""); -+ -+ if (dev == NULL) -+ return -ENODEV; -+ -+ xdev = to_xenbus_device(dev); -+ if (xdev == NULL) -+ return -ENODEV; -+ -+ /* stuff we want to pass to /sbin/hotplug */ -+ add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, -+ "XENBUS_TYPE=%s", xdev->devicetype); -+ -+ add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, -+ "XENBUS_PATH=%s", xdev->nodename); -+ -+ add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, -+ "XENBUS_BASE_PATH=%s", xenbus_backend.root); -+ -+ /* terminate, set to next free slot, shrink available space */ -+ envp[i] = NULL; -+ envp = &envp[i]; -+ num_envp -= i; -+ buffer = &buffer[length]; -+ buffer_size -= length; -+ -+ if (dev->driver) { -+ drv = to_xenbus_driver(dev->driver); -+ if (drv && drv->uevent) -+ return drv->uevent(xdev, envp, num_envp, buffer, -+ buffer_size); -+ } -+ -+ return 0; -+} -+ -+int xenbus_register_backend(struct xenbus_driver *drv) -+{ -+ drv->read_otherend_details = read_frontend_details; -+ -+ return xenbus_register_driver_common(drv, &xenbus_backend); -+} -+EXPORT_SYMBOL_GPL(xenbus_register_backend); -+ -+/* backend/// */ -+static int xenbus_probe_backend_unit(const char *dir, -+ const char *type, -+ const char *name) -+{ -+ char *nodename; -+ int err; -+ -+ nodename = kasprintf("%s/%s", dir, name); -+ if (!nodename) -+ return -ENOMEM; -+ -+ DPRINTK("%s\n", nodename); -+ -+ err = xenbus_probe_node(&xenbus_backend, type, nodename); -+ kfree(nodename); -+ return err; -+} -+ -+/* backend// */ -+static int xenbus_probe_backend(const char *type, const char *domid) -+{ -+ char *nodename; -+ int err = 0; -+ char **dir; -+ unsigned int i, dir_n = 0; -+ -+ DPRINTK(""); -+ -+ nodename = kasprintf("%s/%s/%s", xenbus_backend.root, type, domid); -+ if (!nodename) -+ return -ENOMEM; -+ -+ dir = xenbus_directory(XBT_NIL, nodename, "", &dir_n); -+ if (IS_ERR(dir)) { -+ kfree(nodename); -+ return PTR_ERR(dir); -+ } -+ -+ for (i = 0; i < dir_n; i++) { -+ err = xenbus_probe_backend_unit(nodename, type, dir[i]); -+ if (err) -+ break; -+ } -+ kfree(dir); -+ kfree(nodename); -+ return err; -+} -+ -+static void backend_changed(struct xenbus_watch *watch, -+ const char **vec, unsigned int len) -+{ -+ DPRINTK(""); -+ -+ dev_changed(vec[XS_WATCH_PATH], &xenbus_backend); -+} -+ -+static struct xenbus_watch be_watch = { -+ .node = "backend", -+ .callback = backend_changed, -+}; -+ -+void xenbus_backend_suspend(int (*fn)(struct device *, void *)) -+{ -+ DPRINTK(""); -+ bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn); -+} -+ -+void xenbus_backend_resume(int (*fn)(struct device *, void *)) -+{ -+ DPRINTK(""); -+ bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn); -+} -+ -+void xenbus_backend_probe_and_watch(void) -+{ -+ xenbus_probe_devices(&xenbus_backend); -+ register_xenbus_watch(&be_watch); -+} -+ -+void xenbus_backend_bus_register(void) -+{ -+ bus_register(&xenbus_backend.bus); -+} -+ -+void xenbus_backend_device_register(void) -+{ -+ device_register(&xenbus_backend.dev); -+} - diff --git a/xu-11899-pv-hvm.diff b/xu-11899-pv-hvm.diff deleted file mode 100644 index caedfe6..0000000 --- a/xu-11899-pv-hvm.diff +++ /dev/null @@ -1,39 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID bd643d9db83860ca35ef53f9a3e584985c725c14 -# parent: 47cc7392741ad120a0c5745f7aeaf00a1aefd538 -[LINUX] PV-on-HVM: Remove the attr parameter from device attribute -show methods on kernels prior to 2.6.13. The parameter was not present -before that. - -Signed-off-by: Ian Campbell -Signed-off-by: K. Y. Srinivasan -Signed-off-by: Tsunehisa Doi - ---- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Wed Oct 25 13:58:30 2006 +0100 -@@ -453,14 +453,20 @@ char *kasprintf(const char *fmt, ...) - } - - static ssize_t xendev_show_nodename(struct device *dev, -- struct device_attribute *attr, char *buf) -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) -+ struct device_attribute *attr, -+#endif -+ char *buf) - { - return sprintf(buf, "%s\n", to_xenbus_device(dev)->nodename); - } - DEVICE_ATTR(nodename, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_nodename, NULL); - - static ssize_t xendev_show_devtype(struct device *dev, -- struct device_attribute *attr, char *buf) -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) -+ struct device_attribute *attr, -+#endif -+ char *buf) - { - return sprintf(buf, "%s\n", to_xenbus_device(dev)->devicetype); - } - diff --git a/xu-11900-pv-hvm.diff b/xu-11900-pv-hvm.diff deleted file mode 100644 index 9ef1c8f..0000000 --- a/xu-11900-pv-hvm.diff +++ /dev/null @@ -1,34 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID 40107f658bd984190e14746f25dac750badf4d8c -# parent: bd643d9db83860ca35ef53f9a3e584985c725c14 -[LINUX] Exclude support for /proc/xen/xsd_kva when building a -non-privileged guest. - -This is useful for PV-on-HVM because it removes code which would -otherwise require extra code in the compatability shim. - -Signed-off-by: Ian Campbell - ---- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Wed Oct 25 13:58:30 2006 +0100 -@@ -781,7 +781,7 @@ void xenbus_probe(void *unused) - } - - --#ifdef CONFIG_PROC_FS -+#if defined(CONFIG_PROC_FS) && defined(CONFIG_XEN_PRIVILEGED_GUEST) - static struct file_operations xsd_kva_fops; - static struct proc_dir_entry *xsd_kva_intf; - static struct proc_dir_entry *xsd_port_intf; -@@ -862,7 +862,7 @@ static int __init xenbus_probe_init(void - xen_store_evtchn = xen_start_info->store_evtchn = - alloc_unbound.port; - --#ifdef CONFIG_PROC_FS -+#if defined(CONFIG_PROC_FS) && defined(CONFIG_XEN_PRIVILEGED_GUEST) - /* And finally publish the above info in /proc/xen */ - xsd_kva_intf = create_xen_proc_entry("xsd_kva", 0600); - if (xsd_kva_intf) { - diff --git a/xu-11901-pv-hvm.diff b/xu-11901-pv-hvm.diff deleted file mode 100644 index d9224a5..0000000 --- a/xu-11901-pv-hvm.diff +++ /dev/null @@ -1,26 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID 8102ccad440d3218a179e45c296e328aba564983 -# parent: 40107f658bd984190e14746f25dac750badf4d8c -[LINUX] PV-on-HVM: Only initialize the owner field of struct -device_driver on kernels from 2.6.10 onward. The field was not -available until then. - -Signed-off-by: Ian Campbell -Signed-off-by: K. Y. Srinivasan -Signed-off-by: Tsunehisa Doi - ---- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Wed Oct 25 13:58:30 2006 +0100 -@@ -331,7 +331,9 @@ int xenbus_register_driver_common(struct - - drv->driver.name = drv->name; - drv->driver.bus = &bus->bus; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) - drv->driver.owner = drv->owner; -+#endif - - mutex_lock(&xenwatch_mutex); - ret = driver_register(&drv->driver); - diff --git a/xu-11902-pv-hvm.diff b/xu-11902-pv-hvm.diff deleted file mode 100644 index caa7826..0000000 --- a/xu-11902-pv-hvm.diff +++ /dev/null @@ -1,40 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID a0919d3f7d50dad3db4268611213a3923a497afd -# parent: 8102ccad440d3218a179e45c296e328aba564983 -[LINUX] PV-on-HVM: The probe, remove and shutdown methods were added -to struct bus_type in 2.6.16. For older kernels use the methods on the -struct device_driver. - -Signed-off-by: Ian Campbell -Signed-off-by: K. Y. Srinivasan -Signed-off-by: Tsunehisa Doi - ---- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Wed Oct 25 13:58:30 2006 +0100 -@@ -171,9 +171,11 @@ static struct xen_bus_type xenbus_fronte - .bus = { - .name = "xen", - .match = xenbus_match, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) - .probe = xenbus_dev_probe, - .remove = xenbus_dev_remove, - .shutdown = xenbus_dev_shutdown, -+#endif - }, - .dev = { - .bus_id = "xen", -@@ -333,6 +335,11 @@ int xenbus_register_driver_common(struct - drv->driver.bus = &bus->bus; - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) - drv->driver.owner = drv->owner; -+#endif -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) -+ drv->driver.probe = xenbus_dev_probe; -+ drv->driver.remove = xenbus_dev_remove; -+ drv->driver.shutdown = xenbus_dev_shutdown; - #endif - - mutex_lock(&xenwatch_mutex); - diff --git a/xu-11903-pv-hvm.diff b/xu-11903-pv-hvm.diff deleted file mode 100644 index 150d139..0000000 --- a/xu-11903-pv-hvm.diff +++ /dev/null @@ -1,55 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID 1c985a2e47eadc66e747443dfa65099e5f1dec86 -# parent: a0919d3f7d50dad3db4268611213a3923a497afd -[LINUX] PV-on-HVM: Implement HDIO_GETGEO ioctl on kernels before -2.6.16. - -Signed-off-by: Ian Campbell -Signed-off-by: K. Y. Srinivasan -Signed-off-by: Tsunehisa Doi - ---- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Wed Oct 25 13:58:30 2006 +0100 -@@ -468,6 +468,27 @@ int blkif_ioctl(struct inode *inode, str - command, (long)argument, inode->i_rdev); - - switch (command) { -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) -+ case HDIO_GETGEO: { -+ struct block_device *bd = inode->i_bdev; -+ struct hd_geometry geo; -+ int ret; -+ -+ if (!argument) -+ return -EINVAL; -+ -+ geo.start = get_start_sect(bd); -+ ret = blkif_getgeo(bd, &geo); -+ if (ret) -+ return ret; -+ -+ if (copy_to_user((struct hd_geometry __user *)argument, &geo, -+ sizeof(geo))) -+ return -EFAULT; -+ -+ return 0; -+ } -+#endif - case CDROMMULTISESSION: - DPRINTK("FIXME: support multisession CDs later\n"); - for (i = 0; i < sizeof(struct cdrom_multisession); i++) ---- a/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c Wed Oct 25 13:58:30 2006 +0100 -@@ -91,7 +91,9 @@ static struct block_device_operations xl - .open = blkif_open, - .release = blkif_release, - .ioctl = blkif_ioctl, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) - .getgeo = blkif_getgeo -+#endif - }; - - DEFINE_SPINLOCK(blkif_io_lock); - diff --git a/xu-11904-pv-hvm.diff b/xu-11904-pv-hvm.diff deleted file mode 100644 index df9e6d0..0000000 --- a/xu-11904-pv-hvm.diff +++ /dev/null @@ -1,26 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID db23596992f9388fb776a4518ae638b22ee7c8c2 -# parent: 1c985a2e47eadc66e747443dfa65099e5f1dec86 -[LINUX] PV-on-HVM: The elevator_init prototype changed in 2.6.10 - -Signed-off-by: Ian Campbell -Signed-off-by: K. Y. Srinivasan -Signed-off-by: Tsunehisa Doi - ---- a/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c Wed Oct 25 13:58:30 2006 +0100 -@@ -188,7 +188,11 @@ xlvbd_init_blk_queue(struct gendisk *gd, - if (rq == NULL) - return -1; - -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) - elevator_init(rq, "noop"); -+#else -+ elevator_init(rq, &elevator_noop); -+#endif - - /* Hard sector size and max sectors impersonate the equiv. hardware. */ - blk_queue_hardsect_size(rq, sector_size); - diff --git a/xu-11905-pv-hvm.diff b/xu-11905-pv-hvm.diff deleted file mode 100644 index 62cb258..0000000 --- a/xu-11905-pv-hvm.diff +++ /dev/null @@ -1,230 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID 206e20b7b54e09394ed161006439ee2b75ecee5e -# parent: db23596992f9388fb776a4518ae638b22ee7c8c2 -PV-on-HVM: Add infrastructure for a compatibility shim in order to -support PV-on-HVM drivers for older kernel releases. - -The compatability code is included in the xen-platform-pci module -since this module underpins all the others. - -Signed-off-by: Ian Campbell -Signed-off-by: K. Y. Srinivasan -Signed-off-by: Tsunehisa Doi - ---- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Wed Oct 25 13:58:30 2006 +0100 -@@ -48,6 +48,10 @@ - #include - #include - -+#ifdef HAVE_XEN_PLATFORM_COMPAT_H -+#include -+#endif -+ - #define BLKIF_STATE_DISCONNECTED 0 - #define BLKIF_STATE_CONNECTED 1 - #define BLKIF_STATE_SUSPENDED 2 ---- a/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c Wed Oct 25 13:58:30 2006 +0100 -@@ -35,6 +35,10 @@ - #include "block.h" - #include - #include -+ -+#ifdef HAVE_XEN_PLATFORM_COMPAT_H -+#include -+#endif - - #define BLKIF_MAJOR(dev) ((dev)>>8) - #define BLKIF_MINOR(dev) ((dev) & 0xff) ---- a/linux-2.6-xen-sparse/drivers/xen/core/features.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/core/features.c Wed Oct 25 13:58:30 2006 +0100 -@@ -10,6 +10,10 @@ - #include - #include - #include -+ -+#ifdef HAVE_XEN_PLATFORM_COMPAT_H -+#include -+#endif - - u8 xen_features[XENFEAT_NR_SUBMAPS * 32] __read_mostly; - /* Not a GPL symbol: used in ubiquitous macros, so too restrictive. */ ---- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c Wed Oct 25 13:58:30 2006 +0100 -@@ -44,6 +44,10 @@ - #include - #include - -+#ifdef HAVE_XEN_PLATFORM_COMPAT_H -+#include -+#endif -+ - /* External tools reserve first few grant table entries. */ - #define NR_RESERVED_ENTRIES 8 - ---- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Wed Oct 25 13:58:30 2006 +0100 -@@ -64,6 +64,10 @@ - #include - #include - -+#ifdef HAVE_XEN_PLATFORM_COMPAT_H -+#include -+#endif -+ - /* - * Mutually-exclusive module options to select receive data path: - * rx_copy : Packets are copied by network backend into local memory ---- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c Wed Oct 25 13:58:30 2006 +0100 -@@ -34,6 +34,10 @@ - #include - #include - #include -+ -+#ifdef HAVE_XEN_PLATFORM_COMPAT_H -+#include -+#endif - - /* xenbus_probe.c */ - extern char *kasprintf(const char *fmt, ...); ---- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Wed Oct 25 13:58:30 2006 +0100 -@@ -39,6 +39,10 @@ - #include - #include "xenbus_comms.h" - -+#ifdef HAVE_XEN_PLATFORM_COMPAT_H -+#include -+#endif -+ - static int xenbus_irq; - - extern void xenbus_probe(void *); ---- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Wed Oct 25 13:58:30 2006 +0100 -@@ -49,6 +49,10 @@ - #include - #include - #include -+ -+#ifdef HAVE_XEN_PLATFORM_COMPAT_H -+#include -+#endif - - struct xenbus_dev_transaction { - struct list_head list; ---- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Wed Oct 25 13:58:30 2006 +0100 -@@ -58,6 +58,10 @@ - #include "xenbus_comms.h" - #include "xenbus_probe.h" - -+#ifdef HAVE_XEN_PLATFORM_COMPAT_H -+#include -+#endif -+ - int xen_store_evtchn; - struct xenstore_domain_interface *xen_store_interface; - static unsigned long xen_store_mfn; ---- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Wed Oct 25 13:58:30 2006 +0100 -@@ -47,6 +47,10 @@ - #include - #include "xenbus_comms.h" - -+#ifdef HAVE_XEN_PLATFORM_COMPAT_H -+#include -+#endif -+ - /* xenbus_probe.c */ - extern char *kasprintf(const char *fmt, ...); - ---- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/synch_bitops.h Wed Oct 25 13:58:30 2006 +0100 -+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/synch_bitops.h Wed Oct 25 13:58:30 2006 +0100 -@@ -8,6 +8,10 @@ - */ - - #include -+ -+#ifdef HAVE_XEN_PLATFORM_COMPAT_H -+#include -+#endif - - #define ADDR (*(volatile long *) addr) - ---- a/unmodified_drivers/linux-2.6/overrides.mk Wed Oct 25 13:58:30 2006 +0100 -+++ b/unmodified_drivers/linux-2.6/overrides.mk Wed Oct 25 13:58:30 2006 +0100 -@@ -9,4 +9,4 @@ EXTRA_CFLAGS += -DCONFIG_XEN_BLKDEV_GRAN - EXTRA_CFLAGS += -DCONFIG_XEN_BLKDEV_GRANT -DXEN_EVTCHN_MASK_OPS - EXTRA_CFLAGS += -DCONFIG_XEN_NETDEV_GRANT_RX -DCONFIG_XEN_NETDEV_GRANT_TX - EXTRA_CFLAGS += -D__XEN_INTERFACE_VERSION__=0x00030202 --EXTRA_CFLAGS += -I$(M)/include -+EXTRA_CFLAGS += -I$(M)/include -I$(M)/compat-include -DHAVE_XEN_PLATFORM_COMPAT_H ---- a/unmodified_drivers/linux-2.6/platform-pci/Kbuild Wed Oct 25 13:58:30 2006 +0100 -+++ b/unmodified_drivers/linux-2.6/platform-pci/Kbuild Wed Oct 25 13:58:30 2006 +0100 -@@ -4,4 +4,4 @@ obj-m := xen-platform-pci.o - - EXTRA_CFLAGS += -I$(M)/platform-pci - --xen-platform-pci-objs := evtchn.o platform-pci.o gnttab.o xen_support.o features.o -+xen-platform-pci-objs := evtchn.o platform-pci.o gnttab.o xen_support.o features.o platform-compat.o ---- a/unmodified_drivers/linux-2.6/platform-pci/evtchn.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c Wed Oct 25 13:58:30 2006 +0100 -@@ -35,6 +35,10 @@ - #include - #include - #include "platform-pci.h" -+ -+#ifdef HAVE_XEN_PLATFORM_COMPAT_H -+#include -+#endif - - void *shared_info_area; - ---- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c Wed Oct 25 13:58:30 2006 +0100 -@@ -39,6 +39,10 @@ - - #include "platform-pci.h" - -+#ifdef HAVE_XEN_PLATFORM_COMPAT_H -+#include -+#endif -+ - #define DRV_NAME "xen-platform-pci" - #define DRV_VERSION "0.10" - #define DRV_RELDATE "03/03/2005" ---- a/unmodified_drivers/linux-2.6/platform-pci/xen_support.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/unmodified_drivers/linux-2.6/platform-pci/xen_support.c Wed Oct 25 13:58:30 2006 +0100 -@@ -26,6 +26,10 @@ - #include - #include "platform-pci.h" - -+#ifdef HAVE_XEN_PLATFORM_COMPAT_H -+#include -+#endif -+ - void xen_machphys_update(unsigned long mfn, unsigned long pfn) - { - BUG(); ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Wed Oct 25 13:58:30 2006 +0100 -@@ -0,0 +1,6 @@ -+#ifndef COMPAT_INCLUDE_XEN_PLATFORM_COMPAT_H -+#define COMPAT_INCLUDE_XEN_PLATFORM_COMPAT_H -+ -+#include -+ -+#endif ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c Wed Oct 25 13:58:30 2006 +0100 -@@ -0,0 +1,4 @@ -+#include -+#include -+ -+#include - diff --git a/xu-11906-pv-hvm.diff b/xu-11906-pv-hvm.diff deleted file mode 100644 index 301a747..0000000 --- a/xu-11906-pv-hvm.diff +++ /dev/null @@ -1,25 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID d008b6b44f3c9bd7d7f49737fdc1c93370bf783d -# parent: 206e20b7b54e09394ed161006439ee2b75ecee5e -PV-on-HVM: Add a compatibility linux/io.h for kernels before 2.6.16 - -Signed-off-by: Ian Campbell -Signed-off-by: K. Y. Srinivasan -Signed-off-by: Tsunehisa Doi - ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/unmodified_drivers/linux-2.6/compat-include/linux/io.h Wed Oct 25 13:58:30 2006 +0100 -@@ -0,0 +1,10 @@ -+#ifndef _LINUX_IO_H -+#define _LINUX_IO_H -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+#error "This version of Linux should not need compat linux/io.h" -+#endif -+ -+#include -+ -+#endif - diff --git a/xu-11907-pv-hvm.diff b/xu-11907-pv-hvm.diff deleted file mode 100644 index 41ac714..0000000 --- a/xu-11907-pv-hvm.diff +++ /dev/null @@ -1,48 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID ecc1782f69680d94b7d2fe4283616e4890b55504 -# parent: d008b6b44f3c9bd7d7f49737fdc1c93370bf783d -PV-on-HVM: Add a compatibility linux/mutex.h for kernels before -2.6.16. This implements the new mutex type in terms of the old -semaphore type. - -Signed-off-by: Ian Campbell -Signed-off-by: K. Y. Srinivasan -Signed-off-by: Tsunehisa Doi - ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/unmodified_drivers/linux-2.6/compat-include/linux/mutex.h Wed Oct 25 13:58:30 2006 +0100 -@@ -0,0 +1,31 @@ -+/* -+ * Copyright (c) 2006 Cisco Systems. All rights reserved. -+ * -+ * This file is released under the GPLv2. -+ */ -+ -+/* mutex compatibility for pre-2.6.16 kernels */ -+ -+#ifndef __LINUX_MUTEX_H -+#define __LINUX_MUTEX_H -+ -+#include -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+#error "This version of Linux should not need compat mutex.h" -+#endif -+ -+#include -+#include -+ -+#define mutex semaphore -+#define DEFINE_MUTEX(foo) DECLARE_MUTEX(foo) -+#define mutex_init(foo) init_MUTEX(foo) -+#define mutex_lock(foo) down(foo) -+#define mutex_lock_interruptible(foo) down_interruptible(foo) -+/* this function follows the spin_trylock() convention, so * -+ * it is negated to the down_trylock() return values! Be careful */ -+#define mutex_trylock(foo) !down_trylock(foo) -+#define mutex_unlock(foo) up(foo) -+ -+#endif /* __LINUX_MUTEX_H */ - diff --git a/xu-11908-pv-hvm.diff b/xu-11908-pv-hvm.diff deleted file mode 100644 index d9170ff..0000000 --- a/xu-11908-pv-hvm.diff +++ /dev/null @@ -1,47 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID e09720caf72dbdc0fe0689c8e2bf8ace97abaae4 -# parent: ecc1782f69680d94b7d2fe4283616e4890b55504 -PV-on-HVM: Include compatability headers for asm/pgtable-no{pmd,pud}.h -for kernels before 2.6.11. - -Signed-off-by: Ian Campbell -Signed-off-by: K. Y. Srinivasan -Signed-off-by: Tsunehisa Doi - ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/unmodified_drivers/linux-2.6/compat-include/asm-generic/pgtable-nopmd.h Wed Oct 25 13:58:30 2006 +0100 -@@ -0,0 +1,14 @@ -+#ifndef _PGTABLE_NOPMD_H -+#define _PGTABLE_NOPMD_H -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) -+#error "This version of Linux should not need compat pgtable-nopmd.h" -+#endif -+ -+#define pud_t pgd_t -+#define pud_offset(d, va) d -+#define pud_none(pud) 0 -+#define pud_present(pud) 1 -+#define PTRS_PER_PUD 1 -+ -+#endif /* _PGTABLE_NOPMD_H */ ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/unmodified_drivers/linux-2.6/compat-include/asm-generic/pgtable-nopud.h Wed Oct 25 13:58:30 2006 +0100 -@@ -0,0 +1,14 @@ -+#ifndef _PGTABLE_NOPUD_H -+#define _PGTABLE_NOPUD_H -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) -+#error "This version of Linux should not need compat pgtable-nopud.h" -+#endif -+ -+#define pud_t pgd_t -+#define pud_offset(d, va) d -+#define pud_none(pud) 0 -+#define pud_present(pud) 1 -+#define PTRS_PER_PUD 1 -+ -+#endif /* _PGTABLE_NOPUD_H */ - diff --git a/xu-11909-pv-hvm.diff b/xu-11909-pv-hvm.diff deleted file mode 100644 index b03520e..0000000 --- a/xu-11909-pv-hvm.diff +++ /dev/null @@ -1,42 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID ded9d1ae21f794f924bb312077bab69f782f87b8 -# parent: e09720caf72dbdc0fe0689c8e2bf8ace97abaae4 -PV-to-HVM: Add compatibility definitions of various #defines when they -are not present in the kernel we are building against. - -Signed-off-by: Ian Campbell -Signed-off-by: K. Y. Srinivasan -Signed-off-by: Tsunehisa Doi - ---- a/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Wed Oct 25 13:58:30 2006 +0100 -+++ b/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Wed Oct 25 13:58:30 2006 +0100 -@@ -3,4 +3,26 @@ - - #include - -+#include -+ -+#if defined(__LINUX_COMPILER_H) && !defined(__always_inline) -+#define __always_inline inline - #endif -+ -+#if defined(__LINUX_SPINLOCK_H) && !defined(DEFINE_SPINLOCK) -+#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED -+#endif -+ -+#if defined(_LINUX_INIT_H) && !defined(__init) -+#define __init -+#endif -+ -+#if defined(__LINUX_CACHE_H) && !defined(__read_mostly) -+#define __read_mostly -+#endif -+ -+#if defined(_LINUX_SKBUFF_H) && !defined(NET_IP_ALIGN) -+#define NET_IP_ALIGN 0 -+#endif -+ -+#endif - diff --git a/xu-11910-pv-hvm.diff b/xu-11910-pv-hvm.diff deleted file mode 100644 index c682c85..0000000 --- a/xu-11910-pv-hvm.diff +++ /dev/null @@ -1,22 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID f4b878188b5d521828d8120646ab1192ea5c8483 -# parent: ded9d1ae21f794f924bb312077bab69f782f87b8 -PV-to-HVM: Implement compatibility nonseekable_open as a nop on -kernels before 2.6.9 - -Signed-off-by: Ian Campbell - ---- a/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Wed Oct 25 13:58:30 2006 +0100 -+++ b/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Wed Oct 25 13:58:30 2006 +0100 -@@ -25,4 +25,8 @@ - #define NET_IP_ALIGN 0 - #endif - -+#if defined(_LINUX_FS_H) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) -+#define nonseekable_open(inode, filp) /* Nothing to do */ - #endif -+ -+#endif - diff --git a/xu-11911-pv-hvm.diff b/xu-11911-pv-hvm.diff deleted file mode 100644 index 27605bd..0000000 --- a/xu-11911-pv-hvm.diff +++ /dev/null @@ -1,26 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID 5d2f91f9b2f09fc57d24ef44f3ce31a4f0a9adfb -# parent: f4b878188b5d521828d8120646ab1192ea5c8483 -PV-on-HVM: Define system_state as 1 (SYSTEM_RUNNING) on kernels prior -to 2.6.7. These kernels did not export the system_state variable to -modules. - -Signed-off-by: Ian Campbell - ---- a/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c Wed Oct 25 13:58:30 2006 +0100 -@@ -1,4 +1,11 @@ - #include - #include - -+#include -+ - #include -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) -+static int system_state = 1; -+EXPORT_SYMBOL(system_state); -+#endif - diff --git a/xu-11912-pv-hvm.diff b/xu-11912-pv-hvm.diff deleted file mode 100644 index 33ec2cc..0000000 --- a/xu-11912-pv-hvm.diff +++ /dev/null @@ -1,39 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID 4dcf172e699e094bc772baa66b9dc93083332941 -# parent: 5d2f91f9b2f09fc57d24ef44f3ce31a4f0a9adfb -PV-on-HVM: Kernels prior to 2.6.8 did not export strcspn to modules -therefore implement our own and export it. - -Signed-off-by: Ian Campbell -Signed-off-by: K. Y. Srinivasan -Signed-off-by: Tsunehisa Doi - ---- a/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c Wed Oct 25 13:58:30 2006 +0100 -@@ -9,3 +9,23 @@ static int system_state = 1; - static int system_state = 1; - EXPORT_SYMBOL(system_state); - #endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) -+size_t strcspn(const char *s, const char *reject) -+{ -+ const char *p; -+ const char *r; -+ size_t count = 0; -+ -+ for (p = s; *p != '\0'; ++p) { -+ for (r = reject; *r != '\0'; ++r) { -+ if (*p == *r) -+ return count; -+ } -+ ++count; -+ } -+ -+ return count; -+} -+EXPORT_SYMBOL(strcspn); -+#endif - diff --git a/xu-11913-pv-hvm.diff b/xu-11913-pv-hvm.diff deleted file mode 100644 index 0274dc6..0000000 --- a/xu-11913-pv-hvm.diff +++ /dev/null @@ -1,48 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID ac6e4405ab6c363eae43fd7384b7dca975e9e28e -# parent: 4dcf172e699e094bc772baa66b9dc93083332941 -PV-on-HVM: Include compatability vmalloc_to_pfn for kernels before 2.6.10 - -Signed-off-by: Ian Campbell -Signed-off-by: K. Y. Srinivasan -Signed-off-by: Tsunehisa Doi - ---- a/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Wed Oct 25 13:58:30 2006 +0100 -+++ b/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Wed Oct 25 13:58:30 2006 +0100 -@@ -29,4 +29,8 @@ - #define nonseekable_open(inode, filp) /* Nothing to do */ - #endif - -+#if defined(_LINUX_MM_H) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) -+unsigned long vmalloc_to_pfn(void *addr); - #endif -+ -+#endif ---- a/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c Wed Oct 25 13:58:30 2006 +0100 -@@ -1,6 +1,7 @@ - #include - #include - -+#include - #include - - #include -@@ -29,3 +30,14 @@ size_t strcspn(const char *s, const char - } - EXPORT_SYMBOL(strcspn); - #endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) -+/* -+ * Map a vmalloc()-space virtual address to the physical page frame number. -+ */ -+unsigned long vmalloc_to_pfn(void * vmalloc_addr) -+{ -+ return page_to_pfn(vmalloc_to_page(vmalloc_addr)); -+} -+EXPORT_SYMBOL(vmalloc_to_pfn); -+#endif - diff --git a/xu-11914-pv-hvm.diff b/xu-11914-pv-hvm.diff deleted file mode 100644 index 0866fa4..0000000 --- a/xu-11914-pv-hvm.diff +++ /dev/null @@ -1,67 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID 0886fc73e787076a7ee2247e71da68f48d311e0b -# parent: ac6e4405ab6c363eae43fd7384b7dca975e9e28e -PV-on-HVM: Implement compatibilty version of wait_for_completion_timeout -for kernels before 2.6.11 - -Signed-off-by: Ian Campbell - ---- a/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Wed Oct 25 13:58:30 2006 +0100 -+++ b/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Wed Oct 25 13:58:30 2006 +0100 -@@ -33,4 +33,8 @@ unsigned long vmalloc_to_pfn(void *addr) - unsigned long vmalloc_to_pfn(void *addr); - #endif - -+#if defined(__LINUX_COMPLETION_H) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) -+unsigned long wait_for_completion_timeout(struct completion *x, unsigned long timeout); - #endif -+ -+#endif ---- a/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c Wed Oct 25 13:58:30 2006 +0100 -@@ -3,6 +3,7 @@ - - #include - #include -+#include - - #include - -@@ -41,3 +42,34 @@ unsigned long vmalloc_to_pfn(void * vmal - } - EXPORT_SYMBOL(vmalloc_to_pfn); - #endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) -+unsigned long wait_for_completion_timeout(struct completion *x, unsigned long timeout) -+{ -+ might_sleep(); -+ -+ spin_lock_irq(&x->wait.lock); -+ if (!x->done) { -+ DECLARE_WAITQUEUE(wait, current); -+ -+ wait.flags |= WQ_FLAG_EXCLUSIVE; -+ __add_wait_queue_tail(&x->wait, &wait); -+ do { -+ __set_current_state(TASK_UNINTERRUPTIBLE); -+ spin_unlock_irq(&x->wait.lock); -+ timeout = schedule_timeout(timeout); -+ spin_lock_irq(&x->wait.lock); -+ if (!timeout) { -+ __remove_wait_queue(&x->wait, &wait); -+ goto out; -+ } -+ } while (!x->done); -+ __remove_wait_queue(&x->wait, &wait); -+ } -+ x->done--; -+out: -+ spin_unlock_irq(&x->wait.lock); -+ return timeout; -+} -+EXPORT_SYMBOL(wait_for_completion_timeout); -+#endif - diff --git a/xu-11915-pv-hvm.diff b/xu-11915-pv-hvm.diff deleted file mode 100644 index b344cc5..0000000 --- a/xu-11915-pv-hvm.diff +++ /dev/null @@ -1,34 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID d30a4d4ccd94c41f607e54d2c2233f9be909dda7 -# parent: 0886fc73e787076a7ee2247e71da68f48d311e0b -PV-on-HVM: Implement and export a compatibility version of do_exit(). -Kernels prior to 2.6.12 did not export do_exit(). - -Signed-off-by: Ian Campbell -Signed-off-by: K. Y. Srinivasan -Signed-off-by: Tsunehisa Doi - ---- a/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c Wed Oct 25 13:58:30 2006 +0100 -@@ -73,3 +73,18 @@ out: - } - EXPORT_SYMBOL(wait_for_completion_timeout); - #endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) -+/* -+ fake do_exit using complete_and_exit -+ */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) -+asmlinkage NORET_TYPE void do_exit(long code) -+#else -+fastcall NORET_TYPE void do_exit(long code) -+#endif -+{ -+ complete_and_exit(NULL, code); -+} -+EXPORT_SYMBOL_GPL(do_exit); -+#endif - diff --git a/xu-11916-pv-hvm.diff b/xu-11916-pv-hvm.diff deleted file mode 100644 index 7b00c06..0000000 --- a/xu-11916-pv-hvm.diff +++ /dev/null @@ -1,39 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID db0d3f22e149d832e722173fa0e037e574db5f37 -# parent: d30a4d4ccd94c41f607e54d2c2233f9be909dda7 -PV-to-HVM: Impletement compatibility version of -schedule_timeout_interruptible for kernels before 2.6.14 - -Signed-off-by: Ian Campbell -Signed-off-by: K. Y. Srinivasan -Signed-off-by: Tsunehisa Doi - ---- a/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Wed Oct 25 13:58:30 2006 +0100 -+++ b/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Wed Oct 25 13:58:30 2006 +0100 -@@ -37,4 +37,8 @@ unsigned long wait_for_completion_timeou - unsigned long wait_for_completion_timeout(struct completion *x, unsigned long timeout); - #endif - -+#if defined(_LINUX_SCHED_H) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) -+signed long schedule_timeout_interruptible(signed long timeout); - #endif -+ -+#endif ---- a/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c Wed Oct 25 13:58:30 2006 +0100 -@@ -88,3 +88,12 @@ fastcall NORET_TYPE void do_exit(long co - } - EXPORT_SYMBOL_GPL(do_exit); - #endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) -+signed long schedule_timeout_interruptible(signed long timeout) -+{ -+ __set_current_state(TASK_INTERRUPTIBLE); -+ return schedule_timeout(timeout); -+} -+EXPORT_SYMBOL(schedule_timeout_interruptible); -+#endif - diff --git a/xu-11917-pv-hvm.diff b/xu-11917-pv-hvm.diff deleted file mode 100644 index 5deb22f..0000000 --- a/xu-11917-pv-hvm.diff +++ /dev/null @@ -1,54 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID 9f0b88aaf17076bcdc42dfef0870ba9f39e72f23 -# parent: db0d3f22e149d832e722173fa0e037e574db5f37 -PV-on-HVM: Include compatibility kzalloc implementation for kernels -before 2.6.14. - -Signed-off-by: Ian Campbell -Signed-off-by: K. Y. Srinivasan -Signed-off-by: Tsunehisa Doi - ---- a/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Wed Oct 25 13:58:30 2006 +0100 -+++ b/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Wed Oct 25 13:58:30 2006 +0100 -@@ -41,4 +41,8 @@ signed long schedule_timeout_interruptib - signed long schedule_timeout_interruptible(signed long timeout); - #endif - -+#if defined(_LINUX_SLAB_H) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) -+void *kzalloc(size_t size, int flags); - #endif -+ -+#endif ---- a/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c Wed Oct 25 13:58:30 2006 +0100 -+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c Wed Oct 25 13:58:30 2006 +0100 -@@ -4,6 +4,7 @@ - #include - #include - #include -+#include - - #include - -@@ -97,3 +98,19 @@ signed long schedule_timeout_interruptib - } - EXPORT_SYMBOL(schedule_timeout_interruptible); - #endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) -+/** -+ * kzalloc - allocate memory. The memory is set to zero. -+ * @size: how many bytes of memory are required. -+ * @flags: the type of memory to allocate. -+ */ -+void *kzalloc(size_t size, int flags) -+{ -+ void *ret = kmalloc(size, flags); -+ if (ret) -+ memset(ret, 0, size); -+ return ret; -+} -+EXPORT_SYMBOL(kzalloc); -+#endif - diff --git a/xu-11918-pv-hvm.diff b/xu-11918-pv-hvm.diff deleted file mode 100644 index ae53add..0000000 --- a/xu-11918-pv-hvm.diff +++ /dev/null @@ -1,24 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Wed Oct 25 13:58:30 2006 +0100 -# Node ID fc68e3ef9139b5483649a6bfe87b83a8ce1e9f12 -# parent: 9f0b88aaf17076bcdc42dfef0870ba9f39e72f23 -PV-to-HVM: Add a compatibility define for the end_that_request_last -which changed prototype in 2.6.16. - -Signed-off-by: Ian Campbell -Signed-off-by: K. Y. Srinivasan -Signed-off-by: Tsunehisa Doi - ---- a/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Wed Oct 25 13:58:30 2006 +0100 -+++ b/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Wed Oct 25 13:58:30 2006 +0100 -@@ -45,4 +45,8 @@ void *kzalloc(size_t size, int flags); - void *kzalloc(size_t size, int flags); - #endif - -+#if defined(_LINUX_BLKDEV_H) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) -+#define end_that_request_last(req, uptodate) end_that_request_last(req) - #endif -+ -+#endif - diff --git a/xu-11974-pv-hvm.diff b/xu-11974-pv-hvm.diff deleted file mode 100644 index 8219bb5..0000000 --- a/xu-11974-pv-hvm.diff +++ /dev/null @@ -1,72 +0,0 @@ -# HG changeset patch -# User awilliam@xenbuild.aw -# Date Sat Oct 14 16:28:32 2006 -0600 -# Node ID 7c2a5f96a192a07cc73991a52ff3ffd80658cf94 -# parent: 9e8fdcc46fa31a6e4f607c67e97f8a9d3fa0455c -[IA64] Xencomm fixes for HVM PV-drivers - -Signed-off-by: Tristan Gingold - - - -Index: xen-3.0.3-testing/unmodified_drivers/linux-2.6/mkbuildtree -=================================================================== ---- xen-3.0.3-testing.orig/unmodified_drivers/linux-2.6/mkbuildtree -+++ xen-3.0.3-testing/unmodified_drivers/linux-2.6/mkbuildtree -@@ -27,6 +27,7 @@ mkdir -p include - mkdir -p include/xen - mkdir -p include/public - mkdir -p include/asm -+mkdir -p include/asm/xen - - lndir -silent ${XL}/include/xen include/xen - ln -sf ${XEN}/include/public include/xen/interface -@@ -54,6 +55,10 @@ i[34567]86) - ln -sf ${XL}/include/asm-ia64/hypercall.h include/asm - ln -sf ${XL}/include/asm-ia64/synch_bitops.h include/asm - ln -sf ${XL}/include/asm-ia64/maddr.h include/asm -+ ln -sf ${XL}/include/asm-ia64/xen/xcom_hcall.h include/asm/xen -+ ln -sf ${XL}/include/asm-ia64/xen/xencomm.h include/asm/xen -+ ln -sf ${XL}/arch/ia64/xen/xcom_mini.c platform-pci -+ ln -sf ${XL}/arch/ia64/xen/xencomm.c platform-pci - ;; - *) - echo unknown architecture $uname -Index: xen-3.0.3-testing/unmodified_drivers/linux-2.6/platform-pci/Kbuild -=================================================================== ---- xen-3.0.3-testing.orig/unmodified_drivers/linux-2.6/platform-pci/Kbuild -+++ xen-3.0.3-testing/unmodified_drivers/linux-2.6/platform-pci/Kbuild -@@ -5,3 +5,8 @@ obj-m := xen-platform-pci.o - EXTRA_CFLAGS += -I$(M)/platform-pci - - xen-platform-pci-objs := evtchn.o platform-pci.o gnttab.o xen_support.o features.o platform-compat.o -+ -+# Can we do better ? -+ifeq ($(ARCH),ia64) -+ xen-platform-pci-objs += xcom_mini.o xencomm.o -+endif -Index: xen-3.0.3-testing/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c -=================================================================== ---- xen-3.0.3-testing.orig/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c -+++ xen-3.0.3-testing/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c -@@ -36,6 +36,9 @@ - #include - #include - #include -+#ifdef __ia64__ -+#include -+#endif - - #include "platform-pci.h" - -@@ -64,6 +67,10 @@ static int __init init_xen_info(void) - struct xen_add_to_physmap xatp; - extern void *shared_info_area; - -+#ifdef __ia64__ -+ xencomm_init(); -+#endif -+ - setup_xen_features(); - - shared_info_frame = alloc_xen_mmio(PAGE_SIZE) >> PAGE_SHIFT; diff --git a/xu-12012-hvm-smp-timer.diff b/xu-12012-hvm-smp-timer.diff deleted file mode 100644 index 8695675..0000000 --- a/xu-12012-hvm-smp-timer.diff +++ /dev/null @@ -1,140 +0,0 @@ -# HG changeset patch -# User kaf24@localhost.localdomain -# Date Fri Oct 27 18:00:03 2006 +0100 -# Node ID a1939d76c0e8e27bdac5233df7bd78c004ea8deb -# parent: 66fe61db9e69e03e12d0c4086683bebfb4a67780 -[HVM] Fix SMP timer issues: - * Sync AP TSCs with BP at startup - * Only halt BP TSC when descheduled - * Correctly handle IPIs on timer vector -Signed-off-by: Xiaowei Yang - -Index: xen-3.0.3-testing/xen/arch/x86/hvm/hvm.c -=================================================================== ---- xen-3.0.3-testing.orig/xen/arch/x86/hvm/hvm.c -+++ xen-3.0.3-testing/xen/arch/x86/hvm/hvm.c -@@ -226,7 +226,7 @@ void hvm_do_resume(struct vcpu *v) - hvm_stts(v); - - /* pick up the elapsed PIT ticks and re-enable pit_timer */ -- if ( pt->enabled && pt->first_injected ) { -+ if ( pt->enabled && v->vcpu_id == pt->bind_vcpu && pt->first_injected ) { - if ( v->arch.hvm_vcpu.guest_time ) { - hvm_set_guest_time(v, v->arch.hvm_vcpu.guest_time); - v->arch.hvm_vcpu.guest_time = 0; -Index: xen-3.0.3-testing/xen/arch/x86/hvm/intercept.c -=================================================================== ---- xen-3.0.3-testing.orig/xen/arch/x86/hvm/intercept.c -+++ xen-3.0.3-testing/xen/arch/x86/hvm/intercept.c -@@ -339,6 +339,7 @@ struct periodic_time * create_periodic_t - stop_timer (&pt->timer); - pt->enabled = 0; - } -+ pt->bind_vcpu = 0; /* timer interrupt delivered to BSP by default */ - pt->pending_intr_nr = 0; - pt->first_injected = 0; - if (period < 900000) { /* < 0.9 ms */ -Index: xen-3.0.3-testing/xen/arch/x86/hvm/io.c -=================================================================== ---- xen-3.0.3-testing.orig/xen/arch/x86/hvm/io.c -+++ xen-3.0.3-testing/xen/arch/x86/hvm/io.c -@@ -680,7 +680,7 @@ void hvm_interrupt_post(struct vcpu *v, - struct periodic_time *pt = - &(v->domain->arch.hvm_domain.pl_time.periodic_tm); - -- if ( is_pit_irq(v, vector, type) ) { -+ if ( is_pit_irq(v, vector, type) && (v->vcpu_id == pt->bind_vcpu) ) { - if ( !pt->first_injected ) { - pt->pending_intr_nr = 0; - pt->last_plt_gtime = hvm_get_guest_time(v); -Index: xen-3.0.3-testing/xen/arch/x86/hvm/svm/svm.c -=================================================================== ---- xen-3.0.3-testing.orig/xen/arch/x86/hvm/svm/svm.c -+++ xen-3.0.3-testing/xen/arch/x86/hvm/svm/svm.c -@@ -763,7 +763,8 @@ static void svm_freeze_time(struct vcpu - { - struct periodic_time *pt=&v->domain->arch.hvm_domain.pl_time.periodic_tm; - -- if ( pt->enabled && pt->first_injected && !v->arch.hvm_vcpu.guest_time ) { -+ if ( pt->enabled && pt->first_injected && v->vcpu_id == pt->bind_vcpu -+ && !v->arch.hvm_vcpu.guest_time ) { - v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v); - stop_timer(&(pt->timer)); - } -Index: xen-3.0.3-testing/xen/arch/x86/hvm/vmx/vmcs.c -=================================================================== ---- xen-3.0.3-testing.orig/xen/arch/x86/hvm/vmx/vmcs.c -+++ xen-3.0.3-testing/xen/arch/x86/hvm/vmx/vmcs.c -@@ -314,14 +314,20 @@ static void vmx_set_host_env(struct vcpu - error |= __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom()); - } - -+/* Update CR3, CR0, CR4, GDT, LDT, TR */ - static void vmx_do_launch(struct vcpu *v) - { --/* Update CR3, CR0, CR4, GDT, LDT, TR */ - unsigned int error = 0; - unsigned long cr0, cr4; - -- if (v->vcpu_id == 0) -+ if ( v->vcpu_id == 0 ) - hvm_setup_platform(v->domain); -+ else { -+ /* Sync AP's TSC with BSP's */ -+ v->arch.hvm_vcpu.cache_tsc_offset = -+ v->domain->vcpu[0]->arch.hvm_vcpu.cache_tsc_offset; -+ hvm_funcs.set_tsc_offset(v, v->arch.hvm_vcpu.cache_tsc_offset); -+ } - - __asm__ __volatile__ ("mov %%cr0,%0" : "=r" (cr0) : ); - -@@ -360,9 +366,6 @@ static void vmx_do_launch(struct vcpu *v - __vmwrite(HOST_CR3, v->arch.cr3); - - v->arch.schedule_tail = arch_vmx_do_resume; -- -- /* init guest tsc to start from 0 */ -- hvm_set_guest_time(v, 0); - } - - /* -Index: xen-3.0.3-testing/xen/arch/x86/hvm/vmx/vmx.c -=================================================================== ---- xen-3.0.3-testing.orig/xen/arch/x86/hvm/vmx/vmx.c -+++ xen-3.0.3-testing/xen/arch/x86/hvm/vmx/vmx.c -@@ -456,7 +456,8 @@ static void vmx_freeze_time(struct vcpu - { - struct periodic_time *pt=&v->domain->arch.hvm_domain.pl_time.periodic_tm; - -- if ( pt->enabled && pt->first_injected && !v->arch.hvm_vcpu.guest_time ) { -+ if ( pt->enabled && pt->first_injected && v->vcpu_id == pt->bind_vcpu -+ && !v->arch.hvm_vcpu.guest_time ) { - v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v); - stop_timer(&(pt->timer)); - } -@@ -1927,6 +1928,13 @@ static inline void vmx_do_msr_write(stru - - switch (regs->ecx) { - case MSR_IA32_TIME_STAMP_COUNTER: -+ { -+ struct periodic_time *pt = -+ &(v->domain->arch.hvm_domain.pl_time.periodic_tm); -+ if ( pt->enabled && pt->first_injected -+ && v->vcpu_id == pt->bind_vcpu ) -+ pt->first_injected = 0; -+ } - hvm_set_guest_time(v, msr_content); - break; - case MSR_IA32_SYSENTER_CS: -Index: xen-3.0.3-testing/xen/include/asm-x86/hvm/vpit.h -=================================================================== ---- xen-3.0.3-testing.orig/xen/include/asm-x86/hvm/vpit.h -+++ xen-3.0.3-testing/xen/include/asm-x86/hvm/vpit.h -@@ -58,6 +58,7 @@ struct periodic_time { - char one_shot; /* one shot time */ - char irq; - char first_injected; /* flag to prevent shadow window */ -+ u32 bind_vcpu; /* vcpu timer interrupt delivers to */ - u32 pending_intr_nr; /* the couner for pending timer interrupts */ - u32 period; /* frequency in ns */ - u64 period_cycles; /* frequency in cpu cycles */ diff --git a/xu-12013-hvm-ioapic.diff b/xu-12013-hvm-ioapic.diff deleted file mode 100644 index e0a8d6e..0000000 --- a/xu-12013-hvm-ioapic.diff +++ /dev/null @@ -1,59 +0,0 @@ -# HG changeset patch -# User kaf24@localhost.localdomain -# Date Fri Oct 27 18:02:40 2006 +0100 -# Node ID ee140fbcb88df2e55259b0c6519de7645641468a -# parent: a1939d76c0e8e27bdac5233df7bd78c004ea8deb -[HVM] Ensure that, if AP is blocked, it is woken by interrupt delivered by IOAPIC. - -This fixes 64-bit SMP Windows 2k3 boot. - -Signed-off-by: Xiaowei Yang -Signed-off-by: Xin Li - -Index: xen-3.0.3-testing/xen/arch/x86/hvm/vioapic.c -=================================================================== ---- xen-3.0.3-testing.orig/xen/arch/x86/hvm/vioapic.c -+++ xen-3.0.3-testing/xen/arch/x86/hvm/vioapic.c -@@ -39,6 +39,7 @@ - #include - #include - #include -+#include - - /* HACK: Route IRQ0 only to VCPU0 to prevent time jumps. */ - #define IRQ0_SPECIAL_ROUTING 1 -@@ -436,9 +437,10 @@ static void ioapic_deliver(hvm_vioapic_t - #endif - target = apic_round_robin(s->domain, dest_mode, - vector, deliver_bitmask); -- if (target) -+ if (target) { - ioapic_inj_irq(s, target, vector, trig_mode, delivery_mode); -- else -+ vcpu_kick(target->vcpu); -+ } else - HVM_DBG_LOG(DBG_LEVEL_IOAPIC, - "null round robin mask %x vector %x delivery_mode %x\n", - deliver_bitmask, vector, dest_LowestPrio); -@@ -448,6 +450,7 @@ static void ioapic_deliver(hvm_vioapic_t - case dest_Fixed: - case dest_ExtINT: - { -+ struct vlapic* target; - uint8_t bit; - for (bit = 0; bit < s->lapic_count; bit++) { - if (deliver_bitmask & (1 << bit)) { -@@ -458,9 +461,10 @@ static void ioapic_deliver(hvm_vioapic_t - domain_crash_synchronous(); - } - #endif -- if (s->lapic_info[bit]) { -- ioapic_inj_irq(s, s->lapic_info[bit], -- vector, trig_mode, delivery_mode); -+ target = s->lapic_info[bit]; -+ if (target) { -+ ioapic_inj_irq(s, target, vector, trig_mode, delivery_mode); -+ vcpu_kick(target->vcpu); - } - } - } diff --git a/xu-12030-pv-hvm.diff b/xu-12030-pv-hvm.diff deleted file mode 100644 index c92b023..0000000 --- a/xu-12030-pv-hvm.diff +++ /dev/null @@ -1,99 +0,0 @@ -# HG changeset patch -# User kfraser@localhost.localdomain -# Date Mon Oct 30 14:09:13 2006 +0000 -# Node ID 44caba9460afd444a6a56c5d4517f938ca99130c -# parent: c3b4fef4f751e1fc57b8ee48abf06f1e3e802ce4 -[LINUX] Declare structs as 'static __initdata' where possible. - -Probably still not catching all possible cases, but using static -(where not already the case) makes the code size smaller, and using __initdata -has the usual advantages. - -Signed-off-by: Jan Beulich - ---- a/linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c Mon Oct 30 14:04:44 2006 +0000 -+++ b/linux-2.6-xen-sparse/arch/i386/kernel/sysenter.c Mon Oct 30 14:09:13 2006 +0000 -@@ -60,7 +60,7 @@ int __init sysenter_setup(void) - - #ifdef CONFIG_XEN - if (boot_cpu_has(X86_FEATURE_SEP)) { -- struct callback_register sysenter = { -+ static struct callback_register __initdata sysenter = { - .type = CALLBACKTYPE_sysenter, - .address = { __KERNEL_CS, (unsigned long)sysenter_entry }, - }; ---- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Mon Oct 30 14:04:44 2006 +0000 -+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Mon Oct 30 14:09:13 2006 +0000 -@@ -56,15 +56,15 @@ static void __init machine_specific_arch - struct xen_machphys_mapping mapping; - unsigned long machine_to_phys_nr_ents; - struct xen_platform_parameters pp; -- struct callback_register event = { -+ static struct callback_register __initdata event = { - .type = CALLBACKTYPE_event, - .address = { __KERNEL_CS, (unsigned long)hypervisor_callback }, - }; -- struct callback_register failsafe = { -+ static struct callback_register __initdata failsafe = { - .type = CALLBACKTYPE_failsafe, - .address = { __KERNEL_CS, (unsigned long)failsafe_callback }, - }; -- struct callback_register nmi_cb = { -+ static struct callback_register __initdata nmi_cb = { - .type = CALLBACKTYPE_nmi, - .address = { __KERNEL_CS, (unsigned long)nmi }, - }; -@@ -80,9 +80,10 @@ static void __init machine_specific_arch - - ret = HYPERVISOR_callback_op(CALLBACKOP_register, &nmi_cb); - if (ret == -ENOSYS) { -- struct xennmi_callback cb; -+ static struct xennmi_callback __initdata cb = { -+ .handler_address = (unsigned long)nmi; -+ }; - -- cb.handler_address = nmi_cb.address.eip; - HYPERVISOR_nmi_op(XENNMI_register_callback, &cb); - } - ---- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h Mon Oct 30 14:04:44 2006 +0000 -+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h Mon Oct 30 14:09:13 2006 +0000 -@@ -15,20 +15,20 @@ static void __init machine_specific_arch - static void __init machine_specific_arch_setup(void) - { - int ret; -- struct callback_register event = { -+ static struct callback_register __initdata event = { - .type = CALLBACKTYPE_event, - .address = (unsigned long) hypervisor_callback, - }; -- struct callback_register failsafe = { -+ static struct callback_register __initdata failsafe = { - .type = CALLBACKTYPE_failsafe, - .address = (unsigned long)failsafe_callback, - }; -- struct callback_register syscall = { -+ static struct callback_register __initdata syscall = { - .type = CALLBACKTYPE_syscall, - .address = (unsigned long)system_call, - }; - #ifdef CONFIG_X86_LOCAL_APIC -- struct callback_register nmi_cb = { -+ static struct callback_register __initdata nmi_cb = { - .type = CALLBACKTYPE_nmi, - .address = (unsigned long)nmi, - }; -@@ -49,9 +49,10 @@ static void __init machine_specific_arch - #ifdef CONFIG_X86_LOCAL_APIC - ret = HYPERVISOR_callback_op(CALLBACKOP_register, &nmi_cb); - if (ret == -ENOSYS) { -- struct xennmi_callback cb; -+ static struct xennmi_callback __initdata cb = { -+ .handler_address = (unsigned long)nmi; -+ }; - -- cb.handler_address = nmi_cb.address; - HYPERVISOR_nmi_op(XENNMI_register_callback, &cb); - } - #endif - diff --git a/xu-12031-pv-hvm.diff b/xu-12031-pv-hvm.diff deleted file mode 100644 index d41f7c6..0000000 --- a/xu-12031-pv-hvm.diff +++ /dev/null @@ -1,243 +0,0 @@ -# HG changeset patch -# User kfraser@localhost.localdomain -# Date Mon Oct 30 14:14:46 2006 +0000 -# Node ID 6f3865b4d3d3bddbd64c0ed7c21b03bd98e78a0a -# parent: 44caba9460afd444a6a56c5d4517f938ca99130c -[LINUX] Use CONFIG_XEN_COMPAT_030002 where possible. -Signed-off-by: Jan Beulich - ---- a/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c Mon Oct 30 14:09:13 2006 +0000 -+++ b/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c Mon Oct 30 14:14:46 2006 +0000 -@@ -325,6 +325,7 @@ int xen_create_contiguous_region( - success = (exchange.nr_exchanged == (1UL << order)); - BUG_ON(!success && ((exchange.nr_exchanged != 0) || (rc == 0))); - BUG_ON(success && (rc != 0)); -+#ifdef CONFIG_XEN_COMPAT_030002 - if (unlikely(rc == -ENOSYS)) { - /* Compatibility when XENMEM_exchange is unsupported. */ - if (HYPERVISOR_memory_op(XENMEM_decrease_reservation, -@@ -341,6 +342,7 @@ int xen_create_contiguous_region( - BUG(); - } - } -+#endif - - /* 3. Map the new extent in place of old pages. */ - for (i = 0; i < (1UL< - ---- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Mon Oct 30 14:14:46 2006 +0000 -+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Mon Oct 30 14:28:29 2006 +0000 -@@ -84,7 +84,7 @@ static void __init machine_specific_arch - #ifdef CONFIG_XEN_COMPAT_030002 - if (ret == -ENOSYS) { - static struct xennmi_callback __initdata cb = { -- .handler_address = (unsigned long)nmi; -+ .handler_address = (unsigned long)nmi - }; - - HYPERVISOR_nmi_op(XENNMI_register_callback, &cb); ---- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h Mon Oct 30 14:14:46 2006 +0000 -+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h Mon Oct 30 14:28:29 2006 +0000 -@@ -53,7 +53,7 @@ static void __init machine_specific_arch - #ifdef CONFIG_XEN_COMPAT_030002 - if (ret == -ENOSYS) { - static struct xennmi_callback __initdata cb = { -- .handler_address = (unsigned long)nmi; -+ .handler_address = (unsigned long)nmi - }; - - HYPERVISOR_nmi_op(XENNMI_register_callback, &cb); - diff --git a/xu-12040-pv-spurious-interrupt.diff b/xu-12040-pv-spurious-interrupt.diff deleted file mode 100644 index fc060c1..0000000 --- a/xu-12040-pv-spurious-interrupt.diff +++ /dev/null @@ -1,44 +0,0 @@ -# HG changeset patch -# User Steven Smith -# Date Tue Oct 31 11:38:55 2006 +0000 -# Node ID 79a40acadb41fbe5e5b88b20de5fe53f4dd6b413 -# parent: b2371c9e05f5146767464db8504214ae2b77c25c -[PV-ON-HVM] Don't generate lots of spurious interrupts when using event -channel upcalls. - -The issue here was that the Xen platform PCI interrupt is only updated -when you return from the hypervisor into guest context, and so remained -asserted for a short interval after the interrupt handler ran. If -it happened that the first subsequent trap to the hypervisor was -for unmasking the 8259 interrupt again, the unmasking caused the interrupt -to be reinjected. This caused an edge on the chaining interrupt from -the slave PIC to the master. The platform interrupt on the slave -would then be cleared as we returned to the guest, and so you -eventually end up injecting an interrupt on the master chained -interrupt with nothing pending on the slave, which shows up as -a spurious interrupt in the guest. - -Signed-off-by: Steven Smith - ---- a/unmodified_drivers/linux-2.6/platform-pci/evtchn.c Tue Oct 31 11:31:34 2006 +0000 -+++ b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c Tue Oct 31 11:38:55 2006 +0000 -@@ -167,11 +167,17 @@ irqreturn_t evtchn_interrupt(int irq, vo - l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i]; - } - } -+ -+ /* Make sure the hypervisor has a chance to notice that the -+ upcall_pending condition has been cleared, so that we don't -+ try and reinject the interrupt again. */ -+ (void)HYPERVISOR_xen_version(0, NULL); -+ - return IRQ_HANDLED; - } - - void force_evtchn_callback(void) - { -- evtchn_interrupt(0, NULL, NULL); -+ (void)HYPERVISOR_xen_version(0, NULL); - } - EXPORT_SYMBOL(force_evtchn_callback); - diff --git a/xu-12205-pv-hvm.diff b/xu-12205-pv-hvm.diff deleted file mode 100644 index e1371f5..0000000 --- a/xu-12205-pv-hvm.diff +++ /dev/null @@ -1,23 +0,0 @@ -# HG changeset patch -# User Ian Campbell -# Date Thu Nov 02 11:56:26 2006 +0000 -# Node ID af1403dd13af9f2e3e778001c1ff681036753aca -# parent: e6fdb32b786c3e57b9c641274607603897b97334 -PV-on-HVM: Use ln -nsf in mkbuildtree to avoid creating a symlink loop -if include/xen/interfaces already exists. - -Signed-off-by: Ian Campbell - -Index: xen-3.0.3-testing/unmodified_drivers/linux-2.6/mkbuildtree -=================================================================== ---- xen-3.0.3-testing.orig/unmodified_drivers/linux-2.6/mkbuildtree -+++ xen-3.0.3-testing/unmodified_drivers/linux-2.6/mkbuildtree -@@ -30,7 +30,7 @@ mkdir -p include/asm - mkdir -p include/asm/xen - - lndir -silent ${XL}/include/xen include/xen --ln -sf ${XEN}/include/public include/xen/interface -+ln -nsf ${XEN}/include/public include/xen/interface - - # Need to be quite careful here: we don't want the files we link in to - # risk overriding the native Linux ones (in particular, system.h must diff --git a/xu-12278-hvm-interrupt-race.diff b/xu-12278-hvm-interrupt-race.diff deleted file mode 100644 index 739e744..0000000 --- a/xu-12278-hvm-interrupt-race.diff +++ /dev/null @@ -1,57 +0,0 @@ -# HG changeset patch -# User kfraser@localhost.localdomain -# Date Tue Nov 07 17:48:18 2006 +0000 -# Node ID 2b89ebf00fc884f68168abea4159c11f31db131a -# parent: cba947bc845063ed820142bb921121ab8ead6452 -[SVM] Fix an interrupt race window in the do_launch/vmrun/vmexit loop for AMD-V. - -This problem found by Virtual Iron (Dave Winchell), and patch also -provided by VI. - -Signed-off-by: Tom Woller -Signed-off-by: Dave Winchell - -Index: xen-3.0.3-testing/xen/arch/x86/hvm/svm/x86_32/exits.S -=================================================================== ---- xen-3.0.3-testing.orig/xen/arch/x86/hvm/svm/x86_32/exits.S -+++ xen-3.0.3-testing/xen/arch/x86/hvm/svm/x86_32/exits.S -@@ -89,8 +89,8 @@ - #define CLGI .byte 0x0F,0x01,0xDD - - ENTRY(svm_asm_do_launch) -- sti - CLGI -+ sti - GET_CURRENT(%ebx) - movl VCPU_svm_vmcb(%ebx), %ecx - movl 24(%esp), %eax -@@ -153,7 +153,6 @@ svm_restore_all_guest: - call svm_intr_assist - call svm_asid - call svm_load_cr2 -- sti - /* - * Check if we are going back to SVM-based VM - * By this time, all the setups in the VMCB must be complete. -Index: xen-3.0.3-testing/xen/arch/x86/hvm/svm/x86_64/exits.S -=================================================================== ---- xen-3.0.3-testing.orig/xen/arch/x86/hvm/svm/x86_64/exits.S -+++ xen-3.0.3-testing/xen/arch/x86/hvm/svm/x86_64/exits.S -@@ -99,8 +99,8 @@ - #define CLGI .byte 0x0F,0x01,0xDD - - ENTRY(svm_asm_do_launch) -- sti - CLGI -+ sti - GET_CURRENT(%rbx) - movq VCPU_svm_vmcb(%rbx), %rcx - movq UREGS_rax(%rsp), %rax -@@ -165,7 +165,6 @@ svm_restore_all_guest: - call svm_intr_assist - call svm_asid - call svm_load_cr2 -- sti - /* - * Check if we are going back to VMX-based VM - * By this time, all the setups in the VMCS must be complete. diff --git a/xxx_heap_pages-static.patch b/xxx_heap_pages-static.patch new file mode 100644 index 0000000..1a60c9b --- /dev/null +++ b/xxx_heap_pages-static.patch @@ -0,0 +1,244 @@ +Index: xen-3.0.4-testing/xen/common/page_alloc.c +=================================================================== +--- xen-3.0.4-testing.orig/xen/common/page_alloc.c ++++ xen-3.0.4-testing/xen/common/page_alloc.c +@@ -306,78 +306,11 @@ static unsigned long avail[NR_ZONES][MAX + + static DEFINE_SPINLOCK(heap_lock); + +-void end_boot_allocator(void) +-{ +- unsigned long i, j, k; +- int curr_free, next_free; +- +- memset(avail, 0, sizeof(avail)); +- +- for ( i = 0; i < NR_ZONES; i++ ) +- for ( j = 0; j < MAX_NUMNODES; j++ ) +- for ( k = 0; k <= MAX_ORDER; k++ ) +- INIT_LIST_HEAD(&heap[i][j][k]); +- +- /* Pages that are free now go to the domain sub-allocator. */ +- if ( (curr_free = next_free = !allocated_in_map(first_valid_mfn)) ) +- map_alloc(first_valid_mfn, 1); +- for ( i = first_valid_mfn; i < max_page; i++ ) +- { +- curr_free = next_free; +- next_free = !allocated_in_map(i+1); +- if ( next_free ) +- map_alloc(i+1, 1); /* prevent merging in free_heap_pages() */ +- if ( curr_free ) +- init_heap_pages(pfn_dom_zone_type(i), mfn_to_page(i), 1); +- } +- +- printk("Domain heap initialised: DMA width %u bits\n", dma_bitsize); +-} +- +-/* +- * Hand the specified arbitrary page range to the specified heap zone +- * checking the node_id of the previous page. If they differ and the +- * latter is not on a MAX_ORDER boundary, then we reserve the page by +- * not freeing it to the buddy allocator. +- */ +-#define MAX_ORDER_ALIGNED (1UL << (MAX_ORDER)) +-void init_heap_pages( +- unsigned int zone, struct page_info *pg, unsigned long nr_pages) +-{ +- unsigned int nid_curr, nid_prev; +- unsigned long i; +- +- ASSERT(zone < NR_ZONES); +- +- if ( likely(page_to_mfn(pg) != 0) ) +- nid_prev = phys_to_nid(page_to_maddr(pg-1)); +- else +- nid_prev = phys_to_nid(page_to_maddr(pg)); +- +- for ( i = 0; i < nr_pages; i++ ) +- { +- nid_curr = phys_to_nid(page_to_maddr(pg+i)); +- +- /* +- * free pages of the same node, or if they differ, but are on a +- * MAX_ORDER alignement boundary (which already get reserved) +- */ +- if ( (nid_curr == nid_prev) || (page_to_maddr(pg+i) & +- MAX_ORDER_ALIGNED) ) +- free_heap_pages(zone, pg+i, 0); +- else +- printk("Reserving non-aligned node boundary @ mfn %lu\n", +- page_to_mfn(pg+i)); +- +- nid_prev = nid_curr; +- } +-} +- + /* Allocate 2^@order contiguous pages. */ +-struct page_info *alloc_heap_pages(unsigned int zone, unsigned int cpu, +- unsigned int order) ++static struct page_info *alloc_heap_pages( ++ unsigned int zone, unsigned int cpu, unsigned int order) + { +- unsigned int i,j, node = cpu_to_node(cpu), num_nodes = num_online_nodes(); ++ unsigned int i, j, node = cpu_to_node(cpu), num_nodes = num_online_nodes(); + unsigned int request = (1UL << order); + struct page_info *pg; + +@@ -436,13 +369,12 @@ struct page_info *alloc_heap_pages(unsig + return pg; + } + +- + /* Free 2^@order set of pages. */ +-void free_heap_pages( ++static void free_heap_pages( + unsigned int zone, struct page_info *pg, unsigned int order) + { + unsigned long mask; +- int node = phys_to_nid(page_to_maddr(pg)); ++ unsigned int node = phys_to_nid(page_to_maddr(pg)); + + ASSERT(zone < NR_ZONES); + ASSERT(order <= MAX_ORDER); +@@ -489,6 +421,87 @@ void free_heap_pages( + spin_unlock(&heap_lock); + } + ++/* ++ * Hand the specified arbitrary page range to the specified heap zone ++ * checking the node_id of the previous page. If they differ and the ++ * latter is not on a MAX_ORDER boundary, then we reserve the page by ++ * not freeing it to the buddy allocator. ++ */ ++#define MAX_ORDER_ALIGNED (1UL << (MAX_ORDER)) ++void init_heap_pages( ++ unsigned int zone, struct page_info *pg, unsigned long nr_pages) ++{ ++ unsigned int nid_curr, nid_prev; ++ unsigned long i; ++ ++ ASSERT(zone < NR_ZONES); ++ ++ if ( likely(page_to_mfn(pg) != 0) ) ++ nid_prev = phys_to_nid(page_to_maddr(pg-1)); ++ else ++ nid_prev = phys_to_nid(page_to_maddr(pg)); ++ ++ for ( i = 0; i < nr_pages; i++ ) ++ { ++ nid_curr = phys_to_nid(page_to_maddr(pg+i)); ++ ++ /* ++ * free pages of the same node, or if they differ, but are on a ++ * MAX_ORDER alignement boundary (which already get reserved) ++ */ ++ if ( (nid_curr == nid_prev) || (page_to_maddr(pg+i) & ++ MAX_ORDER_ALIGNED) ) ++ free_heap_pages(zone, pg+i, 0); ++ else ++ printk("Reserving non-aligned node boundary @ mfn %lu\n", ++ page_to_mfn(pg+i)); ++ ++ nid_prev = nid_curr; ++ } ++} ++ ++static unsigned long avail_heap_pages( ++ int zone, int node) ++{ ++ unsigned int i, j, num_nodes = num_online_nodes(); ++ unsigned long free_pages = 0; ++ ++ for (i=0; i