My previous patch fixing invalidation of huge PTEs wasn't good enough, we
still had an issue if a PTE invalidation batch contained both small and
large pages.  This patch fixes this by making sure the batch is flushed if
the page size fed to it changes.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
        hpte_t *hptep;
        unsigned long hpte_v;
        struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
-       unsigned long large;
+       unsigned long large = batch->large;
 
        local_irq_save(flags);
 
 
                va = (vsid << 28) | (batch->addr[i] & 0x0fffffff);
                batch->vaddr[j] = va;
-               large = pte_huge(batch->pte[i]);
                if (large)
                        vpn = va >> HPAGE_SHIFT;
                else
                asm volatile("ptesync":::"memory");
 
                for (i = 0; i < j; i++)
-                       __tlbie(batch->vaddr[i], 0);
+                       __tlbie(batch->vaddr[i], large);
 
                asm volatile("eieio; tlbsync; ptesync":::"memory");
 
 
         * up scanning and resetting referenced bits then our batch context
         * will change mid stream.
         */
-       if (unlikely(i != 0 && context != batch->context)) {
+       if (i != 0 && (context != batch->context ||
+                      batch->large != pte_huge(pte))) {
                flush_tlb_pending();
                i = 0;
        }
        if (i == 0) {
                batch->context = context;
                batch->mm = mm;
+               batch->large = pte_huge(pte);
        }
        batch->pte[i] = __pte(pte);
        batch->addr[i] = addr;
 
        pte_t pte[PPC64_TLB_BATCH_NR];
        unsigned long addr[PPC64_TLB_BATCH_NR];
        unsigned long vaddr[PPC64_TLB_BATCH_NR];
+       unsigned int large;
 };
 DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);