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