Nested Virtualization: p2m infrastructure
PATCH 17/18 Nested Virtualization: p2m infrastructure
Signature · 6 lines
---to satisfy European Law for business letters: Advanced Micro Devices GmbH Karl-Hammerschmidt-Str. 34, 85609 Dornach b. Muenchen Geschaeftsfuehrer: Andrew Bowd, Thomas M. McCoy, Giuliano Meroni Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen Registergericht Muenchen, HRB Nr. 43632
# HG changeset patch
# User cegger
# Date 1271330314 -7200
Change p2m infrastructure to operate on per-p2m instead of per-domain. This allows us to use multiple p2m tables per-domain.
xen/arch/x86/domain.c +1 -1
@@ -160,7 +160,7 @@ void dump_pageframe_info(struct domain *if (is_hvm_domain (d) ) { -p2m_pod_dump_data (d); +p2m_pod_dump_data (p2m_get_hostp2m (d)); }page_list_for_each ( page, &d->xenpage_list )
xen/arch/x86/domctl.c +2 -2
@@ -992,7 +992,7 @@ long arch_do_domctl( ret =iomem_permit_access (d, mfn, mfn + nr_mfns -1 );for ( i =0 ; i < nr_mfns; i++ ) -set_mmio_p2m_entry (d, gfn+i,_mfn (mfn+i)); +set_mmio_p2m_entry (p2m_get_hostp2m (d), gfn+i,_mfn (mfn+i)); }else {
@@ -1001,7 +1001,7 @@ long arch_do_domctl( gfn, mfn, nr_mfns);for ( i =0 ; i < nr_mfns; i++ ) -clear_mmio_p2m_entry (d, gfn+i); +clear_mmio_p2m_entry (p2m_get_hostp2m (d), gfn+i); ret =iomem_deny_access (d, mfn, mfn + nr_mfns -1 ); }
xen/arch/x86/hvm/emulate.c +6 -5
@@ -55,6 +55,7 @@ int hvmemul_do_io(paddr_t value = ram_gpa;int value_is_ptr = (p_data ==NULL );struct vcpu *curr = current; +struct p2m_domain *p2m =p2m_get_hostp2m (curr->domain);ioreq_t *p =get_ioreq (curr);unsigned long ram_gfn =paddr_to_pfn (ram_gpa);p2m_type_t p2mt;
@@ -62,10 +63,10 @@ int hvmemul_do_io(int rc;/* Check for paged out page */ - ram_mfn =gfn_to_mfn_unshare (curr->domain, ram_gfn, &p2mt,0 ); + ram_mfn =gfn_to_mfn_unshare (p2m, ram_gfn, &p2mt,0 );if (p2m_is_paging (p2mt) ) { -p2m_mem_paging_populate (curr->domain, ram_gfn); +p2m_mem_paging_populate (p2m, ram_gfn);return X86EMUL_RETRY ; }if (p2m_is_shared (p2mt) )
@@ -638,7 +639,7 @@ static int hvmemul_rep_movs(unsigned long saddr, daddr, bytes;paddr_t sgpa, dgpa;uint32_t pfec = PFEC_page_present; -struct domain *d = current->domain; +struct p2m_domain *p2m =p2m_get_hostp2m (current->domain);p2m_type_t p2mt;int rc, df = !!(ctxt->regs->eflags &X86_EFLAGS_DF );char *buf;
@@ -669,12 +670,12 @@ static int hvmemul_rep_movs(if ( rc !=X86EMUL_OKAY )return rc; - (void )gfn_to_mfn (d, sgpa >>PAGE_SHIFT , &p2mt); + (void )gfn_to_mfn (p2m, sgpa >>PAGE_SHIFT , &p2mt);if ( !p2m_is_ram (p2mt) && !p2m_is_grant (p2mt) )return hvmemul_do_mmio ( sgpa, reps, bytes_per_rep, dgpa,IOREQ_READ , df,NULL ); - (void )gfn_to_mfn (d, dgpa >>PAGE_SHIFT , &p2mt); + (void )gfn_to_mfn (p2m, dgpa >>PAGE_SHIFT , &p2mt);if ( !p2m_is_ram (p2mt) && !p2m_is_grant (p2mt) )return hvmemul_do_mmio ( dgpa, reps, bytes_per_rep, sgpa,IOREQ_WRITE , df,NULL );
xen/arch/x86/hvm/hvm.c +30 -20
175 lines not on this page · raw message
xen/arch/x86/hvm/mtrr.c +1 -1
@@ -399,7 +399,7 @@ uint32_t get_pat_flags(struct vcpu *v, {struct domain *d = v->domain;p2m_type_t p2mt; -gfn_to_mfn (d,paddr_to_pfn (gpaddr), &p2mt); +gfn_to_mfn (p2m_get_hostp2m (d),paddr_to_pfn (gpaddr), &p2mt);if (p2m_is_ram (p2mt))gdprintk (XENLOG_WARNING , "Conflict occurs for a given guest l1e flags:%x "
xen/arch/x86/hvm/stdvga.c +3 -4
@@ -469,6 +469,7 @@ static int mmio_move(struct hvm_hw_stdvgint i;int sign = p->df ?-1 :1 ;p2m_type_t p2mt; +struct p2m_domain *p2m =p2m_get_hostp2m (current->domain);if ( p->data_is_ptr ) {
@@ -481,8 +482,7 @@ static int mmio_move(struct hvm_hw_stdvgif (hvm_copy_to_guest_phys (data, &tmp, p->size) != HVMCOPY_okay ) { - (void )gfn_to_mfn (current->domain, - data >>PAGE_SHIFT , &p2mt); + (void )gfn_to_mfn (p2m, data >>PAGE_SHIFT , &p2mt);/* * The only case we handle is vga_mem <-> vga_mem. * Anything else disables caching and leaves it to qemu-dm.
@@ -504,8 +504,7 @@ static int mmio_move(struct hvm_hw_stdvgif (hvm_copy_from_guest_phys (&tmp, data, p->size) != HVMCOPY_okay ) { - (void )gfn_to_mfn (current->domain, - data >>PAGE_SHIFT , &p2mt); + (void )gfn_to_mfn (p2m, data >>PAGE_SHIFT , &p2mt);if ( (p2mt != p2m_mmio_dm) || (data <VGA_MEM_BASE ) || ((data + p->size) > (VGA_MEM_BASE +VGA_MEM_SIZE )) )return 0 ;
xen/arch/x86/hvm/svm/svm.c +7 -5
@@ -228,7 +228,7 @@ static int svm_vmcb_restore(struct vcpu {if ( c->cr0 &X86_CR0_PG ) { - mfn =mfn_x (gfn_to_mfn (v->domain, c->cr3 >>PAGE_SHIFT , &p2mt)); + mfn =mfn_x (gfn_to_mfn (p2m, c->cr3 >>PAGE_SHIFT , &p2mt));if ( !p2m_is_ram (p2mt) || !get_page (mfn_to_page (mfn), v->domain) ) { gdprintk(XENLOG_ERR, "Invalid CR3 value=0x%"PRIx64"\n",
@@ -1536,7 +1536,9 @@ static void svm_do_nested_pgfault(paddr_unsigned long gfn = gpa >>PAGE_SHIFT ;mfn_t mfn;p2m_type_t p2mt; -struct domain *d = current->domain; +struct p2m_domain *p2m; + + p2m =p2m_get_hostp2m (current->domain);if ( tb_init_done ) {
@@ -1549,7 +1551,7 @@ static void svm_do_nested_pgfault(paddr_ _d.gpa = gpa; _d.qualification =0 ; - _d.mfn =mfn_x (gfn_to_mfn_query (d, gfn, &_d.p2mt)); + _d.mfn =mfn_x (gfn_to_mfn_query (p2m, gfn, &_d.p2mt));__trace_var (TRC_HVM_NPF ,0 ,sizeof (_d), (unsigned char *)&_d); }
@@ -1558,10 +1560,10 @@ static void svm_do_nested_pgfault(paddr_return ;/* Everything else is an error. */ - mfn =gfn_to_mfn_guest (d, gfn, &p2mt); + mfn =gfn_to_mfn_guest (p2m, gfn, &p2mt);gdprintk (XENLOG_ERR ,"SVM violation gpa %#" PRIpaddr", mfn %#lx, type %i\n" , gpa,mfn_x (mfn), p2mt); -domain_crash (d); +domain_crash (current->domain); }static void svm_fpu_dirty_intercept (void )
xen/arch/x86/hvm/vmx/vmx.c +11 -7
@@ -491,7 +491,8 @@ static int vmx_restore_cr0_cr3( {if ( cr0 &X86_CR0_PG ) { - mfn =mfn_x (gfn_to_mfn (v->domain, cr3 >>PAGE_SHIFT , &p2mt)); + mfn =mfn_x (gfn_to_mfn (p2m_get_hostp2m (v->domain), + cr3 >>PAGE_SHIFT , &p2mt));if ( !p2m_is_ram (p2mt) || !get_page (mfn_to_page (mfn), v->domain) ) {gdprintk (XENLOG_ERR ,"Invalid CR3 value=0x%lx\n" , cr3);
@@ -1007,7 +1008,8 @@ static void vmx_load_pdptrs(struct vcpuif ( cr3 &0x1fUL ) goto crash; - mfn =mfn_x (gfn_to_mfn (v->domain, cr3 >>PAGE_SHIFT , &p2mt)); + mfn =mfn_x (gfn_to_mfn (p2m_get_hostp2m (v->domain), + cr3 >>PAGE_SHIFT , &p2mt));if ( !p2m_is_ram (p2mt) ) goto crash;
@@ -1226,7 +1228,7 @@ void ept_sync_domain(struct domain *d)return ;ASSERT (local_irq_is_enabled ()); -ASSERT (p2m_locked_by_me (d->arch.p2m)); +ASSERT (p2m_locked_by_me (p2m_get_hostp2m (d)));/* * Flush active cpus synchronously. Flush others the next time this domain
@@ -1345,7 +1347,7 @@ static void vmx_set_uc_mode(struct vcpu {if (paging_mode_hap (v->domain) )ept_change_entry_emt_with_range ( - v->domain,0 , v->domain->arch.p2m->max_mapped_pfn); + v->domain,0 ,p2m_get_hostp2m (v->domain)->max_mapped_pfn);hvm_asid_flush_vcpu (v); }
@@ -1915,7 +1917,8 @@ static int vmx_alloc_vlapic_mapping(strureturn -ENOMEM ;share_xen_page_with_guest (virt_to_page (apic_va), d, XENSHARE_writable);set_mmio_p2m_entry ( - d,paddr_to_pfn (APIC_DEFAULT_PHYS_BASE ),_mfn (virt_to_mfn (apic_va))); +p2m_get_hostp2m (d),paddr_to_pfn (APIC_DEFAULT_PHYS_BASE ), +_mfn (virt_to_mfn (apic_va))); d->arch.hvm_domain.vmx.apic_access_mfn =virt_to_mfn (apic_va);return 0 ;
@@ -2123,6 +2126,7 @@ static void ept_handle_violation(unsigneunsigned long gla, gfn = gpa >>PAGE_SHIFT ;mfn_t mfn;p2m_type_t p2mt; +struct p2m_domain *p2m =p2m_get_hostp2m (current->domain);if ( tb_init_done ) {
@@ -2135,7 +2139,7 @@ static void ept_handle_violation(unsigne _d.gpa = gpa; _d.qualification = qualification; - _d.mfn =mfn_x (gfn_to_mfn_query (current->domain, gfn, &_d.p2mt)); + _d.mfn =mfn_x (gfn_to_mfn_query (p2m, gfn, &_d.p2mt));__trace_var (TRC_HVM_NPF ,0 ,sizeof (_d), (unsigned char *)&_d); }
@@ -2145,7 +2149,7 @@ static void ept_handle_violation(unsignereturn ;/* Everything else is an error. */ - mfn =gfn_to_mfn_guest (current->domain, gfn, &p2mt); + mfn =gfn_to_mfn_guest (p2m, gfn, &p2mt); gdprintk(XENLOG_ERR, "EPT violation %#lx (%c%c%c/%c%c%c), " "gpa %#"PRIpaddr", mfn %#lx, type %i.\n", qualification,
xen/arch/x86/mm.c +32 -25
170 lines not on this page · raw message
xen/arch/x86/mm/guest_walk.c +7 -6
@@ -86,17 +86,17 @@ static uint32_t set_ad_bits(void *guest_return 0 ; } -static inline void *map_domain_gfn (struct domain *d, +static inline void *map_domain_gfn (struct p2m_domain *p2m,gfn_t gfn,mfn_t *mfn,p2m_type_t *p2mt,uint32_t *rc) {/* Translate the gfn, unsharing if shared */ - *mfn =gfn_to_mfn_unshare (d,gfn_x (gfn), p2mt,0 ); + *mfn =gfn_to_mfn_unshare (p2m,gfn_x (gfn), p2mt,0 );if (p2m_is_paging (*p2mt) ) { -p2m_mem_paging_populate (d,gfn_x (gfn)); +p2m_mem_paging_populate (p2m,gfn_x (gfn)); *rc = _PAGE_PAGED;return NULL ;
@@ -123,6 +123,7 @@ guest_walk_tables(struct vcpu *v, unsign uint32_t pfec, mfn_t top_mfn, void *top_map) { struct domain *d = v->domain; +struct p2m_domain *p2m =p2m_get_hostp2m (d);p2m_type_t p2mt;guest_l1e_t *l1p =NULL ;guest_l2e_t *l2p =NULL ;
@@ -154,7 +155,7 @@ guest_walk_tables(struct vcpu *v, unsignif ( rc & _PAGE_PRESENT ) goto out;/* Map the l3 table */ - l3p = map_domain_gfn(d, + l3p = map_domain_gfn(p2m, guest_l4e_get_gfn(gw->l4e), &gw->l3mfn, &p2mt,
@@ -181,7 +182,7 @@ guest_walk_tables(struct vcpu *v, unsign#endif /* PAE or 64... */ /* Map the l2 table */ - l2p = map_domain_gfn(d, + l2p = map_domain_gfn(p2m, guest_l3e_get_gfn(gw->l3e), &gw->l2mfn, &p2mt,
@@ -237,7 +238,7 @@ guest_walk_tables(struct vcpu *v, unsignelse {/* Not a superpage: carry on and find the l1e. */ - l1p = map_domain_gfn(d, + l1p = map_domain_gfn(p2m, guest_l2e_get_gfn(gw->l2e), &gw->l1mfn, &p2mt,
xen/arch/x86/mm/hap/guest_walk.c +5 -5
@@ -43,13 +43,14 @@ unsigned long hap_gva_to_gfn(GUEST_PAGINvoid *top_map;p2m_type_t p2mt;walk_t gw; +struct p2m_domain *p2m =p2m_get_hostp2m (v->domain);/* Get the top-level table's MFN */ cr3 = v->arch.hvm_vcpu.guest_cr[3 ]; - top_mfn =gfn_to_mfn_unshare (v->domain, cr3 >>PAGE_SHIFT , &p2mt,0 ); + top_mfn =gfn_to_mfn_unshare (p2m, cr3 >>PAGE_SHIFT , &p2mt,0 );if (p2m_is_paging (p2mt) ) { -p2m_mem_paging_populate (v->domain, cr3 >>PAGE_SHIFT ); +p2m_mem_paging_populate (p2m, cr3 >>PAGE_SHIFT ); pfec[0 ] = PFEC_page_paged;return INVALID_GFN ;
@@ -78,10 +79,10 @@ unsigned long hap_gva_to_gfn(GUEST_PAGINif ( missing ==0 ) {gfn_t gfn =guest_l1e_get_gfn (gw.l1e); -gfn_to_mfn_unshare (v->domain,gfn_x (gfn), &p2mt,0 ); +gfn_to_mfn_unshare (p2m,gfn_x (gfn), &p2mt,0 );if (p2m_is_paging (p2mt) ) { -p2m_mem_paging_populate (v->domain,gfn_x (gfn)); +p2m_mem_paging_populate (p2m,gfn_x (gfn)); pfec[0 ] = PFEC_page_paged;return INVALID_GFN ;
@@ -130,4 +131,3 @@ unsigned long hap_gva_to_gfn(GUEST_PAGIN* indent-tabs-mode: nil * End: */ -
xen/arch/x86/mm/hap/hap.c +22 -15
@@ -70,7 +70,7 @@ static int hap_enable_vram_tracking(stru/* set l1e entries of P2M table to be read-only. */ for (i = dirty_vram->begin_pfn; i < dirty_vram->end_pfn; i++) -p2m_change_type (d, i, p2m_ram_rw, p2m_ram_logdirty); +p2m_change_type (p2m_get_hostp2m (d), i, p2m_ram_rw, p2m_ram_logdirty);flush_tlb_mask (&d->domain_dirty_cpumask);return 0 ;
@@ -90,7 +90,7 @@ static int hap_disable_vram_tracking(str/* set l1e entries of P2M table with normal mode */ for (i = dirty_vram->begin_pfn; i < dirty_vram->end_pfn; i++) -p2m_change_type (d, i, p2m_ram_logdirty, p2m_ram_rw); +p2m_change_type (p2m_get_hostp2m (d), i, p2m_ram_logdirty, p2m_ram_rw);flush_tlb_mask (&d->domain_dirty_cpumask);return 0 ;
@@ -106,7 +106,7 @@ static void hap_clean_vram_tracking(stru/* set l1e entries of P2M table to be read-only. */ for (i = dirty_vram->begin_pfn; i < dirty_vram->end_pfn; i++) -p2m_change_type (d, i, p2m_ram_rw, p2m_ram_logdirty); +p2m_change_type (p2m_get_hostp2m (d), i, p2m_ram_rw, p2m_ram_logdirty);flush_tlb_mask (&d->domain_dirty_cpumask); }
@@ -200,7 +200,8 @@ static int hap_enable_log_dirty(struct dhap_unlock (d);/* set l1e entries of P2M table to be read-only. */ -p2m_change_entry_type_global (d, p2m_ram_rw, p2m_ram_logdirty); +p2m_change_entry_type_global (p2m_get_hostp2m (d), + p2m_ram_rw, p2m_ram_logdirty);flush_tlb_mask (&d->domain_dirty_cpumask);return 0 ; }
@@ -212,14 +213,16 @@ static int hap_disable_log_dirty(structhap_unlock (d);/* set l1e entries of P2M table with normal mode */ -p2m_change_entry_type_global (d, p2m_ram_logdirty, p2m_ram_rw); +p2m_change_entry_type_global (p2m_get_hostp2m (d), + p2m_ram_logdirty, p2m_ram_rw);return 0 ; }static void hap_clean_dirty_bitmap (struct domain *d) {/* set l1e entries of P2M table to be read-only. */ -p2m_change_entry_type_global (d, p2m_ram_rw, p2m_ram_logdirty); +p2m_change_entry_type_global (p2m_get_hostp2m (d), + p2m_ram_rw, p2m_ram_logdirty);flush_tlb_mask (&d->domain_dirty_cpumask); }
@@ -273,8 +276,9 @@ static void hap_free(struct domain *d, mpage_list_add_tail (pg, &d->arch.paging.hap.freelist); } -static struct page_info *hap_alloc_p2m_page (struct domain *d) +static struct page_info *hap_alloc_p2m_page (struct p2m_domain *p2m) { +struct domain *d = p2m->domain;struct page_info *pg;hap_lock (d);
@@ -312,8 +316,9 @@ static struct page_info *hap_alloc_p2m_preturn pg; } -static void hap_free_p2m_page (struct domain *d,struct page_info *pg) +static void hap_free_p2m_page (struct p2m_domain *p2m,struct page_info *pg) { +struct domain *d = p2m->domain;hap_lock (d);ASSERT (page_get_owner (pg) == d);/* Should have just the one ref we gave it in alloc_p2m_page() */
@@ -580,10 +585,11 @@ int hap_enable(struct domain *d, u32 mod } } -/* allocate P2m table */ +/* allocate p2m table */ if ( mode & PG_translate ) { - rv =p2m_alloc_table (d, hap_alloc_p2m_page, hap_free_p2m_page); + rv =p2m_alloc_table (p2m_get_hostp2m (d), + hap_alloc_p2m_page, hap_free_p2m_page);if ( rv !=0 ) goto out; }
@@ -600,7 +606,7 @@ void hap_final_teardown(struct domain *dif ( d->arch.paging.hap.total_pages !=0 )hap_teardown (d); -p2m_teardown (d); +p2m_teardown (p2m_get_hostp2m (d));ASSERT (d->arch.paging.hap.p2m_pages ==0 ); }
@@ -700,9 +706,11 @@ void hap_vcpu_init(struct vcpu *v)static int hap_page_fault (struct vcpu *v,unsigned long va,struct cpu_user_regs *regs) { +struct domain *d = v->domain; +HAP_ERROR ("Intercepted a guest #PF (%u:%u) with HAP enabled.\n" , - v->domain->domain_id, v->vcpu_id); -domain_crash (v->domain); + d->domain_id, v->vcpu_id); +domain_crash (d);return 0 ; }
@@ -822,6 +830,7 @@ static unsigned long hap_gva_to_gfn_realreturn ((paddr_t )gva >>PAGE_SHIFT ); } +/* Entry points into this mode of the hap code. */ static const struct paging_mode hap_paging_real_mode = { .page_fault = hap_page_fault,
@@ -871,5 +880,3 @@ static const struct paging_mode hap_pagi* indent-tabs-mode: nil * End: */ - -
xen/arch/x86/mm/hap/p2m-ept.c +60 -55
369 lines not on this page · raw message
xen/arch/x86/mm/mem_event.c +2 -2
@@ -240,7 +240,7 @@ int mem_event_domctl(struct domain *d, x/* Get MFN of ring page */ guest_get_eff_l1e (v, ring_addr, &l1e); gfn =l1e_get_pfn (l1e); - ring_mfn =gfn_to_mfn (dom_mem_event, gfn, &p2mt); + ring_mfn =gfn_to_mfn (p2m_get_hostp2m (dom_mem_event), gfn, &p2mt); rc = -EINVAL ;if (unlikely (!mfn_valid (mfn_x (ring_mfn))) )
@@ -249,7 +249,7 @@ int mem_event_domctl(struct domain *d, x/* Get MFN of shared page */ guest_get_eff_l1e (v, shared_addr, &l1e); gfn =l1e_get_pfn (l1e); - shared_mfn =gfn_to_mfn (dom_mem_event, gfn, &p2mt); + shared_mfn =gfn_to_mfn (p2m_get_hostp2m (dom_mem_event), gfn, &p2mt); rc = -EINVAL ;if (unlikely (!mfn_valid (mfn_x (shared_mfn))) )
xen/arch/x86/mm/mem_paging.c +5 -4
@@ -29,33 +29,34 @@ int mem_paging_domctl(struct domain *d, XEN_GUEST_HANDLE(void) u_domctl) {int rc; +struct p2m_domain *p2m =p2m_get_hostp2m (d);switch ( mec->op ) {case XEN_DOMCTL_MEM_EVENT_OP_PAGING_NOMINATE : {unsigned long gfn = mec->gfn; - rc =p2m_mem_paging_nominate (d, gfn); + rc =p2m_mem_paging_nominate (p2m, gfn); }break ;case XEN_DOMCTL_MEM_EVENT_OP_PAGING_EVICT : {unsigned long gfn = mec->gfn; - rc =p2m_mem_paging_evict (d, gfn); + rc =p2m_mem_paging_evict (p2m, gfn); }break ;case XEN_DOMCTL_MEM_EVENT_OP_PAGING_PREP : {unsigned long gfn = mec->gfn; - rc =p2m_mem_paging_prep (d, gfn); + rc =p2m_mem_paging_prep (p2m, gfn); }break ;case XEN_DOMCTL_MEM_EVENT_OP_PAGING_RESUME : { -p2m_mem_paging_resume (d); +p2m_mem_paging_resume (p2m); rc =0 ; }break ;
xen/arch/x86/mm/mem_sharing.c +17 -12
@@ -254,6 +254,7 @@ static void mem_sharing_audit(void)list_for_each (le, &e->gfns) {struct domain *d; +struct p2m_domain *p2m;p2m_type_t t;mfn_t mfn;
@@ -265,7 +266,8 @@ static void mem_sharing_audit(void) g->domain, g->gfn, mfn_x(e->mfn));continue ; } - mfn =gfn_to_mfn (d, g->gfn, &t); + p2m =p2m_get_hostp2m (d); + mfn =gfn_to_mfn (p2m, g->gfn, &t);if (mfn_x (mfn) !=mfn_x (e->mfn)) MEM_SHARING_DEBUG("Incorrect P2M for d=%d, PFN=%lx." "Expecting MFN=%ld, got %ld\n",
@@ -380,7 +382,7 @@ int mem_sharing_debug_gfn(struct domainmfn_t mfn;struct page_info *page; - mfn =gfn_to_mfn (d, gfn, &p2mt); + mfn =gfn_to_mfn (p2m_get_hostp2m (d), gfn, &p2mt); page =mfn_to_page (mfn); printk("Debug for domain=%d, gfn=%lx, ",
@@ -490,7 +492,7 @@ int mem_sharing_debug_gref(struct domainreturn mem_sharing_debug_gfn (d, gfn); } -int mem_sharing_nominate_page (struct domain *d, +int mem_sharing_nominate_page (struct p2m_domain *p2m,unsigned long gfn,int expected_refcnt,shr_handle_t *phandle)
@@ -502,10 +504,11 @@ int mem_sharing_nominate_page(struct domshr_handle_t handle;shr_hash_entry_t *hash_entry;struct gfn_info *gfn_info; +struct domain *d = p2m->domain; *phandle =0UL ; - mfn =gfn_to_mfn (d, gfn, &p2mt); + mfn =gfn_to_mfn (p2m, gfn, &p2mt);/* Check if mfn is valid */ ret = -EINVAL ;
@@ -539,7 +542,7 @@ int mem_sharing_nominate_page(struct dom }/* Change the p2m type */ -if (p2m_change_type (d, gfn, p2mt, p2m_ram_shared) != p2mt) +if (p2m_change_type (p2m, gfn, p2mt, p2m_ram_shared) != p2mt) {/* This is unlikely, as the type must have changed since we've checked * it a few lines above.
@@ -602,7 +605,7 @@ int mem_sharing_share_pages(shr_handle_tlist_del (&gfn->list); d =get_domain_by_id (gfn->domain);BUG_ON (!d); -BUG_ON (set_shared_p2m_entry (d, gfn->gfn, se->mfn) ==0 ); +BUG_ON (set_shared_p2m_entry (p2m_get_hostp2m (d), gfn->gfn, se->mfn) ==0 );put_domain (d);list_add (&gfn->list, &se->gfns);put_page_and_type (cpage);
@@ -621,7 +624,7 @@ err_out:return ret; } -int mem_sharing_unshare_page (struct domain *d, +int mem_sharing_unshare_page (struct p2m_domain *p2m,unsigned long gfn,uint16_t flags) {
@@ -634,8 +637,9 @@ int mem_sharing_unshare_page(struct domastruct gfn_info *gfn_info =NULL ;shr_handle_t handle;struct list_head *le; +struct domain *d = p2m->domain; - mfn =gfn_to_mfn (d, gfn, &p2mt); + mfn =gfn_to_mfn (p2m, gfn, &p2mt); page =mfn_to_page (mfn); handle = page->shr_handle;
@@ -699,7 +703,7 @@ gfn_found:unmap_domain_page (s);unmap_domain_page (t); -ASSERT (set_shared_p2m_entry (d, gfn,page_to_mfn (page)) !=0 ); +ASSERT (set_shared_p2m_entry (p2m, gfn,page_to_mfn (page)) !=0 );put_page_and_type (old_page); private_page_found:
@@ -711,7 +715,7 @@ private_page_found:atomic_dec (&nr_saved_mfns);shr_unlock (); -if (p2m_change_type (d, gfn, p2m_ram_shared, p2m_ram_rw) != +if (p2m_change_type (p2m, gfn, p2m_ram_shared, p2m_ram_rw) != p2m_ram_shared) {printk ("Could not change p2m type.\n" );
@@ -743,7 +747,7 @@ int mem_sharing_domctl(struct domain *d,shr_handle_t handle;if (!mem_sharing_enabled (d))return -EINVAL ; - rc =mem_sharing_nominate_page (d, gfn,0 , &handle); + rc =mem_sharing_nominate_page (p2m_get_hostp2m (d), gfn,0 , &handle); mec->u.nominate.handle = handle;mem_sharing_audit (); }
@@ -759,7 +763,8 @@ int mem_sharing_domctl(struct domain *d,return -EINVAL ;if (mem_sharing_gref_to_gfn (d, gref, &gfn) <0 )return -EINVAL ; - rc =mem_sharing_nominate_page (d, gfn,3 , &handle); + rc =mem_sharing_nominate_page (p2m_get_hostp2m (d), + gfn,3 , &handle); mec->u.nominate.handle = handle;mem_sharing_audit (); }
xen/arch/x86/mm/p2m.c +419 -389
1,719 lines not on this page · raw message
xen/arch/x86/mm/shadow/multi.c +24 -17
41 lines not on this page · raw message
xen/include/asm-x86/p2m.h +61 -49
110 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel
Part of the diff is not shown here. View the raw message.
This was mostly OK, with a few oddities (below), and assuming that we can agree that later patches make it necessary.
If you resubmit, please send it as two patches, one of which does _only_ the change from passing struct domains to passing p2m structs and nothing else - no comment changes, no format tidying, nothing. I don't want to have to comb through another 4000 line patch looking for hidden surprises.
xen/arch/x86/mm/p2m.c out: · line 1393
Quoted 5 lines
xen/arch/x86/mm/p2m.c +1
-0@@ -1391,8 +1390,9 @@ out:return rv; } +/* Read p2m table (through the linear mapping). */
That's exactly wrong. The gfn_to_mfn_current() function that you removed was the one that used the linear mapping. This one maps and unmaps pages as it goes.
xen/arch/x86/mm/p2m.c out: · line 1397
Quoted 5 lines
xen/arch/x86/mm/p2m.c +1
-1static mfn_t -p2m_gfn_to_mfn (struct domain *d,unsigned long gfn,p2m_type_t *t, +p2m_gfn_to_mfn (struct p2m_domain *p2m,unsigned long gfn,p2m_type_t *t,p2m_query_t q) {
mfn_t mfn;
...
xen/arch/x86/mm/p2m.c pod_retry_l1: · line 1534
Quoted 7 lines
xen/arch/x86/mm/p2m.c +1
-2@@ -1531,8 +1531,7 @@ pod_retry_l1:return (p2m_is_valid (*t) ||p2m_is_grant (*t)) ? mfn :_mfn (INVALID_MFN ); } -/* Init the datastructures for later use by the p2m code */ -int p2m_init (struct domain *d) +static int p2m_allocp2m (struct p2m_domain **_p2m)
Since the only error this routine can return is -ENOMEM, why not just return the p2m pointer or NULL?
Quoted 8 lines
xen/arch/x86/mm/p2m.c +0
-1{struct p2m_domain *p2m;@@ -1540,39 +1539,68 @@ int p2m_init(struct domain *d)if ( p2m ==NULL )return -ENOMEM ; - d->arch.p2m = p2m;
xen/arch/x86/mm/p2m.c int p2m_init(struct domain *d) · line 1550
Quoted 10 lines
xen/arch/x86/mm/p2m.c +9
-1- + *_p2m = p2m; +return 0 ; +} + +/* Init the datastructures for later use by the p2m code */ +static void p2m_initialise (struct domain *d,struct p2m_domain *p2m, +bool_t preserve_allocfree) +{ +void *alloc, *free;
These are function pointers; there's no need to hack them into void pointers.
Quoted 26 lines
xen/arch/x86/mm/p2m.c +12
-0+ alloc = free =NULL ; +if (preserve_allocfree) { + alloc = p2m->alloc_page; + free = p2m->free_page; + }memset (p2m,0 ,sizeof (*p2m));p2m_lock_init (p2m);INIT_PAGE_LIST_HEAD (&p2m->pages);INIT_PAGE_LIST_HEAD (&p2m->pod.super);INIT_PAGE_LIST_HEAD (&p2m->pod.single); + p2m->domain = d; p2m->set_entry = p2m_set_entry; p2m->get_entry = p2m_gfn_to_mfn; p2m->change_entry_type_global = p2m_change_type_global; +if (preserve_allocfree) { + p2m->alloc_page = alloc; + p2m->free_page = free; + }if (is_hvm_domain (d) && d->arch.hvm_domain.hap_enabled && (boot_cpu_data.x86_vendor ==X86_VENDOR_INTEL ) )ept_p2m_init (d); +return ; +}
...
Quoted 3 lines
void
p2m_final_teardown(struct domain *d)
{
+ /* Iterate over all p2m tables per domain */
Even when the matching code arrives this comment's not really helpful.
Quoted 41 lines
xfree(d->arch.p2m); d->arch.p2m = NULL;}
#if
P2M_AUDITxen/arch/x86/mm/p2m.c +5
-4-static void audit_p2m (struct domain *d) +static void audit_p2m (struct p2m_domain *p2m) {struct page_info *page;struct domain *od;@@ -1735,6 +1761,7 @@ static void audit_p2m(struct domain *d)unsigned long orphans_d =0 , orphans_i =0 , mpbad =0 , pmbad =0 ;int test_linear;p2m_type_t type; +struct domain *d = p2m->domain;if ( !paging_mode_translate (d) )return ;@@ -1789,7 +1816,7 @@ static void audit_p2m(struct domain *d)continue ; } - p2mfn =gfn_to_mfn_type_foreign (d, gfn, &type, p2m_query); + p2mfn =gfn_to_mfn_type_p2m (p2m, gfn, &type, p2m_query);if (mfn_x (p2mfn) != mfn ) { mpbad++;@@ -1805,9 +1832,9 @@ static void audit_p2m(struct domain *d)set_gpfn_from_mfn (mfn,INVALID_M2P_ENTRY ); } -if ( test_linear && (gfn <= d->arch.p2m->max_mapped_pfn) ) +if ( test_linear && (gfn <= p2m->max_mapped_pfn) ) { - lp2mfn =mfn_x (gfn_to_mfn_query (d, gfn, &type)); + lp2mfn =mfn_x (gfn_to_mfn_query (p2m, gfn, &type));if ( lp2mfn !=mfn_x (p2mfn) ) { P2M_PRINTK("linear mismatch gfn %#lx -> mfn %#lx "@@ -1822,21 +1849,19 @@ static void audit_p2m(struct domain *d)spin_unlock (&d->page_alloc_lock);
xen/arch/x86/mm/p2m.c static void audit_p2m(struct domain *d) · line 1857
Quoted 10 lines
xen/arch/x86/mm/p2m.c +3
-2/* Audit part two: walk the domain's p2m table, checking the entries. */ - if ( pagetable_get_pfn(p2m_get_pagetable(p2m_get_hostp2m(d)) != 0 ) +if (pagetable_get_pfn (p2m_get_pagetable (p2m)) !=0 ) { +l3_pgentry_t *l3e;l2_pgentry_t *l2e;l1_pgentry_t *l1e; -int i1, i2; +int i1, i2, i3;
Why are you moving these definitions around? You don't change the use of the variables anywhere.
xen/arch/x86/mm/p2m.c static void audit_p2m(struct domain *d) · line 1838
Quoted 10 lines
xen/arch/x86/mm/p2m.c +2
-5#if CONFIG_PAGING_LEVELS ==4 l4_pgentry_t *l4e; -l3_pgentry_t *l3e; -int i3, i4; - l4e =map_domain_page (mfn_x (pagetable_get_mfn (p2m_get_pagetable (p2m_get_hostp2m (d))))); +int i4; + l4e =map_domain_page (mfn_x (pagetable_get_mfn (p2m_get_pagetable (p2m))));#else /* CONFIG_PAGING_LEVELS == 3 */ -l3_pgentry_t *l3e; -int i3;
Ditto.
Quoted 5 lines
xen/arch/x86/mm/p2m.c +1
-1- l3e =map_domain_page (mfn_x (pagetable_get_mfn (p2m_get_pagetable (p2m_get_hostp2m (d))))); + l3e =map_domain_page (mfn_x (pagetable_get_mfn (p2m_get_pagetable (p2m))));#endif gfn =0 ;
...
Quoted 13 lines
diff -r
f96f6f2cd19a-r3f48b73b0a30xen/common/grant_table.cxen/common/grant_table.c +1
-1@@ -109,7 +109,7 @@ static unsigned inline int max_nr_maptra#define gfn_to_mfn_private (_d, _gfn) ({ \ p2m_type_t __p2mt; \ unsigned long __x; \ - __x = mfn_x(gfn_to_mfn_unshare(_d, _gfn, &__p2mt, 1)); \ + __x = mfn_x(gfn_to_mfn_unshare(p2m_get_hostp2m(_d), _gfn, &__p2mt, 1)); \ if ( !p2m_is_valid(__p2mt) ) \ __x = INVALID_MFN; \ __x; })
xen/common/grant_table.c gnttab_unpopulate_status_frames(struct d · line 1062
Quoted 5 lines
xen/common/grant_table.c +1
-1@@ -1059,7 +1059,7 @@ gnttab_unpopulate_status_frames(struct dfor ( i =0 ; i <nr_status_frames (gt); i++ ) { -page_set_owner (virt_to_page (gt->status[i]), dom_xen); +page_set_owner (virt_to_page (gt->status[i]),p2m_get_hostp2m (dom_xen));
That seems very unlikely to be correct. Did you get carried away?
xen/common/grant_table.c gnttab_transfer( · line 1501
Quoted 9 lines
xen/common/grant_table.c +1
-1free_xenheap_page (gt->status[i]); gt->status[i] =NULL ; }@@ -1498,7 +1498,7 @@ gnttab_transfer(if (unlikely (e->tot_pages++ ==0 ) )get_knownalive_domain (e);page_list_add_tail (page, &e->page_list); -page_set_owner (page, e); +page_set_owner (page,p2m_get_hostp2m (e));
Likewise.
Quoted 3 lines
xen/common/grant_table.c +0
-0spin_unlock (&e->page_alloc_lock);
...
xen/include/asm-x86/mem_sharing.h line 27
Quoted 10 lines
diff -r
f96f6f2cd19a-r3f48b73b0a30xen/include/asm-x86/mem_sharing.hxen/include/asm-x86/mem_sharing.h +1
-1@@ -23,22 +23,22 @@#define __MEM_SHARING_H__#define sharing_supported (_d) \ - (is_hvm_domain(_d) && (_d)->arch.hvm_domain.hap_enabled) + (is_hvm_domain(_d) && paging_mode_hap(_d))
Okay, but it really doesn't belong in this patch.
Cheers,
Tim.
Signature · 3 lines
Tim Deegan <[email protected]> Principal Software Engineer, XenServer Engineering Citrix Systems UK Ltd. (Company #02937203, SL9 0BG)