xref: /qemu/hw/ppc/spapr_nested.c (revision 71c33ef0)
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 #include "mmu-book3s-v3.h"
10 #include "cpu-models.h"
11 
12 void spapr_nested_reset(SpaprMachineState *spapr)
13 {
14     if (spapr_get_cap(spapr, SPAPR_CAP_NESTED_KVM_HV)) {
15         spapr->nested.api = NESTED_API_KVM_HV;
16         spapr_unregister_nested_hv();
17         spapr_register_nested_hv();
18     } else {
19         spapr->nested.api = 0;
20         spapr->nested.capabilities_set = false;
21     }
22 }
23 
24 uint8_t spapr_nested_api(SpaprMachineState *spapr)
25 {
26     return spapr->nested.api;
27 }
28 
29 #ifdef CONFIG_TCG
30 
31 bool spapr_get_pate_nested_hv(SpaprMachineState *spapr, PowerPCCPU *cpu,
32                               target_ulong lpid, ppc_v3_pate_t *entry)
33 {
34     uint64_t patb, pats;
35 
36     assert(lpid != 0);
37 
38     patb = spapr->nested.ptcr & PTCR_PATB;
39     pats = spapr->nested.ptcr & PTCR_PATS;
40 
41     /* Check if partition table is properly aligned */
42     if (patb & MAKE_64BIT_MASK(0, pats + 12)) {
43         return false;
44     }
45 
46     /* Calculate number of entries */
47     pats = 1ull << (pats + 12 - 4);
48     if (pats <= lpid) {
49         return false;
50     }
51 
52     /* Grab entry */
53     patb += 16 * lpid;
54     entry->dw0 = ldq_phys(CPU(cpu)->as, patb);
55     entry->dw1 = ldq_phys(CPU(cpu)->as, patb + 8);
56     return true;
57 }
58 
59 #define PRTS_MASK      0x1f
60 
61 static target_ulong h_set_ptbl(PowerPCCPU *cpu,
62                                SpaprMachineState *spapr,
63                                target_ulong opcode,
64                                target_ulong *args)
65 {
66     target_ulong ptcr = args[0];
67 
68     if (!spapr_get_cap(spapr, SPAPR_CAP_NESTED_KVM_HV)) {
69         return H_FUNCTION;
70     }
71 
72     if ((ptcr & PRTS_MASK) + 12 - 4 > 12) {
73         return H_PARAMETER;
74     }
75 
76     spapr->nested.ptcr = ptcr; /* Save new partition table */
77 
78     return H_SUCCESS;
79 }
80 
81 static target_ulong h_tlb_invalidate(PowerPCCPU *cpu,
82                                      SpaprMachineState *spapr,
83                                      target_ulong opcode,
84                                      target_ulong *args)
85 {
86     /*
87      * The spapr virtual hypervisor nested HV implementation retains no L2
88      * translation state except for TLB. And the TLB is always invalidated
89      * across L1<->L2 transitions, so nothing is required here.
90      */
91 
92     return H_SUCCESS;
93 }
94 
95 static target_ulong h_copy_tofrom_guest(PowerPCCPU *cpu,
96                                         SpaprMachineState *spapr,
97                                         target_ulong opcode,
98                                         target_ulong *args)
99 {
100     /*
101      * This HCALL is not required, L1 KVM will take a slow path and walk the
102      * page tables manually to do the data copy.
103      */
104     return H_FUNCTION;
105 }
106 
107 static void nested_save_state(struct nested_ppc_state *save, PowerPCCPU *cpu)
108 {
109     CPUPPCState *env = &cpu->env;
110 
111     memcpy(save->gpr, env->gpr, sizeof(save->gpr));
112 
113     save->lr = env->lr;
114     save->ctr = env->ctr;
115     save->cfar = env->cfar;
116     save->msr = env->msr;
117     save->nip = env->nip;
118 
119     save->cr = ppc_get_cr(env);
120     save->xer = cpu_read_xer(env);
121 
122     save->lpcr = env->spr[SPR_LPCR];
123     save->lpidr = env->spr[SPR_LPIDR];
124     save->pcr = env->spr[SPR_PCR];
125     save->dpdes = env->spr[SPR_DPDES];
126     save->hfscr = env->spr[SPR_HFSCR];
127     save->srr0 = env->spr[SPR_SRR0];
128     save->srr1 = env->spr[SPR_SRR1];
129     save->sprg0 = env->spr[SPR_SPRG0];
130     save->sprg1 = env->spr[SPR_SPRG1];
131     save->sprg2 = env->spr[SPR_SPRG2];
132     save->sprg3 = env->spr[SPR_SPRG3];
133     save->pidr = env->spr[SPR_BOOKS_PID];
134     save->ppr = env->spr[SPR_PPR];
135 
136     save->tb_offset = env->tb_env->tb_offset;
137 }
138 
139 static void nested_load_state(PowerPCCPU *cpu, struct nested_ppc_state *load)
140 {
141     CPUState *cs = CPU(cpu);
142     CPUPPCState *env = &cpu->env;
143 
144     memcpy(env->gpr, load->gpr, sizeof(env->gpr));
145 
146     env->lr = load->lr;
147     env->ctr = load->ctr;
148     env->cfar = load->cfar;
149     env->msr = load->msr;
150     env->nip = load->nip;
151 
152     ppc_set_cr(env, load->cr);
153     cpu_write_xer(env, load->xer);
154 
155     env->spr[SPR_LPCR] = load->lpcr;
156     env->spr[SPR_LPIDR] = load->lpidr;
157     env->spr[SPR_PCR] = load->pcr;
158     env->spr[SPR_DPDES] = load->dpdes;
159     env->spr[SPR_HFSCR] = load->hfscr;
160     env->spr[SPR_SRR0] = load->srr0;
161     env->spr[SPR_SRR1] = load->srr1;
162     env->spr[SPR_SPRG0] = load->sprg0;
163     env->spr[SPR_SPRG1] = load->sprg1;
164     env->spr[SPR_SPRG2] = load->sprg2;
165     env->spr[SPR_SPRG3] = load->sprg3;
166     env->spr[SPR_BOOKS_PID] = load->pidr;
167     env->spr[SPR_PPR] = load->ppr;
168 
169     env->tb_env->tb_offset = load->tb_offset;
170 
171     /*
172      * MSR updated, compute hflags and possible interrupts.
173      */
174     hreg_compute_hflags(env);
175     ppc_maybe_interrupt(env);
176 
177     /*
178      * Nested HV does not tag TLB entries between L1 and L2, so must
179      * flush on transition.
180      */
181     tlb_flush(cs);
182     env->reserve_addr = -1; /* Reset the reservation */
183 }
184 
185 /*
186  * When this handler returns, the environment is switched to the L2 guest
187  * and TCG begins running that. spapr_exit_nested() performs the switch from
188  * L2 back to L1 and returns from the H_ENTER_NESTED hcall.
189  */
190 static target_ulong h_enter_nested(PowerPCCPU *cpu,
191                                    SpaprMachineState *spapr,
192                                    target_ulong opcode,
193                                    target_ulong *args)
194 {
195     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
196     CPUPPCState *env = &cpu->env;
197     SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
198     struct nested_ppc_state l2_state;
199     target_ulong hv_ptr = args[0];
200     target_ulong regs_ptr = args[1];
201     target_ulong hdec, now = cpu_ppc_load_tbl(env);
202     target_ulong lpcr, lpcr_mask;
203     struct kvmppc_hv_guest_state *hvstate;
204     struct kvmppc_hv_guest_state hv_state;
205     struct kvmppc_pt_regs *regs;
206     hwaddr len;
207 
208     if (spapr->nested.ptcr == 0) {
209         return H_NOT_AVAILABLE;
210     }
211 
212     len = sizeof(*hvstate);
213     hvstate = address_space_map(CPU(cpu)->as, hv_ptr, &len, false,
214                                 MEMTXATTRS_UNSPECIFIED);
215     if (len != sizeof(*hvstate)) {
216         address_space_unmap(CPU(cpu)->as, hvstate, len, 0, false);
217         return H_PARAMETER;
218     }
219 
220     memcpy(&hv_state, hvstate, len);
221 
222     address_space_unmap(CPU(cpu)->as, hvstate, len, len, false);
223 
224     /*
225      * We accept versions 1 and 2. Version 2 fields are unused because TCG
226      * does not implement DAWR*.
227      */
228     if (hv_state.version > HV_GUEST_STATE_VERSION) {
229         return H_PARAMETER;
230     }
231 
232     if (hv_state.lpid == 0) {
233         return H_PARAMETER;
234     }
235 
236     spapr_cpu->nested_host_state = g_try_new(struct nested_ppc_state, 1);
237     if (!spapr_cpu->nested_host_state) {
238         return H_NO_MEM;
239     }
240 
241     assert(env->spr[SPR_LPIDR] == 0);
242     assert(env->spr[SPR_DPDES] == 0);
243     nested_save_state(spapr_cpu->nested_host_state, cpu);
244 
245     len = sizeof(*regs);
246     regs = address_space_map(CPU(cpu)->as, regs_ptr, &len, false,
247                                 MEMTXATTRS_UNSPECIFIED);
248     if (!regs || len != sizeof(*regs)) {
249         address_space_unmap(CPU(cpu)->as, regs, len, 0, false);
250         g_free(spapr_cpu->nested_host_state);
251         return H_P2;
252     }
253 
254     len = sizeof(l2_state.gpr);
255     assert(len == sizeof(regs->gpr));
256     memcpy(l2_state.gpr, regs->gpr, len);
257 
258     l2_state.lr = regs->link;
259     l2_state.ctr = regs->ctr;
260     l2_state.xer = regs->xer;
261     l2_state.cr = regs->ccr;
262     l2_state.msr = regs->msr;
263     l2_state.nip = regs->nip;
264 
265     address_space_unmap(CPU(cpu)->as, regs, len, len, false);
266 
267     l2_state.cfar = hv_state.cfar;
268     l2_state.lpidr = hv_state.lpid;
269 
270     lpcr_mask = LPCR_DPFD | LPCR_ILE | LPCR_AIL | LPCR_LD | LPCR_MER;
271     lpcr = (env->spr[SPR_LPCR] & ~lpcr_mask) | (hv_state.lpcr & lpcr_mask);
272     lpcr |= LPCR_HR | LPCR_UPRT | LPCR_GTSE | LPCR_HVICE | LPCR_HDICE;
273     lpcr &= ~LPCR_LPES0;
274     l2_state.lpcr = lpcr & pcc->lpcr_mask;
275 
276     l2_state.pcr = hv_state.pcr;
277     /* hv_state.amor is not used */
278     l2_state.dpdes = hv_state.dpdes;
279     l2_state.hfscr = hv_state.hfscr;
280     /* TCG does not implement DAWR*, CIABR, PURR, SPURR, IC, VTB, HEIR SPRs*/
281     l2_state.srr0 = hv_state.srr0;
282     l2_state.srr1 = hv_state.srr1;
283     l2_state.sprg0 = hv_state.sprg[0];
284     l2_state.sprg1 = hv_state.sprg[1];
285     l2_state.sprg2 = hv_state.sprg[2];
286     l2_state.sprg3 = hv_state.sprg[3];
287     l2_state.pidr = hv_state.pidr;
288     l2_state.ppr = hv_state.ppr;
289     l2_state.tb_offset = env->tb_env->tb_offset + hv_state.tb_offset;
290 
291     /*
292      * Switch to the nested guest environment and start the "hdec" timer.
293      */
294     nested_load_state(cpu, &l2_state);
295 
296     hdec = hv_state.hdec_expiry - now;
297     cpu_ppc_hdecr_init(env);
298     cpu_ppc_store_hdecr(env, hdec);
299 
300     /*
301      * The hv_state.vcpu_token is not needed. It is used by the KVM
302      * implementation to remember which L2 vCPU last ran on which physical
303      * CPU so as to invalidate process scope translations if it is moved
304      * between physical CPUs. For now TLBs are always flushed on L1<->L2
305      * transitions so this is not a problem.
306      *
307      * Could validate that the same vcpu_token does not attempt to run on
308      * different L1 vCPUs at the same time, but that would be a L1 KVM bug
309      * and it's not obviously worth a new data structure to do it.
310      */
311 
312     spapr_cpu->in_nested = true;
313 
314     /*
315      * The spapr hcall helper sets env->gpr[3] to the return value, but at
316      * this point the L1 is not returning from the hcall but rather we
317      * start running the L2, so r3 must not be clobbered, so return env->gpr[3]
318      * to leave it unchanged.
319      */
320     return env->gpr[3];
321 }
322 
323 static void spapr_exit_nested_hv(PowerPCCPU *cpu, int excp)
324 {
325     CPUPPCState *env = &cpu->env;
326     SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
327     struct nested_ppc_state l2_state;
328     target_ulong hv_ptr = spapr_cpu->nested_host_state->gpr[4];
329     target_ulong regs_ptr = spapr_cpu->nested_host_state->gpr[5];
330     target_ulong hsrr0, hsrr1, hdar, asdr, hdsisr;
331     struct kvmppc_hv_guest_state *hvstate;
332     struct kvmppc_pt_regs *regs;
333     hwaddr len;
334 
335     nested_save_state(&l2_state, cpu);
336     hsrr0 = env->spr[SPR_HSRR0];
337     hsrr1 = env->spr[SPR_HSRR1];
338     hdar = env->spr[SPR_HDAR];
339     hdsisr = env->spr[SPR_HDSISR];
340     asdr = env->spr[SPR_ASDR];
341 
342     /*
343      * Switch back to the host environment (including for any error).
344      */
345     assert(env->spr[SPR_LPIDR] != 0);
346     nested_load_state(cpu, spapr_cpu->nested_host_state);
347     env->gpr[3] = env->excp_vectors[excp]; /* hcall return value */
348 
349     cpu_ppc_hdecr_exit(env);
350 
351     spapr_cpu->in_nested = false;
352 
353     g_free(spapr_cpu->nested_host_state);
354     spapr_cpu->nested_host_state = NULL;
355 
356     len = sizeof(*hvstate);
357     hvstate = address_space_map(CPU(cpu)->as, hv_ptr, &len, true,
358                                 MEMTXATTRS_UNSPECIFIED);
359     if (len != sizeof(*hvstate)) {
360         address_space_unmap(CPU(cpu)->as, hvstate, len, 0, true);
361         env->gpr[3] = H_PARAMETER;
362         return;
363     }
364 
365     hvstate->cfar = l2_state.cfar;
366     hvstate->lpcr = l2_state.lpcr;
367     hvstate->pcr = l2_state.pcr;
368     hvstate->dpdes = l2_state.dpdes;
369     hvstate->hfscr = l2_state.hfscr;
370 
371     if (excp == POWERPC_EXCP_HDSI) {
372         hvstate->hdar = hdar;
373         hvstate->hdsisr = hdsisr;
374         hvstate->asdr = asdr;
375     } else if (excp == POWERPC_EXCP_HISI) {
376         hvstate->asdr = asdr;
377     }
378 
379     /* HEIR should be implemented for HV mode and saved here. */
380     hvstate->srr0 = l2_state.srr0;
381     hvstate->srr1 = l2_state.srr1;
382     hvstate->sprg[0] = l2_state.sprg0;
383     hvstate->sprg[1] = l2_state.sprg1;
384     hvstate->sprg[2] = l2_state.sprg2;
385     hvstate->sprg[3] = l2_state.sprg3;
386     hvstate->pidr = l2_state.pidr;
387     hvstate->ppr = l2_state.ppr;
388 
389     /* Is it okay to specify write length larger than actual data written? */
390     address_space_unmap(CPU(cpu)->as, hvstate, len, len, true);
391 
392     len = sizeof(*regs);
393     regs = address_space_map(CPU(cpu)->as, regs_ptr, &len, true,
394                                 MEMTXATTRS_UNSPECIFIED);
395     if (!regs || len != sizeof(*regs)) {
396         address_space_unmap(CPU(cpu)->as, regs, len, 0, true);
397         env->gpr[3] = H_P2;
398         return;
399     }
400 
401     len = sizeof(env->gpr);
402     assert(len == sizeof(regs->gpr));
403     memcpy(regs->gpr, l2_state.gpr, len);
404 
405     regs->link = l2_state.lr;
406     regs->ctr = l2_state.ctr;
407     regs->xer = l2_state.xer;
408     regs->ccr = l2_state.cr;
409 
410     if (excp == POWERPC_EXCP_MCHECK ||
411         excp == POWERPC_EXCP_RESET ||
412         excp == POWERPC_EXCP_SYSCALL) {
413         regs->nip = l2_state.srr0;
414         regs->msr = l2_state.srr1 & env->msr_mask;
415     } else {
416         regs->nip = hsrr0;
417         regs->msr = hsrr1 & env->msr_mask;
418     }
419 
420     /* Is it okay to specify write length larger than actual data written? */
421     address_space_unmap(CPU(cpu)->as, regs, len, len, true);
422 }
423 
424 void spapr_exit_nested(PowerPCCPU *cpu, int excp)
425 {
426     SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
427     SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
428 
429     assert(spapr_cpu->in_nested);
430     if (spapr_nested_api(spapr) == NESTED_API_KVM_HV) {
431         spapr_exit_nested_hv(cpu, excp);
432     } else {
433         g_assert_not_reached();
434     }
435 }
436 
437 static target_ulong h_guest_get_capabilities(PowerPCCPU *cpu,
438                                              SpaprMachineState *spapr,
439                                              target_ulong opcode,
440                                              target_ulong *args)
441 {
442     CPUPPCState *env = &cpu->env;
443     target_ulong flags = args[0];
444 
445     if (flags) { /* don't handle any flags capabilities for now */
446         return H_PARAMETER;
447     }
448 
449     /* P10 capabilities */
450     if (ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_10, 0,
451         spapr->max_compat_pvr)) {
452         env->gpr[4] |= H_GUEST_CAPABILITIES_P10_MODE;
453     }
454 
455     /* P9 capabilities */
456     if (ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_00, 0,
457         spapr->max_compat_pvr)) {
458         env->gpr[4] |= H_GUEST_CAPABILITIES_P9_MODE;
459     }
460 
461     return H_SUCCESS;
462 }
463 
464 static target_ulong h_guest_set_capabilities(PowerPCCPU *cpu,
465                                              SpaprMachineState *spapr,
466                                              target_ulong opcode,
467                                               target_ulong *args)
468 {
469     CPUPPCState *env = &cpu->env;
470     target_ulong flags = args[0];
471     target_ulong capabilities = args[1];
472     env->gpr[4] = 0;
473 
474     if (flags) { /* don't handle any flags capabilities for now */
475         return H_PARAMETER;
476     }
477 
478     if (capabilities & H_GUEST_CAPABILITIES_COPY_MEM) {
479         env->gpr[4] = 1;
480         return H_P2; /* isn't supported */
481     }
482 
483     /*
484      * If there are no capabilities configured, set the R5 to the index of
485      * the first supported Power Processor Mode
486      */
487     if (!capabilities) {
488         env->gpr[4] = 1;
489 
490         /* set R5 to the first supported Power Processor Mode */
491         if (ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_10, 0,
492                              spapr->max_compat_pvr)) {
493             env->gpr[5] = H_GUEST_CAP_P10_MODE_BMAP;
494         } else if (ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_00, 0,
495                                     spapr->max_compat_pvr)) {
496             env->gpr[5] = H_GUEST_CAP_P9_MODE_BMAP;
497         }
498 
499         return H_P2;
500     }
501 
502     /*
503      * If an invalid capability is set, R5 should contain the index of the
504      * invalid capability bit
505      */
506     if (capabilities & ~H_GUEST_CAP_VALID_MASK) {
507         env->gpr[4] = 1;
508 
509         /* Set R5 to the index of the invalid capability */
510         env->gpr[5] = 63 - ctz64(capabilities);
511 
512         return H_P2;
513     }
514 
515     if (!spapr->nested.capabilities_set) {
516         spapr->nested.capabilities_set = true;
517         spapr->nested.pvr_base = env->spr[SPR_PVR];
518         return H_SUCCESS;
519     } else {
520         return H_STATE;
521     }
522 }
523 
524 void spapr_register_nested_hv(void)
525 {
526     spapr_register_hypercall(KVMPPC_H_SET_PARTITION_TABLE, h_set_ptbl);
527     spapr_register_hypercall(KVMPPC_H_ENTER_NESTED, h_enter_nested);
528     spapr_register_hypercall(KVMPPC_H_TLB_INVALIDATE, h_tlb_invalidate);
529     spapr_register_hypercall(KVMPPC_H_COPY_TOFROM_GUEST, h_copy_tofrom_guest);
530 }
531 
532 void spapr_unregister_nested_hv(void)
533 {
534     spapr_unregister_hypercall(KVMPPC_H_SET_PARTITION_TABLE);
535     spapr_unregister_hypercall(KVMPPC_H_ENTER_NESTED);
536     spapr_unregister_hypercall(KVMPPC_H_TLB_INVALIDATE);
537     spapr_unregister_hypercall(KVMPPC_H_COPY_TOFROM_GUEST);
538 }
539 
540 void spapr_register_nested_papr(void)
541 {
542     spapr_register_hypercall(H_GUEST_GET_CAPABILITIES,
543                              h_guest_get_capabilities);
544     spapr_register_hypercall(H_GUEST_SET_CAPABILITIES,
545                              h_guest_set_capabilities);
546 }
547 
548 void spapr_unregister_nested_papr(void)
549 {
550     spapr_unregister_hypercall(H_GUEST_GET_CAPABILITIES);
551     spapr_unregister_hypercall(H_GUEST_SET_CAPABILITIES);
552 }
553 
554 #else
555 void spapr_exit_nested(PowerPCCPU *cpu, int excp)
556 {
557     g_assert_not_reached();
558 }
559 
560 void spapr_register_nested_hv(void)
561 {
562     /* DO NOTHING */
563 }
564 
565 void spapr_unregister_nested_hv(void)
566 {
567     /* DO NOTHING */
568 }
569 
570 bool spapr_get_pate_nested_hv(SpaprMachineState *spapr, PowerPCCPU *cpu,
571                               target_ulong lpid, ppc_v3_pate_t *entry)
572 {
573     return false;
574 }
575 
576 void spapr_register_nested_papr(void)
577 {
578     /* DO NOTHING */
579 }
580 
581 void spapr_unregister_nested_papr(void)
582 {
583     /* DO NOTHING */
584 }
585 
586 #endif
587