aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAlexey Kardashevskiy <aik@ozlabs.ru>2019-07-16 15:08:49 +1000
committerAlexey Kardashevskiy <aik@ozlabs.ru>2019-07-18 16:36:03 +1000
commit5e4ed1fd0f39e7e6c6a05021451fc2e6a98a8b72 (patch)
treef8b86a22c48d46f7e4519603a19f0a7c80fd292c /lib
parentba1ab360eebe6338bb8d7d83a9220ccf7e213af3 (diff)
downloadSLOF-5e4ed1fd0f39e7e6c6a05021451fc2e6a98a8b72.zip
SLOF-5e4ed1fd0f39e7e6c6a05021451fc2e6a98a8b72.tar.gz
SLOF-5e4ed1fd0f39e7e6c6a05021451fc2e6a98a8b72.tar.bz2
rtas: Integrate RTAS blob
We implement RTAS as a simple binary blob which calls directly into QEMU via a custom hcall. So far we were relying on QEMU putting the RTAS blob to the guest memory with its location in linux,rtas-base/rtas-size. The problems with this are: 1. we need to peek a location in the guest ram in addition to slof, FDT and sometime kernel and init ram disk; having one less image makes QEMU's life easier. 2. for secure VMs, it is yet another image which needs to be signed and verified. This implements "instantiate-rtas" completely in SLOF, including KVM PR support ("broken sc1"). Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> Reviewed-by: Thomas Huth <thuth@redhat.com> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'lib')
-rw-r--r--lib/libhvcall/brokensc1.c2
-rw-r--r--lib/libhvcall/hvcall.S21
-rw-r--r--lib/libhvcall/hvcall.code14
-rw-r--r--lib/libhvcall/hvcall.in1
-rw-r--r--lib/libhvcall/libhvcall.h5
5 files changed, 42 insertions, 1 deletions
diff --git a/lib/libhvcall/brokensc1.c b/lib/libhvcall/brokensc1.c
index d97ae77..f011570 100644
--- a/lib/libhvcall/brokensc1.c
+++ b/lib/libhvcall/brokensc1.c
@@ -36,7 +36,7 @@ static unsigned long hcall(uint32_t inst, unsigned long arg0, unsigned long arg1
return r3;
}
-static int check_broken_sc1(void)
+int check_broken_sc1(void)
{
long r;
diff --git a/lib/libhvcall/hvcall.S b/lib/libhvcall/hvcall.S
index 92cf22e..b19f6db 100644
--- a/lib/libhvcall/hvcall.S
+++ b/lib/libhvcall/hvcall.S
@@ -127,6 +127,27 @@ ENTRY(hv_cas)
HVCALL
blr
+/* This is the actual RTAS blob copied to the OS at instantiate-rtas */
+ENTRY(hv_rtas)
+ mr r4,r3
+ lis r3,KVMPPC_H_RTAS@h
+ ori r3,r3,KVMPPC_H_RTAS@l
+ HVCALL
+ blr
+ .globl hv_rtas_size
+hv_rtas_size:
+ .long . - hv_rtas;
+
+ENTRY(hv_rtas_broken_sc1)
+ mr r4,r3
+ lis r3,KVMPPC_H_RTAS@h
+ ori r3,r3,KVMPPC_H_RTAS@l
+ .long 0x7c000268
+ blr
+ .globl hv_rtas_broken_sc1_size
+hv_rtas_broken_sc1_size:
+ .long . - hv_rtas_broken_sc1;
+
.section ".bss"
inbuf: .space 16
inlen: .space 4
diff --git a/lib/libhvcall/hvcall.code b/lib/libhvcall/hvcall.code
index 5918c90..7e8536a 100644
--- a/lib/libhvcall/hvcall.code
+++ b/lib/libhvcall/hvcall.code
@@ -128,3 +128,17 @@ PRIM(hv_X2d_update_X2d_dt)
unsigned long dt = TOS.u;
TOS.u = hv_generic(KVMPPC_H_UPDATE_DT, dt);
MIRP
+
+PRIM(hv_X2d_rtas_X2d_get)
+ if (check_broken_sc1()) {
+ PUSH;
+ TOS.u = (unsigned long) hv_rtas_broken_sc1;
+ PUSH;
+ TOS.u = hv_rtas_broken_sc1_size;
+ } else {
+ PUSH;
+ TOS.u = (unsigned long) hv_rtas;
+ PUSH;
+ TOS.u = hv_rtas_size;
+ }
+MIRP
diff --git a/lib/libhvcall/hvcall.in b/lib/libhvcall/hvcall.in
index 9193162..05ac386 100644
--- a/lib/libhvcall/hvcall.in
+++ b/lib/libhvcall/hvcall.in
@@ -18,6 +18,7 @@ cod(hv-free-crq)
cod(hv-send-crq)
cod(hv-put-tce)
cod(check-and-patch-sc1)
+cod(hv-rtas-get)
cod(RB@)
cod(RB!)
diff --git a/lib/libhvcall/libhvcall.h b/lib/libhvcall/libhvcall.h
index caa4d6d..72c1f0f 100644
--- a/lib/libhvcall/libhvcall.h
+++ b/lib/libhvcall/libhvcall.h
@@ -97,11 +97,16 @@ extern unsigned long hv_logical_ci_store(unsigned long size, unsigned long addr,
extern unsigned long hv_logical_memop(unsigned long dst, unsigned long src,
unsigned long esize, unsigned long count,
unsigned long op);
+extern int check_broken_sc1(void);
extern int patch_broken_sc1(void *start, void *end, uint32_t *test_ins);
extern unsigned long hv_cas(unsigned long vec, unsigned long buf,
unsigned long size);
+extern unsigned long hv_rtas(unsigned long params);
+extern unsigned long hv_rtas_broken_sc1(unsigned long params);
+extern unsigned int hv_rtas_size, hv_rtas_broken_sc1_size;
+
#endif /* __ASSEMBLY__ */
#endif /* __LIBHVCALL_H__ */