1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright 2017 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com> 4 */ 5 6 #include <linux/kvm_host.h> 7 8 #include <asm/kvm_ppc.h> 9 #include <asm/kvm_book3s.h> 10 #include <asm/kvm_book3s_64.h> 11 #include <asm/reg.h> 12 #include <asm/ppc-opcode.h> 13 14 static void emulate_tx_failure(struct kvm_vcpu *vcpu, u64 failure_cause) 15 { 16 u64 texasr, tfiar; 17 u64 msr = vcpu->arch.shregs.msr; 18 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 /* 33 * This gets called on a softpatch interrupt on POWER9 DD2.2 processors. 34 * We expect to find a TM-related instruction to be emulated. The 35 * instruction image is in vcpu->arch.emul_inst. If the guest was in 36 * TM suspended or transactional state, the checkpointed state has been 37 * reclaimed and is in the vcpu struct. The CPU is in virtual mode in 38 * host context. 39 */ 40 int kvmhv_p9_tm_emulation(struct kvm_vcpu *vcpu) 41 { 42 u32 instr = vcpu->arch.emul_inst; 43 u64 msr = vcpu->arch.shregs.msr; 44 u64 newmsr, bescr; 45 int ra, rs; 46 47 switch (instr & 0xfc0007ff) { 48 case PPC_INST_RFID: 49 /* XXX do we need to check for PR=0 here? */ 50 newmsr = vcpu->arch.shregs.srr1; 51 /* should only get here for Sx -> T1 transition */ 52 WARN_ON_ONCE(!(MSR_TM_SUSPENDED(msr) && 53 MSR_TM_TRANSACTIONAL(newmsr) && 54 (newmsr & MSR_TM))); 55 newmsr = sanitize_msr(newmsr); 56 vcpu->arch.shregs.msr = newmsr; 57 vcpu->arch.cfar = vcpu->arch.regs.nip - 4; 58 vcpu->arch.regs.nip = vcpu->arch.shregs.srr0; 59 return RESUME_GUEST; 60 61 case PPC_INST_RFEBB: 62 if ((msr & MSR_PR) && (vcpu->arch.vcore->pcr & PCR_ARCH_206)) { 63 /* generate an illegal instruction interrupt */ 64 kvmppc_core_queue_program(vcpu, SRR1_PROGILL); 65 return RESUME_GUEST; 66 } 67 /* check EBB facility is available */ 68 if (!(vcpu->arch.hfscr & HFSCR_EBB)) { 69 /* generate an illegal instruction interrupt */ 70 kvmppc_core_queue_program(vcpu, SRR1_PROGILL); 71 return RESUME_GUEST; 72 } 73 if ((msr & MSR_PR) && !(vcpu->arch.fscr & FSCR_EBB)) { 74 /* generate a facility unavailable interrupt */ 75 vcpu->arch.fscr = (vcpu->arch.fscr & ~(0xffull << 56)) | 76 ((u64)FSCR_EBB_LG << 56); 77 kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_FAC_UNAVAIL); 78 return RESUME_GUEST; 79 } 80 bescr = vcpu->arch.bescr; 81 /* expect to see a S->T transition requested */ 82 WARN_ON_ONCE(!(MSR_TM_SUSPENDED(msr) && 83 ((bescr >> 30) & 3) == 2)); 84 bescr &= ~BESCR_GE; 85 if (instr & (1 << 11)) 86 bescr |= BESCR_GE; 87 vcpu->arch.bescr = bescr; 88 msr = (msr & ~MSR_TS_MASK) | MSR_TS_T; 89 vcpu->arch.shregs.msr = msr; 90 vcpu->arch.cfar = vcpu->arch.regs.nip - 4; 91 vcpu->arch.regs.nip = vcpu->arch.ebbrr; 92 return RESUME_GUEST; 93 94 case PPC_INST_MTMSRD: 95 /* XXX do we need to check for PR=0 here? */ 96 rs = (instr >> 21) & 0x1f; 97 newmsr = kvmppc_get_gpr(vcpu, rs); 98 /* check this is a Sx -> T1 transition */ 99 WARN_ON_ONCE(!(MSR_TM_SUSPENDED(msr) && 100 MSR_TM_TRANSACTIONAL(newmsr) && 101 (newmsr & MSR_TM))); 102 /* mtmsrd doesn't change LE */ 103 newmsr = (newmsr & ~MSR_LE) | (msr & MSR_LE); 104 newmsr = sanitize_msr(newmsr); 105 vcpu->arch.shregs.msr = newmsr; 106 return RESUME_GUEST; 107 108 case PPC_INST_TSR: 109 /* check for PR=1 and arch 2.06 bit set in PCR */ 110 if ((msr & MSR_PR) && (vcpu->arch.vcore->pcr & PCR_ARCH_206)) { 111 /* generate an illegal instruction interrupt */ 112 kvmppc_core_queue_program(vcpu, SRR1_PROGILL); 113 return RESUME_GUEST; 114 } 115 /* check for TM disabled in the HFSCR or MSR */ 116 if (!(vcpu->arch.hfscr & HFSCR_TM)) { 117 /* generate an illegal instruction interrupt */ 118 kvmppc_core_queue_program(vcpu, SRR1_PROGILL); 119 return RESUME_GUEST; 120 } 121 if (!(msr & MSR_TM)) { 122 /* generate a facility unavailable interrupt */ 123 vcpu->arch.fscr = (vcpu->arch.fscr & ~(0xffull << 56)) | 124 ((u64)FSCR_TM_LG << 56); 125 kvmppc_book3s_queue_irqprio(vcpu, 126 BOOK3S_INTERRUPT_FAC_UNAVAIL); 127 return RESUME_GUEST; 128 } 129 /* Set CR0 to indicate previous transactional state */ 130 vcpu->arch.regs.ccr = (vcpu->arch.regs.ccr & 0x0fffffff) | 131 (((msr & MSR_TS_MASK) >> MSR_TS_S_LG) << 29); 132 /* L=1 => tresume, L=0 => tsuspend */ 133 if (instr & (1 << 21)) { 134 if (MSR_TM_SUSPENDED(msr)) 135 msr = (msr & ~MSR_TS_MASK) | MSR_TS_T; 136 } else { 137 if (MSR_TM_TRANSACTIONAL(msr)) 138 msr = (msr & ~MSR_TS_MASK) | MSR_TS_S; 139 } 140 vcpu->arch.shregs.msr = msr; 141 return RESUME_GUEST; 142 143 case PPC_INST_TRECLAIM: 144 /* check for TM disabled in the HFSCR or MSR */ 145 if (!(vcpu->arch.hfscr & HFSCR_TM)) { 146 /* generate an illegal instruction interrupt */ 147 kvmppc_core_queue_program(vcpu, SRR1_PROGILL); 148 return RESUME_GUEST; 149 } 150 if (!(msr & MSR_TM)) { 151 /* generate a facility unavailable interrupt */ 152 vcpu->arch.fscr = (vcpu->arch.fscr & ~(0xffull << 56)) | 153 ((u64)FSCR_TM_LG << 56); 154 kvmppc_book3s_queue_irqprio(vcpu, 155 BOOK3S_INTERRUPT_FAC_UNAVAIL); 156 return RESUME_GUEST; 157 } 158 /* If no transaction active, generate TM bad thing */ 159 if (!MSR_TM_ACTIVE(msr)) { 160 kvmppc_core_queue_program(vcpu, SRR1_PROGTM); 161 return RESUME_GUEST; 162 } 163 /* If failure was not previously recorded, recompute TEXASR */ 164 if (!(vcpu->arch.orig_texasr & TEXASR_FS)) { 165 ra = (instr >> 16) & 0x1f; 166 if (ra) 167 ra = kvmppc_get_gpr(vcpu, ra) & 0xff; 168 emulate_tx_failure(vcpu, ra); 169 } 170 171 copy_from_checkpoint(vcpu); 172 173 /* Set CR0 to indicate previous transactional state */ 174 vcpu->arch.regs.ccr = (vcpu->arch.regs.ccr & 0x0fffffff) | 175 (((msr & MSR_TS_MASK) >> MSR_TS_S_LG) << 29); 176 vcpu->arch.shregs.msr &= ~MSR_TS_MASK; 177 return RESUME_GUEST; 178 179 case PPC_INST_TRECHKPT: 180 /* XXX do we need to check for PR=0 here? */ 181 /* check for TM disabled in the HFSCR or MSR */ 182 if (!(vcpu->arch.hfscr & HFSCR_TM)) { 183 /* generate an illegal instruction interrupt */ 184 kvmppc_core_queue_program(vcpu, SRR1_PROGILL); 185 return RESUME_GUEST; 186 } 187 if (!(msr & MSR_TM)) { 188 /* generate a facility unavailable interrupt */ 189 vcpu->arch.fscr = (vcpu->arch.fscr & ~(0xffull << 56)) | 190 ((u64)FSCR_TM_LG << 56); 191 kvmppc_book3s_queue_irqprio(vcpu, 192 BOOK3S_INTERRUPT_FAC_UNAVAIL); 193 return RESUME_GUEST; 194 } 195 /* If transaction active or TEXASR[FS] = 0, bad thing */ 196 if (MSR_TM_ACTIVE(msr) || !(vcpu->arch.texasr & TEXASR_FS)) { 197 kvmppc_core_queue_program(vcpu, SRR1_PROGTM); 198 return RESUME_GUEST; 199 } 200 201 copy_to_checkpoint(vcpu); 202 203 /* Set CR0 to indicate previous transactional state */ 204 vcpu->arch.regs.ccr = (vcpu->arch.regs.ccr & 0x0fffffff) | 205 (((msr & MSR_TS_MASK) >> MSR_TS_S_LG) << 29); 206 vcpu->arch.shregs.msr = msr | MSR_TS_S; 207 return RESUME_GUEST; 208 } 209 210 /* What should we do here? We didn't recognize the instruction */ 211 WARN_ON_ONCE(1); 212 return RESUME_GUEST; 213 } 214