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