# HG changeset patch
# User awilliam@xxxxxxxxxxxx
# Date 1166207578 25200
# Node ID e17d7438e09e5ead12049b44f5bf9d842a401129
# Parent 1e042dde1a5f2a56ed6517e00ac83d44f324a652
# Parent 41d9f00140c51783ef4030b4f646feb36af7c195
merge with xen-ia64-unstable.hg
---
tools/libxen/include/xen_boot_type.h | 87 -
tools/libxen/include/xen_boot_type_internal.h | 37
tools/libxen/src/xen_boot_type.c | 83 -
xen/arch/powerpc/boot/boot32.S | 75 -
xen/arch/powerpc/boot/start.S | 51
xen/arch/powerpc/delay.c | 37
xen/arch/powerpc/mambo.S | 64 -
xen/include/asm-powerpc/misc.h | 33
xen/include/asm-powerpc/uaccess.h | 38
.hgignore | 13
config/powerpc64.mk | 2
linux-2.6-xen-sparse/arch/i386/kernel/fixup.c | 10
linux-2.6-xen-sparse/arch/ia64/Kconfig | 1
linux-2.6-xen-sparse/drivers/xen/core/smpboot.c | 25
linux-2.6-xen-sparse/drivers/xen/fbfront/xenfb.c | 28
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c | 4
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c | 2
linux-2.6-xen-sparse/net/core/skbuff.c | 11
patches/linux-2.6.16.33/net-gso-6-linear-segmentation.patch | 21
patches/linux-2.6.16.33/series | 1
tools/Rules.mk | 4
tools/blktap/drivers/blktapctrl.c | 49
tools/blktap/drivers/block-qcow.c | 120 +-
tools/blktap/drivers/qcow-create.c | 71 -
tools/check/check_crypto_lib | 17
tools/check/check_openssl_devel | 17
tools/check/check_python | 5
tools/check/check_python_devel | 17
tools/check/check_python_xml | 8
tools/check/check_udev | 40
tools/check/check_x11_devel | 18
tools/examples/external-device-migrate | 4
tools/ioemu/target-i386-dm/exec-dm.c | 11
tools/ioemu/vl.c | 7
tools/libaio/src/syscall-ppc.h | 6
tools/libxc/ia64/xc_ia64_hvm_build.c | 10
tools/libxc/powerpc64/Makefile | 4
tools/libxc/powerpc64/flatdevtree.c | 23
tools/libxc/powerpc64/flatdevtree.h | 2
tools/libxc/powerpc64/utils.c | 211 +++
tools/libxc/powerpc64/utils.h | 38
tools/libxc/powerpc64/xc_linux_build.c | 292 +----
tools/libxc/powerpc64/xc_prose_build.c | 323 +++++
tools/libxc/xc_linux_build.c | 16
tools/libxc/xc_load_elf.c | 28
tools/libxc/xenctrl.h | 4
tools/libxc/xenguest.h | 15
tools/libxc/xg_private.h | 1
tools/libxen/include/xen_console.h | 4
tools/libxen/include/xen_host.h | 4
tools/libxen/include/xen_host_cpu.h | 4
tools/libxen/include/xen_internal.h | 1
tools/libxen/include/xen_network.h | 4
tools/libxen/include/xen_pif.h | 4
tools/libxen/include/xen_sr.h | 4
tools/libxen/include/xen_user.h | 4
tools/libxen/include/xen_vdi.h | 4
tools/libxen/include/xen_vif.h | 4
tools/libxen/include/xen_vm.h | 289 +++--
tools/libxen/include/xen_vtpm.h | 4
tools/libxen/src/xen_console.c | 2
tools/libxen/src/xen_vif.c | 2
tools/libxen/src/xen_vm.c | 550 +++++----
tools/libxen/src/xen_vtpm.c | 2
tools/libxen/test/test_bindings.c | 76 +
tools/python/xen/lowlevel/xc/xc.c | 87 +
tools/python/xen/xend/FlatDeviceTree.py | 94 +
tools/python/xen/xend/XendAPI.py | 155 +-
tools/python/xen/xend/XendBootloader.py | 17
tools/python/xen/xend/XendConfig.py | 83 -
tools/python/xen/xend/XendDomain.py | 10
tools/python/xen/xend/XendDomainInfo.py | 309 ++---
tools/python/xen/xend/XendStorageRepository.py | 16
tools/python/xen/xend/image.py | 81 +
tools/python/xen/xend/server/DevController.py | 41
tools/python/xen/xend/server/SrvDomain.py | 9
tools/python/xen/xend/server/blkif.py | 6
tools/python/xen/xm/XenAPI.py | 4
tools/python/xen/xm/main.py | 253 ++--
tools/xenstore/xenstored_domain.c | 2
xen/arch/ia64/xen/xensetup.c | 6
xen/arch/powerpc/Makefile | 69 -
xen/arch/powerpc/backtrace.c | 34
xen/arch/powerpc/bitops.c | 124 +-
xen/arch/powerpc/boot_of.c | 621 +++++++----
xen/arch/powerpc/cmdline.c | 24
xen/arch/powerpc/crash.c | 1
xen/arch/powerpc/dart.c | 13
xen/arch/powerpc/dart_u4.c | 7
xen/arch/powerpc/domain.c | 33
xen/arch/powerpc/domain_build.c | 3
xen/arch/powerpc/domctl.c | 6
xen/arch/powerpc/exceptions.c | 34
xen/arch/powerpc/exceptions.h | 7
xen/arch/powerpc/external.c | 30
xen/arch/powerpc/gdbstub.c | 1
xen/arch/powerpc/iommu.c | 34
xen/arch/powerpc/machine_kexec.c | 6
xen/arch/powerpc/memory.c | 104 +
xen/arch/powerpc/mm.c | 235 +++-
xen/arch/powerpc/mpic.c | 127 +-
xen/arch/powerpc/mpic_init.c | 54
xen/arch/powerpc/numa.c | 1
xen/arch/powerpc/of-devtree.h | 40
xen/arch/powerpc/of-devwalk.c | 14
xen/arch/powerpc/of_handler/console.c | 12
xen/arch/powerpc/ofd_fixup.c | 12
xen/arch/powerpc/ofd_fixup_memory.c | 18
xen/arch/powerpc/papr/xlate.c | 259 ++--
xen/arch/powerpc/powerpc64/exceptions.S | 18
xen/arch/powerpc/powerpc64/io.S | 65 -
xen/arch/powerpc/powerpc64/ppc970.c | 71 -
xen/arch/powerpc/powerpc64/ppc970_machinecheck.c | 7
xen/arch/powerpc/powerpc64/ppc970_scom.c | 175 ++-
xen/arch/powerpc/powerpc64/scom.h | 39
xen/arch/powerpc/powerpc64/traps.c | 4
xen/arch/powerpc/rtas.c | 84 +
xen/arch/powerpc/rtas.h | 34
xen/arch/powerpc/setup.c | 144 +-
xen/arch/powerpc/shadow.c | 7
xen/arch/powerpc/smp.c | 192 +++
xen/arch/powerpc/smpboot.c | 29
xen/arch/powerpc/start.S | 62 +
xen/arch/powerpc/systemsim.S | 64 +
xen/arch/powerpc/time.c | 3
xen/arch/powerpc/usercopy.c | 248 ----
xen/arch/powerpc/xen.lds.S | 8
xen/arch/x86/crash.c | 23
xen/arch/x86/domain.c | 4
xen/arch/x86/domain_build.c | 8
xen/arch/x86/hvm/hvm.c | 7
xen/arch/x86/hvm/i8254.c | 41
xen/arch/x86/hvm/svm/svm.c | 12
xen/arch/x86/hvm/vmx/vmcs.c | 6
xen/arch/x86/hvm/vmx/vmx.c | 30
xen/arch/x86/mm.c | 12
xen/arch/x86/mm/shadow/common.c | 8
xen/arch/x86/mm/shadow/multi.c | 9
xen/arch/x86/numa.c | 2
xen/arch/x86/traps.c | 30
xen/common/Makefile | 2
xen/common/domain.c | 25
xen/common/elf.c | 27
xen/common/gdbstub.c | 1
xen/common/kexec.c | 86 -
xen/common/page_alloc.c | 50
xen/common/sched_credit.c | 663 +++++-------
xen/common/xencomm.c | 316 +++++
xen/drivers/char/console.c | 2
xen/include/asm-powerpc/acpi.h | 2
xen/include/asm-powerpc/cache.h | 1
xen/include/asm-powerpc/config.h | 4
xen/include/asm-powerpc/debugger.h | 70 +
xen/include/asm-powerpc/delay.h | 16
xen/include/asm-powerpc/domain.h | 5
xen/include/asm-powerpc/flushtlb.h | 1
xen/include/asm-powerpc/grant_table.h | 12
xen/include/asm-powerpc/guest_access.h | 78 -
xen/include/asm-powerpc/mach-default/irq_vectors.h | 22
xen/include/asm-powerpc/mm.h | 100 +
xen/include/asm-powerpc/msr.h | 4
xen/include/asm-powerpc/numa.h | 2
xen/include/asm-powerpc/page.h | 5
xen/include/asm-powerpc/powerpc64/string.h | 3
xen/include/asm-powerpc/processor.h | 108 +
xen/include/asm-powerpc/smp.h | 22
xen/include/asm-powerpc/spinlock.h | 33
xen/include/asm-powerpc/xenoprof.h | 26
xen/include/asm-x86/hvm/hvm.h | 7
xen/include/asm-x86/hvm/vpt.h | 2
xen/include/asm-x86/numa.h | 2
xen/include/asm-x86/page.h | 36
xen/include/asm-x86/shadow.h | 3
xen/include/asm-x86/x86_32/page-2level.h | 6
xen/include/asm-x86/x86_32/page-3level.h | 29
xen/include/asm-x86/x86_64/page.h | 6
xen/include/public/arch-ia64.h | 7
xen/include/public/arch-powerpc.h | 2
xen/include/public/domctl.h | 8
xen/include/public/io/fbif.h | 88 -
xen/include/public/io/kbdif.h | 70 -
xen/include/public/io/pciif.h | 44
xen/include/public/io/xenbus.h | 12
xen/include/public/memory.h | 2
xen/include/public/sysctl.h | 2
xen/include/public/trace.h | 2
xen/include/public/xenoprof.h | 2
xen/include/xen/elfcore.h | 4
xen/include/xen/kexec.h | 8
xen/include/xen/list.h | 387 ++++---
xen/include/xen/sched.h | 2
xen/include/xen/xencomm.h | 115 ++
192 files changed, 6225 insertions(+), 3795 deletions(-)
diff -r 1e042dde1a5f -r e17d7438e09e .hgignore
--- a/.hgignore Fri Dec 15 10:59:33 2006 -0700
+++ b/.hgignore Fri Dec 15 11:32:58 2006 -0700
@@ -53,6 +53,8 @@
^docs/user/labels\.pl$
^docs/user/user\.css$
^docs/user/user\.html$
+^docs/xen-api/vm_lifecycle.eps$
+^docs/xen-api/xenapi-datamodel-graph.eps$
^extras/mini-os/h/hypervisor-ifs$
^extras/mini-os/h/xen-public$
^extras/mini-os/mini-os\..*$
@@ -98,17 +100,15 @@
^tools/firmware/.*\.bin$
^tools/firmware/.*\.sym$
^tools/firmware/.*bios/.*bios.*\.txt$
+^tools/firmware/hvmloader/acpi/acpigen$
^tools/firmware/hvmloader/hvmloader$
^tools/firmware/hvmloader/roms\.h$
^tools/firmware/rombios/BIOS-bochs-[^/]*$
^tools/firmware/rombios/_rombios[^/]*_\.c$
^tools/firmware/rombios/rombios[^/]*\.s$
-^tools/firmware/vmxassist/acpi\.h$
^tools/firmware/vmxassist/gen$
^tools/firmware/vmxassist/offsets\.h$
-^tools/firmware/vmxassist/roms\.h$
^tools/firmware/vmxassist/vmxassist$
-^tools/firmware/vmxassist/vmxloader$
^tools/ioemu/\.pc/.*$
^tools/ioemu/config-host\.h$
^tools/ioemu/config-host\.mak$
@@ -220,10 +220,11 @@
^xen/arch/powerpc/dom0\.bin$
^xen/arch/powerpc/asm-offsets\.s$
^xen/arch/powerpc/firmware$
-^xen/arch/powerpc/firmware_image$
+^xen/arch/powerpc/firmware_image.bin$
^xen/arch/powerpc/xen\.lds$
-^xen/arch/powerpc/.xen-syms$
-^xen/arch/powerpc/xen-syms.S$
+^xen/arch/powerpc/\.xen-syms$
+^xen/arch/powerpc/xen-syms\.S$
+^xen/arch/powerpc/cmdline.dep$
^unmodified_drivers/linux-2.6/\.tmp_versions
^unmodified_drivers/linux-2.6/.*\.cmd$
^unmodified_drivers/linux-2.6/.*\.ko$
diff -r 1e042dde1a5f -r e17d7438e09e config/powerpc64.mk
--- a/config/powerpc64.mk Fri Dec 15 10:59:33 2006 -0700
+++ b/config/powerpc64.mk Fri Dec 15 11:32:58 2006 -0700
@@ -1,5 +1,7 @@ CONFIG_POWERPC := y
CONFIG_POWERPC := y
CONFIG_POWERPC_$(XEN_OS) := y
+CONFIG_XENCOMM := y
+
CFLAGS += -DELFSIZE=64
LIBDIR := lib
diff -r 1e042dde1a5f -r e17d7438e09e
linux-2.6-xen-sparse/arch/i386/kernel/fixup.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/fixup.c Fri Dec 15 10:59:33
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/fixup.c Fri Dec 15 11:32:58
2006 -0700
@@ -43,17 +43,17 @@ fastcall void do_fixup_4gb_segment(struc
char info[100];
int i;
- if (test_and_set_bit(0, &printed))
+ /* Ignore statically-linked init. */
+ if (current->tgid == 1)
return;
-
- if (current->tgid == 1) /* Ignore statically linked init */
- return;
HYPERVISOR_vm_assist(
VMASST_CMD_disable, VMASST_TYPE_4gb_segments_notify);
+ if (test_and_set_bit(0, &printed))
+ return;
+
sprintf(info, "%s (pid=%d)", current->comm, current->tgid);
-
DP("");
DP("***************************************************************");
diff -r 1e042dde1a5f -r e17d7438e09e linux-2.6-xen-sparse/arch/ia64/Kconfig
--- a/linux-2.6-xen-sparse/arch/ia64/Kconfig Fri Dec 15 10:59:33 2006 -0700
+++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig Fri Dec 15 11:32:58 2006 -0700
@@ -532,6 +532,7 @@ config XEN_BALLOON
config XEN_SKBUFF
default y
+ depends on NET
config XEN_REBOOT
default y
diff -r 1e042dde1a5f -r e17d7438e09e
linux-2.6-xen-sparse/drivers/xen/core/smpboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c Fri Dec 15 10:59:33
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c Fri Dec 15 11:32:58
2006 -0700
@@ -110,6 +110,18 @@ set_cpu_sibling_map(int cpu)
cpu_data[cpu].booted_cores = 1;
}
+static void
+remove_siblinginfo(int cpu)
+{
+ phys_proc_id[cpu] = BAD_APICID;
+ cpu_core_id[cpu] = BAD_APICID;
+
+ cpus_clear(cpu_sibling_map[cpu]);
+ cpus_clear(cpu_core_map[cpu]);
+
+ cpu_data[cpu].booted_cores = 0;
+}
+
static int xen_smp_intr_init(unsigned int cpu)
{
int rc;
@@ -358,18 +370,6 @@ static int __init initialize_cpu_present
}
core_initcall(initialize_cpu_present_map);
-static void
-remove_siblinginfo(int cpu)
-{
- phys_proc_id[cpu] = BAD_APICID;
- cpu_core_id[cpu] = BAD_APICID;
-
- cpus_clear(cpu_sibling_map[cpu]);
- cpus_clear(cpu_core_map[cpu]);
-
- cpu_data[cpu].booted_cores = 0;
-}
-
int __cpu_disable(void)
{
cpumask_t map = cpu_online_map;
@@ -432,7 +432,6 @@ int __devinit __cpu_up(unsigned int cpu)
/* This must be done before setting cpu_online_map */
set_cpu_sibling_map(cpu);
wmb();
-
rc = xen_smp_intr_init(cpu);
if (rc) {
diff -r 1e042dde1a5f -r e17d7438e09e
linux-2.6-xen-sparse/drivers/xen/fbfront/xenfb.c
--- a/linux-2.6-xen-sparse/drivers/xen/fbfront/xenfb.c Fri Dec 15 10:59:33
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/fbfront/xenfb.c Fri Dec 15 11:32:58
2006 -0700
@@ -105,7 +105,6 @@ static int xenfb_queue_full(struct xenfb
static void xenfb_update_screen(struct xenfb_info *info)
{
- unsigned long flags;
int y1, y2, x1, x2;
struct xenfb_mapping *map;
@@ -114,7 +113,7 @@ static void xenfb_update_screen(struct x
if (xenfb_queue_full(info))
return;
- spin_lock_irqsave(&info->mm_lock, flags);
+ spin_lock(&info->mm_lock);
y1 = info->y1;
y2 = info->y2;
@@ -131,7 +130,7 @@ static void xenfb_update_screen(struct x
map->faults = 0;
}
- spin_unlock_irqrestore(&info->mm_lock, flags);
+ spin_unlock(&info->mm_lock);
xenfb_do_update(info, x1, y1, x2 - x1, y2 - y1);
}
@@ -214,11 +213,9 @@ static void xenfb_refresh(struct xenfb_i
static void xenfb_refresh(struct xenfb_info *info,
int x1, int y1, int w, int h)
{
- unsigned long flags;
-
- spin_lock_irqsave(&info->mm_lock, flags);
+ spin_lock(&info->mm_lock);
__xenfb_refresh(info, x1, y1, w, h);
- spin_unlock_irqrestore(&info->mm_lock, flags);
+ spin_unlock(&info->mm_lock);
}
static void xenfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
@@ -255,14 +252,13 @@ static void xenfb_vm_close(struct vm_are
{
struct xenfb_mapping *map = vma->vm_private_data;
struct xenfb_info *info = map->info;
- unsigned long flags;
-
- spin_lock_irqsave(&info->mm_lock, flags);
+
+ spin_lock(&info->mm_lock);
if (atomic_dec_and_test(&map->map_refs)) {
list_del(&map->link);
kfree(map);
}
- spin_unlock_irqrestore(&info->mm_lock, flags);
+ spin_unlock(&info->mm_lock);
}
static struct page *xenfb_vm_nopage(struct vm_area_struct *vma,
@@ -271,14 +267,13 @@ static struct page *xenfb_vm_nopage(stru
struct xenfb_mapping *map = vma->vm_private_data;
struct xenfb_info *info = map->info;
int pgnr = (vaddr - vma->vm_start) >> PAGE_SHIFT;
- unsigned long flags;
struct page *page;
int y1, y2;
if (pgnr >= info->nr_pages)
return NOPAGE_SIGBUS;
- spin_lock_irqsave(&info->mm_lock, flags);
+ spin_lock(&info->mm_lock);
page = info->pages[pgnr];
get_page(page);
map->faults++;
@@ -288,7 +283,7 @@ static struct page *xenfb_vm_nopage(stru
if (y2 > info->fb_info->var.yres)
y2 = info->fb_info->var.yres;
__xenfb_refresh(info, 0, y1, info->fb_info->var.xres, y2 - y1);
- spin_unlock_irqrestore(&info->mm_lock, flags);
+ spin_unlock(&info->mm_lock);
if (type)
*type = VM_FAULT_MINOR;
@@ -305,7 +300,6 @@ static int xenfb_mmap(struct fb_info *fb
static int xenfb_mmap(struct fb_info *fb_info, struct vm_area_struct *vma)
{
struct xenfb_info *info = fb_info->par;
- unsigned long flags;
struct xenfb_mapping *map;
int map_pages;
@@ -329,9 +323,9 @@ static int xenfb_mmap(struct fb_info *fb
map->info = info;
atomic_set(&map->map_refs, 1);
- spin_lock_irqsave(&info->mm_lock, flags);
+ spin_lock(&info->mm_lock);
list_add(&map->link, &info->mappings);
- spin_unlock_irqrestore(&info->mm_lock, flags);
+ spin_unlock(&info->mm_lock);
vma->vm_ops = &xenfb_vm_ops;
vma->vm_flags |= (VM_DONTEXPAND | VM_RESERVED);
diff -r 1e042dde1a5f -r e17d7438e09e
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Fri Dec 15
10:59:33 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Fri Dec 15
11:32:58 2006 -0700
@@ -525,6 +525,8 @@ static void backend_changed(struct xenbu
break;
case XenbusStateInitWait:
+ if (dev->state != XenbusStateInitialising)
+ break;
if (network_connect(netdev) != 0)
break;
xenbus_switch_state(dev, XenbusStateConnected);
@@ -532,6 +534,8 @@ static void backend_changed(struct xenbu
break;
case XenbusStateClosing:
+ if (dev->state == XenbusStateClosed)
+ break;
netfront_closing(dev);
break;
}
diff -r 1e042dde1a5f -r e17d7438e09e
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Fri Dec 15
10:59:33 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Fri Dec 15
11:32:58 2006 -0700
@@ -487,6 +487,8 @@ int xenbus_probe_node(struct xen_bus_typ
if (!xendev)
return -ENOMEM;
+ xendev->state = XenbusStateInitialising;
+
/* Copy the strings into the extra space. */
tmpstring = (char *)(xendev + 1);
diff -r 1e042dde1a5f -r e17d7438e09e linux-2.6-xen-sparse/net/core/skbuff.c
--- a/linux-2.6-xen-sparse/net/core/skbuff.c Fri Dec 15 10:59:33 2006 -0700
+++ b/linux-2.6-xen-sparse/net/core/skbuff.c Fri Dec 15 11:32:58 2006 -0700
@@ -1875,7 +1875,7 @@ struct sk_buff *skb_segment(struct sk_bu
do {
struct sk_buff *nskb;
skb_frag_t *frag;
- int hsize, nsize;
+ int hsize;
int k;
int size;
@@ -1886,11 +1886,10 @@ struct sk_buff *skb_segment(struct sk_bu
hsize = skb_headlen(skb) - offset;
if (hsize < 0)
hsize = 0;
- nsize = hsize + doffset;
- if (nsize > len + doffset || !sg)
- nsize = len + doffset;
-
- nskb = alloc_skb(nsize + headroom, GFP_ATOMIC);
+ if (hsize > len || !sg)
+ hsize = len;
+
+ nskb = alloc_skb(hsize + doffset + headroom, GFP_ATOMIC);
if (unlikely(!nskb))
goto err;
diff -r 1e042dde1a5f -r e17d7438e09e
patches/linux-2.6.16.33/net-gso-6-linear-segmentation.patch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.16.33/net-gso-6-linear-segmentation.patch Fri Dec
15 11:32:58 2006 -0700
@@ -0,0 +1,26 @@
+diff -Naru a/net/core/skbuff.c b/net/core/skbuff.c
+--- a/net/core/skbuff.c 2006-12-14 09:32:04 -08:00
++++ b/net/core/skbuff.c 2006-12-14 09:32:04 -08:00
+@@ -1946,7 +1946,7 @@
+ do {
+ struct sk_buff *nskb;
+ skb_frag_t *frag;
+- int hsize, nsize;
++ int hsize;
+ int k;
+ int size;
+
+@@ -1957,11 +1957,10 @@
+ hsize = skb_headlen(skb) - offset;
+ if (hsize < 0)
+ hsize = 0;
+- nsize = hsize + doffset;
+- if (nsize > len + doffset || !sg)
+- nsize = len + doffset;
++ if (hsize > len || !sg)
++ hsize = len;
+
+- nskb = alloc_skb(nsize + headroom, GFP_ATOMIC);
++ nskb = alloc_skb(hsize + doffset + headroom, GFP_ATOMIC);
+ if (unlikely(!nskb))
+ goto err;
diff -r 1e042dde1a5f -r e17d7438e09e patches/linux-2.6.16.33/series
--- a/patches/linux-2.6.16.33/series Fri Dec 15 10:59:33 2006 -0700
+++ b/patches/linux-2.6.16.33/series Fri Dec 15 11:32:58 2006 -0700
@@ -17,6 +17,7 @@ net-gso-3-fix-errorcheck.patch
net-gso-3-fix-errorcheck.patch
net-gso-4-kill-warnon.patch
net-gso-5-rcv-mss.patch
+net-gso-6-linear-segmentation.patch
pci-mmconfig-fix-from-2.6.17.patch
pmd-shared.patch
rcu_needs_cpu.patch
diff -r 1e042dde1a5f -r e17d7438e09e tools/Rules.mk
--- a/tools/Rules.mk Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/Rules.mk Fri Dec 15 11:32:58 2006 -0700
@@ -18,6 +18,10 @@ CFLAGS += $(shell getconf LFS_CFLAGS)
CFLAGS += $(shell getconf LFS_CFLAGS)
CFLAGS += -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE
LDFLAGS += $(shell getconf LFS_LDFLAGS)
+
+# 32-bit x86 does not perform well with -ve segment accesses on Xen.
+CFLAGS-$(CONFIG_X86_32) += $(call cc-option,$(CC),-mno-tls-direct-seg-refs)
+CFLAGS += $(CFLAGS-y)
%.opic: %.c
$(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $<
diff -r 1e042dde1a5f -r e17d7438e09e tools/blktap/drivers/blktapctrl.c
--- a/tools/blktap/drivers/blktapctrl.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/blktap/drivers/blktapctrl.c Fri Dec 15 11:32:58 2006 -0700
@@ -57,6 +57,8 @@
#include "blktapctrl.h"
#include "tapdisk.h"
+#define PIDFILE "/var/run/blktapctrl.pid"
+
#define NUM_POLL_FDS 2
#define MSG_SIZE 4096
#define MAX_TIMEOUT 10
@@ -622,6 +624,42 @@ static void print_drivers(void)
DPRINTF("Found driver: [%s]\n",dtypes[i]->name);
}
+static void write_pidfile(long pid)
+{
+ char buf[100];
+ int len;
+ int fd;
+ int flags;
+
+ fd = open(PIDFILE, O_RDWR | O_CREAT, 0600);
+ if (fd == -1) {
+ DPRINTF("Opening pid file failed (%d)\n", errno);
+ exit(1);
+ }
+
+ /* We exit silently if daemon already running. */
+ if (lockf(fd, F_TLOCK, 0) == -1)
+ exit(0);
+
+ /* Set FD_CLOEXEC, so that tapdisk doesn't get this file
+ descriptor. */
+ if ((flags = fcntl(fd, F_GETFD)) == -1) {
+ DPRINTF("F_GETFD failed (%d)\n", errno);
+ exit(1);
+ }
+ flags |= FD_CLOEXEC;
+ if (fcntl(fd, F_SETFD, flags) == -1) {
+ DPRINTF("F_SETFD failed (%d)\n", errno);
+ exit(1);
+ }
+
+ len = sprintf(buf, "%ld\n", pid);
+ if (write(fd, buf, len) != len) {
+ DPRINTF("Writing pid file failed (%d)\n", errno);
+ exit(1);
+ }
+}
+
int main(int argc, char *argv[])
{
char *devname;
@@ -681,6 +719,7 @@ int main(int argc, char *argv[])
ioctl(ctlfd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_INTERPOSE );
process = getpid();
+ write_pidfile(process);
ret = ioctl(ctlfd, BLKTAP_IOCTL_SENDPID, process );
/*Static pollhooks*/
@@ -716,3 +755,13 @@ int main(int argc, char *argv[])
closelog();
return -1;
}
+
+/*
+ * Local variables:
+ * c-file-style: "linux"
+ * indent-tabs-mode: t
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff -r 1e042dde1a5f -r e17d7438e09e tools/blktap/drivers/block-qcow.c
--- a/tools/blktap/drivers/block-qcow.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/blktap/drivers/block-qcow.c Fri Dec 15 11:32:58 2006 -0700
@@ -74,8 +74,9 @@ struct pending_aio {
#define XEN_MAGIC (('X' << 24) | ('E' << 16) | ('N' << 8) | 0xfb)
#define QCOW_VERSION 1
-#define QCOW_CRYPT_NONE 0
-#define QCOW_CRYPT_AES 1
+#define QCOW_CRYPT_NONE 0x00
+#define QCOW_CRYPT_AES 0x01
+#define QCOW_SPARSE_FILE 0x02
#define QCOW_OFLAG_COMPRESSED (1LL << 63)
@@ -101,6 +102,7 @@ typedef struct QCowHeader_ext {
uint32_t xmagic;
uint32_t cksum;
uint32_t min_cluster_alloc;
+ uint32_t flags;
} QCowHeader_ext;
#define L2_CACHE_SIZE 16 /*Fixed allocation in Qemu*/
@@ -119,6 +121,7 @@ struct tdqcow_state {
int cluster_alloc; /*Blktap fix for allocating full
*extents*/
int min_cluster_alloc; /*Blktap historical extent alloc*/
+ int sparse; /*Indicates whether to preserve
sparseness*/
int l2_bits; /*Size of L2 table entry*/
int l2_size; /*Full table size*/
int l1_size; /*L1 table size*/
@@ -413,6 +416,37 @@ static void encrypt_sectors(struct tdqco
}
}
+static int qtruncate(int fd, off_t length, int sparse)
+{
+ int current, ret, i;
+ int sectors = length/DEFAULT_SECTOR_SIZE;
+ struct stat st;
+ char buf[DEFAULT_SECTOR_SIZE];
+
+ /* If length is greater than the current file len
+ * we synchronously write zeroes to the end of the
+ * file, otherwise we truncate the length down
+ */
+ memset(buf, 0x00, DEFAULT_SECTOR_SIZE);
+ ret = fstat(fd, &st);
+ if((ret == -1) || S_ISBLK(st.st_mode))
+ return -1;
+
+ if(st.st_size < length) {
+ /*We are extending the file*/
+ lseek(fd, 0, SEEK_END);
+ for (i = 0; i < sectors; i++ ) {
+ ret = write(fd, buf, DEFAULT_SECTOR_SIZE);
+ if (ret != DEFAULT_SECTOR_SIZE)
+ return -1;
+ }
+
+ } else if(sparse && (st.st_size > length))
+ ftruncate(fd, length);
+
+ return 1;
+}
+
/* 'allocate' is:
*
@@ -463,8 +497,8 @@ static uint64_t get_cluster_offset(struc
/*Truncate file for L2 table
*(initialised to zero in case we crash)*/
- ftruncate(s->fd, l2_offset + (s->l2_size * sizeof(uint64_t)));
- s->fd_end += (s->l2_size * sizeof(uint64_t));
+ qtruncate(s->fd, l2_offset + (s->l2_size * sizeof(uint64_t)),
s->sparse);
+ s->fd_end = l2_offset + (s->l2_size * sizeof(uint64_t));
/*Update the L1 table entry on disk
* (for O_DIRECT we write 4KByte blocks)*/
@@ -483,7 +517,7 @@ static uint64_t get_cluster_offset(struc
*/
lseek(s->fd, s->l1_table_offset + (l1_sector << 12), SEEK_SET);
if (write(s->fd, tmp_ptr, 4096) != 4096)
- return 0;
+ return 0;
free(tmp_ptr);
new_l2_table = 1;
@@ -530,8 +564,8 @@ cache_miss:
(s->l2_size * sizeof(uint64_t));
cluster_offset = (cluster_offset + s->cluster_size - 1)
& ~(s->cluster_size - 1);
- ftruncate(s->fd, cluster_offset +
- (s->cluster_size * s->l2_size));
+ qtruncate(s->fd, cluster_offset +
+ (s->cluster_size * s->l2_size), s->sparse);
s->fd_end = cluster_offset +
(s->cluster_size * s->l2_size);
for (i = 0; i < s->l2_size; i++) {
@@ -542,7 +576,7 @@ cache_miss:
lseek(s->fd, l2_offset, SEEK_SET);
if (write(s->fd, l2_table, s->l2_size * sizeof(uint64_t)) !=
- s->l2_size * sizeof(uint64_t))
+ s->l2_size * sizeof(uint64_t))
return 0;
} else {
lseek(s->fd, l2_offset, SEEK_SET);
@@ -573,7 +607,7 @@ found:
overwritten */
if (decompress_cluster(s, cluster_offset) < 0)
return 0;
- cluster_offset = lseek(s->fd, 0, SEEK_END);
+ cluster_offset = lseek(s->fd, s->fd_end, SEEK_SET);
cluster_offset = (cluster_offset + s->cluster_size - 1)
& ~(s->cluster_size - 1);
/* write the cluster content - not asynchronous */
@@ -583,14 +617,15 @@ found:
return -1;
} else {
/* allocate a new cluster */
- cluster_offset = lseek(s->fd, 0, SEEK_END);
+ cluster_offset = lseek(s->fd, s->fd_end, SEEK_SET);
if (allocate == 1) {
/* round to cluster size */
cluster_offset =
(cluster_offset + s->cluster_size - 1)
& ~(s->cluster_size - 1);
- ftruncate(s->fd, cluster_offset +
- s->cluster_size);
+ qtruncate(s->fd, cluster_offset +
+ s->cluster_size, s->sparse);
+ s->fd_end = (cluster_offset + s->cluster_size);
/* if encrypted, we must initialize the cluster
content which won't be written */
if (s->crypt_method &&
@@ -633,9 +668,9 @@ found:
DPRINTF("ERROR allocating memory for L1 table\n");
}
memcpy(tmp_ptr2, l2_ptr, 4096);
- aio_lock(s, offset >> 9);
- async_write(s, s->fd, 4096, l2_offset + (l2_sector << 12),
- tmp_ptr2, 0, -2, offset >> 9, 0, NULL);
+ lseek(s->fd, l2_offset + (l2_sector << 12), SEEK_SET);
+ write(s->fd, tmp_ptr2, 4096);
+ free(tmp_ptr2);
}
return cluster_offset;
}
@@ -733,6 +768,7 @@ int tdqcow_open (struct td_state *bs, co
QCowHeader *header;
QCowHeader_ext *exthdr;
uint32_t cksum;
+ uint64_t final_cluster = 0;
DPRINTF("QCOW: Opening %s\n",name);
/* set up a pipe so that we can hand back a poll fd that won't fire.*/
@@ -766,7 +802,7 @@ int tdqcow_open (struct td_state *bs, co
be64_to_cpus(&header->size);
be32_to_cpus(&header->crypt_method);
be64_to_cpus(&header->l1_table_offset);
-
+
if (header->magic != QCOW_MAGIC || header->version > QCOW_VERSION)
goto fail;
if (header->size <= 1 || header->cluster_bits < 9)
@@ -798,6 +834,7 @@ int tdqcow_open (struct td_state *bs, co
}
ret = posix_memalign((void **)&s->l1_table, 4096, l1_table_size);
if (ret != 0) goto fail;
+
memset(s->l1_table, 0x00, l1_table_size);
DPRINTF("L1 Table offset detected: %llu, size %d (%d)\n",
@@ -808,10 +845,13 @@ int tdqcow_open (struct td_state *bs, co
lseek(fd, s->l1_table_offset, SEEK_SET);
if (read(fd, s->l1_table, l1_table_size) != l1_table_size)
goto fail;
-/* for(i = 0;i < s->l1_size; i++) {
+
+ for(i = 0;i < s->l1_size; i++) {
//be64_to_cpus(&s->l1_table[i]);
- DPRINTF("L1[%d] => %llu\n", i, s->l1_table[i]);
- }*/
+ //DPRINTF("L1[%d] => %llu\n", i, s->l1_table[i]);
+ if (s->l1_table[i] > final_cluster)
+ final_cluster = s->l1_table[i];
+ }
/* alloc L2 cache */
size = s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t);
@@ -870,10 +910,14 @@ int tdqcow_open (struct td_state *bs, co
/*Finally check the L1 table cksum*/
be32_to_cpus(&exthdr->cksum);
cksum = gen_cksum((char *)s->l1_table, s->l1_size *
sizeof(uint64_t));
- if(exthdr->cksum != cksum)
+ if(exthdr->cksum != cksum) {
goto end_xenhdr;
+ }
be32_to_cpus(&exthdr->min_cluster_alloc);
+ be32_to_cpus(&exthdr->flags);
+ if (exthdr->flags & QCOW_SPARSE_FILE)
+ s->sparse = 1;
s->min_cluster_alloc = exthdr->min_cluster_alloc;
}
@@ -882,7 +926,8 @@ int tdqcow_open (struct td_state *bs, co
DPRINTF("Unable to initialise AIO state\n");
goto fail;
}
- s->fd_end = lseek(s->fd, 0, SEEK_END);
+ s->fd_end = (final_cluster == 0 ? (s->l1_table_offset + l1_table_size)
:
+ (final_cluster + s->cluster_size));
return 0;
@@ -1172,7 +1217,7 @@ int qcow_create(const char *filename, ui
QCowHeader header;
QCowHeader_ext exthdr;
char backing_filename[1024], *ptr;
- uint64_t tmp, size;
+ uint64_t tmp, size, total_length;
struct stat st;
DPRINTF("Qcow_create: size %llu\n",(long long unsigned)total_size);
@@ -1260,7 +1305,7 @@ int qcow_create(const char *filename, ui
DPRINTF("L1 Table offset: %d, size %d\n",
header_size,
(int)(l1_size * sizeof(uint64_t)));
- if (flags) {
+ if (flags & QCOW_CRYPT_AES) {
header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
} else {
header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
@@ -1270,8 +1315,26 @@ int qcow_create(const char *filename, ui
exthdr.cksum = cpu_to_be32(gen_cksum(ptr, l1_size * sizeof(uint64_t)));
printf("Created cksum: %d\n",exthdr.cksum);
free(ptr);
+
+ /*adjust file length to 4 KByte boundary*/
+ length = header_size + l1_size * sizeof(uint64_t);
+ if (length % 4096 > 0) {
+ length = ((length >> 12) + 1) << 12;
+ qtruncate(fd, length, 0);
+ DPRINTF("Adjusted filelength to %d for 4 "
+ "Kbyte alignment\n",length);
+ }
+
+ if (!(flags & QCOW_SPARSE_FILE)) {
+ /*Filesize is length + l1_size * (1 << s->l2_bits) +
(size*512)*/
+ total_length = length + (l1_size * (1 << 9)) + (size * 512);
+ qtruncate(fd, total_length, 0);
+ printf("File truncated to length %"PRIu64"\n",total_length);
+ }
+ exthdr.flags = cpu_to_be32(flags);
/* write all the data */
+ lseek(fd, 0, SEEK_SET);
ret += write(fd, &header, sizeof(header));
ret += write(fd, &exthdr, sizeof(exthdr));
if (backing_file) {
@@ -1283,15 +1346,6 @@ int qcow_create(const char *filename, ui
ret += write(fd, &tmp, sizeof(tmp));
}
- /*adjust file length to 4 KByte boundary*/
- length = header_size + l1_size * sizeof(uint64_t);
- if (length % 4096 > 0) {
- length = ((length >> 12) + 1) << 12;
- ftruncate(fd, length);
- DPRINTF("Adjusted filelength to %d for 4 "
- "Kbyte alignment\n",length);
- }
-
close(fd);
return 0;
@@ -1306,7 +1360,7 @@ int qcow_make_empty(struct td_state *bs)
lseek(s->fd, s->l1_table_offset, SEEK_SET);
if (write(s->fd, s->l1_table, l1_length) < 0)
return -1;
- ftruncate(s->fd, s->l1_table_offset + l1_length);
+ qtruncate(s->fd, s->l1_table_offset + l1_length, s->sparse);
memset(s->l2_cache, 0, s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
memset(s->l2_cache_offsets, 0, L2_CACHE_SIZE * sizeof(uint64_t));
diff -r 1e042dde1a5f -r e17d7438e09e tools/blktap/drivers/qcow-create.c
--- a/tools/blktap/drivers/qcow-create.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/blktap/drivers/qcow-create.c Fri Dec 15 11:32:58 2006 -0700
@@ -47,32 +47,69 @@
#define DFPRINTF(_f, _a...) ((void)0)
#endif
+#define QCOW_NONSPARSE_FILE 0x00
+#define QCOW_SPARSE_FILE 0x02
+#define MAX_NAME_LEN 1000
+
+void help(void)
+{
+ fprintf(stderr, "Qcow-utils: v1.0.0\n");
+ fprintf(stderr,
+ "usage: qcow-create [-h help] [-p reserve] <SIZE(MB)>
<FILENAME> "
+ "[<BACKING_FILENAME>]\n");
+ exit(-1);
+}
int main(int argc, char *argv[])
{
- int ret = -1;
+ int ret = -1, c, backed = 0;
+ int flags = QCOW_SPARSE_FILE;
uint64_t size;
+ char filename[MAX_NAME_LEN], bfilename[MAX_NAME_LEN];
- if ( (argc < 3) || (argc > 4) ) {
- fprintf(stderr, "Qcow-utils: v1.0.0\n");
- fprintf(stderr,
- "usage: %s <SIZE(MB)> <FILENAME> "
- "[<BACKING_FILENAME>]\n",
- argv[0]);
+ for(;;) {
+ c = getopt(argc, argv, "hp");
+ if (c == -1)
+ break;
+ switch(c) {
+ case 'h':
+ help();
+ exit(0);
+ break;
+ case 'p':
+ flags = QCOW_NONSPARSE_FILE;
+ break;
+ }
+ }
+
+ printf("Optind %d, argc %d\n", optind, argc);
+ if ( !(optind == (argc - 2) || optind == (argc - 3)) )
+ help();
+
+ size = atoi(argv[optind++]);
+ size = size << 20;
+
+ if (snprintf(filename, MAX_NAME_LEN, "%s",argv[optind++]) >=
+ MAX_NAME_LEN) {
+ fprintf(stderr,"Device name too long\n");
exit(-1);
}
- size = atoi(argv[1]);
- size = size << 20;
- DFPRINTF("Creating file size %llu\n",(long long unsigned)size);
- switch(argc) {
- case 3:
- ret = qcow_create(argv[2],size,NULL,0);
- break;
- case 4:
- ret = qcow_create(argv[2],size,argv[3],0);
- break;
+ if (optind != argc) {
+ backed = 1;
+ if (snprintf(bfilename, MAX_NAME_LEN, "%s",argv[optind++]) >=
+ MAX_NAME_LEN) {
+ fprintf(stderr,"Device name too long\n");
+ exit(-1);
+ }
}
+
+ DFPRINTF("Creating file size %llu, name %s\n",(long long unsigned)size,
filename);
+ if (!backed)
+ ret = qcow_create(filename,size,NULL,flags);
+ else
+ ret = qcow_create(filename,size,bfilename,flags);
+
if (ret < 0) DPRINTF("Unable to create QCOW file\n");
else DPRINTF("QCOW file successfully created\n");
diff -r 1e042dde1a5f -r e17d7438e09e tools/check/check_crypto_lib
--- a/tools/check/check_crypto_lib Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/check/check_crypto_lib Fri Dec 15 11:32:58 2006 -0700
@@ -1,11 +1,14 @@
-#!/bin/bash
+#!/bin/sh
# CHECK-BUILD CHECK-INSTALL
-function error {
- echo
- echo " *** Check for crypto library FAILED"
- exit 1
-}
+RC=0
set -e
-ldconfig -p | grep -q libcrypto.so || error
+ldconfig -v 2>&1 | grep -q libcrypto.so || RC=1
+
+if test ${RC} -ne 0; then
+ echo
+ echo " *** Check for crypto library FAILED"
+fi
+
+exit ${RC}
diff -r 1e042dde1a5f -r e17d7438e09e tools/check/check_openssl_devel
--- a/tools/check/check_openssl_devel Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/check/check_openssl_devel Fri Dec 15 11:32:58 2006 -0700
@@ -1,11 +1,14 @@
-#!/bin/bash
+#!/bin/sh
# CHECK-BUILD
-function error {
- echo
- echo " *** Check for openssl headers FAILED"
- exit 1
-}
+RC=0
set -e
-[ -e /usr/include/openssl/md5.h ] || error
+test -r /usr/include/openssl/md5.h || RC=1
+
+if test ${RC} -ne 0; then
+ echo
+ echo " *** Check for openssl headers FAILED"
+fi
+
+exit ${RC}
diff -r 1e042dde1a5f -r e17d7438e09e tools/check/check_python
--- a/tools/check/check_python Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/check/check_python Fri Dec 15 11:32:58 2006 -0700
@@ -3,7 +3,10 @@
RC=0
-python -V 2>&1 | cut -d ' ' -f 2 | grep -q '^2.[2345]' || RC=1
+python -c '
+import sys
+sys.exit(sys.version_info[0] < 2 or sys.version_info[1] < 2)
+' || RC=1
if test ${RC} -ne 0; then
echo
diff -r 1e042dde1a5f -r e17d7438e09e tools/check/check_python_devel
--- a/tools/check/check_python_devel Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/check/check_python_devel Fri Dec 15 11:32:58 2006 -0700
@@ -1,11 +1,7 @@
-#!/bin/bash
+#!/bin/sh
# CHECK-BUILD
-function error {
- echo
- echo " *** Check for python development environment FAILED"
- exit 1
-}
+RC=0
python -c '
import os.path, sys
@@ -13,4 +9,11 @@ for p in sys.path:
if os.path.exists(p + "/config/Makefile"):
sys.exit(0)
sys.exit(1)
-' || error
+' || RC=1
+
+if test ${RC} -ne 0; then
+ echo
+ echo " *** Check for python development environment FAILED"
+fi
+
+exit ${RC}
diff -r 1e042dde1a5f -r e17d7438e09e tools/check/check_python_xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/check/check_python_xml Fri Dec 15 11:32:58 2006 -0700
@@ -0,0 +1,8 @@
+#!/bin/sh
+# CHECK-INSTALL
+
+python -c 'import xml.dom.minidom' 2>/dev/null || {
+ echo
+ echo " *** Check for python-xml package FAILED"
+ exit 1
+}
diff -r 1e042dde1a5f -r e17d7438e09e tools/check/check_udev
--- a/tools/check/check_udev Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/check/check_udev Fri Dec 15 11:32:58 2006 -0700
@@ -1,16 +1,34 @@
-#!/bin/bash
+#!/bin/sh
# CHECK-INSTALL
-function error {
- echo
- echo ' *** Check for udev/hotplug FAILED'
- exit 1
-}
-[ -x "$(which udevinfo)" ] && \
- UDEV_VERSION=$(udevinfo -V | sed -e 's/^[^0-9]*
\([0-9]\{1,\}\)[^0-9]\{0,\}/\1/')
+RC=0
-if [ -n "$UDEV_VERSION" ] && [ $UDEV_VERSION -ge 059 ]; then
- exit 0
+case ${OS} in
+OpenBSD|NetBSD|FreeBSD)
+ TOOL="vnconfig"
+ which ${TOOL} 1>/dev/null 2>&1 || RC=1
+ ;;
+Linux)
+ TOOL="udevinfo"
+ UDEV_VERSION="0"
+ test -x "$(which ${TOOL})" && \
+ UDEV_VERSION=$(${TOOL} -V | sed -e 's/^[^0-9]*
\([0-9]\{1,\}\)[^0-9]\{0,\}/\1/')
+ if test "${UDEV_VERSION}" -ge 059; then
+ RC=0
+ else
+ TOOL="hotplug"
+ which ${TOOL} 1>/dev/null 2>&1 || RC=1
+ fi
+ ;;
+*)
+ TOOL=""
+ echo "Unknown OS" && RC=1
+ ;;
+esac
+
+if test ${RC} -ne 0; then
+ echo
+ echo ' *** Check for ${TOOL} FAILED'
fi
-which hotplug 1>/dev/null 2>&1 || error
+exit ${RC}
diff -r 1e042dde1a5f -r e17d7438e09e tools/check/check_x11_devel
--- a/tools/check/check_x11_devel Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/check/check_x11_devel Fri Dec 15 11:32:58 2006 -0700
@@ -1,11 +1,15 @@
-#!/bin/bash
+#!/bin/sh
# CHECK-BUILD
-function error {
- echo
- echo " *** Check for x11 headers FAILED"
- exit 1
-}
+RC=0
set -e
-[ -e /usr/include/X11/keysymdef.h ] || error
+test -r /usr/include/X11/keysymdef.h || \
+test -r /usr/X11R6/include/X11/keysymdef.h || RC=1
+
+if test ${RC} -ne 0; then
+ echo
+ echo " *** Check for x11 headers FAILED"
+fi
+
+exit ${RC}
diff -r 1e042dde1a5f -r e17d7438e09e tools/examples/external-device-migrate
--- a/tools/examples/external-device-migrate Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/examples/external-device-migrate Fri Dec 15 11:32:58 2006 -0700
@@ -60,8 +60,8 @@ function evaluate_params()
-step) step=$2; shift 2;;
-host) host=$2; shift 2;;
-domname) domname=$2; shift 2;;
- -type) type=$2; shift 2;;
- -subtype) subtype=$2; shift 2;;
+ -type) typ=$2; shift 2;;
+ -subtype) stype=$2; shift 2;;
-recover) recover=1; shift;;
-help) ext_dev_migrate_usage; exit 0;;
*) break;;
diff -r 1e042dde1a5f -r e17d7438e09e tools/ioemu/target-i386-dm/exec-dm.c
--- a/tools/ioemu/target-i386-dm/exec-dm.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/ioemu/target-i386-dm/exec-dm.c Fri Dec 15 11:32:58 2006 -0700
@@ -439,7 +439,12 @@ void cpu_physical_memory_rw(target_phys_
int l, io_index;
uint8_t *ptr;
uint32_t val;
-
+
+#if defined(__i386__) || defined(__x86_64__)
+ static pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+ pthread_mutex_lock(&mutex);
+#endif
+
while (len > 0) {
/* How much can we copy before the next page boundary? */
l = TARGET_PAGE_SIZE - (addr & ~TARGET_PAGE_MASK);
@@ -504,6 +509,10 @@ void cpu_physical_memory_rw(target_phys_
buf += l;
addr += l;
}
+
+#if defined(__i386__) || defined(__x86_64__)
+ pthread_mutex_unlock(&mutex);
+#endif
}
#endif
diff -r 1e042dde1a5f -r e17d7438e09e tools/ioemu/vl.c
--- a/tools/ioemu/vl.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/ioemu/vl.c Fri Dec 15 11:32:58 2006 -0700
@@ -5820,8 +5820,8 @@ static int qemu_map_cache_init(unsigned
if (nr_pages < max_pages)
max_pages = nr_pages;
- nr_buckets = (max_pages << PAGE_SHIFT) >> MCACHE_BUCKET_SHIFT;
-
+ nr_buckets = max_pages + (1UL << (MCACHE_BUCKET_SHIFT - PAGE_SHIFT)) - 1;
+ nr_buckets >>= (MCACHE_BUCKET_SHIFT - PAGE_SHIFT);
fprintf(logfile, "qemu_map_cache_init nr_buckets = %lx\n", nr_buckets);
mapcache_entry = malloc(nr_buckets * sizeof(struct map_cache));
@@ -5857,8 +5857,7 @@ uint8_t *qemu_map_cache(target_phys_addr
entry = &mapcache_entry[address_index % nr_buckets];
- if (entry->vaddr_base == NULL || entry->paddr_index != address_index)
- {
+ if (entry->vaddr_base == NULL || entry->paddr_index != address_index) {
/* We need to remap a bucket. */
uint8_t *vaddr_base;
unsigned long pfns[MCACHE_BUCKET_SIZE >> PAGE_SHIFT];
diff -r 1e042dde1a5f -r e17d7438e09e tools/libaio/src/syscall-ppc.h
--- a/tools/libaio/src/syscall-ppc.h Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libaio/src/syscall-ppc.h Fri Dec 15 11:32:58 2006 -0700
@@ -1,3 +1,6 @@
+#include <asm/unistd.h>
+#include <errno.h>
+
#define __NR_io_setup 227
#define __NR_io_destroy 228
#define __NR_io_getevents 229
@@ -9,7 +12,7 @@
* "sc; bnslr" sequence) and CR (where only CR0.SO is clobbered to signal
* an error return status).
*/
-
+#ifndef __syscall_nr
#define __syscall_nr(nr, type, name, args...) \
unsigned long __sc_ret, __sc_err; \
{ \
@@ -37,6 +40,7 @@
} \
if (__sc_err & 0x10000000) return -((int)__sc_ret); \
return (type) __sc_ret
+#endif
#define __sc_loadargs_0(name, dummy...)
\
__sc_0 = __NR_##name
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/ia64/xc_ia64_hvm_build.c
--- a/tools/libxc/ia64/xc_ia64_hvm_build.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxc/ia64/xc_ia64_hvm_build.c Fri Dec 15 11:32:58 2006 -0700
@@ -660,8 +660,14 @@ setup_guest(int xc_handle, uint32_t dom,
goto error_out;
}
- // Get number of vcpus, stored by pyxc_hvm_build()
- xc_get_hvm_param(xc_handle, dom, HVM_PARAM_VCPUS, &vcpus);
+ domctl.cmd = XEN_DOMCTL_getdomaininfo;
+ domctl.domain = (domid_t)dom;
+ if (xc_domctl(xc_handle, &domctl) < 0) {
+ PERROR("Could not get info on domain");
+ goto error_out;
+ }
+
+ vcpus = domctl.u.getdomaininfo.max_vcpu_id + 1;
// Hand-off state passed to guest firmware
if (xc_ia64_build_hob(xc_handle, dom, dom_memsize, vcpus) < 0) {
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/powerpc64/Makefile
--- a/tools/libxc/powerpc64/Makefile Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxc/powerpc64/Makefile Fri Dec 15 11:32:58 2006 -0700
@@ -1,4 +1,6 @@ GUEST_SRCS-y += powerpc64/xc_linux_build
+GUEST_SRCS-y += powerpc64/flatdevtree.c
GUEST_SRCS-y += powerpc64/xc_linux_build.c
-GUEST_SRCS-y += powerpc64/flatdevtree.c
+GUEST_SRCS-y += powerpc64/xc_prose_build.c
+GUEST_SRCS-y += powerpc64/utils.c
CTRL_SRCS-y += powerpc64/xc_memory.c
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/powerpc64/flatdevtree.c
--- a/tools/libxc/powerpc64/flatdevtree.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxc/powerpc64/flatdevtree.c Fri Dec 15 11:32:58 2006 -0700
@@ -220,6 +220,29 @@ void ft_add_rsvmap(struct ft_cxt *cxt, u
cxt->p_anchor = cxt->pres + 16; /* over the terminator */
}
+int ft_set_rsvmap(void *bphp, int m, u64 physaddr, u64 size)
+{
+ const struct boot_param_header *bph = bphp;
+ u64 *p_rsvmap = (u64 *)
+ ((char *)bph + be32_to_cpu(bph->off_mem_rsvmap));
+ u32 i;
+
+ for (i = 0;; i++) {
+ u64 addr, sz;
+
+ addr = be64_to_cpu(p_rsvmap[i * 2]);
+ sz = be64_to_cpu(p_rsvmap[i * 2 + 1]);
+ if (addr == 0 && size == 0)
+ break;
+ if (m == i) {
+ p_rsvmap[i * 2] = cpu_to_be64(physaddr);
+ p_rsvmap[i * 2 + 1] = cpu_to_be64(size);
+ return 0;
+ }
+ }
+ return -1;
+}
+
void ft_begin_tree(struct ft_cxt *cxt)
{
cxt->p_begin = cxt->p_anchor;
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/powerpc64/flatdevtree.h
--- a/tools/libxc/powerpc64/flatdevtree.h Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxc/powerpc64/flatdevtree.h Fri Dec 15 11:32:58 2006 -0700
@@ -66,8 +66,10 @@ void ft_prop_int(struct ft_cxt *cxt, con
void ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val);
void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size);
void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size);
+int ft_set_rsvmap(void *bphp, int m, u64 physaddr, u64 size);
void ft_dump_blob(const void *bphp);
+void ft_backtrack_node(struct ft_cxt *cxt);
void ft_merge_blob(struct ft_cxt *cxt, void *blob);
void *ft_find_node(const void *bphp, const char *srch_path);
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/powerpc64/utils.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/powerpc64/utils.c Fri Dec 15 11:32:58 2006 -0700
@@ -0,0 +1,211 @@
+/*
+ * 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.
+ *
+ * Copyright (C) IBM Corporation 2006
+ *
+ * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
+ * Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <inttypes.h>
+
+#include <xen/xen.h>
+#include <xen/memory.h>
+#include <xc_private.h>
+#include <xg_private.h>
+#include <xenctrl.h>
+
+#include "flatdevtree_env.h"
+#include "flatdevtree.h"
+#include "utils.h"
+
+unsigned long get_rma_pages(void *devtree)
+{
+ void *rma;
+ uint64_t rma_reg[2];
+ int rc;
+
+ rma = ft_find_node(devtree, "/memory@0");
+ if (rma == NULL) {
+ DPRINTF("couldn't find /memory@0\n");
+ return 0;
+ }
+ rc = ft_get_prop(devtree, rma, "reg", rma_reg, sizeof(rma_reg));
+ if (rc < 0) {
+ DPRINTF("couldn't get /memory@0/reg\n");
+ return 0;
+ }
+ if (rma_reg[0] != 0) {
+ DPRINTF("RMA did not start at 0\n");
+ return 0;
+ }
+ return rma_reg[1] >> PAGE_SHIFT;
+}
+
+int get_rma_page_array(int xc_handle, int domid, xen_pfn_t **page_array,
+ unsigned long nr_pages)
+{
+ int rc;
+ int i;
+ xen_pfn_t *p;
+
+ *page_array = malloc(nr_pages * sizeof(xen_pfn_t));
+ if (*page_array == NULL) {
+ perror("malloc");
+ return -1;
+ }
+
+ DPRINTF("xc_get_pfn_list\n");
+ /* We know that the RMA is machine contiguous so lets just get the
+ * first MFN and fill the rest in ourselves */
+ rc = xc_get_pfn_list(xc_handle, domid, *page_array, 1);
+ if (rc == -1) {
+ perror("Could not get the page frame list");
+ return -1;
+ }
+ p = *page_array;
+ for (i = 1; i < nr_pages; i++)
+ p[i] = p[i - 1] + 1;
+ return 0;
+}
+
+int install_image(
+ int xc_handle,
+ int domid,
+ xen_pfn_t *page_array,
+ void *image,
+ unsigned long paddr,
+ unsigned long size)
+{
+ uint8_t *img = image;
+ int i;
+ int rc = 0;
+
+ if (paddr & ~PAGE_MASK) {
+ printf("*** unaligned address\n");
+ return -1;
+ }
+
+ for (i = 0; i < size; i += PAGE_SIZE) {
+ void *page = img + i;
+ xen_pfn_t pfn = (paddr + i) >> PAGE_SHIFT;
+ xen_pfn_t mfn = page_array[pfn];
+
+ rc = xc_copy_to_domain_page(xc_handle, domid, mfn, page);
+ if (rc < 0) {
+ perror("xc_copy_to_domain_page");
+ break;
+ }
+ }
+ return rc;
+}
+
+void *load_file(const char *path, unsigned long *filesize)
+{
+ void *img;
+ ssize_t size;
+ int fd;
+
+ DPRINTF("load_file(%s)\n", path);
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ perror(path);
+ return NULL;
+ }
+
+ size = lseek(fd, 0, SEEK_END);
+ if (size < 0) {
+ perror(path);
+ close(fd);
+ return NULL;
+ }
+ lseek(fd, 0, SEEK_SET);
+
+ img = malloc(size);
+ if (img == NULL) {
+ perror(path);
+ close(fd);
+ return NULL;
+ }
+
+ size = read(fd, img, size);
+ if (size <= 0) {
+ perror(path);
+ close(fd);
+ free(img);
+ return NULL;
+ }
+
+ if (filesize)
+ *filesize = size;
+ close(fd);
+ return img;
+}
+
+int load_elf_kernel(
+ int xc_handle,
+ int domid,
+ const char *kernel_path,
+ struct domain_setup_info *dsi,
+ xen_pfn_t *page_array)
+{
+ struct load_funcs load_funcs;
+ char *kernel_img;
+ unsigned long kernel_size;
+ int rc;
+
+ /* load the kernel ELF file */
+ kernel_img = load_file(kernel_path, &kernel_size);
+ if (kernel_img == NULL) {
+ rc = -1;
+ goto out;
+ }
+
+ DPRINTF("probe_elf\n");
+ rc = probe_elf(kernel_img, kernel_size, &load_funcs);
+ if (rc < 0) {
+ rc = -1;
+ printf("%s is not an ELF file\n", kernel_path);
+ goto out;
+ }
+
+ DPRINTF("parseimage\n");
+ rc = (load_funcs.parseimage)(kernel_img, kernel_size, dsi);
+ if (rc < 0) {
+ rc = -1;
+ goto out;
+ }
+
+ DPRINTF("loadimage\n");
+ (load_funcs.loadimage)(kernel_img, kernel_size, xc_handle, domid,
+ page_array, dsi);
+
+ DPRINTF(" v_start %016"PRIx64"\n", dsi->v_start);
+ DPRINTF(" v_end %016"PRIx64"\n", dsi->v_end);
+ DPRINTF(" v_kernstart %016"PRIx64"\n", dsi->v_kernstart);
+ DPRINTF(" v_kernend %016"PRIx64"\n", dsi->v_kernend);
+ DPRINTF(" v_kernentry %016"PRIx64"\n", dsi->v_kernentry);
+
+out:
+ free(kernel_img);
+ return rc;
+}
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/powerpc64/utils.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/powerpc64/utils.h Fri Dec 15 11:32:58 2006 -0700
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ *
+ * Copyright (C) IBM Corporation 2006
+ *
+ * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
+ * Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
+ */
+
+extern unsigned long get_rma_pages(void *devtree);
+extern int get_rma_page_array(int xc_handle, int domid, xen_pfn_t **page_array,
+ unsigned long nr_pages);
+extern int install_image(int xc_handle, int domid, xen_pfn_t *page_array,
+ void *image, unsigned long paddr, unsigned long size);
+extern void *load_file(const char *path, unsigned long *filesize);
+extern int load_elf_kernel(int xc_handle, int domid, const char *kernel_path,
+ struct domain_setup_info *dsi,
+ xen_pfn_t *page_array);
+
+#define ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
+
+#define max(x,y) ({ \
+ const typeof(x) _x = (x); \
+ const typeof(y) _y = (y); \
+ (void) (&_x == &_y); \
+ _x > _y ? _x : _y; })
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/powerpc64/xc_linux_build.c
--- a/tools/libxc/powerpc64/xc_linux_build.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxc/powerpc64/xc_linux_build.c Fri Dec 15 11:32:58 2006 -0700
@@ -35,60 +35,10 @@
#include "flatdevtree_env.h"
#include "flatdevtree.h"
+#include "utils.h"
#define INITRD_ADDR (24UL << 20)
#define DEVTREE_ADDR (16UL << 20)
-
-#define ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
-
-#define max(x,y) ({ \
- const typeof(x) _x = (x); \
- const typeof(y) _y = (y); \
- (void) (&_x == &_y); \
- _x > _y ? _x : _y; })
-
-static void *load_file(const char *path, unsigned long *filesize)
-{
- void *img;
- ssize_t size;
- int fd;
-
- DPRINTF("load_file(%s)\n", path);
-
- fd = open(path, O_RDONLY);
- if (fd < 0) {
- perror(path);
- return NULL;
- }
-
- size = lseek(fd, 0, SEEK_END);
- if (size < 0) {
- perror(path);
- close(fd);
- return NULL;
- }
- lseek(fd, 0, SEEK_SET);
-
- img = malloc(size);
- if (img == NULL) {
- perror(path);
- close(fd);
- return NULL;
- }
-
- size = read(fd, img, size);
- if (size <= 0) {
- perror(path);
- close(fd);
- free(img);
- return NULL;
- }
-
- if (filesize)
- *filesize = size;
- close(fd);
- return img;
-}
static int init_boot_vcpu(
int xc_handle,
@@ -128,37 +78,6 @@ static int init_boot_vcpu(
return rc;
}
-static int install_image(
- int xc_handle,
- int domid,
- xen_pfn_t *page_array,
- void *image,
- unsigned long paddr,
- unsigned long size)
-{
- uint8_t *img = image;
- int i;
- int rc = 0;
-
- if (paddr & ~PAGE_MASK) {
- printf("*** unaligned address\n");
- return -1;
- }
-
- for (i = 0; i < size; i += PAGE_SIZE) {
- void *page = img + i;
- xen_pfn_t pfn = (paddr + i) >> PAGE_SHIFT;
- xen_pfn_t mfn = page_array[pfn];
-
- rc = xc_copy_to_domain_page(xc_handle, domid, mfn, page);
- if (rc < 0) {
- perror("xc_copy_to_domain_page");
- break;
- }
- }
- return rc;
-}
-
static int load_devtree(
int xc_handle,
int domid,
@@ -167,10 +86,10 @@ static int load_devtree(
unsigned long devtree_addr,
uint64_t initrd_base,
unsigned long initrd_len,
- start_info_t *si,
- unsigned long si_addr)
-{
- uint32_t start_info[4] = {0, si_addr, 0, 0x1000};
+ start_info_t *start_info __attribute__((unused)),
+ unsigned long start_info_addr)
+{
+ uint32_t si[4] = {0, start_info_addr, 0, 0x1000};
struct boot_param_header *header;
void *chosen;
void *xen;
@@ -208,9 +127,14 @@ static int load_devtree(
return rc;
}
+ rc = ft_set_rsvmap(devtree, 1, initrd_base, initrd_len);
+ if (rc < 0) {
+ DPRINTF("couldn't set initrd reservation\n");
+ return ~0UL;
+ }
+
/* start-info (XXX being removed soon) */
- rc = ft_set_prop(&devtree, xen, "start-info",
- start_info, sizeof(start_info));
+ rc = ft_set_prop(&devtree, xen, "start-info", si, sizeof(si));
if (rc < 0) {
DPRINTF("couldn't set /xen/start-info\n");
return rc;
@@ -218,91 +142,19 @@ static int load_devtree(
header = devtree;
devtree_size = header->totalsize;
+ {
+ static const char dtb[] = "/tmp/xc_domU.dtb";
+ int dfd = creat(dtb, 0666);
+ if (dfd != -1) {
+ write(dfd, devtree, devtree_size);
+ close(dfd);
+ } else
+ DPRINTF("could not open(\"%s\")\n", dtb);
+ }
DPRINTF("copying device tree to 0x%lx[0x%x]\n", DEVTREE_ADDR,
devtree_size);
return install_image(xc_handle, domid, page_array, devtree, DEVTREE_ADDR,
devtree_size);
-}
-
-unsigned long spin_list[] = {
-#if 0
- 0x100,
- 0x200,
- 0x300,
- 0x380,
- 0x400,
- 0x480,
- 0x500,
- 0x700,
- 0x900,
- 0xc00,
-#endif
- 0
-};
-
-/* XXX yes, this is a hack */
-static void hack_kernel_img(char *img)
-{
- const off_t file_offset = 0x10000;
- unsigned long *addr = spin_list;
-
- while (*addr) {
- uint32_t *instruction = (uint32_t *)(img + *addr + file_offset);
- printf("installing spin loop at %lx (%x)\n", *addr, *instruction);
- *instruction = 0x48000000;
- addr++;
- }
-}
-
-static int load_kernel(
- int xc_handle,
- int domid,
- const char *kernel_path,
- struct domain_setup_info *dsi,
- xen_pfn_t *page_array)
-{
- struct load_funcs load_funcs;
- char *kernel_img;
- unsigned long kernel_size;
- int rc;
-
- /* load the kernel ELF file */
- kernel_img = load_file(kernel_path, &kernel_size);
- if (kernel_img == NULL) {
- rc = -1;
- goto out;
- }
-
- hack_kernel_img(kernel_img);
-
- DPRINTF("probe_elf\n");
- rc = probe_elf(kernel_img, kernel_size, &load_funcs);
- if (rc < 0) {
- rc = -1;
- printf("%s is not an ELF file\n", kernel_path);
- goto out;
- }
-
- DPRINTF("parseimage\n");
- rc = (load_funcs.parseimage)(kernel_img, kernel_size, dsi);
- if (rc < 0) {
- rc = -1;
- goto out;
- }
-
- DPRINTF("loadimage\n");
- (load_funcs.loadimage)(kernel_img, kernel_size, xc_handle, domid,
- page_array, dsi);
-
- DPRINTF(" v_start %016"PRIx64"\n", dsi->v_start);
- DPRINTF(" v_end %016"PRIx64"\n", dsi->v_end);
- DPRINTF(" v_kernstart %016"PRIx64"\n", dsi->v_kernstart);
- DPRINTF(" v_kernend %016"PRIx64"\n", dsi->v_kernend);
- DPRINTF(" v_kernentry %016"PRIx64"\n", dsi->v_kernentry);
-
-out:
- free(kernel_img);
- return rc;
}
static int load_initrd(
@@ -334,49 +186,38 @@ out:
return rc;
}
-static unsigned long create_start_info(start_info_t *si,
+static unsigned long create_start_info(
+ void *devtree, start_info_t *start_info,
unsigned int console_evtchn, unsigned int store_evtchn,
- unsigned long nr_pages)
-{
- unsigned long si_addr;
-
- memset(si, 0, sizeof(*si));
- snprintf(si->magic, sizeof(si->magic), "xen-%d.%d-powerpc64HV", 3, 0);
-
- si->nr_pages = nr_pages;
- si->shared_info = (nr_pages - 1) << PAGE_SHIFT;
- si->store_mfn = si->nr_pages - 2;
- si->store_evtchn = store_evtchn;
- si->console.domU.mfn = si->nr_pages - 3;
- si->console.domU.evtchn = console_evtchn;
- si_addr = (si->nr_pages - 4) << PAGE_SHIFT;
-
- return si_addr;
-}
-
-static int get_page_array(int xc_handle, int domid, xen_pfn_t **page_array,
- unsigned long *nr_pages)
-{
+ unsigned long nr_pages, unsigned long rma_pages)
+{
+ unsigned long start_info_addr;
+ uint64_t rma_top;
int rc;
- DPRINTF("xc_get_tot_pages\n");
- *nr_pages = xc_get_tot_pages(xc_handle, domid);
- DPRINTF(" 0x%lx\n", *nr_pages);
-
- *page_array = malloc(*nr_pages * sizeof(xen_pfn_t));
- if (*page_array == NULL) {
- perror("malloc");
- return -1;
- }
-
- DPRINTF("xc_get_pfn_list\n");
- rc = xc_get_pfn_list(xc_handle, domid, *page_array, *nr_pages);
- if (rc != *nr_pages) {
- perror("Could not get the page frame list");
- return -1;
- }
-
- return 0;
+ memset(start_info, 0, sizeof(*start_info));
+ snprintf(start_info->magic, sizeof(start_info->magic),
+ "xen-%d.%d-powerpc64HV", 3, 0);
+
+ rma_top = rma_pages << PAGE_SHIFT;
+ DPRINTF("RMA top = 0x%"PRIX64"\n", rma_top);
+
+ start_info->nr_pages = nr_pages;
+ start_info->shared_info = rma_top - PAGE_SIZE;
+ start_info->store_mfn = (rma_top >> PAGE_SHIFT) - 2;
+ start_info->store_evtchn = store_evtchn;
+ start_info->console.domU.mfn = (rma_top >> PAGE_SHIFT) - 3;
+ start_info->console.domU.evtchn = console_evtchn;
+ start_info_addr = rma_top - 4*PAGE_SIZE;
+
+ rc = ft_set_rsvmap(devtree, 0, start_info_addr, 4*PAGE_SIZE);
+ if (rc < 0) {
+ DPRINTF("couldn't set start_info reservation\n");
+ return ~0UL;
+ }
+
+
+ return start_info_addr;
}
static void free_page_array(xen_pfn_t *page_array)
@@ -388,6 +229,7 @@ static void free_page_array(xen_pfn_t *p
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,
@@ -399,7 +241,7 @@ int xc_linux_build(int xc_handle,
unsigned long *console_mfn,
void *devtree)
{
- start_info_t si;
+ start_info_t start_info;
struct domain_setup_info dsi;
xen_pfn_t *page_array = NULL;
unsigned long nr_pages;
@@ -407,18 +249,28 @@ int xc_linux_build(int xc_handle,
unsigned long kern_addr;
unsigned long initrd_base = 0;
unsigned long initrd_len = 0;
- unsigned long si_addr;
+ unsigned long start_info_addr;
+ unsigned long rma_pages;
int rc = 0;
DPRINTF("%s\n", __func__);
- if (get_page_array(xc_handle, domid, &page_array, &nr_pages)) {
+ nr_pages = mem_mb << (20 - PAGE_SHIFT);
+ DPRINTF("nr_pages 0x%lx\n", nr_pages);
+
+ rma_pages = get_rma_pages(devtree);
+ if (rma_pages == 0) {
+ rc = -1;
+ goto out;
+ }
+
+ if (get_rma_page_array(xc_handle, domid, &page_array, rma_pages)) {
rc = -1;
goto out;
}
DPRINTF("loading image '%s'\n", image_name);
- if (load_kernel(xc_handle, domid, image_name, &dsi, page_array)) {
+ if (load_elf_kernel(xc_handle, domid, image_name, &dsi, page_array)) {
rc = -1;
goto out;
}
@@ -434,11 +286,12 @@ int xc_linux_build(int xc_handle,
}
/* start_info stuff: about to be removed */
- si_addr = create_start_info(&si, console_evtchn, store_evtchn, nr_pages);
- *console_mfn = page_array[si.console.domU.mfn];
- *store_mfn = page_array[si.store_mfn];
- if (install_image(xc_handle, domid, page_array, &si, si_addr,
- sizeof(start_info_t))) {
+ start_info_addr = create_start_info(devtree, &start_info, console_evtchn,
+ store_evtchn, nr_pages, rma_pages);
+ *console_mfn = page_array[start_info.console.domU.mfn];
+ *store_mfn = page_array[start_info.store_mfn];
+ if (install_image(xc_handle, domid, page_array, &start_info,
+ start_info_addr, sizeof(start_info_t))) {
rc = -1;
goto out;
}
@@ -447,7 +300,8 @@ int xc_linux_build(int xc_handle,
DPRINTF("loading flattened device tree\n");
devtree_addr = DEVTREE_ADDR;
if (load_devtree(xc_handle, domid, page_array, devtree, devtree_addr,
- initrd_base, initrd_len, &si, si_addr)) {
+ initrd_base, initrd_len, &start_info,
+ start_info_addr)) {
DPRINTF("couldn't load flattened device tree.\n");
rc = -1;
goto out;
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/powerpc64/xc_prose_build.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/powerpc64/xc_prose_build.c Fri Dec 15 11:32:58 2006 -0700
@@ -0,0 +1,323 @@
+/*
+ * 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.
+ *
+ * Copyright (C) IBM Corporation 2006
+ *
+ * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
+ * Jonathan Appavoo <jappavoo@xxxxxxxxxx>
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <inttypes.h>
+
+#include <xen/xen.h>
+#include <xen/memory.h>
+#include <xc_private.h>
+#include <xg_private.h>
+#include <xenctrl.h>
+
+#include "flatdevtree_env.h"
+#include "flatdevtree.h"
+#include "utils.h"
+
+#define INITRD_ADDR (24UL << 20)
+#define DEVTREE_ADDR (16UL << 20)
+
+static int init_boot_vcpu(
+ int xc_handle,
+ int domid,
+ struct domain_setup_info *dsi,
+ unsigned long devtree_addr,
+ unsigned long kern_addr)
+{
+ vcpu_guest_context_t ctxt;
+ int rc;
+
+ 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; /* reserved for specifying OF handler */
+ /* 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;
+
+ DPRINTF("xc_vcpu_setvcpucontext:\n"
+ " pc 0x%016"PRIx64", msr 0x%016"PRIx64"\n"
+ " r1-5 %016"PRIx64" %016"PRIx64" %016"PRIx64" %016"PRIx64
+ " %016"PRIx64"\n",
+ ctxt.user_regs.pc, ctxt.user_regs.msr,
+ ctxt.user_regs.gprs[1],
+ ctxt.user_regs.gprs[2],
+ ctxt.user_regs.gprs[3],
+ ctxt.user_regs.gprs[4],
+ ctxt.user_regs.gprs[5]);
+ rc = xc_vcpu_setcontext(xc_handle, domid, 0, &ctxt);
+ if (rc < 0)
+ perror("setdomaininfo");
+
+ return rc;
+}
+
+static int load_devtree(
+ int xc_handle,
+ int domid,
+ xen_pfn_t *page_array,
+ void *devtree,
+ unsigned long devtree_addr,
+ uint64_t initrd_base,
+ unsigned long initrd_len,
+ start_info_t *start_info __attribute__((unused)),
+ unsigned long start_info_addr)
+{
+ uint32_t si[4] = {0, start_info_addr, 0, 0x1000};
+ struct boot_param_header *header;
+ void *chosen;
+ void *xen;
+ uint64_t initrd_end = initrd_base + initrd_len;
+ unsigned int devtree_size;
+ int rc = 0;
+
+ DPRINTF("adding initrd props\n");
+
+ chosen = ft_find_node(devtree, "/chosen");
+ if (chosen == NULL) {
+ DPRINTF("couldn't find /chosen\n");
+ return -1;
+ }
+
+ xen = ft_find_node(devtree, "/xen");
+ if (xen == NULL) {
+ DPRINTF("couldn't find /xen\n");
+ return -1;
+ }
+
+ /* initrd-start */
+ rc = ft_set_prop(&devtree, chosen, "linux,initrd-start",
+ &initrd_base, sizeof(initrd_base));
+ if (rc < 0) {
+ DPRINTF("couldn't set /chosen/linux,initrd-start\n");
+ return rc;
+ }
+
+ /* initrd-end */
+ rc = ft_set_prop(&devtree, chosen, "linux,initrd-end",
+ &initrd_end, sizeof(initrd_end));
+ if (rc < 0) {
+ DPRINTF("couldn't set /chosen/linux,initrd-end\n");
+ return rc;
+ }
+
+ rc = ft_set_rsvmap(devtree, 1, initrd_base, initrd_len);
+ if (rc < 0) {
+ DPRINTF("couldn't set initrd reservation\n");
+ return ~0UL;
+ }
+
+ /* start-info (XXX being removed soon) */
+ rc = ft_set_prop(&devtree, xen, "start-info", si, sizeof(si));
+ if (rc < 0) {
+ DPRINTF("couldn't set /xen/start-info\n");
+ return rc;
+ }
+
+ header = devtree;
+ devtree_size = header->totalsize;
+ {
+ static const char dtb[] = "/tmp/xc_domU.dtb";
+ int dfd = creat(dtb, 0666);
+ if (dfd != -1) {
+ write(dfd, devtree, devtree_size);
+ close(dfd);
+ } else
+ DPRINTF("could not open(\"%s\")\n", dtb);
+ }
+
+ DPRINTF("copying device tree to 0x%lx[0x%x]\n", DEVTREE_ADDR,
devtree_size);
+ return install_image(xc_handle, domid, page_array, devtree, DEVTREE_ADDR,
+ devtree_size);
+}
+
+static int load_initrd(
+ int xc_handle,
+ int domid,
+ xen_pfn_t *page_array,
+ const char *initrd_path,
+ unsigned long *base,
+ unsigned long *len)
+{
+ uint8_t *initrd_img;
+ int rc = -1;
+
+ /* load the initrd file */
+ initrd_img = load_file(initrd_path, len);
+ if (initrd_img == NULL)
+ return -1;
+
+ DPRINTF("copying initrd to 0x%lx[0x%lx]\n", INITRD_ADDR, *len);
+ if (install_image(xc_handle, domid, page_array, initrd_img, INITRD_ADDR,
+ *len))
+ goto out;
+
+ *base = INITRD_ADDR;
+ rc = 0;
+
+out:
+ free(initrd_img);
+ return rc;
+}
+
+static unsigned long create_start_info(
+ void *devtree, start_info_t *start_info,
+ unsigned int console_evtchn, unsigned int store_evtchn,
+ unsigned long nr_pages, unsigned long rma_pages, const char *cmdline)
+{
+ unsigned long start_info_addr;
+ uint64_t rma_top;
+ int rc;
+
+ memset(start_info, 0, sizeof(*start_info));
+ snprintf(start_info->magic, sizeof(start_info->magic),
+ "xen-%d.%d-powerpc64HV", 3, 0);
+
+ rma_top = rma_pages << PAGE_SHIFT;
+ DPRINTF("RMA top = 0x%"PRIX64"\n", rma_top);
+
+ start_info->nr_pages = nr_pages;
+ start_info->shared_info = rma_top - PAGE_SIZE;
+ start_info->store_mfn = (rma_top >> PAGE_SHIFT) - 2;
+ start_info->store_evtchn = store_evtchn;
+ start_info->console.domU.mfn = (rma_top >> PAGE_SHIFT) - 3;
+ start_info->console.domU.evtchn = console_evtchn;
+ strncpy((char *)start_info->cmd_line, cmdline, MAX_GUEST_CMDLINE);
+ /* just in case we truncated cmdline with strncpy add 0 at the end */
+ start_info->cmd_line[MAX_GUEST_CMDLINE-1]=0;
+ start_info_addr = rma_top - 4*PAGE_SIZE;
+
+ rc = ft_set_rsvmap(devtree, 0, start_info_addr, 4*PAGE_SIZE);
+ if (rc < 0) {
+ DPRINTF("couldn't set start_info reservation\n");
+ return ~0UL;
+ }
+
+ return start_info_addr;
+}
+
+static void free_page_array(xen_pfn_t *page_array)
+{
+ free(page_array);
+}
+
+int xc_prose_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,
+ void *devtree)
+{
+ start_info_t start_info;
+ struct domain_setup_info dsi;
+ xen_pfn_t *page_array = NULL;
+ unsigned long nr_pages;
+ unsigned long devtree_addr = 0;
+ unsigned long kern_addr;
+ unsigned long initrd_base = 0;
+ unsigned long initrd_len = 0;
+ unsigned long start_info_addr;
+ unsigned long rma_pages;
+ int rc = 0;
+
+ DPRINTF("%s\n", __func__);
+
+ DPRINTF("cmdline=%s\n", cmdline);
+
+ nr_pages = mem_mb << (20 - PAGE_SHIFT);
+ DPRINTF("nr_pages 0x%lx\n", nr_pages);
+
+ rma_pages = get_rma_pages(devtree);
+ if (rma_pages == 0) {
+ rc = -1;
+ goto out;
+ }
+
+ if (get_rma_page_array(xc_handle, domid, &page_array, rma_pages)) {
+ rc = -1;
+ goto out;
+ }
+
+ DPRINTF("loading image '%s'\n", image_name);
+ if (load_elf_kernel(xc_handle, domid, image_name, &dsi, page_array)) {
+ rc = -1;
+ goto out;
+ }
+ kern_addr = 0;
+
+ if (initrd_name && initrd_name[0] != '\0') {
+ DPRINTF("loading initrd '%s'\n", initrd_name);
+ if (load_initrd(xc_handle, domid, page_array, initrd_name,
+ &initrd_base, &initrd_len)) {
+ rc = -1;
+ goto out;
+ }
+ }
+
+ /* start_info stuff: about to be removed */
+ start_info_addr = create_start_info(devtree, &start_info, console_evtchn,
+ store_evtchn, nr_pages,
+ rma_pages, cmdline);
+ *console_mfn = page_array[start_info.console.domU.mfn];
+ *store_mfn = page_array[start_info.store_mfn];
+ if (install_image(xc_handle, domid, page_array, &start_info,
+ start_info_addr, sizeof(start_info_t))) {
+ rc = -1;
+ goto out;
+ }
+
+ if (devtree) {
+ DPRINTF("loading flattened device tree\n");
+ devtree_addr = DEVTREE_ADDR;
+ if (load_devtree(xc_handle, domid, page_array, devtree, devtree_addr,
+ initrd_base, initrd_len, &start_info,
+ start_info_addr)) {
+ DPRINTF("couldn't load flattened device tree.\n");
+ rc = -1;
+ goto out;
+ }
+ }
+
+ if (init_boot_vcpu(xc_handle, domid, &dsi, devtree_addr, kern_addr)) {
+ rc = -1;
+ goto out;
+ }
+
+out:
+ free_page_array(page_array);
+ return rc;
+}
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxc/xc_linux_build.c Fri Dec 15 11:32:58 2006 -0700
@@ -596,15 +596,21 @@ static int compat_check(int xc_handle, s
}
if (strstr(xen_caps, "xen-3.0-x86_32p")) {
- if (dsi->pae_kernel == PAEKERN_no) {
+ if (dsi->pae_kernel == PAEKERN_bimodal) {
+ dsi->pae_kernel = PAEKERN_extended_cr3;
+ } else if (dsi->pae_kernel == PAEKERN_no) {
xc_set_error(XC_INVALID_KERNEL,
"Non PAE-kernel on PAE host.");
return 0;
}
- } else if (dsi->pae_kernel != PAEKERN_no) {
- xc_set_error(XC_INVALID_KERNEL,
- "PAE-kernel on non-PAE host.");
- return 0;
+ } else {
+ if (dsi->pae_kernel == PAEKERN_bimodal) {
+ dsi->pae_kernel = PAEKERN_no;
+ } else if (dsi->pae_kernel != PAEKERN_no) {
+ xc_set_error(XC_INVALID_KERNEL,
+ "PAE-kernel on non-PAE host.");
+ return 0;
+ }
}
return 1;
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/xc_load_elf.c
--- a/tools/libxc/xc_load_elf.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxc/xc_load_elf.c Fri Dec 15 11:32:58 2006 -0700
@@ -325,17 +325,6 @@ static int parseelfimage(const char *ima
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 = (Elf_Shdr *)(image + ehdr->e_shoff +
- (ehdr->e_shstrndx*ehdr->e_shentsize));
- shstrtab = image + shdr->sh_offset;
-
dsi->__elfnote_section = NULL;
dsi->__xen_guest_string = NULL;
@@ -354,6 +343,17 @@ static int parseelfimage(const char *ima
/* Fall back to looking for the special '__xen_guest' section. */
if ( dsi->__elfnote_section == NULL )
{
+ /* 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.");
+ return -EINVAL;
+ }
+ shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
+ (ehdr->e_shstrndx*ehdr->e_shentsize));
+ shstrtab = image + shdr->sh_offset;
+
for ( h = 0; h < ehdr->e_shnum; h++ )
{
shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize));
@@ -400,6 +400,8 @@ static int parseelfimage(const char *ima
}
/*
+ * A "bimodal" ELF note indicates the kernel will adjust to the
+ * current paging mode, including handling extended cr3 syntax.
* If we have ELF notes then PAE=yes implies that we must support
* the extended cr3 syntax. Otherwise we need to find the
* [extended-cr3] syntax in the __xen_guest string.
@@ -408,7 +410,9 @@ static int parseelfimage(const char *ima
if ( dsi->__elfnote_section )
{
p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE);
- if ( p != NULL && strncmp(p, "yes", 3) == 0 )
+ if ( p != NULL && strncmp(p, "bimodal", 7) == 0 )
+ dsi->pae_kernel = PAEKERN_bimodal;
+ else if ( p != NULL && strncmp(p, "yes", 3) == 0 )
dsi->pae_kernel = PAEKERN_extended_cr3;
}
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxc/xenctrl.h Fri Dec 15 11:32:58 2006 -0700
@@ -728,4 +728,8 @@ const char *xc_error_code_to_desc(int co
*/
xc_error_handler xc_set_error_handler(xc_error_handler handler);
+/* PowerPC specific. */
+int xc_alloc_real_mode_area(int xc_handle,
+ uint32_t domid,
+ unsigned int log);
#endif
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxc/xenguest.h Fri Dec 15 11:32:58 2006 -0700
@@ -122,4 +122,19 @@ int xc_get_hvm_param(
int xc_get_hvm_param(
int handle, domid_t dom, int param, unsigned long *value);
+/* PowerPC specific. */
+int xc_prose_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,
+ void *arch_args);
+
#endif /* XENGUEST_H */
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxc/xg_private.h Fri Dec 15 11:32:58 2006 -0700
@@ -132,6 +132,7 @@ struct domain_setup_info
#define PAEKERN_no 0
#define PAEKERN_yes 1
#define PAEKERN_extended_cr3 2
+#define PAEKERN_bimodal 3
unsigned int pae_kernel;
unsigned int load_symtab;
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_boot_type.h
--- a/tools/libxen/include/xen_boot_type.h Fri Dec 15 10:59:33 2006 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2006, XenSource Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef XEN_BOOT_TYPE_H
-#define XEN_BOOT_TYPE_H
-
-
-#include "xen_common.h"
-
-
-enum xen_boot_type
-{
- /**
- * boot an HVM guest using an emulated BIOS
- */
- XEN_BOOT_TYPE_BIOS,
-
- /**
- * boot from inside the machine using grub
- */
- XEN_BOOT_TYPE_GRUB,
-
- /**
- * boot from an external kernel
- */
- XEN_BOOT_TYPE_KERNEL_EXTERNAL,
-
- /**
- * boot from a kernel inside the guest filesystem
- */
- XEN_BOOT_TYPE_KERNEL_INTERNAL
-};
-
-
-typedef struct xen_boot_type_set
-{
- size_t size;
- enum xen_boot_type contents[];
-} xen_boot_type_set;
-
-/**
- * Allocate a xen_boot_type_set of the given size.
- */
-extern xen_boot_type_set *
-xen_boot_type_set_alloc(size_t size);
-
-/**
- * Free the given xen_boot_type_set. The given set must have been
- * allocated by this library.
- */
-extern void
-xen_boot_type_set_free(xen_boot_type_set *set);
-
-
-/**
- * Return the name corresponding to the given code. This string must
- * not be modified or freed.
- */
-extern const char *
-xen_boot_type_to_string(enum xen_boot_type val);
-
-
-/**
- * Return the correct code for the given string, or set the session
- * object to failure and return an undefined value if the given string does
- * not match a known code.
- */
-extern enum xen_boot_type
-xen_boot_type_from_string(xen_session *session, const char *str);
-
-
-#endif
diff -r 1e042dde1a5f -r e17d7438e09e
tools/libxen/include/xen_boot_type_internal.h
--- a/tools/libxen/include/xen_boot_type_internal.h Fri Dec 15 10:59:33
2006 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2006, XenSource Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-/*
- * Declarations of the abstract types used during demarshalling of enum
- * xen_boot_type. Internal to this library -- do not use from outside.
- */
-
-
-#ifndef XEN_BOOT_TYPE_INTERNAL_H
-#define XEN_BOOT_TYPE_INTERNAL_H
-
-
-#include "xen_internal.h"
-
-
-extern const abstract_type xen_boot_type_abstract_type_;
-extern const abstract_type xen_boot_type_set_abstract_type_;
-
-
-#endif
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_console.h
--- a/tools/libxen/include/xen_console.h Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_console.h Fri Dec 15 11:32:58 2006 -0700
@@ -149,14 +149,14 @@ xen_console_record_opt_set_free(xen_cons
/**
- * Get the current state of the given console.
+ * Get a record containing the current state of the given console.
*/
extern bool
xen_console_get_record(xen_session *session, xen_console_record **result,
xen_console console);
/**
- * Get a reference to the object with the specified UUID.
+ * Get a reference to the console instance with the specified UUID.
*/
extern bool
xen_console_get_by_uuid(xen_session *session, xen_console *result, char *uuid);
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_host.h
--- a/tools/libxen/include/xen_host.h Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_host.h Fri Dec 15 11:32:58 2006 -0700
@@ -154,14 +154,14 @@ xen_host_record_opt_set_free(xen_host_re
/**
- * Get the current state of the given host. !!!
+ * Get a record containing the current state of the given host.
*/
extern bool
xen_host_get_record(xen_session *session, xen_host_record **result, xen_host
host);
/**
- * Get a reference to the object with the specified UUID. !!!
+ * Get a reference to the host instance with the specified UUID.
*/
extern bool
xen_host_get_by_uuid(xen_session *session, xen_host *result, char *uuid);
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_host_cpu.h
--- a/tools/libxen/include/xen_host_cpu.h Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_host_cpu.h Fri Dec 15 11:32:58 2006 -0700
@@ -153,14 +153,14 @@ xen_host_cpu_record_opt_set_free(xen_hos
/**
- * Get the current state of the given host_cpu. !!!
+ * Get a record containing the current state of the given host_cpu.
*/
extern bool
xen_host_cpu_get_record(xen_session *session, xen_host_cpu_record **result,
xen_host_cpu host_cpu);
/**
- * Get a reference to the object with the specified UUID. !!!
+ * Get a reference to the host_cpu instance with the specified UUID.
*/
extern bool
xen_host_cpu_get_by_uuid(xen_session *session, xen_host_cpu *result, char
*uuid);
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_internal.h
--- a/tools/libxen/include/xen_internal.h Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_internal.h Fri Dec 15 11:32:58 2006 -0700
@@ -128,7 +128,6 @@ xen_enum_lookup_(xen_session *session, c
xen_enum_lookup_(session__, str__, lookup_table__, \
sizeof(lookup_table__) / \
sizeof(lookup_table__[0])) \
- \
#define XEN_ALLOC(type__) \
type__ * \
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_network.h
--- a/tools/libxen/include/xen_network.h Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_network.h Fri Dec 15 11:32:58 2006 -0700
@@ -152,14 +152,14 @@ xen_network_record_opt_set_free(xen_netw
/**
- * Get the current state of the given network. !!!
+ * Get a record containing the current state of the given network.
*/
extern bool
xen_network_get_record(xen_session *session, xen_network_record **result,
xen_network network);
/**
- * Get a reference to the object with the specified UUID. !!!
+ * Get a reference to the network instance with the specified UUID.
*/
extern bool
xen_network_get_by_uuid(xen_session *session, xen_network *result, char *uuid);
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_pif.h
--- a/tools/libxen/include/xen_pif.h Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_pif.h Fri Dec 15 11:32:58 2006 -0700
@@ -155,14 +155,14 @@ xen_pif_record_opt_set_free(xen_pif_reco
/**
- * Get the current state of the given PIF. !!!
+ * Get a record containing the current state of the given PIF.
*/
extern bool
xen_pif_get_record(xen_session *session, xen_pif_record **result, xen_pif pif);
/**
- * Get a reference to the object with the specified UUID. !!!
+ * Get a reference to the PIF instance with the specified UUID.
*/
extern bool
xen_pif_get_by_uuid(xen_session *session, xen_pif *result, char *uuid);
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_sr.h
--- a/tools/libxen/include/xen_sr.h Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_sr.h Fri Dec 15 11:32:58 2006 -0700
@@ -153,14 +153,14 @@ xen_sr_record_opt_set_free(xen_sr_record
/**
- * Get the current state of the given SR. !!!
+ * Get a record containing the current state of the given SR.
*/
extern bool
xen_sr_get_record(xen_session *session, xen_sr_record **result, xen_sr sr);
/**
- * Get a reference to the object with the specified UUID. !!!
+ * Get a reference to the SR instance with the specified UUID.
*/
extern bool
xen_sr_get_by_uuid(xen_session *session, xen_sr *result, char *uuid);
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_user.h
--- a/tools/libxen/include/xen_user.h Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_user.h Fri Dec 15 11:32:58 2006 -0700
@@ -146,14 +146,14 @@ xen_user_record_opt_set_free(xen_user_re
/**
- * Get the current state of the given user. !!!
+ * Get a record containing the current state of the given user.
*/
extern bool
xen_user_get_record(xen_session *session, xen_user_record **result, xen_user
user);
/**
- * Get a reference to the object with the specified UUID. !!!
+ * Get a reference to the user instance with the specified UUID.
*/
extern bool
xen_user_get_by_uuid(xen_session *session, xen_user *result, char *uuid);
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_vdi.h
--- a/tools/libxen/include/xen_vdi.h Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_vdi.h Fri Dec 15 11:32:58 2006 -0700
@@ -159,14 +159,14 @@ xen_vdi_record_opt_set_free(xen_vdi_reco
/**
- * Get the current state of the given VDI. !!!
+ * Get a record containing the current state of the given VDI.
*/
extern bool
xen_vdi_get_record(xen_session *session, xen_vdi_record **result, xen_vdi vdi);
/**
- * Get a reference to the object with the specified UUID. !!!
+ * Get a reference to the VDI instance with the specified UUID.
*/
extern bool
xen_vdi_get_by_uuid(xen_session *session, xen_vdi *result, char *uuid);
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_vif.h
--- a/tools/libxen/include/xen_vif.h Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_vif.h Fri Dec 15 11:32:58 2006 -0700
@@ -156,14 +156,14 @@ xen_vif_record_opt_set_free(xen_vif_reco
/**
- * Get the current state of the given VIF. !!!
+ * Get a record containing the current state of the given VIF.
*/
extern bool
xen_vif_get_record(xen_session *session, xen_vif_record **result, xen_vif vif);
/**
- * Get a reference to the object with the specified UUID. !!!
+ * Get a reference to the VIF instance with the specified UUID.
*/
extern bool
xen_vif_get_by_uuid(xen_session *session, xen_vif *result, char *uuid);
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_vm.h
--- a/tools/libxen/include/xen_vm.h Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_vm.h Fri Dec 15 11:32:58 2006 -0700
@@ -19,7 +19,6 @@
#ifndef XEN_VM_H
#define XEN_VM_H
-#include "xen_boot_type.h"
#include "xen_common.h"
#include "xen_console_decl.h"
#include "xen_cpu_feature.h"
@@ -36,9 +35,36 @@
/*
- * The VM class.
- *
+ * The VM class.
+ *
* A virtual machine (or 'guest').
+ *
+ * VM booting is controlled by setting one of the two mutually exclusive
+ * groups: "PV", and "HVM". If HVM.boot is the empty string, then paravirtual
+ * domain building and booting will be used; otherwise the VM will be loaded
+ * as an HVM domain, and booted using an emulated BIOS.
+ *
+ * When paravirtual booting is in use, the PV/bootloader field indicates the
+ * bootloader to use. It may be "pygrub", in which case the platform's
+ * default installation of pygrub will be used, or a full path within the
+ * control domain to some other bootloader. The other fields, PV/kernel,
+ * PV/ramdisk, PV/args and PV/bootloader_args will be passed to the bootloader
+ * unmodified, and interpretation of those fields is then specific to the
+ * bootloader itself, including the possibility that the bootloader will
+ * ignore some or all of those given values.
+ *
+ * If the bootloader is pygrub, then the menu.lst is parsed if present in the
+ * guest's filesystem, otherwise the specified kernel and ramdisk are used, or
+ * an autodetected kernel is used if nothing is specified and autodetection is
+ * possible. PV/args is appended to the kernel command line, no matter which
+ * mechanism is used for finding the kernel.
+ *
+ * If PV/bootloader is empty but PV/kernel is specified, then the kernel and
+ * ramdisk values will be treated as paths within the control domain. If both
+ * PV/bootloader and PV/kernel are empty, then the behaviour is as if
+ * PV/bootloader was specified as "pygrub".
+ *
+ * When using HVM booting, HVM/boot specifies the order of the boot devices.
*/
@@ -79,6 +105,7 @@ typedef struct xen_vm_record
char *name_description;
int64_t user_version;
bool is_a_template;
+ bool auto_power_on;
struct xen_host_record_opt *resident_on;
int64_t memory_static_max;
int64_t memory_dynamic_max;
@@ -101,18 +128,17 @@ typedef struct xen_vm_record
struct xen_vif_record_opt_set *vifs;
struct xen_vbd_record_opt_set *vbds;
struct xen_vtpm_record_opt_set *vtpms;
- char *bios_boot;
+ char *pv_bootloader;
+ char *pv_kernel;
+ char *pv_ramdisk;
+ char *pv_args;
+ char *pv_bootloader_args;
+ char *hvm_boot;
bool platform_std_vga;
char *platform_serial;
bool platform_localtime;
bool platform_clock_offset;
bool platform_enable_audio;
- char *builder;
- enum xen_boot_type boot_method;
- char *kernel_kernel;
- char *kernel_initrd;
- char *kernel_args;
- char *grub_cmdline;
char *pci_bus;
xen_string_string_map *tools_version;
xen_string_string_map *otherconfig;
@@ -198,14 +224,14 @@ xen_vm_record_opt_set_free(xen_vm_record
/**
- * Get the current state of the given VM. !!!
+ * Get a record containing the current state of the given VM.
*/
extern bool
xen_vm_get_record(xen_session *session, xen_vm_record **result, xen_vm vm);
/**
- * Get a reference to the object with the specified UUID. !!!
+ * Get a reference to the VM instance with the specified UUID.
*/
extern bool
xen_vm_get_by_uuid(xen_session *session, xen_vm *result, char *uuid);
@@ -277,6 +303,13 @@ xen_vm_get_is_a_template(xen_session *se
/**
+ * Get the auto_power_on field of the given VM.
+ */
+extern bool
+xen_vm_get_auto_power_on(xen_session *session, bool *result, xen_vm vm);
+
+
+/**
* Get the resident_on field of the given VM.
*/
extern bool
@@ -431,10 +464,45 @@ xen_vm_get_vtpms(xen_session *session, s
/**
- * Get the bios/boot field of the given VM.
- */
-extern bool
-xen_vm_get_bios_boot(xen_session *session, char **result, xen_vm vm);
+ * Get the PV/bootloader field of the given VM.
+ */
+extern bool
+xen_vm_get_pv_bootloader(xen_session *session, char **result, xen_vm vm);
+
+
+/**
+ * Get the PV/kernel field of the given VM.
+ */
+extern bool
+xen_vm_get_pv_kernel(xen_session *session, char **result, xen_vm vm);
+
+
+/**
+ * Get the PV/ramdisk field of the given VM.
+ */
+extern bool
+xen_vm_get_pv_ramdisk(xen_session *session, char **result, xen_vm vm);
+
+
+/**
+ * Get the PV/args field of the given VM.
+ */
+extern bool
+xen_vm_get_pv_args(xen_session *session, char **result, xen_vm vm);
+
+
+/**
+ * Get the PV/bootloader_args field of the given VM.
+ */
+extern bool
+xen_vm_get_pv_bootloader_args(xen_session *session, char **result, xen_vm vm);
+
+
+/**
+ * Get the HVM/boot field of the given VM.
+ */
+extern bool
+xen_vm_get_hvm_boot(xen_session *session, char **result, xen_vm vm);
/**
@@ -473,48 +541,6 @@ xen_vm_get_platform_enable_audio(xen_ses
/**
- * Get the builder field of the given VM.
- */
-extern bool
-xen_vm_get_builder(xen_session *session, char **result, xen_vm vm);
-
-
-/**
- * Get the boot_method field of the given VM.
- */
-extern bool
-xen_vm_get_boot_method(xen_session *session, enum xen_boot_type *result,
xen_vm vm);
-
-
-/**
- * Get the kernel/kernel field of the given VM.
- */
-extern bool
-xen_vm_get_kernel_kernel(xen_session *session, char **result, xen_vm vm);
-
-
-/**
- * Get the kernel/initrd field of the given VM.
- */
-extern bool
-xen_vm_get_kernel_initrd(xen_session *session, char **result, xen_vm vm);
-
-
-/**
- * Get the kernel/args field of the given VM.
- */
-extern bool
-xen_vm_get_kernel_args(xen_session *session, char **result, xen_vm vm);
-
-
-/**
- * Get the grub/cmdline field of the given VM.
- */
-extern bool
-xen_vm_get_grub_cmdline(xen_session *session, char **result, xen_vm vm);
-
-
-/**
* Get the PCI_bus field of the given VM.
*/
extern bool
@@ -564,6 +590,13 @@ xen_vm_set_is_a_template(xen_session *se
/**
+ * Set the auto_power_on field of the given VM.
+ */
+extern bool
+xen_vm_set_auto_power_on(xen_session *session, xen_vm vm, bool auto_power_on);
+
+
+/**
* Set the memory/dynamic_max field of the given VM.
*/
extern bool
@@ -592,6 +625,13 @@ xen_vm_set_vcpus_params(xen_session *ses
/**
+ * Set the VCPUs/number field of the given VM.
+ */
+extern bool
+xen_vm_set_vcpus_number(xen_session *session, xen_vm vm, int64_t number);
+
+
+/**
* Set the VCPUs/features/force_on field of the given VM.
*/
extern bool
@@ -599,6 +639,22 @@ xen_vm_set_vcpus_features_force_on(xen_s
/**
+ * Add the given value to the VCPUs/features/force_on field of the
+ * given VM. If the value is already in that Set, then do nothing.
+ */
+extern bool
+xen_vm_add_vcpus_features_force_on(xen_session *session, xen_vm vm, enum
xen_cpu_feature value);
+
+
+/**
+ * Remove the given value from the VCPUs/features/force_on field of the
+ * given VM. If the value is not in that Set, then do nothing.
+ */
+extern bool
+xen_vm_remove_vcpus_features_force_on(xen_session *session, xen_vm vm, enum
xen_cpu_feature value);
+
+
+/**
* Set the VCPUs/features/force_off field of the given VM.
*/
extern bool
@@ -606,6 +662,22 @@ xen_vm_set_vcpus_features_force_off(xen_
/**
+ * Add the given value to the VCPUs/features/force_off field of the
+ * given VM. If the value is already in that Set, then do nothing.
+ */
+extern bool
+xen_vm_add_vcpus_features_force_off(xen_session *session, xen_vm vm, enum
xen_cpu_feature value);
+
+
+/**
+ * Remove the given value from the VCPUs/features/force_off field of
+ * the given VM. If the value is not in that Set, then do nothing.
+ */
+extern bool
+xen_vm_remove_vcpus_features_force_off(xen_session *session, xen_vm vm, enum
xen_cpu_feature value);
+
+
+/**
* Set the actions/after_shutdown field of the given VM.
*/
extern bool
@@ -634,10 +706,45 @@ xen_vm_set_actions_after_crash(xen_sessi
/**
- * Set the bios/boot field of the given VM.
- */
-extern bool
-xen_vm_set_bios_boot(xen_session *session, xen_vm vm, char *boot);
+ * Set the PV/bootloader field of the given VM.
+ */
+extern bool
+xen_vm_set_pv_bootloader(xen_session *session, xen_vm vm, char *bootloader);
+
+
+/**
+ * Set the PV/kernel field of the given VM.
+ */
+extern bool
+xen_vm_set_pv_kernel(xen_session *session, xen_vm vm, char *kernel);
+
+
+/**
+ * Set the PV/ramdisk field of the given VM.
+ */
+extern bool
+xen_vm_set_pv_ramdisk(xen_session *session, xen_vm vm, char *ramdisk);
+
+
+/**
+ * Set the PV/args field of the given VM.
+ */
+extern bool
+xen_vm_set_pv_args(xen_session *session, xen_vm vm, char *args);
+
+
+/**
+ * Set the PV/bootloader_args field of the given VM.
+ */
+extern bool
+xen_vm_set_pv_bootloader_args(xen_session *session, xen_vm vm, char
*bootloader_args);
+
+
+/**
+ * Set the HVM/boot field of the given VM.
+ */
+extern bool
+xen_vm_set_hvm_boot(xen_session *session, xen_vm vm, char *boot);
/**
@@ -673,48 +780,6 @@ xen_vm_set_platform_clock_offset(xen_ses
*/
extern bool
xen_vm_set_platform_enable_audio(xen_session *session, xen_vm vm, bool
enable_audio);
-
-
-/**
- * Set the builder field of the given VM.
- */
-extern bool
-xen_vm_set_builder(xen_session *session, xen_vm vm, char *builder);
-
-
-/**
- * Set the boot_method field of the given VM.
- */
-extern bool
-xen_vm_set_boot_method(xen_session *session, xen_vm vm, enum xen_boot_type
boot_method);
-
-
-/**
- * Set the kernel/kernel field of the given VM.
- */
-extern bool
-xen_vm_set_kernel_kernel(xen_session *session, xen_vm vm, char *kernel);
-
-
-/**
- * Set the kernel/initrd field of the given VM.
- */
-extern bool
-xen_vm_set_kernel_initrd(xen_session *session, xen_vm vm, char *initrd);
-
-
-/**
- * Set the kernel/args field of the given VM.
- */
-extern bool
-xen_vm_set_kernel_args(xen_session *session, xen_vm vm, char *args);
-
-
-/**
- * Set the grub/cmdline field of the given VM.
- */
-extern bool
-xen_vm_set_grub_cmdline(xen_session *session, xen_vm vm, char *cmdline);
/**
@@ -760,8 +825,8 @@ xen_vm_unpause(xen_session *session, xen
/**
* Attempt to cleanly shutdown the specified VM. (Note: this may not be
- * supported---e.g. if a guest agent is not installed).
- *
+ * supported---e.g. if a guest agent is not installed).
+ *
* Once shutdown has been completed perform poweroff action specified in guest
* configuration.
*/
@@ -771,8 +836,8 @@ xen_vm_clean_shutdown(xen_session *sessi
/**
* Attempt to cleanly shutdown the specified VM (Note: this may not be
- * supported---e.g. if a guest agent is not installed).
- *
+ * supported---e.g. if a guest agent is not installed).
+ *
* Once shutdown has been completed perform reboot action specified in guest
* configuration.
*/
@@ -817,12 +882,4 @@ xen_vm_get_all(xen_session *session, str
xen_vm_get_all(xen_session *session, struct xen_vm_set **result);
-/**
- * Destroy the specified VM. The VM is completely removed from the system.
- * This function can only be called when the VM is in the Halted State.
- */
-extern bool
-xen_vm_destroy(xen_session *session, xen_vm vm);
-
-
#endif
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/include/xen_vtpm.h
--- a/tools/libxen/include/xen_vtpm.h Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/include/xen_vtpm.h Fri Dec 15 11:32:58 2006 -0700
@@ -151,14 +151,14 @@ xen_vtpm_record_opt_set_free(xen_vtpm_re
/**
- * Get the current state of the given VTPM. !!!
+ * Get a record containing the current state of the given VTPM.
*/
extern bool
xen_vtpm_get_record(xen_session *session, xen_vtpm_record **result, xen_vtpm
vtpm);
/**
- * Get a reference to the object with the specified UUID. !!!
+ * Get a reference to the VTPM instance with the specified UUID.
*/
extern bool
xen_vtpm_get_by_uuid(xen_session *session, xen_vtpm *result, char *uuid);
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/src/xen_boot_type.c
--- a/tools/libxen/src/xen_boot_type.c Fri Dec 15 10:59:33 2006 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2006, XenSource Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <string.h>
-
-#include "xen_internal.h"
-#include "xen_boot_type.h"
-#include "xen_boot_type_internal.h"
-
-
-/*
- * Maintain this in the same order as the enum declaration!
- */
-static const char *lookup_table[] =
-{
- "bios",
- "grub",
- "kernel_external",
- "kernel_internal"
-};
-
-
-extern xen_boot_type_set *
-xen_boot_type_set_alloc(size_t size)
-{
- return calloc(1, sizeof(xen_boot_type_set) +
- size * sizeof(enum xen_boot_type));
-}
-
-
-extern void
-xen_boot_type_set_free(xen_boot_type_set *set)
-{
- free(set);
-}
-
-
-const char *
-xen_boot_type_to_string(enum xen_boot_type val)
-{
- return lookup_table[val];
-}
-
-
-extern enum xen_boot_type
-xen_boot_type_from_string(xen_session *session, const char *str)
-{
- return ENUM_LOOKUP(session, str, lookup_table);
-}
-
-
-const abstract_type xen_boot_type_abstract_type_ =
- {
- .typename = ENUM,
- .enum_marshaller =
- (const char *(*)(int))&xen_boot_type_to_string,
- .enum_demarshaller =
- (int (*)(xen_session *, const char *))&xen_boot_type_from_string
- };
-
-
-const abstract_type xen_boot_type_set_abstract_type_ =
- {
- .typename = SET,
- .child = &xen_boot_type_abstract_type_
- };
-
-
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/src/xen_console.c
--- a/tools/libxen/src/xen_console.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/src/xen_console.c Fri Dec 15 11:32:58 2006 -0700
@@ -158,9 +158,7 @@ xen_console_get_protocol(xen_session *se
};
abstract_type result_type = xen_console_protocol_abstract_type_;
- char *result_str = NULL;
XEN_CALL_("console.get_protocol");
- *result = xen_console_protocol_from_string(session, result_str);
return session->ok;
}
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/src/xen_vif.c
--- a/tools/libxen/src/xen_vif.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/src/xen_vif.c Fri Dec 15 11:32:58 2006 -0700
@@ -197,9 +197,7 @@ xen_vif_get_type(xen_session *session, e
};
abstract_type result_type = xen_driver_type_abstract_type_;
- char *result_str = NULL;
XEN_CALL_("VIF.get_type");
- *result = xen_driver_type_from_string(session, result_str);
return session->ok;
}
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/src/xen_vm.c
--- a/tools/libxen/src/xen_vm.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/src/xen_vm.c Fri Dec 15 11:32:58 2006 -0700
@@ -20,7 +20,6 @@
#include <stddef.h>
#include <stdlib.h>
-#include "xen_boot_type_internal.h"
#include "xen_common.h"
#include "xen_console.h"
#include "xen_cpu_feature.h"
@@ -67,6 +66,9 @@ static const struct_member xen_vm_record
{ .key = "is_a_template",
.type = &abstract_type_bool,
.offset = offsetof(xen_vm_record, is_a_template) },
+ { .key = "auto_power_on",
+ .type = &abstract_type_bool,
+ .offset = offsetof(xen_vm_record, auto_power_on) },
{ .key = "resident_on",
.type = &abstract_type_ref,
.offset = offsetof(xen_vm_record, resident_on) },
@@ -133,9 +135,24 @@ static const struct_member xen_vm_record
{ .key = "VTPMs",
.type = &abstract_type_ref_set,
.offset = offsetof(xen_vm_record, vtpms) },
- { .key = "bios_boot",
+ { .key = "PV_bootloader",
.type = &abstract_type_string,
- .offset = offsetof(xen_vm_record, bios_boot) },
+ .offset = offsetof(xen_vm_record, pv_bootloader) },
+ { .key = "PV_kernel",
+ .type = &abstract_type_string,
+ .offset = offsetof(xen_vm_record, pv_kernel) },
+ { .key = "PV_ramdisk",
+ .type = &abstract_type_string,
+ .offset = offsetof(xen_vm_record, pv_ramdisk) },
+ { .key = "PV_args",
+ .type = &abstract_type_string,
+ .offset = offsetof(xen_vm_record, pv_args) },
+ { .key = "PV_bootloader_args",
+ .type = &abstract_type_string,
+ .offset = offsetof(xen_vm_record, pv_bootloader_args) },
+ { .key = "HVM_boot",
+ .type = &abstract_type_string,
+ .offset = offsetof(xen_vm_record, hvm_boot) },
{ .key = "platform_std_VGA",
.type = &abstract_type_bool,
.offset = offsetof(xen_vm_record, platform_std_vga) },
@@ -151,24 +168,6 @@ static const struct_member xen_vm_record
{ .key = "platform_enable_audio",
.type = &abstract_type_bool,
.offset = offsetof(xen_vm_record, platform_enable_audio) },
- { .key = "builder",
- .type = &abstract_type_string,
- .offset = offsetof(xen_vm_record, builder) },
- { .key = "boot_method",
- .type = &xen_boot_type_abstract_type_,
- .offset = offsetof(xen_vm_record, boot_method) },
- { .key = "kernel_kernel",
- .type = &abstract_type_string,
- .offset = offsetof(xen_vm_record, kernel_kernel) },
- { .key = "kernel_initrd",
- .type = &abstract_type_string,
- .offset = offsetof(xen_vm_record, kernel_initrd) },
- { .key = "kernel_args",
- .type = &abstract_type_string,
- .offset = offsetof(xen_vm_record, kernel_args) },
- { .key = "grub_cmdline",
- .type = &abstract_type_string,
- .offset = offsetof(xen_vm_record, grub_cmdline) },
{ .key = "PCI_bus",
.type = &abstract_type_string,
.offset = offsetof(xen_vm_record, pci_bus) },
@@ -213,13 +212,13 @@ xen_vm_record_free(xen_vm_record *record
xen_vif_record_opt_set_free(record->vifs);
xen_vbd_record_opt_set_free(record->vbds);
xen_vtpm_record_opt_set_free(record->vtpms);
- free(record->bios_boot);
+ free(record->pv_bootloader);
+ free(record->pv_kernel);
+ free(record->pv_ramdisk);
+ free(record->pv_args);
+ free(record->pv_bootloader_args);
+ free(record->hvm_boot);
free(record->platform_serial);
- free(record->builder);
- free(record->kernel_kernel);
- free(record->kernel_initrd);
- free(record->kernel_args);
- free(record->grub_cmdline);
free(record->pci_bus);
xen_string_string_map_free(record->tools_version);
xen_string_string_map_free(record->otherconfig);
@@ -325,9 +324,7 @@ xen_vm_get_power_state(xen_session *sess
};
abstract_type result_type = xen_vm_power_state_abstract_type_;
- char *result_str = NULL;
XEN_CALL_("VM.get_power_state");
- *result = xen_vm_power_state_from_string(session, result_str);
return session->ok;
}
@@ -399,6 +396,22 @@ xen_vm_get_is_a_template(xen_session *se
bool
+xen_vm_get_auto_power_on(xen_session *session, bool *result, xen_vm vm)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vm }
+ };
+
+ abstract_type result_type = abstract_type_bool;
+
+ XEN_CALL_("VM.get_auto_power_on");
+ return session->ok;
+}
+
+
+bool
xen_vm_get_resident_on(xen_session *session, xen_host *result, xen_vm vm)
{
abstract_value param_values[] =
@@ -640,9 +653,7 @@ xen_vm_get_actions_after_shutdown(xen_se
};
abstract_type result_type = xen_on_normal_exit_abstract_type_;
- char *result_str = NULL;
XEN_CALL_("VM.get_actions_after_shutdown");
- *result = xen_on_normal_exit_from_string(session, result_str);
return session->ok;
}
@@ -657,9 +668,7 @@ xen_vm_get_actions_after_reboot(xen_sess
};
abstract_type result_type = xen_on_normal_exit_abstract_type_;
- char *result_str = NULL;
XEN_CALL_("VM.get_actions_after_reboot");
- *result = xen_on_normal_exit_from_string(session, result_str);
return session->ok;
}
@@ -674,9 +683,7 @@ xen_vm_get_actions_after_suspend(xen_ses
};
abstract_type result_type = xen_on_normal_exit_abstract_type_;
- char *result_str = NULL;
XEN_CALL_("VM.get_actions_after_suspend");
- *result = xen_on_normal_exit_from_string(session, result_str);
return session->ok;
}
@@ -691,9 +698,7 @@ xen_vm_get_actions_after_crash(xen_sessi
};
abstract_type result_type = xen_on_crash_behaviour_abstract_type_;
- char *result_str = NULL;
XEN_CALL_("VM.get_actions_after_crash");
- *result = xen_on_crash_behaviour_from_string(session, result_str);
return session->ok;
}
@@ -767,7 +772,7 @@ xen_vm_get_vtpms(xen_session *session, s
bool
-xen_vm_get_bios_boot(xen_session *session, char **result, xen_vm vm)
+xen_vm_get_pv_bootloader(xen_session *session, char **result, xen_vm vm)
{
abstract_value param_values[] =
{
@@ -778,7 +783,92 @@ xen_vm_get_bios_boot(xen_session *sessio
abstract_type result_type = abstract_type_string;
*result = NULL;
- XEN_CALL_("VM.get_bios_boot");
+ XEN_CALL_("VM.get_PV_bootloader");
+ return session->ok;
+}
+
+
+bool
+xen_vm_get_pv_kernel(xen_session *session, char **result, xen_vm vm)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vm }
+ };
+
+ abstract_type result_type = abstract_type_string;
+
+ *result = NULL;
+ XEN_CALL_("VM.get_PV_kernel");
+ return session->ok;
+}
+
+
+bool
+xen_vm_get_pv_ramdisk(xen_session *session, char **result, xen_vm vm)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vm }
+ };
+
+ abstract_type result_type = abstract_type_string;
+
+ *result = NULL;
+ XEN_CALL_("VM.get_PV_ramdisk");
+ return session->ok;
+}
+
+
+bool
+xen_vm_get_pv_args(xen_session *session, char **result, xen_vm vm)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vm }
+ };
+
+ abstract_type result_type = abstract_type_string;
+
+ *result = NULL;
+ XEN_CALL_("VM.get_PV_args");
+ return session->ok;
+}
+
+
+bool
+xen_vm_get_pv_bootloader_args(xen_session *session, char **result, xen_vm vm)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vm }
+ };
+
+ abstract_type result_type = abstract_type_string;
+
+ *result = NULL;
+ XEN_CALL_("VM.get_PV_bootloader_args");
+ return session->ok;
+}
+
+
+bool
+xen_vm_get_hvm_boot(xen_session *session, char **result, xen_vm vm)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vm }
+ };
+
+ abstract_type result_type = abstract_type_string;
+
+ *result = NULL;
+ XEN_CALL_("VM.get_HVM_boot");
return session->ok;
}
@@ -860,108 +950,6 @@ xen_vm_get_platform_enable_audio(xen_ses
abstract_type result_type = abstract_type_bool;
XEN_CALL_("VM.get_platform_enable_audio");
- return session->ok;
-}
-
-
-bool
-xen_vm_get_builder(xen_session *session, char **result, xen_vm vm)
-{
- abstract_value param_values[] =
- {
- { .type = &abstract_type_string,
- .u.string_val = vm }
- };
-
- abstract_type result_type = abstract_type_string;
-
- *result = NULL;
- XEN_CALL_("VM.get_builder");
- return session->ok;
-}
-
-
-bool
-xen_vm_get_boot_method(xen_session *session, enum xen_boot_type *result,
xen_vm vm)
-{
- abstract_value param_values[] =
- {
- { .type = &abstract_type_string,
- .u.string_val = vm }
- };
-
- abstract_type result_type = xen_boot_type_abstract_type_;
- char *result_str = NULL;
- XEN_CALL_("VM.get_boot_method");
- *result = xen_boot_type_from_string(session, result_str);
- return session->ok;
-}
-
-
-bool
-xen_vm_get_kernel_kernel(xen_session *session, char **result, xen_vm vm)
-{
- abstract_value param_values[] =
- {
- { .type = &abstract_type_string,
- .u.string_val = vm }
- };
-
- abstract_type result_type = abstract_type_string;
-
- *result = NULL;
- XEN_CALL_("VM.get_kernel_kernel");
- return session->ok;
-}
-
-
-bool
-xen_vm_get_kernel_initrd(xen_session *session, char **result, xen_vm vm)
-{
- abstract_value param_values[] =
- {
- { .type = &abstract_type_string,
- .u.string_val = vm }
- };
-
- abstract_type result_type = abstract_type_string;
-
- *result = NULL;
- XEN_CALL_("VM.get_kernel_initrd");
- return session->ok;
-}
-
-
-bool
-xen_vm_get_kernel_args(xen_session *session, char **result, xen_vm vm)
-{
- abstract_value param_values[] =
- {
- { .type = &abstract_type_string,
- .u.string_val = vm }
- };
-
- abstract_type result_type = abstract_type_string;
-
- *result = NULL;
- XEN_CALL_("VM.get_kernel_args");
- return session->ok;
-}
-
-
-bool
-xen_vm_get_grub_cmdline(xen_session *session, char **result, xen_vm vm)
-{
- abstract_value param_values[] =
- {
- { .type = &abstract_type_string,
- .u.string_val = vm }
- };
-
- abstract_type result_type = abstract_type_string;
-
- *result = NULL;
- XEN_CALL_("VM.get_grub_cmdline");
return session->ok;
}
@@ -1082,6 +1070,22 @@ xen_vm_set_is_a_template(xen_session *se
bool
+xen_vm_set_auto_power_on(xen_session *session, xen_vm vm, bool auto_power_on)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vm },
+ { .type = &abstract_type_bool,
+ .u.bool_val = auto_power_on }
+ };
+
+ xen_call_(session, "VM.set_auto_power_on", param_values, 2, NULL, NULL);
+ return session->ok;
+}
+
+
+bool
xen_vm_set_memory_dynamic_max(xen_session *session, xen_vm vm, int64_t
dynamic_max)
{
abstract_value param_values[] =
@@ -1146,6 +1150,22 @@ xen_vm_set_vcpus_params(xen_session *ses
bool
+xen_vm_set_vcpus_number(xen_session *session, xen_vm vm, int64_t number)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vm },
+ { .type = &abstract_type_int,
+ .u.int_val = number }
+ };
+
+ xen_call_(session, "VM.set_VCPUs_number", param_values, 2, NULL, NULL);
+ return session->ok;
+}
+
+
+bool
xen_vm_set_vcpus_features_force_on(xen_session *session, xen_vm vm, struct
xen_cpu_feature_set *force_on)
{
abstract_value param_values[] =
@@ -1162,6 +1182,38 @@ xen_vm_set_vcpus_features_force_on(xen_s
bool
+xen_vm_add_vcpus_features_force_on(xen_session *session, xen_vm vm, enum
xen_cpu_feature value)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vm },
+ { .type = &xen_cpu_feature_abstract_type_,
+ .u.string_val = xen_cpu_feature_to_string(value) }
+ };
+
+ xen_call_(session, "VM.add_VCPUs_features_force_on", param_values, 2,
NULL, NULL);
+ return session->ok;
+}
+
+
+bool
+xen_vm_remove_vcpus_features_force_on(xen_session *session, xen_vm vm, enum
xen_cpu_feature value)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vm },
+ { .type = &xen_cpu_feature_abstract_type_,
+ .u.string_val = xen_cpu_feature_to_string(value) }
+ };
+
+ xen_call_(session, "VM.remove_VCPUs_features_force_on", param_values, 2,
NULL, NULL);
+ return session->ok;
+}
+
+
+bool
xen_vm_set_vcpus_features_force_off(xen_session *session, xen_vm vm, struct
xen_cpu_feature_set *force_off)
{
abstract_value param_values[] =
@@ -1178,6 +1230,38 @@ xen_vm_set_vcpus_features_force_off(xen_
bool
+xen_vm_add_vcpus_features_force_off(xen_session *session, xen_vm vm, enum
xen_cpu_feature value)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vm },
+ { .type = &xen_cpu_feature_abstract_type_,
+ .u.string_val = xen_cpu_feature_to_string(value) }
+ };
+
+ xen_call_(session, "VM.add_VCPUs_features_force_off", param_values, 2,
NULL, NULL);
+ return session->ok;
+}
+
+
+bool
+xen_vm_remove_vcpus_features_force_off(xen_session *session, xen_vm vm, enum
xen_cpu_feature value)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vm },
+ { .type = &xen_cpu_feature_abstract_type_,
+ .u.string_val = xen_cpu_feature_to_string(value) }
+ };
+
+ xen_call_(session, "VM.remove_VCPUs_features_force_off", param_values, 2,
NULL, NULL);
+ return session->ok;
+}
+
+
+bool
xen_vm_set_actions_after_shutdown(xen_session *session, xen_vm vm, enum
xen_on_normal_exit after_shutdown)
{
abstract_value param_values[] =
@@ -1242,7 +1326,87 @@ xen_vm_set_actions_after_crash(xen_sessi
bool
-xen_vm_set_bios_boot(xen_session *session, xen_vm vm, char *boot)
+xen_vm_set_pv_bootloader(xen_session *session, xen_vm vm, char *bootloader)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vm },
+ { .type = &abstract_type_string,
+ .u.string_val = bootloader }
+ };
+
+ xen_call_(session, "VM.set_PV_bootloader", param_values, 2, NULL, NULL);
+ return session->ok;
+}
+
+
+bool
+xen_vm_set_pv_kernel(xen_session *session, xen_vm vm, char *kernel)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vm },
+ { .type = &abstract_type_string,
+ .u.string_val = kernel }
+ };
+
+ xen_call_(session, "VM.set_PV_kernel", param_values, 2, NULL, NULL);
+ return session->ok;
+}
+
+
+bool
+xen_vm_set_pv_ramdisk(xen_session *session, xen_vm vm, char *ramdisk)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vm },
+ { .type = &abstract_type_string,
+ .u.string_val = ramdisk }
+ };
+
+ xen_call_(session, "VM.set_PV_ramdisk", param_values, 2, NULL, NULL);
+ return session->ok;
+}
+
+
+bool
+xen_vm_set_pv_args(xen_session *session, xen_vm vm, char *args)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vm },
+ { .type = &abstract_type_string,
+ .u.string_val = args }
+ };
+
+ xen_call_(session, "VM.set_PV_args", param_values, 2, NULL, NULL);
+ return session->ok;
+}
+
+
+bool
+xen_vm_set_pv_bootloader_args(xen_session *session, xen_vm vm, char
*bootloader_args)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vm },
+ { .type = &abstract_type_string,
+ .u.string_val = bootloader_args }
+ };
+
+ xen_call_(session, "VM.set_PV_bootloader_args", param_values, 2, NULL,
NULL);
+ return session->ok;
+}
+
+
+bool
+xen_vm_set_hvm_boot(xen_session *session, xen_vm vm, char *boot)
{
abstract_value param_values[] =
{
@@ -1252,7 +1416,7 @@ xen_vm_set_bios_boot(xen_session *sessio
.u.string_val = boot }
};
- xen_call_(session, "VM.set_bios_boot", param_values, 2, NULL, NULL);
+ xen_call_(session, "VM.set_HVM_boot", param_values, 2, NULL, NULL);
return session->ok;
}
@@ -1268,7 +1432,7 @@ xen_vm_set_platform_std_vga(xen_session
.u.bool_val = std_vga }
};
- xen_call_(session, "VM.set_platform_std_vga", param_values, 2, NULL, NULL);
+ xen_call_(session, "VM.set_platform_std_VGA", param_values, 2, NULL, NULL);
return session->ok;
}
@@ -1338,102 +1502,6 @@ xen_vm_set_platform_enable_audio(xen_ses
bool
-xen_vm_set_builder(xen_session *session, xen_vm vm, char *builder)
-{
- abstract_value param_values[] =
- {
- { .type = &abstract_type_string,
- .u.string_val = vm },
- { .type = &abstract_type_string,
- .u.string_val = builder }
- };
-
- xen_call_(session, "VM.set_builder", param_values, 2, NULL, NULL);
- return session->ok;
-}
-
-
-bool
-xen_vm_set_boot_method(xen_session *session, xen_vm vm, enum xen_boot_type
boot_method)
-{
- abstract_value param_values[] =
- {
- { .type = &abstract_type_string,
- .u.string_val = vm },
- { .type = &xen_boot_type_abstract_type_,
- .u.string_val = xen_boot_type_to_string(boot_method) }
- };
-
- xen_call_(session, "VM.set_boot_method", param_values, 2, NULL, NULL);
- return session->ok;
-}
-
-
-bool
-xen_vm_set_kernel_kernel(xen_session *session, xen_vm vm, char *kernel)
-{
- abstract_value param_values[] =
- {
- { .type = &abstract_type_string,
- .u.string_val = vm },
- { .type = &abstract_type_string,
- .u.string_val = kernel }
- };
-
- xen_call_(session, "VM.set_kernel_kernel", param_values, 2, NULL, NULL);
- return session->ok;
-}
-
-
-bool
-xen_vm_set_kernel_initrd(xen_session *session, xen_vm vm, char *initrd)
-{
- abstract_value param_values[] =
- {
- { .type = &abstract_type_string,
- .u.string_val = vm },
- { .type = &abstract_type_string,
- .u.string_val = initrd }
- };
-
- xen_call_(session, "VM.set_kernel_initrd", param_values, 2, NULL, NULL);
- return session->ok;
-}
-
-
-bool
-xen_vm_set_kernel_args(xen_session *session, xen_vm vm, char *args)
-{
- abstract_value param_values[] =
- {
- { .type = &abstract_type_string,
- .u.string_val = vm },
- { .type = &abstract_type_string,
- .u.string_val = args }
- };
-
- xen_call_(session, "VM.set_kernel_args", param_values, 2, NULL, NULL);
- return session->ok;
-}
-
-
-bool
-xen_vm_set_grub_cmdline(xen_session *session, xen_vm vm, char *cmdline)
-{
- abstract_value param_values[] =
- {
- { .type = &abstract_type_string,
- .u.string_val = vm },
- { .type = &abstract_type_string,
- .u.string_val = cmdline }
- };
-
- xen_call_(session, "VM.set_grub_cmdline", param_values, 2, NULL, NULL);
- return session->ok;
-}
-
-
-bool
xen_vm_set_otherconfig(xen_session *session, xen_vm vm, xen_string_string_map
*otherconfig)
{
abstract_value param_values[] =
@@ -1444,7 +1512,7 @@ xen_vm_set_otherconfig(xen_session *sess
.u.set_val = (arbitrary_set *)otherconfig }
};
- xen_call_(session, "VM.set_otherconfig", param_values, 2, NULL, NULL);
+ xen_call_(session, "VM.set_otherConfig", param_values, 2, NULL, NULL);
return session->ok;
}
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/src/xen_vtpm.c
--- a/tools/libxen/src/xen_vtpm.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/src/xen_vtpm.c Fri Dec 15 11:32:58 2006 -0700
@@ -196,9 +196,7 @@ xen_vtpm_get_driver(xen_session *session
};
abstract_type result_type = xen_driver_type_abstract_type_;
- char *result_str = NULL;
XEN_CALL_("VTPM.get_driver");
- *result = xen_driver_type_from_string(session, result_str);
return session->ok;
}
diff -r 1e042dde1a5f -r e17d7438e09e tools/libxen/test/test_bindings.c
--- a/tools/libxen/test/test_bindings.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/libxen/test/test_bindings.c Fri Dec 15 11:32:58 2006 -0700
@@ -58,7 +58,8 @@ typedef struct
} xen_comms;
-static void create_new_vm(xen_session *session);
+static xen_vm create_new_vm(xen_session *session);
+static void print_vm_power_state(xen_session *session, xen_vm vm);
static size_t
@@ -244,7 +245,7 @@ int main(int argc, char **argv)
xen_string_string_map_free(versions);
- create_new_vm(session);
+ xen_vm new_vm = create_new_vm(session);
if (!session->ok)
{
/* Error has been logged, just clean up. */
@@ -252,6 +253,16 @@ int main(int argc, char **argv)
return 1;
}
+ print_vm_power_state(session, new_vm);
+ if (!session->ok)
+ {
+ /* Error has been logged, just clean up. */
+ xen_vm_free(new_vm);
+ CLEANUP;
+ return 1;
+ }
+
+ xen_vm_free(new_vm);
CLEANUP;
return 0;
@@ -264,7 +275,7 @@ int main(int argc, char **argv)
* allocation patterns can be used, as long as the allocation and free are
* paired correctly.
*/
-static void create_new_vm(xen_session *session)
+static xen_vm create_new_vm(xen_session *session)
{
xen_cpu_feature_set *empty_cpu_feature_set =
xen_cpu_feature_set_alloc(0);
@@ -294,12 +305,12 @@ static void create_new_vm(xen_session *s
.actions_after_reboot = XEN_ON_NORMAL_EXIT_RESTART,
.actions_after_suspend = XEN_ON_NORMAL_EXIT_DESTROY,
.actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_PRESERVE,
- .bios_boot = "hd(0,0)",
- .builder = "Linux",
- .boot_method = XEN_BOOT_TYPE_KERNEL_EXTERNAL,
- .kernel_kernel = "vmlinuz",
- .kernel_initrd = "initrd.img",
- .kernel_args = ""
+ .hvm_boot = "",
+ .pv_bootloader = "pygrub",
+ .pv_kernel = "/boot/vmlinuz-2.6.16.33-xen",
+ .pv_ramdisk = "",
+ .pv_args = "",
+ .pv_bootloader_args = ""
};
@@ -313,7 +324,7 @@ static void create_new_vm(xen_session *s
{
fprintf(stderr, "VM creation failed.\n");
print_error(session);
- return;
+ return NULL;
}
@@ -327,7 +338,7 @@ static void create_new_vm(xen_session *s
fprintf(stderr, "SR lookup failed.\n");
print_error(session);
xen_vm_free(vm);
- return;
+ return NULL;
}
xen_sr_record_opt sr_record =
@@ -339,7 +350,7 @@ static void create_new_vm(xen_session *s
.name_label = "MyRootFS",
.name_description = "MyRootFS description",
.sr = &sr_record,
- .virtual_size = (1 << 20) / 512,
+ .virtual_size = (1 << 21), // 1GiB / 512 bytes/sector
.sector_size = 512,
.type = XEN_VDI_TYPE_SYSTEM,
.sharable = false,
@@ -354,7 +365,7 @@ static void create_new_vm(xen_session *s
xen_sr_set_free(srs);
xen_vm_free(vm);
- return;
+ return NULL;
}
@@ -370,7 +381,7 @@ static void create_new_vm(xen_session *s
{
.vm = &vm_record_opt,
.vdi = &vdi0_record_opt,
- .device = "sda1",
+ .device = "xvda1",
.mode = XEN_VBD_MODE_RW,
.driver = XEN_DRIVER_TYPE_PARAVIRTUALISED
};
@@ -384,7 +395,7 @@ static void create_new_vm(xen_session *s
xen_vdi_free(vdi0);
xen_sr_set_free(srs);
xen_vm_free(vm);
- return;
+ return NULL;
}
char *vm_uuid;
@@ -407,7 +418,7 @@ static void create_new_vm(xen_session *s
xen_vdi_free(vdi0);
xen_sr_set_free(srs);
xen_vm_free(vm);
- return;
+ return NULL;
}
fprintf(stderr,
@@ -420,5 +431,34 @@ static void create_new_vm(xen_session *s
xen_vbd_free(vbd0);
xen_vdi_free(vdi0);
xen_sr_set_free(srs);
- xen_vm_free(vm);
-}
+
+ return vm;
+}
+
+
+/**
+ * Print the power state for the given VM.
+ */
+static void print_vm_power_state(xen_session *session, xen_vm vm)
+{
+ char *vm_uuid;
+ enum xen_vm_power_state power_state;
+
+ if (!xen_vm_get_uuid(session, &vm_uuid, vm))
+ {
+ print_error(session);
+ return;
+ }
+
+ if (!xen_vm_get_power_state(session, &power_state, vm))
+ {
+ xen_uuid_free(vm_uuid);
+ print_error(session);
+ return;
+ }
+
+ printf("VM %s power state is %s.\n", vm_uuid,
+ xen_vm_power_state_to_string(power_state));
+
+ xen_uuid_free(vm_uuid);
+}
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/lowlevel/xc/xc.c Fri Dec 15 11:32:58 2006 -0700
@@ -408,10 +408,6 @@ static PyObject *pyxc_hvm_build(XcObject
&image, &vcpus, &pae, &acpi, &apic) )
return NULL;
-#if defined(__ia64__)
- /* Set vcpus to later be retrieved in setup_guest() */
- xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_VCPUS, vcpus);
-#endif
if ( xc_hvm_build(self->xc_handle, dom, memsize, image) != 0 )
return pyxc_error_to_exception();
@@ -919,6 +915,68 @@ static PyObject *dom_op(XcObject *self,
return zero;
}
+#ifdef __powerpc__
+static PyObject *pyxc_alloc_real_mode_area(XcObject *self,
+ PyObject *args,
+ PyObject *kwds)
+{
+ uint32_t dom;
+ unsigned int log;
+
+ static char *kwd_list[] = { "dom", "log", NULL };
+
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
+ &dom, &log) )
+ return NULL;
+
+ if ( xc_alloc_real_mode_area(self->xc_handle, dom, log) )
+ return PyErr_SetFromErrno(xc_error);
+
+ Py_INCREF(zero);
+ return zero;
+}
+
+static PyObject *pyxc_prose_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 long store_mfn = 0;
+ unsigned long console_mfn = 0;
+ void *arch_args = NULL;
+ int unused;
+
+ static char *kwd_list[] = { "dom", "store_evtchn",
+ "console_evtchn", "image",
+ /* optional */
+ "ramdisk", "cmdline", "flags",
+ "features", "arch_args", NULL };
+
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssiss#", kwd_list,
+ &dom, &store_evtchn,
+ &console_evtchn, &image,
+ /* optional */
+ &ramdisk, &cmdline, &flags,
+ &features, &arch_args, &unused) )
+ return NULL;
+
+ if ( xc_prose_build(self->xc_handle, dom, image,
+ ramdisk, cmdline, features, flags,
+ store_evtchn, &store_mfn,
+ console_evtchn, &console_mfn,
+ arch_args) != 0 ) {
+ if (!errno)
+ errno = EINVAL;
+ return PyErr_SetFromErrno(xc_error);
+ }
+ return Py_BuildValue("{s:i,s:i}",
+ "store_mfn", store_mfn,
+ "console_mfn", console_mfn);
+}
+#endif /* powerpc */
static PyMethodDef pyxc_methods[] = {
{ "handle",
@@ -1224,6 +1282,27 @@ static PyMethodDef pyxc_methods[] = {
"Set a domain's time offset to Dom0's localtime\n"
" dom [int]: Domain whose time offset is being set.\n"
"Returns: [int] 0 on success; -1 on error.\n" },
+
+#ifdef __powerpc__
+ { "arch_alloc_real_mode_area",
+ (PyCFunction)pyxc_alloc_real_mode_area,
+ METH_VARARGS | METH_KEYWORDS, "\n"
+ "Allocate a domain's real mode area.\n"
+ " dom [int]: Identifier of domain.\n"
+ " log [int]: Specifies the area's size.\n"
+ "Returns: [int] 0 on success; -1 on error.\n" },
+
+ { "arch_prose_build",
+ (PyCFunction)pyxc_prose_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" },
+#endif /* __powerpc */
{ NULL, NULL, 0, NULL }
};
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/xend/FlatDeviceTree.py
--- a/tools/python/xen/xend/FlatDeviceTree.py Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/xend/FlatDeviceTree.py Fri Dec 15 11:32:58 2006 -0700
@@ -22,6 +22,10 @@ import struct
import struct
import stat
import re
+import glob
+import math
+
+_host_devtree_root = '/proc/device-tree'
_OF_DT_HEADER = int("d00dfeed", 16) # avoid signed/unsigned FutureWarning
_OF_DT_BEGIN_NODE = 0x1
@@ -33,8 +37,10 @@ def _bincat(seq, separator=''):
'''Concatenate the contents of seq into a bytestream.'''
strs = []
for item in seq:
- if type(item) == type(0):
+ if isinstance(item, int):
strs.append(struct.pack(">I", item))
+ elif isinstance(item, long):
+ strs.append(struct.pack(">Q", item))
else:
try:
strs.append(item.to_bin())
@@ -231,37 +237,50 @@ class Tree(_Node):
header.totalsize = len(payload) + _alignup(len(header.to_bin()), 8)
return _pad(header.to_bin(), 8) + payload
-_host_devtree_root = '/proc/device-tree'
-def _getprop(propname):
- '''Extract a property from the system's device tree.'''
- f = file(os.path.join(_host_devtree_root, propname), 'r')
+def _readfile(fullpath):
+ '''Return full contents of a file.'''
+ f = file(fullpath, 'r')
data = f.read()
f.close()
return data
+def _find_first_cpu(dirpath):
+ '''Find the first node of type 'cpu' in a directory tree.'''
+ cpulist = glob.glob(os.path.join(dirpath, 'cpus', '*'))
+ for node in cpulist:
+ try:
+ data = _readfile(os.path.join(node, 'device_type'))
+ except IOError:
+ continue
+ if 'cpu' in data:
+ return node
+ raise IOError("couldn't find any CPU nodes under " + dirpath)
+
def _copynode(node, dirpath, propfilter):
- '''Extract all properties from a node in the system's device tree.'''
+ '''Copy all properties and children nodes from a directory tree.'''
dirents = os.listdir(dirpath)
for dirent in dirents:
fullpath = os.path.join(dirpath, dirent)
st = os.lstat(fullpath)
if stat.S_ISDIR(st.st_mode):
child = node.addnode(dirent)
- _copytree(child, fullpath, propfilter)
+ _copynode(child, fullpath, propfilter)
elif stat.S_ISREG(st.st_mode) and propfilter(fullpath):
- node.addprop(dirent, _getprop(fullpath))
-
-def _copytree(node, dirpath, propfilter):
- path = os.path.join(_host_devtree_root, dirpath)
- _copynode(node, path, propfilter)
+ node.addprop(dirent, _readfile(fullpath))
def build(imghandler):
'''Construct a device tree by combining the domain's configuration and
the host's device tree.'''
root = Tree()
- # 4 pages: start_info, console, store, shared_info
+ # 1st reseravtion entry used for start_info, console, store, shared_info
root.reserve(0x3ffc000, 0x4000)
+
+ # 2nd reservation enrty used for initrd, later on when we load the
+ # initrd we may fill this in with zeroes which signifies the end
+ # of the reservation map. So as to avoid adding a zero map now we
+ # put some bogus yet sensible numbers here.
+ root.reserve(0x1000000, 0x1000)
root.addprop('device_type', 'chrp-but-not-really\0')
root.addprop('#size-cells', 2)
@@ -270,35 +289,52 @@ def build(imghandler):
root.addprop('compatible', 'Momentum,Maple\0')
xen = root.addnode('xen')
- xen.addprop('start-info', 0, 0x3ffc000, 0, 0x1000)
+ xen.addprop('start-info', long(0x3ffc000), long(0x1000))
xen.addprop('version', 'Xen-3.0-unstable\0')
- xen.addprop('reg', 0, imghandler.vm.domid, 0, 0)
+ xen.addprop('reg', long(imghandler.vm.domid), long(0))
xen.addprop('domain-name', imghandler.vm.getName() + '\0')
xencons = xen.addnode('console')
xencons.addprop('interrupts', 1, 0)
- # XXX split out RMA node
- mem = root.addnode('memory@0')
+ # add memory nodes
totalmem = imghandler.vm.getMemoryTarget() * 1024
- mem.addprop('reg', 0, 0, 0, totalmem)
- mem.addprop('device_type', 'memory\0')
-
+ rma_log = 26 ### imghandler.vm.info.get('powerpc_rma_log')
+ rma_bytes = 1 << rma_log
+
+ # RMA node
+ rma = root.addnode('memory@0')
+ rma.addprop('reg', long(0), long(rma_bytes))
+ rma.addprop('device_type', 'memory\0')
+
+ # all the rest in a single node
+ remaining = totalmem - rma_bytes
+ if remaining > 0:
+ mem = root.addnode('memory@1')
+ mem.addprop('reg', long(rma_bytes), long(remaining))
+ mem.addprop('device_type', 'memory\0')
+
+ # add CPU nodes
cpus = root.addnode('cpus')
cpus.addprop('smp-enabled')
cpus.addprop('#size-cells', 0)
cpus.addprop('#address-cells', 1)
# Copy all properties the system firmware gave us, except for 'linux,'
- # properties, from 'cpus/@0', once for every vcpu. Hopefully all cpus are
- # identical...
+ # properties, from the first CPU node in the device tree. Do this once for
+ # every vcpu. Hopefully all cpus are identical...
cpu0 = None
+ cpu0path = _find_first_cpu(_host_devtree_root)
def _nolinuxprops(fullpath):
return not os.path.basename(fullpath).startswith('linux,')
for i in range(imghandler.vm.getVCpuCount()):
- cpu = cpus.addnode('PowerPC,970@0')
- _copytree(cpu, 'cpus/PowerPC,970@0', _nolinuxprops)
- # and then overwrite what we need to
- pft_size = imghandler.vm.info.get('pft-size', 0x14)
+ # create new node and copy all properties
+ cpu = cpus.addnode('PowerPC,970@%d' % i)
+ _copynode(cpu, cpu0path, _nolinuxprops)
+
+ # overwrite what we need to
+ shadow_mb = imghandler.vm.info.get('shadow_memory', 1)
+ shadow_mb_log = int(math.log(shadow_mb, 2))
+ pft_size = shadow_mb_log + 20
cpu.setprop('ibm,pft-size', 0, pft_size)
# set default CPU
@@ -307,13 +343,13 @@ def build(imghandler):
chosen = root.addnode('chosen')
chosen.addprop('cpu', cpu0.get_phandle())
- chosen.addprop('memory', mem.get_phandle())
+ chosen.addprop('memory', rma.get_phandle())
chosen.addprop('linux,stdout-path', '/xen/console\0')
chosen.addprop('interrupt-controller', xen.get_phandle())
chosen.addprop('bootargs', imghandler.cmdline + '\0')
# xc_linux_load.c will overwrite these 64-bit properties later
- chosen.addprop('linux,initrd-start', 0, 0)
- chosen.addprop('linux,initrd-end', 0, 0)
+ chosen.addprop('linux,initrd-start', long(0))
+ chosen.addprop('linux,initrd-end', long(0))
if 1:
f = file('/tmp/domU.dtb', 'w')
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/xend/XendAPI.py Fri Dec 15 11:32:58 2006 -0700
@@ -118,11 +118,16 @@ def valid_vm(func):
@param func: function with params: (self, session, vm_ref)
@rtype: callable object
"""
- def check_vm_ref(self, session, vm_ref, *args, **kwargs):
+ def check_vm_ref(self, session, *args, **kwargs):
+ if len(args) == 0:
+ return {'Status': 'Failure',
+ 'ErrorDescription': XEND_ERROR_VM_INVALID}
+
+ vm_ref = args[0]
xendom = XendDomain.instance()
if type(vm_ref) == type(str()) and \
xendom.is_valid_vm(vm_ref):
- return func(self, session, vm_ref, *args, **kwargs)
+ return func(self, session, *args, **kwargs)
else:
return {'Status': 'Failure',
'ErrorDescription': XEND_ERROR_VM_INVALID}
@@ -567,6 +572,7 @@ class XendAPI:
'VCPUs_utilisation',
'VCPUs_features_required',
'VCPUs_can_use',
+ 'consoles',
'VIFs',
'VBDs',
'VTPMs',
@@ -578,6 +584,7 @@ class XendAPI:
'name_description',
'user_version',
'is_a_template',
+ 'auto_power_on',
'memory_dynamic_max',
'memory_dynamic_min',
'VCPUs_policy',
@@ -588,19 +595,18 @@ class XendAPI:
'actions_after_reboot',
'actions_after_suspend',
'actions_after_crash',
- 'bios_boot',
+ 'PV_bootloader',
+ 'PV_kernel',
+ 'PV_ramdisk',
+ 'PV_args',
+ 'PV_bootloader_args',
+ 'HVM_boot',
'platform_std_VGA',
'platform_serial',
'platform_localtime',
'platform_clock_offset',
'platform_enable_audio',
'platform_keymap',
- 'builder',
- 'boot_method',
- 'kernel_kernel',
- 'kernel_initrd',
- 'kernel_args',
- 'grub_cmdline',
'otherConfig']
VM_methods = ['clone',
@@ -636,26 +642,34 @@ class XendAPI:
'actions_after_reboot',
'actions_after_suspend',
'actions_after_crash',
- 'bios_boot',
+ 'PV_bootloader',
+ 'PV_kernel',
+ 'PV_ramdisk',
+ 'PV_args',
+ 'PV_bootloader_args',
+ 'HVM_boot',
'platform_std_VGA',
'platform_serial',
'platform_localtime',
'platform_clock_offset',
'platform_enable_audio',
'platform_keymap',
- 'builder',
- 'boot_method',
- 'kernel_kernel',
- 'kernel_initrd',
- 'kernel_args',
'grub_cmdline',
'PCI_bus',
'otherConfig']
+ def VM_get(self, name, session, vm_ref):
+ return xen_api_success(
+ XendDomain.instance().get_vm_by_uuid(vm_ref).info[name])
+
+ def VM_set(self, name, session, vm_ref, value):
+ XendDomain.instance().get_vm_by_uuid(vm_ref).info[name] = value
+ return xen_api_success_void()
+
# attributes (ro)
def VM_get_power_state(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success(dom.state)
+ return xen_api_success(dom.get_power_state())
def VM_get_resident_on(self, session, vm_ref):
return xen_api_success(XendNode.instance().uuid)
@@ -765,9 +779,23 @@ class XendAPI:
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_on_crash())
- def VM_get_bios_boot(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success(dom.get_bios_boot())
+ def VM_get_PV_bootloader(self, session, vm_ref):
+ return self.VM_get('PV_bootloader', session, vm_ref)
+
+ def VM_get_PV_kernel(self, session, vm_ref):
+ return self.VM_get('PV_kernel', session, vm_ref)
+
+ def VM_get_PV_ramdisk(self, session, vm_ref):
+ return self.VM_get('PV_ramdisk', session, vm_ref)
+
+ def VM_get_PV_args(self, session, vm_ref):
+ return self.VM_get('PV_args', session, vm_ref)
+
+ def VM_get_PV_bootloader_args(self, session, vm_ref):
+ return self.VM_get('PV_bootloader_args', session, vm_ref)
+
+ def VM_get_HVM_boot(self, session, vm_ref):
+ return self.VM_get('HVM_boot', session, vm_ref)
def VM_get_platform_std_VGA(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
@@ -793,34 +821,10 @@ class XendAPI:
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_todo()
- def VM_get_builder(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success(dom.get_builder())
-
- def VM_get_boot_method(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success(dom.get_boot_method())
-
- def VM_get_kernel_kernel(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success('')
-
- def VM_get_kernel_initrd(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success('')
-
- def VM_get_kernel_args(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success('')
-
- def VM_get_grub_cmdline(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success('')
-
def VM_get_otherConfig(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_todo()
-
+
def VM_set_name_label(self, session, vm_ref, label):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
dom.setName(label)
@@ -877,11 +881,25 @@ class XendAPI:
def VM_set_actions_after_crash(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success_void()
-
- def VM_set_bios_boot(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
+
+ def VM_set_HVM_boot(self, session, vm_ref, value):
+ return self.VM_set('HVM_boot', session, vm_ref, value)
+
+ def VM_set_PV_bootloader(self, session, vm_ref, value):
+ return self.VM_set('PV_bootloader', session, vm_ref, value)
+
+ def VM_set_PV_kernel(self, session, vm_ref, value):
+ return self.VM_set('PV_kernel', session, vm_ref, value)
+
+ def VM_set_PV_ramdisk(self, session, vm_ref, value):
+ return self.VM_set('PV_ramdisk', session, vm_ref, value)
+
+ def VM_set_PV_args(self, session, vm_ref, value):
+ return self.VM_set('PV_args', session, vm_ref, value)
+
+ def VM_set_PV_bootloader_args(self, session, vm_ref, value):
+ return self.VM_set('PV_bootloader_args', session, vm_ref, value)
+
def VM_set_platform_std_VGA(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success_void()
@@ -899,30 +917,6 @@ class XendAPI:
return xen_api_success_void()
def VM_set_platform_enable_audio(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def VM_set_builder(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def VM_set_boot_method(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def VM_set_kernel_kernel(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def VM_set_kernel_initrd(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def VM_set_kernel_args(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def VM_set_grub_cmdline(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success_void()
@@ -961,6 +955,7 @@ class XendAPI:
'name_description': xeninfo.getName(),
'user_version': 1,
'is_a_template': False,
+ 'auto_power_on': False,
'resident_on': XendNode.instance().uuid,
'memory_static_min': xeninfo.get_memory_static_min(),
'memory_static_max': xeninfo.get_memory_static_max(),
@@ -979,22 +974,22 @@ class XendAPI:
'actions_after_reboot': xeninfo.get_on_reboot(),
'actions_after_suspend': xeninfo.get_on_suspend(),
'actions_after_crash': xeninfo.get_on_crash(),
+ 'consoles': xeninfo.get_consoles(),
'VIFs': xeninfo.get_vifs(),
'VBDs': xeninfo.get_vbds(),
'VTPMs': xeninfo.get_vtpms(),
- 'bios_boot': xeninfo.get_bios_boot(),
+ 'PV_bootloader': xeninfo.info.get('PV_bootloader'),
+ 'PV_kernel': xeninfo.info.get('PV_kernel'),
+ 'PV_ramdisk': xeninfo.info.get('PV_ramdisk'),
+ 'PV_args': xeninfo.info.get('PV_args'),
+ 'PV_bootloader_args': xeninfo.info.get('PV_bootloader_args'),
+ 'HVM_boot': xeninfo.info.get('HVM_boot'),
'platform_std_VGA': xeninfo.get_platform_std_vga(),
'platform_serial': xeninfo.get_platform_serial(),
'platform_localtime': xeninfo.get_platform_localtime(),
'platform_clock_offset': xeninfo.get_platform_clock_offset(),
'platform_enable_audio': xeninfo.get_platform_enable_audio(),
'platform_keymap': xeninfo.get_platform_keymap(),
- 'builder': xeninfo.get_builder(),
- 'boot_method': xeninfo.get_boot_method(),
- 'kernel_kernel': xeninfo.get_kernel_image(),
- 'kernel_initrd': xeninfo.get_kernel_initrd(),
- 'kernel_args': xeninfo.get_kernel_args(),
- 'grub_cmdline': xeninfo.get_grub_cmdline(),
'PCI_bus': xeninfo.get_pci_bus(),
'tools_version': xeninfo.get_tools_version(),
'otherConfig': xeninfo.get_other_config()
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/xend/XendBootloader.py
--- a/tools/python/xen/xend/XendBootloader.py Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/xend/XendBootloader.py Fri Dec 15 11:32:58 2006 -0700
@@ -21,7 +21,8 @@ from XendLogging import log
from XendLogging import log
from XendError import VmError
-def bootloader(blexec, disk, quiet = 0, blargs = None, imgcfg = None):
+def bootloader(blexec, disk, quiet = False, blargs = '', kernel = '',
+ ramdisk = '', kernel_args = ''):
"""Run the boot loader executable on the given disk and return a
config image.
@param blexec Binary to use as the boot loader
@@ -55,18 +56,19 @@ def bootloader(blexec, disk, quiet = 0,
if quiet:
args.append("-q")
args.append("--output=%s" % fifo)
- if blargs is not None:
+ if blargs:
args.extend(shlex.split(blargs))
args.append(disk)
try:
+ log.debug("Launching bootloader as %s." % str(args))
os.execvp(args[0], args)
except OSError, e:
print e
pass
os._exit(1)
- while 1:
+ while True:
try:
r = os.open(fifo, os.O_RDONLY)
except OSError, e:
@@ -74,7 +76,7 @@ def bootloader(blexec, disk, quiet = 0,
continue
break
ret = ""
- while 1:
+ while True:
select.select([r], [], [])
s = os.read(r, 1024)
ret = ret + s
@@ -94,9 +96,4 @@ def bootloader(blexec, disk, quiet = 0,
pin.input(ret)
pin.input_eof()
blcfg = pin.val
-
- if imgcfg is None:
- return blcfg
- else:
- c = sxp.merge(blcfg, imgcfg)
- return c
+ return blcfg
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/xend/XendConfig.py Fri Dec 15 11:32:58 2006 -0700
@@ -103,7 +103,7 @@ XENAPI_HVM_CFG = {
'platform_keymap' : 'keymap',
}
-# List of XendConfig configuration keys that have no equivalent
+# List of XendConfig configuration keys that have no direct equivalent
# in the old world.
XENAPI_CFG_TYPES = {
@@ -132,19 +132,18 @@ XENAPI_CFG_TYPES = {
'actions_after_crash': str,
'tpm_instance': int,
'tpm_backend': int,
- 'bios_boot': str,
+ 'PV_bootloader': str,
+ 'PV_kernel': str,
+ 'PV_initrd': str,
+ 'PV_args': str,
+ 'PV_bootloader_args': str,
+ 'HVM_boot': str,
'platform_std_vga': bool0,
'platform_serial': str,
'platform_localtime': bool0,
'platform_clock_offset': bool0,
'platform_enable_audio': bool0,
'platform_keymap': str,
- 'boot_method': str,
- 'builder': str,
- 'kernel_kernel': str,
- 'kernel_initrd': str,
- 'kernel_args': str,
- 'grub_cmdline': str,
'pci_bus': str,
'tools_version': dict,
'otherconfig': dict,
@@ -160,8 +159,6 @@ LEGACY_UNSUPPORTED_BY_XENAPI_CFG = [
'vcpu_avail',
'cpu_weight',
'cpu_cap',
- 'bootloader',
- 'bootloader_args',
'features',
# read/write
'on_xend_start',
@@ -188,8 +185,6 @@ LEGACY_CFG_TYPES = {
'cpu_cap': int,
'cpu_weight': int,
'cpu_time': float,
- 'bootloader': str,
- 'bootloader_args': str,
'features': str,
'localtime': int,
'name': str,
@@ -331,16 +326,18 @@ class XendConfig(dict):
'actions_after_crash': 'restart',
'actions_after_suspend': '',
'features': '',
- 'builder': 'linux',
+ 'PV_bootloader': '',
+ 'PV_kernel': '',
+ 'PV_ramdisk': '',
+ 'PV_args': '',
+ 'PV_bootloader_args': '',
+ 'HVM_boot': '',
'memory_static_min': 0,
'memory_dynamic_min': 0,
'shadow_memory': 0,
'memory_static_max': 0,
'memory_dynamic_max': 0,
'memory_actual': 0,
- 'boot_method': None,
- 'bootloader': None,
- 'bootloader_args': None,
'devices': {},
'image': {},
'security': None,
@@ -353,6 +350,7 @@ class XendConfig(dict):
'online_vcpus': 1,
'max_vcpu_id': 0,
'vcpu_avail': 1,
+ 'console_refs': [],
'vif_refs': [],
'vbd_refs': [],
'vtpm_refs': [],
@@ -382,10 +380,6 @@ class XendConfig(dict):
raise XendConfigError('Invalid event handling mode: ' +
event)
- def _builder_sanity_check(self):
- if self['builder'] not in ('hvm', 'linux'):
- raise XendConfigError('Invalid builder configuration')
-
def _vcpus_sanity_check(self):
if self.get('vcpus_number') != None:
self['vcpu_avail'] = (1 << self['vcpus_number']) - 1
@@ -397,7 +391,6 @@ class XendConfig(dict):
def validate(self):
self._memory_sanity_check()
self._actions_sanity_check()
- self._builder_sanity_check()
self._vcpus_sanity_check()
self._uuid_sanity_check()
@@ -597,38 +590,18 @@ class XendConfig(dict):
except KeyError:
pass
- # Convert Legacy "image" config to Xen API kernel_*
- # configuration
+ self['PV_bootloader'] = cfg.get('bootloader', '')
+ self['PV_bootloader_args'] = cfg.get('bootloader_args', '')
+
image_sxp = sxp.child_value(sxp_cfg, 'image', [])
if image_sxp:
- self['kernel_kernel'] = sxp.child_value(image_sxp, 'kernel','')
- self['kernel_initrd'] = sxp.child_value(image_sxp, 'ramdisk','')
- kernel_args = sxp.child_value(image_sxp, 'args', '')
-
- # attempt to extract extra arguments from SXP config
- arg_ip = sxp.child_value(image_sxp, 'ip')
- if arg_ip and not re.search(r'ip=[^ ]+', kernel_args):
- kernel_args += ' ip=%s' % arg_ip
- arg_root = sxp.child_value(image_sxp, 'root')
- if arg_root and not re.search(r'root=[^ ]+', kernel_args):
- kernel_args += ' root=%s' % arg_root
-
- self['kernel_args'] = kernel_args
+ self.update_with_image_sxp(image_sxp)
# Convert Legacy HVM parameters to Xen API configuration
self['platform_std_vga'] = bool0(cfg.get('stdvga', 0))
self['platform_serial'] = str(cfg.get('serial', ''))
self['platform_localtime'] = bool0(cfg.get('localtime', 0))
self['platform_enable_audio'] = bool0(cfg.get('soundhw', 0))
-
- # Convert path to bootloader to boot_method
- if not cfg.get('bootloader'):
- if self.get('kernel_kernel','').endswith('hvmloader'):
- self['boot_method'] = 'bios'
- else:
- self['boot_method'] = 'kernel_external'
- else:
- self['boot_method'] = 'grub'
# make sure a sane maximum is set
if self['memory_static_max'] <= 0:
@@ -643,6 +616,7 @@ class XendConfig(dict):
# set device references in the configuration
self['devices'] = cfg.get('devices', {})
+ self['console_refs'] = []
self['vif_refs'] = []
self['vbd_refs'] = []
self['vtpm_refs'] = []
@@ -703,9 +677,6 @@ class XendConfig(dict):
if backend:
self['backend'] = backend
- if self['image'].has_key('hvm'):
- self['builder'] = 'hvm'
-
# Parse and convert other Non Xen API parameters.
def _set_cfg_if_exists(sxp_arg):
val = sxp.child_value(sxp_cfg, sxp_arg)
@@ -715,7 +686,6 @@ class XendConfig(dict):
else:
self[sxp_arg] = val
- _set_cfg_if_exists('bootloader')
_set_cfg_if_exists('shadow_memory')
_set_cfg_if_exists('security')
_set_cfg_if_exists('features')
@@ -739,8 +709,9 @@ class XendConfig(dict):
"""
# populate image
- self['image']['type'] = self['builder']
- if self['builder'] == 'hvm':
+ hvm = self['HVM_boot'] != ''
+ self['image']['type'] = hvm and 'hvm' or 'linux'
+ if hvm:
self['image']['hvm'] = {}
for xapi, cfgapi in XENAPI_HVM_CFG.items():
self['image']['hvm'][cfgapi] = self[xapi]
@@ -778,8 +749,10 @@ class XendConfig(dict):
@type xapi: dict
"""
for key, val in xapi.items():
- key = key.lower()
type_conv = XENAPI_CFG_TYPES.get(key)
+ if type_conv is None:
+ key = key.lower()
+ type_conv = XENAPI_CFG_TYPES.get(key)
if callable(type_conv):
self[key] = type_conv(val)
else:
@@ -1098,8 +1071,8 @@ class XendConfig(dict):
def update_with_image_sxp(self, image_sxp):
# Convert Legacy "image" config to Xen API kernel_*
# configuration
- self['kernel_kernel'] = sxp.child_value(image_sxp, 'kernel','')
- self['kernel_initrd'] = sxp.child_value(image_sxp, 'ramdisk','')
+ self['PV_kernel'] = sxp.child_value(image_sxp, 'kernel','')
+ self['PV_ramdisk'] = sxp.child_value(image_sxp, 'ramdisk','')
kernel_args = sxp.child_value(image_sxp, 'args', '')
# attempt to extract extra arguments from SXP config
@@ -1109,7 +1082,7 @@ class XendConfig(dict):
arg_root = sxp.child_value(image_sxp, 'root')
if arg_root and not re.search(r'root=', kernel_args):
kernel_args += ' root=%s' % arg_root
- self['kernel_args'] = kernel_args
+ self['PV_args'] = kernel_args
# Store image SXP in python dictionary format
image = {}
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/xend/XendDomain.py Fri Dec 15 11:32:58 2006 -0700
@@ -591,7 +591,9 @@ class XendDomain:
try:
self.domains_lock.acquire()
result = [d.get_uuid() for d in self.domains.values()]
- result += self.managed_domains.keys()
+ for d in self.managed_domains.keys():
+ if d not in result:
+ result.append(d)
return result
finally:
self.domains_lock.release()
@@ -1337,11 +1339,7 @@ class XendDomain:
dominfo = self.domain_lookup_nr(domid)
if not dominfo:
raise XendInvalidDomain(str(domid))
- maxmem = int(mem) * 1024
- try:
- return xc.domain_setmaxmem(dominfo.getDomid(), maxmem)
- except Exception, ex:
- raise XendError(str(ex))
+ dominfo.setMemoryMaximum(mem)
def domain_ioport_range_enable(self, domid, first, last):
"""Enable access to a range of IO ports for a domain
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/xend/XendDomainInfo.py Fri Dec 15 11:32:58 2006 -0700
@@ -51,71 +51,13 @@ from xen.xend.XendAPIConstants import *
from xen.xend.XendAPIConstants import *
MIGRATE_TIMEOUT = 30.0
+BOOTLOADER_LOOPBACK_DEVICE = '/dev/xvdp'
xc = xen.lowlevel.xc.xc()
xroot = XendRoot.instance()
log = logging.getLogger("xend.XendDomainInfo")
#log.setLevel(logging.TRACE)
-
-
-def bool0(v):
- return v != "0" and bool(v)
-
-
-##
-# All parameters of VMs that may be configured on-the-fly, or at start-up.
-#
-VM_CONFIG_PARAMS = [
- ('name', str),
- ('on_poweroff', str),
- ('on_reboot', str),
- ('on_crash', str),
- ]
-
-
-##
-# Configuration entries that we expect to round-trip -- be read from the
-# config file or xc, written to save-files (i.e. through sxpr), and reused as
-# config on restart or restore, all without munging. Some configuration
-# entries are munged for backwards compatibility reasons, or because they
-# don't come out of xc in the same form as they are specified in the config
-# file, so those are handled separately.
-ROUNDTRIPPING_CONFIG_ENTRIES = [
- ('uuid', str),
- ('vcpus', int),
- ('vcpu_avail', int),
- ('cpu_cap', int),
- ('cpu_weight', int),
- ('memory', int),
- ('shadow_memory', int),
- ('maxmem', int),
- ('bootloader', str),
- ('bootloader_args', str),
- ('features', str),
- ('localtime', bool0),
- ]
-
-ROUNDTRIPPING_CONFIG_ENTRIES += VM_CONFIG_PARAMS
-
-
-##
-# All entries written to the store. This is VM_CONFIG_PARAMS, plus those
-# entries written to the store that cannot be reconfigured on-the-fly.
-#
-VM_STORE_ENTRIES = [
- ('uuid', str),
- ('vcpus', int),
- ('vcpu_avail', int),
- ('memory', int),
- ('shadow_memory', int),
- ('maxmem', int),
- ('start_time', float),
- ('on_xend_start', str),
- ('on_xend_stop', str),
- ]
-
-VM_STORE_ENTRIES += VM_CONFIG_PARAMS
#
@@ -167,7 +109,7 @@ def recreate(info, priv):
@param xeninfo: Parsed configuration
@type xeninfo: Dictionary
- @param priv: TODO, unknown, something to do with memory
+ @param priv: Is a privileged domain (Dom 0)
@type priv: bool
@rtype: XendDomainInfo
@@ -381,7 +323,7 @@ class XendDomainInfo:
@type dompath: string
@keyword augment: Augment given info with xenstored VM info
@type augment: bool
- @keyword priv: Is a privledged domain (Dom 0) (TODO: really?)
+ @keyword priv: Is a privileged domain (Dom 0)
@type priv: bool
@keyword resume: Is this domain being resumed?
@type resume: bool
@@ -497,6 +439,7 @@ class XendDomainInfo:
xc.domain_pause(self.domid)
self._stateSet(DOM_STATE_PAUSED)
except Exception, ex:
+ log.exception(ex)
raise XendError("Domain unable to be paused: %s" % str(ex))
def unpause(self):
@@ -508,6 +451,7 @@ class XendDomainInfo:
xc.domain_unpause(self.domid)
self._stateSet(DOM_STATE_RUNNING)
except Exception, ex:
+ log.exception(ex)
raise XendError("Domain unable to be unpaused: %s" % str(ex))
def send_sysrq(self, key):
@@ -526,7 +470,8 @@ class XendDomainInfo:
dev_uuid = self.info.device_add(dev_type, cfg_sxp = dev_config)
dev_config_dict = self.info['devices'][dev_uuid][1]
log.debug("XendDomainInfo.device_create: %s" %
scrub_password(dev_config_dict))
- devid = self._createDevice(dev_type, dev_config_dict)
+ dev_config_dict['devid'] = devid = \
+ self._createDevice(dev_type, dev_config_dict)
self._waitForDevice(dev_type, devid)
return self.getDeviceController(dev_type).sxpr(devid)
@@ -563,7 +508,7 @@ class XendDomainInfo:
for devclass in XendDevices.valid_devices():
self.getDeviceController(devclass).waitForDevices()
- def destroyDevice(self, deviceClass, devid):
+ def destroyDevice(self, deviceClass, devid, force = False):
try:
devid = int(devid)
except ValueError:
@@ -578,7 +523,7 @@ class XendDomainInfo:
devid = entry
break
- return self.getDeviceController(deviceClass).destroyDevice(devid)
+ return self.getDeviceController(deviceClass).destroyDevice(devid,
force)
@@ -606,8 +551,34 @@ class XendDomainInfo:
raise XendError('Invalid memory size')
self.info['memory_static_min'] = target
- self.storeVm("memory", target)
- self.storeDom("memory/target", target << 10)
+ if self.domid >= 0:
+ self.storeVm("memory", target)
+ self.storeDom("memory/target", target << 10)
+ else:
+ self.info['memory_dynamic_min'] = target
+ xen.xend.XendDomain.instance().managed_config_save(self)
+
+ def setMemoryMaximum(self, limit):
+ """Set the maximum memory limit of this domain
+ @param limit: In MiB.
+ """
+ log.debug("Setting memory maximum of domain %s (%d) to %d MiB.",
+ self.info['name_label'], self.domid, limit)
+
+ if limit <= 0:
+ raise XendError('Invalid memory size')
+
+ self.info['memory_static_max'] = limit
+ if self.domid >= 0:
+ maxmem = int(limit) * 1024
+ try:
+ return xc.domain_setmaxmem(self.domid, maxmem)
+ except Exception, ex:
+ raise XendError(str(ex))
+ else:
+ self.info['memory_dynamic_max'] = limit
+ xen.xend.XendDomain.instance().managed_config_save(self)
+
def getVCPUInfo(self):
try:
@@ -647,6 +618,8 @@ class XendDomainInfo:
if priv:
augment_entries.remove('memory')
augment_entries.remove('maxmem')
+ augment_entries.remove('vcpus')
+ augment_entries.remove('vcpu_avail')
vm_config = self._readVMDetails([(k, XendConfig.LEGACY_CFG_TYPES[k])
for k in augment_entries])
@@ -663,6 +636,14 @@ class XendDomainInfo:
self.info[xapiarg] = val
else:
self.info[arg] = val
+
+ # For dom0, we ignore any stored value for the vcpus fields, and
+ # read the current value from Xen instead. This allows boot-time
+ # settings to take precedence over any entries in the store.
+ if priv:
+ xeninfo = dom_get(self.domid)
+ self.info['vcpus_number'] = xeninfo['online_vcpus']
+ self.info['vcpu_avail'] = (1 << xeninfo['online_vcpus']) - 1
# read image value
image_sxp = self._readVm('image')
@@ -876,18 +857,23 @@ class XendDomainInfo:
def setVCpuCount(self, vcpus):
self.info['vcpu_avail'] = (1 << vcpus) - 1
- self.storeVm('vcpu_avail', self.info['vcpu_avail'])
- # update dom differently depending on whether we are adjusting
- # vcpu number up or down, otherwise _vcpuDomDetails does not
- # disable the vcpus
- if self.info['vcpus_number'] > vcpus:
- # decreasing
- self._writeDom(self._vcpuDomDetails())
+ if self.domid >= 0:
+ self.storeVm('vcpu_avail', self.info['vcpu_avail'])
+ # update dom differently depending on whether we are adjusting
+ # vcpu number up or down, otherwise _vcpuDomDetails does not
+ # disable the vcpus
+ if self.info['vcpus_number'] > vcpus:
+ # decreasing
+ self._writeDom(self._vcpuDomDetails())
+ self.info['vcpus_number'] = vcpus
+ else:
+ # same or increasing
+ self.info['vcpus_number'] = vcpus
+ self._writeDom(self._vcpuDomDetails())
+ else:
self.info['vcpus_number'] = vcpus
- else:
- # same or increasing
- self.info['vcpus_number'] = vcpus
- self._writeDom(self._vcpuDomDetails())
+ self.info['online_vcpus'] = vcpus
+ xen.xend.XendDomain.instance().managed_config_save(self)
def getLabel(self):
return security.get_security_info(self.info, 'label')
@@ -895,6 +881,10 @@ class XendDomainInfo:
def getMemoryTarget(self):
"""Get this domain's target memory size, in KB."""
return self.info['memory_static_min'] * 1024
+
+ def getMemoryMaximum(self):
+ """Get this domain's maximum memory size, in KB."""
+ return self.info['memory_static_max'] * 1024
def getResume(self):
return str(self._resume)
@@ -1017,7 +1007,8 @@ class XendDomainInfo:
self.refresh_shutdown_lock.release()
if restart_reason:
- self._maybeRestart(restart_reason)
+ threading.Thread(target = self._maybeRestart,
+ args = (restart_reason,)).start()
#
@@ -1060,7 +1051,6 @@ class XendDomainInfo:
"""
from xen.xend import XendDomain
- self._configureBootloader()
config = self.sxpr()
if self._infoIsSet('cpus') and len(self.info['cpus']) != 0:
@@ -1186,6 +1176,10 @@ class XendDomainInfo:
def _waitForDevice(self, deviceClass, devid):
return self.getDeviceController(deviceClass).waitForDevice(devid)
+ def _waitForDeviceUUID(self, dev_uuid):
+ deviceClass, config = self.info['devices'].get(dev_uuid)
+ self._waitForDevice(deviceClass, config['devid'])
+
def _reconfigureDevice(self, deviceClass, devid, devconfig):
return self.getDeviceController(deviceClass).reconfigureDevice(
devid, devconfig)
@@ -1289,6 +1283,8 @@ class XendDomainInfo:
log.debug('XendDomainInfo.constructDomain')
+ self.shutdownStartTime = None
+
image_cfg = self.info.get('image', {})
hvm = image_cfg.has_key('hvm')
@@ -1333,10 +1329,7 @@ class XendDomainInfo:
self.domid,
self.info['cpu_weight'])
- # if we have a boot loader but no image, then we need to set things
- # up by running the boot loader non-interactively
- if self.info.get('bootloader'):
- self._configureBootloader()
+ self._configureBootloader()
if not self._infoIsSet('image'):
raise VmError('Missing image in configuration')
@@ -1363,9 +1356,9 @@ class XendDomainInfo:
# Use architecture- and image-specific calculations to determine
# the various headrooms necessary, given the raw configured
# values. maxmem, memory, and shadow are all in KiB.
+ memory = self.image.getRequiredAvailableMemory(
+ self.info['memory_static_min'] * 1024)
maxmem = self.image.getRequiredAvailableMemory(
- self.info['memory_static_min'] * 1024)
- memory = self.image.getRequiredAvailableMemory(
self.info['memory_static_max'] * 1024)
shadow = self.image.getRequiredShadowMemory(
self.info['shadow_memory'] * 1024,
@@ -1397,17 +1390,14 @@ class XendDomainInfo:
self._createDevices()
- if self.info['bootloader']:
- self.image.cleanupBootloading()
+ self.image.cleanupBootloading()
self.info['start_time'] = time.time()
self._stateSet(DOM_STATE_RUNNING)
except RuntimeError, exn:
log.exception("XendDomainInfo.initDomain: exception occurred")
- if self.info['bootloader'] not in (None, 'kernel_external') \
- and self.image is not None:
- self.image.cleanupBootloading()
+ self.image.cleanupBootloading()
raise VmError(str(exn))
@@ -1538,33 +1528,78 @@ class XendDomainInfo:
def _configureBootloader(self):
"""Run the bootloader if we're configured to do so."""
- if not self.info.get('bootloader'):
- return
- blcfg = None
-
- # FIXME: this assumes that we want to use the first disk device
- for (devtype, devinfo) in self.info.all_devices_sxpr():
- if not devtype or not devinfo or devtype not in ('vbd', 'tap'):
- continue
- disk = None
- for param in devinfo:
- if param[0] == 'uname':
- disk = param[1]
- break
-
- 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
- if blcfg is None:
- msg = "Had a bootloader specified, but can't find disk"
- log.error(msg)
- raise VmError(msg)
-
- self.info.update_with_image_sxp(blcfg)
+
+ blexec = self.info['PV_bootloader']
+ bootloader_args = self.info['PV_bootloader_args']
+ kernel = self.info['PV_kernel']
+ ramdisk = self.info['PV_ramdisk']
+ args = self.info['PV_args']
+ boot = self.info['HVM_boot']
+
+ if boot:
+ # HVM booting.
+ self.info['image']['type'] = 'hvm'
+ self.info['image']['devices']['boot'] = boot
+ elif not blexec and kernel:
+ # Boot from dom0. Nothing left to do -- the kernel and ramdisk
+ # will be picked up by image.py.
+ pass
+ else:
+ # Boot using bootloader
+ if not blexec or blexec == 'pygrub':
+ blexec = '/usr/bin/pygrub'
+
+ blcfg = None
+ for (devtype, devinfo) in self.info.all_devices_sxpr():
+ if not devtype or not devinfo or devtype not in ('vbd', 'tap'):
+ continue
+ disk = None
+ for param in devinfo:
+ if param[0] == 'uname':
+ disk = param[1]
+ break
+
+ if disk is None:
+ continue
+ fn = blkdev_uname_to_file(disk)
+ mounted = devtype == 'tap' and not os.stat(fn).st_rdev
+ if mounted:
+ # This is a file, not a device. pygrub can cope with a
+ # file if it's raw, but if it's QCOW or other such formats
+ # used through blktap, then we need to mount it first.
+
+ log.info("Mounting %s on %s." %
+ (fn, BOOTLOADER_LOOPBACK_DEVICE))
+
+ vbd = {
+ 'mode': 'RO',
+ 'device': BOOTLOADER_LOOPBACK_DEVICE,
+ }
+
+ from xen.xend import XendDomain
+ dom0 = XendDomain.instance().privilegedDomain()
+ dom0._waitForDeviceUUID(dom0.create_vbd_with_vdi(vbd, fn))
+ fn = BOOTLOADER_LOOPBACK_DEVICE
+
+ try:
+ blcfg = bootloader(blexec, fn, True,
+ bootloader_args, kernel, ramdisk, args)
+ finally:
+ if mounted:
+ log.info("Unmounting %s from %s." %
+ (fn, BOOTLOADER_LOOPBACK_DEVICE))
+
+ dom0.destroyDevice('tap', '/dev/xvdp')
+
+ break
+
+ if blcfg is None:
+ msg = "Had a bootloader specified, but can't find disk"
+ log.error(msg)
+ raise VmError(msg)
+
+ self.info.update_with_image_sxp(blcfg)
+
#
# VM Functions
@@ -1727,7 +1762,7 @@ class XendDomainInfo:
raise VmError("VM name '%s' already exists%s" %
(name,
dom.domid is not None and
- ("as domain %s" % str(dom.domid)) or ""))
+ (" as domain %s" % str(dom.domid)) or ""))
def update(self, info = None, refresh = True):
@@ -1809,8 +1844,6 @@ class XendDomainInfo:
return '' # TODO
def get_power_state(self):
return XEN_API_VM_POWER_STATE[self.state]
- def get_bios_boot(self):
- return '' # TODO
def get_platform_std_vga(self):
return self.info.get('platform_std_vga', False)
def get_platform_keymap(self):
@@ -1825,18 +1858,6 @@ class XendDomainInfo:
return self.info.get('platform_enable_audio', False)
def get_platform_keymap(self):
return self.info.get('platform_keymap', '')
- def get_builder(self):
- return self.info.get('builder', 0)
- def get_boot_method(self):
- return self.info.get('boot_method', XEN_API_BOOT_TYPE[2])
- def get_kernel_image(self):
- return self.info.get('kernel_kernel', '')
- def get_kernel_initrd(self):
- return self.info.get('kernel_initrd', '')
- def get_kernel_args(self):
- return self.info.get('kernel_args', '')
- def get_grub_cmdline(self):
- return '' # TODO
def get_pci_bus(self):
return '' # TODO
def get_tools_version(self):
@@ -1972,6 +1993,9 @@ class XendDomainInfo:
return vcpu_util
+ def get_consoles(self):
+ return self.info.get('console_refs', [])
+
def get_vifs(self):
return self.info.get('vif_refs', [])
@@ -1992,10 +2016,9 @@ class XendDomainInfo:
if not dev_uuid:
raise XendError('Failed to create device')
- if self.state in (XEN_API_VM_POWER_STATE_RUNNING,):
- sxpr = self.info.device_sxpr(dev_uuid)
- devid = self.getDeviceController('vbd').createDevice(sxpr)
- raise XendError("Device creation failed")
+ if self.state == XEN_API_VM_POWER_STATE_RUNNING:
+ _, config = self.info['devices'][dev_uuid]
+ config['devid'] =
self.getDeviceController('vbd').createDevice(config)
return dev_uuid
@@ -2013,10 +2036,9 @@ class XendDomainInfo:
if not dev_uuid:
raise XendError('Failed to create device')
- if self.state in (XEN_API_VM_POWER_STATE_RUNNING,):
- sxpr = self.info.device_sxpr(dev_uuid)
- devid = self.getDeviceController('tap').createDevice(sxpr)
- raise XendError("Device creation failed")
+ if self.state == XEN_API_VM_POWER_STATE_RUNNING:
+ _, config = self.info['devices'][dev_uuid]
+ config['devid'] =
self.getDeviceController('tap').createDevice(config)
return dev_uuid
@@ -2031,10 +2053,9 @@ class XendDomainInfo:
if not dev_uuid:
raise XendError('Failed to create device')
- if self.state in (DOM_STATE_HALTED,):
- sxpr = self.info.device_sxpr(dev_uuid)
- devid = self.getDeviceController('vif').createDevice(sxpr)
- raise XendError("Device creation failed")
+ if self.state == XEN_API_VM_POWER_STATE_RUNNING:
+ _, config = self.info['devices'][dev_uuid]
+ config['devid'] =
self.getDeviceController('vif').createDevice(config)
return dev_uuid
diff -r 1e042dde1a5f -r e17d7438e09e
tools/python/xen/xend/XendStorageRepository.py
--- a/tools/python/xen/xend/XendStorageRepository.py Fri Dec 15 10:59:33
2006 -0700
+++ b/tools/python/xen/xend/XendStorageRepository.py Fri Dec 15 11:32:58
2006 -0700
@@ -20,6 +20,7 @@
#
import commands
+import logging
import os
import stat
import threading
@@ -33,9 +34,12 @@ XEND_STORAGE_DIR = "/var/lib/xend/storag
XEND_STORAGE_DIR = "/var/lib/xend/storage/"
XEND_STORAGE_QCOW_FILENAME = "%s.qcow"
XEND_STORAGE_VDICFG_FILENAME = "%s.vdi.xml"
-QCOW_CREATE_COMMAND = "/usr/sbin/qcow-create %d %s"
-
-MB = 1024 *1024
+QCOW_CREATE_COMMAND = "/usr/sbin/qcow-create -p %d %s"
+
+MB = 1024 * 1024
+
+log = logging.getLogger("xend.XendStorageRepository")
+
class DeviceInvalidError(Exception):
pass
@@ -89,8 +93,7 @@ class XendStorageRepository:
open(uuid_file, 'w').write(new_uuid + '\n')
return new_uuid
except IOError:
- # TODO: log warning
- pass
+ log.exception("Failed to determine SR UUID")
return uuid.createString()
@@ -229,8 +232,7 @@ class XendStorageRepository:
if cfg_path and os.path.exists(cfg_path):
os.unlink(cfg_path)
except OSError:
- # TODO: log warning
- pass
+ log.exception("Failed to destroy image")
del self.images[image_uuid]
return True
finally:
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/xend/image.py Fri Dec 15 11:32:58 2006 -0700
@@ -68,6 +68,7 @@ class ImageHandler:
def __init__(self, vm, vmConfig, imageConfig, deviceConfig):
self.vm = vm
+ self.bootloader = None
self.kernel = None
self.ramdisk = None
self.cmdline = None
@@ -76,9 +77,10 @@ class ImageHandler:
def configure(self, vmConfig, imageConfig, _):
"""Config actions common to all unix-like domains."""
- self.kernel = vmConfig['kernel_kernel']
- self.cmdline = vmConfig['kernel_args']
- self.ramdisk = vmConfig['kernel_initrd']
+ self.bootloader = vmConfig['PV_bootloader']
+ self.kernel = vmConfig['PV_kernel']
+ self.cmdline = vmConfig['PV_args']
+ self.ramdisk = vmConfig['PV_ramdisk']
self.vm.storeVm(("image/ostype", self.ostype),
("image/kernel", self.kernel),
("image/cmdline", self.cmdline),
@@ -86,8 +88,9 @@ class ImageHandler:
def cleanupBootloading(self):
- self.unlink(self.kernel)
- self.unlink(self.ramdisk)
+ if self.bootloader:
+ self.unlink(self.kernel)
+ self.unlink(self.ramdisk)
def unlink(self, f):
@@ -145,6 +148,14 @@ class ImageHandler:
add headroom where necessary."""
return self.getRequiredAvailableMemory(self.vm.getMemoryTarget())
+ def getRequiredMaximumReservation(self):
+ """@param mem_kb The maximum possible memory, in KiB.
+ @return The corresponding required amount of memory to be free, also
+ in KiB. This is normally the same as getRequiredAvailableMemory, but
+ architecture- or image-specific code may override this to
+ add headroom where necessary."""
+ return self.getRequiredAvailableMemory(self.vm.getMemoryMaximum())
+
def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
"""@param shadow_mem_kb The configured shadow memory, in KiB.
@param maxmem_kb The configured maxmem, in KiB.
@@ -234,6 +245,60 @@ class PPC_LinuxImageHandler(LinuxImageHa
ramdisk = self.ramdisk,
features = self.vm.getFeatures(),
arch_args = devtree.to_bin())
+
+ def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
+ """@param shadow_mem_kb The configured shadow memory, in KiB.
+ @param maxmem_kb The configured maxmem, in KiB.
+ @return The corresponding required amount of shadow memory, also in
+ KiB.
+ PowerPC currently uses "shadow memory" to refer to the hash table."""
+ return max(maxmem_kb / 64, shadow_mem_kb)
+
+
+class PPC_ProseImageHandler(LinuxImageHandler):
+
+ ostype = "prose"
+
+ def configure(self, imageConfig, deviceConfig):
+ LinuxImageHandler.configure(self, imageConfig, deviceConfig)
+ self.imageConfig = imageConfig
+
+ def buildDomain(self):
+ store_evtchn = self.vm.getStorePort()
+ console_evtchn = self.vm.getConsolePort()
+
+ mem_mb = self.getRequiredInitialReservation() / 1024
+
+ log.debug("dom = %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())
+
+ devtree = FlatDeviceTree.build(self)
+
+ return xc.arch_prose_build(dom = 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(),
+ arch_args = devtree.to_bin())
+
+ def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
+ """@param shadow_mem_kb The configured shadow memory, in KiB.
+ @param maxmem_kb The configured maxmem, in KiB.
+ @return The corresponding required amount of shadow memory, also in
+ KiB.
+ PowerPC currently uses "shadow memory" to refer to the hash table."""
+ return max(maxmem_kb / 64, shadow_mem_kb)
+
class HVMImageHandler(ImageHandler):
@@ -539,6 +604,9 @@ class X86_HVM_ImageHandler(HVMImageHandl
def getRequiredInitialReservation(self):
return self.vm.getMemoryTarget()
+ def getRequiredMaximumReservation(self):
+ return self.vm.getMemoryMaximum()
+
def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
# 256 pages (1MB) per vcpu,
# plus 1 page per MiB of RAM for the P2M map,
@@ -553,13 +621,14 @@ class X86_Linux_ImageHandler(LinuxImageH
def buildDomain(self):
# set physical mapping limit
# add an 8MB slack to balance backend allocations.
- mem_kb = self.getRequiredInitialReservation() + (8 * 1024)
+ mem_kb = self.getRequiredMaximumReservation() + (8 * 1024)
xc.domain_set_memmap_limit(self.vm.getDomid(), mem_kb)
return LinuxImageHandler.buildDomain(self)
_handlers = {
"powerpc": {
"linux": PPC_LinuxImageHandler,
+ "prose": PPC_ProseImageHandler,
},
"ia64": {
"linux": LinuxImageHandler,
diff -r 1e042dde1a5f -r e17d7438e09e
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py Fri Dec 15 10:59:33
2006 -0700
+++ b/tools/python/xen/xend/server/DevController.py Fri Dec 15 11:32:58
2006 -0700
@@ -19,12 +19,14 @@ from threading import Event
from threading import Event
import types
-from xen.xend import sxp
+from xen.xend import sxp, XendRoot
from xen.xend.XendError import VmError
from xen.xend.XendLogging import log
from xen.xend.xenstore.xstransact import xstransact, complete
from xen.xend.xenstore.xswatch import xswatch
+
+import os
DEVICE_CREATE_TIMEOUT = 100
HOTPLUG_STATUS_NODE = "hotplug-status"
@@ -47,6 +49,8 @@ xenbusState = {
'Closing' : 5,
'Closed' : 6,
}
+
+xroot = XendRoot.instance()
xenbusState.update(dict(zip(xenbusState.values(), xenbusState.keys())))
@@ -151,13 +155,13 @@ class DevController:
status = self.waitForBackend(devid)
if status == Timeout:
- self.destroyDevice(devid)
+ self.destroyDevice(devid, False)
raise VmError("Device %s (%s) could not be connected. "
"Hotplug scripts not working." %
(devid, self.deviceClass))
elif status == Error:
- self.destroyDevice(devid)
+ self.destroyDevice(devid, False)
raise VmError("Device %s (%s) could not be connected. "
"Backend device not found." %
(devid, self.deviceClass))
@@ -176,7 +180,7 @@ class DevController:
if not err:
err = "Busy."
- self.destroyDevice(devid)
+ self.destroyDevice(devid, False)
raise VmError("Device %s (%s) could not be connected.\n%s" %
(devid, self.deviceClass, err))
@@ -191,7 +195,7 @@ class DevController:
raise VmError('%s devices may not be reconfigured' % self.deviceClass)
- def destroyDevice(self, devid):
+ def destroyDevice(self, devid, force):
"""Destroy the specified device.
@param devid The device ID, or something device-specific from which
@@ -211,6 +215,13 @@ class DevController:
# drivers, so this ordering avoids a race).
self.writeBackend(devid, 'online', "0")
self.writeBackend(devid, 'state', str(xenbusState['Closing']))
+
+ if force:
+ frontpath = self.frontendPath(devid)
+ backpath = xstransact.Read(frontpath, "backend")
+ if backpath:
+ xstransact.Remove(backpath)
+ xstransact.Remove(frontpath)
def configurations(self):
@@ -313,6 +324,16 @@ class DevController:
Make sure that the migration has finished and only
then return from the call.
"""
+ tool = xroot.get_external_migration_tool()
+ if tool:
+ log.info("Calling external migration tool for step %d" % step)
+ fd = os.popen("%s -type %s -step %d -host %s -domname %s" %
+ (tool, self.deviceClass, step, dst, domName))
+ for line in fd:
+ log.info(line.rstrip())
+ rc = fd.close()
+ if rc:
+ raise VmError('Migration tool returned %d' % (rc >> 8))
return 0
@@ -320,6 +341,16 @@ class DevController:
""" Recover from device migration. The given step was the
last one that was successfully executed.
"""
+ tool = xroot.get_external_migration_tool()
+ if tool:
+ log.info("Calling external migration tool")
+ fd = os.popen("%s -type %s -step %d -host %s -domname %s -recover"
%
+ (tool, self.deviceClass, step, dst, domName))
+ for line in fd:
+ log.info(line.rstrip())
+ rc = fd.close()
+ if rc:
+ raise VmError('Migration tool returned %d' % (rc >> 8))
return 0
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/xend/server/SrvDomain.py
--- a/tools/python/xen/xend/server/SrvDomain.py Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/xend/server/SrvDomain.py Fri Dec 15 11:32:58 2006 -0700
@@ -160,12 +160,9 @@ class SrvDomain(SrvDir):
return val
def op_maxmem_set(self, _, req):
- fn = FormFn(self.xd.domain_maxmem_set,
- [['dom', 'int'],
- ['memory', 'int']])
- val = fn(req.args, {'dom': self.dom.domid})
- return val
-
+ return self.call(self.dom.setMemoryMaximum,
+ [['memory', 'int']],
+ req)
def call(self, fn, args, req):
return FormFn(fn, args)(req.args)
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/xend/server/blkif.py
--- a/tools/python/xen/xend/server/blkif.py Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/xend/server/blkif.py Fri Dec 15 11:32:58 2006 -0700
@@ -133,7 +133,7 @@ class BlkifController(DevController):
return config
- def destroyDevice(self, devid):
+ def destroyDevice(self, devid, force):
"""@see DevController.destroyDevice"""
# If we are given a device name, then look up the device ID from it,
@@ -142,13 +142,13 @@ class BlkifController(DevController):
# superclass's method.
try:
- DevController.destroyDevice(self, int(devid))
+ DevController.destroyDevice(self, int(devid), force)
except ValueError:
devid_end = type(devid) is str and devid.split('/')[-1] or None
for i in self.deviceIDs():
d = self.readBackend(i, 'dev')
if d == devid or (devid_end and d == devid_end):
- DevController.destroyDevice(self, i)
+ DevController.destroyDevice(self, i, force)
return
raise VmError("Device %s not connected" % devid)
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/xm/XenAPI.py
--- a/tools/python/xen/xm/XenAPI.py Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/xm/XenAPI.py Fri Dec 15 11:32:58 2006 -0700
@@ -82,7 +82,7 @@ class Session(xen.util.xmlrpclib2.Server
self._session = None
- def _xen_request(self, methodname, params):
+ def xenapi_request(self, methodname, params):
full_params = (self._session,) + params
return _parse_result(getattr(self, methodname)(*full_params))
@@ -94,7 +94,7 @@ class Session(xen.util.xmlrpclib2.Server
def __getattr__(self, name):
if name == 'xenapi':
- return _Dispatcher(self._xen_request, None)
+ return _Dispatcher(self.xenapi_request, None)
elif name.startswith('login'):
return lambda u, p: self._login(name, u, p)
else:
diff -r 1e042dde1a5f -r e17d7438e09e tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/python/xen/xm/main.py Fri Dec 15 11:32:58 2006 -0700
@@ -22,7 +22,10 @@
"""Grand unified management application for Xen.
"""
import atexit
+import cmd
import os
+import pprint
+import shlex
import sys
import re
import getopt
@@ -77,6 +80,8 @@ USAGE_FOOTER = '<Domain> can either be t
SUBCOMMAND_HELP = {
# common commands
+
+ 'shell' : ('', 'Launch an interactive shell.'),
'console' : ('[-q|--quiet] <Domain>',
'Attach to <Domain>\'s console.'),
@@ -142,14 +147,15 @@ SUBCOMMAND_HELP = {
'Create a new virtual block device.'),
'block-configure': ('<Domain> <BackDev> <FrontDev> <Mode> [BackDomain]',
'Change block device configuration'),
- 'block-detach' : ('<Domain> <DevId>',
+ 'block-detach' : ('<Domain> <DevId> [-f|--force]',
'Destroy a domain\'s virtual block device.'),
'block-list' : ('<Domain> [--long]',
'List virtual block devices for a domain.'),
- 'network-attach': ('<Domain> [--script=<script>] [--ip=<ip>] '
- '[--mac=<mac>]',
+ 'network-attach': ('<Domain> [type=<type>] [mac=<mac>] [bridge=<bridge>] '
+ '[ip=<ip>] [script=<script>] [backend=<BackDomain>] '
+ '[vifname=<name>]',
'Create a new virtual network device.'),
- 'network-detach': ('<Domain> <DevId>',
+ 'network-detach': ('<Domain> <DevId> [-f|--force]',
'Destroy a domain\'s virtual network device.'),
'network-list' : ('<Domain> [--long]',
'List virtual network interfaces for a domain.'),
@@ -245,6 +251,7 @@ common_commands = [
"restore",
"resume",
"save",
+ "shell",
"shutdown",
"start",
"suspend",
@@ -328,7 +335,7 @@ acm_commands = [
]
all_commands = (domain_commands + host_commands + scheduler_commands +
- device_commands + vnet_commands + acm_commands)
+ device_commands + vnet_commands + acm_commands + ['shell'])
##
@@ -362,6 +369,7 @@ def parseAuthentication():
server.getAttribute('password'))
serverType, serverURI = parseServer()
+server = None
####################################################################
@@ -455,12 +463,16 @@ def longHelp():
print
print USAGE_FOOTER
+def _usage(cmd):
+ """ Print help usage information """
+ if cmd:
+ cmdHelp(cmd)
+ else:
+ shortHelp()
+
def usage(cmd = None):
""" Print help usage information and exits """
- if cmd:
- cmdHelp(cmd)
- else:
- shortHelp()
+ _usage(cmd)
sys.exit(1)
@@ -523,6 +535,49 @@ def get_single_vm(dom):
dominfo = server.xend.domain(dom, False)
return dominfo['uuid']
+##
+#
+# Xen-API Shell
+#
+##
+
+class Shell(cmd.Cmd):
+ def __init__(self):
+ cmd.Cmd.__init__(self)
+ self.prompt = "xm> "
+
+ def default(self, line):
+ words = shlex.split(line)
+ if len(words) > 0 and words[0] == 'xm':
+ words = words[1:]
+ if len(words) > 0:
+ cmd = xm_lookup_cmd(words[0])
+ if cmd:
+ _run_cmd(cmd, words[0], words[1:])
+ elif serverType == SERVER_XEN_API:
+ ok, res = _run_cmd(lambda x: server.xenapi_request(words[0],
+ tuple(x)),
+ words[0], words[1:])
+ if ok and res != '':
+ pprint.pprint(res)
+ else:
+ print '*** Unknown command: %s' % words[0]
+ return False
+
+ def emptyline(self):
+ pass
+
+ def do_EOF(self, line):
+ print
+ sys.exit(0)
+
+ def do_help(self, line):
+ _usage(line)
+
+
+def xm_shell(args):
+ Shell().cmdloop('The Xen Master. Type "help" for a list of functions.')
+
#########################################################################
#
@@ -554,7 +609,7 @@ def xm_restore(args):
(options, params) = getopt.gnu_getopt(args, 'p', ['paused'])
except getopt.GetoptError, opterr:
err(opterr)
- sys.exit(1)
+ usage('restore')
paused = False
for (k, v) in options:
@@ -564,7 +619,6 @@ def xm_restore(args):
if len(params) != 1:
err("Wrong number of parameters")
usage('restore')
- sys.exit(1)
savefile = os.path.abspath(params[0])
@@ -594,7 +648,6 @@ def xm_list(args):
except getopt.GetoptError, opterr:
err(opterr)
usage('list')
- sys.exit(1)
for (k, v) in options:
if k in ['-l', '--long']:
@@ -709,7 +762,7 @@ def xm_vcpu_list(args):
dominfo = map(server.xend.domain.getVCPUInfo, doms)
print '%-32s %3s %5s %5s %5s %9s %s' % \
- ('Name', 'ID', 'VCPUs', 'CPU', 'State', 'Time(s)', 'CPU Affinity')
+ ('Name', 'ID', 'VCPU', 'CPU', 'State', 'Time(s)', 'CPU Affinity')
format = '%(name)-32s %(domid)3d %(number)5d %(c)5s %(s)5s ' \
' %(cpu_time)8.1f %(cpumap)s'
@@ -815,7 +868,7 @@ def xm_start(args):
(options, params) = getopt.gnu_getopt(args, 'p', ['paused'])
except getopt.GetoptError, opterr:
err(opterr)
- sys.exit(1)
+ usage('start')
paused = False
for (k, v) in options:
@@ -825,7 +878,6 @@ def xm_start(args):
if len(params) != 1:
err("Wrong number of parameters")
usage('start')
- sys.exit(1)
dom = params[0]
if serverType == SERVER_XEN_API:
@@ -856,7 +908,7 @@ def xm_resume(args):
(options, params) = getopt.gnu_getopt(args, 'p', ['paused'])
except getopt.GetoptError, opterr:
err(opterr)
- sys.exit(1)
+ usage('resume')
paused = False
for (k, v) in options:
@@ -866,7 +918,6 @@ def xm_resume(args):
if len(params) != 1:
err("Wrong number of parameters")
usage('resume')
- sys.exit(1)
dom = params[0]
if serverType == SERVER_XEN_API:
@@ -1061,7 +1112,7 @@ def xm_sched_sedf(args):
['period=', 'slice=', 'latency=', 'extratime=', 'weight='])
except getopt.GetoptError, opterr:
err(opterr)
- sys.exit(1)
+ usage('sched-sedf')
# convert to nanoseconds if needed
for (k, v) in options:
@@ -1122,7 +1173,6 @@ def xm_sched_credit(args):
except getopt.GetoptError, opterr:
err(opterr)
usage('sched-credit')
- sys.exit(1)
domain = None
weight = None
@@ -1140,7 +1190,6 @@ def xm_sched_credit(args):
# place holder for system-wide scheduler parameters
err("No domain given.")
usage('sched-credit')
- sys.exit(1)
if weight is None and cap is None:
print server.xend.domain.sched_credit_get(domain)
@@ -1169,7 +1218,7 @@ def xm_console(args):
(options, params) = getopt.gnu_getopt(args, 'q', ['quiet'])
except getopt.GetoptError, opterr:
err(opterr)
- sys.exit(1)
+ usage('console')
for (k, v) in options:
if k in ['-q', '--quiet']:
@@ -1180,7 +1229,6 @@ def xm_console(args):
if len(params) != 1:
err('No domain given')
usage('console')
- sys.exit(1)
dom = params[0]
@@ -1208,7 +1256,7 @@ def xm_uptime(args):
(options, params) = getopt.gnu_getopt(args, 's', ['short'])
except getopt.GetoptError, opterr:
err(opterr)
- sys.exit(1)
+ usage('uptime')
for (k, v) in options:
if k in ['-s', '--short']:
@@ -1273,7 +1321,7 @@ def xm_dmesg(args):
(options, params) = getopt.gnu_getopt(args, 'c', ['clear'])
except getopt.GetoptError, opterr:
err(opterr)
- sys.exit(1)
+ usage('dmesg')
use_clear = 0
for (k, v) in options:
@@ -1283,7 +1331,6 @@ def xm_dmesg(args):
if len(params) :
err("No parameter required")
usage('dmesg')
- sys.exit(1)
if not use_clear:
print server.xend.node.dmesg.info()
@@ -1493,16 +1540,24 @@ def xm_network_attach(args):
def detach(args, command, deviceClass):
- arg_check(args, command, 2)
+ arg_check(args, command, 2, 3)
dom = args[0]
dev = args[1]
-
- server.xend.domain.destroyDevice(dom, deviceClass, dev)
+ try:
+ force = args[2]
+ if (force != "--force") and (force != "-f"):
+ print "Ignoring option %s"%(force)
+ force = None
+ except IndexError:
+ force = None
+
+ server.xend.domain.destroyDevice(dom, deviceClass, dev, force)
def xm_block_detach(args):
detach(args, 'block-detach', 'vbd')
+ detach(args, 'block-detach', 'tap')
def xm_network_detach(args):
@@ -1514,7 +1569,7 @@ def xm_vnet_list(args):
(options, params) = getopt.gnu_getopt(args, 'l', ['long'])
except getopt.GetoptError, opterr:
err(opterr)
- sys.exit(1)
+ usage('vnet-list')
use_long = 0
for (k, v) in options:
@@ -1552,6 +1607,7 @@ def xm_vnet_delete(args):
server.xend_vnet_delete(vnet)
commands = {
+ "shell": xm_shell,
# console commands
"console": xm_console,
# xenstat commands
@@ -1655,17 +1711,13 @@ def xm_lookup_cmd(cmd):
# only execute if there is only 1 match
if len(same_prefix_cmds) == 1:
return same_prefix_cmds[0]
-
- err('Sub Command %s not found!' % cmd)
- usage()
+ return None
def deprecated(old,new):
print >>sys.stderr, (
"Command %s is deprecated. Please use xm %s instead." % (old, new))
def main(argv=sys.argv):
- global server
-
if len(argv) < 2:
usage()
@@ -1674,16 +1726,26 @@ def main(argv=sys.argv):
if help in argv[1:]:
if help == argv[1]:
longHelp()
+ sys.exit(0)
else:
usage(argv[1])
- sys.exit(0)
-
- cmd = xm_lookup_cmd(argv[1])
-
- # strip off prog name and subcmd
- args = argv[2:]
+
+ cmd_name = argv[1]
+ cmd = xm_lookup_cmd(cmd_name)
if cmd:
- try:
+ # strip off prog name and subcmd
+ args = argv[2:]
+ _, rc = _run_cmd(cmd, cmd_name, args)
+ sys.exit(rc)
+ else:
+ err('Subcommand %s not found!' % cmd_name)
+ usage()
+
+def _run_cmd(cmd, cmd_name, args):
+ global server
+
+ try:
+ if server is None:
if serverType == SERVER_XEN_API:
server = XenAPI.Session(serverURI)
username, password = parseAuthentication()
@@ -1697,66 +1759,55 @@ def main(argv=sys.argv):
else:
server = ServerProxy(serverURI)
- rc = cmd(args)
- if rc:
- usage()
- except socket.error, ex:
- if os.geteuid() != 0:
- err("Most commands need root access. Please try again as
root.")
- else:
- err("Unable to connect to xend: %s. Is xend running?" % ex[1])
- sys.exit(1)
- except KeyboardInterrupt:
- print "Interrupted."
- sys.exit(1)
- except IOError, ex:
- if os.geteuid() != 0:
- err("Most commands need root access. Please try again as
root.")
- else:
- err("Unable to connect to xend: %s." % ex[1])
- sys.exit(1)
- except SystemExit:
- sys.exit(1)
- except XenAPI.Failure, exn:
- err(str(exn))
- sys.exit(1)
- except xmlrpclib.Fault, ex:
- if ex.faultCode == XendClient.ERROR_INVALID_DOMAIN:
- err("Domain '%s' does not exist." % ex.faultString)
- else:
- err(ex.faultString)
- usage(argv[1])
- sys.exit(1)
- except xmlrpclib.ProtocolError, ex:
- if ex.errcode == -1:
- print >>sys.stderr, (
- "Xend has probably crashed! Invalid or missing HTTP "
- "status code.")
- else:
- print >>sys.stderr, (
- "Xend has probably crashed! ProtocolError(%d, %s)." %
- (ex.errcode, ex.errmsg))
- sys.exit(1)
- except (ValueError, OverflowError):
- err("Invalid argument.")
- usage(argv[1])
- sys.exit(1)
- except OptionError, e:
- err(str(e))
- usage(argv[1])
- print e.usage()
- sys.exit(1)
- except security.ACMError, e:
- err(str(e))
- sys.exit(1)
- except:
- print "Unexpected error:", sys.exc_info()[0]
- print
- print "Please report to xen-devel@xxxxxxxxxxxxxxxxxxx"
- raise
-
- else:
- usage()
+ return True, cmd(args)
+ except socket.error, ex:
+ if os.geteuid() != 0:
+ err("Most commands need root access. Please try again as root.")
+ else:
+ err("Unable to connect to xend: %s. Is xend running?" % ex[1])
+ except KeyboardInterrupt:
+ print "Interrupted."
+ return True, ''
+ except IOError, ex:
+ if os.geteuid() != 0:
+ err("Most commands need root access. Please try again as root.")
+ else:
+ err("Unable to connect to xend: %s." % ex[1])
+ except SystemExit, code:
+ return code == 0, code
+ except XenAPI.Failure, exn:
+ err(str(exn))
+ except xmlrpclib.Fault, ex:
+ if ex.faultCode == XendClient.ERROR_INVALID_DOMAIN:
+ err("Domain '%s' does not exist." % ex.faultString)
+ else:
+ err(ex.faultString)
+ _usage(cmd_name)
+ except xmlrpclib.ProtocolError, ex:
+ if ex.errcode == -1:
+ print >>sys.stderr, (
+ "Xend has probably crashed! Invalid or missing HTTP "
+ "status code.")
+ else:
+ print >>sys.stderr, (
+ "Xend has probably crashed! ProtocolError(%d, %s)." %
+ (ex.errcode, ex.errmsg))
+ except (ValueError, OverflowError):
+ err("Invalid argument.")
+ _usage(cmd_name)
+ except OptionError, e:
+ err(str(e))
+ _usage(cmd_name)
+ print e.usage()
+ except security.ACMError, e:
+ err(str(e))
+ except:
+ print "Unexpected error:", sys.exc_info()[0]
+ print
+ print "Please report to xen-devel@xxxxxxxxxxxxxxxxxxx"
+ raise
+
+ return False, 1
if __name__ == "__main__":
main()
diff -r 1e042dde1a5f -r e17d7438e09e tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Fri Dec 15 10:59:33 2006 -0700
+++ b/tools/xenstore/xenstored_domain.c Fri Dec 15 11:32:58 2006 -0700
@@ -459,6 +459,8 @@ static int dom0_init(void)
return -1;
dom0 = new_domain(NULL, 0, port);
+ if (dom0 == NULL)
+ return -1;
dom0->interface = xenbus_map();
if (dom0->interface == NULL)
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/ia64/xen/xensetup.c
--- a/xen/arch/ia64/xen/xensetup.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/ia64/xen/xensetup.c Fri Dec 15 11:32:58 2006 -0700
@@ -51,7 +51,7 @@ extern void xen_patch_kernel(void);
extern void xen_patch_kernel(void);
/* opt_nosmp: If true, secondary processors are ignored. */
-static int opt_nosmp = 0;
+static int opt_nosmp;
boolean_param("nosmp", opt_nosmp);
/* maxcpus: maximum number of CPUs to activate. */
@@ -65,7 +65,7 @@ integer_param("xencons", opt_xencons);
integer_param("xencons", opt_xencons);
/* Toggle to allow non-legacy xencons UARTs to run in polling mode */
-static int opt_xencons_poll = 0;
+static int opt_xencons_poll;
boolean_param("xencons_poll", opt_xencons_poll);
/*
@@ -163,7 +163,7 @@ struct ns16550_defaults ns16550_com2 = {
};
/* efi_print: print efi table at boot */
-static int opt_efi_print = 0;
+static int opt_efi_print;
boolean_param("efi_print", opt_efi_print);
/* print EFI memory map: */
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/Makefile
--- a/xen/arch/powerpc/Makefile Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/Makefile Fri Dec 15 11:32:58 2006 -0700
@@ -9,10 +9,10 @@ obj-y += backtrace.o
obj-y += backtrace.o
obj-y += bitops.o
obj-y += boot_of.o
+obj-y += cmdline.o
obj-y += dart.o
obj-y += dart_u3.o
obj-y += dart_u4.o
-obj-y += delay.o
obj-y += domctl.o
obj-y += domain_build.o
obj-y += domain.o
@@ -22,11 +22,12 @@ obj-y += hcalls.o
obj-y += hcalls.o
obj-y += iommu.o
obj-y += irq.o
-obj-y += mambo.o
+obj-y += systemsim.o
obj-y += memory.o
obj-y += mm.o
obj-y += mpic.o
obj-y += mpic_init.o
+obj-y += numa.o
obj-y += of-devtree.o
obj-y += of-devwalk.o
obj-y += ofd_fixup.o
@@ -36,6 +37,7 @@ obj-y += setup.o
obj-y += setup.o
obj-y += shadow.o
obj-y += smp.o
+obj-y += smpboot.o
obj-y += smp-tbsync.o
obj-y += sysctl.o
obj-y += time.o
@@ -57,11 +59,6 @@ PPC_C_WARNINGS += -Wshadow
PPC_C_WARNINGS += -Wshadow
CFLAGS += $(PPC_C_WARNINGS)
-LINK=0x400000
-boot32_link_base = $(LINK)
-xen_link_offset = 100
-xen_link_base = $(patsubst %000,%$(xen_link_offset),$(LINK))
-
#
# The following flags are fed to gcc in order to link several
# objects into a single ELF segment and to not link in any additional
@@ -72,34 +69,39 @@ firmware: of_handler/built_in.o $(TARGET
firmware: of_handler/built_in.o $(TARGET_SUBARCH)/memcpy.o of-devtree.o
$(CC) $(CFLAGS) $(OMAGIC) -e __ofh_start -Wl,-Ttext,0x0 $^ -o $@
-firmware_image: firmware
+firmware_image.bin: firmware
$(CROSS_COMPILE)objcopy --output-target=binary $< $@
-
-firmware_image.o: firmware_image
- $(CROSS_COMPILE)objcopy --input-target=binary \
- --output-target=elf64-powerpc \
- --binary-architecture=powerpc \
- --redefine-sym _binary_$<_start=$(@:%.o=%)_start \
- --redefine-sym _binary_$<_end=$(@:%.o=%)_end \
- --redefine-sym _binary_$<_size=$(@:%.o=%)_size $< $@
#
# Hacks for included C files
#
irq.o: ../x86/irq.c
physdev.o: ../x86/physdev.c
+numa.o: ../x86/numa.c
HDRS += $(wildcard *.h)
+ifneq ($(CMDLINE),)
# The first token in the arguments will be silently dropped.
-IMAGENAME = xen
-CMDLINE = ""
-boot_of.o: CFLAGS += -DCMDLINE="\"$(IMAGENAME) $(CMDLINE)\""
+FULL_CMDLINE := xen $(CMDLINE)
+endif
-start.o: boot/start.S
- $(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@
+ifeq ($(wildcard cmdline.dep),)
+cmdline.dep:
+ echo $(FULL_CMDLINE) > cmdline.dep
+else
+ifneq ($(FULL_CMDLINE),$(shell cat cmdline.dep))
+cmdline.dep::
+ echo $(FULL_CMDLINE) > cmdline.dep
+else
+cmdline.dep:
+endif
+endif
-TARGET_OPTS = $(OMAGIC) -Wl,-Ttext,$(xen_link_base),-T,xen.lds
+cmdline.o: cmdline.dep
+cmdline.o: CFLAGS += -DCMDLINE="\"$(FULL_CMDLINE)\""
+
+TARGET_OPTS = $(OMAGIC) -Wl,-T,xen.lds
TARGET_OPTS += start.o $(ALL_OBJS)
.xen-syms: start.o $(ALL_OBJS) xen.lds
@@ -122,22 +124,10 @@ xen-syms.o: xen-syms.S
$(TARGET)-syms: start.o $(ALL_OBJS) xen-syms.o xen.lds
$(CC) $(CFLAGS) $(TARGET_OPTS) xen-syms.o -o $@
-$(TARGET).bin: $(TARGET)-syms
- $(CROSS_COMPILE)objcopy --output-target=binary $< $@
-
-$(TARGET).bin.o: $(TARGET).bin
- $(CROSS_COMPILE)objcopy --input-target=binary \
- --output-target=elf32-powerpc \
- --binary-architecture=powerpc $< $@
-
-boot32.o: boot/boot32.S
- $(CC) -m32 -Wa,-a32,-mppc64bridge \
- -D__ASSEMBLY__ -D__BRIDGE64__ $(CFLAGS) -c $< -o $@
-
-$(TARGET): boot32.o $(TARGET).bin.o
- $(CC) -m32 -N -Wl,-melf32ppclinux -static -nostdlib \
- -Wl,-Ttext,$(boot32_link_base) -Wl,-Tdata,$(xen_link_base) \
- $(CFLAGS) $^ -o $@
+# our firmware only loads 32-bit ELF files
+OCPYFLAGS := --input-target=elf64-powerpc --output-target=elf32-powerpc
+$(TARGET): $(TARGET)-syms
+ $(CROSS_COMPILE)objcopy $(OCPYFLAGS) $^ $@
asm-offsets.s: $(TARGET_SUBARCH)/asm-offsets.c $(HDRS)
$(CC) $(CFLAGS) -S -o $@ $<
@@ -150,4 +140,5 @@ dom0.bin: $(DOM0_IMAGE)
clean::
$(MAKE) -f $(BASEDIR)/Rules.mk -C of_handler clean
- rm -f firmware firmware_image dom0.bin .xen-syms
+ rm -f firmware firmware_image.bin dom0.bin .xen-syms xen-syms.S \
+ xen.lds asm-offsets.s cmdline.dep
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/backtrace.c
--- a/xen/arch/powerpc/backtrace.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/backtrace.c Fri Dec 15 11:32:58 2006 -0700
@@ -14,6 +14,7 @@
#include <xen/console.h>
#include <xen/sched.h>
#include <xen/symbols.h>
+#include <asm/debugger.h>
static char namebuf[KSYM_NAME_LEN+1];
@@ -192,6 +193,19 @@ void show_backtrace(ulong sp, ulong lr,
console_end_sync();
}
+void show_backtrace_regs(struct cpu_user_regs *regs)
+{
+ console_start_sync();
+
+ show_registers(regs);
+ printk("dar 0x%016lx, dsisr 0x%08x\n", mfdar(), mfdsisr());
+ printk("hid4 0x%016lx\n", regs->hid4);
+ printk("---[ backtrace ]---\n");
+ show_backtrace(regs->gprs[1], regs->lr, regs->pc);
+
+ console_end_sync();
+}
+
void __warn(char *file, int line)
{
ulong sp;
@@ -202,9 +216,19 @@ void __warn(char *file, int line)
sp = (ulong)__builtin_frame_address(0);
lr = (ulong)__builtin_return_address(0);
-
backtrace(sp, lr, lr);
- console_end_sync();
-}
-
-
+
+ console_end_sync();
+}
+
+void dump_execution_state(void)
+{
+ struct vcpu *v = current;
+ struct cpu_user_regs *regs = &v->arch.ctxt;
+
+ show_registers(regs);
+ if (regs->msr & MSR_HV) {
+ printk("In Xen:\n");
+ show_backtrace(regs->gprs[1], regs->pc, regs->lr);
+ }
+}
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/bitops.c
--- a/xen/arch/powerpc/bitops.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/bitops.c Fri Dec 15 11:32:58 2006 -0700
@@ -12,42 +12,42 @@
* @size: The maximum size to search
*/
unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
- unsigned long offset)
+ unsigned long offset)
{
- const unsigned long *p = addr + BITOP_WORD(offset);
- unsigned long result = offset & ~(BITS_PER_LONG-1);
- unsigned long tmp;
+ const unsigned long *p = addr + BITOP_WORD(offset);
+ unsigned long result = offset & ~(BITS_PER_LONG-1);
+ unsigned long tmp;
- if (offset >= size)
- return size;
- size -= result;
- offset %= BITS_PER_LONG;
- if (offset) {
- tmp = *(p++);
- tmp &= (~0UL << offset);
- if (size < BITS_PER_LONG)
- goto found_first;
- if (tmp)
- goto found_middle;
- size -= BITS_PER_LONG;
- result += BITS_PER_LONG;
- }
- while (size & ~(BITS_PER_LONG-1)) {
- if ((tmp = *(p++)))
- goto found_middle;
- result += BITS_PER_LONG;
- size -= BITS_PER_LONG;
- }
- if (!size)
- return result;
- tmp = *p;
+ if (offset >= size)
+ return size;
+ size -= result;
+ offset %= BITS_PER_LONG;
+ if (offset) {
+ tmp = *(p++);
+ tmp &= (~0UL << offset);
+ if (size < BITS_PER_LONG)
+ goto found_first;
+ if (tmp)
+ goto found_middle;
+ size -= BITS_PER_LONG;
+ result += BITS_PER_LONG;
+ }
+ while (size & ~(BITS_PER_LONG-1)) {
+ if ((tmp = *(p++)))
+ goto found_middle;
+ result += BITS_PER_LONG;
+ size -= BITS_PER_LONG;
+ }
+ if (!size)
+ return result;
+ tmp = *p;
found_first:
- tmp &= (~0UL >> (BITS_PER_LONG - size));
- if (tmp == 0UL) /* Are any bits set? */
- return result + size; /* Nope. */
+ tmp &= (~0UL >> (BITS_PER_LONG - size));
+ if (tmp == 0UL) /* Are any bits set? */
+ return result + size; /* Nope. */
found_middle:
- return result + __ffs(tmp);
+ return result + __ffs(tmp);
}
/*
@@ -55,40 +55,40 @@ found_middle:
* Linus' asm-alpha/bitops.h.
*/
unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
- unsigned long offset)
+ unsigned long offset)
{
- const unsigned long *p = addr + BITOP_WORD(offset);
- unsigned long result = offset & ~(BITS_PER_LONG-1);
- unsigned long tmp;
+ const unsigned long *p = addr + BITOP_WORD(offset);
+ unsigned long result = offset & ~(BITS_PER_LONG-1);
+ unsigned long tmp;
- if (offset >= size)
- return size;
- size -= result;
- offset %= BITS_PER_LONG;
- if (offset) {
- tmp = *(p++);
- tmp |= ~0UL >> (BITS_PER_LONG - offset);
- if (size < BITS_PER_LONG)
- goto found_first;
- if (~tmp)
- goto found_middle;
- size -= BITS_PER_LONG;
- result += BITS_PER_LONG;
- }
- while (size & ~(BITS_PER_LONG-1)) {
- if (~(tmp = *(p++)))
- goto found_middle;
- result += BITS_PER_LONG;
- size -= BITS_PER_LONG;
- }
- if (!size)
- return result;
- tmp = *p;
+ if (offset >= size)
+ return size;
+ size -= result;
+ offset %= BITS_PER_LONG;
+ if (offset) {
+ tmp = *(p++);
+ tmp |= ~0UL >> (BITS_PER_LONG - offset);
+ if (size < BITS_PER_LONG)
+ goto found_first;
+ if (~tmp)
+ goto found_middle;
+ size -= BITS_PER_LONG;
+ result += BITS_PER_LONG;
+ }
+ while (size & ~(BITS_PER_LONG-1)) {
+ if (~(tmp = *(p++)))
+ goto found_middle;
+ result += BITS_PER_LONG;
+ size -= BITS_PER_LONG;
+ }
+ if (!size)
+ return result;
+ tmp = *p;
found_first:
- tmp |= ~0UL << size;
- if (tmp == ~0UL) /* Are any bits zero? */
- return result + size; /* Nope. */
+ tmp |= ~0UL << size;
+ if (tmp == ~0UL) /* Are any bits zero? */
+ return result + size; /* Nope. */
found_middle:
- return result + ffz(tmp);
+ return result + ffz(tmp);
}
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/boot/boot32.S
--- a/xen/arch/powerpc/boot/boot32.S Fri Dec 15 10:59:33 2006 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2005 Jimi Xenidis <jimix@xxxxxxxxxxxxxx>, IBM Corporation
- *
- * 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
- *
- */
-
-### 32 bit strapping code so Of will like us
- .section ".text"
- .align 3
- .globl _start
-
-_start:
- ## Double word align the MSR value below
- nop
- bl _real_start
- ## static value for MSR
- .llong 0x9000000000001000
-
- ## see also docs/reference/ppc/msr.txt
-##bit C Hex Name Desc
-## 0 63 80000000 00000000 SF 64-bit Mode
-## 3 60 10000000 00000000 HV Hypervisor State iff PR = 0 in hypervisor
state.
-## 51 12 00000000 00001000 ME Machine Check Enable
-
-_real_start:
- # pass the original msr as argument to hype_init
- mfmsr 8
-
- ## Set PC
- li 21, 0
- oris 21, 21, _hype64@h
- ori 21, 21, _hype64@l
-#ifdef __BRIDGE64__
- ## In 64bit we use rfid to switch from 32bit to 64 bit
- mtsrr0 21
-
- ## Set MSR
- mflr 21
- ld 22, 0(21)
- mtsrr1 22
- bl __leap
- /* should never return */
- trap
-__leap:
- rfid
-#else
- mtctr 21
- bctrl
- /* should never return */
- trap
-#endif
-
-
-_real_end:
- .data
- .align 3
- ## Hypervisor starts here, at the first data address
- ## linker magic positions _hype64 0x100 after _start
- ## hype/ppc64/Makefile.isa
-_hype64:
-
-
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/boot/start.S
--- a/xen/arch/powerpc/boot/start.S Fri Dec 15 10:59:33 2006 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2005 Jimi Xenidis <jimix@xxxxxxxxxxxxxx>, IBM Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/config.h>
-#include <asm/processor.h>
-#include <asm/page.h>
-
- .globl _start
-_start:
- /* load up the stack */
- SET_REG_TO_LABEL(r1, cpu0_stack)
-
- /* call the init function */
- LOADADDR(r21,__start_xen_ppc)
-
-#ifdef __PPC64__
- ld r2, 8(r21)
- ld r21, 0(r21)
-#endif
- mtctr r21
- bctrl
- /* should never return */
- trap
-
- /* Note! GDB 6.3 makes the very stupid assumption that PC > SP means we are
- * in a Linux signal trampoline, and it begins groping for a struct
- * rt_sigframe on the stack. Naturally, this fails miserably for our
- * backtrace. To work around this behavior, we must make certain that our
- * stack is always above our text, e.g. in the data section. */
- .data /* DO NOT REMOVE; see GDB note above */
- .align 4
-cpu0_stack_bottom:
- .space STACK_SIZE
-cpu0_stack:
- .space STACK_FRAME_OVERHEAD
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/boot_of.c
--- a/xen/arch/powerpc/boot_of.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/boot_of.c Fri Dec 15 11:32:58 2006 -0700
@@ -16,6 +16,7 @@
* Copyright (C) IBM Corp. 2005, 2006
*
* Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
+ * Hollis Blanchard <hollisb@xxxxxxxxxx>
*/
#include <xen/config.h>
@@ -32,6 +33,7 @@
#include "exceptions.h"
#include "of-devtree.h"
#include "oftree.h"
+#include "rtas.h"
/* Secondary processors use this for handshaking with main processor. */
volatile unsigned int __spin_ack;
@@ -39,20 +41,27 @@ static ulong of_vec;
static ulong of_vec;
static ulong of_msr;
static int of_out;
-static char bootargs[256];
-
-#define COMMAND_LINE_SIZE 512
-static char builtin_cmdline[COMMAND_LINE_SIZE]
- __attribute__((section("__builtin_cmdline"))) = CMDLINE;
-
+static ulong eomem;
+
+#define MEM_AVAILABLE_PAGES ((32 << 20) >> PAGE_SHIFT)
+static DECLARE_BITMAP(mem_available_pages, MEM_AVAILABLE_PAGES);
+
+extern char builtin_cmdline[];
extern struct ns16550_defaults ns16550;
#undef OF_DEBUG
+#undef OF_DEBUG_LOW
#ifdef OF_DEBUG
#define DBG(args...) of_printf(args)
#else
#define DBG(args...)
+#endif
+
+#ifdef OF_DEBUG_LOW
+#define DBG_LOW(args...) of_printf(args)
+#else
+#define DBG_LOW(args...)
#endif
#define of_panic(MSG...) \
@@ -68,7 +77,6 @@ static int bof_chosen;
static int bof_chosen;
static struct of_service s;
-extern s32 prom_call(void *arg, ulong rtas_base, ulong func, ulong msr);
static int __init of_call(
const char *service, u32 nargs, u32 nrets, s32 rets[], ...)
@@ -78,7 +86,6 @@ static int __init of_call(
if (of_vec != 0) {
va_list args;
int i;
-
memset(&s, 0, sizeof (s));
s.ofs_service = (ulong)service;
s.ofs_nargs = nargs;
@@ -189,7 +196,7 @@ static int __init of_finddevice(const ch
DBG("finddevice %s -> FAILURE %d\n",devspec,rets[0]);
return OF_FAILURE;
}
- DBG("finddevice %s -> %d\n",devspec, rets[0]);
+ DBG_LOW("finddevice %s -> %d\n",devspec, rets[0]);
return rets[0];
}
@@ -200,11 +207,11 @@ static int __init of_getprop(int ph, con
of_call("getprop", 4, 1, rets, ph, name, buf, buflen);
if (rets[0] == OF_FAILURE) {
- DBG("getprop 0x%x %s -> FAILURE\n", ph, name);
+ DBG_LOW("getprop 0x%x %s -> FAILURE\n", ph, name);
return OF_FAILURE;
}
- DBG("getprop 0x%x %s -> 0x%x (%s)\n", ph, name, rets[0], (char *)buf);
+ DBG_LOW("getprop 0x%x %s -> 0x%x (%s)\n", ph, name, rets[0], (char *)buf);
return rets[0];
}
@@ -220,7 +227,7 @@ static int __init of_setprop(
return OF_FAILURE;
}
- DBG("setprop 0x%x %s -> %s\n", ph, name, (char *)buf);
+ DBG_LOW("setprop 0x%x %s -> %s\n", ph, name, (char *)buf);
return rets[0];
}
@@ -232,7 +239,7 @@ static int __init of_getchild(int ph)
int rets[1] = { OF_FAILURE };
of_call("child", 1, 1, rets, ph);
- DBG("getchild 0x%x -> 0x%x\n", ph, rets[0]);
+ DBG_LOW("getchild 0x%x -> 0x%x\n", ph, rets[0]);
return rets[0];
}
@@ -245,7 +252,7 @@ static int __init of_getpeer(int ph)
int rets[1] = { OF_FAILURE };
of_call("peer", 1, 1, rets, ph);
- DBG("getpeer 0x%x -> 0x%x\n", ph, rets[0]);
+ DBG_LOW("getpeer 0x%x -> 0x%x\n", ph, rets[0]);
return rets[0];
}
@@ -259,7 +266,7 @@ static int __init of_getproplen(int ph,
DBG("getproplen 0x%x %s -> FAILURE\n", ph, name);
return OF_FAILURE;
}
- DBG("getproplen 0x%x %s -> 0x%x\n", ph, name, rets[0]);
+ DBG_LOW("getproplen 0x%x %s -> 0x%x\n", ph, name, rets[0]);
return rets[0];
}
@@ -272,7 +279,7 @@ static int __init of_package_to_path(int
DBG("%s 0x%x -> FAILURE\n", __func__, ph);
return OF_FAILURE;
}
- DBG("%s 0x%x %s -> 0x%x\n", __func__, ph, buffer, rets[0]);
+ DBG_LOW("%s 0x%x %s -> 0x%x\n", __func__, ph, buffer, rets[0]);
if (rets[0] <= buflen)
buffer[rets[0]] = '\0';
return rets[0];
@@ -289,7 +296,7 @@ static int __init of_nextprop(int ph, co
return OF_FAILURE;
}
- DBG("nextprop 0x%x %s -> %s\n", ph, name, (char *)buf);
+ DBG_LOW("nextprop 0x%x %s -> %s\n", ph, name, (char *)buf);
return rets[0];
}
@@ -336,7 +343,7 @@ static int __init of_claim(u32 virt, u32
return OF_FAILURE;
}
- DBG("%s 0x%08x 0x%08x 0x%08x -> 0x%08x\n", __func__, virt, size, align,
+ DBG_LOW("%s 0x%08x 0x%08x 0x%08x -> 0x%08x\n", __func__, virt, size,
align,
rets[0]);
return rets[0];
}
@@ -358,29 +365,194 @@ static int __init of_getparent(int ph)
of_call("parent", 1, 1, rets, ph);
- DBG("getparent 0x%x -> 0x%x\n", ph, rets[0]);
- return rets[0];
-}
-
-static void boot_of_probemem(multiboot_info_t *mbi)
+ DBG_LOW("getparent 0x%x -> 0x%x\n", ph, rets[0]);
+ return rets[0];
+}
+
+static int __init of_open(const char *devspec)
+{
+ int rets[1] = { OF_FAILURE };
+
+ of_call("open", 1, 1, rets, devspec);
+ return rets[0];
+}
+
+static void boot_of_alloc_init(int m, uint addr_cells, uint size_cells)
+{
+ int rc;
+ uint pg;
+ uint a[64];
+ int tst;
+ u64 start;
+ u64 size;
+
+ rc = of_getprop(m, "available", a, sizeof (a));
+ if (rc > 0) {
+ int l = rc / sizeof(a[0]);
+ int r = 0;
+
+#ifdef OF_DEBUG
+ {
+ int i;
+ of_printf("avail:\n");
+ for (i = 0; i < l; i += 4)
+ of_printf(" 0x%x%x, 0x%x%x\n",
+ a[i], a[i + 1],
+ a[i + 2] ,a[i + 3]);
+ }
+#endif
+
+ pg = 0;
+ while (pg < MEM_AVAILABLE_PAGES && r < l) {
+ ulong end;
+
+ start = a[r++];
+ if (addr_cells == 2 && (r < l) )
+ start = (start << 32) | a[r++];
+
+ size = a[r++];
+ if (size_cells == 2 && (r < l) )
+ size = (size << 32) | a[r++];
+
+ end = ALIGN_DOWN(start + size, PAGE_SIZE);
+
+ start = ALIGN_UP(start, PAGE_SIZE);
+
+ DBG("%s: marking 0x%x - 0x%lx\n", __func__,
+ pg << PAGE_SHIFT, start);
+
+ start >>= PAGE_SHIFT;
+ while (pg < MEM_AVAILABLE_PAGES && pg < start) {
+ set_bit(pg, mem_available_pages);
+ pg++;
+ }
+
+ pg = end >> PAGE_SHIFT;
+ }
+ }
+
+ /* Now make sure we mark our own memory */
+ pg = (ulong)_start >> PAGE_SHIFT;
+ start = (ulong)_end >> PAGE_SHIFT;
+
+ DBG("%s: marking 0x%x - 0x%lx\n", __func__,
+ pg << PAGE_SHIFT, start << PAGE_SHIFT);
+
+ /* Lets try and detect if our image has stepped on something. It
+ * is possible that FW has already subtracted our image from
+ * available memory so we must make sure that the previous bits
+ * are the same for the whole image */
+ tst = test_and_set_bit(pg, mem_available_pages);
+ ++pg;
+ while (pg <= start) {
+ if (test_and_set_bit(pg, mem_available_pages) != tst)
+ of_panic("%s: pg :0x%x of our image is different\n",
+ __func__, pg);
+ ++pg;
+ }
+
+ DBG("%s: marking 0x%x - 0x%x\n", __func__,
+ 0 << PAGE_SHIFT, 3 << PAGE_SHIFT);
+ /* First for pages (where the vectors are) should be left alone as well */
+ set_bit(0, mem_available_pages);
+ set_bit(1, mem_available_pages);
+ set_bit(2, mem_available_pages);
+ set_bit(3, mem_available_pages);
+}
+
+#ifdef BOOT_OF_FREE
+/* this is here in case we ever need a free call at a later date */
+static void boot_of_free(ulong addr, ulong size)
+{
+ ulong bits;
+ ulong pos;
+ ulong i;
+
+ size = ALIGN_UP(size, PAGE_SIZE);
+ bits = size >> PAGE_SHIFT;
+ pos = addr >> PAGE_SHIFT;
+
+ for (i = 0; i < bits; i++) {
+ if (!test_and_clear_bit(pos + i, mem_available_pages))
+ of_panic("%s: pg :0x%lx was never allocated\n",
+ __func__, pos + i);
+ }
+}
+#endif
+
+static ulong boot_of_alloc(ulong size)
+{
+ ulong bits;
+ ulong pos;
+
+ if (size == 0)
+ return 0;
+
+ DBG("%s(0x%lx)\n", __func__, size);
+
+ size = ALIGN_UP(size, PAGE_SIZE);
+ bits = size >> PAGE_SHIFT;
+ pos = 0;
+ for (;;) {
+ ulong i;
+
+ pos = find_next_zero_bit(mem_available_pages,
+ MEM_AVAILABLE_PAGES, pos);
+ DBG("%s: found start bit at: 0x%lx\n", __func__, pos);
+
+ /* found nothing */
+ if ((pos + bits) > MEM_AVAILABLE_PAGES) {
+ of_printf("%s: allocation of size: 0x%lx failed\n",
+ __func__, size);
+ return 0;
+ }
+
+ /* find a set that fits */
+ DBG("%s: checking for 0x%lx bits: 0x%lx\n", __func__, bits, pos);
+
+ i = find_next_bit(mem_available_pages, MEM_AVAILABLE_PAGES, pos);
+ if (i - pos >= bits) {
+ uint addr = pos << PAGE_SHIFT;
+
+ /* make sure OF is happy with our choice */
+ if (of_claim(addr, size, 0) != OF_FAILURE) {
+ for (i = 0; i < bits; i++)
+ set_bit(pos + i, mem_available_pages);
+
+ DBG("%s: 0x%lx is good returning 0x%x\n",
+ __func__, pos, addr);
+ return addr;
+ }
+ /* if OF did not like the address then simply start from
+ * the next bit */
+ i = 1;
+ }
+
+ pos = pos + i;
+ }
+}
+
+static ulong boot_of_mem_init(void)
{
int root;
int p;
- u32 addr_cells = 1;
- u32 size_cells = 1;
int rc;
- int mcount = 0;
- static memory_map_t mmap[16];
+ uint addr_cells;
+ uint size_cells;
root = of_finddevice("/");
p = of_getchild(root);
/* code is writen to assume sizes of 1 */
- of_getprop(root, "#address-cells", &addr_cells, sizeof (addr_cells));
- of_getprop(root, "#size-cells", &size_cells, sizeof (size_cells));
+ of_getprop(root, "#address-cells", &addr_cells,
+ sizeof (addr_cells));
+ of_getprop(root, "#size-cells", &size_cells,
+ sizeof (size_cells));
DBG("%s: address_cells=%d size_cells=%d\n",
__func__, addr_cells, size_cells);
-
+
+ /* We do ream memory discovery later, for now we only want to find
+ * the first LMB */
do {
const char memory[] = "memory";
char type[32];
@@ -389,82 +561,69 @@ static void boot_of_probemem(multiboot_i
of_getprop(p, "device_type", type, sizeof (type));
if (strncmp(type, memory, sizeof (memory)) == 0) {
- u32 reg[48];
- u32 al, ah, ll, lh;
+ uint reg[48];
+ u64 start;
+ u64 size;
int r;
+ int l;
rc = of_getprop(p, "reg", reg, sizeof (reg));
if (rc == OF_FAILURE) {
of_panic("no reg property for memory node: 0x%x.\n", p);
}
- int l = rc/sizeof(u32); /* number reg element */
+
+ l = rc / sizeof(reg[0]); /* number reg element */
DBG("%s: number of bytes in property 'reg' %d\n",
__func__, rc);
r = 0;
while (r < l) {
- al = ah = ll = lh = 0;
- if (addr_cells == 2) {
- ah = reg[r++];
- if (r >= l)
- break; /* partial line. Skip */
- al = reg[r++];
- if (r >= l)
- break; /* partial line. Skip */
- } else {
- al = reg[r++];
- if (r >= l)
- break; /* partial line. Skip */
+ start = reg[r++];
+ if (addr_cells == 2 && (r < l) )
+ start = (start << 32) | reg[r++];
+
+ if (r >= l)
+ break; /* partial line. Skip */
+
+ if (start > 0) {
+ /* this is not the first LMB so we skip it */
+ break;
}
- if (size_cells == 2) {
- lh = reg[r++];
- if (r >= l)
- break; /* partial line. Skip */
- ll = reg[r++];
- } else {
- ll = reg[r++];
- }
-
- if ((ll != 0) || (lh != 0)) {
- mmap[mcount].size = 20; /* - size field */
- mmap[mcount].type = 1; /* Regular ram */
- mmap[mcount].length_high = lh;
- mmap[mcount].length_low = ll;
- mmap[mcount].base_addr_high = ah;
- mmap[mcount].base_addr_low = al;
- of_printf("%s: memory 0x%016lx[0x%08lx]\n",
- __func__,
- (u64)(((u64)mmap[mcount].base_addr_high << 32)
- | mmap[mcount].base_addr_low),
- (u64)(((u64)mmap[mcount].length_high << 32)
- | mmap[mcount].length_low));
- ++mcount;
- }
+
+ size = reg[r++];
+ if (size_cells == 2 && (r < l) )
+ size = (size << 32) | reg[r++];
+
+ if (r > l)
+ break; /* partial line. Skip */
+
+ boot_of_alloc_init(p, addr_cells, size_cells);
+
+ eomem = size;
+ return size;
}
}
p = of_getpeer(p);
} while (p != OF_FAILURE && p != 0);
- if (mcount > 0) {
- mbi->flags |= MBI_MEMMAP;
- mbi->mmap_length = sizeof (mmap[0]) * mcount;
- mbi->mmap_addr = (ulong)mmap;
- }
+ return 0;
}
static void boot_of_bootargs(multiboot_info_t *mbi)
{
int rc;
- rc = of_getprop(bof_chosen, "bootargs", &bootargs, sizeof (bootargs));
- if (rc == OF_FAILURE || bootargs[0] == '\0') {
- strlcpy(bootargs, builtin_cmdline, sizeof(bootargs));
+ if (builtin_cmdline[0] == '\0') {
+ rc = of_getprop(bof_chosen, "bootargs", builtin_cmdline,
+ CONFIG_CMDLINE_SIZE);
+ if (rc > CONFIG_CMDLINE_SIZE)
+ of_panic("bootargs[] not big enough for /chosen/bootargs\n");
}
mbi->flags |= MBI_CMDLINE;
- mbi->cmdline = (u32)bootargs;
-
- of_printf("bootargs = %s\n", bootargs);
+ mbi->cmdline = (ulong)builtin_cmdline;
+
+ of_printf("bootargs = %s\n", builtin_cmdline);
}
static int save_props(void *m, ofdn_t n, int pkg)
@@ -500,7 +659,8 @@ static int save_props(void *m, ofdn_t n,
of_panic("obj array not big enough for 0x%x\n", sz);
}
actual = of_getprop(pkg, name, obj, sz);
- if (actual > sz) of_panic("obj too small");
+ if (actual > sz)
+ of_panic("obj too small");
}
if (strncmp(name, name_str, sizeof(name_str)) == 0) {
@@ -512,7 +672,8 @@ static int save_props(void *m, ofdn_t n,
}
pos = ofd_prop_add(m, n, name, obj, actual);
- if (pos == 0) of_panic("prop_create");
+ if (pos == 0)
+ of_panic("prop_create");
}
result = of_nextprop(pkg, name, name);
@@ -536,10 +697,12 @@ retry:
if (pnext != 0) {
sz = of_package_to_path(pnext, path, psz);
- if (sz == OF_FAILURE) of_panic("bad path\n");
+ if (sz == OF_FAILURE)
+ of_panic("bad path\n");
nnext = ofd_node_child_create(m, n, path, sz);
- if (nnext == 0) of_panic("out of mem\n");
+ if (nnext == 0)
+ of_panic("out of mem\n");
do_pkg(m, nnext, pnext, path, psz);
}
@@ -551,7 +714,8 @@ retry:
sz = of_package_to_path(pnext, path, psz);
nnext = ofd_node_peer_create(m, n, path, sz);
- if (nnext <= 0) of_panic("out of space in OFD tree.\n");
+ if (nnext <= 0)
+ of_panic("out of space in OFD tree.\n");
n = nnext;
p = pnext;
@@ -559,7 +723,7 @@ retry:
}
}
-static int pkg_save(void *mem)
+static long pkg_save(void *mem)
{
int root;
char path[256];
@@ -570,11 +734,12 @@ static int pkg_save(void *mem)
/* get root */
root = of_getpeer(0);
- if (root == OF_FAILURE) of_panic("no root package\n");
+ if (root == OF_FAILURE)
+ of_panic("no root package\n");
do_pkg(mem, OFD_ROOT, root, path, sizeof(path));
- r = (((ofdn_t *)mem)[1] + 1) * sizeof (u64);
+ r = ofd_size(mem);
of_printf("%s: saved device tree in 0x%x bytes\n", __func__, r);
@@ -604,7 +769,8 @@ static int boot_of_fixup_refs(void *mem)
char ofpath[256];
path = ofd_node_path(mem, c);
- if (path == NULL) of_panic("no path to found prop: %s\n", name);
+ if (path == NULL)
+ of_panic("no path to found prop: %s\n", name);
rp = of_finddevice(path);
if (rp == OF_FAILURE)
@@ -629,13 +795,15 @@ static int boot_of_fixup_refs(void *mem)
"ref 0x%x\n", name, path, rp, ref);
dp = ofd_node_find(mem, ofpath);
- if (dp <= 0) of_panic("no ofd node for OF node[0x%x]: %s\n",
- ref, ofpath);
+ if (dp <= 0)
+ of_panic("no ofd node for OF node[0x%x]: %s\n",
+ ref, ofpath);
ref = dp;
upd = ofd_prop_add(mem, c, name, &ref, sizeof(ref));
- if (upd <= 0) of_panic("update failed: %s\n", name);
+ if (upd <= 0)
+ of_panic("update failed: %s\n", name);
#ifdef DEBUG
of_printf("%s: %s/%s -> %s\n", __func__,
@@ -658,7 +826,8 @@ static int boot_of_fixup_chosen(void *me
char ofpath[256];
ch = of_finddevice("/chosen");
- if (ch == OF_FAILURE) of_panic("/chosen not found\n");
+ if (ch == OF_FAILURE)
+ of_panic("/chosen not found\n");
rc = of_getprop(ch, "cpu", &val, sizeof (val));
@@ -667,16 +836,19 @@ static int boot_of_fixup_chosen(void *me
if (rc > 0) {
dn = ofd_node_find(mem, ofpath);
- if (dn <= 0) of_panic("no node for: %s\n", ofpath);
+ if (dn <= 0)
+ of_panic("no node for: %s\n", ofpath);
ofd_boot_cpu = dn;
val = dn;
dn = ofd_node_find(mem, "/chosen");
- if (dn <= 0) of_panic("no /chosen node\n");
+ if (dn <= 0)
+ of_panic("no /chosen node\n");
dc = ofd_prop_add(mem, dn, "cpu", &val, sizeof (val));
- if (dc <= 0) of_panic("could not fix /chosen/cpu\n");
+ if (dc <= 0)
+ of_panic("could not fix /chosen/cpu\n");
rc = 1;
} else {
of_printf("*** can't find path to booting cpu, "
@@ -685,56 +857,6 @@ static int boot_of_fixup_chosen(void *me
}
}
return rc;
-}
-
-static ulong space_base;
-
-/*
- * The following function is necessary because we cannot depend on all
- * FW to actually allocate us any space, so we look for it _hoping_
- * that at least is will fail if we try to claim something that
- * belongs to FW. This hope does not seem to be true on some version
- * of PIBS.
- */
-static ulong find_space(u32 size, u32 align, multiboot_info_t *mbi)
-{
- memory_map_t *map = (memory_map_t *)((ulong)mbi->mmap_addr);
- ulong eomem = ((u64)map->length_high << 32) | (u64)map->length_low;
- ulong base;
-
- if (size == 0)
- return 0;
-
- if (align == 0)
- of_panic("cannot call %s() with align of 0\n", __func__);
-
-#ifdef BROKEN_CLAIM_WORKAROUND
- {
- static int broken_claim;
- if (!broken_claim) {
- /* just try and claim it to the FW chosen address */
- base = of_claim(0, size, align);
- if (base != OF_FAILURE)
- return base;
- of_printf("%s: Firmware does not allocate memory for you\n",
- __func__);
- broken_claim = 1;
- }
- }
-#endif
-
- of_printf("%s base=0x%016lx eomem=0x%016lx size=0x%08x align=0x%x\n",
- __func__, space_base, eomem, size, align);
- base = ALIGN_UP(space_base, PAGE_SIZE);
-
- while ((base + size) < rma_size(cpu_default_rma_order_pages())) {
- if (of_claim(base, size, 0) != OF_FAILURE) {
- space_base = base + size;
- return base;
- }
- base += (PAGE_SIZE > align) ? PAGE_SIZE : align;
- }
- of_panic("Cannot find memory in the RMA\n");
}
/* PIBS Version 1.05.0000 04/26/2005 has an incorrect /ht/isa/ranges
@@ -798,8 +920,10 @@ static int __init boot_of_serial(void *o
of_panic("package-to-path failed\n");
rc = of_getprop(p, "device_type", type, sizeof (type));
- if (rc == OF_FAILURE)
- of_panic("fetching device type failed\n");
+ if (rc == OF_FAILURE) {
+ of_printf("%s: fetching type of `%s' failed\n", __func__, buf);
+ continue;
+ }
if (strcmp(type, "serial") != 0)
continue;
@@ -855,17 +979,104 @@ static int __init boot_of_serial(void *o
return 1;
}
-static void boot_of_module(ulong r3, ulong r4, multiboot_info_t *mbi)
-{
- static module_t mods[3];
+static int __init boot_of_rtas(module_t *mod, multiboot_info_t *mbi)
+{
+ int rtas_node;
+ int rtas_instance;
+ uint size = 0;
+ int res[2];
+ int mem;
+ int ret;
+
+ rtas_node = of_finddevice("/rtas");
+
+ if (rtas_node <= 0) {
+ of_printf("No RTAS, Xen has no power control\n");
+ return 0;
+ }
+ of_getprop(rtas_node, "rtas-size", &size, sizeof (size));
+ if (size == 0) {
+ of_printf("RTAS, has no size\n");
+ return 0;
+ }
+
+ rtas_instance = of_open("/rtas");
+ if (rtas_instance == OF_FAILURE) {
+ of_printf("RTAS, could not open\n");
+ return 0;
+ }
+
+ size = ALIGN_UP(size, PAGE_SIZE);
+
+ mem = boot_of_alloc(size);
+ if (mem == 0)
+ of_panic("Could not allocate RTAS tree\n");
+
+ of_printf("instantiating RTAS at: 0x%x\n", mem);
+
+ ret = of_call("call-method", 3, 2, res,
+ "instantiate-rtas", rtas_instance, mem);
+ if (ret == OF_FAILURE) {
+ of_printf("RTAS, could not open\n");
+ return 0;
+ }
+
+ rtas_entry = res[1];
+ rtas_base = mem;
+ rtas_end = mem + size;
+ rtas_msr = of_msr;
+
+ mod->mod_start = rtas_base;
+ mod->mod_end = rtas_end;
+ return 1;
+}
+
+static void * __init boot_of_devtree(module_t *mod, multiboot_info_t *mbi)
+{
void *oft;
ulong oft_sz = 48 * PAGE_SIZE;
+
+ /* snapshot the tree */
+ oft = (void *)boot_of_alloc(oft_sz);
+ if (oft == NULL)
+ of_panic("Could not allocate OFD tree\n");
+
+ of_printf("creating oftree at: 0x%p\n", oft);
+ of_test("package-to-path");
+ oft = ofd_create(oft, oft_sz);
+ pkg_save(oft);
+
+ if (ofd_size(oft) > oft_sz)
+ of_panic("Could not fit all of native devtree\n");
+
+ boot_of_fixup_refs(oft);
+ boot_of_fixup_chosen(oft);
+
+ if (ofd_size(oft) > oft_sz)
+ of_panic("Could not fit all devtree fixups\n");
+
+ ofd_walk(oft, __func__, OFD_ROOT, /* add_hype_props */ NULL, 2);
+
+ mod->mod_start = (ulong)oft;
+ mod->mod_end = mod->mod_start + oft_sz;
+ of_printf("%s: devtree mod @ 0x%016x - 0x%016x\n", __func__,
+ mod->mod_start, mod->mod_end);
+
+ return oft;
+}
+
+static void * __init boot_of_module(ulong r3, ulong r4, multiboot_info_t *mbi)
+{
+ static module_t mods[4];
ulong mod0_start;
ulong mod0_size;
- static const char sepr[] = " -- ";
+ static const char * sepr[] = {" -- ", " || "};
+ int sepr_index;
extern char dom0_start[] __attribute__ ((weak));
extern char dom0_size[] __attribute__ ((weak));
- const char *p;
+ const char *p = NULL;
+ int mod;
+ void *oft;
if ((r3 > 0) && (r4 > 0)) {
/* was it handed to us in registers ? */
@@ -908,57 +1119,50 @@ static void boot_of_module(ulong r3, ulo
of_printf("mod0: %o %c %c %c\n", c[0], c[1], c[2], c[3]);
}
- space_base = (ulong)_end;
- mods[0].mod_start = mod0_start;
- mods[0].mod_end = mod0_start + mod0_size;
-
- of_printf("%s: mod[0] @ 0x%016x[0x%x]\n", __func__,
- mods[0].mod_start, mods[0].mod_end);
- p = strstr((char *)(ulong)mbi->cmdline, sepr);
+ mod = 0;
+ mods[mod].mod_start = mod0_start;
+ mods[mod].mod_end = mod0_start + mod0_size;
+
+ of_printf("%s: dom0 mod @ 0x%016x[0x%x]\n", __func__,
+ mods[mod].mod_start, mods[mod].mod_end);
+
+ /* look for delimiter: "--" or "||" */
+ for (sepr_index = 0; sepr_index < ARRAY_SIZE(sepr); sepr_index++){
+ p = strstr((char *)(ulong)mbi->cmdline, sepr[sepr_index]);
+ if (p != NULL)
+ break;
+ }
+
if (p != NULL) {
- p += sizeof (sepr) - 1;
- mods[0].string = (u32)(ulong)p;
- of_printf("%s: mod[0].string: %s\n", __func__, p);
- }
-
- /* snapshot the tree */
- oft = (void*)find_space(oft_sz, PAGE_SIZE, mbi);
- if (oft == 0)
- of_panic("Could not allocate OFD tree\n");
-
- of_printf("creating oft\n");
- of_test("package-to-path");
- oft = ofd_create(oft, oft_sz);
- pkg_save(oft);
-
- if (ofd_size(oft) > oft_sz)
- of_panic("Could not fit all of native devtree\n");
-
- boot_of_fixup_refs(oft);
- boot_of_fixup_chosen(oft);
-
- if (ofd_size(oft) > oft_sz)
- of_panic("Could not fit all devtree fixups\n");
-
- ofd_walk(oft, OFD_ROOT, /* add_hype_props */ NULL, 2);
-
- mods[1].mod_start = (ulong)oft;
- mods[1].mod_end = mods[1].mod_start + oft_sz;
- of_printf("%s: mod[1] @ 0x%016x[0x%x]\n", __func__,
- mods[1].mod_start, mods[1].mod_end);
-
+ /* Xen proper should never know about the dom0 args. */
+ *(char *)p = '\0';
+ p += strlen(sepr[sepr_index]);
+ mods[mod].string = (u32)(ulong)p;
+ of_printf("%s: dom0 mod string: %s\n", __func__, p);
+ }
+
+ ++mod;
+ if (boot_of_rtas(&mods[mod], mbi))
+ ++mod;
+
+ oft = boot_of_devtree(&mods[mod], mbi);
+ if (oft == NULL)
+ of_panic("%s: boot_of_devtree failed\n", __func__);
+
+ ++mod;
mbi->flags |= MBI_MODULES;
- mbi->mods_count = 2;
+ mbi->mods_count = mod;
mbi->mods_addr = (u32)mods;
- boot_of_serial(oft);
+ return oft;
}
static int __init boot_of_cpus(void)
{
- int cpus_node;
- int cpu_node, bootcpu_node, logical;
+ int cpus_node, cpu_node;
+ int bootcpu_instance, bootcpu_node;
+ int logical;
int result;
s32 cpuid;
u32 cpu_clock[2];
@@ -967,9 +1171,13 @@ static int __init boot_of_cpus(void)
/* Look up which CPU we are running on right now and get all info
* from there */
result = of_getprop(bof_chosen, "cpu",
- &bootcpu_node, sizeof (bootcpu_node));
+ &bootcpu_instance, sizeof (bootcpu_instance));
if (result == OF_FAILURE)
- of_panic("Failed to look up boot cpu\n");
+ of_panic("Failed to look up boot cpu instance\n");
+
+ bootcpu_node = of_instance_to_package(bootcpu_instance);
+ if (result == OF_FAILURE)
+ of_panic("Failed to look up boot cpu package\n");
cpu_node = bootcpu_node;
@@ -1070,15 +1278,12 @@ static int __init boot_of_cpus(void)
return 1;
}
-static int __init boot_of_rtas(void)
-{
- return 1;
-}
-
multiboot_info_t __init *boot_of_init(
ulong r3, ulong r4, ulong vec, ulong r6, ulong r7, ulong orig_msr)
{
static multiboot_info_t mbi;
+ void *oft;
+ int r;
of_vec = vec;
of_msr = orig_msr;
@@ -1098,18 +1303,20 @@ multiboot_info_t __init *boot_of_init(
r3, r4, vec, r6, r7, orig_msr);
if ((vec >= (ulong)_start) && (vec <= (ulong)_end)) {
- of_printf("Hmm.. OF[0x%lx] seems to have stepped on our image "
- "that ranges: %p .. %p.\n HANG!\n",
+ of_panic("Hmm.. OF[0x%lx] seems to have stepped on our image "
+ "that ranges: %p .. %p.\n",
vec, _start, _end);
}
of_printf("%s: _start %p _end %p 0x%lx\n", __func__, _start, _end, r6);
boot_of_fix_maple();
- boot_of_probemem(&mbi);
+ r = boot_of_mem_init();
+ if (r == 0)
+ of_panic("failure to initialize memory allocator");
boot_of_bootargs(&mbi);
- boot_of_module(r3, r4, &mbi);
+ oft = boot_of_module(r3, r4, &mbi);
boot_of_cpus();
- boot_of_rtas();
+ boot_of_serial(oft);
/* end of OF */
of_printf("Quiescing Open Firmware ...\n");
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/cmdline.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/powerpc/cmdline.c Fri Dec 15 11:32:58 2006 -0700
@@ -0,0 +1,24 @@
+/*
+ * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright (C) IBM Corp. 2006
+ *
+ * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx>
+ */
+
+#include <asm/config.h>
+
+char builtin_cmdline[CONFIG_CMDLINE_SIZE]
+ __attribute__((section("__builtin_cmdline"))) = CMDLINE;
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/crash.c
--- a/xen/arch/powerpc/crash.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/crash.c Fri Dec 15 11:32:58 2006 -0700
@@ -1,5 +1,6 @@
#include <xen/lib.h> /* for printk() used in stub */
#include <xen/types.h>
+#include <xen/kexec.h>
#include <public/kexec.h>
void machine_crash_shutdown(void)
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/dart.c
--- a/xen/arch/powerpc/dart.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/dart.c Fri Dec 15 11:32:58 2006 -0700
@@ -60,8 +60,8 @@ union dart_entry {
u32 de_word;
struct {
u32 de_v:1; /* valid */
- u32 de_rp:1; /* read protected*/
- u32 de_wp:1; /* write protected*/
+ u32 de_rp:1; /* read protected */
+ u32 de_wp:1; /* write protected */
u32 _de_res:5;
u32 de_ppn:24; /* 24 bit Physical Page Number
* representing address [28:51] */
@@ -98,7 +98,6 @@ static u32 dart_encode(int perm, ulong r
if (perm & DART_WRITE) {
e.de_bits.de_wp = 0;
}
-
return e.de_word;
}
@@ -190,10 +189,8 @@ static int find_dart(struct dart_info *d
ofdn_t n;
char compat[128];
-
- if (on_mambo()) {
- /* mambo has no dart */
- DBG("%s: Mambo does not support a dart\n", __func__);
+ if (on_systemsim()) {
+ DBG("%s: systemsim does not support a dart\n", __func__);
return -1;
}
@@ -263,7 +260,7 @@ static int init_dart(void)
/* Linux uses a dummy page, filling "empty" DART entries with a
reference to this page to capture stray DMA's */
- dummy_page = (ulong)alloc_xenheap_pages(1);
+ dummy_page = (ulong)alloc_xenheap_pages(0);
clear_page((void *)dummy_page);
dummy_page >>= PAGE_SHIFT;
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/dart_u4.c
--- a/xen/arch/powerpc/dart_u4.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/dart_u4.c Fri Dec 15 11:32:58 2006 -0700
@@ -19,6 +19,7 @@
*/
#undef DEBUG
+#define INVALIDATE_ALL
#include <xen/config.h>
#include <xen/types.h>
@@ -123,8 +124,13 @@ static void u4_inv_all(void)
static void u4_inv_entry(ulong pgn)
{
+#ifdef INVALIDATE_ALL
+ return u4_inv_all();
+#else
union dart_ctl dc;
ulong retries = 0;
+
+ return u4_inv_all();
dc.dc_word = in_32(&dart->d_dartcntl.dc_word);
dc.dc_bits.dc_ilpn = pgn;
@@ -139,6 +145,7 @@ static void u4_inv_entry(ulong pgn)
if (retries > 1000000)
panic("WAY! too long\n");
} while (dc.dc_bits.dc_ione != 0);
+#endif
}
static struct dart_ops u4_ops = {
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/delay.c
--- a/xen/arch/powerpc/delay.c Fri Dec 15 10:59:33 2006 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (C) IBM Corp. 2005
- *
- * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
- */
-
-#include <xen/config.h>
-#include <xen/delay.h>
-#include <xen/time.h>
-#include <asm/processor.h>
-
-void udelay(unsigned long usecs)
-{
- ulong ticks = usecs * ticks_per_usec;
- ulong s;
- ulong e;
-
- s = get_timebase();
- do {
- asm volatile("or 1,1,1"); /* also puts the thread to low priority */
- e = get_timebase();
- } while ((e-s) < ticks);
-}
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/domain.c
--- a/xen/arch/powerpc/domain.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/domain.c Fri Dec 15 11:32:58 2006 -0700
@@ -33,6 +33,8 @@
#include <asm/htab.h>
#include <asm/current.h>
#include <asm/hcalls.h>
+#include "rtas.h"
+#include "exceptions.h"
#define next_arg(fmt, args) ({ \
unsigned long __arg; \
@@ -46,7 +48,6 @@
} \
__arg; \
})
-extern void idle_loop(void);
unsigned long hypercall_create_continuation(unsigned int op,
const char *format, ...)
@@ -87,26 +88,44 @@ int arch_domain_create(struct domain *d)
INIT_LIST_HEAD(&d->arch.extent_list);
+ d->arch.foreign_mfn_count = 1024;
+ d->arch.foreign_mfns = xmalloc_array(uint, d->arch.foreign_mfn_count);
+ BUG_ON(d->arch.foreign_mfns == NULL);
+
+ memset(d->arch.foreign_mfns, -1, d->arch.foreign_mfn_count * sizeof(uint));
+
return 0;
}
void arch_domain_destroy(struct domain *d)
{
shadow_teardown(d);
-}
-
+ /* shared_info is part of the RMA so no need to release it */
+}
+
+static void machine_fail(const char *s)
+{
+ printk("%s failed, manual powercycle required!\n", s);
+ for (;;)
+ sleep();
+}
void machine_halt(void)
{
printk("machine_halt called: spinning....\n");
console_start_sync();
- while(1);
+ printk("%s called\n", __func__);
+ rtas_halt();
+
+ machine_fail(__func__);
}
void machine_restart(char * __unused)
{
printk("machine_restart called: spinning....\n");
console_start_sync();
- while(1);
+ printk("%s called\n", __func__);
+ rtas_reboot();
+ machine_fail(__func__);
}
struct vcpu *alloc_vcpu_struct(void)
@@ -222,6 +241,7 @@ void context_switch(struct vcpu *prev, s
mtsdr1(next->domain->arch.htab.sdr1);
local_flush_tlb(); /* XXX maybe flush_tlb_mask? */
+ cpu_flush_icache();
if (is_idle_vcpu(next)) {
reset_stack_and_jump(idle_loop);
@@ -278,8 +298,10 @@ static void relinquish_memory(struct dom
void domain_relinquish_resources(struct domain *d)
{
+ relinquish_memory(d, &d->xenpage_list);
relinquish_memory(d, &d->page_list);
free_extents(d);
+ xfree(d->arch.foreign_mfns);
return;
}
@@ -291,7 +313,6 @@ void arch_dump_vcpu_info(struct vcpu *v)
{
}
-extern void sleep(void);
static void safe_halt(void)
{
int cpu = smp_processor_id();
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/domain_build.c
--- a/xen/arch/powerpc/domain_build.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/domain_build.c Fri Dec 15 11:32:58 2006 -0700
@@ -178,8 +178,7 @@ int construct_dom0(struct domain *d,
shadow_set_allocation(d, opt_dom0_shadow, &preempt);
} while (preempt);
if (shadow_get_allocation(d) == 0)
- panic("shadow allocation failed 0x%x < 0x%x\n",
- shadow_get_allocation(d), opt_dom0_shadow);
+ panic("shadow allocation failed: %dMib\n", opt_dom0_shadow);
ASSERT( image_len < rma_sz );
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/domctl.c
--- a/xen/arch/powerpc/domctl.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/domctl.c Fri Dec 15 11:32:58 2006 -0700
@@ -96,14 +96,14 @@ long arch_do_domctl(struct xen_domctl *d
case XEN_DOMCTL_real_mode_area:
{
struct domain *d;
- unsigned int log = domctl->u.real_mode_area.log;
+ unsigned int order = domctl->u.real_mode_area.log - PAGE_SHIFT;
ret = -ESRCH;
d = find_domain_by_id(domctl->domain);
if (d != NULL) {
ret = -EINVAL;
- if (cpu_rma_valid(log))
- ret = allocate_rma(d, log - PAGE_SHIFT);
+ if (cpu_rma_valid(order))
+ ret = allocate_rma(d, order);
put_domain(d);
}
}
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/exceptions.c
--- a/xen/arch/powerpc/exceptions.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/exceptions.c Fri Dec 15 11:32:58 2006 -0700
@@ -25,8 +25,10 @@
#include <xen/serial.h>
#include <xen/gdbstub.h>
#include <xen/console.h>
+#include <xen/shutdown.h>
#include <asm/time.h>
#include <asm/processor.h>
+#include <asm/debugger.h>
#undef DEBUG
@@ -56,25 +58,19 @@ void do_dec(struct cpu_user_regs *regs)
void program_exception(struct cpu_user_regs *regs, unsigned long cookie)
{
+ if (cookie == 0x200) {
+ if (cpu_machinecheck(regs))
+ return;
+
+ printk("%s: machine check\n", __func__);
+ } else {
#ifdef CRASH_DEBUG
- __trap_to_gdb(regs, cookie);
-#else /* CRASH_DEBUG */
- int recover = 0;
+ if (__trap_to_gdb(regs, cookie) == 0)
+ return;
+#endif /* CRASH_DEBUG */
- console_start_sync();
-
- show_registers(regs);
- printk("dar 0x%016lx, dsisr 0x%08x\n", mfdar(), mfdsisr());
- printk("hid4 0x%016lx\n", regs->hid4);
- printk("---[ backtrace ]---\n");
- show_backtrace(regs->gprs[1], regs->lr, regs->pc);
-
- if (cookie == 0x200)
- recover = cpu_machinecheck(regs);
-
- if (!recover)
- panic("%s: 0x%lx\n", __func__, cookie);
-
- console_end_sync();
-#endif /* CRASH_DEBUG */
+ printk("%s: type: 0x%lx\n", __func__, cookie);
+ show_backtrace_regs(regs);
+ }
+ machine_halt();
}
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/exceptions.h
--- a/xen/arch/powerpc/exceptions.h Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/exceptions.h Fri Dec 15 11:32:58 2006 -0700
@@ -43,13 +43,14 @@ extern void program_exception(
struct cpu_user_regs *regs, unsigned long cookie);
extern long xen_hvcall_jump(struct cpu_user_regs *regs, ulong address);
-extern void *mambo_memset(void *, int, ulong);
-extern void *mambo_memcpy(void *, const void *, ulong);
+
+extern void sleep(void);
+extern void idle_loop(void);
extern ulong *__hypercall_table[];
extern char exception_vectors[];
extern char exception_vectors_end[];
extern int spin_start[];
-extern int secondary_cpu_init(int cpuid, unsigned long r4);
+extern void secondary_cpu_init(int cpuid, unsigned long r4);
#endif
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/external.c
--- a/xen/arch/powerpc/external.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/external.c Fri Dec 15 11:32:58 2006 -0700
@@ -82,7 +82,14 @@ void do_external(struct cpu_user_regs *r
vec = xen_mpic_get_irq(regs);
- if (vec != -1) {
+ if (irq_desc[vec].status & IRQ_PER_CPU) {
+ /* x86 do_IRQ does not respect the per cpu flag. */
+ irq_desc_t *desc = &irq_desc[vec];
+ regs->entry_vector = vec;
+ desc->handler->ack(vec);
+ desc->action->handler(vector_to_irq(vec), desc->action->dev_id, regs);
+ desc->handler->end(vec);
+ } else if (vec != -1) {
DBG("EE:0x%lx isrc: %d\n", regs->msr, vec);
regs->entry_vector = vec;
do_IRQ(regs);
@@ -253,3 +260,24 @@ int ioapic_guest_write(unsigned long phy
BUG_ON(val != val);
return 0;
}
+
+void send_IPI_mask(cpumask_t mask, int vector)
+{
+ unsigned int cpus;
+ int const bits = 8 * sizeof(cpus);
+
+ switch(vector) {
+ case CALL_FUNCTION_VECTOR:
+ case EVENT_CHECK_VECTOR:
+ break;
+ default:
+ BUG();
+ return;
+ }
+
+ BUG_ON(NR_CPUS > bits);
+ BUG_ON(fls(mask.bits[0]) > bits);
+
+ cpus = mask.bits[0];
+ mpic_send_ipi(vector, cpus);
+}
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/gdbstub.c
--- a/xen/arch/powerpc/gdbstub.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/gdbstub.c Fri Dec 15 11:32:58 2006 -0700
@@ -25,6 +25,7 @@
#include <asm/msr.h>
#include <asm/bitops.h>
#include <asm/cache.h>
+#include <asm/debugger.h>
#include <asm/processor.h>
asm(".globl trap_instruction\n"
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/iommu.c
--- a/xen/arch/powerpc/iommu.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/iommu.c Fri Dec 15 11:32:58 2006 -0700
@@ -32,6 +32,12 @@
#include "tce.h"
#include "iommu.h"
+#ifdef DEBUG
+#define DBG(fmt...) printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
struct iommu_funcs {
int (*iommu_put)(ulong, union tce);
};
@@ -46,17 +52,31 @@ int iommu_put(u32 buid, ulong ioba, unio
struct domain *d = v->domain;
if (buid < iommu_phbs_num && iommu_phbs[buid].iommu_put != NULL) {
- ulong pfn;
+ ulong gmfn;
ulong mfn;
int mtype;
- pfn = tce.tce_bits.tce_rpn;
- mfn = pfn2mfn(d, pfn, &mtype);
+ gmfn = tce.tce_bits.tce_rpn;
+
+
+ mfn = pfn2mfn(d, gmfn, &mtype);
if (mfn != INVALID_MFN) {
-#ifdef DEBUG
- printk("%s: ioba=0x%lx pfn=0x%lx mfn=0x%lx\n", __func__,
- ioba, pfn, mfn);
-#endif
+ switch (mtype) {
+ case PFN_TYPE_RMA:
+ case PFN_TYPE_LOGICAL:
+ break;
+ case PFN_TYPE_FOREIGN:
+ DBG("%s: assigning to Foriegn page: "
+ "gmfn: 0x%lx mfn: 0x%lx\n", __func__, gmfn, mfn);
+ break;
+ default:
+ printk("%s: unsupported type[%d]: gmfn: 0x%lx mfn: 0x%lx\n",
+ __func__, mtype, gmfn, mfn);
+ return -1;
+ break;
+ }
+ DBG("%s: ioba=0x%lx gmfn=0x%lx mfn=0x%lx\n", __func__,
+ ioba, gmfn, mfn);
tce.tce_bits.tce_rpn = mfn;
return iommu_phbs[buid].iommu_put(ioba, tce);
}
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/machine_kexec.c
--- a/xen/arch/powerpc/machine_kexec.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/machine_kexec.c Fri Dec 15 11:32:58 2006 -0700
@@ -1,5 +1,6 @@
#include <xen/lib.h> /* for printk() used in stubs */
#include <xen/types.h>
+#include <xen/kexec.h>
#include <public/kexec.h>
int machine_kexec_load(int type, int slot, xen_kexec_image_t *image)
@@ -9,11 +10,6 @@ int machine_kexec_load(int type, int slo
}
void machine_kexec_unload(int type, int slot, xen_kexec_image_t *image)
-{
- printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
-}
-
-void machine_kexec(xen_kexec_image_t *image)
{
printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
}
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/mambo.S
--- a/xen/arch/powerpc/mambo.S Fri Dec 15 10:59:33 2006 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2005 Jimi Xenidis <jimix@xxxxxxxxxxxxxx>, IBM Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <asm/config.h>
-#include <asm/processor.h>
-
-_GLOBAL(mambo_callthru)
- .long 0x000eaeb0
- blr
-
-_GLOBAL(mambo_write)
- mr r5, r4
- mr r4, r3
- li r3, 0 # Write console code
-
- li r6, 0
- /* need to fix return value */
- mflr r7
- bl _ENTRY(mambo_callthru)
- mtlr r7
- mr r3, r5
- blr
-
-_GLOBAL(mambo_memset)
- mr r6, r5
- mr r5, r4
- mr r4, r3
- li r3, 0x47 # memset
- /* need to fix return value */
- mflr r7
- bl _ENTRY(mambo_callthru)
- mtlr r7
- mr r3, r4
- blr
-
-_GLOBAL(mambo_memcpy)
- mr r6, r5
- mr r5, r4
- mr r4, r3
- li r3, 0x45 # memcpy
- /* need to fix return value */
- mflr r7
- bl _ENTRY(mambo_callthru)
- mtlr r7
- mr r3, r4
- blr
-
-
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/memory.c
--- a/xen/arch/powerpc/memory.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/memory.c Fri Dec 15 11:32:58 2006 -0700
@@ -20,10 +20,31 @@
*/
#include <xen/sched.h>
#include <xen/mm.h>
+#include <xen/numa.h>
#include "of-devtree.h"
#include "oftree.h"
+#include "rtas.h"
+
+#undef DEBUG
+#ifdef DEBUG
+#define DBG(fmt...) printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+/*
+ * opt_xenheap_megabytes: Size of Xen heap in megabytes, excluding the
+ * page_info table and allocation bitmap.
+ */
+static unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB;
+integer_param("xenheap_megabytes", opt_xenheap_megabytes);
unsigned long xenheap_phys_end;
+static uint nr_pages;
+static ulong xenheap_size;
+static ulong save_start;
+static ulong save_end;
+
struct membuf {
ulong start;
ulong size;
@@ -36,15 +57,20 @@ static ulong free_xenheap(ulong start, u
start = ALIGN_UP(start, PAGE_SIZE);
end = ALIGN_DOWN(end, PAGE_SIZE);
- printk("%s: 0x%lx - 0x%lx\n", __func__, start, end);
-
- if (oftree <= end && oftree >= start) {
- printk("%s: Go around the devtree: 0x%lx - 0x%lx\n",
- __func__, oftree, oftree_end);
- init_xenheap_pages(start, ALIGN_DOWN(oftree, PAGE_SIZE));
- init_xenheap_pages(ALIGN_UP(oftree_end, PAGE_SIZE), end);
+ DBG("%s: 0x%lx - 0x%lx\n", __func__, start, end);
+
+ /* need to do this better */
+ if (save_start <= end && save_start >= start) {
+ DBG("%s: Go around the saved area: 0x%lx - 0x%lx\n",
+ __func__, save_start, save_end);
+ init_xenheap_pages(start, ALIGN_DOWN(save_start, PAGE_SIZE));
+ xenheap_size += ALIGN_DOWN(save_start, PAGE_SIZE) - start;
+
+ init_xenheap_pages(ALIGN_UP(save_end, PAGE_SIZE), end);
+ xenheap_size += end - ALIGN_UP(save_end, PAGE_SIZE);
} else {
init_xenheap_pages(start, end);
+ xenheap_size += end - start;
}
return ALIGN_UP(end, PAGE_SIZE);
@@ -57,8 +83,10 @@ static void set_max_page(struct membuf *
for (i = 0; i < entries; i++) {
ulong end_page;
+ printk(" %016lx: %016lx\n", mb[i].start, mb[i].size);
+ nr_pages += mb[i].size >> PAGE_SHIFT;
+
end_page = (mb[i].start + mb[i].size) >> PAGE_SHIFT;
-
if (end_page > max_page)
max_page = end_page;
}
@@ -71,11 +99,11 @@ static void heap_init(struct membuf *mb,
ulong start_blk;
ulong end_blk = 0;
- for (i = 0; i < entries; i++) {
- start_blk = mb[i].start;
- end_blk = start_blk + mb[i].size;
-
- if (start_blk < xenheap_phys_end) {
+ for (i = 0; i < entries; i++) {
+ start_blk = mb[i].start;
+ end_blk = start_blk + mb[i].size;
+
+ if (start_blk < xenheap_phys_end) {
if (xenheap_phys_end > end_blk) {
panic("xenheap spans LMB\n");
}
@@ -87,7 +115,7 @@ static void heap_init(struct membuf *mb,
init_boot_pages(start_blk, end_blk);
total_pages += (end_blk - start_blk) >> PAGE_SHIFT;
- }
+ }
}
static void ofd_walk_mem(void *m, walk_mem_fn fn)
@@ -123,7 +151,7 @@ static void setup_xenheap(module_t *mod,
for (i = 0; i < mcount; i++) {
u32 s;
- if(mod[i].mod_end == mod[i].mod_start)
+ if (mod[i].mod_end == mod[i].mod_start)
continue;
s = ALIGN_DOWN(mod[i].mod_start, PAGE_SIZE);
@@ -149,19 +177,42 @@ void memory_init(module_t *mod, int mcou
void memory_init(module_t *mod, int mcount)
{
ulong eomem;
- ulong heap_start, heap_size;
-
- printk("Physical RAM map:\n");
+ ulong heap_start;
+ ulong xh_pages;
/* lets find out how much memory there is and set max_page */
max_page = 0;
+ printk("Physical RAM map:\n");
ofd_walk_mem((void *)oftree, set_max_page);
eomem = max_page << PAGE_SHIFT;
if (eomem == 0){
panic("ofd_walk_mem() failed\n");
}
- printk("End of RAM: %luMB (%lukB)\n", eomem >> 20, eomem >> 10);
+
+ /* find the portion of memory we need to keep safe */
+ save_start = oftree;
+ save_end = oftree_end;
+ if (rtas_base) {
+ if (save_start > rtas_base)
+ save_start = rtas_base;
+ if (save_end < rtas_end)
+ save_end = rtas_end;
+ }
+
+ /* minimum heap has to reach to the end of all Xen required memory */
+ xh_pages = ALIGN_UP(save_end, PAGE_SIZE) >> PAGE_SHIFT;
+ xh_pages += opt_xenheap_megabytes << (20 - PAGE_SHIFT);
+
+ /* While we are allocating HTABS from The Xen Heap we need it to
+ * be larger */
+ xh_pages += nr_pages >> 5;
+
+ xenheap_phys_end = xh_pages << PAGE_SHIFT;
+ printk("End of Xen Area: %luMiB (%luKiB)\n",
+ xenheap_phys_end >> 20, xenheap_phys_end >> 10);
+
+ printk("End of RAM: %luMiB (%luKiB)\n", eomem >> 20, eomem >> 10);
/* Architecturally the first 4 pages are exception hendlers, we
* will also be copying down some code there */
@@ -185,22 +236,23 @@ void memory_init(module_t *mod, int mcou
panic("total_pages > max_page: 0x%lx > 0x%lx\n",
total_pages, max_page);
- printk("total_pages: 0x%016lx\n", total_pages);
+ DBG("total_pages: 0x%016lx\n", total_pages);
init_frametable();
+
+ numa_initmem_init(0, max_page);
+
end_boot_allocator();
/* Add memory between the beginning of the heap and the beginning
- * of out text */
+ * of our text */
free_xenheap(heap_start, (ulong)_start);
-
- heap_size = xenheap_phys_end - heap_start;
- printk("Xen heap: %luMB (%lukB)\n", heap_size >> 20, heap_size >> 10);
-
setup_xenheap(mod, mcount);
+ printk("Xen Heap: %luMiB (%luKiB)\n",
+ xenheap_size >> 20, xenheap_size >> 10);
eomem = avail_domheap_pages();
- printk("Domheap pages: 0x%lx %luMB (%lukB)\n", eomem,
+ printk("Dom Heap: %luMiB (%luKiB)\n",
(eomem << PAGE_SHIFT) >> 20,
(eomem << PAGE_SHIFT) >> 10);
}
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/mm.c
--- a/xen/arch/powerpc/mm.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/mm.c Fri Dec 15 11:32:58 2006 -0700
@@ -25,9 +25,9 @@
#include <xen/kernel.h>
#include <xen/sched.h>
#include <xen/perfc.h>
-#include <asm/misc.h>
#include <asm/init.h>
#include <asm/page.h>
+#include <asm/string.h>
#ifdef VERBOSE
#define MEM_LOG(_f, _a...) \
@@ -42,18 +42,129 @@ unsigned long max_page;
unsigned long max_page;
unsigned long total_pages;
+void __init init_frametable(void)
+{
+ unsigned long p;
+ unsigned long nr_pages;
+ int i;
+
+ nr_pages = PFN_UP(max_page * sizeof(struct page_info));
+
+ p = alloc_boot_pages(nr_pages, 1);
+ if (p == 0)
+ panic("Not enough memory for frame table\n");
+
+ frame_table = (struct page_info *)(p << PAGE_SHIFT);
+ for (i = 0; i < nr_pages; i += 1)
+ clear_page((void *)((p + i) << PAGE_SHIFT));
+}
+
+void share_xen_page_with_guest(
+ struct page_info *page, struct domain *d, int readonly)
+{
+ if ( page_get_owner(page) == d )
+ return;
+
+ /* this causes us to leak pages in the Domain and reuslts in
+ * Zombie domains, I think we are missing a piece, until we find
+ * it we disable the following code */
+ set_gpfn_from_mfn(page_to_mfn(page), INVALID_M2P_ENTRY);
+
+ spin_lock(&d->page_alloc_lock);
+
+ /* The incremented type count pins as writable or read-only. */
+ page->u.inuse.type_info = (readonly ? PGT_none : PGT_writable_page);
+ page->u.inuse.type_info |= PGT_validated | 1;
+
+ page_set_owner(page, d);
+ wmb(); /* install valid domain ptr before updating refcnt. */
+ ASSERT(page->count_info == 0);
+ page->count_info |= PGC_allocated | 1;
+
+ if ( unlikely(d->xenheap_pages++ == 0) )
+ get_knownalive_domain(d);
+ list_add_tail(&page->list, &d->xenpage_list);
+
+ spin_unlock(&d->page_alloc_lock);
+}
+
+void share_xen_page_with_privileged_guests(
+ struct page_info *page, int readonly)
+{
+ unimplemented();
+}
+
+static ulong foreign_to_mfn(struct domain *d, ulong pfn)
+{
+
+ pfn -= 1UL << cpu_foreign_map_order();
+
+ BUG_ON(pfn >= d->arch.foreign_mfn_count);
+
+ return d->arch.foreign_mfns[pfn];
+}
+
+static int set_foreign(struct domain *d, ulong pfn, ulong mfn)
+{
+ pfn -= 1UL << cpu_foreign_map_order();
+
+ BUG_ON(pfn >= d->arch.foreign_mfn_count);
+ d->arch.foreign_mfns[pfn] = mfn;
+
+ return 0;
+}
+
+static int create_grant_va_mapping(
+ unsigned long va, unsigned long frame, struct vcpu *v)
+{
+ if (v->domain->domain_id != 0) {
+ printk("only Dom0 can map a grant entry\n");
+ BUG();
+ return GNTST_permission_denied;
+ }
+ set_foreign(v->domain, va >> PAGE_SHIFT, frame);
+ return GNTST_okay;
+}
+
+static int destroy_grant_va_mapping(
+ unsigned long addr, unsigned long frame, struct domain *d)
+{
+ if (d->domain_id != 0) {
+ printk("only Dom0 can map a grant entry\n");
+ BUG();
+ return GNTST_permission_denied;
+ }
+ set_foreign(d, addr >> PAGE_SHIFT, ~0UL);
+ return GNTST_okay;
+}
+
int create_grant_host_mapping(
unsigned long addr, unsigned long frame, unsigned int flags)
{
- panic("%s called\n", __func__);
- return 1;
+ if (flags & GNTMAP_application_map) {
+ printk("%s: GNTMAP_application_map not supported\n", __func__);
+ BUG();
+ return GNTST_general_error;
+ }
+ if (flags & GNTMAP_contains_pte) {
+ printk("%s: GNTMAP_contains_pte not supported\n", __func__);
+ BUG();
+ return GNTST_general_error;
+ }
+ return create_grant_va_mapping(addr, frame, current);
}
int destroy_grant_host_mapping(
unsigned long addr, unsigned long frame, unsigned int flags)
{
- panic("%s called\n", __func__);
- return 1;
+ if (flags & GNTMAP_contains_pte) {
+ printk("%s: GNTMAP_contains_pte not supported\n", __func__);
+ BUG();
+ return GNTST_general_error;
+ }
+
+ /* may have force the remove here */
+ return destroy_grant_va_mapping(addr, frame, current->domain);
}
int steal_page(struct domain *d, struct page_info *page, unsigned int memflags)
@@ -139,7 +250,7 @@ int get_page_type(struct page_info *page
{
return 0;
}
- if ( unlikely(!(x & PGT_validated)) )
+ else if ( unlikely(!(x & PGT_validated)) )
{
/* Someone else is updating validation of this page. Wait... */
while ( (y = page->u.inuse.type_info) == x )
@@ -158,25 +269,6 @@ int get_page_type(struct page_info *page
return 1;
}
-void __init init_frametable(void)
-{
- unsigned long p;
- unsigned long nr_pages;
- int i;
-
- nr_pages = PFN_UP(max_page * sizeof(struct page_info));
- nr_pages = min(nr_pages, (4UL << (20 - PAGE_SHIFT)));
-
-
- p = alloc_boot_pages(nr_pages, 1);
- if (p == 0)
- panic("Not enough memory for frame table\n");
-
- frame_table = (struct page_info *)(p << PAGE_SHIFT);
- for (i = 0; i < nr_pages; i += 1)
- clear_page((void *)((p + i) << PAGE_SHIFT));
-}
-
long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
{
printk("%s: no PPC specific memory ops\n", __func__);
@@ -185,29 +277,28 @@ long arch_memory_op(int op, XEN_GUEST_HA
extern void copy_page(void *dp, void *sp)
{
- if (on_mambo()) {
- extern void *mambo_memcpy(void *,const void *,__kernel_size_t);
- mambo_memcpy(dp, sp, PAGE_SIZE);
+ if (on_systemsim()) {
+ systemsim_memcpy(dp, sp, PAGE_SIZE);
} else {
memcpy(dp, sp, PAGE_SIZE);
}
}
+/* XXX should probably replace with faster data structure */
static uint add_extent(struct domain *d, struct page_info *pg, uint order)
{
struct page_extents *pe;
pe = xmalloc(struct page_extents);
if (pe == NULL)
- return 0;
+ return -ENOMEM;
pe->pg = pg;
pe->order = order;
- pe->pfn = page_to_mfn(pg);
list_add_tail(&pe->pe_list, &d->arch.extent_list);
- return pe->pfn;
+ return 0;
}
void free_extents(struct domain *d)
@@ -246,7 +337,7 @@ uint allocate_extents(struct domain *d,
if (pg == NULL)
return total_nrpages;
- if (add_extent(d, pg, ext_order) == 0) {
+ if (add_extent(d, pg, ext_order) < 0) {
free_domheap_pages(pg, ext_order);
return total_nrpages;
}
@@ -299,13 +390,13 @@ int allocate_rma(struct domain *d, unsig
return 0;
}
+
void free_rma_check(struct page_info *page)
{
if (test_bit(_PGC_page_RMA, &page->count_info) &&
!test_bit(_DOMF_dying, &page_get_owner(page)->domain_flags))
panic("Attempt to free an RMA page: 0x%lx\n", page_to_mfn(page));
}
-
ulong pfn2mfn(struct domain *d, ulong pfn, int *type)
{
@@ -314,9 +405,17 @@ ulong pfn2mfn(struct domain *d, ulong pf
struct page_extents *pe;
ulong mfn = INVALID_MFN;
int t = PFN_TYPE_NONE;
+ ulong foreign_map_pfn = 1UL << cpu_foreign_map_order();
/* quick tests first */
- if (d->is_privileged && cpu_io_mfn(pfn)) {
+ if (pfn & foreign_map_pfn) {
+ t = PFN_TYPE_FOREIGN;
+ mfn = foreign_to_mfn(d, pfn);
+ } else if (pfn >= max_page && pfn < (max_page + NR_GRANT_FRAMES)) {
+ /* Its a grant table access */
+ t = PFN_TYPE_GNTTAB;
+ mfn = gnttab_shared_mfn(d, d->grant_table, (pfn - max_page));
+ } else if (d->is_privileged && cpu_io_mfn(pfn)) {
t = PFN_TYPE_IO;
mfn = pfn;
} else {
@@ -324,17 +423,32 @@ ulong pfn2mfn(struct domain *d, ulong pf
t = PFN_TYPE_RMA;
mfn = pfn + rma_base_mfn;
} else {
+ ulong cur_pfn = rma_size_mfn;
+
list_for_each_entry (pe, &d->arch.extent_list, pe_list) {
- uint end_pfn = pe->pfn + (1 << pe->order);
-
- if (pfn >= pe->pfn && pfn < end_pfn) {
+ uint pe_pages = 1UL << pe->order;
+ uint end_pfn = cur_pfn + pe_pages;
+
+ if (pfn >= cur_pfn && pfn < end_pfn) {
t = PFN_TYPE_LOGICAL;
- mfn = page_to_mfn(pe->pg) + (pfn - pe->pfn);
+ mfn = page_to_mfn(pe->pg) + (pfn - cur_pfn);
break;
}
+ cur_pfn += pe_pages;
}
}
- BUG_ON(t != PFN_TYPE_NONE && page_get_owner(mfn_to_page(mfn)) != d);
+#ifdef DEBUG
+ if (t != PFN_TYPE_NONE &&
+ (d->domain_flags & DOMF_dying) &&
+ page_get_owner(mfn_to_page(mfn)) != d) {
+ printk("%s: page type: %d owner Dom[%d]:%p expected Dom[%d]:%p\n",
+ __func__, t,
+ page_get_owner(mfn_to_page(mfn))->domain_id,
+ page_get_owner(mfn_to_page(mfn)),
+ d->domain_id, d);
+ BUG();
+ }
+#endif
}
if (t == PFN_TYPE_NONE) {
@@ -368,6 +482,42 @@ ulong pfn2mfn(struct domain *d, ulong pf
return mfn;
}
+unsigned long mfn_to_gmfn(struct domain *d, unsigned long mfn)
+{
+ struct page_extents *pe;
+ ulong cur_pfn;
+ ulong gnttab_mfn;
+ ulong rma_mfn;
+
+ /* grant? */
+ gnttab_mfn = gnttab_shared_mfn(d, d->grant_table, 0);
+ if (mfn >= gnttab_mfn && mfn < (gnttab_mfn + NR_GRANT_FRAMES))
+ return max_page + (mfn - gnttab_mfn);
+
+ /* IO? */
+ if (d->is_privileged && cpu_io_mfn(mfn))
+ return mfn;
+
+ rma_mfn = page_to_mfn(d->arch.rma_page);
+ if (mfn >= rma_mfn &&
+ mfn < (rma_mfn + (1 << d->arch.rma_order)))
+ return mfn - rma_mfn;
+
+ /* Extent? */
+ cur_pfn = 1UL << d->arch.rma_order;
+ list_for_each_entry (pe, &d->arch.extent_list, pe_list) {
+ uint pe_pages = 1UL << pe->order;
+ uint b_mfn = page_to_mfn(pe->pg);
+ uint e_mfn = b_mfn + pe_pages;
+
+ if (mfn >= b_mfn && mfn < e_mfn) {
+ return cur_pfn + (mfn - b_mfn);
+ }
+ cur_pfn += pe_pages;
+ }
+ return INVALID_M2P_ENTRY;
+}
+
void guest_physmap_add_page(
struct domain *d, unsigned long gpfn, unsigned long mfn)
{
@@ -382,3 +532,10 @@ void shadow_drop_references(
struct domain *d, struct page_info *page)
{
}
+
+int arch_domain_add_extent(struct domain *d, struct page_info *page, int order)
+{
+ if (add_extent(d, page, order) < 0)
+ return -ENOMEM;
+ return 0;
+}
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/mpic.c
--- a/xen/arch/powerpc/mpic.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/mpic.c Fri Dec 15 11:32:58 2006 -0700
@@ -15,22 +15,18 @@
/* XXX Xen hacks ... */
/* make this generic */
-#define le32_to_cpu(x) \
-({ \
- __u32 __x = (x); \
- ((__u32)( \
- (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | \
- (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | \
- (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | \
- (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \
-})
+#define le32_to_cpu(x) \
+ ({ \
+ __u32 __x = (x); \
+ ((__u32)( \
+ (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | \
+ (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | \
+ (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | \
+ (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \
+ })
#define alloc_bootmem(x) xmalloc_bytes(x)
-#define request_irq(irq, handler, f, devname, dev_id) \
- panic("IPI requested: %d: %p: %s: %p\n", irq, handler, devname, dev_id)
-
-typedef int irqreturn_t;
#define IRQ_NONE (0)
#define IRQ_HANDLED (1)
@@ -97,11 +93,6 @@ typedef int irqreturn_t;
#include <asm/mpic.h>
#include <asm/smp.h>
-static inline void smp_message_recv(int msg, struct pt_regs *regs)
-{
- return;
-}
-
#ifdef DEBUG
#define DBG(fmt...) printk(fmt)
#else
@@ -126,7 +117,7 @@ static DEFINE_SPINLOCK(mpic_lock);
static inline u32 _mpic_read(unsigned int be, volatile u32 __iomem *base,
- unsigned int reg)
+ unsigned int reg)
{
if (be)
return in_be32(base + (reg >> 2));
@@ -135,7 +126,7 @@ static inline u32 _mpic_read(unsigned in
}
static inline void _mpic_write(unsigned int be, volatile u32 __iomem *base,
- unsigned int reg, u32 value)
+ unsigned int reg, u32 value)
{
if (be)
out_be32(base + (reg >> 2), value);
@@ -186,17 +177,17 @@ static inline u32 _mpic_irq_read(struct
unsigned int idx = src_no & mpic->isu_mask;
return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
- reg + (idx * MPIC_IRQ_STRIDE));
+ reg + (idx * MPIC_IRQ_STRIDE));
}
static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
- unsigned int reg, u32 value)
+ unsigned int reg, u32 value)
{
unsigned int isu = src_no >> mpic->isu_shift;
unsigned int idx = src_no & mpic->isu_mask;
_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
- reg + (idx * MPIC_IRQ_STRIDE), value);
+ reg + (idx * MPIC_IRQ_STRIDE), value);
}
#define mpic_read(b,r) _mpic_read(mpic->flags &
MPIC_BIG_ENDIAN,(b),(r))
@@ -261,7 +252,7 @@ static inline void mpic_ht_end_irq(struc
}
static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source,
- unsigned int irqflags)
+ unsigned int irqflags)
{
struct mpic_irq_fixup *fixup = &mpic->fixups[source];
unsigned long flags;
@@ -284,7 +275,7 @@ static void mpic_startup_ht_interrupt(st
}
static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source,
- unsigned int irqflags)
+ unsigned int irqflags)
{
struct mpic_irq_fixup *fixup = &mpic->fixups[source];
unsigned long flags;
@@ -305,7 +296,7 @@ static void mpic_shutdown_ht_interrupt(s
}
static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase,
- unsigned int devfn, u32 vdid)
+ unsigned int devfn, u32 vdid)
{
int i, irq, n;
u8 __iomem *base;
@@ -485,8 +476,8 @@ static void mpic_enable_irq(unsigned int
DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
- mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
- ~MPIC_VECPRI_MASK);
+ mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
+ ~MPIC_VECPRI_MASK);
/* make sure mask gets to controller before we return to user */
do {
@@ -532,8 +523,8 @@ static void mpic_disable_irq(unsigned in
DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
- mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
- MPIC_VECPRI_MASK);
+ mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
+ MPIC_VECPRI_MASK);
/* make sure mask gets to controller before we return to user */
do {
@@ -623,7 +614,7 @@ static void mpic_set_affinity(unsigned i
cpus_and(tmp, cpumask, cpu_online_map);
mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_DESTINATION,
- mpic_physmask(cpus_addr(tmp)[0]));
+ mpic_physmask(cpus_addr(tmp)[0]));
}
@@ -633,14 +624,14 @@ static void mpic_set_affinity(unsigned i
struct mpic * __init mpic_alloc(unsigned long phys_addr,
- unsigned int flags,
- unsigned int isu_size,
- unsigned int irq_offset,
- unsigned int irq_count,
- unsigned int ipi_offset,
- unsigned char *senses,
- unsigned int senses_count,
- const char *name)
+ unsigned int flags,
+ unsigned int isu_size,
+ unsigned int irq_offset,
+ unsigned int irq_count,
+ unsigned int ipi_offset,
+ unsigned char *senses,
+ unsigned int senses_count,
+ const char *name)
{
struct mpic *mpic;
u32 reg;
@@ -687,8 +678,8 @@ struct mpic * __init mpic_alloc(unsigned
/* Reset */
if (flags & MPIC_WANTS_RESET) {
mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
- mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
- | MPIC_GREG_GCONF_RESET);
+ mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
+ | MPIC_GREG_GCONF_RESET);
while( mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
& MPIC_GREG_GCONF_RESET)
mb();
@@ -700,15 +691,15 @@ struct mpic * __init mpic_alloc(unsigned
*/
reg = mpic_read(mpic->gregs, MPIC_GREG_FEATURE_0);
mpic->num_cpus = ((reg & MPIC_GREG_FEATURE_LAST_CPU_MASK)
- >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1;
+ >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1;
if (isu_size == 0)
mpic->num_sources = ((reg & MPIC_GREG_FEATURE_LAST_SRC_MASK)
- >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1;
+ >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1;
/* Map the per-CPU registers */
for (i = 0; i < mpic->num_cpus; i++) {
mpic->cpuregs[i] = ioremap(phys_addr + MPIC_CPU_BASE +
- i * MPIC_CPU_STRIDE, 0x1000);
+ i * MPIC_CPU_STRIDE, 0x1000);
BUG_ON(mpic->cpuregs[i] == NULL);
}
@@ -716,7 +707,7 @@ struct mpic * __init mpic_alloc(unsigned
if (mpic->isu_size == 0) {
mpic->isu_size = mpic->num_sources;
mpic->isus[0] = ioremap(phys_addr + MPIC_IRQ_BASE,
- MPIC_IRQ_STRIDE * mpic->isu_size);
+ MPIC_IRQ_STRIDE * mpic->isu_size);
BUG_ON(mpic->isus[0] == NULL);
}
mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
@@ -752,7 +743,7 @@ struct mpic * __init mpic_alloc(unsigned
}
void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
- unsigned long phys_addr)
+ unsigned long phys_addr)
{
unsigned int isu_first = isu_num * mpic->isu_size;
@@ -764,7 +755,7 @@ void __init mpic_assign_isu(struct mpic
}
void __init mpic_setup_cascade(unsigned int irq, mpic_cascade_t handler,
- void *data)
+ void *data)
{
struct mpic *mpic = mpic_find(irq, NULL);
unsigned long flags;
@@ -799,20 +790,20 @@ void __init mpic_init(struct mpic *mpic)
/* Initialize timers: just disable them all */
for (i = 0; i < 4; i++) {
mpic_write(mpic->tmregs,
- i * MPIC_TIMER_STRIDE + MPIC_TIMER_DESTINATION, 0);
+ i * MPIC_TIMER_STRIDE + MPIC_TIMER_DESTINATION, 0);
mpic_write(mpic->tmregs,
- i * MPIC_TIMER_STRIDE + MPIC_TIMER_VECTOR_PRI,
- MPIC_VECPRI_MASK |
- (MPIC_VEC_TIMER_0 + i));
+ i * MPIC_TIMER_STRIDE + MPIC_TIMER_VECTOR_PRI,
+ MPIC_VECPRI_MASK |
+ (MPIC_VEC_TIMER_0 + i));
}
/* Initialize IPIs to our reserved vectors and mark them disabled for
now */
mpic_test_broken_ipi(mpic);
for (i = 0; i < 4; i++) {
mpic_ipi_write(i,
- MPIC_VECPRI_MASK |
- (10 << MPIC_VECPRI_PRIORITY_SHIFT) |
- (MPIC_VEC_IPI_0 + i));
+ MPIC_VECPRI_MASK |
+ (10 << MPIC_VECPRI_PRIORITY_SHIFT) |
+ (MPIC_VEC_IPI_0 + i));
#ifdef CONFIG_SMP
if (!(mpic->flags & MPIC_PRIMARY))
continue;
@@ -859,7 +850,7 @@ void __init mpic_init(struct mpic *mpic)
#ifdef CONFIG_MPIC_BROKEN_U3
if (mpic_is_ht_interrupt(mpic, i)) {
vecpri &= ~(MPIC_VECPRI_SENSE_MASK |
- MPIC_VECPRI_POLARITY_MASK);
+ MPIC_VECPRI_POLARITY_MASK);
vecpri |= MPIC_VECPRI_POLARITY_POSITIVE;
}
#else
@@ -873,7 +864,7 @@ void __init mpic_init(struct mpic *mpic)
/* init hw */
mpic_irq_write(i, MPIC_IRQ_VECTOR_PRI, vecpri);
mpic_irq_write(i, MPIC_IRQ_DESTINATION,
- 1 << hard_smp_processor_id());
+ 1 << hard_smp_processor_id());
/* init linux descriptors */
if (i < mpic->irq_count) {
@@ -887,8 +878,8 @@ void __init mpic_init(struct mpic *mpic)
/* Disable 8259 passthrough */
mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
- mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
- | MPIC_GREG_GCONF_8259_PTHROU_DIS);
+ mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
+ | MPIC_GREG_GCONF_8259_PTHROU_DIS);
/* Set current processor priority to 0 */
mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);
@@ -908,12 +899,12 @@ void mpic_irq_set_priority(unsigned int
reg = mpic_ipi_read(irq - mpic->ipi_offset) &
~MPIC_VECPRI_PRIORITY_MASK;
mpic_ipi_write(irq - mpic->ipi_offset,
- reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
+ reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
} else {
reg = mpic_irq_read(irq - mpic->irq_offset,MPIC_IRQ_VECTOR_PRI)
& ~MPIC_VECPRI_PRIORITY_MASK;
mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI,
- reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
+ reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
}
spin_unlock_irqrestore(&mpic_lock, flags);
}
@@ -956,7 +947,7 @@ void mpic_setup_this_cpu(void)
if (distribute_irqs) {
for (i = 0; i < mpic->num_sources ; i++)
mpic_irq_write(i, MPIC_IRQ_DESTINATION,
- mpic_irq_read(i, MPIC_IRQ_DESTINATION) | msk);
+ mpic_irq_read(i, MPIC_IRQ_DESTINATION) | msk);
}
/* Set current processor priority to 0 */
@@ -1001,7 +992,7 @@ void mpic_teardown_this_cpu(int secondar
/* let the mpic know we don't want intrs. */
for (i = 0; i < mpic->num_sources ; i++)
mpic_irq_write(i, MPIC_IRQ_DESTINATION,
- mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk);
+ mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk);
/* Set current processor priority to max */
mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);
@@ -1021,7 +1012,7 @@ void mpic_send_ipi(unsigned int ipi_no,
#endif
mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10,
- mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
+ mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
}
int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs)
@@ -1049,7 +1040,7 @@ int mpic_get_one_irq(struct mpic *mpic,
return irq + mpic->irq_offset;
}
#ifdef DEBUG_IPI
- DBG("%s: ipi %d !\n", mpic->name, irq - MPIC_VEC_IPI_0);
+ DBG("%s: ipi %d !\n", mpic->name, irq - MPIC_VEC_IPI_0);
#endif
return irq - MPIC_VEC_IPI_0 + mpic->ipi_offset;
}
@@ -1075,13 +1066,13 @@ void mpic_request_ipis(void)
/* IPIs are marked SA_INTERRUPT as they must run with irqs disabled */
request_irq(mpic->ipi_offset+0, mpic_ipi_action, SA_INTERRUPT,
- "IPI0 (call function)", mpic);
+ "IPI0 (call function)", mpic);
request_irq(mpic->ipi_offset+1, mpic_ipi_action, SA_INTERRUPT,
- "IPI1 (reschedule)", mpic);
+ "IPI1 (reschedule)", mpic);
request_irq(mpic->ipi_offset+2, mpic_ipi_action, SA_INTERRUPT,
- "IPI2 (unused)", mpic);
+ "IPI2 (unused)", mpic);
request_irq(mpic->ipi_offset+3, mpic_ipi_action, SA_INTERRUPT,
- "IPI3 (debugger break)", mpic);
+ "IPI3 (debugger break)", mpic);
printk("IPIs requested... \n");
}
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/mpic_init.c
--- a/xen/arch/powerpc/mpic_init.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/mpic_init.c Fri Dec 15 11:32:58 2006 -0700
@@ -22,6 +22,7 @@
#include <xen/init.h>
#include <xen/lib.h>
#include <asm/mpic.h>
+#include <errno.h>
#include "mpic_init.h"
#include "oftree.h"
#include "of-devtree.h"
@@ -74,7 +75,7 @@ static unsigned long reg2(void *oft_p, o
rc = ofd_getprop(oft_p, c, "reg", &isa_reg, sizeof(isa_reg));
DBG("%s: reg property address=0x%08x size=0x%08x\n", __func__,
- isa_reg.address, isa_reg.size);
+ isa_reg.address, isa_reg.size);
return isa_reg.address;
}
@@ -92,7 +93,7 @@ static unsigned long reg1(void *oft_p, o
rc = ofd_getprop(oft_p, c, "reg", ®, sizeof(reg));
DBG("%s: reg property address=0x%08x size=0x%08x\n", __func__,
- reg.address, reg.size);
+ reg.address, reg.size);
return reg.address;
}
@@ -173,15 +174,15 @@ static unsigned long find_ranges_addr_fr
break;
case 2:
ranges_addr = (((u64)ranges[ranges_i]) << 32) |
- ranges[ranges_i + 1];
+ ranges[ranges_i + 1];
break;
case 3: /* the G5 case, how to squeeze 96 bits into 64 */
ranges_addr = (((u64)ranges[ranges_i+1]) << 32) |
- ranges[ranges_i + 2];
+ ranges[ranges_i + 2];
break;
case 4:
ranges_addr = (((u64)ranges[ranges_i+2]) << 32) |
- ranges[ranges_i + 4];
+ ranges[ranges_i + 4];
break;
default:
PANIC("#address-cells out of range\n");
@@ -266,7 +267,7 @@ static int find_mpic_canonical_probe(voi
* We select the one without an 'interrupt' property.
*/
c = ofd_node_find_by_prop(oft_p, OFD_ROOT, "device_type", mpic_type,
- sizeof(mpic_type));
+ sizeof(mpic_type));
while (c > 0) {
int int_len;
int good_mpic;
@@ -357,6 +358,42 @@ static struct hw_interrupt_type *share_m
#define share_mpic(M,X) (M)
#endif
+
+static unsigned int mpic_startup_ipi(unsigned int irq)
+{
+ mpic->hc_ipi.enable(irq);
+ return 0;
+}
+
+int request_irq(unsigned int irq,
+ irqreturn_t (*handler)(int, void *, struct cpu_user_regs *),
+ unsigned long irqflags, const char * devname, void *dev_id)
+{
+ int retval;
+ struct irqaction *action;
+ void (*func)(int, void *, struct cpu_user_regs *);
+
+ action = xmalloc(struct irqaction);
+ if (!action) {
+ BUG();
+ return -ENOMEM;
+ }
+
+ /* Xen's handler prototype is slightly different than Linux's. */
+ func = (void (*)(int, void *, struct cpu_user_regs *))handler;
+
+ action->handler = func;
+ action->name = devname;
+ action->dev_id = dev_id;
+
+ retval = setup_irq(irq, action);
+ if (retval) {
+ BUG();
+ xfree(action);
+ }
+
+ return retval;
+}
struct hw_interrupt_type *xen_mpic_init(struct hw_interrupt_type *xen_irq)
{
@@ -397,6 +434,11 @@ struct hw_interrupt_type *xen_mpic_init(
hit = share_mpic(&mpic->hc_irq, xen_irq);
printk("%s: success\n", __func__);
+
+ mpic->hc_ipi.ack = xen_irq->ack;
+ mpic->hc_ipi.startup = mpic_startup_ipi;
+ mpic_request_ipis();
+
return hit;
}
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/numa.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/powerpc/numa.c Fri Dec 15 11:32:58 2006 -0700
@@ -0,0 +1,1 @@
+#include "../x86/numa.c"
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/of-devtree.h
--- a/xen/arch/powerpc/of-devtree.h Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/of-devtree.h Fri Dec 15 11:32:58 2006 -0700
@@ -33,15 +33,15 @@ union of_pci_hi {
union of_pci_hi {
u32 word;
struct {
- u32 opa_n: 1; /* relocatable */
- u32 opa_p: 1; /* prefetchable */
- u32 opa_t: 1; /* aliased */
+ u32 opa_n: 1; /* relocatable */
+ u32 opa_p: 1; /* prefetchable */
+ u32 opa_t: 1; /* aliased */
u32 _opa_res: 3;
- u32 opa: 2; /* space code */
+ u32 opa: 2; /* space code */
u32 opa_b: 8; /* bus number */
- u32 opa_d: 5; /* device number */
- u32 opa_f: 3; /* function number */
- u32 opa_r: 8; /* register number */
+ u32 opa_d: 5; /* device number */
+ u32 opa_f: 3; /* function number */
+ u32 opa_r: 8; /* register number */
} bits;
};
@@ -79,9 +79,9 @@ typedef s32 ofdn_t;
typedef s32 ofdn_t;
#define OFD_ROOT 1
-#define OFD_DUMP_NAMES 0x1
-#define OFD_DUMP_VALUES 0x2
-#define OFD_DUMP_ALL (OFD_DUMP_VALUES|OFD_DUMP_NAMES)
+#define OFD_DUMP_NAMES 0x1
+#define OFD_DUMP_VALUES 0x2
+#define OFD_DUMP_ALL (OFD_DUMP_VALUES|OFD_DUMP_NAMES)
extern void *ofd_create(void *mem, size_t sz);
extern ofdn_t ofd_node_parent(void *mem, ofdn_t n);
@@ -90,9 +90,9 @@ extern const char *ofd_node_path(void *m
extern const char *ofd_node_path(void *mem, ofdn_t p);
extern int ofd_node_to_path(void *mem, ofdn_t p, void *buf, size_t sz);
extern ofdn_t ofd_node_child_create(void *mem, ofdn_t parent,
- const char *path, size_t pathlen);
+ const char *path, size_t pathlen);
extern ofdn_t ofd_node_peer_create(void *mem, ofdn_t sibling,
- const char *path, size_t pathlen);
+ const char *path, size_t pathlen);
extern ofdn_t ofd_node_find(void *mem, const char *devspec);
extern ofdn_t ofd_node_add(void *m, ofdn_t n, const char *path, size_t sz);
extern int ofd_node_prune(void *m, ofdn_t n);
@@ -102,23 +102,23 @@ extern ofdn_t ofd_nextprop(void *mem, of
extern ofdn_t ofd_nextprop(void *mem, ofdn_t n, const char *prev, char *name);
extern ofdn_t ofd_prop_find(void *mem, ofdn_t n, const char *name);
extern int ofd_getprop(void *mem, ofdn_t n, const char *name,
- void *buf, size_t sz);
+ void *buf, size_t sz);
extern int ofd_getproplen(void *mem, ofdn_t n, const char *name);
extern int ofd_setprop(void *mem, ofdn_t n, const char *name,
- const void *buf, size_t sz);
+ const void *buf, size_t sz);
extern void ofd_prop_remove(void *mem, ofdn_t node, ofdn_t prop);
extern ofdn_t ofd_prop_add(void *mem, ofdn_t n, const char *name,
- const void *buf, size_t sz);
+ const void *buf, size_t sz);
extern ofdn_t ofd_io_create(void *m, ofdn_t node, u64 open);
extern u32 ofd_io_open(void *mem, ofdn_t n);
extern void ofd_io_close(void *mem, ofdn_t n);
-typedef void (*walk_fn)(void *m, ofdn_t p, int arg);
-extern void ofd_dump_props(void *m, ofdn_t p, int dump);
+typedef void (*walk_fn)(void *m, const char *pre, ofdn_t p, int arg);
+extern void ofd_dump_props(void *m, const char *pre, ofdn_t p, int dump);
-extern void ofd_walk(void *m, ofdn_t p, walk_fn fn, int arg);
+extern void ofd_walk(void *m, const char *pre, ofdn_t p, walk_fn fn, int arg);
/* Recursively look up #address_cells and #size_cells properties */
@@ -129,10 +129,10 @@ extern size_t ofd_space(void *mem);
extern size_t ofd_space(void *mem);
extern void ofd_prop_print(const char *head, const char *path,
- const char *name, const char *prop, size_t sz);
+ const char *name, const char *prop, size_t sz);
extern ofdn_t ofd_node_find_by_prop(void *mem, ofdn_t n, const char *name,
- const void *val, size_t sz);
+ const void *val, size_t sz);
extern ofdn_t ofd_node_find_next(void *mem, ofdn_t n);
extern ofdn_t ofd_node_find_prev(void *mem, ofdn_t n);
extern void ofd_init(int (*write)(const char *, size_t len));
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/of-devwalk.c
--- a/xen/arch/powerpc/of-devwalk.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/of-devwalk.c Fri Dec 15 11:32:58 2006 -0700
@@ -80,7 +80,7 @@ void ofd_prop_print(
#endif
}
-void ofd_dump_props(void *mem, ofdn_t n, int dump)
+void ofd_dump_props(void *mem, const char *pre, ofdn_t n, int dump)
{
ofdn_t p;
char name[128];
@@ -95,7 +95,7 @@ void ofd_dump_props(void *mem, ofdn_t n,
}
if (dump & OFD_DUMP_NAMES) {
- printk("of_walk: %s: phandle 0x%x\n", path, n);
+ printk("%s: %s: phandle 0x%x\n", pre, path, n);
}
p = ofd_nextprop(mem, n, NULL, name);
@@ -106,30 +106,30 @@ void ofd_dump_props(void *mem, ofdn_t n,
}
if ( dump & OFD_DUMP_VALUES ) {
- ofd_prop_print("of_walk", path, name, prop, sz);
+ ofd_prop_print(pre, path, name, prop, sz);
}
p = ofd_nextprop(mem, n, name, name);
}
}
-void ofd_walk(void *m, ofdn_t p, walk_fn fn, int arg)
+void ofd_walk(void *m, const char *pre, ofdn_t p, walk_fn fn, int arg)
{
ofdn_t n;
if ( fn != NULL ) {
- (*fn)(m, p, arg);
+ (*fn)(m, pre, p, arg);
}
/* child */
n = ofd_node_child(m, p);
if ( n != 0 ) {
- ofd_walk(m, n, fn, arg);
+ ofd_walk(m, pre, n, fn, arg);
}
/* peer */
n = ofd_node_peer(m, p);
if ( n != 0 ) {
- ofd_walk(m, n, fn, arg);
+ ofd_walk(m, pre, n, fn, arg);
}
}
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/of_handler/console.c
--- a/xen/arch/powerpc/of_handler/console.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/of_handler/console.c Fri Dec 15 11:32:58 2006 -0700
@@ -113,7 +113,7 @@ static s32 ofh_xen_dom0_read(s32 chan, v
return ret;
rc = xen_hvcall(XEN_MARK(__HYPERVISOR_console_io), CONSOLEIO_read,
- count, desc);
+ count, desc);
if (rc <= 0) {
return ret;
}
@@ -139,7 +139,7 @@ static s32 ofh_xen_dom0_write(s32 chan,
return ret;
rc = xen_hvcall(XEN_MARK(__HYPERVISOR_console_io), CONSOLEIO_write,
- count, desc);
+ count, desc);
if (rc <= 0) {
return ret;
}
@@ -157,8 +157,8 @@ static s32 ofh_xen_domu_read(s32 chan, v
static s32 ofh_xen_domu_read(s32 chan, void *buf, u32 count, s32 *actual,
ulong b)
{
- struct xencons_interface *intf;
- XENCONS_RING_IDX cons, prod;
+ struct xencons_interface *intf;
+ XENCONS_RING_IDX cons, prod;
s32 ret;
intf = DRELA(ofh_ihp, b)->ofi_intf;
@@ -180,8 +180,8 @@ static s32 ofh_xen_domu_write(s32 chan,
static s32 ofh_xen_domu_write(s32 chan, const void *buf, u32 count,
s32 *actual, ulong b)
{
- struct xencons_interface *intf;
- XENCONS_RING_IDX cons, prod;
+ struct xencons_interface *intf;
+ XENCONS_RING_IDX cons, prod;
s32 ret;
intf = DRELA(ofh_ihp, b)->ofi_intf;
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/ofd_fixup.c
--- a/xen/arch/powerpc/ofd_fixup.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/ofd_fixup.c Fri Dec 15 11:32:58 2006 -0700
@@ -25,6 +25,7 @@
#include <public/xen.h>
#include "of-devtree.h"
#include "oftree.h"
+#include "rtas.h"
#undef RTAS
@@ -347,6 +348,15 @@ static ofdn_t ofd_xen_props(void *m, str
val[0] = rma_size(d->arch.rma_order) - val[1];
ofd_prop_add(m, n, "reserved", val, sizeof (val));
+ /* tell dom0 that Xen depends on it to have power control */
+ if (!rtas_entry)
+ ofd_prop_add(m, n, "power-control", NULL, 0);
+
+ /* tell dom0 where ranted pages go in the linear map */
+ val[0] = cpu_foreign_map_order();
+ val[1] = d->arch.foreign_mfn_count;
+ ofd_prop_add(m, n, "foreign-map", val, sizeof (val));
+
n = ofd_node_add(m, n, console, sizeof (console));
if (n > 0) {
val[0] = 0;
@@ -417,7 +427,7 @@ int ofd_dom0_fixup(struct domain *d, ulo
#ifdef DEBUG
- ofd_walk(m, OFD_ROOT, ofd_dump_props, OFD_DUMP_ALL);
+ ofd_walk(m, __func__, OFD_ROOT, ofd_dump_props, OFD_DUMP_ALL);
#endif
return 1;
}
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/ofd_fixup_memory.c
--- a/xen/arch/powerpc/ofd_fixup_memory.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/ofd_fixup_memory.c Fri Dec 15 11:32:58 2006 -0700
@@ -68,6 +68,8 @@ static ofdn_t ofd_memory_node_create(
reg.sz = size;
ofd_prop_add(m, n, "reg", ®, sizeof (reg));
+ printk("Dom0: %s: %016lx, %016lx\n", path, start, size);
+
return n;
}
@@ -86,17 +88,19 @@ static void ofd_memory_extent_nodes(void
ulong size;
ofdn_t n;
struct page_extents *pe;
+ ulong cur_pfn = 1UL << d->arch.rma_order;
+ start = cur_pfn << PAGE_SHIFT;
+ size = 0;
list_for_each_entry (pe, &d->arch.extent_list, pe_list) {
- start = pe->pfn << PAGE_SHIFT;
- size = 1UL << (pe->order + PAGE_SHIFT);
-
- n = ofd_memory_node_create(m, OFD_ROOT, "", memory, memory,
- start, size);
-
- BUG_ON(n <= 0);
+ size += 1UL << (pe->order + PAGE_SHIFT);
+ if (pe->order != cpu_extent_order())
+ panic("we don't handle this yet\n");
}
+ n = ofd_memory_node_create(m, OFD_ROOT, "", memory, memory,
+ start, size);
+ BUG_ON(n <= 0);
}
void ofd_memory_props(void *m, struct domain *d)
diff -r 1e042dde1a5f -r e17d7438e09e xen/arch/powerpc/papr/xlate.c
--- a/xen/arch/powerpc/papr/xlate.c Fri Dec 15 10:59:33 2006 -0700
+++ b/xen/arch/powerpc/papr/xlate.c Fri Dec 15 11:32:58 2006 -0700
@@ -19,7 +19,7 @@
*/
#undef DEBUG
-#undef DEBUG_FAIL
+#undef DEBUG_LOW
#include <xen/config.h>
#include <xen/types.h>
@@ -30,6 +30,17 @@
#include <asm/papr.h>
#include <asm/hcalls.h>
+#ifdef DEBUG
+#define DBG(fmt...) printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
+#ifdef DEBUG_LOW
+#define DBG_LOW(fmt...) printk(fmt)
+#else
+#define DBG_LOW(fmt...)
+#endif
+
#ifdef USE_PTE_INSERT
static inline void pte_insert(union pte volatile *pte,
ulong vsid, ulong rpn, ulong lrpn)
@@ -106,11 +117,8 @@ static void pte_tlbie(union pte volatile
}
-static void h_enter(struct cpu_user_regs *regs)
-{
- ulong flags = regs->gprs[4];
- ulong ptex = regs->gprs[5];
-
+long pte_enter(ulong flags, ulong ptex, ulong vsid, ulong rpn)
+{
union pte pte;
union pte volatile *ppte;
struct domain_htab *htab;
@@ -129,14 +137,13 @@ static void h_enter(struct cpu_user_regs
htab = &d->arch.htab;
if (ptex > (1UL << htab->log_num_ptes)) {
- regs->gprs[3] = H_Parameter;
- printk("%s: bad ptex: 0x%lx\n", __func__, ptex);
- return;
+ DBG("%s: bad ptex: 0x%lx\n", __func__, ptex);
+ return H_Parameter;
}
/* use local HPTE to avoid manual shifting & masking */
- pte.words.vsid = regs->gprs[6];
- pte.words.rpn = regs->gprs[7];
+ pte.words.vsid = vsid;
+ pte.words.rpn = rpn;
if ( pte.bits.l ) { /* large page? */
/* figure out the page size for the selected large page */
@@ -150,10 +157,9 @@ static void h_enter(struct cpu_user_regs
}
if ( lp_size >= d->arch.large_page_sizes ) {
- printk("%s: attempt to use unsupported lp_size %d\n",
- __func__, lp_size);
- regs->gprs[3] = H_Parameter;
- return;
+ DBG("%s: attempt to use unsupported lp_size %d\n",
+ __func__, lp_size);
+ return H_Parameter;
}
/* get correct pgshift value */
@@ -168,31 +174,32 @@ static void h_enter(struct cpu_user_regs
mfn = pfn2mfn(d, pfn, &mtype);
if (mfn == INVALID_MFN) {
- regs->gprs[3] = H_Parameter;
- return;
- }
-
+ DBG("%s: Bad PFN: 0x%lx\n", __func__, pfn);
+ return H_Parameter;
+ }
+
+ if (mtype == PFN_TYPE_IO && !d->is_privileged) {
+ /* only a privilaged dom can access outside IO space */
+ DBG("%s: unprivileged access to physical page: 0x%lx\n",
+ __func__, pfn);
+ return H_Privilege;
+ }
if (mtype == PFN_TYPE_IO) {
- /* only a privilaged dom can access outside IO space */
- if ( !d->is_privileged ) {
- regs->gprs[3] = H_Privilege;
- printk("%s: unprivileged access to physical page: 0x%lx\n",
- __func__, pfn);
- return;
- }
-
if ( !((pte.bits.w == 0)
&& (pte.bits.i == 1)
&& (pte.bits.g == 1)) ) {
-#ifdef DEBUG_FAIL
- printk("%s: expecting an IO WIMG "
- "w=%x i=%d m=%d, g=%d\n word 0x%lx\n", __func__,
- pte.bits.w, pte.bits.i, pte.bits.m, pte.bits.g,
- pte.words.rpn);
-#endif
- regs->gprs[3] = H_Parameter;
- return;
- }
+ DBG("%s: expecting an IO WIMG "
+ "w=%x i=%d m=%d, g=%d\n word 0x%lx\n", __func__,
+ pte.bits.w, pte.bits.i, pte.bits.m, pte.bits.g,
+ pte.words.rpn);
+ return H_Parameter;
+ }
+ }
+ if (mtype == PFN_TYPE_GNTTAB) {
+ DBG("%s: Dom[%d] mapping grant table: 0x%lx\n",
+ __func__, d->domain_id, pfn << PAGE_SHIFT);
+ pte.bits.i = 0;
+ pte.bits.g = 0;
}
/* fixup the RPN field of our local PTE copy */
pte.bits.rpn = mfn | lp_bits;
@@ -213,13 +220,13 @@ static void h_enter(struct cpu_user_regs
BUG_ON(f == d);
if (unlikely(!get_domain(f))) {
- regs->gprs[3] = H_Rescinded;
- return;
+ DBG("%s: Rescinded, no domain: 0x%lx\n", __func__, pfn);
+ return H_Rescinded;
}
if (unlikely(!get_page(pg, f))) {
put_domain(f);
- regs->gprs[3] = H_Rescinded;
- return;
+ DBG("%s: Rescinded, no page: 0x%lx\n", __func__, pfn);
+ return H_Rescinded;
}
}
@@ -276,17 +283,12 @@ static void h_enter(struct cpu_user_regs
: "b" (ppte), "r" (pte.words.rpn), "r" (pte.words.vsid)
: "memory");
- regs->gprs[3] = H_Success;
- regs->gprs[4] = idx;
-
- return;
- }
- }
-
-#ifdef DEBUG
+ return idx;
+ }
+ }
+
/* If the PTEG is full then no additional values are returned. */
- printk("%s: PTEG FULL\n", __func__);
-#endif
+ DBG("%s: PTEG FULL\n", __func__);
if (pg != NULL)
put_page(pg);
@@ -294,7 +296,24 @@ static void h_enter(struct cpu_user_regs
if (f != NULL)
put_domain(f);
- regs->gprs[3] = H_PTEG_Full;
+ return H_PTEG_Full;
+}
+
+static void h_enter(struct cpu_user_regs *regs)
+{
+ ulong flags = regs->gprs[4];
+ ulong ptex = regs->gprs[5];
+ ulong vsid = regs->gprs[6];
+ ulong rpn = regs->gprs[7];
+ long ret;
+
+ ret = pte_enter(flags, ptex, vsid, rpn);
+
+ if (ret >= 0) {
+ regs->gprs[3] = H_Success;
+ regs->gprs[4] = ret;
+ } else
+ regs->gprs[3] = ret;
}
static void h_protect(struct cpu_user_regs *regs)
@@ -308,13 +327,11 @@ static void h_protect(struct cpu_user_re
union pte volatile *ppte;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|