xref: /qemu/hw/ppc/spapr_caps.c (revision e68b3baa)
1 /*
2  * QEMU PowerPC pSeries Logical Partition capabilities handling
3  *
4  * Copyright (c) 2017 David Gibson, Red Hat Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #include "qemu/osdep.h"
25 #include "qemu/error-report.h"
26 #include "qapi/error.h"
27 #include "qapi/visitor.h"
28 #include "sysemu/hw_accel.h"
29 #include "exec/ram_addr.h"
30 #include "target/ppc/cpu.h"
31 #include "target/ppc/mmu-hash64.h"
32 #include "cpu-models.h"
33 #include "kvm_ppc.h"
34 #include "sysemu/qtest.h"
35 
36 #include "hw/ppc/spapr.h"
37 
38 typedef struct SpaprCapPossible {
39     int num;            /* size of vals array below */
40     const char *help;   /* help text for vals */
41     /*
42      * Note:
43      * - because of the way compatibility is determined vals MUST be ordered
44      *   such that later options are a superset of all preceding options.
45      * - the order of vals must be preserved, that is their index is important,
46      *   however vals may be added to the end of the list so long as the above
47      *   point is observed
48      */
49     const char *vals[];
50 } SpaprCapPossible;
51 
52 typedef struct SpaprCapabilityInfo {
53     const char *name;
54     const char *description;
55     int index;
56 
57     /* Getter and Setter Function Pointers */
58     ObjectPropertyAccessor *get;
59     ObjectPropertyAccessor *set;
60     const char *type;
61     /* Possible values if this is a custom string type */
62     SpaprCapPossible *possible;
63     /* Make sure the virtual hardware can support this capability */
64     void (*apply)(SpaprMachineState *spapr, uint8_t val, Error **errp);
65     void (*cpu_apply)(SpaprMachineState *spapr, PowerPCCPU *cpu,
66                       uint8_t val, Error **errp);
67 } SpaprCapabilityInfo;
68 
69 static void spapr_cap_get_bool(Object *obj, Visitor *v, const char *name,
70                                void *opaque, Error **errp)
71 {
72     SpaprCapabilityInfo *cap = opaque;
73     SpaprMachineState *spapr = SPAPR_MACHINE(obj);
74     bool value = spapr_get_cap(spapr, cap->index) == SPAPR_CAP_ON;
75 
76     visit_type_bool(v, name, &value, errp);
77 }
78 
79 static void spapr_cap_set_bool(Object *obj, Visitor *v, const char *name,
80                                void *opaque, Error **errp)
81 {
82     SpaprCapabilityInfo *cap = opaque;
83     SpaprMachineState *spapr = SPAPR_MACHINE(obj);
84     bool value;
85     Error *local_err = NULL;
86 
87     visit_type_bool(v, name, &value, &local_err);
88     if (local_err) {
89         error_propagate(errp, local_err);
90         return;
91     }
92 
93     spapr->cmd_line_caps[cap->index] = true;
94     spapr->eff.caps[cap->index] = value ? SPAPR_CAP_ON : SPAPR_CAP_OFF;
95 }
96 
97 
98 static void  spapr_cap_get_string(Object *obj, Visitor *v, const char *name,
99                                   void *opaque, Error **errp)
100 {
101     SpaprCapabilityInfo *cap = opaque;
102     SpaprMachineState *spapr = SPAPR_MACHINE(obj);
103     char *val = NULL;
104     uint8_t value = spapr_get_cap(spapr, cap->index);
105 
106     if (value >= cap->possible->num) {
107         error_setg(errp, "Invalid value (%d) for cap-%s", value, cap->name);
108         return;
109     }
110 
111     val = g_strdup(cap->possible->vals[value]);
112 
113     visit_type_str(v, name, &val, errp);
114     g_free(val);
115 }
116 
117 static void spapr_cap_set_string(Object *obj, Visitor *v, const char *name,
118                                  void *opaque, Error **errp)
119 {
120     SpaprCapabilityInfo *cap = opaque;
121     SpaprMachineState *spapr = SPAPR_MACHINE(obj);
122     Error *local_err = NULL;
123     uint8_t i;
124     char *val;
125 
126     visit_type_str(v, name, &val, &local_err);
127     if (local_err) {
128         error_propagate(errp, local_err);
129         return;
130     }
131 
132     if (!strcmp(val, "?")) {
133         error_setg(errp, "%s", cap->possible->help);
134         goto out;
135     }
136     for (i = 0; i < cap->possible->num; i++) {
137         if (!strcasecmp(val, cap->possible->vals[i])) {
138             spapr->cmd_line_caps[cap->index] = true;
139             spapr->eff.caps[cap->index] = i;
140             goto out;
141         }
142     }
143 
144     error_setg(errp, "Invalid capability mode \"%s\" for cap-%s", val,
145                cap->name);
146 out:
147     g_free(val);
148 }
149 
150 static void spapr_cap_get_pagesize(Object *obj, Visitor *v, const char *name,
151                                    void *opaque, Error **errp)
152 {
153     SpaprCapabilityInfo *cap = opaque;
154     SpaprMachineState *spapr = SPAPR_MACHINE(obj);
155     uint8_t val = spapr_get_cap(spapr, cap->index);
156     uint64_t pagesize = (1ULL << val);
157 
158     visit_type_size(v, name, &pagesize, errp);
159 }
160 
161 static void spapr_cap_set_pagesize(Object *obj, Visitor *v, const char *name,
162                                    void *opaque, Error **errp)
163 {
164     SpaprCapabilityInfo *cap = opaque;
165     SpaprMachineState *spapr = SPAPR_MACHINE(obj);
166     uint64_t pagesize;
167     uint8_t val;
168     Error *local_err = NULL;
169 
170     visit_type_size(v, name, &pagesize, &local_err);
171     if (local_err) {
172         error_propagate(errp, local_err);
173         return;
174     }
175 
176     if (!is_power_of_2(pagesize)) {
177         error_setg(errp, "cap-%s must be a power of 2", cap->name);
178         return;
179     }
180 
181     val = ctz64(pagesize);
182     spapr->cmd_line_caps[cap->index] = true;
183     spapr->eff.caps[cap->index] = val;
184 }
185 
186 static void cap_htm_apply(SpaprMachineState *spapr, uint8_t val, Error **errp)
187 {
188     if (!val) {
189         /* TODO: We don't support disabling htm yet */
190         return;
191     }
192     if (tcg_enabled()) {
193         error_setg(errp,
194                    "No Transactional Memory support in TCG, try cap-htm=off");
195     } else if (kvm_enabled() && !kvmppc_has_cap_htm()) {
196         error_setg(errp,
197 "KVM implementation does not support Transactional Memory, try cap-htm=off"
198             );
199     }
200 }
201 
202 static void cap_vsx_apply(SpaprMachineState *spapr, uint8_t val, Error **errp)
203 {
204     PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
205     CPUPPCState *env = &cpu->env;
206 
207     if (!val) {
208         /* TODO: We don't support disabling vsx yet */
209         return;
210     }
211     /* Allowable CPUs in spapr_cpu_core.c should already have gotten
212      * rid of anything that doesn't do VMX */
213     g_assert(env->insns_flags & PPC_ALTIVEC);
214     if (!(env->insns_flags2 & PPC2_VSX)) {
215         error_setg(errp, "VSX support not available, try cap-vsx=off");
216     }
217 }
218 
219 static void cap_dfp_apply(SpaprMachineState *spapr, uint8_t val, Error **errp)
220 {
221     PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
222     CPUPPCState *env = &cpu->env;
223 
224     if (!val) {
225         /* TODO: We don't support disabling dfp yet */
226         return;
227     }
228     if (!(env->insns_flags2 & PPC2_DFP)) {
229         error_setg(errp, "DFP support not available, try cap-dfp=off");
230     }
231 }
232 
233 SpaprCapPossible cap_cfpc_possible = {
234     .num = 3,
235     .vals = {"broken", "workaround", "fixed"},
236     .help = "broken - no protection, workaround - workaround available,"
237             " fixed - fixed in hardware",
238 };
239 
240 static void cap_safe_cache_apply(SpaprMachineState *spapr, uint8_t val,
241                                  Error **errp)
242 {
243     Error *local_err = NULL;
244     uint8_t kvm_val =  kvmppc_get_cap_safe_cache();
245 
246     if (tcg_enabled() && val) {
247         /* TCG only supports broken, allow other values and print a warning */
248         error_setg(&local_err,
249                    "TCG doesn't support requested feature, cap-cfpc=%s",
250                    cap_cfpc_possible.vals[val]);
251     } else if (kvm_enabled() && (val > kvm_val)) {
252         error_setg(errp,
253 "Requested safe cache capability level not supported by kvm, try cap-cfpc=%s",
254                    cap_cfpc_possible.vals[kvm_val]);
255     }
256 
257     if (local_err != NULL)
258         warn_report_err(local_err);
259 }
260 
261 SpaprCapPossible cap_sbbc_possible = {
262     .num = 3,
263     .vals = {"broken", "workaround", "fixed"},
264     .help = "broken - no protection, workaround - workaround available,"
265             " fixed - fixed in hardware",
266 };
267 
268 static void cap_safe_bounds_check_apply(SpaprMachineState *spapr, uint8_t val,
269                                         Error **errp)
270 {
271     Error *local_err = NULL;
272     uint8_t kvm_val =  kvmppc_get_cap_safe_bounds_check();
273 
274     if (tcg_enabled() && val) {
275         /* TCG only supports broken, allow other values and print a warning */
276         error_setg(&local_err,
277                    "TCG doesn't support requested feature, cap-sbbc=%s",
278                    cap_sbbc_possible.vals[val]);
279     } else if (kvm_enabled() && (val > kvm_val)) {
280         error_setg(errp,
281 "Requested safe bounds check capability level not supported by kvm, try cap-sbbc=%s",
282                    cap_sbbc_possible.vals[kvm_val]);
283     }
284 
285     if (local_err != NULL)
286         warn_report_err(local_err);
287 }
288 
289 SpaprCapPossible cap_ibs_possible = {
290     .num = 5,
291     /* Note workaround only maintained for compatibility */
292     .vals = {"broken", "workaround", "fixed-ibs", "fixed-ccd", "fixed-na"},
293     .help = "broken - no protection, workaround - count cache flush"
294             ", fixed-ibs - indirect branch serialisation,"
295             " fixed-ccd - cache count disabled,"
296             " fixed-na - fixed in hardware (no longer applicable)",
297 };
298 
299 static void cap_safe_indirect_branch_apply(SpaprMachineState *spapr,
300                                            uint8_t val, Error **errp)
301 {
302     Error *local_err = NULL;
303     uint8_t kvm_val = kvmppc_get_cap_safe_indirect_branch();
304 
305     if (tcg_enabled() && val) {
306         /* TCG only supports broken, allow other values and print a warning */
307         error_setg(&local_err,
308                    "TCG doesn't support requested feature, cap-ibs=%s",
309                    cap_ibs_possible.vals[val]);
310     } else if (kvm_enabled() && (val > kvm_val)) {
311         error_setg(errp,
312 "Requested safe indirect branch capability level not supported by kvm, try cap-ibs=%s",
313                    cap_ibs_possible.vals[kvm_val]);
314     }
315 
316     if (local_err != NULL) {
317         warn_report_err(local_err);
318     }
319 }
320 
321 #define VALUE_DESC_TRISTATE     " (broken, workaround, fixed)"
322 
323 void spapr_check_pagesize(SpaprMachineState *spapr, hwaddr pagesize,
324                           Error **errp)
325 {
326     hwaddr maxpagesize = (1ULL << spapr->eff.caps[SPAPR_CAP_HPT_MAXPAGESIZE]);
327 
328     if (!kvmppc_hpt_needs_host_contiguous_pages()) {
329         return;
330     }
331 
332     if (maxpagesize > pagesize) {
333         error_setg(errp,
334                    "Can't support %"HWADDR_PRIu" kiB guest pages with %"
335                    HWADDR_PRIu" kiB host pages with this KVM implementation",
336                    maxpagesize >> 10, pagesize >> 10);
337     }
338 }
339 
340 static void cap_hpt_maxpagesize_apply(SpaprMachineState *spapr,
341                                       uint8_t val, Error **errp)
342 {
343     if (val < 12) {
344         error_setg(errp, "Require at least 4kiB hpt-max-page-size");
345         return;
346     } else if (val < 16) {
347         warn_report("Many guests require at least 64kiB hpt-max-page-size");
348     }
349 
350     spapr_check_pagesize(spapr, qemu_getrampagesize(), errp);
351 }
352 
353 static bool spapr_pagesize_cb(void *opaque, uint32_t seg_pshift,
354                               uint32_t pshift)
355 {
356     unsigned maxshift = *((unsigned *)opaque);
357 
358     assert(pshift >= seg_pshift);
359 
360     /* Don't allow the guest to use pages bigger than the configured
361      * maximum size */
362     if (pshift > maxshift) {
363         return false;
364     }
365 
366     /* For whatever reason, KVM doesn't allow multiple pagesizes
367      * within a segment, *except* for the case of 16M pages in a 4k or
368      * 64k segment.  Always exclude other cases, so that TCG and KVM
369      * guests see a consistent environment */
370     if ((pshift != seg_pshift) && (pshift != 24)) {
371         return false;
372     }
373 
374     return true;
375 }
376 
377 static void cap_hpt_maxpagesize_cpu_apply(SpaprMachineState *spapr,
378                                           PowerPCCPU *cpu,
379                                           uint8_t val, Error **errp)
380 {
381     unsigned maxshift = val;
382 
383     ppc_hash64_filter_pagesizes(cpu, spapr_pagesize_cb, &maxshift);
384 }
385 
386 static void cap_nested_kvm_hv_apply(SpaprMachineState *spapr,
387                                     uint8_t val, Error **errp)
388 {
389     if (!val) {
390         /* capability disabled by default */
391         return;
392     }
393 
394     if (tcg_enabled()) {
395         error_setg(errp,
396                    "No Nested KVM-HV support in tcg, try cap-nested-hv=off");
397     } else if (kvm_enabled()) {
398         if (!kvmppc_has_cap_nested_kvm_hv()) {
399             error_setg(errp,
400 "KVM implementation does not support Nested KVM-HV, try cap-nested-hv=off");
401         } else if (kvmppc_set_cap_nested_kvm_hv(val) < 0) {
402                 error_setg(errp,
403 "Error enabling cap-nested-hv with KVM, try cap-nested-hv=off");
404         }
405     }
406 }
407 
408 static void cap_large_decr_apply(SpaprMachineState *spapr,
409                                  uint8_t val, Error **errp)
410 {
411     PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
412     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
413 
414     if (!val) {
415         return; /* Disabled by default */
416     }
417 
418     if (tcg_enabled()) {
419         if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_00, 0,
420                               spapr->max_compat_pvr)) {
421             error_setg(errp,
422                 "Large decrementer only supported on POWER9, try -cpu POWER9");
423             return;
424         }
425     } else if (kvm_enabled()) {
426         int kvm_nr_bits = kvmppc_get_cap_large_decr();
427 
428         if (!kvm_nr_bits) {
429             error_setg(errp,
430                        "No large decrementer support, try cap-large-decr=off");
431         } else if (pcc->lrg_decr_bits != kvm_nr_bits) {
432             error_setg(errp,
433 "KVM large decrementer size (%d) differs to model (%d), try -cap-large-decr=off",
434                 kvm_nr_bits, pcc->lrg_decr_bits);
435         }
436     }
437 }
438 
439 static void cap_large_decr_cpu_apply(SpaprMachineState *spapr,
440                                      PowerPCCPU *cpu,
441                                      uint8_t val, Error **errp)
442 {
443     CPUPPCState *env = &cpu->env;
444     target_ulong lpcr = env->spr[SPR_LPCR];
445 
446     if (kvm_enabled()) {
447         if (kvmppc_enable_cap_large_decr(cpu, val)) {
448             error_setg(errp,
449                        "No large decrementer support, try cap-large-decr=off");
450         }
451     }
452 
453     if (val) {
454         lpcr |= LPCR_LD;
455     } else {
456         lpcr &= ~LPCR_LD;
457     }
458     ppc_store_lpcr(cpu, lpcr);
459 }
460 
461 static void cap_ccf_assist_apply(SpaprMachineState *spapr, uint8_t val,
462                                  Error **errp)
463 {
464     uint8_t kvm_val = kvmppc_get_cap_count_cache_flush_assist();
465 
466     if (tcg_enabled() && val) {
467         /* TODO - for now only allow broken for TCG */
468         error_setg(errp,
469 "Requested count cache flush assist capability level not supported by tcg, try cap-ccf-assist=off");
470     } else if (kvm_enabled() && (val > kvm_val)) {
471         error_setg(errp,
472 "Requested count cache flush assist capability level not supported by kvm, try cap-ccf-assist=off");
473     }
474 }
475 
476 SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
477     [SPAPR_CAP_HTM] = {
478         .name = "htm",
479         .description = "Allow Hardware Transactional Memory (HTM)",
480         .index = SPAPR_CAP_HTM,
481         .get = spapr_cap_get_bool,
482         .set = spapr_cap_set_bool,
483         .type = "bool",
484         .apply = cap_htm_apply,
485     },
486     [SPAPR_CAP_VSX] = {
487         .name = "vsx",
488         .description = "Allow Vector Scalar Extensions (VSX)",
489         .index = SPAPR_CAP_VSX,
490         .get = spapr_cap_get_bool,
491         .set = spapr_cap_set_bool,
492         .type = "bool",
493         .apply = cap_vsx_apply,
494     },
495     [SPAPR_CAP_DFP] = {
496         .name = "dfp",
497         .description = "Allow Decimal Floating Point (DFP)",
498         .index = SPAPR_CAP_DFP,
499         .get = spapr_cap_get_bool,
500         .set = spapr_cap_set_bool,
501         .type = "bool",
502         .apply = cap_dfp_apply,
503     },
504     [SPAPR_CAP_CFPC] = {
505         .name = "cfpc",
506         .description = "Cache Flush on Privilege Change" VALUE_DESC_TRISTATE,
507         .index = SPAPR_CAP_CFPC,
508         .get = spapr_cap_get_string,
509         .set = spapr_cap_set_string,
510         .type = "string",
511         .possible = &cap_cfpc_possible,
512         .apply = cap_safe_cache_apply,
513     },
514     [SPAPR_CAP_SBBC] = {
515         .name = "sbbc",
516         .description = "Speculation Barrier Bounds Checking" VALUE_DESC_TRISTATE,
517         .index = SPAPR_CAP_SBBC,
518         .get = spapr_cap_get_string,
519         .set = spapr_cap_set_string,
520         .type = "string",
521         .possible = &cap_sbbc_possible,
522         .apply = cap_safe_bounds_check_apply,
523     },
524     [SPAPR_CAP_IBS] = {
525         .name = "ibs",
526         .description =
527             "Indirect Branch Speculation (broken, workaround, fixed-ibs,"
528             "fixed-ccd, fixed-na)",
529         .index = SPAPR_CAP_IBS,
530         .get = spapr_cap_get_string,
531         .set = spapr_cap_set_string,
532         .type = "string",
533         .possible = &cap_ibs_possible,
534         .apply = cap_safe_indirect_branch_apply,
535     },
536     [SPAPR_CAP_HPT_MAXPAGESIZE] = {
537         .name = "hpt-max-page-size",
538         .description = "Maximum page size for Hash Page Table guests",
539         .index = SPAPR_CAP_HPT_MAXPAGESIZE,
540         .get = spapr_cap_get_pagesize,
541         .set = spapr_cap_set_pagesize,
542         .type = "int",
543         .apply = cap_hpt_maxpagesize_apply,
544         .cpu_apply = cap_hpt_maxpagesize_cpu_apply,
545     },
546     [SPAPR_CAP_NESTED_KVM_HV] = {
547         .name = "nested-hv",
548         .description = "Allow Nested KVM-HV",
549         .index = SPAPR_CAP_NESTED_KVM_HV,
550         .get = spapr_cap_get_bool,
551         .set = spapr_cap_set_bool,
552         .type = "bool",
553         .apply = cap_nested_kvm_hv_apply,
554     },
555     [SPAPR_CAP_LARGE_DECREMENTER] = {
556         .name = "large-decr",
557         .description = "Allow Large Decrementer",
558         .index = SPAPR_CAP_LARGE_DECREMENTER,
559         .get = spapr_cap_get_bool,
560         .set = spapr_cap_set_bool,
561         .type = "bool",
562         .apply = cap_large_decr_apply,
563         .cpu_apply = cap_large_decr_cpu_apply,
564     },
565     [SPAPR_CAP_CCF_ASSIST] = {
566         .name = "ccf-assist",
567         .description = "Count Cache Flush Assist via HW Instruction",
568         .index = SPAPR_CAP_CCF_ASSIST,
569         .get = spapr_cap_get_bool,
570         .set = spapr_cap_set_bool,
571         .type = "bool",
572         .apply = cap_ccf_assist_apply,
573     },
574 };
575 
576 static SpaprCapabilities default_caps_with_cpu(SpaprMachineState *spapr,
577                                                const char *cputype)
578 {
579     SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
580     SpaprCapabilities caps;
581 
582     caps = smc->default_caps;
583 
584     if (!ppc_type_check_compat(cputype, CPU_POWERPC_LOGICAL_3_00,
585                                0, spapr->max_compat_pvr)) {
586         caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_OFF;
587     }
588 
589     if (!ppc_type_check_compat(cputype, CPU_POWERPC_LOGICAL_2_07,
590                                0, spapr->max_compat_pvr)) {
591         caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF;
592         caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN;
593     }
594 
595     if (!ppc_type_check_compat(cputype, CPU_POWERPC_LOGICAL_2_06_PLUS,
596                                0, spapr->max_compat_pvr)) {
597         caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN;
598     }
599 
600     if (!ppc_type_check_compat(cputype, CPU_POWERPC_LOGICAL_2_06,
601                                0, spapr->max_compat_pvr)) {
602         caps.caps[SPAPR_CAP_VSX] = SPAPR_CAP_OFF;
603         caps.caps[SPAPR_CAP_DFP] = SPAPR_CAP_OFF;
604         caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN;
605     }
606 
607     /* This is for pseries-2.12 and older */
608     if (smc->default_caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] == 0) {
609         uint8_t mps;
610 
611         if (kvmppc_hpt_needs_host_contiguous_pages()) {
612             mps = ctz64(qemu_getrampagesize());
613         } else {
614             mps = 34; /* allow everything up to 16GiB, i.e. everything */
615         }
616 
617         caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] = mps;
618     }
619 
620     return caps;
621 }
622 
623 int spapr_caps_pre_load(void *opaque)
624 {
625     SpaprMachineState *spapr = opaque;
626 
627     /* Set to default so we can tell if this came in with the migration */
628     spapr->mig = spapr->def;
629     return 0;
630 }
631 
632 int spapr_caps_pre_save(void *opaque)
633 {
634     SpaprMachineState *spapr = opaque;
635 
636     spapr->mig = spapr->eff;
637     return 0;
638 }
639 
640 /* This has to be called from the top-level spapr post_load, not the
641  * caps specific one.  Otherwise it wouldn't be called when the source
642  * caps are all defaults, which could still conflict with overridden
643  * caps on the destination */
644 int spapr_caps_post_migration(SpaprMachineState *spapr)
645 {
646     int i;
647     bool ok = true;
648     SpaprCapabilities dstcaps = spapr->eff;
649     SpaprCapabilities srccaps;
650 
651     srccaps = default_caps_with_cpu(spapr, MACHINE(spapr)->cpu_type);
652     for (i = 0; i < SPAPR_CAP_NUM; i++) {
653         /* If not default value then assume came in with the migration */
654         if (spapr->mig.caps[i] != spapr->def.caps[i]) {
655             srccaps.caps[i] = spapr->mig.caps[i];
656         }
657     }
658 
659     for (i = 0; i < SPAPR_CAP_NUM; i++) {
660         SpaprCapabilityInfo *info = &capability_table[i];
661 
662         if (srccaps.caps[i] > dstcaps.caps[i]) {
663             error_report("cap-%s higher level (%d) in incoming stream than on destination (%d)",
664                          info->name, srccaps.caps[i], dstcaps.caps[i]);
665             ok = false;
666         }
667 
668         if (srccaps.caps[i] < dstcaps.caps[i]) {
669             warn_report("cap-%s lower level (%d) in incoming stream than on destination (%d)",
670                          info->name, srccaps.caps[i], dstcaps.caps[i]);
671         }
672     }
673 
674     return ok ? 0 : -EINVAL;
675 }
676 
677 /* Used to generate the migration field and needed function for a spapr cap */
678 #define SPAPR_CAP_MIG_STATE(sname, cap)                 \
679 static bool spapr_cap_##sname##_needed(void *opaque)    \
680 {                                                       \
681     SpaprMachineState *spapr = opaque;                  \
682                                                         \
683     return spapr->cmd_line_caps[cap] &&                 \
684            (spapr->eff.caps[cap] !=                     \
685             spapr->def.caps[cap]);                      \
686 }                                                       \
687                                                         \
688 const VMStateDescription vmstate_spapr_cap_##sname = {  \
689     .name = "spapr/cap/" #sname,                        \
690     .version_id = 1,                                    \
691     .minimum_version_id = 1,                            \
692     .needed = spapr_cap_##sname##_needed,               \
693     .fields = (VMStateField[]) {                        \
694         VMSTATE_UINT8(mig.caps[cap],                    \
695                       SpaprMachineState),               \
696         VMSTATE_END_OF_LIST()                           \
697     },                                                  \
698 }
699 
700 SPAPR_CAP_MIG_STATE(htm, SPAPR_CAP_HTM);
701 SPAPR_CAP_MIG_STATE(vsx, SPAPR_CAP_VSX);
702 SPAPR_CAP_MIG_STATE(dfp, SPAPR_CAP_DFP);
703 SPAPR_CAP_MIG_STATE(cfpc, SPAPR_CAP_CFPC);
704 SPAPR_CAP_MIG_STATE(sbbc, SPAPR_CAP_SBBC);
705 SPAPR_CAP_MIG_STATE(ibs, SPAPR_CAP_IBS);
706 SPAPR_CAP_MIG_STATE(nested_kvm_hv, SPAPR_CAP_NESTED_KVM_HV);
707 SPAPR_CAP_MIG_STATE(large_decr, SPAPR_CAP_LARGE_DECREMENTER);
708 SPAPR_CAP_MIG_STATE(ccf_assist, SPAPR_CAP_CCF_ASSIST);
709 
710 void spapr_caps_init(SpaprMachineState *spapr)
711 {
712     SpaprCapabilities default_caps;
713     int i;
714 
715     /* Compute the actual set of caps we should run with */
716     default_caps = default_caps_with_cpu(spapr, MACHINE(spapr)->cpu_type);
717 
718     for (i = 0; i < SPAPR_CAP_NUM; i++) {
719         /* Store the defaults */
720         spapr->def.caps[i] = default_caps.caps[i];
721         /* If not set on the command line then apply the default value */
722         if (!spapr->cmd_line_caps[i]) {
723             spapr->eff.caps[i] = default_caps.caps[i];
724         }
725     }
726 }
727 
728 void spapr_caps_apply(SpaprMachineState *spapr)
729 {
730     int i;
731 
732     for (i = 0; i < SPAPR_CAP_NUM; i++) {
733         SpaprCapabilityInfo *info = &capability_table[i];
734 
735         /*
736          * If the apply function can't set the desired level and thinks it's
737          * fatal, it should cause that.
738          */
739         info->apply(spapr, spapr->eff.caps[i], &error_fatal);
740     }
741 }
742 
743 void spapr_caps_cpu_apply(SpaprMachineState *spapr, PowerPCCPU *cpu)
744 {
745     int i;
746 
747     for (i = 0; i < SPAPR_CAP_NUM; i++) {
748         SpaprCapabilityInfo *info = &capability_table[i];
749 
750         /*
751          * If the apply function can't set the desired level and thinks it's
752          * fatal, it should cause that.
753          */
754         if (info->cpu_apply) {
755             info->cpu_apply(spapr, cpu, spapr->eff.caps[i], &error_fatal);
756         }
757     }
758 }
759 
760 void spapr_caps_add_properties(SpaprMachineClass *smc, Error **errp)
761 {
762     Error *local_err = NULL;
763     ObjectClass *klass = OBJECT_CLASS(smc);
764     int i;
765 
766     for (i = 0; i < ARRAY_SIZE(capability_table); i++) {
767         SpaprCapabilityInfo *cap = &capability_table[i];
768         const char *name = g_strdup_printf("cap-%s", cap->name);
769         char *desc;
770 
771         object_class_property_add(klass, name, cap->type,
772                                   cap->get, cap->set,
773                                   NULL, cap, &local_err);
774         if (local_err) {
775             error_propagate(errp, local_err);
776             return;
777         }
778 
779         desc = g_strdup_printf("%s", cap->description);
780         object_class_property_set_description(klass, name, desc, &local_err);
781         g_free(desc);
782         if (local_err) {
783             error_propagate(errp, local_err);
784             return;
785         }
786     }
787 }
788