aboutsummaryrefslogtreecommitdiff
path: root/board-qemu/slof/tree.fs
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2013-12-16 14:10:20 +0100
committerNikunj A Dadhania <nikunj@linux.vnet.ibm.com>2013-12-17 11:01:46 +0530
commitdd53579ae82bed0654dd3e4b3052ef2cac58b5f4 (patch)
treea21b15355998f71e143f42ecd5775e96f7499c6c /board-qemu/slof/tree.fs
parent69c6fc492ca1f9855643d5be5c96b8e19b8f20f8 (diff)
downloadSLOF-dd53579ae82bed0654dd3e4b3052ef2cac58b5f4.zip
SLOF-dd53579ae82bed0654dd3e4b3052ef2cac58b5f4.tar.gz
SLOF-dd53579ae82bed0654dd3e4b3052ef2cac58b5f4.tar.bz2
Work around missing sc 1 traps on pHyp
When running a pseries guest in PR KVM on top of pHyp, sc 1 instructions are handled directly by pHyp, so we don't get to see them. That means we need to get inventive. Invent a new instruction that behaves like sc 1, but really is a reserved instruction that traps. This instruction can be used by KVM to emulate sc 1 behavior. This patch adds the SLOF support for it. With this, SLOF detects whether it's running on such a broken setup and if so patches itself to execute the fake sc 1 instruction instead of the real one. Furthermore, we also hook into "quiesce" which Linux calls when it boots. This gives us the chance to also patch Linux when it boots up, so it uses the fake sc 1 too. Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Diffstat (limited to 'board-qemu/slof/tree.fs')
-rw-r--r--board-qemu/slof/tree.fs24
1 files changed, 24 insertions, 0 deletions
diff --git a/board-qemu/slof/tree.fs b/board-qemu/slof/tree.fs
index dbf6b09..4aba4c5 100644
--- a/board-qemu/slof/tree.fs
+++ b/board-qemu/slof/tree.fs
@@ -124,6 +124,30 @@ populate-pci-busses
600 cp
+: check-patch-kernel-sc1 ( -- )
+ \ At this point we can try our best to patch the kernel. This function
+ \ gets called from the "quiesce" call that kernels execute before they
+ \ take over the system.
+ \
+ \ Here we know that ciregs->r4 contains the return address that gets us
+ \ back into enter_prom inside the guest kernel.
+ \ We assume that within a range of +- 16MB of that pointer all sc 1
+ \ instructions inside of that kernel reside.
+
+ \ test_ins (instruction that tells us the kernel's endianness; we use the
+ \ return address back into the kernel here.)
+ ciregs >r4 @
+ \ test_ins + 16MB (end of search range)
+ dup 1000000 +
+ \ MAX(test_ins - 16MB, 0) (start of search range)
+ dup 2000000 < IF 0 ELSE dup 2000000 - THEN
+ swap
+ check-and-patch-sc1
+;
+
+\ Add sc 1 patching
+' check-patch-kernel-sc1 add-quiesce-xt
+
\ Add rtas cleanup last
' rtas-quiesce add-quiesce-xt