From 54ac837cb52616764d8fa086ca9c5f7daadd965a Mon Sep 17 00:00:00 2001 From: Jimi Xenidis Date: Wed, 9 Aug 2006 18:53:00 -0400 Subject: [PATCH 01/11] [POWERPC] enable shadow mode This should have been enabled right from the begining. Signed-off-by: Jimi Xenidis Signed-off-by: Hollis Blanchard --- xen/arch/powerpc/mm.c | 17 +++++++++++++++++ xen/include/asm-powerpc/config.h | 1 + xen/include/asm-powerpc/shadow.h | 9 ++++++++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/xen/arch/powerpc/mm.c b/xen/arch/powerpc/mm.c index 00e072747b..783a8cdbae 100644 --- a/xen/arch/powerpc/mm.c +++ b/xen/arch/powerpc/mm.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -139,3 +140,19 @@ ulong pfn2mfn(struct domain *d, long pfn, int *type) return mfn; } + +void guest_physmap_add_page( + struct domain *d, unsigned long gpfn, unsigned long mfn) +{ + panic("%s\n", __func__); +} +void guest_physmap_remove_page( + struct domain *d, unsigned long gpfn, unsigned long mfn) +{ + panic("%s\n", __func__); +} +void shadow_drop_references( + struct domain *d, struct page_info *page) +{ + panic("%s\n", __func__); +} diff --git a/xen/include/asm-powerpc/config.h b/xen/include/asm-powerpc/config.h index 94caa6bea3..ff28fc7de5 100644 --- a/xen/include/asm-powerpc/config.h +++ b/xen/include/asm-powerpc/config.h @@ -47,6 +47,7 @@ extern char __bss_start[]; /* this should be per processor, but for now */ #define CACHE_LINE_SIZE 128 +#define CONFIG_SHADOW 1 #define CONFIG_GDB 1 #define CONFIG_SMP 1 #define CONFIG_PCI 1 diff --git a/xen/include/asm-powerpc/shadow.h b/xen/include/asm-powerpc/shadow.h index c247659f5e..8c7f3598bb 100644 --- a/xen/include/asm-powerpc/shadow.h +++ b/xen/include/asm-powerpc/shadow.h @@ -23,7 +23,7 @@ #include -#define shadow_mode_translate(_d) 1 +#define shadow_mode_translate(_d) (1) #define __translate_gpfn_to_mfn(_d, gpfn) \ ( (shadow_mode_translate(_d)) \ @@ -41,5 +41,12 @@ translate_gpfn_to_mfn(struct domain *rd, unsigned long gpfn) trap(); return 0; } +extern void guest_physmap_add_page( + struct domain *d, unsigned long gpfn, unsigned long mfn); +extern void guest_physmap_remove_page( + struct domain *d, unsigned long gpfn, unsigned long mfn); + +extern void shadow_drop_references( + struct domain *d, struct page_info *page); #endif From 5db603a56169a2f86732728d8eeb6c2049417229 Mon Sep 17 00:00:00 2001 From: Jimi Xenidis Date: Fri, 11 Aug 2006 13:30:48 -0400 Subject: [PATCH 02/11] [POWERPC] start-cpu has no return code According to this document: PowerPC Processor binding to: IEEE 1275-1994 Standard for Boot (Initialization, Configuration) Firmware Revision: 2.1 (Approved Version) Date: November 6, 1996 The start-cpu client interface has the following signature: start-cpu IN: nodeid, pc, arg OUT: none This patch reflects that, and makes us stop seeing a bogus OF_FAILURE if we do actually check the return code of of_start_cpu. Tested on JS20 and JS21 blades. Signed-off-by: Amos Waterland Signed-off-by: Hollis Blanchard --- xen/arch/powerpc/boot_of.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/xen/arch/powerpc/boot_of.c b/xen/arch/powerpc/boot_of.c index a450b7de9a..57465e7bc0 100644 --- a/xen/arch/powerpc/boot_of.c +++ b/xen/arch/powerpc/boot_of.c @@ -304,12 +304,11 @@ static int __init of_instance_to_path(int ih, char *buffer, u32 buflen) static int __init of_start_cpu(int cpu, u32 pc, u32 reg) { - int rets[1] = { OF_FAILURE }; + int ret; - if ( of_call("start-cpu", 3, 0, rets, cpu, pc, reg) == OF_FAILURE ) - return OF_FAILURE; + ret = of_call("start-cpu", 3, 0, NULL, cpu, pc, reg); - return rets[0]; + return ret; } static void __init of_test(const char *of_method_name) From 0303587f6d402463116c50dfeefd726f0543f611 Mon Sep 17 00:00:00 2001 From: Jimi Xenidis Date: Sun, 13 Aug 2006 14:43:50 -0400 Subject: [PATCH 03/11] [POWERPC] need a real definition for gnttab_log_dirty() Signed-off-by: Jimi Xenidis Signed-off-by: Hollis Blanchard --- xen/include/asm-powerpc/grant_table.h | 2 +- xen/include/asm-powerpc/shadow.h | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/xen/include/asm-powerpc/grant_table.h b/xen/include/asm-powerpc/grant_table.h index b439b53d64..e573f714a2 100644 --- a/xen/include/asm-powerpc/grant_table.h +++ b/xen/include/asm-powerpc/grant_table.h @@ -47,7 +47,7 @@ int destroy_grant_host_mapping( #define gnttab_shared_gmfn(d, t, i) \ (mfn_to_gmfn(d, gnttab_shared_mfn(d, t, i))) -#define gnttab_log_dirty(d, f) ((void )0) +#define gnttab_log_dirty(d, f) mark_dirty((d), (f)) static inline void gnttab_clear_flag(unsigned long nr, uint16_t *addr) { diff --git a/xen/include/asm-powerpc/shadow.h b/xen/include/asm-powerpc/shadow.h index 8c7f3598bb..88f7b0c84a 100644 --- a/xen/include/asm-powerpc/shadow.h +++ b/xen/include/asm-powerpc/shadow.h @@ -24,6 +24,7 @@ #include #define shadow_mode_translate(_d) (1) +#define shadow_mode_refcounts(_d) (1) #define __translate_gpfn_to_mfn(_d, gpfn) \ ( (shadow_mode_translate(_d)) \ @@ -49,4 +50,9 @@ extern void guest_physmap_remove_page( extern void shadow_drop_references( struct domain *d, struct page_info *page); + +static inline void mark_dirty(struct domain *d, unsigned int mfn) +{ + return; +} #endif From e8b7ed7c0890153ef8506214fe202286f0440815 Mon Sep 17 00:00:00 2001 From: Jimi Xenidis Date: Sun, 13 Aug 2006 19:19:37 -0400 Subject: [PATCH 04/11] [POWERPC] memory cleanup The following changes have been made: - htab is allocated by "order" using RMA size, soon it will be assigned memory. - keep track of RMA in terms of its allocated page struct and order - free htab and RMA memory in arch_domain_destroy() - get rid of PTEG FULL message, everyone thinks its a bug Signed-off-by: Jimi Xenidis Signed-off-by: Hollis Blanchard --- xen/arch/powerpc/domain.c | 33 +++++++++++++++++------------ xen/arch/powerpc/domain_build.c | 6 +++--- xen/arch/powerpc/htab.c | 5 +++-- xen/arch/powerpc/mm.c | 4 ++-- xen/arch/powerpc/ofd_fixup.c | 8 +++---- xen/arch/powerpc/papr/xlate.c | 2 ++ xen/arch/powerpc/powerpc64/ppc970.c | 4 ++-- xen/include/asm-powerpc/domain.h | 13 +++++++----- xen/include/asm-powerpc/htab.h | 5 +---- 9 files changed, 44 insertions(+), 36 deletions(-) diff --git a/xen/arch/powerpc/domain.c b/xen/arch/powerpc/domain.c index cd719815d7..149736f40f 100644 --- a/xen/arch/powerpc/domain.c +++ b/xen/arch/powerpc/domain.c @@ -73,10 +73,9 @@ unsigned long hypercall_create_continuation(unsigned int op, int arch_domain_create(struct domain *d) { - struct page_info *rma; unsigned long rma_base; unsigned long rma_size; - unsigned int rma_order; + uint htab_order; if (d->domain_id == IDLE_DOMAIN_ID) { d->shared_info = (void *)alloc_xenheap_page(); @@ -85,38 +84,44 @@ int arch_domain_create(struct domain *d) return 0; } - rma_order = cpu_rma_order(); - rma_size = 1UL << rma_order << PAGE_SHIFT; + d->arch.rma_order = cpu_rma_order(); + rma_size = 1UL << d->arch.rma_order << PAGE_SHIFT; /* allocate the real mode area */ - d->max_pages = 1UL << rma_order; - rma = alloc_domheap_pages(d, rma_order, 0); - if (NULL == rma) + d->max_pages = 1UL << d->arch.rma_order; + d->arch.rma_page = alloc_domheap_pages(d, d->arch.rma_order, 0); + if (NULL == d->arch.rma_page) return 1; - rma_base = page_to_maddr(rma); + rma_base = page_to_maddr(d->arch.rma_page); BUG_ON(rma_base & (rma_size-1)); /* check alignment */ - d->arch.rma_base = rma_base; - d->arch.rma_size = rma_size; - printk("clearing RMO: 0x%lx[0x%lx]\n", rma_base, rma_size); memset((void *)rma_base, 0, rma_size); - htab_alloc(d, LOG_DEFAULT_HTAB_BYTES); - d->shared_info = (shared_info_t *) (rma_addr(&d->arch, RMA_SHARED_INFO) + rma_base); d->arch.large_page_sizes = 1; d->arch.large_page_shift[0] = 24; /* 16 M for 970s */ + /* FIXME: we need to the the maximum addressible memory for this + * domain to calculate this correctly. It should probably be set + * by the managment tools */ + htab_order = d->arch.rma_order - 6; /* (1/64) */ + if (test_bit(_DOMF_privileged, &d->domain_flags)) { + /* bump the htab size of privleged domains */ + ++htab_order; + } + htab_alloc(d, htab_order); + return 0; } void arch_domain_destroy(struct domain *d) { - unimplemented(); + free_domheap_pages(d->arch.rma_page, d->arch.rma_order); + htab_free(d); } void machine_halt(void) diff --git a/xen/arch/powerpc/domain_build.c b/xen/arch/powerpc/domain_build.c index 89f68dae1b..4134bbaf02 100644 --- a/xen/arch/powerpc/domain_build.c +++ b/xen/arch/powerpc/domain_build.c @@ -105,8 +105,8 @@ int construct_dom0(struct domain *d, struct domain_setup_info dsi; ulong dst; u64 *ofh_tree; - ulong rma_sz = d->arch.rma_size; - ulong rma = d->arch.rma_base; + ulong rma_sz = rma_size(d->arch.rma_order); + ulong rma = page_to_maddr(d->arch.rma_page); start_info_t *si; ulong eomem; int am64 = 1; @@ -145,7 +145,7 @@ int construct_dom0(struct domain *d, /* By default DOM0 is allocated all available memory. */ d->max_pages = ~0U; - d->tot_pages = (d->arch.rma_size >> PAGE_SHIFT); + d->tot_pages = 1UL << d->arch.rma_order; ASSERT( image_len < rma_sz ); diff --git a/xen/arch/powerpc/htab.c b/xen/arch/powerpc/htab.c index 5d33e03288..c80b4480b9 100644 --- a/xen/arch/powerpc/htab.c +++ b/xen/arch/powerpc/htab.c @@ -34,13 +34,14 @@ static ulong htab_calc_sdr1(ulong htab_addr, ulong log_htab_size) return (htab_addr | (sdr1_htabsize & SDR1_HTABSIZE_MASK)); } -void htab_alloc(struct domain *d, int log_htab_bytes) +void htab_alloc(struct domain *d, uint order) { ulong htab_raddr; + ulong log_htab_bytes = order + PAGE_SHIFT; ulong htab_bytes = 1UL << log_htab_bytes; /* XXX use alloc_domheap_pages instead? */ - htab_raddr = (ulong)alloc_xenheap_pages(log_htab_bytes - PAGE_SHIFT); + htab_raddr = (ulong)alloc_xenheap_pages(order); ASSERT(htab_raddr != 0); /* XXX check alignment guarantees */ ASSERT((htab_raddr & (htab_bytes-1)) == 0); diff --git a/xen/arch/powerpc/mm.c b/xen/arch/powerpc/mm.c index 783a8cdbae..b03f795cdc 100644 --- a/xen/arch/powerpc/mm.c +++ b/xen/arch/powerpc/mm.c @@ -109,8 +109,8 @@ extern void copy_page(void *dp, void *sp) ulong pfn2mfn(struct domain *d, long pfn, int *type) { - ulong rma_base_mfn = d->arch.rma_base >> PAGE_SHIFT; - ulong rma_size_mfn = d->arch.rma_size >> PAGE_SHIFT; + ulong rma_base_mfn = page_to_mfn(d->arch.rma_page); + ulong rma_size_mfn = 1UL << d->arch.rma_order; ulong mfn; int t; diff --git a/xen/arch/powerpc/ofd_fixup.c b/xen/arch/powerpc/ofd_fixup.c index 5905423590..d18ff1808c 100644 --- a/xen/arch/powerpc/ofd_fixup.c +++ b/xen/arch/powerpc/ofd_fixup.c @@ -359,8 +359,8 @@ static ofdn_t ofd_memory_props(void *m, struct domain *d, ulong eoload) ofdn_t n = -1; ulong start = 0; static char name[] = "memory"; - ulong mem_size = d->arch.rma_size; - ulong chunk_size = d->arch.rma_size; + ulong mem_size = rma_size(d->arch.rma_order); + ulong chunk_size = rma_size(d->arch.rma_order); /* Remove all old memory props */ do { @@ -424,12 +424,12 @@ static ofdn_t ofd_xen_props(void *m, struct domain *d, start_info_t *si) ASSERT(xl < sizeof (xen)); ofd_prop_add(m, n, "version", xen, xl + 1); - val[0] = (ulong)si - d->arch.rma_base; + val[0] = (ulong)si - page_to_maddr(d->arch.rma_page); val[1] = PAGE_SIZE; ofd_prop_add(m, n, "start-info", val, sizeof (val)); val[1] = RMA_LAST_DOM0 * PAGE_SIZE; - val[0] = d->arch.rma_size - val[1]; + val[0] = rma_size(d->arch.rma_order) - val[1]; ofd_prop_add(m, n, "reserved", val, sizeof (val)); n = ofd_node_add(m, n, console, sizeof (console)); diff --git a/xen/arch/powerpc/papr/xlate.c b/xen/arch/powerpc/papr/xlate.c index fe5be75e18..82e18a1d2d 100644 --- a/xen/arch/powerpc/papr/xlate.c +++ b/xen/arch/powerpc/papr/xlate.c @@ -258,8 +258,10 @@ static void h_enter(struct cpu_user_regs *regs) } } +#ifdef DEBUG /* If the PTEG is full then no additional values are returned. */ printk("%s: PTEG FULL\n", __func__); +#endif regs->gprs[3] = H_PTEG_Full; } diff --git a/xen/arch/powerpc/powerpc64/ppc970.c b/xen/arch/powerpc/powerpc64/ppc970.c index 3be55a229c..b82e30ce80 100644 --- a/xen/arch/powerpc/powerpc64/ppc970.c +++ b/xen/arch/powerpc/powerpc64/ppc970.c @@ -114,8 +114,8 @@ void cpu_init_vcpu(struct vcpu *v) { struct domain *d = v->domain; union hid4 hid4; - ulong rma_base = d->arch.rma_base; - ulong rma_size = d->arch.rma_size; + ulong rma_base = page_to_maddr(d->arch.rma_page); + ulong rma_size = rma_size(d->arch.rma_order); hid4.word = mfhid4(); diff --git a/xen/include/asm-powerpc/domain.h b/xen/include/asm-powerpc/domain.h index 1bb7195f41..c5bab388dd 100644 --- a/xen/include/asm-powerpc/domain.h +++ b/xen/include/asm-powerpc/domain.h @@ -32,10 +32,11 @@ struct arch_domain { struct domain_htab htab; - /* The RMO area is fixed to the domain and is accessible while the + + /* The Real Mode area is fixed to the domain and is accessible while the * processor is in real mode */ - ulong rma_base; - ulong rma_size; + struct page_info *rma_page; + uint rma_order; /* This is regular memory, only available thru translataion */ ulong logical_base_pfn; @@ -106,9 +107,11 @@ extern void load_float(struct vcpu *); #define RMA_CONSOLE 3 #define RMA_LAST_DOMU 3 -static inline ulong rma_addr(struct arch_domain *d, int type) +#define rma_size(rma_order) (1UL << (rma_order) << PAGE_SHIFT) + +static inline ulong rma_addr(struct arch_domain *ad, int type) { - return d->rma_size - (type * PAGE_SIZE); + return rma_size(ad->rma_order) - (type * PAGE_SIZE); } #endif diff --git a/xen/include/asm-powerpc/htab.h b/xen/include/asm-powerpc/htab.h index 55b3259459..2a4ac26824 100644 --- a/xen/include/asm-powerpc/htab.h +++ b/xen/include/asm-powerpc/htab.h @@ -26,9 +26,6 @@ /***** general PowerPC architecture limits ******/ -#define LOG_DEFAULT_HTAB_BYTES 20 -#define DEFAULT_HTAB_BYTES (1UL << LOG_HTAB_BYTES) - /* 256KB, from PowerPC Architecture specification */ #define HTAB_MIN_LOG_SIZE 18 @@ -137,6 +134,6 @@ struct domain_htab { }; struct domain; -extern void htab_alloc(struct domain *d, int log_htab_bytes); +extern void htab_alloc(struct domain *d, uint order); extern void htab_free(struct domain *d); #endif From d7cb21e64ce7fe55b1ab3ea10677b185da7814b7 Mon Sep 17 00:00:00 2001 From: Jimi Xenidis Date: Mon, 14 Aug 2006 09:53:46 -0400 Subject: [PATCH 05/11] [POWERPC] memory cleanup (phase 2), destroy (et. al) now work The patch fixes the following problems: - Fix initializing the heaps so we can Link anywhere < RMA. We not link xen at 4MiB, which is way saner. - We track and allocate pages (especially RMA) based on order. - free domain memory as a resource not as domain - clarify "order" arithmetic - update stale def of fix IS_XEN_HEAP_FRAME() Signed-off-by: Jimi Xenidis Signed-off-by: Hollis Blanchard --- xen/arch/powerpc/Makefile | 2 +- xen/arch/powerpc/domain.c | 14 ++++++------ xen/arch/powerpc/htab.c | 8 +++---- xen/arch/powerpc/mm.c | 1 - xen/arch/powerpc/powerpc64/ppc970.c | 3 ++- xen/arch/powerpc/setup.c | 33 ++++++++++++++++++----------- xen/include/asm-powerpc/domain.h | 2 +- xen/include/asm-powerpc/htab.h | 3 ++- xen/include/asm-powerpc/mm.h | 2 +- 9 files changed, 38 insertions(+), 30 deletions(-) diff --git a/xen/arch/powerpc/Makefile b/xen/arch/powerpc/Makefile index 7a44f65c25..9b54aad3cc 100644 --- a/xen/arch/powerpc/Makefile +++ b/xen/arch/powerpc/Makefile @@ -49,7 +49,7 @@ obj-y += elf32.o PPC_C_WARNINGS += -Wundef -Wmissing-prototypes -Wmissing-declarations CFLAGS += $(PPC_C_WARNINGS) -LINK=0x3000000 +LINK=0x400000 boot32_link_base = $(LINK) xen_link_offset = 100 xen_link_base = $(patsubst %000,%$(xen_link_offset),$(LINK)) diff --git a/xen/arch/powerpc/domain.c b/xen/arch/powerpc/domain.c index 149736f40f..ab24303654 100644 --- a/xen/arch/powerpc/domain.c +++ b/xen/arch/powerpc/domain.c @@ -74,7 +74,7 @@ unsigned long hypercall_create_continuation(unsigned int op, int arch_domain_create(struct domain *d) { unsigned long rma_base; - unsigned long rma_size; + unsigned long rma_sz; uint htab_order; if (d->domain_id == IDLE_DOMAIN_ID) { @@ -85,19 +85,20 @@ int arch_domain_create(struct domain *d) } d->arch.rma_order = cpu_rma_order(); - rma_size = 1UL << d->arch.rma_order << PAGE_SHIFT; + rma_sz = rma_size(d->arch.rma_order); /* allocate the real mode area */ d->max_pages = 1UL << d->arch.rma_order; + d->tot_pages = 0; d->arch.rma_page = alloc_domheap_pages(d, d->arch.rma_order, 0); if (NULL == d->arch.rma_page) return 1; rma_base = page_to_maddr(d->arch.rma_page); - BUG_ON(rma_base & (rma_size-1)); /* check alignment */ + BUG_ON(rma_base & (rma_sz - 1)); /* check alignment */ - printk("clearing RMO: 0x%lx[0x%lx]\n", rma_base, rma_size); - memset((void *)rma_base, 0, rma_size); + printk("clearing RMO: 0x%lx[0x%lx]\n", rma_base, rma_sz); + memset((void *)rma_base, 0, rma_sz); d->shared_info = (shared_info_t *) (rma_addr(&d->arch, RMA_SHARED_INFO) + rma_base); @@ -120,7 +121,6 @@ int arch_domain_create(struct domain *d) void arch_domain_destroy(struct domain *d) { - free_domheap_pages(d->arch.rma_page, d->arch.rma_order); htab_free(d); } @@ -263,7 +263,7 @@ void sync_vcpu_execstate(struct vcpu *v) void domain_relinquish_resources(struct domain *d) { - /* nothing to do? */ + free_domheap_pages(d->arch.rma_page, d->arch.rma_order); } void arch_dump_domain_info(struct domain *d) diff --git a/xen/arch/powerpc/htab.c b/xen/arch/powerpc/htab.c index c80b4480b9..bdac165720 100644 --- a/xen/arch/powerpc/htab.c +++ b/xen/arch/powerpc/htab.c @@ -44,27 +44,25 @@ void htab_alloc(struct domain *d, uint order) htab_raddr = (ulong)alloc_xenheap_pages(order); ASSERT(htab_raddr != 0); /* XXX check alignment guarantees */ - ASSERT((htab_raddr & (htab_bytes-1)) == 0); + ASSERT((htab_raddr & (htab_bytes - 1)) == 0); /* XXX slow. move memset out to service partition? */ memset((void *)htab_raddr, 0, htab_bytes); + d->arch.htab.order = order; d->arch.htab.log_num_ptes = log_htab_bytes - LOG_PTE_SIZE; d->arch.htab.sdr1 = htab_calc_sdr1(htab_raddr, log_htab_bytes); d->arch.htab.map = (union pte *)htab_raddr; d->arch.htab.shadow = xmalloc_array(ulong, 1UL << d->arch.htab.log_num_ptes); ASSERT(d->arch.htab.shadow != NULL); - - printf("%s: dom%x sdr1: %lx\n", __func__, d->domain_id, d->arch.htab.sdr1); } void htab_free(struct domain *d) { ulong htab_raddr = GET_HTAB(d); - free_xenheap_pages((void *)htab_raddr, - (1UL << d->arch.htab.log_num_ptes) << LOG_PTE_SIZE); + free_xenheap_pages((void *)htab_raddr, d->arch.htab.order); xfree(d->arch.htab.shadow); } diff --git a/xen/arch/powerpc/mm.c b/xen/arch/powerpc/mm.c index b03f795cdc..e4d080a372 100644 --- a/xen/arch/powerpc/mm.c +++ b/xen/arch/powerpc/mm.c @@ -154,5 +154,4 @@ void guest_physmap_remove_page( void shadow_drop_references( struct domain *d, struct page_info *page) { - panic("%s\n", __func__); } diff --git a/xen/arch/powerpc/powerpc64/ppc970.c b/xen/arch/powerpc/powerpc64/ppc970.c index b82e30ce80..f5d15512b5 100644 --- a/xen/arch/powerpc/powerpc64/ppc970.c +++ b/xen/arch/powerpc/powerpc64/ppc970.c @@ -34,7 +34,8 @@ unsigned int cpu_rma_order(void) { /* XXX what about non-HV mode? */ - return 14; /* 1<<14<> 20, eomem >> 10); + /* top of memory */ max_page = PFN_DOWN(ALIGN_DOWN(eomem, PAGE_SIZE)); total_pages = max_page; - /* skip the exception handlers */ + /* Architecturally the first 4 pages are exception hendlers, we + * will also be copying down some code there */ heap_start = init_boot_allocator(4 << PAGE_SHIFT); + /* we give the first RMA to the hypervisor */ + xenheap_phys_end = rma_size(cpu_rma_order()); + + /* allow everything else to be allocated */ + init_boot_pages(xenheap_phys_end, eomem); + init_frametable(); + end_boot_allocator(); + + /* Add memory between the beginning of the heap and the beginning + * of out text */ + init_xenheap_pages(heap_start, (ulong)_start); + /* move the modules to just after _end */ if (modules_start) { printk("modules at: %016lx - %016lx\n", modules_start, @@ -293,27 +307,22 @@ static void __init __start_xen(multiboot_info_t *mbi) modules_start + modules_size); } + /* the rest of the xenheap, starting at the end of modules */ + init_xenheap_pages(freemem, xenheap_phys_end); + + #ifdef OF_DEBUG printk("ofdump:\n"); /* make sure the OF devtree is good */ ofd_walk((void *)oftree, OFD_ROOT, ofd_dump_props, OFD_DUMP_ALL); #endif - percpu_init_areas(); - - /* mark all memory from modules onward as unused */ - init_boot_pages(freemem, eomem); - - init_frametable(); - end_boot_allocator(); - - /* place the heap from after the allocator bitmap to _start */ - xenheap_phys_end = (ulong)_start; - init_xenheap_pages(heap_start, xenheap_phys_end); heap_size = xenheap_phys_end - heap_start; printk("Xen heap: %luMB (%lukB)\n", heap_size >> 20, heap_size >> 10); + percpu_init_areas(); + cpu_initialize(); #ifdef CONFIG_GDB diff --git a/xen/include/asm-powerpc/domain.h b/xen/include/asm-powerpc/domain.h index c5bab388dd..b7e0cef292 100644 --- a/xen/include/asm-powerpc/domain.h +++ b/xen/include/asm-powerpc/domain.h @@ -107,7 +107,7 @@ extern void load_float(struct vcpu *); #define RMA_CONSOLE 3 #define RMA_LAST_DOMU 3 -#define rma_size(rma_order) (1UL << (rma_order) << PAGE_SHIFT) +#define rma_size(rma_order) (1UL << ((rma_order) + PAGE_SHIFT)) static inline ulong rma_addr(struct arch_domain *ad, int type) { diff --git a/xen/include/asm-powerpc/htab.h b/xen/include/asm-powerpc/htab.h index 2a4ac26824..da1b58f9e5 100644 --- a/xen/include/asm-powerpc/htab.h +++ b/xen/include/asm-powerpc/htab.h @@ -128,7 +128,8 @@ union ptel { struct domain_htab { ulong sdr1; - ulong log_num_ptes; /* log number of PTEs in HTAB. */ + uint log_num_ptes; /* log number of PTEs in HTAB. */ + uint order; /* order for freeing. */ union pte *map; /* access the htab like an array */ ulong *shadow; /* idx -> logical translation array */ }; diff --git a/xen/include/asm-powerpc/mm.h b/xen/include/asm-powerpc/mm.h index 91e757912f..c57a999b92 100644 --- a/xen/include/asm-powerpc/mm.h +++ b/xen/include/asm-powerpc/mm.h @@ -33,7 +33,7 @@ #define memguard_unguard_range(_p,_l) ((void)0) extern unsigned long xenheap_phys_end; -#define IS_XEN_HEAP_FRAME(_pfn) (page_to_mfn(_pfn) < xenheap_phys_end) +#define IS_XEN_HEAP_FRAME(_pfn) (page_to_maddr(_pfn) < xenheap_phys_end) /* * Per-page-frame information. From 47bc089713c69ab5031193070640fdd8e46451b7 Mon Sep 17 00:00:00 2001 From: Hollis Blanchard Date: Mon, 14 Aug 2006 15:22:22 -0500 Subject: [PATCH 06/11] [POWERPC] Support console=comX option for Xen console. Let Xen/PPC support the console=comX option that Xen/x86 uses, so one need simply supply CMDLINE="console=com2" on the make invocation to get proper use of the physical serial port on a JS21. We do this by pruning all serial devices from the device tree, and then initializing both com1 and com2 (like arch/x86/setup.c does). Note that `setenv direct-serial? true; nvupdate' should in theory help with this, but it does not work at present, and will only be supported in some future version of SLOF. Regardless, it is useful to support the console=comX option, since there will always be environments where it is difficult to get access to the firmware console. Tested on JS20 and JS21 blades. Signed-off-by: Amos Waterland Signed-off-by: Hollis Blanchard --- xen/arch/powerpc/Makefile | 6 ++++-- xen/arch/powerpc/boot_of.c | 38 ++++++++++++++++++++++++-------------- xen/arch/powerpc/setup.c | 4 ++++ 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/xen/arch/powerpc/Makefile b/xen/arch/powerpc/Makefile index 9b54aad3cc..489b168632 100644 --- a/xen/arch/powerpc/Makefile +++ b/xen/arch/powerpc/Makefile @@ -83,8 +83,10 @@ physdev.o: ../x86/physdev.c HDRS += $(wildcard *.h) -CMDLINE = "xen" -boot_of.o: CFLAGS += -DCMDLINE="\"$(CMDLINE)\"" +# The first token in the arguments will be silently dropped. +IMAGENAME = xen +CMDLINE = "" +boot_of.o: CFLAGS += -DCMDLINE="\"$(IMAGENAME) $(CMDLINE)\"" start.o: boot/start.S $(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@ diff --git a/xen/arch/powerpc/boot_of.c b/xen/arch/powerpc/boot_of.c index 57465e7bc0..6e552702f6 100644 --- a/xen/arch/powerpc/boot_of.c +++ b/xen/arch/powerpc/boot_of.c @@ -13,7 +13,7 @@ * 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 + * Copyright (C) IBM Corp. 2005, 2006 * * Authors: Jimi Xenidis */ @@ -759,19 +759,30 @@ static int __init boot_of_serial(void *oftree) if (n == OF_FAILURE) { of_panic("instance-to-package of /chosen/stdout: failed\n"); } - - /* prune this from the oftree */ - rc = of_package_to_path(n, buf, sizeof(buf)); - if (rc == OF_FAILURE) { - of_panic("package-to-path of /chosen/stdout: failed\n"); - } - of_printf("Pruning from devtree: %s\n" - " since Xen will be using it for console\n", buf); - rc = ofd_prune_path(oftree, buf); - if (rc < 0) { - of_panic("prune path \"%s\" failed\n", buf); - } + /* Prune all serial devices from the device tree, including the + * one pointed to by /chosen/stdout, because a guest domain can + * initialize them and in so doing corrupt our console output. + */ + for (p = n; p > 0; p = of_getpeer(p)) { + char type[32]; + + rc = of_package_to_path(p, buf, sizeof(buf)); + if (rc == OF_FAILURE) + 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 (strcmp(type, "serial") != 0) + continue; + + of_printf("pruning `%s' from devtree\n", buf); + rc = ofd_prune_path(oftree, buf); + if (rc < 0) + of_panic("prune of `%s' failed\n", buf); + } p = of_getparent(n); if (p == OF_FAILURE) { @@ -798,7 +809,6 @@ static int __init boot_of_serial(void *oftree) if (rc == OF_FAILURE) { of_panic("%s: no location for serial port\n", __func__); } - ns16550.io_base = val[1]; ns16550.baud = BAUD_AUTO; ns16550.data_bits = 8; diff --git a/xen/arch/powerpc/setup.c b/xen/arch/powerpc/setup.c index 24e5f5b67e..2e4bbb5e68 100644 --- a/xen/arch/powerpc/setup.c +++ b/xen/arch/powerpc/setup.c @@ -214,7 +214,11 @@ static void __init __start_xen(multiboot_info_t *mbi) if ((mbi->flags & MBI_CMDLINE) && (mbi->cmdline != 0)) cmdline_parse(__va((ulong)mbi->cmdline)); + /* We initialise the serial devices very early so we can get debugging. */ + ns16550.io_base = 0x3f8; ns16550_init(0, &ns16550); + ns16550.io_base = 0x2f8; + ns16550_init(1, &ns16550); serial_init_preirq(); init_console(); From 6d5c761cecaf488992822408ee8515d73b8286ef Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 15 Aug 2006 10:38:59 +0100 Subject: [PATCH 07/11] [POWERPC] Update .hgignore Signed-off-by: Hollis Blanchard --- .hgignore | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.hgignore b/.hgignore index 1730d04bbe..354b6fa294 100644 --- a/.hgignore +++ b/.hgignore @@ -199,5 +199,6 @@ ^xen/xen\..*$ ^xen/arch/powerpc/dom0\.bin$ ^xen/arch/powerpc/asm-offsets\.s$ -^xen/arch/powerpc/firmware -^xen/arch/powerpc/firmware_image +^xen/arch/powerpc/firmware$ +^xen/arch/powerpc/firmware_image$ +^xen/arch/powerpc/xen\.lds$ From 386f9501d539410da1fee424568325060ecf0747 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 15 Aug 2006 10:43:43 +0100 Subject: [PATCH 08/11] [VMX] Fix VMX ap boot. Signed-off-by: Xin Li --- tools/firmware/vmxassist/head.S | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/firmware/vmxassist/head.S b/tools/firmware/vmxassist/head.S index 129f69274f..b183fac54e 100644 --- a/tools/firmware/vmxassist/head.S +++ b/tools/firmware/vmxassist/head.S @@ -114,8 +114,6 @@ _start: #ifdef TEST xorl %edx, %edx #endif - movl %edx, booting_cpu - movl %ebx, booting_vector /* clear bss */ cld @@ -125,6 +123,9 @@ _start: subl %edi, %ecx rep stosb + movl %edx, booting_cpu + movl %ebx, booting_vector + /* make sure we are in a sane world */ clts From 01c74dcb721aa3012ae81538409c6cafb02b5232 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 15 Aug 2006 10:45:05 +0100 Subject: [PATCH 09/11] [VMX] Fix vmxassist for booting Vista. This patch fixes 2 vmxassist bugs to boot Vista: 1) When switching from VM86_REAL_TO_PROTECTED to VM86_PROTECTED, protected_mode() sets return eip to switch_to_protected_mode and segments to vmxassist's. But in later set_mode(), it still consides these segments are guest's (Bios at this time) and use its gdt table to calculate address(), which results in segment limitation fault. 2) In current vmxassist, when entering VM86_PROTECTED_TO_REAL, we need to decode every instruction manually until we catch instructions like jmpl to reset cs to really return to real mode. Vista boot manager uses more instructions. Signed-off-by: Xiaowei Yang --- tools/firmware/vmxassist/vm86.c | 103 ++++++++++++++++++++++++++++---- 1 file changed, 92 insertions(+), 11 deletions(-) diff --git a/tools/firmware/vmxassist/vm86.c b/tools/firmware/vmxassist/vm86.c index 67bd2d0f7b..52a8ae236d 100644 --- a/tools/firmware/vmxassist/vm86.c +++ b/tools/firmware/vmxassist/vm86.c @@ -983,7 +983,9 @@ set_mode(struct regs *regs, enum vm86_mode newmode) case VM86_PROTECTED: if (mode == VM86_REAL_TO_PROTECTED) { protected_mode(regs); - break; +// printf("\n"); + mode = newmode; + return; } else panic("unexpected protected mode transition"); break; @@ -1170,6 +1172,26 @@ inbyte(struct regs *regs, unsigned prefix, unsigned opc) return 1; } +static void +pushrm(struct regs *regs, int prefix, unsigned modrm) +{ + unsigned n = regs->eip; + unsigned addr; + unsigned data; + + addr = operand(prefix, regs, modrm); + + if (prefix & DATA32) { + data = read32(addr); + push32(regs, data); + } else { + data = read16(addr); + push16(regs, data); + } + + TRACE((regs, (regs->eip - n) + 1, "push *0x%x", addr)); +} + enum { OPC_INVALID, OPC_EMULATED }; /* @@ -1186,6 +1208,14 @@ opcode(struct regs *regs) for (;;) { switch ((opc = fetch8(regs))) { + case 0x07: + if (prefix & DATA32) + regs->ves = pop32(regs); + else + regs->ves = pop16(regs); + TRACE((regs, regs->eip - eip, "pop %%es")); + return OPC_EMULATED; + case 0x0F: /* two byte opcode */ if (mode == VM86_PROTECTED) goto invalid; @@ -1288,6 +1318,22 @@ opcode(struct regs *regs) return OPC_EMULATED; case 0x89: /* addr32 mov r16, r/m16 */ + if (mode == VM86_PROTECTED_TO_REAL) { + unsigned modrm = fetch8(regs); + unsigned addr = operand(prefix, regs, modrm); + unsigned val, r = (modrm >> 3) & 7; + + if (prefix & DATA32) { + val = getreg16(regs, r); + write32(addr, val); + } else { + val = getreg32(regs, r); + write16(addr, MASK16(val)); + } + TRACE((regs, regs->eip - eip, + "mov %%%s, *0x%x", rnames[r], addr)); + return OPC_EMULATED; + } case 0x8B: /* addr32 mov r/m16, r16 */ if (mode != VM86_REAL && mode != VM86_REAL_TO_PROTECTED) goto invalid; @@ -1326,6 +1372,37 @@ opcode(struct regs *regs) regs->eflags |= EFLAGS_VM; return OPC_EMULATED; + case 0xA1: /* mov ax, r/m16 */ + { + int addr, data; + int seg = segment(prefix, regs, regs->vds); + if (prefix & DATA32) { + addr = address(regs, seg, fetch32(regs)); + data = read32(addr); + setreg32(regs, 0, data); + } else { + addr = address(regs, seg, fetch16(regs)); + data = read16(addr); + setreg16(regs, 0, data); + } + TRACE((regs, regs->eip - eip, "mov *0x%x, %%ax", addr)); + } + return OPC_EMULATED; + + case 0xBB: /* mov bx, imm16 */ + { + int data; + if (prefix & DATA32) { + data = fetch32(regs); + setreg32(regs, 3, data); + } else { + data = fetch16(regs); + setreg16(regs, 3, data); + } + TRACE((regs, regs->eip - eip, "mov $0x%x, %%bx", data)); + } + return OPC_EMULATED; + case 0xC6: /* addr32 movb $imm, r/m8 */ if ((prefix & ADDR32) == 0) goto invalid; @@ -1380,21 +1457,25 @@ opcode(struct regs *regs) goto invalid; case 0xFF: /* jmpl (indirect) */ - if ((mode == VM86_REAL_TO_PROTECTED) || - (mode == VM86_PROTECTED_TO_REAL)) { - unsigned modrm = fetch8(regs); - + { + unsigned modrm = fetch8(regs); switch((modrm >> 3) & 7) { - case 5: - jmpl_indirect(regs, prefix, modrm); - return OPC_INVALID; + case 5: /* jmpl (indirect) */ + if ((mode == VM86_REAL_TO_PROTECTED) || + (mode == VM86_PROTECTED_TO_REAL)) { + jmpl_indirect(regs, prefix, modrm); + return OPC_INVALID; + } + goto invalid; + + case 6: /* push r/m16 */ + pushrm(regs, prefix, modrm); + return OPC_EMULATED; default: - break; + goto invalid; } - } - goto invalid; case 0xEB: /* short jump */ if ((mode == VM86_REAL_TO_PROTECTED) || From 46655653d33b6a1d5bcb0a882e5903b30091d5e6 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 15 Aug 2006 10:47:26 +0100 Subject: [PATCH 10/11] Remove another external-to-libxc user of xc_dom0_op(). Signed-off-by: John Levon --- tools/xenmon/xenbaked.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/tools/xenmon/xenbaked.c b/tools/xenmon/xenbaked.c index fc0eb727e0..5908a6c1c9 100644 --- a/tools/xenmon/xenbaked.c +++ b/tools/xenmon/xenbaked.c @@ -444,14 +444,11 @@ struct t_rec **init_rec_ptrs(struct t_buf **meta, unsigned int num) */ unsigned int get_num_cpus(void) { - dom0_op_t op; + xc_physinfo_t physinfo; int xc_handle = xc_interface_open(); int ret; - op.cmd = DOM0_PHYSINFO; - op.interface_version = DOM0_INTERFACE_VERSION; - - ret = xc_dom0_op(xc_handle, &op); + ret = xc_physinfo(xc_handle, &physinfo); if ( ret != 0 ) { @@ -460,12 +457,12 @@ unsigned int get_num_cpus(void) } xc_interface_close(xc_handle); - opts.cpu_freq = (double)op.u.physinfo.cpu_khz/1000.0; + opts.cpu_freq = (double)physinfo.cpu_khz/1000.0; - return (op.u.physinfo.threads_per_core * - op.u.physinfo.cores_per_socket * - op.u.physinfo.sockets_per_node * - op.u.physinfo.nr_nodes); + return (physinfo.threads_per_core * + physinfo.cores_per_socket * + physinfo.sockets_per_node * + physinfo.nr_nodes); } From 13451be1da714dc48351e091b02a984a25170eeb Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 15 Aug 2006 10:56:59 +0100 Subject: [PATCH 11/11] [XEND] Apply the domain cpumask fully to every vcpu in the domain. Apply the domain cpumask to each vcpu rather than mapping vcpus to cpus in the list. This is more inline with the comments for the cpus parameter and also allows the credit scheduler to balance vcpus within the domain cpumask. Signed-off-by: Ryan Harper --- tools/python/xen/xend/XendDomainInfo.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 35a014900d..daedcff625 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -1272,12 +1272,9 @@ class XendDomainInfo: # repin domain vcpus if a restricted cpus list is provided # this is done prior to memory allocation to aide in memory # distribution for NUMA systems. - cpus = self.info['cpus'] - if cpus is not None and len(cpus) > 0: + if self.info['cpus'] is not None and len(self.info['cpus']) > 0: for v in range(0, self.info['max_vcpu_id']+1): - # pincpu takes a list of ints - cpu = [ int( cpus[v % len(cpus)] ) ] - xc.vcpu_setaffinity(self.domid, v, cpu) + xc.vcpu_setaffinity(self.domid, v, self.info['cpus']) # set domain maxmem in KiB xc.domain_setmaxmem(self.domid, self.info['maxmem'] * 1024)