]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - arch/ia64/mm/tlb.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
[mirror_ubuntu-bionic-kernel.git] / arch / ia64 / mm / tlb.c
index ffad7624436c84e02e62b7e38b72066bc689492f..655da240d13cf04a91f0fdcc7c846eb1d1a25d25 100644 (file)
@@ -10,6 +10,7 @@
  *              IPI based ptc implementation and A-step IPI implementation.
  * Rohit Seth <rohit.seth@intel.com>
  * Ken Chen <kenneth.w.chen@intel.com>
+ * Christophe de Dinechin <ddd@hp.com>: Avoid ptc.e on memory allocation
  */
 #include <linux/module.h>
 #include <linux/init.h>
@@ -32,9 +33,9 @@ static struct {
 } purge;
 
 struct ia64_ctx ia64_ctx = {
-       .lock =         SPIN_LOCK_UNLOCKED,
-       .next =         1,
-       .max_ctx =      ~0U
+       .lock = __SPIN_LOCK_UNLOCKED(ia64_ctx.lock),
+       .next = 1,
+       .max_ctx = ~0U
 };
 
 DEFINE_PER_CPU(u8, ia64_need_tlb_flush);
@@ -89,9 +90,16 @@ ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start,
 {
        static DEFINE_SPINLOCK(ptcg_lock);
 
-       if (mm != current->active_mm || !current->mm) {
-               flush_tlb_all();
-               return;
+       struct mm_struct *active_mm = current->active_mm;
+
+       if (mm != active_mm) {
+               /* Restore region IDs for mm */
+               if (mm && active_mm) {
+                       activate_context(mm);
+               } else {
+                       flush_tlb_all();
+                       return;
+               }
        }
 
        /* HW requires global serialization of ptc.ga.  */
@@ -107,6 +115,10 @@ ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start,
                } while (start < end);
        }
        spin_unlock(&ptcg_lock);
+
+        if (mm != active_mm) {
+                activate_context(active_mm);
+        }
 }
 
 void
@@ -175,12 +187,12 @@ EXPORT_SYMBOL(flush_tlb_range);
 void __devinit
 ia64_tlb_init (void)
 {
-       ia64_ptce_info_t ptce_info;
+       ia64_ptce_info_t uninitialized_var(ptce_info); /* GCC be quiet */
        unsigned long tr_pgbits;
        long status;
 
        if ((status = ia64_pal_vm_page_size(&tr_pgbits, &purge.mask)) != 0) {
-               printk(KERN_ERR "PAL_VM_PAGE_SIZE failed with status=%ld;"
+               printk(KERN_ERR "PAL_VM_PAGE_SIZE failed with status=%ld; "
                       "defaulting to architected purge page-sizes.\n", status);
                purge.mask = 0x115557000UL;
        }