[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] hvm: Cleanups to state-restore paths (including vmxassist world restore).
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Date 1187025502 -3600 # Node ID 08e962b8597cdc7c1dbef7c8228f4ceef1d5737e # Parent d8b5b02c52cf997eaa9be4717dd2da1a8a1cb4d2 hvm: Cleanups to state-restore paths (including vmxassist world restore). Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/arch/x86/hvm/hvm.c | 2 xen/arch/x86/hvm/svm/svm.c | 14 ++---- xen/arch/x86/hvm/vmx/vmx.c | 105 ++++++++++++++------------------------------- 3 files changed, 41 insertions(+), 80 deletions(-) diff -r d8b5b02c52cf -r 08e962b8597c xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Mon Aug 13 16:47:11 2007 +0100 +++ b/xen/arch/x86/hvm/hvm.c Mon Aug 13 18:18:22 2007 +0100 @@ -587,7 +587,7 @@ int hvm_set_cr0(unsigned long value) hvm_update_guest_efer(v); } - if ( !paging_mode_hap(v->domain) && v->arch.hvm_vcpu.guest_cr[3] ) + if ( !paging_mode_hap(v->domain) ) { put_page(mfn_to_page(get_mfn_from_gpfn( v->arch.hvm_vcpu.guest_cr[3] >> PAGE_SHIFT))); diff -r d8b5b02c52cf -r 08e962b8597c xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Mon Aug 13 16:47:11 2007 +0100 +++ b/xen/arch/x86/hvm/svm/svm.c Mon Aug 13 18:18:22 2007 +0100 @@ -345,14 +345,13 @@ int svm_vmcb_restore(struct vcpu *v, str vmcb->rflags = c->rflags; v->arch.hvm_vcpu.guest_cr[0] = c->cr0 | X86_CR0_ET; + v->arch.hvm_vcpu.guest_cr[2] = c->cr2; + v->arch.hvm_vcpu.guest_cr[3] = c->cr3; + v->arch.hvm_vcpu.guest_cr[4] = c->cr4; svm_update_guest_cr(v, 0); - - v->arch.hvm_vcpu.guest_cr[2] = c->cr2; svm_update_guest_cr(v, 2); - - v->arch.hvm_vcpu.guest_cr[4] = c->cr4; svm_update_guest_cr(v, 4); - + #ifdef HVM_DEBUG_SUSPEND printk("%s: cr3=0x%"PRIx64", cr0=0x%"PRIx64", cr4=0x%"PRIx64".\n", __func__, c->cr3, c->cr0, c->cr4); @@ -360,15 +359,14 @@ int svm_vmcb_restore(struct vcpu *v, str if ( hvm_paging_enabled(v) && !paging_mode_hap(v->domain) ) { - HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 c->cr3 = %"PRIx64, c->cr3); + HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 = %"PRIx64, c->cr3); mfn = gmfn_to_mfn(v->domain, c->cr3 >> PAGE_SHIFT); if( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain) ) goto bad_cr3; old_base_mfn = pagetable_get_pfn(v->arch.guest_table); v->arch.guest_table = pagetable_from_pfn(mfn); - if (old_base_mfn) + if ( old_base_mfn ) put_page(mfn_to_page(old_base_mfn)); - v->arch.hvm_vcpu.guest_cr[3] = c->cr3; } vmcb->idtr.limit = c->idtr_limit; diff -r d8b5b02c52cf -r 08e962b8597c xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Mon Aug 13 16:47:11 2007 +0100 +++ b/xen/arch/x86/hvm/vmx/vmx.c Mon Aug 13 18:18:22 2007 +0100 @@ -61,6 +61,7 @@ static int vmx_alloc_vlapic_mapping(str static int vmx_alloc_vlapic_mapping(struct domain *d); static void vmx_free_vlapic_mapping(struct domain *d); static void vmx_install_vlapic_mapping(struct vcpu *v); +static void vmx_update_guest_cr(struct vcpu *v, unsigned int cr); static void vmx_update_guest_efer(struct vcpu *v); static int vmx_domain_initialise(struct domain *d) @@ -572,50 +573,33 @@ int vmx_vmcs_restore(struct vcpu *v, str __vmwrite(GUEST_RSP, c->rsp); __vmwrite(GUEST_RFLAGS, c->rflags); - v->arch.hvm_vcpu.hw_cr[0] = (c->cr0 | X86_CR0_PE | X86_CR0_PG | - X86_CR0_NE | X86_CR0_WP | X86_CR0_ET); - __vmwrite(GUEST_CR0, v->arch.hvm_vcpu.hw_cr[0]); - v->arch.hvm_vcpu.guest_cr[0] = c->cr0; - __vmwrite(CR0_READ_SHADOW, v->arch.hvm_vcpu.guest_cr[0]); - + v->arch.hvm_vcpu.guest_cr[0] = c->cr0 | X86_CR0_ET; v->arch.hvm_vcpu.guest_cr[2] = c->cr2; - - v->arch.hvm_vcpu.guest_efer = c->msr_efer; + v->arch.hvm_vcpu.guest_cr[3] = c->cr3; + v->arch.hvm_vcpu.guest_cr[4] = c->cr4; + vmx_update_guest_cr(v, 0); + vmx_update_guest_cr(v, 2); + vmx_update_guest_cr(v, 4); #ifdef HVM_DEBUG_SUSPEND printk("%s: cr3=0x%"PRIx64", cr0=0x%"PRIx64", cr4=0x%"PRIx64".\n", __func__, c->cr3, c->cr0, c->cr4); #endif - if ( !hvm_paging_enabled(v) ) - { - HVM_DBG_LOG(DBG_LEVEL_VMMU, "%s: paging not enabled.", __func__); - goto skip_cr3; - } - - HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 = %"PRIx64, c->cr3); - /* current!=vcpu as not called by arch_vmx_do_launch */ - mfn = gmfn_to_mfn(v->domain, c->cr3 >> PAGE_SHIFT); - if ( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain) ) - { - gdprintk(XENLOG_ERR, "Invalid CR3 value=0x%"PRIx64".\n", c->cr3); - vmx_vmcs_exit(v); - return -EINVAL; - } - - old_base_mfn = pagetable_get_pfn(v->arch.guest_table); - v->arch.guest_table = pagetable_from_pfn(mfn); - if ( old_base_mfn ) - put_page(mfn_to_page(old_base_mfn)); - - skip_cr3: - v->arch.hvm_vcpu.guest_cr[3] = c->cr3; - + if ( hvm_paging_enabled(v) ) + { + HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 = %"PRIx64, c->cr3); + mfn = gmfn_to_mfn(v->domain, c->cr3 >> PAGE_SHIFT); + if ( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain) ) + goto bad_cr3; + old_base_mfn = pagetable_get_pfn(v->arch.guest_table); + v->arch.guest_table = pagetable_from_pfn(mfn); + if ( old_base_mfn ) + put_page(mfn_to_page(old_base_mfn)); + } + + v->arch.hvm_vcpu.guest_efer = c->msr_efer; vmx_update_guest_efer(v); - - __vmwrite(GUEST_CR4, (c->cr4 | HVM_CR4_HOST_MASK)); - v->arch.hvm_vcpu.guest_cr[4] = c->cr4; - __vmwrite(CR4_READ_SHADOW, v->arch.hvm_vcpu.guest_cr[4]); __vmwrite(GUEST_IDTR_LIMIT, c->idtr_limit); __vmwrite(GUEST_IDTR_BASE, c->idtr_base); @@ -696,6 +680,11 @@ int vmx_vmcs_restore(struct vcpu *v, str } return 0; + + bad_cr3: + gdprintk(XENLOG_ERR, "Invalid CR3 value=0x%"PRIx64"\n", c->cr3); + vmx_vmcs_exit(v); + return -EINVAL; } #if defined(__x86_64__) && defined(HVM_DEBUG_SUSPEND) @@ -1923,29 +1912,14 @@ static int vmx_world_restore(struct vcpu __vmwrite(GUEST_RFLAGS, c->eflags); v->arch.hvm_vcpu.guest_cr[0] = c->cr0; - __vmwrite(CR0_READ_SHADOW, v->arch.hvm_vcpu.guest_cr[0]); - - if ( !hvm_paging_enabled(v) ) - goto skip_cr3; - - if ( c->cr3 == v->arch.hvm_vcpu.guest_cr[3] ) - { - /* - * This is simple TLB flush, implying the guest has - * removed some translation or changed page attributes. - * We simply invalidate the shadow. - */ - mfn = get_mfn_from_gpfn(c->cr3 >> PAGE_SHIFT); - if ( mfn != pagetable_get_pfn(v->arch.guest_table) ) - goto bad_cr3; - } - else - { - /* - * If different, make a shadow. Check if the PDBR is valid - * first. - */ - HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 c->cr3 = %x", c->cr3); + v->arch.hvm_vcpu.guest_cr[3] = c->cr3; + v->arch.hvm_vcpu.guest_cr[4] = c->cr4; + vmx_update_guest_cr(v, 0); + vmx_update_guest_cr(v, 4); + + if ( hvm_paging_enabled(v) ) + { + HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 = %x", c->cr3); mfn = get_mfn_from_gpfn(c->cr3 >> PAGE_SHIFT); if ( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain) ) goto bad_cr3; @@ -1953,18 +1927,7 @@ static int vmx_world_restore(struct vcpu v->arch.guest_table = pagetable_from_pfn(mfn); if ( old_base_mfn ) put_page(mfn_to_page(old_base_mfn)); - v->arch.hvm_vcpu.guest_cr[3] = c->cr3; - } - - skip_cr3: - if ( !hvm_paging_enabled(v) ) - HVM_DBG_LOG(DBG_LEVEL_VMMU, "switching to vmxassist. use phys table"); - else - HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %x", c->cr3); - - __vmwrite(GUEST_CR4, (c->cr4 | HVM_CR4_HOST_MASK)); - v->arch.hvm_vcpu.guest_cr[4] = c->cr4; - __vmwrite(CR4_READ_SHADOW, v->arch.hvm_vcpu.guest_cr[4]); + } __vmwrite(GUEST_IDTR_LIMIT, c->idtr_limit); __vmwrite(GUEST_IDTR_BASE, c->idtr_base); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |