book3s_hv_rm_mmu.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. /*
  2. * This program is free software; you can redistribute it and/or modify
  3. * it under the terms of the GNU General Public License, version 2, as
  4. * published by the Free Software Foundation.
  5. *
  6. * Copyright 2010-2011 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
  7. */
  8. #include <linux/types.h>
  9. #include <linux/string.h>
  10. #include <linux/kvm.h>
  11. #include <linux/kvm_host.h>
  12. #include <linux/hugetlb.h>
  13. #include <linux/module.h>
  14. #include <asm/tlbflush.h>
  15. #include <asm/kvm_ppc.h>
  16. #include <asm/kvm_book3s.h>
  17. #include <asm/mmu-hash64.h>
  18. #include <asm/hvcall.h>
  19. #include <asm/synch.h>
  20. #include <asm/ppc-opcode.h>
  21. /*
  22. * Since this file is built in even if KVM is a module, we need
  23. * a local copy of this function for the case where kvm_main.c is
  24. * modular.
  25. */
  26. static struct kvm_memory_slot *builtin_gfn_to_memslot(struct kvm *kvm,
  27. gfn_t gfn)
  28. {
  29. struct kvm_memslots *slots;
  30. struct kvm_memory_slot *memslot;
  31. slots = kvm_memslots(kvm);
  32. kvm_for_each_memslot(memslot, slots)
  33. if (gfn >= memslot->base_gfn &&
  34. gfn < memslot->base_gfn + memslot->npages)
  35. return memslot;
  36. return NULL;
  37. }
  38. /* Translate address of a vmalloc'd thing to a linear map address */
  39. static void *real_vmalloc_addr(void *x)
  40. {
  41. unsigned long addr = (unsigned long) x;
  42. pte_t *p;
  43. p = find_linux_pte(swapper_pg_dir, addr);
  44. if (!p || !pte_present(*p))
  45. return NULL;
  46. /* assume we don't have huge pages in vmalloc space... */
  47. addr = (pte_pfn(*p) << PAGE_SHIFT) | (addr & ~PAGE_MASK);
  48. return __va(addr);
  49. }
  50. long kvmppc_h_enter(struct kvm_vcpu *vcpu, unsigned long flags,
  51. long pte_index, unsigned long pteh, unsigned long ptel)
  52. {
  53. struct kvm *kvm = vcpu->kvm;
  54. unsigned long i, pa, gpa, gfn, psize;
  55. unsigned long slot_fn;
  56. unsigned long *hpte;
  57. struct revmap_entry *rev;
  58. unsigned long g_ptel = ptel;
  59. struct kvm_memory_slot *memslot;
  60. unsigned long *physp, pte_size;
  61. bool realmode = vcpu->arch.vcore->vcore_state == VCORE_RUNNING;
  62. psize = hpte_page_size(pteh, ptel);
  63. if (!psize)
  64. return H_PARAMETER;
  65. /* Find the memslot (if any) for this address */
  66. gpa = (ptel & HPTE_R_RPN) & ~(psize - 1);
  67. gfn = gpa >> PAGE_SHIFT;
  68. memslot = builtin_gfn_to_memslot(kvm, gfn);
  69. if (!(memslot && !(memslot->flags & KVM_MEMSLOT_INVALID)))
  70. return H_PARAMETER;
  71. slot_fn = gfn - memslot->base_gfn;
  72. physp = kvm->arch.slot_phys[memslot->id];
  73. if (!physp)
  74. return H_PARAMETER;
  75. physp += slot_fn;
  76. if (realmode)
  77. physp = real_vmalloc_addr(physp);
  78. pa = *physp;
  79. if (!pa)
  80. return H_TOO_HARD;
  81. pa &= PAGE_MASK;
  82. pte_size = kvm->arch.ram_psize;
  83. if (pte_size < psize)
  84. return H_PARAMETER;
  85. if (pa && pte_size > psize)
  86. pa |= gpa & (pte_size - 1);
  87. ptel &= ~(HPTE_R_PP0 - psize);
  88. ptel |= pa;
  89. /* Check WIMG */
  90. if ((ptel & HPTE_R_WIMG) != HPTE_R_M &&
  91. (ptel & HPTE_R_WIMG) != (HPTE_R_W | HPTE_R_I | HPTE_R_M))
  92. return H_PARAMETER;
  93. pteh &= ~0x60UL;
  94. pteh |= HPTE_V_VALID;
  95. if (pte_index >= HPT_NPTE)
  96. return H_PARAMETER;
  97. if (likely((flags & H_EXACT) == 0)) {
  98. pte_index &= ~7UL;
  99. hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4));
  100. for (i = 0; i < 8; ++i) {
  101. if ((*hpte & HPTE_V_VALID) == 0 &&
  102. try_lock_hpte(hpte, HPTE_V_HVLOCK | HPTE_V_VALID))
  103. break;
  104. hpte += 2;
  105. }
  106. if (i == 8) {
  107. /*
  108. * Since try_lock_hpte doesn't retry (not even stdcx.
  109. * failures), it could be that there is a free slot
  110. * but we transiently failed to lock it. Try again,
  111. * actually locking each slot and checking it.
  112. */
  113. hpte -= 16;
  114. for (i = 0; i < 8; ++i) {
  115. while (!try_lock_hpte(hpte, HPTE_V_HVLOCK))
  116. cpu_relax();
  117. if ((*hpte & HPTE_V_VALID) == 0)
  118. break;
  119. *hpte &= ~HPTE_V_HVLOCK;
  120. hpte += 2;
  121. }
  122. if (i == 8)
  123. return H_PTEG_FULL;
  124. }
  125. pte_index += i;
  126. } else {
  127. hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4));
  128. if (!try_lock_hpte(hpte, HPTE_V_HVLOCK | HPTE_V_VALID)) {
  129. /* Lock the slot and check again */
  130. while (!try_lock_hpte(hpte, HPTE_V_HVLOCK))
  131. cpu_relax();
  132. if (*hpte & HPTE_V_VALID) {
  133. *hpte &= ~HPTE_V_HVLOCK;
  134. return H_PTEG_FULL;
  135. }
  136. }
  137. }
  138. /* Save away the guest's idea of the second HPTE dword */
  139. rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]);
  140. if (rev)
  141. rev->guest_rpte = g_ptel;
  142. hpte[1] = ptel;
  143. eieio();
  144. hpte[0] = pteh;
  145. asm volatile("ptesync" : : : "memory");
  146. vcpu->arch.gpr[4] = pte_index;
  147. return H_SUCCESS;
  148. }
  149. EXPORT_SYMBOL_GPL(kvmppc_h_enter);
  150. #define LOCK_TOKEN (*(u32 *)(&get_paca()->lock_token))
  151. static inline int try_lock_tlbie(unsigned int *lock)
  152. {
  153. unsigned int tmp, old;
  154. unsigned int token = LOCK_TOKEN;
  155. asm volatile("1:lwarx %1,0,%2\n"
  156. " cmpwi cr0,%1,0\n"
  157. " bne 2f\n"
  158. " stwcx. %3,0,%2\n"
  159. " bne- 1b\n"
  160. " isync\n"
  161. "2:"
  162. : "=&r" (tmp), "=&r" (old)
  163. : "r" (lock), "r" (token)
  164. : "cc", "memory");
  165. return old == 0;
  166. }
  167. long kvmppc_h_remove(struct kvm_vcpu *vcpu, unsigned long flags,
  168. unsigned long pte_index, unsigned long avpn,
  169. unsigned long va)
  170. {
  171. struct kvm *kvm = vcpu->kvm;
  172. unsigned long *hpte;
  173. unsigned long v, r, rb;
  174. if (pte_index >= HPT_NPTE)
  175. return H_PARAMETER;
  176. hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4));
  177. while (!try_lock_hpte(hpte, HPTE_V_HVLOCK))
  178. cpu_relax();
  179. if ((hpte[0] & HPTE_V_VALID) == 0 ||
  180. ((flags & H_AVPN) && (hpte[0] & ~0x7fUL) != avpn) ||
  181. ((flags & H_ANDCOND) && (hpte[0] & avpn) != 0)) {
  182. hpte[0] &= ~HPTE_V_HVLOCK;
  183. return H_NOT_FOUND;
  184. }
  185. if (atomic_read(&kvm->online_vcpus) == 1)
  186. flags |= H_LOCAL;
  187. vcpu->arch.gpr[4] = v = hpte[0] & ~HPTE_V_HVLOCK;
  188. vcpu->arch.gpr[5] = r = hpte[1];
  189. rb = compute_tlbie_rb(v, r, pte_index);
  190. hpte[0] = 0;
  191. if (!(flags & H_LOCAL)) {
  192. while(!try_lock_tlbie(&kvm->arch.tlbie_lock))
  193. cpu_relax();
  194. asm volatile("ptesync" : : : "memory");
  195. asm volatile(PPC_TLBIE(%1,%0)"; eieio; tlbsync"
  196. : : "r" (rb), "r" (kvm->arch.lpid));
  197. asm volatile("ptesync" : : : "memory");
  198. kvm->arch.tlbie_lock = 0;
  199. } else {
  200. asm volatile("ptesync" : : : "memory");
  201. asm volatile("tlbiel %0" : : "r" (rb));
  202. asm volatile("ptesync" : : : "memory");
  203. }
  204. return H_SUCCESS;
  205. }
  206. long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu)
  207. {
  208. struct kvm *kvm = vcpu->kvm;
  209. unsigned long *args = &vcpu->arch.gpr[4];
  210. unsigned long *hp, tlbrb[4];
  211. long int i, found;
  212. long int n_inval = 0;
  213. unsigned long flags, req, pte_index;
  214. long int local = 0;
  215. long int ret = H_SUCCESS;
  216. if (atomic_read(&kvm->online_vcpus) == 1)
  217. local = 1;
  218. for (i = 0; i < 4; ++i) {
  219. pte_index = args[i * 2];
  220. flags = pte_index >> 56;
  221. pte_index &= ((1ul << 56) - 1);
  222. req = flags >> 6;
  223. flags &= 3;
  224. if (req == 3)
  225. break;
  226. if (req != 1 || flags == 3 ||
  227. pte_index >= HPT_NPTE) {
  228. /* parameter error */
  229. args[i * 2] = ((0xa0 | flags) << 56) + pte_index;
  230. ret = H_PARAMETER;
  231. break;
  232. }
  233. hp = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4));
  234. while (!try_lock_hpte(hp, HPTE_V_HVLOCK))
  235. cpu_relax();
  236. found = 0;
  237. if (hp[0] & HPTE_V_VALID) {
  238. switch (flags & 3) {
  239. case 0: /* absolute */
  240. found = 1;
  241. break;
  242. case 1: /* andcond */
  243. if (!(hp[0] & args[i * 2 + 1]))
  244. found = 1;
  245. break;
  246. case 2: /* AVPN */
  247. if ((hp[0] & ~0x7fUL) == args[i * 2 + 1])
  248. found = 1;
  249. break;
  250. }
  251. }
  252. if (!found) {
  253. hp[0] &= ~HPTE_V_HVLOCK;
  254. args[i * 2] = ((0x90 | flags) << 56) + pte_index;
  255. continue;
  256. }
  257. /* insert R and C bits from PTE */
  258. flags |= (hp[1] >> 5) & 0x0c;
  259. args[i * 2] = ((0x80 | flags) << 56) + pte_index;
  260. tlbrb[n_inval++] = compute_tlbie_rb(hp[0], hp[1], pte_index);
  261. hp[0] = 0;
  262. }
  263. if (n_inval == 0)
  264. return ret;
  265. if (!local) {
  266. while(!try_lock_tlbie(&kvm->arch.tlbie_lock))
  267. cpu_relax();
  268. asm volatile("ptesync" : : : "memory");
  269. for (i = 0; i < n_inval; ++i)
  270. asm volatile(PPC_TLBIE(%1,%0)
  271. : : "r" (tlbrb[i]), "r" (kvm->arch.lpid));
  272. asm volatile("eieio; tlbsync; ptesync" : : : "memory");
  273. kvm->arch.tlbie_lock = 0;
  274. } else {
  275. asm volatile("ptesync" : : : "memory");
  276. for (i = 0; i < n_inval; ++i)
  277. asm volatile("tlbiel %0" : : "r" (tlbrb[i]));
  278. asm volatile("ptesync" : : : "memory");
  279. }
  280. return ret;
  281. }
  282. long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags,
  283. unsigned long pte_index, unsigned long avpn,
  284. unsigned long va)
  285. {
  286. struct kvm *kvm = vcpu->kvm;
  287. unsigned long *hpte;
  288. struct revmap_entry *rev;
  289. unsigned long v, r, rb, mask, bits;
  290. if (pte_index >= HPT_NPTE)
  291. return H_PARAMETER;
  292. hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4));
  293. while (!try_lock_hpte(hpte, HPTE_V_HVLOCK))
  294. cpu_relax();
  295. if ((hpte[0] & HPTE_V_VALID) == 0 ||
  296. ((flags & H_AVPN) && (hpte[0] & ~0x7fUL) != avpn)) {
  297. hpte[0] &= ~HPTE_V_HVLOCK;
  298. return H_NOT_FOUND;
  299. }
  300. if (atomic_read(&kvm->online_vcpus) == 1)
  301. flags |= H_LOCAL;
  302. v = hpte[0];
  303. bits = (flags << 55) & HPTE_R_PP0;
  304. bits |= (flags << 48) & HPTE_R_KEY_HI;
  305. bits |= flags & (HPTE_R_PP | HPTE_R_N | HPTE_R_KEY_LO);
  306. /* Update guest view of 2nd HPTE dword */
  307. mask = HPTE_R_PP0 | HPTE_R_PP | HPTE_R_N |
  308. HPTE_R_KEY_HI | HPTE_R_KEY_LO;
  309. rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]);
  310. if (rev) {
  311. r = (rev->guest_rpte & ~mask) | bits;
  312. rev->guest_rpte = r;
  313. }
  314. r = (hpte[1] & ~mask) | bits;
  315. /* Update HPTE */
  316. rb = compute_tlbie_rb(v, r, pte_index);
  317. hpte[0] = v & ~HPTE_V_VALID;
  318. if (!(flags & H_LOCAL)) {
  319. while(!try_lock_tlbie(&kvm->arch.tlbie_lock))
  320. cpu_relax();
  321. asm volatile("ptesync" : : : "memory");
  322. asm volatile(PPC_TLBIE(%1,%0)"; eieio; tlbsync"
  323. : : "r" (rb), "r" (kvm->arch.lpid));
  324. asm volatile("ptesync" : : : "memory");
  325. kvm->arch.tlbie_lock = 0;
  326. } else {
  327. asm volatile("ptesync" : : : "memory");
  328. asm volatile("tlbiel %0" : : "r" (rb));
  329. asm volatile("ptesync" : : : "memory");
  330. }
  331. hpte[1] = r;
  332. eieio();
  333. hpte[0] = v & ~HPTE_V_HVLOCK;
  334. asm volatile("ptesync" : : : "memory");
  335. return H_SUCCESS;
  336. }
  337. long kvmppc_h_read(struct kvm_vcpu *vcpu, unsigned long flags,
  338. unsigned long pte_index)
  339. {
  340. struct kvm *kvm = vcpu->kvm;
  341. unsigned long *hpte, r;
  342. int i, n = 1;
  343. struct revmap_entry *rev = NULL;
  344. if (pte_index >= HPT_NPTE)
  345. return H_PARAMETER;
  346. if (flags & H_READ_4) {
  347. pte_index &= ~3;
  348. n = 4;
  349. }
  350. if (flags & H_R_XLATE)
  351. rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]);
  352. for (i = 0; i < n; ++i, ++pte_index) {
  353. hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4));
  354. r = hpte[1];
  355. if (hpte[0] & HPTE_V_VALID) {
  356. if (rev)
  357. r = rev[i].guest_rpte;
  358. else
  359. r = hpte[1] | HPTE_R_RPN;
  360. }
  361. vcpu->arch.gpr[4 + i * 2] = hpte[0];
  362. vcpu->arch.gpr[5 + i * 2] = r;
  363. }
  364. return H_SUCCESS;
  365. }