Further release shadow lock. emulate_map_dest doesn't require holding lock, since only shadow related operation possibly involved is to remove shadow which is less frequent and can acquire lock inside. Rest are either guest table walk or per-vcpu monitor table manipulation Signed-off-by Kevin Tian diff -r 0a56f6e9e0a5 xen/arch/x86/mm/shadow/multi.c --- a/xen/arch/x86/mm/shadow/multi.c Mon Jan 14 09:04:35 2008 +0800 +++ b/xen/arch/x86/mm/shadow/multi.c Tue Jan 22 10:32:01 2008 +0800 @@ -4180,17 +4180,14 @@ sh_x86_emulate_write(struct vcpu *v, uns if ( (vaddr & (bytes - 1)) && !is_hvm_vcpu(v) ) return X86EMUL_UNHANDLEABLE; - shadow_lock(v->domain); addr = emulate_map_dest(v, vaddr, bytes, sh_ctxt); if ( emulate_map_dest_failed(addr) ) - { - shadow_unlock(v->domain); return ((addr == MAPPING_EXCEPTION) ? X86EMUL_EXCEPTION : X86EMUL_UNHANDLEABLE); - } memcpy(addr, src, bytes); + shadow_lock(v->domain); emulate_unmap_dest(v, addr, bytes, sh_ctxt); shadow_audit_tables(v); shadow_unlock(v->domain); @@ -4210,15 +4207,10 @@ sh_x86_emulate_cmpxchg(struct vcpu *v, u if ( (vaddr & (bytes - 1)) && !is_hvm_vcpu(v) ) return X86EMUL_UNHANDLEABLE; - shadow_lock(v->domain); - addr = emulate_map_dest(v, vaddr, bytes, sh_ctxt); if ( emulate_map_dest_failed(addr) ) - { - shadow_unlock(v->domain); return ((addr == MAPPING_EXCEPTION) ? X86EMUL_EXCEPTION : X86EMUL_UNHANDLEABLE); - } switch ( bytes ) { @@ -4238,6 +4230,7 @@ sh_x86_emulate_cmpxchg(struct vcpu *v, u " wanted %#lx now %#lx bytes %u\n", vaddr, prev, old, new, *(unsigned long *)addr, bytes); + shadow_lock(v->domain); emulate_unmap_dest(v, addr, bytes, sh_ctxt); shadow_audit_tables(v); shadow_unlock(v->domain); @@ -4258,15 +4251,10 @@ sh_x86_emulate_cmpxchg8b(struct vcpu *v, if ( (vaddr & 7) && !is_hvm_vcpu(v) ) return X86EMUL_UNHANDLEABLE; - shadow_lock(v->domain); - addr = emulate_map_dest(v, vaddr, 8, sh_ctxt); if ( emulate_map_dest_failed(addr) ) - { - shadow_unlock(v->domain); return ((addr == MAPPING_EXCEPTION) ? X86EMUL_EXCEPTION : X86EMUL_UNHANDLEABLE); - } old = (((u64) old_hi) << 32) | (u64) old_lo; new = (((u64) new_hi) << 32) | (u64) new_lo; @@ -4275,6 +4263,7 @@ sh_x86_emulate_cmpxchg8b(struct vcpu *v, if ( prev != old ) rv = X86EMUL_CMPXCHG_FAILED; + shadow_lock(v->domain); emulate_unmap_dest(v, addr, 8, sh_ctxt); shadow_audit_tables(v); shadow_unlock(v->domain);