[SLOF] [PATCH slof v2] rtas: Integrate RTAS blob
Alexey Kardashevskiy
aik at ozlabs.ru
Wed Jul 17 14:41:45 AEST 2019
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 at ozlabs.ru>
---
Changes:
v2:
* fixed rtas for slof itself
* removed rtas-entry as it is the same as rtas-base now
* fixed style
---
lib/libhvcall/libhvcall.h | 5 +++++
lib/libhvcall/brokensc1.c | 2 +-
board-qemu/slof/rtas.fs | 45 ++++++---------------------------------
lib/libhvcall/hvcall.S | 21 ++++++++++++++++++
lib/libhvcall/hvcall.code | 14 ++++++++++++
lib/libhvcall/hvcall.in | 1 +
6 files changed, 49 insertions(+), 39 deletions(-)
diff --git a/lib/libhvcall/libhvcall.h b/lib/libhvcall/libhvcall.h
index caa4d6d3f17f..72c1f0ffb7c1 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__ */
diff --git a/lib/libhvcall/brokensc1.c b/lib/libhvcall/brokensc1.c
index d97ae77558c7..f01157029b8a 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/board-qemu/slof/rtas.fs b/board-qemu/slof/rtas.fs
index 092f5b1131f0..90efe602f5d7 100644
--- a/board-qemu/slof/rtas.fs
+++ b/board-qemu/slof/rtas.fs
@@ -37,48 +37,13 @@ rtas-cb /rtas-control-block erase
0 VALUE rtas-base
0 VALUE rtas-size
-0 VALUE rtas-entry
0 VALUE rtas-node
-\ Locate qemu RTAS, remove the linux,... properties we really don't
-\ want them to stick around
-
-372 cp
-
-: find-qemu-rtas ( -- )
- " /rtas" find-device get-node to rtas-node
-
- " linux,rtas-base" rtas-node get-package-property IF
- device-end EXIT THEN
- drop l@ to rtas-base
- " linux,rtas-base" delete-property
-
- " rtas-size" rtas-node get-package-property IF
- device-end EXIT THEN
- drop l@ to rtas-size
-
- " linux,rtas-entry" rtas-node get-package-property IF
- rtas-base to rtas-entry
- ELSE
- drop l@ to rtas-entry
- " linux,rtas-entry" delete-property
- THEN
-
-\ ." RTAS found, base=" rtas-base . ." size=" rtas-size . cr
-
- \ Patch the RTAS blob with our sc1 patcher if necessary
- 0
- rtas-base
- dup rtas-size +
- check-and-patch-sc1
-
- device-end
-;
-find-qemu-rtas
+s" /rtas" find-node to rtas-node
373 cp
: enter-rtas ( -- )
- rtas-cb rtas-base 0 rtas-entry call-c drop
+ rtas-cb rtas-base 0 rtas-base call-c drop
;
: rtas-get-token ( str len -- token | 0 )
@@ -185,9 +150,13 @@ rtas-node set-node
: instantiate-rtas ( adr -- entry )
dup store-rtas-loc
dup rtas-base swap rtas-size move
- rtas-entry rtas-base - +
;
+hv-rtas-get
+dup encode-int s" rtas-size" s" /rtas" find-node set-property
+to rtas-size
+to rtas-base
+
device-end
374 cp
diff --git a/lib/libhvcall/hvcall.S b/lib/libhvcall/hvcall.S
index 92cf22e4c22c..b19f6dbeff2c 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 at h
+ ori r3,r3,KVMPPC_H_RTAS at 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 at h
+ ori r3,r3,KVMPPC_H_RTAS at 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 5918c901252e..7e8536aa81fa 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 9193162dd8ce..05ac3865ab75 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!)
--
2.17.1
More information about the SLOF
mailing list