xref: /openbmc/qemu/hw/ppc/spapr_nested.c (revision 6026fdbdbdf5f30edc906de0ae287e95c1b6892b)
1 #include "qemu/osdep.h"
2 #include "qemu/cutils.h"
3 #include "exec/exec-all.h"
4 #include "helper_regs.h"
5 #include "hw/ppc/ppc.h"
6 #include "hw/ppc/spapr.h"
7 #include "hw/ppc/spapr_cpu_core.h"
8 #include "hw/ppc/spapr_nested.h"
9 
10 void spapr_nested_reset(SpaprMachineState *spapr)
11 {
12     if (spapr_get_cap(spapr, SPAPR_CAP_NESTED_KVM_HV)) {
13         spapr_unregister_nested_hv();
14         spapr_register_nested_hv();
15     }
16 }
17 
18 #ifdef CONFIG_TCG
19 #define PRTS_MASK      0x1f
20 
21 static target_ulong h_set_ptbl(PowerPCCPU *cpu,
22                                SpaprMachineState *spapr,
23                                target_ulong opcode,
24                                target_ulong *args)
25 {
26     target_ulong ptcr = args[0];
27 
28     if (!spapr_get_cap(spapr, SPAPR_CAP_NESTED_KVM_HV)) {
29         return H_FUNCTION;
30     }
31 
32     if ((ptcr & PRTS_MASK) + 12 - 4 > 12) {
33         return H_PARAMETER;
34     }
35 
36     spapr->nested_ptcr = ptcr; /* Save new partition table */
37 
38     return H_SUCCESS;
39 }
40 
41 static target_ulong h_tlb_invalidate(PowerPCCPU *cpu,
42                                      SpaprMachineState *spapr,
43                                      target_ulong opcode,
44                                      target_ulong *args)
45 {
46     /*
47      * The spapr virtual hypervisor nested HV implementation retains no L2
48      * translation state except for TLB. And the TLB is always invalidated
49      * across L1<->L2 transitions, so nothing is required here.
50      */
51 
52     return H_SUCCESS;
53 }
54 
55 static target_ulong h_copy_tofrom_guest(PowerPCCPU *cpu,
56                                         SpaprMachineState *spapr,
57                                         target_ulong opcode,
58                                         target_ulong *args)
59 {
60     /*
61      * This HCALL is not required, L1 KVM will take a slow path and walk the
62      * page tables manually to do the data copy.
63      */
64     return H_FUNCTION;
65 }
66 
67 static void nested_save_state(struct nested_ppc_state *save, PowerPCCPU *cpu)
68 {
69     CPUPPCState *env = &cpu->env;
70 
71     memcpy(save->gpr, env->gpr, sizeof(save->gpr));
72 
73     save->lr = env->lr;
74     save->ctr = env->ctr;
75     save->cfar = env->cfar;
76     save->msr = env->msr;
77     save->nip = env->nip;
78 
79     save->cr = ppc_get_cr(env);
80     save->xer = cpu_read_xer(env);
81 
82     save->lpcr = env->spr[SPR_LPCR];
83     save->lpidr = env->spr[SPR_LPIDR];
84     save->pcr = env->spr[SPR_PCR];
85     save->dpdes = env->spr[SPR_DPDES];
86     save->hfscr = env->spr[SPR_HFSCR];
87     save->srr0 = env->spr[SPR_SRR0];
88     save->srr1 = env->spr[SPR_SRR1];
89     save->sprg0 = env->spr[SPR_SPRG0];
90     save->sprg1 = env->spr[SPR_SPRG1];
91     save->sprg2 = env->spr[SPR_SPRG2];
92     save->sprg3 = env->spr[SPR_SPRG3];
93     save->pidr = env->spr[SPR_BOOKS_PID];
94     save->ppr = env->spr[SPR_PPR];
95 
96     save->tb_offset = env->tb_env->tb_offset;
97 }
98 
99 static void nested_load_state(PowerPCCPU *cpu, struct nested_ppc_state *load)
100 {
101     CPUState *cs = CPU(cpu);
102     CPUPPCState *env = &cpu->env;
103 
104     memcpy(env->gpr, load->gpr, sizeof(env->gpr));
105 
106     env->lr = load->lr;
107     env->ctr = load->ctr;
108     env->cfar = load->cfar;
109     env->msr = load->msr;
110     env->nip = load->nip;
111 
112     ppc_set_cr(env, load->cr);
113     cpu_write_xer(env, load->xer);
114 
115     env->spr[SPR_LPCR] = load->lpcr;
116     env->spr[SPR_LPIDR] = load->lpidr;
117     env->spr[SPR_PCR] = load->pcr;
118     env->spr[SPR_DPDES] = load->dpdes;
119     env->spr[SPR_HFSCR] = load->hfscr;
120     env->spr[SPR_SRR0] = load->srr0;
121     env->spr[SPR_SRR1] = load->srr1;
122     env->spr[SPR_SPRG0] = load->sprg0;
123     env->spr[SPR_SPRG1] = load->sprg1;
124     env->spr[SPR_SPRG2] = load->sprg2;
125     env->spr[SPR_SPRG3] = load->sprg3;
126     env->spr[SPR_BOOKS_PID] = load->pidr;
127     env->spr[SPR_PPR] = load->ppr;
128 
129     env->tb_env->tb_offset = load->tb_offset;
130 
131     /*
132      * MSR updated, compute hflags and possible interrupts.
133      */
134     hreg_compute_hflags(env);
135     ppc_maybe_interrupt(env);
136 
137     /*
138      * Nested HV does not tag TLB entries between L1 and L2, so must
139      * flush on transition.
140      */
141     tlb_flush(cs);
142     env->reserve_addr = -1; /* Reset the reservation */
143 }
144 
145 /*
146  * When this handler returns, the environment is switched to the L2 guest
147  * and TCG begins running that. spapr_exit_nested() performs the switch from
148  * L2 back to L1 and returns from the H_ENTER_NESTED hcall.
149  */
150 static target_ulong h_enter_nested(PowerPCCPU *cpu,
151                                    SpaprMachineState *spapr,
152                                    target_ulong opcode,
153                                    target_ulong *args)
154 {
155     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
156     CPUPPCState *env = &cpu->env;
157     SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
158     struct nested_ppc_state l2_state;
159     target_ulong hv_ptr = args[0];
160     target_ulong regs_ptr = args[1];
161     target_ulong hdec, now = cpu_ppc_load_tbl(env);
162     target_ulong lpcr, lpcr_mask;
163     struct kvmppc_hv_guest_state *hvstate;
164     struct kvmppc_hv_guest_state hv_state;
165     struct kvmppc_pt_regs *regs;
166     hwaddr len;
167 
168     if (spapr->nested_ptcr == 0) {
169         return H_NOT_AVAILABLE;
170     }
171 
172     len = sizeof(*hvstate);
173     hvstate = address_space_map(CPU(cpu)->as, hv_ptr, &len, false,
174                                 MEMTXATTRS_UNSPECIFIED);
175     if (len != sizeof(*hvstate)) {
176         address_space_unmap(CPU(cpu)->as, hvstate, len, 0, false);
177         return H_PARAMETER;
178     }
179 
180     memcpy(&hv_state, hvstate, len);
181 
182     address_space_unmap(CPU(cpu)->as, hvstate, len, len, false);
183 
184     /*
185      * We accept versions 1 and 2. Version 2 fields are unused because TCG
186      * does not implement DAWR*.
187      */
188     if (hv_state.version > HV_GUEST_STATE_VERSION) {
189         return H_PARAMETER;
190     }
191 
192     if (hv_state.lpid == 0) {
193         return H_PARAMETER;
194     }
195 
196     spapr_cpu->nested_host_state = g_try_new(struct nested_ppc_state, 1);
197     if (!spapr_cpu->nested_host_state) {
198         return H_NO_MEM;
199     }
200 
201     assert(env->spr[SPR_LPIDR] == 0);
202     assert(env->spr[SPR_DPDES] == 0);
203     nested_save_state(spapr_cpu->nested_host_state, cpu);
204 
205     len = sizeof(*regs);
206     regs = address_space_map(CPU(cpu)->as, regs_ptr, &len, false,
207                                 MEMTXATTRS_UNSPECIFIED);
208     if (!regs || len != sizeof(*regs)) {
209         address_space_unmap(CPU(cpu)->as, regs, len, 0, false);
210         g_free(spapr_cpu->nested_host_state);
211         return H_P2;
212     }
213 
214     len = sizeof(l2_state.gpr);
215     assert(len == sizeof(regs->gpr));
216     memcpy(l2_state.gpr, regs->gpr, len);
217 
218     l2_state.lr = regs->link;
219     l2_state.ctr = regs->ctr;
220     l2_state.xer = regs->xer;
221     l2_state.cr = regs->ccr;
222     l2_state.msr = regs->msr;
223     l2_state.nip = regs->nip;
224 
225     address_space_unmap(CPU(cpu)->as, regs, len, len, false);
226 
227     l2_state.cfar = hv_state.cfar;
228     l2_state.lpidr = hv_state.lpid;
229 
230     lpcr_mask = LPCR_DPFD | LPCR_ILE | LPCR_AIL | LPCR_LD | LPCR_MER;
231     lpcr = (env->spr[SPR_LPCR] & ~lpcr_mask) | (hv_state.lpcr & lpcr_mask);
232     lpcr |= LPCR_HR | LPCR_UPRT | LPCR_GTSE | LPCR_HVICE | LPCR_HDICE;
233     lpcr &= ~LPCR_LPES0;
234     l2_state.lpcr = lpcr & pcc->lpcr_mask;
235 
236     l2_state.pcr = hv_state.pcr;
237     /* hv_state.amor is not used */
238     l2_state.dpdes = hv_state.dpdes;
239     l2_state.hfscr = hv_state.hfscr;
240     /* TCG does not implement DAWR*, CIABR, PURR, SPURR, IC, VTB, HEIR SPRs*/
241     l2_state.srr0 = hv_state.srr0;
242     l2_state.srr1 = hv_state.srr1;
243     l2_state.sprg0 = hv_state.sprg[0];
244     l2_state.sprg1 = hv_state.sprg[1];
245     l2_state.sprg2 = hv_state.sprg[2];
246     l2_state.sprg3 = hv_state.sprg[3];
247     l2_state.pidr = hv_state.pidr;
248     l2_state.ppr = hv_state.ppr;
249     l2_state.tb_offset = env->tb_env->tb_offset + hv_state.tb_offset;
250 
251     /*
252      * Switch to the nested guest environment and start the "hdec" timer.
253      */
254     nested_load_state(cpu, &l2_state);
255 
256     hdec = hv_state.hdec_expiry - now;
257     cpu_ppc_hdecr_init(env);
258     cpu_ppc_store_hdecr(env, hdec);
259 
260     /*
261      * The hv_state.vcpu_token is not needed. It is used by the KVM
262      * implementation to remember which L2 vCPU last ran on which physical
263      * CPU so as to invalidate process scope translations if it is moved
264      * between physical CPUs. For now TLBs are always flushed on L1<->L2
265      * transitions so this is not a problem.
266      *
267      * Could validate that the same vcpu_token does not attempt to run on
268      * different L1 vCPUs at the same time, but that would be a L1 KVM bug
269      * and it's not obviously worth a new data structure to do it.
270      */
271 
272     spapr_cpu->in_nested = true;
273 
274     /*
275      * The spapr hcall helper sets env->gpr[3] to the return value, but at
276      * this point the L1 is not returning from the hcall but rather we
277      * start running the L2, so r3 must not be clobbered, so return env->gpr[3]
278      * to leave it unchanged.
279      */
280     return env->gpr[3];
281 }
282 
283 void spapr_exit_nested(PowerPCCPU *cpu, int excp)
284 {
285     CPUPPCState *env = &cpu->env;
286     SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
287     struct nested_ppc_state l2_state;
288     target_ulong hv_ptr = spapr_cpu->nested_host_state->gpr[4];
289     target_ulong regs_ptr = spapr_cpu->nested_host_state->gpr[5];
290     target_ulong hsrr0, hsrr1, hdar, asdr, hdsisr;
291     struct kvmppc_hv_guest_state *hvstate;
292     struct kvmppc_pt_regs *regs;
293     hwaddr len;
294 
295     assert(spapr_cpu->in_nested);
296 
297     nested_save_state(&l2_state, cpu);
298     hsrr0 = env->spr[SPR_HSRR0];
299     hsrr1 = env->spr[SPR_HSRR1];
300     hdar = env->spr[SPR_HDAR];
301     hdsisr = env->spr[SPR_HDSISR];
302     asdr = env->spr[SPR_ASDR];
303 
304     /*
305      * Switch back to the host environment (including for any error).
306      */
307     assert(env->spr[SPR_LPIDR] != 0);
308     nested_load_state(cpu, spapr_cpu->nested_host_state);
309     env->gpr[3] = env->excp_vectors[excp]; /* hcall return value */
310 
311     cpu_ppc_hdecr_exit(env);
312 
313     spapr_cpu->in_nested = false;
314 
315     g_free(spapr_cpu->nested_host_state);
316     spapr_cpu->nested_host_state = NULL;
317 
318     len = sizeof(*hvstate);
319     hvstate = address_space_map(CPU(cpu)->as, hv_ptr, &len, true,
320                                 MEMTXATTRS_UNSPECIFIED);
321     if (len != sizeof(*hvstate)) {
322         address_space_unmap(CPU(cpu)->as, hvstate, len, 0, true);
323         env->gpr[3] = H_PARAMETER;
324         return;
325     }
326 
327     hvstate->cfar = l2_state.cfar;
328     hvstate->lpcr = l2_state.lpcr;
329     hvstate->pcr = l2_state.pcr;
330     hvstate->dpdes = l2_state.dpdes;
331     hvstate->hfscr = l2_state.hfscr;
332 
333     if (excp == POWERPC_EXCP_HDSI) {
334         hvstate->hdar = hdar;
335         hvstate->hdsisr = hdsisr;
336         hvstate->asdr = asdr;
337     } else if (excp == POWERPC_EXCP_HISI) {
338         hvstate->asdr = asdr;
339     }
340 
341     /* HEIR should be implemented for HV mode and saved here. */
342     hvstate->srr0 = l2_state.srr0;
343     hvstate->srr1 = l2_state.srr1;
344     hvstate->sprg[0] = l2_state.sprg0;
345     hvstate->sprg[1] = l2_state.sprg1;
346     hvstate->sprg[2] = l2_state.sprg2;
347     hvstate->sprg[3] = l2_state.sprg3;
348     hvstate->pidr = l2_state.pidr;
349     hvstate->ppr = l2_state.ppr;
350 
351     /* Is it okay to specify write length larger than actual data written? */
352     address_space_unmap(CPU(cpu)->as, hvstate, len, len, true);
353 
354     len = sizeof(*regs);
355     regs = address_space_map(CPU(cpu)->as, regs_ptr, &len, true,
356                                 MEMTXATTRS_UNSPECIFIED);
357     if (!regs || len != sizeof(*regs)) {
358         address_space_unmap(CPU(cpu)->as, regs, len, 0, true);
359         env->gpr[3] = H_P2;
360         return;
361     }
362 
363     len = sizeof(env->gpr);
364     assert(len == sizeof(regs->gpr));
365     memcpy(regs->gpr, l2_state.gpr, len);
366 
367     regs->link = l2_state.lr;
368     regs->ctr = l2_state.ctr;
369     regs->xer = l2_state.xer;
370     regs->ccr = l2_state.cr;
371 
372     if (excp == POWERPC_EXCP_MCHECK ||
373         excp == POWERPC_EXCP_RESET ||
374         excp == POWERPC_EXCP_SYSCALL) {
375         regs->nip = l2_state.srr0;
376         regs->msr = l2_state.srr1 & env->msr_mask;
377     } else {
378         regs->nip = hsrr0;
379         regs->msr = hsrr1 & env->msr_mask;
380     }
381 
382     /* Is it okay to specify write length larger than actual data written? */
383     address_space_unmap(CPU(cpu)->as, regs, len, len, true);
384 }
385 
386 void spapr_register_nested_hv(void)
387 {
388     spapr_register_hypercall(KVMPPC_H_SET_PARTITION_TABLE, h_set_ptbl);
389     spapr_register_hypercall(KVMPPC_H_ENTER_NESTED, h_enter_nested);
390     spapr_register_hypercall(KVMPPC_H_TLB_INVALIDATE, h_tlb_invalidate);
391     spapr_register_hypercall(KVMPPC_H_COPY_TOFROM_GUEST, h_copy_tofrom_guest);
392 }
393 
394 void spapr_unregister_nested_hv(void)
395 {
396     spapr_unregister_hypercall(KVMPPC_H_SET_PARTITION_TABLE);
397     spapr_unregister_hypercall(KVMPPC_H_ENTER_NESTED);
398     spapr_unregister_hypercall(KVMPPC_H_TLB_INVALIDATE);
399     spapr_unregister_hypercall(KVMPPC_H_COPY_TOFROM_GUEST);
400 }
401 #else
402 void spapr_exit_nested(PowerPCCPU *cpu, int excp)
403 {
404     g_assert_not_reached();
405 }
406 
407 void spapr_register_nested_hv(void)
408 {
409     /* DO NOTHING */
410 }
411 
412 void spapr_unregister_nested_hv(void)
413 {
414     /* DO NOTHING */
415 }
416 #endif
417