cleanup
[linux-2.4.21-pre4.git] / arch / ppc64 / kernel / htab.c
1 /*
2  * PowerPC64 port by Mike Corrigan and Dave Engebretsen
3  *   {mikejc|engebret}@us.ibm.com
4  *
5  *    Copyright (c) 2000 Mike Corrigan <mikejc@us.ibm.com>
6  *
7  * SMP scalability work:
8  *    Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
9  * 
10  *    Module name: htab.c
11  *
12  *    Description:
13  *      PowerPC Hashed Page Table functions
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version
18  * 2 of the License, or (at your option) any later version.
19  */
20
21 #include <linux/config.h>
22 #include <linux/spinlock.h>
23 #include <linux/errno.h>
24 #include <linux/sched.h>
25 #include <linux/proc_fs.h>
26 #include <linux/stat.h>
27 #include <linux/sysctl.h>
28 #include <linux/ctype.h>
29 #include <linux/cache.h>
30
31 #include <asm/ppcdebug.h>
32 #include <asm/processor.h>
33 #include <asm/pgtable.h>
34 #include <asm/mmu.h>
35 #include <asm/mmu_context.h>
36 #include <asm/page.h>
37 #include <asm/types.h>
38 #include <asm/uaccess.h>
39 #include <asm/naca.h>
40 #include <asm/pmc.h>
41 #include <asm/machdep.h>
42 #include <asm/lmb.h>
43 #include <asm/abs_addr.h>
44 #include <asm/io.h>
45 #include <asm/eeh.h>
46 #include <asm/hvcall.h>
47 #include <asm/iSeries/LparData.h>
48 #include <asm/iSeries/HvCallHpt.h>
49
50 /*
51  * Note:  pte   --> Linux PTE
52  *        HPTE  --> PowerPC Hashed Page Table Entry
53  *
54  * Execution context:
55  *   htab_initialize is called with the MMU off (of course), but
56  *   the kernel has been copied down to zero so it can directly
57  *   reference global data.  At this point it is very difficult
58  *   to print debug info.
59  *
60  */
61
62 HTAB htab_data = {NULL, 0, 0, 0, 0};
63
64 extern unsigned long _SDR1;
65 extern unsigned long klimit;
66
67 void make_pte(HPTE *htab, unsigned long va, unsigned long pa,
68               int mode, unsigned long hash_mask, int large);
69 long plpar_pte_enter(unsigned long flags,
70                      unsigned long ptex,
71                      unsigned long new_pteh, unsigned long new_ptel,
72                      unsigned long *old_pteh_ret, unsigned long *old_ptel_ret);
73 static long hpte_remove(unsigned long hpte_group);
74 static long rpa_lpar_hpte_remove(unsigned long hpte_group);
75 static long iSeries_hpte_remove(unsigned long hpte_group);
76 inline unsigned long get_lock_slot(unsigned long vpn);
77
78 static spinlock_t pSeries_tlbie_lock = SPIN_LOCK_UNLOCKED;
79 static spinlock_t pSeries_lpar_tlbie_lock = SPIN_LOCK_UNLOCKED;
80
81 #define LOCK_SPLIT
82 #ifdef LOCK_SPLIT
83 hash_table_lock_t hash_table_lock[128] __cacheline_aligned_in_smp = { [0 ... 31] = {SPIN_LOCK_UNLOCKED}};
84 #else
85 hash_table_lock_t hash_table_lock[1] __cacheline_aligned_in_smp = { [0] = {SPIN_LOCK_UNLOCKED}};
86 #endif
87
88 #define KB (1024)
89 #define MB (1024*KB)
90
91 static inline void
92 loop_forever(void)
93 {
94         volatile unsigned long x = 1;
95         for(;x;x|=1)
96                 ;
97 }
98
99 static inline void
100 create_pte_mapping(unsigned long start, unsigned long end,
101                    unsigned long mode, unsigned long mask, int large)
102 {
103         unsigned long addr;
104         HPTE *htab = (HPTE *)__v2a(htab_data.htab);
105         unsigned int step;
106
107         if (large)
108                 step = 16*MB;
109         else
110                 step = 4*KB;
111
112         for (addr = start; addr < end; addr += step) {
113                 unsigned long vsid = get_kernel_vsid(addr);
114                 unsigned long va = (vsid << 28) | (addr & 0xfffffff);
115                 make_pte(htab, va, (unsigned long)__v2a(addr), 
116                          mode, mask, large);
117         }
118 }
119
120 void
121 htab_initialize(void)
122 {
123         unsigned long table, htab_size_bytes;
124         unsigned long pteg_count;
125         unsigned long mode_rw, mask, lock_shift;
126
127 #if 0
128         /* Can't really do the call below since it calls the normal RTAS
129          * entry point and we're still relocate off at the moment.
130          * Temporarily diabling until it can call through the relocate off
131          * RTAS entry point.  -Peter
132          */
133         ppc64_boot_msg(0x05, "htab init");
134 #endif
135         /*
136          * Calculate the required size of the htab.  We want the number of
137          * PTEGs to equal one half the number of real pages.
138          */ 
139         htab_size_bytes = 1UL << naca->pftSize;
140         pteg_count = htab_size_bytes >> 7;
141
142         /* For debug, make the HTAB 1/8 as big as it normally would be. */
143         ifppcdebug(PPCDBG_HTABSIZE) {
144                 pteg_count >>= 3;
145                 htab_size_bytes = pteg_count << 7;
146         }
147
148         htab_data.htab_num_ptegs = pteg_count;
149         htab_data.htab_hash_mask = pteg_count - 1;
150
151         /* 
152          * Calculate the number of bits to shift the pteg selector such that we
153          * use the high order 8 bits to select a page table lock.
154          */
155         asm ("cntlzd %0,%1" : "=r" (lock_shift) : 
156              "r" (htab_data.htab_hash_mask));
157         htab_data.htab_lock_shift = (64 - lock_shift) - 8;
158
159         if(systemcfg->platform == PLATFORM_PSERIES) {
160                 /* Find storage for the HPT.  Must be contiguous in
161                  * the absolute address space.
162                  */
163                 table = lmb_alloc(htab_size_bytes, htab_size_bytes);
164                 if ( !table ) {
165                         ppc64_terminate_msg(0x20, "hpt space");
166                         loop_forever();
167                 }
168                 htab_data.htab = (HPTE *)__a2v(table);
169
170                 /* htab absolute addr + encoded htabsize */
171                 _SDR1 = table + __ilog2(pteg_count) - 11;
172
173                 /* Initialize the HPT with no entries */
174                 memset((void *)table, 0, htab_size_bytes);
175         } else {
176                 /* Using a hypervisor which owns the htab */
177                 htab_data.htab = NULL;
178                 _SDR1 = 0; 
179         }
180
181         mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX;
182         mask = pteg_count-1;
183
184         /* XXX we currently map kernel text rw, should fix this */
185         if ((systemcfg->platform & PLATFORM_PSERIES) &&
186            cpu_has_largepage() && (systemcfg->physicalMemorySize > 256*MB)) {
187                 create_pte_mapping((unsigned long)KERNELBASE, 
188                                    KERNELBASE + 256*MB, mode_rw, mask, 0);
189                 create_pte_mapping((unsigned long)KERNELBASE + 256*MB, 
190                                    KERNELBASE + (systemcfg->physicalMemorySize), 
191                                    mode_rw, mask, 1);
192         } else {
193                 create_pte_mapping((unsigned long)KERNELBASE, 
194                                    KERNELBASE+(systemcfg->physicalMemorySize), 
195                                    mode_rw, mask, 0);
196         }
197 #if 0
198         /* Can't really do the call below since it calls the normal RTAS
199          * entry point and we're still relocate off at the moment.
200          * Temporarily diabling until it can call through the relocate off
201          * RTAS entry point.  -Peter
202          */
203         ppc64_boot_msg(0x06, "htab done");
204 #endif
205 }
206 #undef KB
207 #undef MB
208
209 /*
210  * Create a pte. Used during initialization only.
211  * We assume the PTE will fit in the primary PTEG.
212  */
213 void make_pte(HPTE *htab, unsigned long va, unsigned long pa,
214               int mode, unsigned long hash_mask, int large)
215 {
216         HPTE *hptep, local_hpte, rhpte;
217         unsigned long hash, vpn, flags, lpar_rc;
218         unsigned long i, dummy1, dummy2;
219         long slot;
220
221         if (large)
222                 vpn = va >> LARGE_PAGE_SHIFT;
223         else
224                 vpn = va >> PAGE_SHIFT;
225
226         hash = hpt_hash(vpn, large);
227
228         local_hpte.dw1.dword1 = pa | mode;
229         local_hpte.dw0.dword0 = 0;
230         local_hpte.dw0.dw0.avpn = va >> 23;
231         local_hpte.dw0.dw0.bolted = 1;          /* bolted */
232         if (large) {
233                 local_hpte.dw0.dw0.l = 1;       /* large page */
234                 local_hpte.dw0.dw0.avpn &= ~0x1UL;
235         }
236         local_hpte.dw0.dw0.v = 1;
237
238         if (systemcfg->platform == PLATFORM_PSERIES) {
239                 hptep  = htab + ((hash & hash_mask)*HPTES_PER_GROUP);
240
241                 for (i = 0; i < 8; ++i, ++hptep) {
242                         if (hptep->dw0.dw0.v == 0) {            /* !valid */
243                                 *hptep = local_hpte;
244                                 return;
245                         }
246                 }
247         } else if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
248                 slot = ((hash & hash_mask)*HPTES_PER_GROUP);
249                 
250                 /* Set CEC cookie to 0                   */
251                 /* Zero page = 0                         */
252                 /* I-cache Invalidate = 0                */
253                 /* I-cache synchronize = 0               */
254                 /* Exact = 0 - modify any entry in group */
255                 flags = 0;
256                 
257                 lpar_rc =  plpar_pte_enter(flags, slot, local_hpte.dw0.dword0,
258                                            local_hpte.dw1.dword1, 
259                                            &dummy1, &dummy2);
260                 return;
261         } else if (systemcfg->platform == PLATFORM_ISERIES_LPAR) {
262                 slot = HvCallHpt_findValid(&rhpte, vpn);
263                 if (slot < 0) {
264                         /* Must find space in primary group */
265                         panic("hash_page: hpte already exists\n");
266                 }
267                 HvCallHpt_addValidate(slot, 0, (HPTE *)&local_hpte );
268                 return;
269         }
270
271         /* We should _never_ get here and too early to call xmon. */
272         ppc64_terminate_msg(0x22, "hpte platform");
273         loop_forever();
274 }
275
276 /*
277  * find_linux_pte returns the address of a linux pte for a given 
278  * effective address and directory.  If not found, it returns zero.
279  */
280 pte_t *find_linux_pte(pgd_t *pgdir, unsigned long ea)
281 {
282         pgd_t *pg;
283         pmd_t *pm;
284         pte_t *pt = NULL;
285         pte_t pte;
286
287         pg = pgdir + pgd_index(ea);
288         if (!pgd_none(*pg)) {
289                 pm = pmd_offset(pg, ea);
290                 if (!pmd_none(*pm)) { 
291                         pt = pte_offset(pm, ea);
292                         pte = *pt;
293                         if (!pte_present(pte))
294                                 pt = NULL;
295                 }
296         }
297
298         return pt;
299 }
300
301 static inline unsigned long computeHptePP(unsigned long pte)
302 {
303         return (pte & _PAGE_USER) |
304                 (((pte & _PAGE_USER) >> 1) &
305                  ((~((pte >> 2) &       /* _PAGE_RW */
306                      (pte >> 7))) &     /* _PAGE_DIRTY */
307                   1));
308 }
309
310 /*
311  * Handle a fault by adding an HPTE. If the address can't be determined
312  * to be valid via Linux page tables, return 1. If handled return 0
313  */
314 int __hash_page(unsigned long ea, unsigned long access, 
315                 unsigned long vsid, pte_t *ptep)
316 {
317         unsigned long va, vpn;
318         unsigned long newpp, prpn;
319         unsigned long hpteflags, lock_slot;
320         long slot;
321         pte_t old_pte, new_pte;
322
323         /* Search the Linux page table for a match with va */
324         va = (vsid << 28) | (ea & 0x0fffffff);
325         vpn = va >> PAGE_SHIFT;
326         lock_slot = get_lock_slot(vpn); 
327
328         /* Acquire the hash table lock to guarantee that the linux
329          * pte we fetch will not change
330          */
331         spin_lock(&hash_table_lock[lock_slot].lock);
332         
333         /* 
334          * Check the user's access rights to the page.  If access should be
335          * prevented then send the problem up to do_page_fault.
336          */
337         access |= _PAGE_PRESENT;
338         if (unlikely(access & ~(pte_val(*ptep)))) {
339                 spin_unlock(&hash_table_lock[lock_slot].lock);
340                 return 1;
341         }
342
343         /* 
344          * We have found a pte (which was present).
345          * The spinlocks prevent this status from changing
346          * The hash_table_lock prevents the _PAGE_HASHPTE status
347          * from changing (RPN, DIRTY and ACCESSED too)
348          * The page_table_lock prevents the pte from being 
349          * invalidated or modified
350          */
351
352         /*
353          * At this point, we have a pte (old_pte) which can be used to build
354          * or update an HPTE. There are 2 cases:
355          *
356          * 1. There is a valid (present) pte with no associated HPTE (this is 
357          *      the most common case)
358          * 2. There is a valid (present) pte with an associated HPTE. The
359          *      current values of the pp bits in the HPTE prevent access
360          *      because we are doing software DIRTY bit management and the
361          *      page is currently not DIRTY. 
362          */
363
364         old_pte = *ptep;
365         new_pte = old_pte;
366
367         /* If the attempted access was a store */
368         if (access & _PAGE_RW)
369                 pte_val(new_pte) |= _PAGE_ACCESSED | _PAGE_DIRTY;
370         else
371                 pte_val(new_pte) |= _PAGE_ACCESSED;
372
373         newpp = computeHptePP(pte_val(new_pte));
374         
375         /* Check if pte already has an hpte (case 2) */
376         if (unlikely(pte_val(old_pte) & _PAGE_HASHPTE)) {
377                 /* There MIGHT be an HPTE for this pte */
378                 unsigned long hash, slot, secondary;
379
380                 /* XXX fix large pte flag */
381                 hash = hpt_hash(vpn, 0);
382                 secondary = (pte_val(old_pte) & _PAGE_SECONDARY) >> 15;
383                 if (secondary)
384                         hash = ~hash;
385                 slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
386                 slot += (pte_val(old_pte) & _PAGE_GROUP_IX) >> 12;
387
388                 /* XXX fix large pte flag */
389                 if (ppc_md.hpte_updatepp(slot, secondary, 
390                                          newpp, va, 0) == -1) {
391                         pte_val(old_pte) &= ~_PAGE_HPTEFLAGS;
392                 } else {
393                         if (!pte_same(old_pte, new_pte)) {
394                                 *ptep = new_pte;
395                         }
396                 }
397         }
398
399         if (likely(!(pte_val(old_pte) & _PAGE_HASHPTE))) {
400                 /* Update the linux pte with the HPTE slot */
401                 pte_val(new_pte) &= ~_PAGE_HPTEFLAGS;
402                 pte_val(new_pte) |= _PAGE_HASHPTE;
403                 prpn = pte_val(old_pte) >> PTE_SHIFT;
404
405                 /* copy appropriate flags from linux pte */
406                 hpteflags = (pte_val(new_pte) & 0x1f8) | newpp;
407
408                 slot = ppc_md.hpte_insert(vpn, prpn, hpteflags, 0, 0);
409
410                 pte_val(new_pte) |= ((slot<<12) & 
411                                      (_PAGE_GROUP_IX | _PAGE_SECONDARY));
412
413                 *ptep = new_pte;
414         }
415
416         spin_unlock(&hash_table_lock[lock_slot].lock);
417
418         return 0;
419 }
420
421 /*
422  * Handle a fault by adding an HPTE. If the address can't be determined
423  * to be valid via Linux page tables, return 1. If handled return 0
424  */
425 int hash_page(unsigned long ea, unsigned long access)
426 {
427         void *pgdir;
428         unsigned long vsid;
429         struct mm_struct *mm;
430         pte_t *ptep;
431         int ret;
432
433         /* Check for invalid addresses. */
434         if (!IS_VALID_EA(ea)) return 1;
435
436         switch (REGION_ID(ea)) {
437         case USER_REGION_ID:
438                 mm = current->mm;
439                 if (mm == NULL) return 1;
440                 vsid = get_vsid(mm->context, ea);
441                 break;
442         case IO_REGION_ID:
443                 mm = &ioremap_mm;
444                 vsid = get_kernel_vsid(ea);
445                 break;
446         case VMALLOC_REGION_ID:
447                 mm = &init_mm;
448                 vsid = get_kernel_vsid(ea);
449                 break;
450         case EEH_REGION_ID:
451                 /*
452                  * Should only be hit if there is an access to MMIO space
453                  * which is protected by EEH.
454                  * Send the problem up to do_page_fault 
455                  */
456         case KERNEL_REGION_ID:
457                 /*
458                  * Should never get here - entire 0xC0... region is bolted.
459                  * Send the problem up to do_page_fault 
460                  */
461         default:
462                 /* Not a valid range
463                  * Send the problem up to do_page_fault 
464                  */
465                 return 1;
466                 break;
467         }
468
469         pgdir = mm->pgd;
470         if (pgdir == NULL) return 1;
471
472         /*
473          * Lock the Linux page table to prevent mmap and kswapd
474          * from modifying entries while we search and update
475          */
476         spin_lock(&mm->page_table_lock);
477
478         ptep = find_linux_pte(pgdir, ea);
479         /*
480          * If no pte found or not present, send the problem up to
481          * do_page_fault
482          */
483         if (ptep && pte_present(*ptep)) {
484                 ret = __hash_page(ea, access, vsid, ptep);
485         } else {        
486                 /* If no pte, send the problem up to do_page_fault */
487                 ret = 1;
488         }
489
490         spin_unlock(&mm->page_table_lock);
491
492         return ret;
493 }
494
495 void flush_hash_page(unsigned long context, unsigned long ea, pte_t *ptep)
496 {
497         unsigned long vsid, vpn, va, hash, secondary, slot, flags, lock_slot;
498         unsigned long large = 0, local = 0;
499         pte_t pte;
500
501         if ((ea >= USER_START) && (ea <= USER_END))
502                 vsid = get_vsid(context, ea);
503         else
504                 vsid = get_kernel_vsid(ea);
505
506         va = (vsid << 28) | (ea & 0x0fffffff);
507         if (large)
508                 vpn = va >> LARGE_PAGE_SHIFT;
509         else
510                 vpn = va >> PAGE_SHIFT;
511
512         lock_slot = get_lock_slot(vpn); 
513         hash = hpt_hash(vpn, large);
514
515         spin_lock_irqsave(&hash_table_lock[lock_slot].lock, flags);
516
517         pte = __pte(pte_update(ptep, _PAGE_HPTEFLAGS, 0));
518         secondary = (pte_val(pte) & _PAGE_SECONDARY) >> 15;
519         if (secondary) hash = ~hash;
520         slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
521         slot += (pte_val(pte) & _PAGE_GROUP_IX) >> 12;
522         
523         if (pte_val(pte) & _PAGE_HASHPTE) {
524                 ppc_md.hpte_invalidate(slot, secondary, va, large, local);
525         }
526
527         spin_unlock_irqrestore(&hash_table_lock[lock_slot].lock, flags);
528 }
529
530 long plpar_pte_enter(unsigned long flags,
531                      unsigned long ptex,
532                      unsigned long new_pteh, unsigned long new_ptel,
533                      unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
534 {
535         unsigned long dummy, ret;
536         ret = plpar_hcall(H_ENTER, flags, ptex, new_pteh, new_ptel,
537                            old_pteh_ret, old_ptel_ret, &dummy);
538         return(ret);
539 }
540
541 long plpar_pte_remove(unsigned long flags,
542                       unsigned long ptex,
543                       unsigned long avpn,
544                       unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
545 {
546         unsigned long dummy;
547         return plpar_hcall(H_REMOVE, flags, ptex, avpn, 0,
548                            old_pteh_ret, old_ptel_ret, &dummy);
549 }
550
551 long plpar_pte_read(unsigned long flags,
552                     unsigned long ptex,
553                     unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
554 {
555         unsigned long dummy;
556         return plpar_hcall(H_READ, flags, ptex, 0, 0,
557                            old_pteh_ret, old_ptel_ret, &dummy);
558 }
559
560 long plpar_pte_protect(unsigned long flags,
561                        unsigned long ptex,
562                        unsigned long avpn)
563 {
564         return plpar_hcall_norets(H_PROTECT, flags, ptex, avpn);
565 }
566
567 static __inline__ void set_pp_bit(unsigned long pp, HPTE *addr)
568 {
569         unsigned long old;
570         unsigned long *p = &addr->dw1.dword1;
571
572         __asm__ __volatile__(
573         "1:     ldarx   %0,0,%3\n\
574                 rldimi  %0,%2,0,62\n\
575                 stdcx.  %0,0,%3\n\
576                 bne     1b"
577         : "=&r" (old), "=m" (*p)
578         : "r" (pp), "r" (p), "m" (*p)
579         : "cc");
580 }
581
582 /*
583  * Calculate which hash_table_lock to use, based on the pteg being used.
584  *
585  * Given a VPN, use the high order 8 bits to select one of 2^7 locks.  The
586  * highest order bit is used to indicate primary vs. secondary group.  If the
587  * secondary is selected, complement the lock select bits.  This results in
588  * both the primary and secondary groups being covered under the same lock.
589  */
590 inline unsigned long get_lock_slot(unsigned long vpn)
591 {
592         unsigned long lock_slot;
593 #ifdef LOCK_SPLIT
594         lock_slot = (hpt_hash(vpn,0) >> htab_data.htab_lock_shift) & 0xff;
595         if(lock_slot & 0x80) lock_slot = (~lock_slot) & 0x7f;
596 #else
597         lock_slot = 0;
598 #endif
599         return(lock_slot);
600 }
601
602 /*
603  * Functions used to retrieve word 0 of a given page table entry.
604  *
605  * Input : slot : PTE index within the page table of the entry to retrieve 
606  * Output: Contents of word 0 of the specified entry
607  */
608 static unsigned long rpa_lpar_hpte_getword0(unsigned long slot)
609 {
610         unsigned long dword0;
611         unsigned long lpar_rc;
612         unsigned long dummy_word1;
613         unsigned long flags;
614
615         /* Read 1 pte at a time                        */
616         /* Do not need RPN to logical page translation */
617         /* No cross CEC PFT access                     */
618         flags = 0;
619         
620         lpar_rc = plpar_pte_read(flags, slot, &dword0, &dummy_word1);
621
622         if (lpar_rc != H_Success)
623                 panic("Error on pte read in get_hpte0 rc = %lx\n", lpar_rc);
624
625         return dword0;
626 }
627
628 unsigned long iSeries_hpte_getword0(unsigned long slot)
629 {
630         unsigned long dword0;
631
632         HPTE hpte;
633         HvCallHpt_get(&hpte, slot);
634         dword0 = hpte.dw0.dword0;
635
636         return dword0;
637 }
638
639 /*
640  * Functions used to find the PTE for a particular virtual address. 
641  * Only used during boot when bolting pages.
642  *
643  * Input : vpn      : virtual page number
644  * Output: PTE index within the page table of the entry
645  *         -1 on failure
646  */
647 static long hpte_find(unsigned long vpn)
648 {
649         HPTE *hptep;
650         unsigned long hash;
651         unsigned long i, j;
652         long slot;
653         Hpte_dword0 dw0;
654
655         hash = hpt_hash(vpn, 0);
656
657         for (j = 0; j < 2; j++) {
658                 slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
659                 for (i = 0; i < HPTES_PER_GROUP; i++) {
660                         hptep = htab_data.htab + slot;
661                         dw0 = hptep->dw0.dw0;
662
663                         if ((dw0.avpn == (vpn >> 11)) && dw0.v &&
664                             (dw0.h == j)) {
665                                 /* HPTE matches */
666                                 if (j)
667                                         slot = -slot;
668                                 return slot;
669                         }
670                         ++slot;
671                 }
672                 hash = ~hash;
673         }
674
675         return -1;
676 }
677
678 static long rpa_lpar_hpte_find(unsigned long vpn)
679 {
680         unsigned long hash;
681         unsigned long i, j;
682         long slot;
683         union {
684                 unsigned long dword0;
685                 Hpte_dword0 dw0;
686         } hpte_dw0;
687         Hpte_dword0 dw0;
688
689         hash = hpt_hash(vpn, 0);
690
691         for (j = 0; j < 2; j++) {
692                 slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
693                 for (i = 0; i < HPTES_PER_GROUP; i++) {
694                         hpte_dw0.dword0 = rpa_lpar_hpte_getword0(slot);
695                         dw0 = hpte_dw0.dw0;
696
697                         if ((dw0.avpn == (vpn >> 11)) && dw0.v &&
698                             (dw0.h == j)) {
699                                 /* HPTE matches */
700                                 if (j)
701                                         slot = -slot;
702                                 return slot;
703                         }
704                         ++slot;
705                 }
706                 hash = ~hash;
707         }
708
709         return -1;
710
711
712 static long iSeries_hpte_find(unsigned long vpn)
713 {
714         HPTE hpte;
715         long slot;
716
717         /*
718          * The HvCallHpt_findValid interface is as follows:
719          * 0xffffffffffffffff : No entry found.
720          * 0x00000000xxxxxxxx : Entry found in primary group, slot x
721          * 0x80000000xxxxxxxx : Entry found in secondary group, slot x
722          */
723         slot = HvCallHpt_findValid(&hpte, vpn); 
724         if (hpte.dw0.dw0.v) {
725                 if (slot < 0) {
726                         slot &= 0x7fffffffffffffff;
727                         slot = -slot;
728                 }
729         } else {
730                 slot = -1;
731         }
732
733         return slot;
734 }
735
736 /*
737  * Functions used to invalidate a page table entry from the page table
738  * and tlb.
739  *
740  * Input : slot  : PTE index within the page table of the entry to invalidated
741  *         va    : Virtual address of the entry being invalidated
742  *         large : 1 = large page (16M)
743  *         local : 1 = Use tlbiel to only invalidate the local tlb 
744  */
745 static void hpte_invalidate(unsigned long slot, 
746                             unsigned long secondary,
747                             unsigned long va,
748                             int large, int local)
749 {
750         HPTE *hptep = htab_data.htab + slot;
751         Hpte_dword0 dw0;
752         unsigned long vpn, avpn;
753         unsigned long flags;
754
755         if (large)
756                 vpn = va >> LARGE_PAGE_SHIFT;
757         else
758                 vpn = va >> PAGE_SHIFT;
759
760         avpn = vpn >> 11;
761
762         dw0 = hptep->dw0.dw0;
763
764         /*
765          * Do not remove bolted entries.  Alternatively, we could check
766          * the AVPN, hash group, and valid bits.  By doing it this way,
767          * it is common with the pSeries LPAR optimal path.
768          */
769         if (dw0.bolted) return;
770
771         /* Invalidate the hpte. */
772         hptep->dw0.dword0 = 0;
773
774         /* Invalidate the tlb */
775         spin_lock_irqsave(&pSeries_tlbie_lock, flags);
776         _tlbie(va, large);
777         spin_unlock_irqrestore(&pSeries_tlbie_lock, flags);
778 }
779
780 static void rpa_lpar_hpte_invalidate(unsigned long slot, 
781                                      unsigned long secondary,
782                                      unsigned long va,
783                                      int large, int local)
784 {
785         unsigned long lpar_rc;
786         unsigned long dummy1, dummy2;
787
788         /* 
789          * Don't remove a bolted entry.  This case can occur when we bolt
790          * pages dynamically after initial boot.
791          */
792         lpar_rc = plpar_pte_remove(H_ANDCOND, slot, (0x1UL << 4), 
793                                    &dummy1, &dummy2);
794
795         if (lpar_rc != H_Success)
796                 panic("Bad return code from invalidate rc = %lx\n", lpar_rc);
797 }
798
799 static void iSeries_hpte_invalidate(unsigned long slot, 
800                                     unsigned long secondary,
801                                     unsigned long va,
802                                     int large, int local)
803 {
804         HPTE lhpte;
805         unsigned long vpn, avpn;
806
807         if (large)
808                 vpn = va >> LARGE_PAGE_SHIFT;
809         else
810                 vpn = va >> PAGE_SHIFT;
811
812         avpn = vpn >> 11;
813
814         lhpte.dw0.dword0 = iSeries_hpte_getword0(slot);
815         
816         if ((lhpte.dw0.dw0.avpn == avpn) && 
817             (lhpte.dw0.dw0.v) &&
818             (lhpte.dw0.dw0.h == secondary)) {
819                 HvCallHpt_invalidateSetSwBitsGet(slot, 0, 0);
820         }
821 }
822
823 /*
824  * Functions used to update page protection bits.
825  *
826  * Input : slot  : PTE index within the page table of the entry to update
827  *         newpp : new page protection bits
828  *         va    : Virtual address of the entry being updated
829  *         large : 1 = large page (16M)
830  * Output: 0 on success, -1 on failure
831  */
832 static long hpte_updatepp(unsigned long slot, 
833                           unsigned long secondary,
834                           unsigned long newpp,
835                           unsigned long va, int large)
836 {
837         HPTE *hptep = htab_data.htab + slot;
838         Hpte_dword0 dw0;
839         Hpte_dword1 dw1;
840         unsigned long vpn, avpn;
841         unsigned long flags;
842
843         if (large)
844                 vpn = va >> LARGE_PAGE_SHIFT;
845         else
846                 vpn = va >> PAGE_SHIFT;
847
848         avpn = vpn >> 11;
849
850         dw0 = hptep->dw0.dw0;
851         if ((dw0.avpn == avpn) && 
852             (dw0.v) && (dw0.h == secondary)) {
853                 /* Turn off valid bit in HPTE */
854                 dw0.v = 0;
855                 hptep->dw0.dw0 = dw0;
856                 
857                 /* Ensure it is out of the tlb too */
858                 spin_lock_irqsave(&pSeries_tlbie_lock, flags);
859                 _tlbie(va, large);
860                 spin_unlock_irqrestore(&pSeries_tlbie_lock, flags);
861                 
862                 /* Insert the new pp bits into the HPTE */
863                 dw1 = hptep->dw1.dw1;
864                 dw1.pp = newpp;
865                 hptep->dw1.dw1 = dw1;
866                 
867                 /* Ensure it is visible before validating */
868                 __asm__ __volatile__ ("eieio" : : : "memory");
869                 
870                 /* Turn the valid bit back on in HPTE */
871                 dw0.v = 1;
872                 hptep->dw0.dw0 = dw0;
873                 
874                 __asm__ __volatile__ ("ptesync" : : : "memory");
875                 
876                 return 0;
877         }
878
879         return -1;
880 }
881
882 static long rpa_lpar_hpte_updatepp(unsigned long slot, 
883                                    unsigned long secondary,
884                                    unsigned long newpp,
885                                    unsigned long va, int large)
886 {
887         unsigned long lpar_rc;
888         unsigned long flags = (newpp & 7);
889         unsigned long avpn = va >> 23;
890         HPTE hpte;
891
892         lpar_rc = plpar_pte_read(0, slot, &hpte.dw0.dword0, &hpte.dw1.dword1);
893
894         if ((hpte.dw0.dw0.avpn == avpn) &&
895             (hpte.dw0.dw0.v) && 
896             (hpte.dw0.dw0.h == secondary)) {
897                 lpar_rc = plpar_pte_protect(flags, slot, 0);
898                 if (lpar_rc != H_Success)
899                         panic("bad return code from pte protect rc = %lx\n", 
900                               lpar_rc);
901                 return 0;
902         }
903
904         return -1;
905 }
906
907 static long iSeries_hpte_updatepp(unsigned long slot, 
908                                   unsigned long secondary,
909                                   unsigned long newpp, 
910                                   unsigned long va, int large)
911 {
912         unsigned long vpn, avpn;
913         HPTE hpte;
914
915         if (large)
916                 vpn = va >> LARGE_PAGE_SHIFT;
917         else
918                 vpn = va >> PAGE_SHIFT;
919
920         avpn = vpn >> 11;
921
922         HvCallHpt_get(&hpte, slot);
923         if ((hpte.dw0.dw0.avpn == avpn) && 
924             (hpte.dw0.dw0.v) &&
925             (hpte.dw0.dw0.h == secondary)) {
926                 HvCallHpt_setPp(slot, newpp);
927                 return 0;
928         }
929         return -1;
930 }
931
932 /*
933  * Functions used to update the page protection bits. Intended to be used 
934  * to create guard pages for kernel data structures on pages which are bolted
935  * in the HPT. Assumes pages being operated on will not be stolen.
936  * Does not work on large pages. No need to lock here because we are the 
937  * only user.
938  * 
939  * Input : newpp : page protection flags
940  *         ea    : effective kernel address to bolt.
941  */
942 static void hpte_updateboltedpp(unsigned long newpp, unsigned long ea)
943 {
944         unsigned long vsid, va, vpn, flags;
945         long slot;
946         HPTE *hptep;
947
948         vsid = get_kernel_vsid(ea);
949         va = (vsid << 28) | (ea & 0x0fffffff);
950         vpn = va >> PAGE_SHIFT;
951
952         slot = hpte_find(vpn);
953         if (slot == -1)
954                 panic("could not find page to bolt\n");
955         hptep = htab_data.htab + slot;
956
957         set_pp_bit(newpp, hptep);
958
959         /* Ensure it is out of the tlb too */
960         spin_lock_irqsave(&pSeries_tlbie_lock, flags);
961         _tlbie(va, 0);
962         spin_unlock_irqrestore(&pSeries_tlbie_lock, flags);
963 }
964
965 static void rpa_lpar_hpte_updateboltedpp(unsigned long newpp, unsigned long ea)
966 {
967         unsigned long lpar_rc;
968         unsigned long vsid, va, vpn, flags;
969         long slot;
970
971         vsid = get_kernel_vsid(ea);
972         va = (vsid << 28) | (ea & 0x0fffffff);
973         vpn = va >> PAGE_SHIFT;
974
975         slot = rpa_lpar_hpte_find(vpn);
976         if (slot == -1)
977                 panic("updateboltedpp: Could not find page to bolt\n");
978
979         flags = newpp & 3;
980         lpar_rc = plpar_pte_protect(flags, slot, 0);
981
982         if (lpar_rc != H_Success)
983                 panic("Bad return code from pte bolted protect rc = %lx\n",
984                       lpar_rc); 
985 }
986
987 void iSeries_hpte_updateboltedpp(unsigned long newpp, unsigned long ea)
988 {
989         unsigned long vsid,va,vpn;
990         long slot;
991
992         vsid = get_kernel_vsid( ea );
993         va = ( vsid << 28 ) | ( ea & 0x0fffffff );
994         vpn = va >> PAGE_SHIFT;
995
996         slot = iSeries_hpte_find(vpn); 
997         if (slot == -1)
998                 panic("updateboltedpp: Could not find page to bolt\n");
999
1000         HvCallHpt_setPp(slot, newpp);
1001 }
1002
1003 /*
1004  * Functions used to insert new hardware page table entries.
1005  * Will castout non-bolted entries as necessary using a random
1006  * algorithm.
1007  *
1008  * Input : vpn      : virtual page number
1009  *         prpn     : real page number in absolute space
1010  *         hpteflags: page protection flags
1011  *         bolted   : 1 = bolt the page
1012  *         large    : 1 = large page (16M)
1013  * Output: hsss, where h = hash group, sss = slot within that group
1014  */
1015 static long hpte_insert(unsigned long vpn, unsigned long prpn,
1016                         unsigned long hpteflags, int bolted, int large)
1017 {
1018         HPTE *hptep;
1019         Hpte_dword0 dw0;
1020         HPTE lhpte;
1021         int i, secondary;
1022         unsigned long hash = hpt_hash(vpn, 0);
1023         unsigned long avpn = vpn >> 11;
1024         unsigned long arpn = physRpn_to_absRpn(prpn);
1025         unsigned long hpte_group;
1026
1027 repeat:
1028         secondary = 0;
1029         hpte_group = ((hash & htab_data.htab_hash_mask) *
1030                       HPTES_PER_GROUP) & ~0x7UL;
1031         hptep = htab_data.htab + hpte_group;
1032
1033         for (i = 0; i < HPTES_PER_GROUP; i++) {
1034                 dw0 = hptep->dw0.dw0;
1035                 if (!dw0.v) {
1036                         /* retry with lock held */
1037                         dw0 = hptep->dw0.dw0;
1038                         if (!dw0.v)
1039                                 break;
1040                 }
1041                 hptep++;
1042         }
1043
1044         if (i == HPTES_PER_GROUP) {
1045                 secondary = 1;
1046                 hpte_group = ((~hash & htab_data.htab_hash_mask) *
1047                               HPTES_PER_GROUP) & ~0x7UL;
1048                 hptep = htab_data.htab + hpte_group;
1049
1050                 for (i = 0; i < HPTES_PER_GROUP; i++) {
1051                         dw0 = hptep->dw0.dw0;
1052                         if (!dw0.v) {
1053                                 /* retry with lock held */
1054                                 dw0 = hptep->dw0.dw0;
1055                                 if (!dw0.v)
1056                                         break;
1057                         }
1058                         hptep++;
1059                 }
1060                 if (i == HPTES_PER_GROUP) {
1061                         if (mftb() & 0x1)
1062                                 hpte_group=((hash & htab_data.htab_hash_mask)* 
1063                                             HPTES_PER_GROUP) & ~0x7UL;
1064                         
1065                         hpte_remove(hpte_group);
1066                         goto repeat;
1067                 }
1068         }
1069
1070         lhpte.dw1.dword1      = 0;
1071         lhpte.dw1.dw1.rpn     = arpn;
1072         lhpte.dw1.flags.flags = hpteflags;
1073
1074         lhpte.dw0.dword0      = 0;
1075         lhpte.dw0.dw0.avpn    = avpn;
1076         lhpte.dw0.dw0.h       = secondary;
1077         lhpte.dw0.dw0.bolted  = bolted;
1078         lhpte.dw0.dw0.v       = 1;
1079
1080         if (large) lhpte.dw0.dw0.l = 1;
1081
1082         hptep->dw1.dword1 = lhpte.dw1.dword1;
1083
1084         /* Guarantee the second dword is visible before the valid bit */
1085         __asm__ __volatile__ ("eieio" : : : "memory");
1086
1087         /*
1088          * Now set the first dword including the valid bit
1089          * NOTE: this also unlocks the hpte
1090          */
1091         hptep->dw0.dword0 = lhpte.dw0.dword0;
1092
1093         __asm__ __volatile__ ("ptesync" : : : "memory");
1094
1095         return ((secondary << 3) | i);
1096 }
1097
1098 static long rpa_lpar_hpte_insert(unsigned long vpn, unsigned long prpn,
1099                                  unsigned long hpteflags,
1100                                  int bolted, int large)
1101 {
1102         /* XXX fix for large page */
1103         unsigned long lpar_rc;
1104         unsigned long flags;
1105         unsigned long slot;
1106         HPTE lhpte;
1107         int secondary;
1108         unsigned long hash = hpt_hash(vpn, 0);
1109         unsigned long avpn = vpn >> 11;
1110         unsigned long arpn = physRpn_to_absRpn(prpn);
1111         unsigned long hpte_group;
1112
1113         /* Fill in the local HPTE with absolute rpn, avpn and flags */
1114         lhpte.dw1.dword1      = 0;
1115         lhpte.dw1.dw1.rpn     = arpn;
1116         lhpte.dw1.flags.flags = hpteflags;
1117
1118         lhpte.dw0.dword0      = 0;
1119         lhpte.dw0.dw0.avpn    = avpn;
1120         lhpte.dw0.dw0.bolted  = bolted;
1121         lhpte.dw0.dw0.v       = 1;
1122
1123         if (large) lhpte.dw0.dw0.l = 1;
1124
1125         /* Now fill in the actual HPTE */
1126         /* Set CEC cookie to 0         */
1127         /* Large page = 0              */
1128         /* Zero page = 0               */
1129         /* I-cache Invalidate = 0      */
1130         /* I-cache synchronize = 0     */
1131         /* Exact = 0                   */
1132         flags = 0;
1133
1134         /* XXX why is this here? - Anton */
1135         /*   -- Because at one point we hit a case where non cachable
1136          *      pages where marked coherent & this is rejected by the HV.
1137          *      Perhaps it is no longer an issue ... DRENG.
1138          */ 
1139         if (hpteflags & (_PAGE_GUARDED|_PAGE_NO_CACHE))
1140                 lhpte.dw1.flags.flags &= ~_PAGE_COHERENT;
1141
1142 repeat:
1143         secondary = 0;
1144         lhpte.dw0.dw0.h = secondary;
1145         hpte_group = ((hash & htab_data.htab_hash_mask) *
1146                       HPTES_PER_GROUP) & ~0x7UL;
1147
1148         __asm__ __volatile__ (
1149                 H_ENTER_r3
1150                 "mr    4, %2\n"
1151                 "mr    5, %3\n"
1152                 "mr    6, %4\n"
1153                 "mr    7, %5\n"
1154                 HSC    
1155                 "mr    %0, 3\n"
1156                 "mr    %1, 4\n"
1157                 : "=r" (lpar_rc), "=r" (slot)
1158                 : "r" (flags), "r" (hpte_group), "r" (lhpte.dw0.dword0),
1159                 "r" (lhpte.dw1.dword1)
1160                 : "r0", "r3", "r4", "r5", "r6", "r7", 
1161                   "r8", "r9", "r10", "r11", "r12", "cc");
1162
1163         if (lpar_rc == H_PTEG_Full) {
1164                 secondary = 1;
1165                 lhpte.dw0.dw0.h = secondary;
1166                 hpte_group = ((~hash & htab_data.htab_hash_mask) *
1167                               HPTES_PER_GROUP) & ~0x7UL;
1168
1169                 __asm__ __volatile__ (
1170                               H_ENTER_r3
1171                               "mr    4, %2\n"
1172                               "mr    5, %3\n"
1173                               "mr    6, %4\n"
1174                               "mr    7, %5\n"
1175                               HSC    
1176                               "mr    %0, 3\n"
1177                               "mr    %1, 4\n"
1178                               : "=r" (lpar_rc), "=r" (slot)
1179                               : "r" (flags), "r" (hpte_group), "r" (lhpte.dw0.dword0),
1180                               "r" (lhpte.dw1.dword1)
1181                               : "r0", "r3", "r4", "r5", "r6", "r7",
1182                                 "r8", "r9", "r10", "r11", "r12", "cc");
1183                 if (lpar_rc == H_PTEG_Full) {
1184                         if (mftb() & 0x1)
1185                                 hpte_group=((hash & htab_data.htab_hash_mask)* 
1186                                             HPTES_PER_GROUP) & ~0x7UL;
1187                         
1188                         rpa_lpar_hpte_remove(hpte_group);
1189                         goto repeat;
1190                 }
1191         }
1192
1193         if (lpar_rc != H_Success)
1194                 panic("Bad return code from pte enter rc = %lx\n", lpar_rc);
1195
1196         return ((secondary << 3) | (slot & 0x7));
1197 }
1198
1199 static long iSeries_hpte_insert(unsigned long vpn, unsigned long prpn,
1200                                 unsigned long hpteflags,
1201                                 int bolted, int large)
1202 {
1203         HPTE lhpte;
1204         unsigned long hash, hpte_group;
1205         unsigned long avpn = vpn >> 11;
1206         unsigned long arpn = physRpn_to_absRpn( prpn );
1207         int secondary = 0;
1208         long slot;
1209
1210         hash = hpt_hash(vpn, 0);
1211
1212 repeat:
1213         slot = HvCallHpt_findValid(&lhpte, vpn);
1214         if (lhpte.dw0.dw0.v) {
1215                 panic("select_hpte_slot found entry already valid\n");
1216         }
1217
1218         if (slot == -1) { /* No available entry found in either group */
1219                 if (mftb() & 0x1) {
1220                         hpte_group=((hash & htab_data.htab_hash_mask)* 
1221                                     HPTES_PER_GROUP) & ~0x7UL;
1222                 } else {
1223                         hpte_group=((~hash & htab_data.htab_hash_mask)* 
1224                                     HPTES_PER_GROUP) & ~0x7UL;
1225                 }
1226
1227                 hash = hpt_hash(vpn, 0);
1228                 iSeries_hpte_remove(hpte_group);
1229                 goto repeat;
1230         } else if (slot < 0) {
1231                 slot &= 0x7fffffffffffffff;
1232                 secondary = 1;
1233         }
1234
1235         /* Create the HPTE */
1236         lhpte.dw1.dword1      = 0;
1237         lhpte.dw1.dw1.rpn     = arpn;
1238         lhpte.dw1.flags.flags = hpteflags;
1239
1240         lhpte.dw0.dword0     = 0;
1241         lhpte.dw0.dw0.avpn   = avpn;
1242         lhpte.dw0.dw0.h      = secondary;
1243         lhpte.dw0.dw0.bolted = bolted;
1244         lhpte.dw0.dw0.v      = 1;
1245
1246         /* Now fill in the actual HPTE */
1247         HvCallHpt_addValidate(slot, secondary, (HPTE *)&lhpte);
1248         return ((secondary << 3) | (slot & 0x7));
1249 }
1250
1251 /*
1252  * Functions used to remove hardware page table entries.
1253  *
1254  * Input : hpte_group: PTE index of the first entry in a group
1255  * Output: offset within the group of the entry removed or
1256  *         -1 on failure
1257  */
1258 static long hpte_remove(unsigned long hpte_group)
1259 {
1260         HPTE *hptep;
1261         Hpte_dword0 dw0;
1262         int i;
1263         int slot_offset;
1264         unsigned long vsid, group, pi, pi_high;
1265         unsigned long slot;
1266         unsigned long flags;
1267         int large;
1268         unsigned long va;
1269
1270         /* pick a random slot to start at */
1271         slot_offset = mftb() & 0x7;
1272
1273         for (i = 0; i < HPTES_PER_GROUP; i++) {
1274                 hptep = htab_data.htab + hpte_group + slot_offset;
1275                 dw0 = hptep->dw0.dw0;
1276
1277                 if (dw0.v && !dw0.bolted) {
1278                         /* retry with lock held */
1279                         dw0 = hptep->dw0.dw0;
1280                         if (dw0.v && !dw0.bolted)
1281                                 break;
1282                 }
1283
1284                 slot_offset++;
1285                 slot_offset &= 0x7;
1286         }
1287
1288         if (i == HPTES_PER_GROUP)
1289                 return -1;
1290
1291         large = dw0.l;
1292
1293         /* Invalidate the hpte. NOTE: this also unlocks it */
1294         hptep->dw0.dword0 = 0;
1295
1296         /* Invalidate the tlb */
1297         vsid = dw0.avpn >> 5;
1298         slot = hptep - htab_data.htab;
1299         group = slot >> 3;
1300         if (dw0.h)
1301                 group = ~group;
1302         pi = (vsid ^ group) & 0x7ff;
1303         pi_high = (dw0.avpn & 0x1f) << 11;
1304         pi |= pi_high;
1305
1306         if (large)
1307                 va = pi << LARGE_PAGE_SHIFT;
1308         else
1309                 va = pi << PAGE_SHIFT;
1310
1311         spin_lock_irqsave(&pSeries_tlbie_lock, flags);
1312         _tlbie(va, large);
1313         spin_unlock_irqrestore(&pSeries_tlbie_lock, flags);
1314
1315         return i;
1316 }
1317
1318 static long rpa_lpar_hpte_remove(unsigned long hpte_group)
1319 {
1320         unsigned long slot_offset;
1321         unsigned long lpar_rc;
1322         int i;
1323         unsigned long dummy1, dummy2;
1324
1325         /* pick a random slot to start at */
1326         slot_offset = mftb() & 0x7;
1327
1328         for (i = 0; i < HPTES_PER_GROUP; i++) {
1329
1330                 /* Don't remove a bolted entry */
1331                 lpar_rc = plpar_pte_remove(H_ANDCOND, hpte_group + slot_offset,
1332                                            (0x1UL << 4), &dummy1, &dummy2);
1333
1334                 if (lpar_rc == H_Success)
1335                         return i;
1336
1337                 if (lpar_rc != H_Not_Found)
1338                         panic("Bad return code from pte remove rc = %lx\n",
1339                               lpar_rc);
1340
1341                 slot_offset++;
1342                 slot_offset &= 0x7;
1343         }
1344
1345         return -1;
1346 }
1347
1348 static long iSeries_hpte_remove(unsigned long hpte_group)
1349 {
1350         unsigned long slot_offset;
1351         int i;
1352         HPTE lhpte;
1353
1354         /* Pick a random slot to start at */
1355         slot_offset = mftb() & 0x7;
1356
1357         for (i = 0; i < HPTES_PER_GROUP; i++) {
1358                 lhpte.dw0.dword0 = 
1359                         iSeries_hpte_getword0(hpte_group + slot_offset);
1360
1361                 if (!lhpte.dw0.dw0.bolted) {
1362                         HvCallHpt_invalidateSetSwBitsGet(hpte_group + 
1363                                                          slot_offset, 0, 0);
1364                         return i;
1365                 }
1366
1367                 slot_offset++;
1368                 slot_offset &= 0x7;
1369         }
1370
1371         return -1;
1372 }
1373
1374 void hpte_init_pSeries(void)
1375 {
1376         ppc_md.hpte_invalidate     = hpte_invalidate;
1377         ppc_md.hpte_updatepp       = hpte_updatepp;
1378         ppc_md.hpte_updateboltedpp = hpte_updateboltedpp;
1379         ppc_md.hpte_insert         = hpte_insert;
1380         ppc_md.hpte_remove         = hpte_remove;
1381 }
1382
1383 void pSeries_lpar_mm_init(void)
1384 {
1385         ppc_md.hpte_invalidate     = rpa_lpar_hpte_invalidate;
1386         ppc_md.hpte_updatepp       = rpa_lpar_hpte_updatepp;
1387         ppc_md.hpte_updateboltedpp = rpa_lpar_hpte_updateboltedpp;
1388         ppc_md.hpte_insert         = rpa_lpar_hpte_insert;
1389         ppc_md.hpte_remove         = rpa_lpar_hpte_remove;
1390 }
1391
1392 void hpte_init_iSeries(void)
1393 {
1394         ppc_md.hpte_invalidate     = iSeries_hpte_invalidate;
1395         ppc_md.hpte_updatepp       = iSeries_hpte_updatepp;
1396         ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp;
1397         ppc_md.hpte_insert         = iSeries_hpte_insert;
1398         ppc_md.hpte_remove         = iSeries_hpte_remove;
1399 }
1400