[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [HVM] Move shadow initialisation into domain-creation hypercall.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Node ID cf3d69ba5633284234f428b26e4465b593b70244 # Parent 96f51a000ed024728ea5653f9f0f0550affc3f8b [HVM] Move shadow initialisation into domain-creation hypercall. Allocate HVM guest memory in the libxc builder function rather than in xend. Clean up fall out from these changes. Todo: Fix ia64. Move PV builder to same model (it should allocate the memory rather than xend doing so -- then it can avoid using xc_get_pfn_list()). Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- tools/ioemu/vl.c | 9 +- tools/libxc/xc_hvm_build.c | 121 +++++--------------------------- tools/python/xen/xend/XendDomainInfo.py | 8 +- tools/python/xen/xend/image.py | 14 --- xen/arch/x86/domain.c | 36 +++++---- xen/arch/x86/domctl.c | 47 ++---------- xen/arch/x86/mm/shadow/common.c | 4 - xen/include/asm-x86/shadow.h | 3 8 files changed, 71 insertions(+), 171 deletions(-) diff -r 96f51a000ed0 -r cf3d69ba5633 tools/ioemu/vl.c --- a/tools/ioemu/vl.c Wed Nov 01 18:32:45 2006 +0000 +++ b/tools/ioemu/vl.c Wed Nov 01 18:37:23 2006 +0000 @@ -6420,14 +6420,13 @@ int main(int argc, char **argv) } #if defined(__i386__) || defined(__x86_64__) - if (xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages) { + for ( i = 0; i < tmp_nr_pages; i++) + page_array[i] = i; + if (xc_domain_translate_gpfn_list(xc_handle, domid, tmp_nr_pages, + page_array, page_array)) { fprintf(logfile, "xc_get_pfn_list returned error %d\n", errno); exit(-1); } - - if (ram_size > HVM_BELOW_4G_RAM_END) - for (i = 0; i < nr_pages - (HVM_BELOW_4G_RAM_END >> PAGE_SHIFT); i++) - page_array[tmp_nr_pages - 1 - i] = page_array[nr_pages - 1 - i]; phys_ram_base = xc_map_foreign_batch(xc_handle, domid, PROT_READ|PROT_WRITE, page_array, diff -r 96f51a000ed0 -r cf3d69ba5633 tools/libxc/xc_hvm_build.c --- a/tools/libxc/xc_hvm_build.c Wed Nov 01 18:32:45 2006 +0000 +++ b/tools/libxc/xc_hvm_build.c Wed Nov 01 18:37:23 2006 +0000 @@ -196,7 +196,6 @@ static int setup_guest(int xc_handle, static int setup_guest(int xc_handle, uint32_t dom, int memsize, char *image, unsigned long image_size, - unsigned long nr_pages, vcpu_guest_context_t *ctxt, unsigned long shared_info_frame, unsigned int vcpus, @@ -207,18 +206,13 @@ static int setup_guest(int xc_handle, unsigned long *store_mfn) { xen_pfn_t *page_array = NULL; - unsigned long count, i; - unsigned long long ptr; - xc_mmu_t *mmu = NULL; - + unsigned long i, nr_pages = (unsigned long)memsize << (20 - PAGE_SHIFT); + unsigned long shared_page_nr; shared_info_t *shared_info; void *e820_page; - struct domain_setup_info dsi; uint64_t v_end; - unsigned long shared_page_nr; - memset(&dsi, 0, sizeof(struct domain_setup_info)); if ( (parseelfimage(image, image_size, &dsi)) != 0 ) @@ -230,7 +224,6 @@ static int setup_guest(int xc_handle, goto error_out; } - /* memsize is in megabytes */ v_end = (unsigned long long)memsize << 20; IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n" @@ -255,52 +248,26 @@ static int setup_guest(int xc_handle, goto error_out; } - if ( xc_get_pfn_list(xc_handle, dom, page_array, nr_pages) != nr_pages ) - { - PERROR("Could not get the page frame list.\n"); - goto error_out; - } - - /* HVM domains must be put into shadow mode at the start of day. */ - /* XXX *After* xc_get_pfn_list()!! */ - if ( xc_shadow_control(xc_handle, dom, XEN_DOMCTL_SHADOW_OP_ENABLE, - NULL, 0, NULL, - XEN_DOMCTL_SHADOW_ENABLE_REFCOUNT | - XEN_DOMCTL_SHADOW_ENABLE_TRANSLATE | - XEN_DOMCTL_SHADOW_ENABLE_EXTERNAL, - NULL) ) - { - PERROR("Could not enable shadow paging for domain.\n"); - goto error_out; - } + for ( i = 0; i < nr_pages; i++ ) + page_array[i] = i; + for ( i = HVM_BELOW_4G_RAM_END >> PAGE_SHIFT; i < nr_pages; i++ ) + page_array[i] += HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT; + + if ( xc_domain_memory_populate_physmap(xc_handle, dom, nr_pages, + 0, 0, page_array) ) + { + PERROR("Could not allocate memory for HVM guest.\n"); + goto error_out; + } + + if ( xc_domain_translate_gpfn_list(xc_handle, dom, nr_pages, + page_array, page_array) ) + { + PERROR("Could not translate addresses of HVM guest.\n"); + goto error_out; + } loadelfimage(image, xc_handle, dom, page_array, &dsi); - - if ( (mmu = xc_init_mmu_updates(xc_handle, dom)) == NULL ) - goto error_out; - - /* Write the machine->phys table entries. */ - for ( count = 0; count < nr_pages; count++ ) - { - unsigned long gpfn_count_skip; - - ptr = (unsigned long long)page_array[count] << PAGE_SHIFT; - - gpfn_count_skip = 0; - - /* - * physical address space from HVM_BELOW_4G_RAM_END to 4G is reserved - * for PCI devices MMIO. So if HVM has more than HVM_BELOW_4G_RAM_END - * RAM, memory beyond HVM_BELOW_4G_RAM_END will go to 4G above. - */ - if ( count >= (HVM_BELOW_4G_RAM_END >> PAGE_SHIFT) ) - gpfn_count_skip = HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT; - - if ( xc_add_mmu_update(xc_handle, mmu, - ptr | MMU_MACHPHYS_UPDATE, - count + gpfn_count_skip) ) - goto error_out; - } if ( set_hvm_info(xc_handle, dom, page_array, vcpus, acpi) ) { @@ -352,22 +319,13 @@ static int setup_guest(int xc_handle, if ( xc_clear_domain_page(xc_handle, dom, *store_mfn) ) goto error_out; - /* Send the page update requests down to the hypervisor. */ - if ( xc_finish_mmu_updates(xc_handle, mmu) ) - goto error_out; - - free(mmu); free(page_array); - /* - * Initial register values: - */ ctxt->user_regs.eip = dsi.v_kernentry; return 0; error_out: - free(mmu); free(page_array); return -1; } @@ -387,31 +345,10 @@ static int xc_hvm_build_internal(int xc_ struct xen_domctl launch_domctl, domctl; int rc, i; vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt; - unsigned long nr_pages; - xen_capabilities_info_t xen_caps; if ( (image == NULL) || (image_size == 0) ) { ERROR("Image required"); - goto error_out; - } - - if ( (rc = xc_version(xc_handle, XENVER_capabilities, &xen_caps)) != 0 ) - { - PERROR("Failed to get xen version info"); - goto error_out; - } - - if ( !strstr(xen_caps, "hvm") ) - { - PERROR("CPU doesn't support HVM extensions or " - "the extensions are not enabled"); - goto error_out; - } - - if ( (nr_pages = xc_get_tot_pages(xc_handle, domid)) < 0 ) - { - PERROR("Could not find total pages for domain"); goto error_out; } @@ -430,24 +367,10 @@ static int xc_hvm_build_internal(int xc_ goto error_out; } -#if 0 - /* HVM domains must be put into shadow mode at the start of day */ - if ( xc_shadow_control(xc_handle, domid, XEN_DOMCTL_SHADOW_OP_ENABLE, - NULL, 0, NULL, - XEN_DOMCTL_SHADOW_ENABLE_REFCOUNT | - XEN_DOMCTL_SHADOW_ENABLE_TRANSLATE | - XEN_DOMCTL_SHADOW_ENABLE_EXTERNAL, - NULL) ) - { - PERROR("Could not enable shadow paging for domain.\n"); - goto error_out; - } -#endif - memset(ctxt, 0, sizeof(*ctxt)); - ctxt->flags = VGCF_HVM_GUEST; - if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages, + + if ( setup_guest(xc_handle, domid, memsize, image, image_size, ctxt, domctl.u.getdomaininfo.shared_info_frame, vcpus, pae, acpi, apic, store_evtchn, store_mfn) < 0) { diff -r 96f51a000ed0 -r cf3d69ba5633 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Wed Nov 01 18:32:45 2006 +0000 +++ b/tools/python/xen/xend/XendDomainInfo.py Wed Nov 01 18:37:23 2006 +0000 @@ -1295,9 +1295,11 @@ class XendDomainInfo: shadow_cur = xc.shadow_mem_control(self.domid, shadow / 1024) self.info['shadow_memory'] = shadow_cur - # initial memory reservation - xc.domain_memory_increase_reservation(self.domid, reservation, 0, - 0) + # Initial memory reservation + if not (self._infoIsSet('image') and + sxp.name(self.info['image']) == "hvm"): + xc.domain_memory_increase_reservation( + self.domid, reservation, 0, 0) self._createChannels() diff -r 96f51a000ed0 -r cf3d69ba5633 tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py Wed Nov 01 18:32:45 2006 +0000 +++ b/tools/python/xen/xend/image.py Wed Nov 01 18:37:23 2006 +0000 @@ -478,22 +478,12 @@ class X86_HVM_ImageHandler(HVMImageHandl def getRequiredAvailableMemory(self, mem_kb): # Add 8 MiB overhead for QEMU's video RAM. - return self.getRequiredInitialReservation(mem_kb) + 8192 + return mem_kb + 8192 def getRequiredInitialReservation(self, mem_kb): - page_kb = 4 - # This was derived emperically: - # 2.4 MB overhead per 1024 MB RAM - # + 4 to avoid low-memory condition - extra_mb = (2.4/1024) * (mem_kb/1024.0) + 4; - extra_pages = int( math.ceil( extra_mb*1024 / page_kb )) - return mem_kb + extra_pages * page_kb + return mem_kb def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb): - # The given value is the configured value -- we need to include the - # overhead due to getRequiredInitialReservation. - maxmem_kb = self.getRequiredInitialReservation(maxmem_kb) - # 256 pages (1MB) per vcpu, # plus 1 page per MiB of RAM for the P2M map, # plus 1 page per MiB of RAM to shadow the resident processes. diff -r 96f51a000ed0 -r cf3d69ba5633 xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Wed Nov 01 18:32:45 2006 +0000 +++ b/xen/arch/x86/domain.c Wed Nov 01 18:37:23 2006 +0000 @@ -155,19 +155,12 @@ int arch_domain_create(struct domain *d) { l1_pgentry_t gdt_l1e; int vcpuid, pdpt_order; - int i; - - if ( is_hvm_domain(d) && !hvm_enabled ) - { - gdprintk(XENLOG_WARNING, "Attempt to create a HVM guest " - "on a non-VT/AMDV platform.\n"); - return -EINVAL; - } + int i, rc = -ENOMEM; pdpt_order = get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t)); d->arch.mm_perdomain_pt = alloc_xenheap_pages(pdpt_order); if ( d->arch.mm_perdomain_pt == NULL ) - goto fail_nomem; + goto fail; memset(d->arch.mm_perdomain_pt, 0, PAGE_SIZE << pdpt_order); /* @@ -192,7 +185,7 @@ int arch_domain_create(struct domain *d) d->arch.mm_perdomain_l3 = alloc_xenheap_page(); if ( (d->arch.mm_perdomain_l2 == NULL) || (d->arch.mm_perdomain_l3 == NULL) ) - goto fail_nomem; + goto fail; memset(d->arch.mm_perdomain_l2, 0, PAGE_SIZE); for ( i = 0; i < (1 << pdpt_order); i++ ) @@ -219,26 +212,41 @@ int arch_domain_create(struct domain *d) d->arch.ioport_caps = rangeset_new(d, "I/O Ports", RANGESETF_prettyprint_hex); if ( d->arch.ioport_caps == NULL ) - goto fail_nomem; + goto fail; if ( (d->shared_info = alloc_xenheap_page()) == NULL ) - goto fail_nomem; + goto fail; memset(d->shared_info, 0, PAGE_SIZE); share_xen_page_with_guest( virt_to_page(d->shared_info), d, XENSHARE_writable); } + if ( is_hvm_domain(d) ) + { + if ( !hvm_enabled ) + { + gdprintk(XENLOG_WARNING, "Attempt to create a HVM guest " + "on a non-VT/AMDV platform.\n"); + rc = -EINVAL; + goto fail; + } + + rc = shadow_enable(d, SHM2_refcounts|SHM2_translate|SHM2_external); + if ( rc != 0 ) + goto fail; + } + return 0; - fail_nomem: + fail: free_xenheap_page(d->shared_info); #ifdef __x86_64__ free_xenheap_page(d->arch.mm_perdomain_l2); free_xenheap_page(d->arch.mm_perdomain_l3); #endif free_xenheap_pages(d->arch.mm_perdomain_pt, pdpt_order); - return -ENOMEM; + return rc; } void arch_domain_destroy(struct domain *d) diff -r 96f51a000ed0 -r cf3d69ba5633 xen/arch/x86/domctl.c --- a/xen/arch/x86/domctl.c Wed Nov 01 18:32:45 2006 +0000 +++ b/xen/arch/x86/domctl.c Wed Nov 01 18:37:23 2006 +0000 @@ -224,45 +224,18 @@ long arch_do_domctl( spin_lock(&d->page_alloc_lock); - if ( is_hvm_domain(d) && shadow_mode_translate(d) ) - { - /* HVM domain: scan P2M to get guaranteed physmap order. */ - for ( i = 0, gmfn = 0; - (i < max_pfns) && (i < d->tot_pages); - i++, gmfn++ ) + list_ent = d->page_list.next; + for ( i = 0; (i < max_pfns) && (list_ent != &d->page_list); i++ ) + { + mfn = page_to_mfn(list_entry( + list_ent, struct page_info, list)); + if ( copy_to_guest_offset(domctl->u.getmemlist.buffer, + i, &mfn, 1) ) { - if ( unlikely(i == (HVM_BELOW_4G_MMIO_START>>PAGE_SHIFT)) ) - { - /* skip MMIO range */ - gmfn += HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT; - } - mfn = gmfn_to_mfn(d, gmfn); - if ( copy_to_guest_offset(domctl->u.getmemlist.buffer, - i, &mfn, 1) ) - { - ret = -EFAULT; - break; - } + ret = -EFAULT; + break; } - } - else - { - /* Other guests: return in order of ownership list. */ - list_ent = d->page_list.next; - for ( i = 0; - (i < max_pfns) && (list_ent != &d->page_list); - i++ ) - { - mfn = page_to_mfn(list_entry( - list_ent, struct page_info, list)); - if ( copy_to_guest_offset(domctl->u.getmemlist.buffer, - i, &mfn, 1) ) - { - ret = -EFAULT; - break; - } - list_ent = mfn_to_page(mfn)->list.next; - } + list_ent = mfn_to_page(mfn)->list.next; } spin_unlock(&d->page_alloc_lock); diff -r 96f51a000ed0 -r cf3d69ba5633 xen/arch/x86/mm/shadow/common.c --- a/xen/arch/x86/mm/shadow/common.c Wed Nov 01 18:32:45 2006 +0000 +++ b/xen/arch/x86/mm/shadow/common.c Wed Nov 01 18:37:23 2006 +0000 @@ -2461,7 +2461,7 @@ static void sh_new_mode(struct domain *d sh_update_paging_modes(v); } -static int shadow_enable(struct domain *d, u32 mode) +int shadow_enable(struct domain *d, u32 mode) /* Turn on "permanent" shadow features: external, translate, refcount. * Can only be called once on a domain, and these features cannot be * disabled. @@ -3092,6 +3092,8 @@ int shadow_domctl(struct domain *d, if ( shadow_mode_log_dirty(d) ) if ( (rc = shadow_log_dirty_disable(d)) != 0 ) return rc; + if ( is_hvm_domain(d) ) + return -EINVAL; if ( d->arch.shadow.mode & SHM2_enable ) if ( (rc = shadow_test_disable(d)) != 0 ) return rc; diff -r 96f51a000ed0 -r cf3d69ba5633 xen/include/asm-x86/shadow.h --- a/xen/include/asm-x86/shadow.h Wed Nov 01 18:32:45 2006 +0000 +++ b/xen/include/asm-x86/shadow.h Wed Nov 01 18:37:23 2006 +0000 @@ -313,6 +313,9 @@ static inline int shadow_guest_paging_le /**************************************************************************/ /* Entry points into the shadow code */ +/* Enable arbitrary shadow mode. */ +int shadow_enable(struct domain *d, u32 mode); + /* Turning on shadow test mode */ int shadow_test_enable(struct domain *d); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |