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