]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/x86/kernel/cpu/mtrr/main.c
x86/mtrr: Prevent CPU hotplug lock recursion
[karo-tx-linux.git] / arch / x86 / kernel / cpu / mtrr / main.c
index c5bb63be4ba1e6a2df1203fe73079faad9fc62e7..40d5a8a752125ed5d26a7605d5eabad572879bfc 100644 (file)
@@ -237,6 +237,18 @@ set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type typ
        stop_machine(mtrr_rendezvous_handler, &data, cpu_online_mask);
 }
 
+static void set_mtrr_cpuslocked(unsigned int reg, unsigned long base,
+                               unsigned long size, mtrr_type type)
+{
+       struct set_mtrr_data data = { .smp_reg = reg,
+                                     .smp_base = base,
+                                     .smp_size = size,
+                                     .smp_type = type
+                                   };
+
+       stop_machine_cpuslocked(mtrr_rendezvous_handler, &data, cpu_online_mask);
+}
+
 static void set_mtrr_from_inactive_cpu(unsigned int reg, unsigned long base,
                                      unsigned long size, mtrr_type type)
 {
@@ -370,7 +382,7 @@ int mtrr_add_page(unsigned long base, unsigned long size,
        /* Search for an empty MTRR */
        i = mtrr_if->get_free_region(base, size, replace);
        if (i >= 0) {
-               set_mtrr(i, base, size, type);
+               set_mtrr_cpuslocked(i, base, size, type);
                if (likely(replace < 0)) {
                        mtrr_usage_table[i] = 1;
                } else {
@@ -378,7 +390,7 @@ int mtrr_add_page(unsigned long base, unsigned long size,
                        if (increment)
                                mtrr_usage_table[i]++;
                        if (unlikely(replace != i)) {
-                               set_mtrr(replace, 0, 0, 0);
+                               set_mtrr_cpuslocked(replace, 0, 0, 0);
                                mtrr_usage_table[replace] = 0;
                        }
                }
@@ -506,7 +518,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
                goto out;
        }
        if (--mtrr_usage_table[reg] < 1)
-               set_mtrr(reg, 0, 0, 0);
+               set_mtrr_cpuslocked(reg, 0, 0, 0);
        error = reg;
  out:
        mutex_unlock(&mtrr_mutex);