WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] x86 svm: Clean up and fix start_svm() to

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86 svm: Clean up and fix start_svm() to avoid memory leaks and
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 19 Jun 2009 00:56:18 -0700
Delivery-date: Fri, 19 Jun 2009 01:07:20 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1245314869 -3600
# Node ID 44fe7ad6fee8229654875485ca57bb6f616045ab
# Parent  61ec78692b13bd83392f169de793b677b3b24db0
x86 svm: Clean up and fix start_svm() to avoid memory leaks and
resetting ASID generations.

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/cpu/amd.c      |    2 -
 xen/arch/x86/hvm/svm/asid.c |   12 +++++++-
 xen/arch/x86/hvm/svm/svm.c  |   61 ++++++++++++++++++++++++++++----------------
 xen/arch/x86/hvm/vmx/vmx.c  |    6 +---
 4 files changed, 54 insertions(+), 27 deletions(-)

diff -r 61ec78692b13 -r 44fe7ad6fee8 xen/arch/x86/cpu/amd.c
--- a/xen/arch/x86/cpu/amd.c    Wed Jun 17 07:39:27 2009 +0100
+++ b/xen/arch/x86/cpu/amd.c    Thu Jun 18 09:47:49 2009 +0100
@@ -12,7 +12,7 @@
 #include "cpu.h"
 #include "amd.h"
 
-int start_svm(struct cpuinfo_x86 *c);
+void start_svm(struct cpuinfo_x86 *c);
 
 /*
  * Pre-canned values for overriding the CPUID features 
diff -r 61ec78692b13 -r 44fe7ad6fee8 xen/arch/x86/hvm/svm/asid.c
--- a/xen/arch/x86/hvm/svm/asid.c       Wed Jun 17 07:39:27 2009 +0100
+++ b/xen/arch/x86/hvm/svm/asid.c       Thu Jun 18 09:47:49 2009 +0100
@@ -61,6 +61,7 @@ struct svm_asid_data {
    u32 next_asid;
    u32 max_asid;
    u32 erratum170:1;
+   u32 initialised:1;
 };
 
 static DEFINE_PER_CPU(struct svm_asid_data, svm_asid_data);
@@ -70,7 +71,7 @@ static DEFINE_PER_CPU(struct svm_asid_da
  */
 static struct svm_asid_data *svm_asid_core_data(void)
 {
-    return &get_cpu_var(svm_asid_data);
+    return &this_cpu(svm_asid_data);
 }
 
 /*
@@ -80,6 +81,15 @@ void svm_asid_init(struct cpuinfo_x86 *c
 {
     int nasids;
     struct svm_asid_data *data = svm_asid_core_data();
+
+    /*
+     * If already initialised, we just bump the generation to force a TLB
+     * flush. Resetting the generation could be dangerous, if VCPUs still
+     * exist that reference earlier generations on this CPU.
+     */
+    if ( data->initialised )
+        return svm_asid_inc_generation();
+    data->initialised = 1;
 
     /* Find #ASID. */
     nasids = cpuid_ebx(0x8000000A);
diff -r 61ec78692b13 -r 44fe7ad6fee8 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Wed Jun 17 07:39:27 2009 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c        Thu Jun 18 09:47:49 2009 +0100
@@ -839,45 +839,66 @@ static struct hvm_function_table svm_fun
     .invlpg_intercept     = svm_invlpg_intercept
 };
 
-int start_svm(struct cpuinfo_x86 *c)
-{
-    u32 eax, ecx, edx;
-    u32 phys_hsa_lo, phys_hsa_hi;   
+static int svm_cpu_up(struct cpuinfo_x86 *c)
+{
+    u32 eax, edx, 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;
-    
-    if ( !(test_bit(X86_FEATURE_SVME, &boot_cpu_data.x86_capability)) )
-        return 0;
-
     /* Check whether SVM feature is disabled in BIOS */
     rdmsr(MSR_K8_VM_CR, eax, edx);
     if ( eax & K8_VMCR_SVME_DISABLE )
     {
-        printk("AMD SVM Extension is disabled in BIOS.\n");
+        printk("CPU%d: AMD SVM Extension is disabled in BIOS.\n", cpu);
         return 0;
     }
 
-    if ( ((hsa[cpu] = alloc_host_save_area()) == NULL) ||
-         ((root_vmcb[cpu] = alloc_vmcb()) == NULL) )
+    if ( ((hsa[cpu] == NULL) &&
+          ((hsa[cpu] = alloc_host_save_area()) == NULL)) ||
+         ((root_vmcb[cpu] == NULL) &&
+          ((root_vmcb[cpu] = alloc_vmcb()) == NULL)) )
         return 0;
 
     write_efer(read_efer() | EFER_SVME);
 
     /* Initialize the HSA for this core. */
-    phys_hsa = (u64) virt_to_maddr(hsa[cpu]);
-    phys_hsa_lo = (u32) phys_hsa;
-    phys_hsa_hi = (u32) (phys_hsa >> 32);    
+    phys_hsa = (u64)virt_to_maddr(hsa[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);
 
     /* Initialize core's ASID handling. */
     svm_asid_init(c);
 
-    if ( cpu != 0 )
-        return 1;
+    return 1;
+}
+
+void start_svm(struct cpuinfo_x86 *c)
+{
+    static bool_t bootstrapped;
+
+    if ( !test_and_set_bool(bootstrapped) )
+    {
+        if ( hvm_enabled && !svm_cpu_up(c) )
+        {
+            printk("SVM: FATAL: failed to initialise CPU%d!\n",
+                   smp_processor_id());
+            BUG();
+        }
+        return;
+    }
+
+    /* Xen does not fill x86_capability words except 0. */
+    boot_cpu_data.x86_capability[5] = cpuid_ecx(0x80000001);
+
+    if ( !test_bit(X86_FEATURE_SVME, &boot_cpu_data.x86_capability) )
+        return;
+
+    if ( !svm_cpu_up(c) )
+    {
+        printk("SVM: failed to initialise.\n");
+        return;
+    }
 
     setup_vmcb_dump();
 
@@ -887,8 +908,6 @@ int start_svm(struct cpuinfo_x86 *c)
     svm_function_table.hap_supported = cpu_has_svm_npt;
 
     hvm_enable(&svm_function_table);
-
-    return 1;
 }
 
 static void svm_do_nested_pgfault(paddr_t gpa, struct cpu_user_regs *regs)
diff -r 61ec78692b13 -r 44fe7ad6fee8 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Wed Jun 17 07:39:27 2009 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Thu Jun 18 09:47:49 2009 +0100
@@ -1403,11 +1403,11 @@ static unsigned long *vpid_bitmap;
 
 void start_vmx(void)
 {
-    static int bootstrapped;
+    static bool_t bootstrapped;
 
     vmx_save_host_msrs();
 
-    if ( bootstrapped )
+    if ( !test_and_set_bool(bootstrapped) )
     {
         if ( hvm_enabled && !vmx_cpu_up() )
         {
@@ -1417,8 +1417,6 @@ void start_vmx(void)
         }
         return;
     }
-
-    bootstrapped = 1;
 
     /* Xen does not fill x86_capability words except 0. */
     boot_cpu_data.x86_capability[4] = cpuid_ecx(1);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] x86 svm: Clean up and fix start_svm() to avoid memory leaks and, Xen patchbot-unstable <=