SpaprPendingHpt *pending = opaque;
size_t size = 1ULL << pending->shift;
- pending->hpt = qemu_memalign(size, size);
+ pending->hpt = qemu_try_memalign(size, size);
if (pending->hpt) {
memset(pending->hpt, 0, size);
pending->ret = H_SUCCESS;
}
static target_ulong h_set_mode_resource_le(PowerPCCPU *cpu,
+ SpaprMachineState *spapr,
target_ulong mflags,
target_ulong value1,
target_ulong value2)
switch (mflags) {
case H_SET_MODE_ENDIAN_BIG:
spapr_set_all_lpcrs(0, LPCR_ILE);
- spapr_pci_switch_vga(true);
+ spapr_pci_switch_vga(spapr, true);
return H_SUCCESS;
case H_SET_MODE_ENDIAN_LITTLE:
spapr_set_all_lpcrs(LPCR_ILE, LPCR_ILE);
- spapr_pci_switch_vga(false);
+ spapr_pci_switch_vga(spapr, false);
return H_SUCCESS;
}
switch (resource) {
case H_SET_MODE_RESOURCE_LE:
- ret = h_set_mode_resource_le(cpu, args[0], args[2], args[3]);
+ ret = h_set_mode_resource_le(cpu, spapr, args[0], args[2], args[3]);
break;
case H_SET_MODE_RESOURCE_ADDR_TRANS_MODE:
ret = h_set_mode_resource_addr_trans_mode(cpu, args[0],
}
}
-static uint32_t cas_check_pvr(SpaprMachineState *spapr, PowerPCCPU *cpu,
- target_ulong *addr, bool *raw_mode_supported,
- Error **errp)
+/* Returns either a logical PVR or zero if none was found */
+static uint32_t cas_check_pvr(PowerPCCPU *cpu, uint32_t max_compat,
+ target_ulong *addr, bool *raw_mode_supported)
{
bool explicit_match = false; /* Matched the CPU's real PVR */
- uint32_t max_compat = spapr->max_compat_pvr;
uint32_t best_compat = 0;
int i;
}
}
- if ((best_compat == 0) && (!explicit_match || max_compat)) {
- /* We couldn't find a suitable compatibility mode, and either
- * the guest doesn't support "raw" mode for this CPU, or raw
- * mode is disabled because a maximum compat mode is set */
- error_setg(errp, "Couldn't negotiate a suitable PVR during CAS");
- return 0;
- }
-
*raw_mode_supported = explicit_match;
/* Parsing finished */
uint32_t cas_pvr;
SpaprOptionVector *ov1_guest, *ov5_guest;
bool guest_radix;
- Error *local_err = NULL;
bool raw_mode_supported = false;
bool guest_xive;
CPUState *cs;
void *fdt;
+ uint32_t max_compat = spapr->max_compat_pvr;
/* CAS is supposed to be called early when only the boot vCPU is active. */
CPU_FOREACH(cs) {
}
}
- cas_pvr = cas_check_pvr(spapr, cpu, &vec, &raw_mode_supported, &local_err);
- if (local_err) {
- error_report_err(local_err);
+ cas_pvr = cas_check_pvr(cpu, max_compat, &vec, &raw_mode_supported);
+ if (!cas_pvr && (!raw_mode_supported || max_compat)) {
+ /*
+ * We couldn't find a suitable compatibility mode, and either
+ * the guest doesn't support "raw" mode for this CPU, or "raw"
+ * mode is disabled because a maximum compat mode is set.
+ */
+ error_report("Couldn't negotiate a suitable PVR during CAS");
return H_HARDWARE;
}
/* Update CPUs */
if (cpu->compat_pvr != cas_pvr) {
- ppc_set_compat_all(cas_pvr, &local_err);
- if (local_err) {
+ Error *local_err = NULL;
+
+ if (ppc_set_compat_all(cas_pvr, &local_err) < 0) {
/* 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.
*/
return H_HARDWARE;
}
error_free(local_err);
- local_err = NULL;
}
}