[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] SVM patch to add add init intercept handler.
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID e1db72ac19292f2b79d5f4c2b09feb13e29e4194 # Parent 7b6358566d49300ec9b22d2d7537c310ce4ca0f1 SVM patch to add add init intercept handler. Signed-off-by: Tom Woller <thomas.woller@xxxxxxx> xen-unstable changeset: 9632:cff23e96eae7af54c7b4e5cae80ed1565d6f4941 xen-unstable date: Thu Apr 13 11:00:54 2006 +0100 SVM patch to add PAE support. Signed-off-by: Tom Woller <thomas.woller@xxxxxxx> xen-unstable changeset: 9633:9849bd4a86dd319d8d791e767e37e0d586459c90 xen-unstable date: Thu Apr 13 11:06:43 2006 +0100 SVM patch to init rsp properly. Signed-off-by: Tom Woller <thomas.woller@xxxxxxx> xen-unstable changeset: 9634:137b60a47d139dfaa7d202edb612bcaa1c595801 xen-unstable date: Thu Apr 13 11:07:28 2006 +0100 SVM patch to add BP exception intercept support. Signed-off-by: Tom Woller <thomas.woller@xxxxxxx> xen-unstable changeset: 9635:b77ebfaa72b200af0cdfc38dd8f7dbe274e5e386 xen-unstable date: Thu Apr 13 11:08:20 2006 +0100 SVM patch to cleanup the host save area allocation and deallocation, including removing memory leaks concerning these areas. Also fixes problem where the HSA MSR was not initialized properly for cores>0. Signed-off-by: Tom Woller <thomas.woller@xxxxxxx> xen-unstable changeset: 9922:e1a47a2696004087852cb9f2e09fe4eb8ad1b928 xen-unstable date: Thu May 4 11:14:45 2006 +0100 diff -r 7b6358566d49 -r e1db72ac1929 xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Thu May 04 10:34:27 2006 +0100 +++ b/xen/arch/x86/hvm/svm/svm.c Thu May 04 17:08:19 2006 +0100 @@ -79,6 +79,8 @@ void svm_dump_regs(const char *from, str static void svm_relinquish_guest_resources(struct domain *d); +/* Host save area */ +struct host_save_area *host_save_area[ NR_CPUS ] = {0}; static struct asid_pool ASIDpool[NR_CPUS]; /* @@ -185,11 +187,16 @@ void stop_svm(void) void stop_svm(void) { u32 eax, edx; + int cpu = smp_processor_id(); /* We turn off the EFER_SVME bit. */ rdmsr(MSR_EFER, eax, edx); eax &= ~EFER_SVME; wrmsr(MSR_EFER, eax, edx); + + /* release the HSA */ + free_host_save_area( host_save_area[ cpu ] ); + host_save_area[ cpu ] = NULL; printk("AMD SVM Extension is disabled.\n"); } @@ -315,19 +322,29 @@ static inline int long_mode_do_msr_write { case MSR_EFER: #ifdef __x86_64__ - if ((msr_content & EFER_LME) ^ test_bit(SVM_CPU_STATE_LME_ENABLED, - &vc->arch.hvm_svm.cpu_state)) + /* offending reserved bit will cause #GP */ + if ( msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE) ) { - if (test_bit(SVM_CPU_STATE_PG_ENABLED, &vc->arch.hvm_svm.cpu_state) - || !test_bit(SVM_CPU_STATE_PAE_ENABLED, - &vc->arch.hvm_svm.cpu_state)) + printk("trying to set reserved bit in EFER\n"); + svm_inject_exception(vmcb, TRAP_gp_fault, 1, 0); + return 0; + } + + /* LME: 0 -> 1 */ + if ( msr_content & EFER_LME && + !test_bit(SVM_CPU_STATE_LME_ENABLED, &vc->arch.hvm_svm.cpu_state) ) + { + if ( svm_paging_enabled(vc) || + !test_bit(SVM_CPU_STATE_PAE_ENABLED, + &vc->arch.hvm_svm.cpu_state) ) { + printk("trying to set LME bit when " + "in paging mode or PAE bit is not set\n"); svm_inject_exception(vmcb, TRAP_gp_fault, 1, 0); + return 0; } - } - - if (msr_content & EFER_LME) set_bit(SVM_CPU_STATE_LME_ENABLED, &vc->arch.hvm_svm.cpu_state); + } /* We have already recorded that we want LME, so it will be set * next time CR0 gets updated. So we clear that bit and continue. @@ -421,8 +438,11 @@ int start_svm(void) int start_svm(void) { u32 eax, ecx, edx; - - /* Xen does not fill x86_capability words except 0. */ + u32 phys_hsa_lo, phys_hsa_hi; + u64 phys_hsa; + int cpu = smp_processor_id(); + + /* Xen does not fill x86_capability words except 0. */ ecx = cpuid_ecx(0x80000001); boot_cpu_data.x86_capability[5] = ecx; @@ -433,7 +453,14 @@ int start_svm(void) eax |= EFER_SVME; wrmsr(MSR_EFER, eax, edx); asidpool_init(smp_processor_id()); - printk("AMD SVM Extension is enabled for cpu %d.\n", smp_processor_id()); + printk("AMD SVM Extension is enabled for cpu %d.\n", cpu ); + + /* Initialize the HSA for this core */ + host_save_area[ cpu ] = alloc_host_save_area(); + phys_hsa = (u64) virt_to_maddr( host_save_area[ cpu ] ); + phys_hsa_lo = (u32) phys_hsa; + phys_hsa_hi = (u32) (phys_hsa >> 32); + wrmsr(MSR_K8_VM_HSAVE_PA, phys_hsa_lo, phys_hsa_hi); /* Setup HVM interfaces */ hvm_funcs.disable = stop_svm; @@ -536,20 +563,6 @@ void save_svm_cpu_user_regs(struct vcpu ctxt->ds = vmcb->ds.sel; } -#if defined (__x86_64__) -void svm_store_cpu_user_regs(struct cpu_user_regs *regs, struct vcpu *v ) -{ - struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; - - regs->rip = vmcb->rip; - regs->rsp = vmcb->rsp; - regs->rflags = vmcb->rflags; - regs->cs = vmcb->cs.sel; - regs->ds = vmcb->ds.sel; - regs->es = vmcb->es.sel; - regs->ss = vmcb->ss.sel; -} -#elif defined (__i386__) void svm_store_cpu_user_regs(struct cpu_user_regs *regs, struct vcpu *v) { struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; @@ -561,11 +574,11 @@ void svm_store_cpu_user_regs(struct cpu_ regs->ds = vmcb->ds.sel; regs->es = vmcb->es.sel; regs->ss = vmcb->ss.sel; -} -#endif + regs->fs = vmcb->fs.sel; + regs->gs = vmcb->gs.sel; +} /* XXX Use svm_load_cpu_guest_regs instead */ -#if defined (__i386__) void svm_load_cpu_user_regs(struct vcpu *v, struct cpu_user_regs *regs) { struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; @@ -578,30 +591,17 @@ void svm_load_cpu_user_regs(struct vcpu vmcb->rflags = regs->eflags; vmcb->cs.sel = regs->cs; vmcb->rip = regs->eip; + + vmcb->ds.sel = regs->ds; + vmcb->es.sel = regs->es; + vmcb->fs.sel = regs->fs; + vmcb->gs.sel = regs->gs; + if (regs->eflags & EF_TF) *intercepts |= EXCEPTION_BITMAP_DB; else *intercepts &= ~EXCEPTION_BITMAP_DB; } -#else /* (__i386__) */ -void svm_load_cpu_user_regs(struct vcpu *v, struct cpu_user_regs *regs) -{ - struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; - u32 *intercepts = &v->arch.hvm_svm.vmcb->exception_intercepts; - - /* Write the guest register value into VMCB */ - vmcb->rax = regs->rax; - vmcb->ss.sel = regs->ss; - vmcb->rsp = regs->rsp; - vmcb->rflags = regs->rflags; - vmcb->cs.sel = regs->cs; - vmcb->rip = regs->rip; - if (regs->rflags & EF_TF) - *intercepts |= EXCEPTION_BITMAP_DB; - else - *intercepts &= ~EXCEPTION_BITMAP_DB; -} -#endif /* !(__i386__) */ int svm_paging_enabled(struct vcpu *v) { @@ -724,10 +724,6 @@ static void svm_relinquish_guest_resourc { if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) ) continue; -#if 0 - /* Memory leak by not freeing this. XXXKAF: *Why* is not per core?? */ - free_host_save_area(v->arch.hvm_svm.host_save_area); -#endif destroy_vmcb(&v->arch.hvm_svm); free_monitor_pagetable(v); @@ -757,7 +753,8 @@ void arch_svm_do_resume(struct vcpu *v) reset_stack_and_jump( svm_asm_do_resume ); } else { - printk("VCPU core pinned: %d to %d\n", v->arch.hvm_svm.launch_core, smp_processor_id() ); + printk("VCPU core pinned: %d to %d\n", + v->arch.hvm_svm.launch_core, smp_processor_id() ); v->arch.hvm_svm.launch_core = smp_processor_id(); svm_migrate_timers( v ); svm_do_resume( v ); @@ -928,6 +925,7 @@ static void svm_vmexit_do_cpuid(struct v } #if CONFIG_PAGING_LEVELS < 3 + clear_bit(X86_FEATURE_NX, &edx); clear_bit(X86_FEATURE_PAE, &edx); clear_bit(X86_FEATURE_PSE, &edx); clear_bit(X86_FEATURE_PSE36, &edx); @@ -935,12 +933,14 @@ static void svm_vmexit_do_cpuid(struct v if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 ) { if ( !v->domain->arch.hvm_domain.pae_enabled ) - clear_bit(X86_FEATURE_PAE, &edx); + { + clear_bit(X86_FEATURE_PAE, &edx); + clear_bit(X86_FEATURE_NX, &edx); + } clear_bit(X86_FEATURE_PSE, &edx); clear_bit(X86_FEATURE_PSE36, &edx); } -#endif - +#endif /* Clear out reserved bits. */ ecx &= ~SVM_VCPU_CPUID_L1_RESERVED; /* mask off reserved bits */ clear_bit(X86_FEATURE_MWAIT & 31, &ecx); @@ -1318,8 +1318,7 @@ static int svm_set_cr0(unsigned long val unsigned long mfn; int paging_enabled; struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; - unsigned long crn; - + ASSERT(vmcb); /* We don't want to lose PG. ET is reserved and should be always be 1*/ @@ -1364,35 +1363,37 @@ static int svm_set_cr0(unsigned long val set_bit(SVM_CPU_STATE_LMA_ENABLED, &v->arch.hvm_svm.cpu_state); vmcb->efer |= (EFER_LMA | EFER_LME); - -#if CONFIG_PAGING_LEVELS >= 4 - if (!shadow_set_guest_paging_levels(v->domain, 4)) + if (!shadow_set_guest_paging_levels(v->domain, PAGING_L4) ) { printk("Unsupported guest paging levels\n"); domain_crash_synchronous(); /* need to take a clean path */ } -#endif } else #endif /* __x86_64__ */ { #if CONFIG_PAGING_LEVELS >= 3 - if (!shadow_set_guest_paging_levels(v->domain, 2)) + /* seems it's a 32-bit or 32-bit PAE guest */ + if ( test_bit(SVM_CPU_STATE_PAE_ENABLED, + &v->arch.hvm_svm.cpu_state) ) { - printk("Unsupported guest paging levels\n"); - domain_crash_synchronous(); /* need to take a clean path */ + /* The guest enables PAE first and then it enables PG, it is + * really a PAE guest */ + if ( !shadow_set_guest_paging_levels(v->domain, PAGING_L3) ) + { + printk("Unsupported guest paging levels\n"); + domain_crash_synchronous(); + } + } + else + { + if ( !shadow_set_guest_paging_levels(v->domain, PAGING_L2) ) + { + printk("Unsupported guest paging levels\n"); + domain_crash_synchronous(); /* need to take a clean path */ + } } #endif - } - - /* update CR4's PAE if needed */ - crn = vmcb->cr4; - if ((!(crn & X86_CR4_PAE)) - && test_bit(SVM_CPU_STATE_PAE_ENABLED, - &v->arch.hvm_svm.cpu_state)) - { - HVM_DBG_LOG(DBG_LEVEL_1, "enable PAE on cr4\n"); - vmcb->cr4 |= X86_CR4_PAE; } /* Now arch.guest_table points to machine physical. */ @@ -1408,7 +1409,16 @@ static int svm_set_cr0(unsigned long val /* arch->shadow_table should hold the next CR3 for shadow */ HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx, mfn = %lx\n", v->arch.hvm_svm.cpu_cr3, mfn); - } + + return 1; + } + + if ( !((value & X86_CR0_PE) && (value & X86_CR0_PG)) && paging_enabled ) + if ( v->arch.hvm_svm.cpu_cr3 ) { + put_page(mfn_to_page(get_mfn_from_gpfn( + v->arch.hvm_svm.cpu_cr3 >> PAGE_SHIFT))); + v->arch.guest_table = mk_pagetable(0); + } /* * SVM implements paged real-mode and when we return to real-mode @@ -1421,6 +1431,14 @@ static int svm_set_cr0(unsigned long val return 0; } + clear_all_shadow_status( v->domain ); + set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags); + vmcb->cr3 = pagetable_get_paddr(v->domain->arch.phys_table); + } + else if ( (value & (X86_CR0_PE | X86_CR0_PG)) == X86_CR0_PE ) + { + /* we should take care of this kind of situation */ + clear_all_shadow_status(v->domain); set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags); vmcb->cr3 = pagetable_get_paddr(v->domain->arch.phys_table); } @@ -1444,15 +1462,21 @@ static void mov_from_cr(int cr, int gp, { case 0: value = v->arch.hvm_svm.cpu_shadow_cr0; - break; + if (svm_dbg_on) + printk("CR0 read =%lx \n", value ); + break; case 2: value = vmcb->cr2; break; case 3: value = (unsigned long) v->arch.hvm_svm.cpu_cr3; - break; + if (svm_dbg_on) + printk("CR3 read =%lx \n", value ); + break; case 4: value = (unsigned long) v->arch.hvm_svm.cpu_shadow_cr4; + if (svm_dbg_on) + printk( "CR4 read=%lx\n", value ); break; case 8: #if 0 @@ -1472,6 +1496,12 @@ static void mov_from_cr(int cr, int gp, } +static inline int svm_pgbit_test(struct vcpu *v) +{ + return v->arch.hvm_svm.cpu_shadow_cr0 & X86_CR0_PG; +} + + /* * Write to control registers */ @@ -1492,12 +1522,15 @@ static int mov_to_cr(int gpreg, int cr, switch (cr) { case 0: + if (svm_dbg_on) + printk("CR0 write =%lx \n", value ); return svm_set_cr0(value); case 3: { unsigned long old_base_mfn, mfn; - + if (svm_dbg_on) + printk("CR3 write =%lx \n", value ); /* If paging is not enabled yet, simply copy the value to CR3. */ if (!svm_paging_enabled(v)) { v->arch.hvm_svm.cpu_cr3 = value; @@ -1539,19 +1572,104 @@ static int mov_to_cr(int gpreg, int cr, if (old_base_mfn) put_page(mfn_to_page(old_base_mfn)); + /* + * arch.shadow_table should now hold the next CR3 for shadow + */ +#if CONFIG_PAGING_LEVELS >= 3 + if ( v->domain->arch.ops->guest_paging_levels == PAGING_L3 ) + shadow_sync_all(v->domain); +#endif + v->arch.hvm_svm.cpu_cr3 = value; update_pagetables(v); - - /* arch.shadow_table should now hold the next CR3 for shadow*/ - v->arch.hvm_svm.cpu_cr3 = value; HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx", value); vmcb->cr3 = pagetable_get_paddr(v->arch.shadow_table); } break; } - case 4: - /* CR4 */ - if (value & X86_CR4_PAE) { + case 4: /* CR4 */ + { + if (svm_dbg_on) + printk( "write cr4=%lx, cr0=%lx\n", + value, v->arch.hvm_svm.cpu_shadow_cr0 ); + old_cr = v->arch.hvm_svm.cpu_shadow_cr4; + if ( value & X86_CR4_PAE && !(old_cr & X86_CR4_PAE) ) + { + set_bit(SVM_CPU_STATE_PAE_ENABLED, &v->arch.hvm_svm.cpu_state); + if ( svm_pgbit_test(v) ) + { + /* The guest is a 32-bit PAE guest. */ +#if CONFIG_PAGING_LEVELS >= 4 + unsigned long mfn, old_base_mfn; + + if( !shadow_set_guest_paging_levels(v->domain, PAGING_L3) ) + { + printk("Unsupported guest paging levels\n"); + domain_crash_synchronous(); /* need to take a clean path */ + } + + if ( !VALID_MFN(mfn = get_mfn_from_gpfn( + v->arch.hvm_svm.cpu_cr3 >> PAGE_SHIFT)) || + !get_page(mfn_to_page(mfn), v->domain) ) + { + printk("Invalid CR3 value = %lx", v->arch.hvm_svm.cpu_cr3); + domain_crash_synchronous(); /* need to take a clean path */ + } + + old_base_mfn = pagetable_get_pfn(v->arch.guest_table); + if ( old_base_mfn ) + put_page(mfn_to_page(old_base_mfn)); + + /* + * Now arch.guest_table points to machine physical. + */ + + v->arch.guest_table = mk_pagetable((u64)mfn << PAGE_SHIFT); + update_pagetables(v); + + HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx", + (unsigned long) (mfn << PAGE_SHIFT)); + + vmcb->cr3 = pagetable_get_paddr(v->arch.shadow_table); + + /* + * arch->shadow_table should hold the next CR3 for shadow + */ + + HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx, mfn = %lx", + v->arch.hvm_svm.cpu_cr3, mfn); +#endif + } + else + { + /* The guest is a 64 bit or 32-bit PAE guest. */ +#if CONFIG_PAGING_LEVELS >= 4 + if ( (v->domain->arch.ops != NULL) && + v->domain->arch.ops->guest_paging_levels == PAGING_L2) + { + /* Seems the guest first enables PAE without enabling PG, + * it must enable PG after that, and it is a 32-bit PAE + * guest */ + + if ( !shadow_set_guest_paging_levels(v->domain, PAGING_L3) ) + { + printk("Unsupported guest paging levels\n"); + domain_crash_synchronous(); + } + } + else + { + if ( !shadow_set_guest_paging_levels(v->domain, + PAGING_L4) ) + { + printk("Unsupported guest paging levels\n"); + domain_crash_synchronous(); + } + } +#endif + } + } + else if (value & X86_CR4_PAE) { set_bit(SVM_CPU_STATE_PAE_ENABLED, &v->arch.hvm_svm.cpu_state); } else { if (test_bit(SVM_CPU_STATE_LMA_ENABLED, @@ -1561,7 +1679,6 @@ static int mov_to_cr(int gpreg, int cr, clear_bit(SVM_CPU_STATE_PAE_ENABLED, &v->arch.hvm_svm.cpu_state); } - old_cr = v->arch.hvm_svm.cpu_shadow_cr4; v->arch.hvm_svm.cpu_shadow_cr4 = value; vmcb->cr4 = value | SVM_CR4_HOST_MASK; @@ -1575,6 +1692,7 @@ static int mov_to_cr(int gpreg, int cr, shadow_sync_all(v->domain); } break; + } default: printk("invalid cr: %d\n", cr); @@ -1939,6 +2057,7 @@ static int svm_do_vmmcall_reset_to_realm vmcb->cr4 = SVM_CR4_HOST_MASK; v->arch.hvm_svm.cpu_shadow_cr4 = 0; + clear_bit(SVM_CPU_STATE_PAE_ENABLED, &v->arch.hvm_svm.cpu_state); /* This will jump to ROMBIOS */ vmcb->rip = 0xFFF0; @@ -1995,6 +2114,7 @@ static int svm_do_vmmcall_reset_to_realm vmcb->idtr.base = 0x00; vmcb->rax = 0; + vmcb->rsp = 0; return 0; } @@ -2286,7 +2406,8 @@ void walk_shadow_and_guest_pt(unsigned l gpte.l1 = 0; __copy_from_user(&gpte, &linear_pg_table[ l1_linear_offset(gva) ], sizeof(gpte) ); printk( "G-PTE = %x, flags=%x\n", gpte.l1, l1e_get_flags(gpte) ); - __copy_from_user( &spte, &phys_to_machine_mapping[ l1e_get_pfn( gpte ) ], sizeof(spte) ); + __copy_from_user( &spte, &phys_to_machine_mapping[ l1e_get_pfn( gpte ) ], + sizeof(spte) ); printk( "S-PTE = %x, flags=%x\n", spte.l1, l1e_get_flags(spte)); } #endif /* SVM_WALK_GUEST_PAGES */ @@ -2319,6 +2440,17 @@ asmlinkage void svm_vmexit_handler(struc if (svm_dbg_on && exit_reason == VMEXIT_EXCEPTION_PF) { if (svm_paging_enabled(v) && !mmio_space(gva_to_gpa(vmcb->exitinfo2))) + { + printk("I%08ld,ExC=%s(%d),IP=%x:%llx,I1=%llx,I2=%llx,INT=%llx, gpa=%llx\n", + intercepts_counter, + exit_reasons[exit_reason], exit_reason, regs.cs, + (unsigned long long) regs.rip, + (unsigned long long) vmcb->exitinfo1, + (unsigned long long) vmcb->exitinfo2, + (unsigned long long) vmcb->exitintinfo.bytes, + (unsigned long long) gva_to_gpa( vmcb->exitinfo2 ) ); + } + else { printk("I%08ld,ExC=%s(%d),IP=%x:%llx,I1=%llx,I2=%llx,INT=%llx\n", intercepts_counter, @@ -2326,12 +2458,12 @@ asmlinkage void svm_vmexit_handler(struc (unsigned long long) regs.rip, (unsigned long long) vmcb->exitinfo1, (unsigned long long) vmcb->exitinfo2, - (unsigned long long) vmcb->exitintinfo.bytes); + (unsigned long long) vmcb->exitintinfo.bytes ); } } - else if (svm_dbg_on - && exit_reason != VMEXIT_IOIO - && exit_reason != VMEXIT_INTR) + else if ( svm_dbg_on + && exit_reason != VMEXIT_IOIO + && exit_reason != VMEXIT_INTR) { if (exit_reasons[exit_reason]) @@ -2356,7 +2488,9 @@ asmlinkage void svm_vmexit_handler(struc } #ifdef SVM_WALK_GUEST_PAGES - if( exit_reason == VMEXIT_EXCEPTION_PF && ( ( vmcb->exitinfo2 == vmcb->rip )|| vmcb->exitintinfo.bytes) ) + if( exit_reason == VMEXIT_EXCEPTION_PF + && ( ( vmcb->exitinfo2 == vmcb->rip ) + || vmcb->exitintinfo.bytes) ) { if (svm_paging_enabled(v) && !mmio_space(gva_to_gpa(vmcb->exitinfo2))) walk_shadow_and_guest_pt( vmcb->exitinfo2 ); @@ -2440,13 +2574,24 @@ asmlinkage void svm_vmexit_handler(struc */ break; + case VMEXIT_INIT: + /* + * Nothing to do, in fact we should never get to this point. + */ + break; + + case VMEXIT_EXCEPTION_BP: #ifdef XEN_DEBUGGER - case VMEXIT_EXCEPTION_BP: svm_debug_save_cpu_user_regs(®s); pdb_handle_exception(3, ®s, 1); svm_debug_restore_cpu_user_regs(®s); - break; +#else + if ( test_bit(_DOMF_debugging, &v->domain->domain_flags) ) + domain_pause_for_debugger(); + else + svm_inject_exception(vmcb, TRAP_int3, 0, 0); #endif + break; case VMEXIT_EXCEPTION_NM: svm_do_no_device_fault(vmcb); diff -r 7b6358566d49 -r e1db72ac1929 xen/arch/x86/hvm/svm/vmcb.c --- a/xen/arch/x86/hvm/svm/vmcb.c Thu May 04 10:34:27 2006 +0100 +++ b/xen/arch/x86/hvm/svm/vmcb.c Thu May 04 17:08:19 2006 +0100 @@ -36,9 +36,11 @@ #include <xen/kernel.h> #include <xen/domain_page.h> +extern struct host_save_area *host_save_area[]; extern int svm_dbg_on; extern int asidpool_assign_next( struct vmcb_struct *vmcb, int retire_current, int oldcore, int newcore); +extern void set_hsa_to_guest( struct arch_svm_struct *arch_svm ); #define round_pgdown(_p) ((_p)&PAGE_MASK) /* coped from domain.c */ @@ -257,7 +259,8 @@ static int construct_init_vmcb_guest(str /* CR3 is set in svm_final_setup_guest */ __asm__ __volatile__ ("mov %%cr4,%0" : "=r" (crn) :); - arch_svm->cpu_shadow_cr4 = crn & ~(X86_CR4_PGE | X86_CR4_PSE); + crn &= ~(X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE); + arch_svm->cpu_shadow_cr4 = crn; vmcb->cr4 = crn | SVM_CR4_HOST_MASK; vmcb->rsp = 0; @@ -308,8 +311,6 @@ int construct_vmcb(struct arch_svm_struc { int error; long rc=0; - struct host_save_area *hsa = NULL; - u64 phys_hsa; memset(arch_svm, 0, sizeof(struct arch_svm_struct)); @@ -319,36 +320,9 @@ int construct_vmcb(struct arch_svm_struc goto err_out; } - /* - * The following code is for allocating host_save_area. - * Note: We either allocate a Host Save Area per core or per VCPU. - * However, we do not want a global data structure - * for HSA per core, we decided to implement a HSA for each VCPU. - * It will waste space since VCPU number is larger than core number. - * But before we find a better place for HSA for each core, we will - * stay will this solution. - */ - - if (!(hsa = alloc_host_save_area())) - { - printk("Failed to allocate Host Save Area\n"); - rc = -ENOMEM; - goto err_out; - } - - phys_hsa = (u64) virt_to_maddr(hsa); - arch_svm->host_save_area = hsa; - arch_svm->host_save_pa = phys_hsa; - + /* update the HSA for the current Core */ + set_hsa_to_guest( arch_svm ); arch_svm->vmcb_pa = (u64) virt_to_maddr(arch_svm->vmcb); - - if ((error = load_vmcb(arch_svm, arch_svm->host_save_pa))) - { - printk("construct_vmcb: load_vmcb failed: VMCB = %lx\n", - (unsigned long) arch_svm->host_save_pa); - rc = -EINVAL; - goto err_out; - } if ((error = construct_vmcb_controls(arch_svm))) { @@ -457,18 +431,11 @@ void svm_do_launch(struct vcpu *v) } -int load_vmcb(struct arch_svm_struct *arch_svm, u64 phys_hsa) -{ - u32 phys_hsa_lo, phys_hsa_hi; - - phys_hsa_lo = (u32) phys_hsa; - phys_hsa_hi = (u32) (phys_hsa >> 32); - - wrmsr(MSR_K8_VM_HSAVE_PA, phys_hsa_lo, phys_hsa_hi); - set_bit(ARCH_SVM_VMCB_LOADED, &arch_svm->flags); - return 0; -} - +void set_hsa_to_guest( struct arch_svm_struct *arch_svm ) +{ + arch_svm->host_save_area = host_save_area[ smp_processor_id() ]; + arch_svm->host_save_pa = (u64)virt_to_maddr( arch_svm->host_save_area ); +} /* * Resume the guest. @@ -479,6 +446,9 @@ void svm_do_resume(struct vcpu *v) struct hvm_virpit *vpit = &d->arch.hvm_domain.vpit; svm_stts(v); + + /* make sure the HSA is set for the current core */ + set_hsa_to_guest( &v->arch.hvm_svm ); /* pick up the elapsed PIT ticks and re-enable pit_timer */ if ( vpit->first_injected ) { _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |