summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index c93848c..c374b37 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -23,6 +23,7 @@
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/phy.h>
#include <linux/phy_fixed.h>
@@ -326,3 +327,44 @@ void fsl_hv_halt(void)
fh_partition_stop(-1);
}
#endif
+
+#ifdef CONFIG_KVM
+static const struct of_device_id cpc_matches[] = {
+ { .compatible = "fsl,b4860-l3-cache-controller" },
+ { .compatible = "fsl,t2080-l3-cache-controller" },
+ { .compatible = "fsl,t4240-l3-cache-controller" },
+ {}
+};
+
+static int __init cpc_disable_sole_data(void)
+{
+ struct device_node *node;
+ u32 __iomem *regs;
+ int i;
+
+ for_each_matching_node(node, cpc_matches) {
+ i = 0;
+
+ for (;;) {
+ regs = of_iomap(node, i++);
+ if (!regs)
+ break;
+
+ /*
+ * Set undocumented bit to disable CPC sole data
+ * mode, making it safe to use the LRAT with KVM
+ * guests, which could otherwise hang the host (under
+ * certain usage patterns) by accessing memory with
+ * the M bit unset. The guest still needs to set the
+ * M bit to operate properly, but this removes a DoS
+ * vector.
+ */
+ setbits32(regs + 0xf00 / 4, 0x4000);
+ iounmap(regs);
+ }
+ }
+
+ return 0;
+}
+arch_initcall(cpc_disable_sole_data);
+#endif