[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86 hvm: Pre-allocate per-cpu HVM memory before bringing CPUs online
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1263810936 0 # Node ID 508f457aa439b1d388144f9fedfb773c5e3ff6e1 # Parent 7a8cee80597eb374409fe2f320e740ef9ef051ce x86 hvm: Pre-allocate per-cpu HVM memory before bringing CPUs online after boot. Avoids doing the allocations on the CPU itself, while in a not-fully-online state and with irqs disabled. This way we avoid assertions about irqs being disabled in e.g., tlb flush logic. Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/arch/x86/hvm/svm/svm.c | 16 ++++++++++++---- xen/arch/x86/hvm/vmx/vmcs.c | 24 +++++++++++++++--------- xen/arch/x86/hvm/vmx/vmx.c | 1 + xen/arch/x86/smpboot.c | 6 +++++- xen/include/asm-x86/hvm/hvm.h | 11 ++++++++--- xen/include/asm-x86/hvm/vmx/vmcs.h | 1 + 6 files changed, 42 insertions(+), 17 deletions(-) diff -r 7a8cee80597e -r 508f457aa439 xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Sun Jan 17 18:20:04 2010 +0000 +++ b/xen/arch/x86/hvm/svm/svm.c Mon Jan 18 10:35:36 2010 +0000 @@ -809,6 +809,16 @@ static int svm_do_pmu_interrupt(struct c return 0; } +static int svm_cpu_prepare(unsigned int cpu) +{ + if ( ((hsa[cpu] == NULL) && + ((hsa[cpu] = alloc_host_save_area()) == NULL)) || + ((root_vmcb[cpu] == NULL) && + ((root_vmcb[cpu] = alloc_vmcb()) == NULL)) ) + return -ENOMEM; + return 0; +} + static int svm_cpu_up(struct cpuinfo_x86 *c) { u32 eax, edx, phys_hsa_lo, phys_hsa_hi; @@ -823,10 +833,7 @@ static int svm_cpu_up(struct cpuinfo_x86 return 0; } - if ( ((hsa[cpu] == NULL) && - ((hsa[cpu] = alloc_host_save_area()) == NULL)) || - ((root_vmcb[cpu] == NULL) && - ((root_vmcb[cpu] = alloc_vmcb()) == NULL)) ) + if ( svm_cpu_prepare(cpu) != 0 ) return 0; write_efer(read_efer() | EFER_SVME); @@ -1231,6 +1238,7 @@ static void svm_invlpg_intercept(unsigne static struct hvm_function_table __read_mostly svm_function_table = { .name = "SVM", + .cpu_prepare = svm_cpu_prepare, .cpu_down = svm_cpu_down, .domain_initialise = svm_domain_initialise, .domain_destroy = svm_domain_destroy, diff -r 7a8cee80597e -r 508f457aa439 xen/arch/x86/hvm/vmx/vmcs.c --- a/xen/arch/x86/hvm/vmx/vmcs.c Sun Jan 17 18:20:04 2010 +0000 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Mon Jan 18 10:35:36 2010 +0000 @@ -320,6 +320,19 @@ static void vmx_load_vmcs(struct vcpu *v local_irq_restore(flags); } +int vmx_cpu_prepare(unsigned int cpu) +{ + if ( per_cpu(host_vmcs, cpu) != NULL ) + return 0; + + per_cpu(host_vmcs, cpu) = vmx_alloc_vmcs(); + if ( per_cpu(host_vmcs, cpu) != NULL ) + return 0; + + printk("CPU%d: Could not allocate host VMCS\n", cpu); + return -ENOMEM; +} + int vmx_cpu_up(void) { u32 eax, edx; @@ -367,15 +380,8 @@ int vmx_cpu_up(void) INIT_LIST_HEAD(&this_cpu(active_vmcs_list)); - if ( this_cpu(host_vmcs) == NULL ) - { - this_cpu(host_vmcs) = vmx_alloc_vmcs(); - if ( this_cpu(host_vmcs) == NULL ) - { - printk("CPU%d: Could not allocate host VMCS\n", cpu); - return 0; - } - } + if ( vmx_cpu_prepare(cpu) != 0 ) + return 0; switch ( __vmxon(virt_to_maddr(this_cpu(host_vmcs))) ) { diff -r 7a8cee80597e -r 508f457aa439 xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Sun Jan 17 18:20:04 2010 +0000 +++ b/xen/arch/x86/hvm/vmx/vmx.c Mon Jan 18 10:35:36 2010 +0000 @@ -1377,6 +1377,7 @@ static void vmx_set_info_guest(struct vc static struct hvm_function_table __read_mostly vmx_function_table = { .name = "VMX", + .cpu_prepare = vmx_cpu_prepare, .domain_initialise = vmx_domain_initialise, .domain_destroy = vmx_domain_destroy, .vcpu_initialise = vmx_vcpu_initialise, diff -r 7a8cee80597e -r 508f457aa439 xen/arch/x86/smpboot.c --- a/xen/arch/x86/smpboot.c Sun Jan 17 18:20:04 2010 +0000 +++ b/xen/arch/x86/smpboot.c Mon Jan 18 10:35:36 2010 +0000 @@ -1518,7 +1518,11 @@ int cpu_add(uint32_t apic_id, uint32_t a int __devinit __cpu_up(unsigned int cpu) { - int ret = 0; + int ret; + + ret = hvm_cpu_prepare(cpu); + if (ret) + return ret; /* * We do warm boot only on cpus that had booted earlier diff -r 7a8cee80597e -r 508f457aa439 xen/include/asm-x86/hvm/hvm.h --- a/xen/include/asm-x86/hvm/hvm.h Sun Jan 17 18:20:04 2010 +0000 +++ b/xen/include/asm-x86/hvm/hvm.h Mon Jan 18 10:35:36 2010 +0000 @@ -111,6 +111,7 @@ struct hvm_function_table { int (*event_pending)(struct vcpu *v); int (*do_pmu_interrupt)(struct cpu_user_regs *regs); + int (*cpu_prepare)(unsigned int cpu); int (*cpu_up)(void); void (*cpu_down)(void); @@ -290,11 +291,15 @@ void hvm_set_rdtsc_exiting(struct domain void hvm_set_rdtsc_exiting(struct domain *d, bool_t enable); int hvm_gtsc_need_scale(struct domain *d); +static inline int +hvm_cpu_prepare(unsigned int cpu) +{ + return (hvm_funcs.cpu_prepare ? hvm_funcs.cpu_prepare(cpu) : 0); +} + static inline int hvm_cpu_up(void) { - if ( hvm_funcs.cpu_up ) - return hvm_funcs.cpu_up(); - return 1; + return (hvm_funcs.cpu_up ? hvm_funcs.cpu_up() : 1); } static inline void hvm_cpu_down(void) diff -r 7a8cee80597e -r 508f457aa439 xen/include/asm-x86/hvm/vmx/vmcs.h --- a/xen/include/asm-x86/hvm/vmx/vmcs.h Sun Jan 17 18:20:04 2010 +0000 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h Mon Jan 18 10:35:36 2010 +0000 @@ -26,6 +26,7 @@ extern void start_vmx(void); extern void start_vmx(void); extern void vmcs_dump_vcpu(struct vcpu *v); extern void setup_vmcs_dump(void); +extern int vmx_cpu_prepare(unsigned int cpu); extern int vmx_cpu_up(void); extern void vmx_cpu_down(void); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |