spapr: Workaround for broken radix guests
For a little while around 4.9, Linux kernels that saw the radix bit in
ibm,pa-features would attempt to set up the MMU as if they were a
hypervisor, even if they were a guest, which would cause them to
crash.
Work around this by detecting pre-ISA 3.0 guests by their lack of that
bit in option vector 1, and then removing the radix bit from
ibm,pa-features. Note: This now requires regeneration of that node
after CAS negotiation.
Signed-off-by: Sam Bobroff <sam.bobroff@au1.ibm.com>
[dwg: Fix style nits]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index cbd1f29..9f18f75 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1062,7 +1062,7 @@
uint32_t max_compat = cpu->max_compat;
uint32_t best_compat = 0;
int i;
- sPAPROptionVector *ov5_guest, *ov5_cas_old, *ov5_updates;
+ sPAPROptionVector *ov1_guest, *ov5_guest, *ov5_cas_old, *ov5_updates;
bool guest_radix;
/*
@@ -1114,6 +1114,7 @@
/* For the future use: here @ov_table points to the first option vector */
ov_table = list;
+ ov1_guest = spapr_ovec_parse_vector(ov_table, 1);
ov5_guest = spapr_ovec_parse_vector(ov_table, 5);
if (spapr_ovec_test(ov5_guest, OV5_MMU_BOTH)) {
error_report("guest requested hash and radix MMU, which is invalid.");
@@ -1155,7 +1156,8 @@
exit(EXIT_FAILURE);
}
}
-
+ spapr->cas_legacy_guest_workaround = !spapr_ovec_test(ov1_guest,
+ OV1_PPC_3_00);
if (!spapr->cas_reboot) {
spapr->cas_reboot =
(spapr_h_cas_compose_response(spapr, args[1], args[2],