hash_native.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. /*
  2. * native hashtable management.
  3. *
  4. * SMP scalability work:
  5. * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version
  10. * 2 of the License, or (at your option) any later version.
  11. */
  12. #include <linux/spinlock.h>
  13. #include <linux/bitops.h>
  14. #include <linux/threads.h>
  15. #include <linux/smp.h>
  16. #include <asm/abs_addr.h>
  17. #include <asm/machdep.h>
  18. #include <asm/mmu.h>
  19. #include <asm/mmu_context.h>
  20. #include <asm/pgtable.h>
  21. #include <asm/tlbflush.h>
  22. #include <asm/tlb.h>
  23. #include <asm/cputable.h>
  24. #define HPTE_LOCK_BIT 3
  25. static DEFINE_SPINLOCK(native_tlbie_lock);
  26. static inline void native_lock_hpte(HPTE *hptep)
  27. {
  28. unsigned long *word = &hptep->dw0.dword0;
  29. while (1) {
  30. if (!test_and_set_bit(HPTE_LOCK_BIT, word))
  31. break;
  32. while(test_bit(HPTE_LOCK_BIT, word))
  33. cpu_relax();
  34. }
  35. }
  36. static inline void native_unlock_hpte(HPTE *hptep)
  37. {
  38. unsigned long *word = &hptep->dw0.dword0;
  39. asm volatile("lwsync":::"memory");
  40. clear_bit(HPTE_LOCK_BIT, word);
  41. }
  42. long native_hpte_insert(unsigned long hpte_group, unsigned long va,
  43. unsigned long prpn, int secondary,
  44. unsigned long hpteflags, int bolted, int large)
  45. {
  46. unsigned long arpn = physRpn_to_absRpn(prpn);
  47. HPTE *hptep = htab_address + hpte_group;
  48. Hpte_dword0 dw0;
  49. HPTE lhpte;
  50. int i;
  51. for (i = 0; i < HPTES_PER_GROUP; i++) {
  52. dw0 = hptep->dw0.dw0;
  53. if (!dw0.v) {
  54. /* retry with lock held */
  55. native_lock_hpte(hptep);
  56. dw0 = hptep->dw0.dw0;
  57. if (!dw0.v)
  58. break;
  59. native_unlock_hpte(hptep);
  60. }
  61. hptep++;
  62. }
  63. if (i == HPTES_PER_GROUP)
  64. return -1;
  65. lhpte.dw1.dword1 = 0;
  66. lhpte.dw1.dw1.rpn = arpn;
  67. lhpte.dw1.flags.flags = hpteflags;
  68. lhpte.dw0.dword0 = 0;
  69. lhpte.dw0.dw0.avpn = va >> 23;
  70. lhpte.dw0.dw0.h = secondary;
  71. lhpte.dw0.dw0.bolted = bolted;
  72. lhpte.dw0.dw0.v = 1;
  73. if (large) {
  74. lhpte.dw0.dw0.l = 1;
  75. lhpte.dw0.dw0.avpn &= ~0x1UL;
  76. }
  77. hptep->dw1.dword1 = lhpte.dw1.dword1;
  78. /* Guarantee the second dword is visible before the valid bit */
  79. __asm__ __volatile__ ("eieio" : : : "memory");
  80. /*
  81. * Now set the first dword including the valid bit
  82. * NOTE: this also unlocks the hpte
  83. */
  84. hptep->dw0.dword0 = lhpte.dw0.dword0;
  85. __asm__ __volatile__ ("ptesync" : : : "memory");
  86. return i | (secondary << 3);
  87. }
  88. static long native_hpte_remove(unsigned long hpte_group)
  89. {
  90. HPTE *hptep;
  91. Hpte_dword0 dw0;
  92. int i;
  93. int slot_offset;
  94. /* pick a random entry to start at */
  95. slot_offset = mftb() & 0x7;
  96. for (i = 0; i < HPTES_PER_GROUP; i++) {
  97. hptep = htab_address + hpte_group + slot_offset;
  98. dw0 = hptep->dw0.dw0;
  99. if (dw0.v && !dw0.bolted) {
  100. /* retry with lock held */
  101. native_lock_hpte(hptep);
  102. dw0 = hptep->dw0.dw0;
  103. if (dw0.v && !dw0.bolted)
  104. break;
  105. native_unlock_hpte(hptep);
  106. }
  107. slot_offset++;
  108. slot_offset &= 0x7;
  109. }
  110. if (i == HPTES_PER_GROUP)
  111. return -1;
  112. /* Invalidate the hpte. NOTE: this also unlocks it */
  113. hptep->dw0.dword0 = 0;
  114. return i;
  115. }
  116. static inline void set_pp_bit(unsigned long pp, HPTE *addr)
  117. {
  118. unsigned long old;
  119. unsigned long *p = &addr->dw1.dword1;
  120. __asm__ __volatile__(
  121. "1: ldarx %0,0,%3\n\
  122. rldimi %0,%2,0,61\n\
  123. stdcx. %0,0,%3\n\
  124. bne 1b"
  125. : "=&r" (old), "=m" (*p)
  126. : "r" (pp), "r" (p), "m" (*p)
  127. : "cc");
  128. }
  129. /*
  130. * Only works on small pages. Yes its ugly to have to check each slot in
  131. * the group but we only use this during bootup.
  132. */
  133. static long native_hpte_find(unsigned long vpn)
  134. {
  135. HPTE *hptep;
  136. unsigned long hash;
  137. unsigned long i, j;
  138. long slot;
  139. Hpte_dword0 dw0;
  140. hash = hpt_hash(vpn, 0);
  141. for (j = 0; j < 2; j++) {
  142. slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
  143. for (i = 0; i < HPTES_PER_GROUP; i++) {
  144. hptep = htab_address + slot;
  145. dw0 = hptep->dw0.dw0;
  146. if ((dw0.avpn == (vpn >> 11)) && dw0.v &&
  147. (dw0.h == j)) {
  148. /* HPTE matches */
  149. if (j)
  150. slot = -slot;
  151. return slot;
  152. }
  153. ++slot;
  154. }
  155. hash = ~hash;
  156. }
  157. return -1;
  158. }
  159. static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
  160. unsigned long va, int large, int local)
  161. {
  162. HPTE *hptep = htab_address + slot;
  163. Hpte_dword0 dw0;
  164. unsigned long avpn = va >> 23;
  165. int ret = 0;
  166. if (large)
  167. avpn &= ~0x1UL;
  168. native_lock_hpte(hptep);
  169. dw0 = hptep->dw0.dw0;
  170. /* Even if we miss, we need to invalidate the TLB */
  171. if ((dw0.avpn != avpn) || !dw0.v) {
  172. native_unlock_hpte(hptep);
  173. ret = -1;
  174. } else {
  175. set_pp_bit(newpp, hptep);
  176. native_unlock_hpte(hptep);
  177. }
  178. /* Ensure it is out of the tlb too */
  179. if (cpu_has_feature(CPU_FTR_TLBIEL) && !large && local) {
  180. tlbiel(va);
  181. } else {
  182. int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
  183. if (lock_tlbie)
  184. spin_lock(&native_tlbie_lock);
  185. tlbie(va, large);
  186. if (lock_tlbie)
  187. spin_unlock(&native_tlbie_lock);
  188. }
  189. return ret;
  190. }
  191. /*
  192. * Update the page protection bits. Intended to be used to create
  193. * guard pages for kernel data structures on pages which are bolted
  194. * in the HPT. Assumes pages being operated on will not be stolen.
  195. * Does not work on large pages.
  196. *
  197. * No need to lock here because we should be the only user.
  198. */
  199. static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea)
  200. {
  201. unsigned long vsid, va, vpn, flags = 0;
  202. long slot;
  203. HPTE *hptep;
  204. int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
  205. vsid = get_kernel_vsid(ea);
  206. va = (vsid << 28) | (ea & 0x0fffffff);
  207. vpn = va >> PAGE_SHIFT;
  208. slot = native_hpte_find(vpn);
  209. if (slot == -1)
  210. panic("could not find page to bolt\n");
  211. hptep = htab_address + slot;
  212. set_pp_bit(newpp, hptep);
  213. /* Ensure it is out of the tlb too */
  214. if (lock_tlbie)
  215. spin_lock_irqsave(&native_tlbie_lock, flags);
  216. tlbie(va, 0);
  217. if (lock_tlbie)
  218. spin_unlock_irqrestore(&native_tlbie_lock, flags);
  219. }
  220. static void native_hpte_invalidate(unsigned long slot, unsigned long va,
  221. int large, int local)
  222. {
  223. HPTE *hptep = htab_address + slot;
  224. Hpte_dword0 dw0;
  225. unsigned long avpn = va >> 23;
  226. unsigned long flags;
  227. int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
  228. if (large)
  229. avpn &= ~0x1UL;
  230. local_irq_save(flags);
  231. native_lock_hpte(hptep);
  232. dw0 = hptep->dw0.dw0;
  233. /* Even if we miss, we need to invalidate the TLB */
  234. if ((dw0.avpn != avpn) || !dw0.v) {
  235. native_unlock_hpte(hptep);
  236. } else {
  237. /* Invalidate the hpte. NOTE: this also unlocks it */
  238. hptep->dw0.dword0 = 0;
  239. }
  240. /* Invalidate the tlb */
  241. if (cpu_has_feature(CPU_FTR_TLBIEL) && !large && local) {
  242. tlbiel(va);
  243. } else {
  244. if (lock_tlbie)
  245. spin_lock(&native_tlbie_lock);
  246. tlbie(va, large);
  247. if (lock_tlbie)
  248. spin_unlock(&native_tlbie_lock);
  249. }
  250. local_irq_restore(flags);
  251. }
  252. /*
  253. * clear all mappings on kexec. All cpus are in real mode (or they will
  254. * be when they isi), and we are the only one left. We rely on our kernel
  255. * mapping being 0xC0's and the hardware ignoring those two real bits.
  256. *
  257. * TODO: add batching support when enabled. remember, no dynamic memory here,
  258. * athough there is the control page available...
  259. */
  260. static void native_hpte_clear(void)
  261. {
  262. unsigned long slot, slots, flags;
  263. HPTE *hptep = htab_address;
  264. Hpte_dword0 dw0;
  265. unsigned long pteg_count;
  266. pteg_count = htab_hash_mask + 1;
  267. local_irq_save(flags);
  268. /* we take the tlbie lock and hold it. Some hardware will
  269. * deadlock if we try to tlbie from two processors at once.
  270. */
  271. spin_lock(&native_tlbie_lock);
  272. slots = pteg_count * HPTES_PER_GROUP;
  273. for (slot = 0; slot < slots; slot++, hptep++) {
  274. /*
  275. * we could lock the pte here, but we are the only cpu
  276. * running, right? and for crash dump, we probably
  277. * don't want to wait for a maybe bad cpu.
  278. */
  279. dw0 = hptep->dw0.dw0;
  280. if (dw0.v) {
  281. hptep->dw0.dword0 = 0;
  282. tlbie(slot2va(dw0.avpn, dw0.l, dw0.h, slot), dw0.l);
  283. }
  284. }
  285. spin_unlock(&native_tlbie_lock);
  286. local_irq_restore(flags);
  287. }
  288. static void native_flush_hash_range(unsigned long context,
  289. unsigned long number, int local)
  290. {
  291. unsigned long vsid, vpn, va, hash, secondary, slot, flags, avpn;
  292. int i, j;
  293. HPTE *hptep;
  294. Hpte_dword0 dw0;
  295. struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
  296. /* XXX fix for large ptes */
  297. unsigned long large = 0;
  298. local_irq_save(flags);
  299. j = 0;
  300. for (i = 0; i < number; i++) {
  301. if (batch->addr[i] < KERNELBASE)
  302. vsid = get_vsid(context, batch->addr[i]);
  303. else
  304. vsid = get_kernel_vsid(batch->addr[i]);
  305. va = (vsid << 28) | (batch->addr[i] & 0x0fffffff);
  306. batch->vaddr[j] = va;
  307. if (large)
  308. vpn = va >> HPAGE_SHIFT;
  309. else
  310. vpn = va >> PAGE_SHIFT;
  311. hash = hpt_hash(vpn, large);
  312. secondary = (pte_val(batch->pte[i]) & _PAGE_SECONDARY) >> 15;
  313. if (secondary)
  314. hash = ~hash;
  315. slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
  316. slot += (pte_val(batch->pte[i]) & _PAGE_GROUP_IX) >> 12;
  317. hptep = htab_address + slot;
  318. avpn = va >> 23;
  319. if (large)
  320. avpn &= ~0x1UL;
  321. native_lock_hpte(hptep);
  322. dw0 = hptep->dw0.dw0;
  323. /* Even if we miss, we need to invalidate the TLB */
  324. if ((dw0.avpn != avpn) || !dw0.v) {
  325. native_unlock_hpte(hptep);
  326. } else {
  327. /* Invalidate the hpte. NOTE: this also unlocks it */
  328. hptep->dw0.dword0 = 0;
  329. }
  330. j++;
  331. }
  332. if (cpu_has_feature(CPU_FTR_TLBIEL) && !large && local) {
  333. asm volatile("ptesync":::"memory");
  334. for (i = 0; i < j; i++)
  335. __tlbiel(batch->vaddr[i]);
  336. asm volatile("ptesync":::"memory");
  337. } else {
  338. int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
  339. if (lock_tlbie)
  340. spin_lock(&native_tlbie_lock);
  341. asm volatile("ptesync":::"memory");
  342. for (i = 0; i < j; i++)
  343. __tlbie(batch->vaddr[i], 0);
  344. asm volatile("eieio; tlbsync; ptesync":::"memory");
  345. if (lock_tlbie)
  346. spin_unlock(&native_tlbie_lock);
  347. }
  348. local_irq_restore(flags);
  349. }
  350. #ifdef CONFIG_PPC_PSERIES
  351. /* Disable TLB batching on nighthawk */
  352. static inline int tlb_batching_enabled(void)
  353. {
  354. struct device_node *root = of_find_node_by_path("/");
  355. int enabled = 1;
  356. if (root) {
  357. const char *model = get_property(root, "model", NULL);
  358. if (model && !strcmp(model, "IBM,9076-N81"))
  359. enabled = 0;
  360. of_node_put(root);
  361. }
  362. return enabled;
  363. }
  364. #else
  365. static inline int tlb_batching_enabled(void)
  366. {
  367. return 1;
  368. }
  369. #endif
  370. void hpte_init_native(void)
  371. {
  372. ppc_md.hpte_invalidate = native_hpte_invalidate;
  373. ppc_md.hpte_updatepp = native_hpte_updatepp;
  374. ppc_md.hpte_updateboltedpp = native_hpte_updateboltedpp;
  375. ppc_md.hpte_insert = native_hpte_insert;
  376. ppc_md.hpte_remove = native_hpte_remove;
  377. ppc_md.hpte_clear_all = native_hpte_clear;
  378. if (tlb_batching_enabled())
  379. ppc_md.flush_hash_range = native_flush_hash_range;
  380. htab_finish_init();
  381. }