diff options
author | Alexey Kardashevskiy <aik@ozlabs.ru> | 2019-07-16 15:08:49 +1000 |
---|---|---|
committer | Alexey Kardashevskiy <aik@ozlabs.ru> | 2019-07-18 16:36:03 +1000 |
commit | 5e4ed1fd0f39e7e6c6a05021451fc2e6a98a8b72 (patch) | |
tree | f8b86a22c48d46f7e4519603a19f0a7c80fd292c /lib | |
parent | ba1ab360eebe6338bb8d7d83a9220ccf7e213af3 (diff) | |
download | SLOF-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.c | 2 | ||||
-rw-r--r-- | lib/libhvcall/hvcall.S | 21 | ||||
-rw-r--r-- | lib/libhvcall/hvcall.code | 14 | ||||
-rw-r--r-- | lib/libhvcall/hvcall.in | 1 | ||||
-rw-r--r-- | lib/libhvcall/libhvcall.h | 5 |
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__ */ |