}
static uint32_t cas_check_pvr(sPAPRMachineState *spapr, PowerPCCPU *cpu,
- target_ulong *addr, Error **errp)
+ target_ulong *addr, bool *raw_mode_supported,
+ Error **errp)
{
bool explicit_match = false; /* Matched the CPU's real PVR */
uint32_t max_compat = spapr->max_compat_pvr;
return 0;
}
+ *raw_mode_supported = explicit_match;
+
/* Parsing finished */
trace_spapr_cas_pvr(cpu->compat_pvr, explicit_match, best_compat);
sPAPROptionVector *ov1_guest, *ov5_guest, *ov5_cas_old, *ov5_updates;
bool guest_radix;
Error *local_err = NULL;
+ bool raw_mode_supported = false;
- cas_pvr = cas_check_pvr(spapr, cpu, &addr, &local_err);
+ cas_pvr = cas_check_pvr(spapr, cpu, &addr, &raw_mode_supported, &local_err);
if (local_err) {
error_report_err(local_err);
return H_HARDWARE;
if (cpu->compat_pvr != cas_pvr) {
ppc_set_compat_all(cas_pvr, &local_err);
if (local_err) {
- error_report_err(local_err);
- return H_HARDWARE;
+ /* We fail to set compat mode (likely because running with KVM PR),
+ * but maybe we can fallback to raw mode if the guest supports it.
+ */
+ if (!raw_mode_supported) {
+ error_report_err(local_err);
+ return H_HARDWARE;
+ }
+ local_err = NULL;
}
}