book3s_hv_tm.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. * Copyright 2017 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License, version 2, as
  6. * published by the Free Software Foundation.
  7. */
  8. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  9. #include <linux/kvm_host.h>
  10. #include <asm/kvm_ppc.h>
  11. #include <asm/kvm_book3s.h>
  12. #include <asm/kvm_book3s_64.h>
  13. #include <asm/reg.h>
  14. #include <asm/ppc-opcode.h>
  15. static void emulate_tx_failure(struct kvm_vcpu *vcpu, u64 failure_cause)
  16. {
  17. u64 texasr, tfiar;
  18. u64 msr = vcpu->arch.shregs.msr;
  19. tfiar = vcpu->arch.regs.nip & ~0x3ull;
  20. texasr = (failure_cause << 56) | TEXASR_ABORT | TEXASR_FS | TEXASR_EXACT;
  21. if (MSR_TM_SUSPENDED(vcpu->arch.shregs.msr))
  22. texasr |= TEXASR_SUSP;
  23. if (msr & MSR_PR) {
  24. texasr |= TEXASR_PR;
  25. tfiar |= 1;
  26. }
  27. vcpu->arch.tfiar = tfiar;
  28. /* Preserve ROT and TL fields of existing TEXASR */
  29. vcpu->arch.texasr = (vcpu->arch.texasr & 0x3ffffff) | texasr;
  30. }
  31. /*
  32. * This gets called on a softpatch interrupt on POWER9 DD2.2 processors.
  33. * We expect to find a TM-related instruction to be emulated. The
  34. * instruction image is in vcpu->arch.emul_inst. If the guest was in
  35. * TM suspended or transactional state, the checkpointed state has been
  36. * reclaimed and is in the vcpu struct. The CPU is in virtual mode in
  37. * host context.
  38. */
  39. int kvmhv_p9_tm_emulation(struct kvm_vcpu *vcpu)
  40. {
  41. u32 instr = vcpu->arch.emul_inst;
  42. u64 msr = vcpu->arch.shregs.msr;
  43. u64 newmsr, bescr;
  44. int ra, rs;
  45. /*
  46. * rfid, rfebb, and mtmsrd encode bit 31 = 0 since it's a reserved bit
  47. * in these instructions, so masking bit 31 out doesn't change these
  48. * instructions. For treclaim., tsr., and trechkpt. instructions if bit
  49. * 31 = 0 then they are per ISA invalid forms, however P9 UM, in section
  50. * 4.6.10 Book II Invalid Forms, informs specifically that ignoring bit
  51. * 31 is an acceptable way to handle these invalid forms that have
  52. * bit 31 = 0. Moreover, for emulation purposes both forms (w/ and wo/
  53. * bit 31 set) can generate a softpatch interrupt. Hence both forms
  54. * are handled below for these instructions so they behave the same way.
  55. */
  56. switch (instr & PO_XOP_OPCODE_MASK) {
  57. case PPC_INST_RFID:
  58. /* XXX do we need to check for PR=0 here? */
  59. newmsr = vcpu->arch.shregs.srr1;
  60. /* should only get here for Sx -> T1 transition */
  61. WARN_ON_ONCE(!(MSR_TM_SUSPENDED(msr) &&
  62. MSR_TM_TRANSACTIONAL(newmsr) &&
  63. (newmsr & MSR_TM)));
  64. newmsr = sanitize_msr(newmsr);
  65. vcpu->arch.shregs.msr = newmsr;
  66. vcpu->arch.cfar = vcpu->arch.regs.nip - 4;
  67. vcpu->arch.regs.nip = vcpu->arch.shregs.srr0;
  68. return RESUME_GUEST;
  69. case PPC_INST_RFEBB:
  70. if ((msr & MSR_PR) && (vcpu->arch.vcore->pcr & PCR_ARCH_206)) {
  71. /* generate an illegal instruction interrupt */
  72. kvmppc_core_queue_program(vcpu, SRR1_PROGILL);
  73. return RESUME_GUEST;
  74. }
  75. /* check EBB facility is available */
  76. if (!(vcpu->arch.hfscr & HFSCR_EBB)) {
  77. /* generate an illegal instruction interrupt */
  78. kvmppc_core_queue_program(vcpu, SRR1_PROGILL);
  79. return RESUME_GUEST;
  80. }
  81. if ((msr & MSR_PR) && !(vcpu->arch.fscr & FSCR_EBB)) {
  82. /* generate a facility unavailable interrupt */
  83. vcpu->arch.fscr = (vcpu->arch.fscr & ~(0xffull << 56)) |
  84. ((u64)FSCR_EBB_LG << 56);
  85. kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_FAC_UNAVAIL);
  86. return RESUME_GUEST;
  87. }
  88. bescr = vcpu->arch.bescr;
  89. /* expect to see a S->T transition requested */
  90. WARN_ON_ONCE(!(MSR_TM_SUSPENDED(msr) &&
  91. ((bescr >> 30) & 3) == 2));
  92. bescr &= ~BESCR_GE;
  93. if (instr & (1 << 11))
  94. bescr |= BESCR_GE;
  95. vcpu->arch.bescr = bescr;
  96. msr = (msr & ~MSR_TS_MASK) | MSR_TS_T;
  97. vcpu->arch.shregs.msr = msr;
  98. vcpu->arch.cfar = vcpu->arch.regs.nip - 4;
  99. vcpu->arch.regs.nip = vcpu->arch.ebbrr;
  100. return RESUME_GUEST;
  101. case PPC_INST_MTMSRD:
  102. /* XXX do we need to check for PR=0 here? */
  103. rs = (instr >> 21) & 0x1f;
  104. newmsr = kvmppc_get_gpr(vcpu, rs);
  105. /* check this is a Sx -> T1 transition */
  106. WARN_ON_ONCE(!(MSR_TM_SUSPENDED(msr) &&
  107. MSR_TM_TRANSACTIONAL(newmsr) &&
  108. (newmsr & MSR_TM)));
  109. /* mtmsrd doesn't change LE */
  110. newmsr = (newmsr & ~MSR_LE) | (msr & MSR_LE);
  111. newmsr = sanitize_msr(newmsr);
  112. vcpu->arch.shregs.msr = newmsr;
  113. return RESUME_GUEST;
  114. /* ignore bit 31, see comment above */
  115. case (PPC_INST_TSR & PO_XOP_OPCODE_MASK):
  116. /* check for PR=1 and arch 2.06 bit set in PCR */
  117. if ((msr & MSR_PR) && (vcpu->arch.vcore->pcr & PCR_ARCH_206)) {
  118. /* generate an illegal instruction interrupt */
  119. kvmppc_core_queue_program(vcpu, SRR1_PROGILL);
  120. return RESUME_GUEST;
  121. }
  122. /* check for TM disabled in the HFSCR or MSR */
  123. if (!(vcpu->arch.hfscr & HFSCR_TM)) {
  124. /* generate an illegal instruction interrupt */
  125. kvmppc_core_queue_program(vcpu, SRR1_PROGILL);
  126. return RESUME_GUEST;
  127. }
  128. if (!(msr & MSR_TM)) {
  129. /* generate a facility unavailable interrupt */
  130. vcpu->arch.fscr = (vcpu->arch.fscr & ~(0xffull << 56)) |
  131. ((u64)FSCR_TM_LG << 56);
  132. kvmppc_book3s_queue_irqprio(vcpu,
  133. BOOK3S_INTERRUPT_FAC_UNAVAIL);
  134. return RESUME_GUEST;
  135. }
  136. /* Set CR0 to indicate previous transactional state */
  137. vcpu->arch.regs.ccr = (vcpu->arch.regs.ccr & 0x0fffffff) |
  138. (((msr & MSR_TS_MASK) >> MSR_TS_S_LG) << 29);
  139. /* L=1 => tresume, L=0 => tsuspend */
  140. if (instr & (1 << 21)) {
  141. if (MSR_TM_SUSPENDED(msr))
  142. msr = (msr & ~MSR_TS_MASK) | MSR_TS_T;
  143. } else {
  144. if (MSR_TM_TRANSACTIONAL(msr))
  145. msr = (msr & ~MSR_TS_MASK) | MSR_TS_S;
  146. }
  147. vcpu->arch.shregs.msr = msr;
  148. return RESUME_GUEST;
  149. /* ignore bit 31, see comment above */
  150. case (PPC_INST_TRECLAIM & PO_XOP_OPCODE_MASK):
  151. /* check for TM disabled in the HFSCR or MSR */
  152. if (!(vcpu->arch.hfscr & HFSCR_TM)) {
  153. /* generate an illegal instruction interrupt */
  154. kvmppc_core_queue_program(vcpu, SRR1_PROGILL);
  155. return RESUME_GUEST;
  156. }
  157. if (!(msr & MSR_TM)) {
  158. /* generate a facility unavailable interrupt */
  159. vcpu->arch.fscr = (vcpu->arch.fscr & ~(0xffull << 56)) |
  160. ((u64)FSCR_TM_LG << 56);
  161. kvmppc_book3s_queue_irqprio(vcpu,
  162. BOOK3S_INTERRUPT_FAC_UNAVAIL);
  163. return RESUME_GUEST;
  164. }
  165. /* If no transaction active, generate TM bad thing */
  166. if (!MSR_TM_ACTIVE(msr)) {
  167. kvmppc_core_queue_program(vcpu, SRR1_PROGTM);
  168. return RESUME_GUEST;
  169. }
  170. /* If failure was not previously recorded, recompute TEXASR */
  171. if (!(vcpu->arch.orig_texasr & TEXASR_FS)) {
  172. ra = (instr >> 16) & 0x1f;
  173. if (ra)
  174. ra = kvmppc_get_gpr(vcpu, ra) & 0xff;
  175. emulate_tx_failure(vcpu, ra);
  176. }
  177. copy_from_checkpoint(vcpu);
  178. /* Set CR0 to indicate previous transactional state */
  179. vcpu->arch.regs.ccr = (vcpu->arch.regs.ccr & 0x0fffffff) |
  180. (((msr & MSR_TS_MASK) >> MSR_TS_S_LG) << 29);
  181. vcpu->arch.shregs.msr &= ~MSR_TS_MASK;
  182. return RESUME_GUEST;
  183. /* ignore bit 31, see comment above */
  184. case (PPC_INST_TRECHKPT & PO_XOP_OPCODE_MASK):
  185. /* XXX do we need to check for PR=0 here? */
  186. /* check for TM disabled in the HFSCR or MSR */
  187. if (!(vcpu->arch.hfscr & HFSCR_TM)) {
  188. /* generate an illegal instruction interrupt */
  189. kvmppc_core_queue_program(vcpu, SRR1_PROGILL);
  190. return RESUME_GUEST;
  191. }
  192. if (!(msr & MSR_TM)) {
  193. /* generate a facility unavailable interrupt */
  194. vcpu->arch.fscr = (vcpu->arch.fscr & ~(0xffull << 56)) |
  195. ((u64)FSCR_TM_LG << 56);
  196. kvmppc_book3s_queue_irqprio(vcpu,
  197. BOOK3S_INTERRUPT_FAC_UNAVAIL);
  198. return RESUME_GUEST;
  199. }
  200. /* If transaction active or TEXASR[FS] = 0, bad thing */
  201. if (MSR_TM_ACTIVE(msr) || !(vcpu->arch.texasr & TEXASR_FS)) {
  202. kvmppc_core_queue_program(vcpu, SRR1_PROGTM);
  203. return RESUME_GUEST;
  204. }
  205. copy_to_checkpoint(vcpu);
  206. /* Set CR0 to indicate previous transactional state */
  207. vcpu->arch.regs.ccr = (vcpu->arch.regs.ccr & 0x0fffffff) |
  208. (((msr & MSR_TS_MASK) >> MSR_TS_S_LG) << 29);
  209. vcpu->arch.shregs.msr = msr | MSR_TS_S;
  210. return RESUME_GUEST;
  211. }
  212. /* What should we do here? We didn't recognize the instruction */
  213. kvmppc_core_queue_program(vcpu, SRR1_PROGILL);
  214. pr_warn_ratelimited("Unrecognized TM-related instruction %#x for emulation", instr);
  215. return RESUME_GUEST;
  216. }