[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 2/2] x86/shadow: Move shadow pagetable fields into struct shadow_vcpu
The vTLB and last_write* booleans are used exclusively by the shadow pagetable code. Move them from paging_vcpu to shadow_vcpu, which causes them to be entirely omitted on a build without shadow paging support. While changing the qualified names of these variables, drop an unnessary NULL check before freeing the vTLB, and move allocation of the vTLB from sh_update_paging_modes() to shadow_vcpu_init() where it more logically belongs. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- CC: Jan Beulich <JBeulich@xxxxxxxx> CC: Tim Deegan <tim@xxxxxxx> CC: George Dunlap <george.dunlap@xxxxxxxxxxxxx> --- xen/arch/x86/mm/shadow/common.c | 35 ++++++++++++----------------------- xen/arch/x86/mm/shadow/multi.c | 22 +++++++++++----------- xen/arch/x86/mm/shadow/private.h | 24 ++++++++++++------------ xen/include/asm-x86/domain.h | 18 ++++++++++-------- 4 files changed, 45 insertions(+), 54 deletions(-) diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index aa0b8f0..1075d56 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -95,6 +95,14 @@ int shadow_vcpu_init(struct vcpu *v) } #endif +#if (SHADOW_OPTIMIZATIONS & SHOPT_VIRTUAL_TLB) + /* Allocate a virtual TLB for this vcpu. */ + v->arch.paging.shadow.vtlb = xzalloc_array(struct shadow_vtlb, VTLB_ENTRIES); + if ( !v->arch.paging.shadow.vtlb ) + return -ENOMEM; + spin_lock_init(&v->arch.paging.shadow.vtlb_lock); +#endif /* (SHADOW_OPTIMIZATIONS & SHOPT_VIRTUAL_TLB) */ + v->arch.paging.mode = is_pv_vcpu(v) ? &SHADOW_INTERNAL_NAME(sh_paging_mode, 4) : &SHADOW_INTERNAL_NAME(sh_paging_mode, 3); @@ -1459,7 +1467,7 @@ void shadow_free(struct domain *d, mfn_t smfn) v->arch.paging.shadow.last_writeable_pte_smfn = 0; #endif #if SHADOW_OPTIMIZATIONS & SHOPT_FAST_EMULATION - v->arch.paging.last_write_emul_ok = 0; + v->arch.paging.shadow.last_write_emul_ok = 0; #endif } #endif @@ -1680,7 +1688,7 @@ static mfn_t emulate_gva_to_mfn(struct vcpu *v, unsigned long vaddr, mfn = page_to_mfn(page); ASSERT(mfn_valid(mfn)); - v->arch.paging.last_write_was_pt = !!sh_mfn_is_a_page_table(mfn); + v->arch.paging.shadow.last_write_was_pt = !!sh_mfn_is_a_page_table(mfn); /* * Note shadow cannot page out or unshare this mfn, so the map won't * disappear. Otherwise, caller must hold onto page until done. @@ -2864,22 +2872,6 @@ static void sh_update_paging_modes(struct vcpu *v) ASSERT(paging_locked_by_me(d)); -#if (SHADOW_OPTIMIZATIONS & SHOPT_VIRTUAL_TLB) - /* Make sure this vcpu has a virtual TLB array allocated */ - if ( unlikely(!v->arch.paging.vtlb) ) - { - v->arch.paging.vtlb = xzalloc_array(struct shadow_vtlb, VTLB_ENTRIES); - if ( unlikely(!v->arch.paging.vtlb) ) - { - SHADOW_ERROR("Could not allocate vTLB space for dom %u vcpu %u\n", - d->domain_id, v->vcpu_id); - domain_crash(v->domain); - return; - } - spin_lock_init(&v->arch.paging.vtlb_lock); - } -#endif /* (SHADOW_OPTIMIZATIONS & SHOPT_VIRTUAL_TLB) */ - #if (SHADOW_OPTIMIZATIONS & SHOPT_OUT_OF_SYNC) if ( mfn_eq(v->arch.paging.shadow.oos_snapshot[0], INVALID_MFN) ) { @@ -3206,11 +3198,8 @@ void shadow_teardown(struct domain *d, bool *preempted) for_each_vcpu(d, v) { #if (SHADOW_OPTIMIZATIONS & SHOPT_VIRTUAL_TLB) - if ( v->arch.paging.vtlb ) - { - xfree(v->arch.paging.vtlb); - v->arch.paging.vtlb = NULL; - } + xfree(v->arch.paging.shadow.vtlb); + v->arch.paging.shadow.vtlb = NULL; #endif /* (SHADOW_OPTIMIZATIONS & SHOPT_VIRTUAL_TLB) */ #if (SHADOW_OPTIMIZATIONS & SHOPT_OUT_OF_SYNC) diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c index d4090d7..20db60f 100644 --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -2881,7 +2881,7 @@ static int sh_page_fault(struct vcpu *v, * it's highly likely to reach same emulation action for this frame. * Then try to emulate early to avoid lock aquisition. */ - if ( v->arch.paging.last_write_emul_ok + if ( v->arch.paging.shadow.last_write_emul_ok && v->arch.paging.shadow.last_emulated_frame == (va >> PAGE_SHIFT) ) { /* check whether error code is 3, or else fall back to normal path @@ -2898,7 +2898,7 @@ static int sh_page_fault(struct vcpu *v, if ( mfn_valid(gmfn) && mfn_is_out_of_sync(gmfn) ) { fast_emul = 0; - v->arch.paging.last_write_emul_ok = 0; + v->arch.paging.shadow.last_write_emul_ok = 0; goto page_fault_slow_path; } #endif /* OOS */ @@ -2907,7 +2907,7 @@ static int sh_page_fault(struct vcpu *v, goto early_emulation; } else - v->arch.paging.last_write_emul_ok = 0; + v->arch.paging.shadow.last_write_emul_ok = 0; } #endif @@ -3344,7 +3344,7 @@ static int sh_page_fault(struct vcpu *v, if ( fast_emul ) { perfc_incr(shadow_fault_fast_emulate_fail); - v->arch.paging.last_write_emul_ok = 0; + v->arch.paging.shadow.last_write_emul_ok = 0; } #endif gdprintk(XENLOG_DEBUG, "write to pagetable during event " @@ -3399,7 +3399,7 @@ static int sh_page_fault(struct vcpu *v, if ( fast_emul ) { perfc_incr(shadow_fault_fast_emulate_fail); - v->arch.paging.last_write_emul_ok = 0; + v->arch.paging.shadow.last_write_emul_ok = 0; } #endif SHADOW_PRINTK("emulator failure, unshadowing mfn %#lx\n", @@ -3429,11 +3429,11 @@ static int sh_page_fault(struct vcpu *v, { v->arch.paging.shadow.last_emulated_frame = va >> PAGE_SHIFT; v->arch.paging.shadow.last_emulated_mfn = mfn_x(gmfn); - v->arch.paging.last_write_emul_ok = 1; + v->arch.paging.shadow.last_write_emul_ok = 1; } } else if ( fast_emul ) - v->arch.paging.last_write_emul_ok = 0; + v->arch.paging.shadow.last_write_emul_ok = 0; #endif if ( emul_ctxt.ctxt.retire.singlestep ) @@ -3452,7 +3452,7 @@ static int sh_page_fault(struct vcpu *v, for ( i = 0 ; i < 4 ; i++ ) { shadow_continue_emulation(&emul_ctxt, regs); - v->arch.paging.last_write_was_pt = 0; + v->arch.paging.shadow.last_write_was_pt = 0; r = x86_emulate(&emul_ctxt.ctxt, emul_ops); /* @@ -3463,7 +3463,7 @@ static int sh_page_fault(struct vcpu *v, if ( r == X86EMUL_OKAY && !emul_ctxt.ctxt.retire.raw ) { emulation_count++; - if ( v->arch.paging.last_write_was_pt ) + if ( v->arch.paging.shadow.last_write_was_pt ) { perfc_incr(shadow_em_ex_pt); TRACE_SHADOW_PATH_FLAG(TRCE_SFLAG_EMULATION_2ND_PT_WRITTEN); @@ -3539,7 +3539,7 @@ static bool_t sh_invlpg(struct vcpu *v, unsigned long va) #endif #if SHADOW_OPTIMIZATIONS & SHOPT_FAST_EMULATION - v->arch.paging.last_write_emul_ok = 0; + v->arch.paging.shadow.last_write_emul_ok = 0; #endif /* First check that we can safely read the shadow l2e. SMP/PAE linux can @@ -4232,7 +4232,7 @@ sh_update_cr3(struct vcpu *v, int do_locking) #endif #if SHADOW_OPTIMIZATIONS & SHOPT_FAST_EMULATION - v->arch.paging.last_write_emul_ok = 0; + v->arch.paging.shadow.last_write_emul_ok = 0; #endif #if (SHADOW_OPTIMIZATIONS & SHOPT_OUT_OF_SYNC) diff --git a/xen/arch/x86/mm/shadow/private.h b/xen/arch/x86/mm/shadow/private.h index f0b0ed4..5649e81 100644 --- a/xen/arch/x86/mm/shadow/private.h +++ b/xen/arch/x86/mm/shadow/private.h @@ -768,9 +768,9 @@ struct shadow_vtlb { /* Call whenever the guest flushes hit actual TLB */ static inline void vtlb_flush(struct vcpu *v) { - spin_lock(&v->arch.paging.vtlb_lock); - memset(v->arch.paging.vtlb, 0, VTLB_ENTRIES * sizeof (struct shadow_vtlb)); - spin_unlock(&v->arch.paging.vtlb_lock); + spin_lock(&v->arch.paging.shadow.vtlb_lock); + memset(v->arch.paging.shadow.vtlb, 0, VTLB_ENTRIES * sizeof(struct shadow_vtlb)); + spin_unlock(&v->arch.paging.shadow.vtlb_lock); } static inline int vtlb_hash(unsigned long page_number) @@ -784,9 +784,9 @@ static inline void vtlb_insert(struct vcpu *v, unsigned long page, { struct shadow_vtlb entry = { .page_number = page, .frame_number = frame, .pfec = pfec }; - spin_lock(&v->arch.paging.vtlb_lock); - v->arch.paging.vtlb[vtlb_hash(page)] = entry; - spin_unlock(&v->arch.paging.vtlb_lock); + spin_lock(&v->arch.paging.shadow.vtlb_lock); + v->arch.paging.shadow.vtlb[vtlb_hash(page)] = entry; + spin_unlock(&v->arch.paging.shadow.vtlb_lock); } /* Look a translation up in the vTLB. Returns INVALID_GFN if not found. */ @@ -797,15 +797,15 @@ static inline unsigned long vtlb_lookup(struct vcpu *v, unsigned long frame_number = gfn_x(INVALID_GFN); int i = vtlb_hash(page_number); - spin_lock(&v->arch.paging.vtlb_lock); - if ( v->arch.paging.vtlb[i].pfec != 0 - && v->arch.paging.vtlb[i].page_number == page_number + spin_lock(&v->arch.paging.shadow.vtlb_lock); + if ( v->arch.paging.shadow.vtlb[i].pfec != 0 + && v->arch.paging.shadow.vtlb[i].page_number == page_number /* Any successful walk that had at least these pfec bits is OK */ - && (v->arch.paging.vtlb[i].pfec & pfec) == pfec ) + && (v->arch.paging.shadow.vtlb[i].pfec & pfec) == pfec ) { - frame_number = v->arch.paging.vtlb[i].frame_number; + frame_number = v->arch.paging.shadow.vtlb[i].frame_number; } - spin_unlock(&v->arch.paging.vtlb_lock); + spin_unlock(&v->arch.paging.shadow.vtlb_lock); return frame_number; } #endif /* (SHADOW_OPTIMIZATIONS & SHOPT_VIRTUAL_TLB) */ diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index e6c7e13..3e7d791 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -147,7 +147,16 @@ struct shadow_vcpu { unsigned long off[SHADOW_OOS_FIXUPS]; } oos_fixup[SHADOW_OOS_PAGES]; - bool_t pagetable_dying; + /* Translated guest: virtual TLB */ + struct shadow_vtlb *vtlb; + spinlock_t vtlb_lock; + + /* HVM guest: last emulate was to a pagetable */ + bool last_write_was_pt; + /* HVM guest: last write emulation succeeds */ + bool last_write_emul_ok; + + bool pagetable_dying; #endif }; @@ -222,13 +231,6 @@ struct paging_vcpu { const struct paging_mode *mode; /* Nested Virtualization: paging mode of nested guest */ const struct paging_mode *nestedmode; - /* HVM guest: last emulate was to a pagetable */ - unsigned int last_write_was_pt:1; - /* HVM guest: last write emulation succeeds */ - unsigned int last_write_emul_ok:1; - /* Translated guest: virtual TLB */ - struct shadow_vtlb *vtlb; - spinlock_t vtlb_lock; /* paging support extension */ struct shadow_vcpu shadow; -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |