VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / arch / ppc64 / mm / hugetlbpage.c
1 /*
2  * PPC64 (POWER4) Huge TLB Page Support for Kernel.
3  *
4  * Copyright (C) 2003 David Gibson, IBM Corporation.
5  *
6  * Based on the IA-32 version:
7  * Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com>
8  */
9
10 #include <linux/init.h>
11 #include <linux/fs.h>
12 #include <linux/mm.h>
13 #include <linux/hugetlb.h>
14 #include <linux/pagemap.h>
15 #include <linux/smp_lock.h>
16 #include <linux/slab.h>
17 #include <linux/err.h>
18 #include <linux/sysctl.h>
19 #include <asm/mman.h>
20 #include <asm/pgalloc.h>
21 #include <asm/tlb.h>
22 #include <asm/tlbflush.h>
23 #include <asm/mmu_context.h>
24 #include <asm/machdep.h>
25 #include <asm/cputable.h>
26 #include <asm/tlb.h>
27
28 #include <linux/sysctl.h>
29
30 /* HugePTE layout:
31  *
32  * 31 30 ... 15 14 13 12 10 9  8  7   6    5    4    3    2    1    0
33  * PFN>>12..... -  -  -  -  -  -  HASH_IX....   2ND  HASH RW   -    HG=1
34  */
35
36 #define HUGEPTE_SHIFT   15
37 #define _HUGEPAGE_PFN           0xffff8000
38 #define _HUGEPAGE_BAD           0x00007f00
39 #define _HUGEPAGE_HASHPTE       0x00000008
40 #define _HUGEPAGE_SECONDARY     0x00000010
41 #define _HUGEPAGE_GROUP_IX      0x000000e0
42 #define _HUGEPAGE_HPTEFLAGS     (_HUGEPAGE_HASHPTE | _HUGEPAGE_SECONDARY | \
43                                  _HUGEPAGE_GROUP_IX)
44 #define _HUGEPAGE_RW            0x00000004
45
46 typedef struct {unsigned int val;} hugepte_t;
47 #define hugepte_val(hugepte)    ((hugepte).val)
48 #define __hugepte(x)            ((hugepte_t) { (x) } )
49 #define hugepte_pfn(x)          \
50         ((unsigned long)(hugepte_val(x)>>HUGEPTE_SHIFT) << HUGETLB_PAGE_ORDER)
51 #define mk_hugepte(page,wr)     __hugepte( \
52         ((page_to_pfn(page)>>HUGETLB_PAGE_ORDER) << HUGEPTE_SHIFT ) \
53         | (!!(wr) * _HUGEPAGE_RW) | _PMD_HUGEPAGE )
54
55 #define hugepte_bad(x)  ( !(hugepte_val(x) & _PMD_HUGEPAGE) || \
56                           (hugepte_val(x) & _HUGEPAGE_BAD) )
57 #define hugepte_page(x) pfn_to_page(hugepte_pfn(x))
58 #define hugepte_none(x) (!(hugepte_val(x) & _HUGEPAGE_PFN))
59
60
61 static void flush_hash_hugepage(mm_context_t context, unsigned long ea,
62                                 hugepte_t pte, int local);
63
64 static inline unsigned int hugepte_update(hugepte_t *p, unsigned int clr,
65                                           unsigned int set)
66 {
67         unsigned int old, tmp;
68
69         __asm__ __volatile__(
70         "1:     lwarx   %0,0,%3         # pte_update\n\
71         andc    %1,%0,%4 \n\
72         or      %1,%1,%5 \n\
73         stwcx.  %1,0,%3 \n\
74         bne-    1b"
75         : "=&r" (old), "=&r" (tmp), "=m" (*p)
76         : "r" (p), "r" (clr), "r" (set), "m" (*p)
77         : "cc" );
78         return old;
79 }
80
81 static inline void set_hugepte(hugepte_t *ptep, hugepte_t pte)
82 {
83         hugepte_update(ptep, ~_HUGEPAGE_HPTEFLAGS,
84                        hugepte_val(pte) & ~_HUGEPAGE_HPTEFLAGS);
85 }
86
87 static hugepte_t *hugepte_alloc(struct mm_struct *mm, unsigned long addr)
88 {
89         pgd_t *pgd;
90         pmd_t *pmd = NULL;
91
92         BUG_ON(!in_hugepage_area(mm->context, addr));
93
94         pgd = pgd_offset(mm, addr);
95         pmd = pmd_alloc(mm, pgd, addr);
96
97         /* We shouldn't find a (normal) PTE page pointer here */
98         BUG_ON(!pmd_none(*pmd) && !pmd_hugepage(*pmd));
99         
100         return (hugepte_t *)pmd;
101 }
102
103 static hugepte_t *hugepte_offset(struct mm_struct *mm, unsigned long addr)
104 {
105         pgd_t *pgd;
106         pmd_t *pmd = NULL;
107
108         BUG_ON(!in_hugepage_area(mm->context, addr));
109
110         pgd = pgd_offset(mm, addr);
111         if (pgd_none(*pgd))
112                 return NULL;
113
114         pmd = pmd_offset(pgd, addr);
115
116         /* We shouldn't find a (normal) PTE page pointer here */
117         BUG_ON(!pmd_none(*pmd) && !pmd_hugepage(*pmd));
118
119         return (hugepte_t *)pmd;
120 }
121
122 static void setup_huge_pte(struct mm_struct *mm, struct page *page,
123                            hugepte_t *ptep, int write_access)
124 {
125         hugepte_t entry;
126         int i;
127
128         // mm->rss += (HPAGE_SIZE / PAGE_SIZE);
129         vx_rsspages_sub(mm, HPAGE_SIZE / PAGE_SIZE);
130         entry = mk_hugepte(page, write_access);
131         for (i = 0; i < HUGEPTE_BATCH_SIZE; i++)
132                 set_hugepte(ptep+i, entry);
133 }
134
135 static void teardown_huge_pte(hugepte_t *ptep)
136 {
137         int i;
138
139         for (i = 0; i < HUGEPTE_BATCH_SIZE; i++)
140                 pmd_clear((pmd_t *)(ptep+i));
141 }
142
143 /*
144  * This function checks for proper alignment of input addr and len parameters.
145  */
146 int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
147 {
148         if (len & ~HPAGE_MASK)
149                 return -EINVAL;
150         if (addr & ~HPAGE_MASK)
151                 return -EINVAL;
152         if (! (within_hugepage_low_range(addr, len)
153                || within_hugepage_high_range(addr, len)) )
154                 return -EINVAL;
155         return 0;
156 }
157
158 static void flush_segments(void *parm)
159 {
160         u16 segs = (unsigned long) parm;
161         unsigned long i;
162
163         asm volatile("isync" : : : "memory");
164
165         for (i = 0; i < 16; i++) {
166                 if (! (segs & (1U << i)))
167                         continue;
168                 asm volatile("slbie %0" : : "r" (i << SID_SHIFT));
169         }
170
171         asm volatile("isync" : : : "memory");
172 }
173
174 static int prepare_low_seg_for_htlb(struct mm_struct *mm, unsigned long seg)
175 {
176         unsigned long start = seg << SID_SHIFT;
177         unsigned long end = (seg+1) << SID_SHIFT;
178         struct vm_area_struct *vma;
179         unsigned long addr;
180         struct mmu_gather *tlb;
181
182         BUG_ON(seg >= 16);
183
184         /* Check no VMAs are in the region */
185         vma = find_vma(mm, start);
186         if (vma && (vma->vm_start < end))
187                 return -EBUSY;
188
189         /* Clean up any leftover PTE pages in the region */
190         spin_lock(&mm->page_table_lock);
191         tlb = tlb_gather_mmu(mm, 0);
192         for (addr = start; addr < end; addr += PMD_SIZE) {
193                 pgd_t *pgd = pgd_offset(mm, addr);
194                 pmd_t *pmd;
195                 struct page *page;
196                 pte_t *pte;
197                 int i;
198
199                 if (pgd_none(*pgd))
200                         continue;
201                 pmd = pmd_offset(pgd, addr);
202                 if (!pmd || pmd_none(*pmd))
203                         continue;
204                 if (pmd_bad(*pmd)) {
205                         pmd_ERROR(*pmd);
206                         pmd_clear(pmd);
207                         continue;
208                 }
209                 pte = (pte_t *)pmd_page_kernel(*pmd);
210                 /* No VMAs, so there should be no PTEs, check just in case. */
211                 for (i = 0; i < PTRS_PER_PTE; i++) {
212                         BUG_ON(!pte_none(*pte));
213                         pte++;
214                 }
215                 page = pmd_page(*pmd);
216                 pmd_clear(pmd);
217                 dec_page_state(nr_page_table_pages);
218                 pte_free_tlb(tlb, page);
219         }
220         tlb_finish_mmu(tlb, start, end);
221         spin_unlock(&mm->page_table_lock);
222
223         return 0;
224 }
225
226 static int open_low_hpage_segs(struct mm_struct *mm, u16 newsegs)
227 {
228         unsigned long i;
229
230         newsegs &= ~(mm->context.htlb_segs);
231         if (! newsegs)
232                 return 0; /* The segments we want are already open */
233
234         for (i = 0; i < 16; i++)
235                 if ((1 << i) & newsegs)
236                         if (prepare_low_seg_for_htlb(mm, i) != 0)
237                                 return -EBUSY;
238
239         mm->context.htlb_segs |= newsegs;
240         /* the context change must make it to memory before the flush,
241          * so that further SLB misses do the right thing. */
242         mb();
243         on_each_cpu(flush_segments, (void *)(unsigned long)newsegs, 0, 1);
244
245         return 0;
246 }
247
248 int prepare_hugepage_range(unsigned long addr, unsigned long len)
249 {
250         if (within_hugepage_high_range(addr, len))
251                 return 0;
252         else if ((addr < 0x100000000) && ((addr+len) < 0x100000000)) {
253                 int err;
254                 /* Yes, we need both tests, in case addr+len overflows
255                  * 64-bit arithmetic */
256                 err = open_low_hpage_segs(current->mm,
257                                           LOW_ESID_MASK(addr, len));
258                 if (err)
259                         printk(KERN_DEBUG "prepare_hugepage_range(%lx, %lx)"
260                                " failed (segs: 0x%04hx)\n", addr, len,
261                                LOW_ESID_MASK(addr, len));
262                 return err;
263         }
264
265         return -EINVAL;
266 }
267
268 int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
269                         struct vm_area_struct *vma)
270 {
271         hugepte_t *src_pte, *dst_pte, entry;
272         struct page *ptepage;
273         unsigned long addr = vma->vm_start;
274         unsigned long end = vma->vm_end;
275
276         while (addr < end) {
277                 BUG_ON(! in_hugepage_area(src->context, addr));
278                 BUG_ON(! in_hugepage_area(dst->context, addr));
279
280                 dst_pte = hugepte_alloc(dst, addr);
281                 if (!dst_pte)
282                         return -ENOMEM;
283
284                 src_pte = hugepte_offset(src, addr);
285                 entry = *src_pte;
286                 
287                 if ((addr % HPAGE_SIZE) == 0) {
288                         /* This is the first hugepte in a batch */
289                         ptepage = hugepte_page(entry);
290                         get_page(ptepage);
291                         // dst->rss += (HPAGE_SIZE / PAGE_SIZE);
292                         vx_rsspages_add(dst, HPAGE_SIZE / PAGE_SIZE);
293                 }
294                 set_hugepte(dst_pte, entry);
295
296
297                 addr += PMD_SIZE;
298         }
299         return 0;
300 }
301
302 int
303 follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
304                     struct page **pages, struct vm_area_struct **vmas,
305                     unsigned long *position, int *length, int i)
306 {
307         unsigned long vpfn, vaddr = *position;
308         int remainder = *length;
309
310         WARN_ON(!is_vm_hugetlb_page(vma));
311
312         vpfn = vaddr/PAGE_SIZE;
313         while (vaddr < vma->vm_end && remainder) {
314                 BUG_ON(!in_hugepage_area(mm->context, vaddr));
315
316                 if (pages) {
317                         hugepte_t *pte;
318                         struct page *page;
319
320                         pte = hugepte_offset(mm, vaddr);
321
322                         /* hugetlb should be locked, and hence, prefaulted */
323                         WARN_ON(!pte || hugepte_none(*pte));
324
325                         page = &hugepte_page(*pte)[vpfn % (HPAGE_SIZE/PAGE_SIZE)];
326
327                         WARN_ON(!PageCompound(page));
328
329                         get_page(page);
330                         pages[i] = page;
331                 }
332
333                 if (vmas)
334                         vmas[i] = vma;
335
336                 vaddr += PAGE_SIZE;
337                 ++vpfn;
338                 --remainder;
339                 ++i;
340         }
341
342         *length = remainder;
343         *position = vaddr;
344
345         return i;
346 }
347
348 struct page *
349 follow_huge_addr(struct mm_struct *mm, unsigned long address, int write)
350 {
351         return ERR_PTR(-EINVAL);
352 }
353
354 int pmd_huge(pmd_t pmd)
355 {
356         return pmd_hugepage(pmd);
357 }
358
359 struct page *
360 follow_huge_pmd(struct mm_struct *mm, unsigned long address,
361                 pmd_t *pmd, int write)
362 {
363         struct page *page;
364
365         BUG_ON(! pmd_hugepage(*pmd));
366
367         page = hugepte_page(*(hugepte_t *)pmd);
368         if (page)
369                 page += ((address & ~HPAGE_MASK) >> PAGE_SHIFT);
370         return page;
371 }
372
373 void unmap_hugepage_range(struct vm_area_struct *vma,
374                           unsigned long start, unsigned long end)
375 {
376         struct mm_struct *mm = vma->vm_mm;
377         unsigned long addr;
378         hugepte_t *ptep;
379         struct page *page;
380         int cpu;
381         int local = 0;
382         cpumask_t tmp;
383
384         WARN_ON(!is_vm_hugetlb_page(vma));
385         BUG_ON((start % HPAGE_SIZE) != 0);
386         BUG_ON((end % HPAGE_SIZE) != 0);
387
388         /* XXX are there races with checking cpu_vm_mask? - Anton */
389         cpu = get_cpu();
390         tmp = cpumask_of_cpu(cpu);
391         if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp))
392                 local = 1;
393
394         for (addr = start; addr < end; addr += HPAGE_SIZE) {
395                 hugepte_t pte;
396
397                 BUG_ON(!in_hugepage_area(mm->context, addr));
398
399                 ptep = hugepte_offset(mm, addr);
400                 if (!ptep || hugepte_none(*ptep))
401                         continue;
402
403                 pte = *ptep;
404                 page = hugepte_page(pte);
405                 teardown_huge_pte(ptep);
406                 
407                 if (hugepte_val(pte) & _HUGEPAGE_HASHPTE)
408                         flush_hash_hugepage(mm->context, addr,
409                                             pte, local);
410
411                 put_page(page);
412         }
413         put_cpu();
414
415         // mm->rss -= (end - start) >> PAGE_SHIFT;
416         vx_rsspages_sub(mm, (end - start) >> PAGE_SHIFT);
417 }
418
419 int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
420 {
421         struct mm_struct *mm = current->mm;
422         unsigned long addr;
423         int ret = 0;
424
425         WARN_ON(!is_vm_hugetlb_page(vma));
426         BUG_ON((vma->vm_start % HPAGE_SIZE) != 0);
427         BUG_ON((vma->vm_end % HPAGE_SIZE) != 0);
428
429         spin_lock(&mm->page_table_lock);
430         for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
431                 unsigned long idx;
432                 hugepte_t *pte = hugepte_alloc(mm, addr);
433                 struct page *page;
434
435                 BUG_ON(!in_hugepage_area(mm->context, addr));
436
437                 if (!pte) {
438                         ret = -ENOMEM;
439                         goto out;
440                 }
441                 if (!hugepte_none(*pte))
442                         continue;
443
444                 idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
445                         + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
446                 page = find_get_page(mapping, idx);
447                 if (!page) {
448                         /* charge the fs quota first */
449                         if (hugetlb_get_quota(mapping)) {
450                                 ret = -ENOMEM;
451                                 goto out;
452                         }
453                         page = alloc_huge_page();
454                         if (!page) {
455                                 hugetlb_put_quota(mapping);
456                                 ret = -ENOMEM;
457                                 goto out;
458                         }
459                         ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
460                         if (! ret) {
461                                 unlock_page(page);
462                         } else {
463                                 hugetlb_put_quota(mapping);
464                                 free_huge_page(page);
465                                 goto out;
466                         }
467                 }
468                 setup_huge_pte(mm, page, pte, vma->vm_flags & VM_WRITE);
469         }
470 out:
471         spin_unlock(&mm->page_table_lock);
472         return ret;
473 }
474
475 /* Because we have an exclusive hugepage region which lies within the
476  * normal user address space, we have to take special measures to make
477  * non-huge mmap()s evade the hugepage reserved regions. */
478 unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
479                                      unsigned long len, unsigned long pgoff,
480                                      unsigned long flags)
481 {
482         struct mm_struct *mm = current->mm;
483         struct vm_area_struct *vma;
484         unsigned long start_addr;
485
486         if (len > TASK_SIZE)
487                 return -ENOMEM;
488
489         if (addr) {
490                 addr = PAGE_ALIGN(addr);
491                 vma = find_vma(mm, addr);
492                 if (((TASK_SIZE - len) >= addr)
493                     && (!vma || (addr+len) <= vma->vm_start)
494                     && !is_hugepage_only_range(addr,len))
495                         return addr;
496         }
497         start_addr = addr = mm->free_area_cache;
498
499 full_search:
500         vma = find_vma(mm, addr);
501         while (TASK_SIZE - len >= addr) {
502                 BUG_ON(vma && (addr >= vma->vm_end));
503
504                 if (touches_hugepage_low_range(addr, len)) {
505                         addr = ALIGN(addr+1, 1<<SID_SHIFT);
506                         vma = find_vma(mm, addr);
507                         continue;
508                 }
509                 if (touches_hugepage_high_range(addr, len)) {
510                         addr = TASK_HPAGE_END;
511                         vma = find_vma(mm, addr);
512                         continue;
513                 }
514                 if (!vma || addr + len <= vma->vm_start) {
515                         /*
516                          * Remember the place where we stopped the search:
517                          */
518                         mm->free_area_cache = addr + len;
519                         return addr;
520                 }
521                 addr = vma->vm_end;
522                 vma = vma->vm_next;
523         }
524
525         /* Make sure we didn't miss any holes */
526         if (start_addr != TASK_UNMAPPED_BASE) {
527                 start_addr = addr = TASK_UNMAPPED_BASE;
528                 goto full_search;
529         }
530         return -ENOMEM;
531 }
532
533 static unsigned long htlb_get_low_area(unsigned long len, u16 segmask)
534 {
535         unsigned long addr = 0;
536         struct vm_area_struct *vma;
537
538         vma = find_vma(current->mm, addr);
539         while (addr + len <= 0x100000000UL) {
540                 BUG_ON(vma && (addr >= vma->vm_end)); /* invariant */
541
542                 if (! __within_hugepage_low_range(addr, len, segmask)) {
543                         addr = ALIGN(addr+1, 1<<SID_SHIFT);
544                         vma = find_vma(current->mm, addr);
545                         continue;
546                 }
547
548                 if (!vma || (addr + len) <= vma->vm_start)
549                         return addr;
550                 addr = ALIGN(vma->vm_end, HPAGE_SIZE);
551                 /* Depending on segmask this might not be a confirmed
552                  * hugepage region, so the ALIGN could have skipped
553                  * some VMAs */
554                 vma = find_vma(current->mm, addr);
555         }
556
557         return -ENOMEM;
558 }
559
560 static unsigned long htlb_get_high_area(unsigned long len)
561 {
562         unsigned long addr = TASK_HPAGE_BASE;
563         struct vm_area_struct *vma;
564
565         vma = find_vma(current->mm, addr);
566         for (vma = find_vma(current->mm, addr);
567              addr + len <= TASK_HPAGE_END;
568              vma = vma->vm_next) {
569                 BUG_ON(vma && (addr >= vma->vm_end)); /* invariant */
570                 BUG_ON(! within_hugepage_high_range(addr, len));
571
572                 if (!vma || (addr + len) <= vma->vm_start)
573                         return addr;
574                 addr = ALIGN(vma->vm_end, HPAGE_SIZE);
575                 /* Because we're in a hugepage region, this alignment
576                  * should not skip us over any VMAs */
577         }
578
579         return -ENOMEM;
580 }
581
582 unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
583                                         unsigned long len, unsigned long pgoff,
584                                         unsigned long flags)
585 {
586         if (len & ~HPAGE_MASK)
587                 return -EINVAL;
588
589         if (!(cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE))
590                 return -EINVAL;
591
592         if (test_thread_flag(TIF_32BIT)) {
593                 int lastshift = 0;
594                 u16 segmask, cursegs = current->mm->context.htlb_segs;
595
596                 /* First see if we can do the mapping in the existing
597                  * low hpage segments */
598                 addr = htlb_get_low_area(len, cursegs);
599                 if (addr != -ENOMEM)
600                         return addr;
601
602                 for (segmask = LOW_ESID_MASK(0x100000000UL-len, len);
603                      ! lastshift; segmask >>=1) {
604                         if (segmask & 1)
605                                 lastshift = 1;
606
607                         addr = htlb_get_low_area(len, cursegs | segmask);
608                         if ((addr != -ENOMEM)
609                             && open_low_hpage_segs(current->mm, segmask) == 0)
610                                 return addr;
611                 }
612                 printk(KERN_DEBUG "hugetlb_get_unmapped_area() unable to open"
613                        " enough segments\n");
614                 return -ENOMEM;
615         } else {
616                 return htlb_get_high_area(len);
617         }
618 }
619
620 int hash_huge_page(struct mm_struct *mm, unsigned long access,
621                    unsigned long ea, unsigned long vsid, int local)
622 {
623         hugepte_t *ptep;
624         unsigned long va, vpn;
625         int is_write;
626         hugepte_t old_pte, new_pte;
627         unsigned long hpteflags, prpn, flags;
628         long slot;
629
630         /* We have to find the first hugepte in the batch, since
631          * that's the one that will store the HPTE flags */
632         ea &= HPAGE_MASK;
633         ptep = hugepte_offset(mm, ea);
634
635         /* Search the Linux page table for a match with va */
636         va = (vsid << 28) | (ea & 0x0fffffff);
637         vpn = va >> HPAGE_SHIFT;
638
639         /*
640          * If no pte found or not present, send the problem up to
641          * do_page_fault
642          */
643         if (unlikely(!ptep || hugepte_none(*ptep)))
644                 return 1;
645
646         BUG_ON(hugepte_bad(*ptep));
647
648         /* 
649          * Check the user's access rights to the page.  If access should be
650          * prevented then send the problem up to do_page_fault.
651          */
652         is_write = access & _PAGE_RW;
653         if (unlikely(is_write && !(hugepte_val(*ptep) & _HUGEPAGE_RW)))
654                 return 1;
655
656         /*
657          * At this point, we have a pte (old_pte) which can be used to build
658          * or update an HPTE. There are 2 cases:
659          *
660          * 1. There is a valid (present) pte with no associated HPTE (this is 
661          *      the most common case)
662          * 2. There is a valid (present) pte with an associated HPTE. The
663          *      current values of the pp bits in the HPTE prevent access
664          *      because we are doing software DIRTY bit management and the
665          *      page is currently not DIRTY. 
666          */
667
668         spin_lock_irqsave(&mm->page_table_lock, flags);
669
670         old_pte = *ptep;
671         new_pte = old_pte;
672
673         hpteflags = 0x2 | (! (hugepte_val(new_pte) & _HUGEPAGE_RW));
674
675         /* Check if pte already has an hpte (case 2) */
676         if (unlikely(hugepte_val(old_pte) & _HUGEPAGE_HASHPTE)) {
677                 /* There MIGHT be an HPTE for this pte */
678                 unsigned long hash, slot;
679
680                 hash = hpt_hash(vpn, 1);
681                 if (hugepte_val(old_pte) & _HUGEPAGE_SECONDARY)
682                         hash = ~hash;
683                 slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
684                 slot += (hugepte_val(old_pte) & _HUGEPAGE_GROUP_IX) >> 5;
685
686                 if (ppc_md.hpte_updatepp(slot, hpteflags, va, 1, local) == -1)
687                         hugepte_val(old_pte) &= ~_HUGEPAGE_HPTEFLAGS;
688         }
689
690         if (likely(!(hugepte_val(old_pte) & _HUGEPAGE_HASHPTE))) {
691                 unsigned long hash = hpt_hash(vpn, 1);
692                 unsigned long hpte_group;
693
694                 prpn = hugepte_pfn(old_pte);
695
696 repeat:
697                 hpte_group = ((hash & htab_data.htab_hash_mask) *
698                               HPTES_PER_GROUP) & ~0x7UL;
699
700                 /* Update the linux pte with the HPTE slot */
701                 hugepte_val(new_pte) &= ~_HUGEPAGE_HPTEFLAGS;
702                 hugepte_val(new_pte) |= _HUGEPAGE_HASHPTE;
703
704                 /* Add in WIMG bits */
705                 /* XXX We should store these in the pte */
706                 hpteflags |= _PAGE_COHERENT;
707
708                 slot = ppc_md.hpte_insert(hpte_group, va, prpn, 0,
709                                           hpteflags, 0, 1);
710
711                 /* Primary is full, try the secondary */
712                 if (unlikely(slot == -1)) {
713                         hugepte_val(new_pte) |= _HUGEPAGE_SECONDARY;
714                         hpte_group = ((~hash & htab_data.htab_hash_mask) *
715                                       HPTES_PER_GROUP) & ~0x7UL; 
716                         slot = ppc_md.hpte_insert(hpte_group, va, prpn,
717                                                   1, hpteflags, 0, 1);
718                         if (slot == -1) {
719                                 if (mftb() & 0x1)
720                                         hpte_group = ((hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL;
721
722                                 ppc_md.hpte_remove(hpte_group);
723                                 goto repeat;
724                         }
725                 }
726
727                 if (unlikely(slot == -2))
728                         panic("hash_huge_page: pte_insert failed\n");
729
730                 hugepte_val(new_pte) |= (slot<<5) & _HUGEPAGE_GROUP_IX;
731
732                 /* 
733                  * No need to use ldarx/stdcx here because all who
734                  * might be updating the pte will hold the
735                  * page_table_lock or the hash_table_lock
736                  * (we hold both)
737                  */
738                 *ptep = new_pte;
739         }
740
741         spin_unlock_irqrestore(&mm->page_table_lock, flags);
742
743         return 0;
744 }
745
746 static void flush_hash_hugepage(mm_context_t context, unsigned long ea,
747                                 hugepte_t pte, int local)
748 {
749         unsigned long vsid, vpn, va, hash, slot;
750
751         BUG_ON(hugepte_bad(pte));
752         BUG_ON(!in_hugepage_area(context, ea));
753
754         vsid = get_vsid(context.id, ea);
755
756         va = (vsid << 28) | (ea & 0x0fffffff);
757         vpn = va >> LARGE_PAGE_SHIFT;
758         hash = hpt_hash(vpn, 1);
759         if (hugepte_val(pte) & _HUGEPAGE_SECONDARY)
760                 hash = ~hash;
761         slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
762         slot += (hugepte_val(pte) & _HUGEPAGE_GROUP_IX) >> 5;
763
764         ppc_md.hpte_invalidate(slot, va, 1, local);
765 }