[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 2/3] x86_64: don't allocate L1 per-domain page table pages in a single chunk
Instead, allocate them on demand, and adjust the consumer to no longer assume the allocated space is contiguous. This another prerequisite to extend to number of vCPU-s the hypervisor can support per guest. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx> --- 2009-06-10.orig/xen/arch/x86/domain.c 2009-05-27 13:54:05.000000000 +0200 +++ 2009-06-10/xen/arch/x86/domain.c 2009-06-10 10:48:19.000000000 +0200 @@ -322,6 +322,22 @@ int vcpu_initialise(struct vcpu *v) #if defined(__i386__) mapcache_vcpu_init(v); +#else + { + unsigned int idx = perdomain_pt_pgidx(v); + struct page_info *pg; + + if ( !perdomain_pt_page(d, idx) ) + { + pg = alloc_domheap_page(NULL, MEMF_node(vcpu_to_node(v))); + if ( !pg ) + return -ENOMEM; + clear_page(page_to_virt(pg)); + perdomain_pt_page(d, idx) = pg; + d->arch.mm_perdomain_l2[l2_table_offset(PERDOMAIN_VIRT_START)+idx] + = l2e_from_page(pg, __PAGE_HYPERVISOR); + } + } #endif pae_l3_cache_init(&v->arch.pae_l3_cache); @@ -357,8 +373,7 @@ int vcpu_initialise(struct vcpu *v) real_cr4_to_pv_guest_cr4(mmu_cr4_features); } - v->arch.perdomain_ptes = - d->arch.mm_perdomain_pt + (v->vcpu_id << GDT_LDT_VCPU_SHIFT); + v->arch.perdomain_ptes = perdomain_ptes(d, v); spin_lock_init(&v->arch.shadow_ldt_lock); @@ -378,8 +393,10 @@ int arch_domain_create(struct domain *d, { #ifdef __x86_64__ struct page_info *pg; +#else + int pdpt_order; #endif - int i, pdpt_order, paging_initialised = 0; + int i, paging_initialised = 0; int rc = -ENOMEM; d->arch.hvm_domain.hap_enabled = @@ -394,27 +411,30 @@ int arch_domain_create(struct domain *d, d->arch.relmem = RELMEM_not_started; INIT_PAGE_LIST_HEAD(&d->arch.relmem_list); +#if defined(__i386__) + pdpt_order = get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t)); d->arch.mm_perdomain_pt = alloc_xenheap_pages(pdpt_order, 0); if ( d->arch.mm_perdomain_pt == NULL ) goto fail; memset(d->arch.mm_perdomain_pt, 0, PAGE_SIZE << pdpt_order); -#if defined(__i386__) - mapcache_domain_init(d); #else /* __x86_64__ */ + d->arch.mm_perdomain_pt_pages = xmalloc_array(struct page_info *, + PDPT_L2_ENTRIES); + if ( !d->arch.mm_perdomain_pt_pages ) + goto fail; + memset(d->arch.mm_perdomain_pt_pages, 0, + PDPT_L2_ENTRIES * sizeof(*d->arch.mm_perdomain_pt_pages)); + pg = alloc_domheap_page(NULL, MEMF_node(domain_to_node(d))); if ( pg == NULL ) goto fail; d->arch.mm_perdomain_l2 = page_to_virt(pg); clear_page(d->arch.mm_perdomain_l2); - for ( i = 0; i < (1 << pdpt_order); i++ ) - d->arch.mm_perdomain_l2[l2_table_offset(PERDOMAIN_VIRT_START)+i] = - l2e_from_page(virt_to_page(d->arch.mm_perdomain_pt)+i, - __PAGE_HYPERVISOR); pg = alloc_domheap_page(NULL, MEMF_node(domain_to_node(d))); if ( pg == NULL ) @@ -503,13 +523,19 @@ int arch_domain_create(struct domain *d, free_domheap_page(virt_to_page(d->arch.mm_perdomain_l2)); if ( d->arch.mm_perdomain_l3 ) free_domheap_page(virt_to_page(d->arch.mm_perdomain_l3)); -#endif + xfree(d->arch.mm_perdomain_pt_pages); +#else free_xenheap_pages(d->arch.mm_perdomain_pt, pdpt_order); +#endif return rc; } void arch_domain_destroy(struct domain *d) { +#ifdef __x86_64__ + unsigned int i; +#endif + if ( is_hvm_domain(d) ) hvm_domain_destroy(d); @@ -520,11 +546,17 @@ void arch_domain_destroy(struct domain * paging_final_teardown(d); +#ifdef __i386__ free_xenheap_pages( d->arch.mm_perdomain_pt, get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t))); - -#ifdef __x86_64__ +#else + for ( i = 0; i < PDPT_L2_ENTRIES; ++i ) + { + if ( perdomain_pt_page(d, i) ) + free_domheap_page(perdomain_pt_page(d, i)); + } + xfree(d->arch.mm_perdomain_pt_pages); free_domheap_page(virt_to_page(d->arch.mm_perdomain_l2)); free_domheap_page(virt_to_page(d->arch.mm_perdomain_l3)); #endif @@ -1272,8 +1304,7 @@ static void __context_switch(void) struct page_info *page = virt_to_page(gdt); unsigned int i; for ( i = 0; i < NR_RESERVED_GDT_PAGES; i++ ) - l1e_write(n->domain->arch.mm_perdomain_pt + - (n->vcpu_id << GDT_LDT_VCPU_SHIFT) + + l1e_write(n->arch.perdomain_ptes + FIRST_RESERVED_GDT_PAGE + i, l1e_from_page(page + i, __PAGE_HYPERVISOR)); } --- 2009-06-10.orig/xen/arch/x86/domain_build.c 2009-05-27 13:54:05.000000000 +0200 +++ 2009-06-10/xen/arch/x86/domain_build.c 2009-06-10 10:46:31.000000000 +0200 @@ -480,8 +480,7 @@ int __init construct_dom0( for ( i = 0; i < PDPT_L2_ENTRIES; i++ ) l2tab[l2_linear_offset(PERDOMAIN_VIRT_START) + i] = - l2e_from_page(virt_to_page(d->arch.mm_perdomain_pt) + i, - __PAGE_HYPERVISOR); + l2e_from_page(perdomain_pt_page(d, i), __PAGE_HYPERVISOR); l2tab += l2_linear_offset(v_start); mfn = alloc_spfn; --- 2009-06-10.orig/xen/arch/x86/mm.c 2009-06-10 10:46:17.000000000 +0200 +++ 2009-06-10/xen/arch/x86/mm.c 2009-06-10 10:46:31.000000000 +0200 @@ -1207,9 +1207,7 @@ static int create_pae_xen_mappings(struc L2_PAGETABLE_XEN_SLOTS * sizeof(l2_pgentry_t)); for ( i = 0; i < PDPT_L2_ENTRIES; i++ ) { - l2e = l2e_from_page( - virt_to_page(d->arch.mm_perdomain_pt) + i, - __PAGE_HYPERVISOR); + l2e = l2e_from_page(perdomain_pt_page(d, i), __PAGE_HYPERVISOR); l2e_write(&pl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i], l2e); } for ( i = 0; i < (LINEARPT_MBYTES >> (L2_PAGETABLE_SHIFT - 20)); i++ ) --- 2009-06-10.orig/xen/arch/x86/mm/hap/hap.c 2009-06-08 08:44:53.000000000 +0200 +++ 2009-06-10/xen/arch/x86/mm/hap/hap.c 2009-06-10 10:46:31.000000000 +0200 @@ -437,7 +437,7 @@ static void hap_install_xen_entries_in_l for ( i = 0; i < PDPT_L2_ENTRIES; i++ ) l2e[l2_table_offset(PERDOMAIN_VIRT_START) + i] = l2e_from_pfn( - mfn_x(page_to_mfn(virt_to_page(d->arch.mm_perdomain_pt) + i)), + mfn_x(page_to_mfn(perdomain_pt_page(d, i))), __PAGE_HYPERVISOR); /* No linear mapping; will be set up by monitor-table contructor. */ --- 2009-06-10.orig/xen/arch/x86/mm/shadow/multi.c 2009-06-08 08:44:53.000000000 +0200 +++ 2009-06-10/xen/arch/x86/mm/shadow/multi.c 2009-06-10 10:46:31.000000000 +0200 @@ -1470,7 +1470,7 @@ static void sh_install_xen_entries_in_l2 for ( i = 0; i < PDPT_L2_ENTRIES; i++ ) sl2e[shadow_l2_table_offset(PERDOMAIN_VIRT_START) + i] = shadow_l2e_from_mfn( - page_to_mfn(virt_to_page(d->arch.mm_perdomain_pt) + i), + page_to_mfn(perdomain_pt_page(d, i)), __PAGE_HYPERVISOR); /* We don't set up a linear mapping here because we can't until this --- 2009-06-10.orig/xen/include/asm-x86/domain.h 2009-05-27 13:54:07.000000000 +0200 +++ 2009-06-10/xen/include/asm-x86/domain.h 2009-06-10 10:46:31.000000000 +0200 @@ -231,10 +231,12 @@ struct domain_mca_msrs struct arch_domain { - l1_pgentry_t *mm_perdomain_pt; #ifdef CONFIG_X86_64 + struct page_info **mm_perdomain_pt_pages; l2_pgentry_t *mm_perdomain_l2; l3_pgentry_t *mm_perdomain_l3; +#else + l1_pgentry_t *mm_perdomain_pt; #endif #ifdef CONFIG_X86_32 @@ -302,6 +304,21 @@ struct arch_domain #define has_arch_pdevs(d) (!list_empty(&(d)->arch.pdev_list)) +#ifdef CONFIG_X86_64 +#define perdomain_pt_pgidx(v) \ + ((v)->vcpu_id >> (PAGETABLE_ORDER - GDT_LDT_VCPU_SHIFT)) +#define perdomain_ptes(d, v) \ + ((l1_pgentry_t *)page_to_virt((d)->arch.mm_perdomain_pt_pages \ + [perdomain_pt_pgidx(v)]) + (((v)->vcpu_id << GDT_LDT_VCPU_SHIFT) & \ + (L1_PAGETABLE_ENTRIES - 1))) +#define perdomain_pt_page(d, n) ((d)->arch.mm_perdomain_pt_pages[n]) +#else +#define perdomain_ptes(d, v) \ + ((d)->arch.mm_perdomain_pt + ((v)->vcpu_id << GDT_LDT_VCPU_SHIFT)) +#define perdomain_pt_page(d, n) \ + (virt_to_page((d)->arch.mm_perdomain_pt) + (n)) +#endif + #ifdef __i386__ struct pae_l3_cache { _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |