From patchwork Tue Jul 16 05:11:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 1132440 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45npRg3ds4z9sBt for ; Tue, 16 Jul 2019 15:12:15 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ozlabs.ru Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 45npRg1lSSzDqWW for ; Tue, 16 Jul 2019 15:12:15 +1000 (AEST) X-Original-To: slof@lists.ozlabs.org Delivered-To: slof@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=ozlabs.ru (client-ip=107.173.13.209; helo=ozlabs.ru; envelope-from=aik@ozlabs.ru; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=ozlabs.ru Received: from ozlabs.ru (ozlabs.ru [107.173.13.209]) by lists.ozlabs.org (Postfix) with ESMTP id 45npRX4gJ4zDqVv for ; Tue, 16 Jul 2019 15:12:08 +1000 (AEST) Received: from fstn1-p1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id 3EB0EAE80597; Tue, 16 Jul 2019 01:11:32 -0400 (EDT) From: Alexey Kardashevskiy To: slof@lists.ozlabs.org Date: Tue, 16 Jul 2019 15:11:31 +1000 Message-Id: <20190716051131.65756-1-aik@ozlabs.ru> X-Mailer: git-send-email 2.17.1 Subject: [SLOF] [PATCH slof] rtas: Integrate RTAS blob X-BeenThere: slof@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Patches for https://github.com/aik/SLOF" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: slof-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "SLOF" 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 --- lib/libhvcall/libhvcall.h | 4 ++++ lib/libhvcall/brokensc1.c | 2 +- board-qemu/slof/rtas.fs | 44 +++++++++++++-------------------------- lib/libhvcall/hvcall.S | 19 +++++++++++++++++ lib/libhvcall/hvcall.code | 22 ++++++++++++++++++++ lib/libhvcall/hvcall.in | 2 ++ 6 files changed, 62 insertions(+), 31 deletions(-) diff --git a/lib/libhvcall/libhvcall.h b/lib/libhvcall/libhvcall.h index caa4d6d3f17f..bd402be3fa48 100644 --- a/lib/libhvcall/libhvcall.h +++ b/lib/libhvcall/libhvcall.h @@ -97,11 +97,15 @@ 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 void *hv_rtas, *hv_rtas_end; +extern void *hv_rtas_broken_sc1, *hv_rtas_broken_sc1_end; + #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..1b791b538d92 100644 --- a/board-qemu/slof/rtas.fs +++ b/board-qemu/slof/rtas.fs @@ -40,38 +40,10 @@ rtas-cb /rtas-control-block erase 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 @@ -176,6 +148,14 @@ rtas-node set-node : open true ; : close ; +: store-hv-rtas-size ( ) + hv-rtas-size + dup to rtas-size + encode-int s" rtas-size" s" /rtas" find-node set-property +; + +store-hv-rtas-size + : store-rtas-loc ( adr ) s" /rtas" find-node >r encode-int s" slof,rtas-base" r@ set-property @@ -184,8 +164,12 @@ rtas-node set-node : instantiate-rtas ( adr -- entry ) dup store-rtas-loc - dup rtas-base swap rtas-size move - rtas-entry rtas-base - + + dup to rtas-base + dup to rtas-entry + s" /rtas" find-node >r + dup encode-int s" linux,rtas-base" r@ set-property + dup encode-int s" linux,rtas-entry" r> set-property + dup hv-instantiate-rtas ; device-end diff --git a/lib/libhvcall/hvcall.S b/lib/libhvcall/hvcall.S index 92cf22e4c22c..19163f619be4 100644 --- a/lib/libhvcall/hvcall.S +++ b/lib/libhvcall/hvcall.S @@ -127,6 +127,25 @@ 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_end +hv_rtas_end = .; + +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_end +hv_rtas_broken_sc1_end = .; + .section ".bss" inbuf: .space 16 inlen: .space 4 diff --git a/lib/libhvcall/hvcall.code b/lib/libhvcall/hvcall.code index 5918c901252e..1e47e55a5cc2 100644 --- a/lib/libhvcall/hvcall.code +++ b/lib/libhvcall/hvcall.code @@ -128,3 +128,25 @@ PRIM(hv_X2d_update_X2d_dt) unsigned long dt = TOS.u; TOS.u = hv_generic(KVMPPC_H_UPDATE_DT, dt); MIRP + +PRIM(hv_X2d_instantiate_X2d_rtas) + unsigned long start = TOS.u; POP; + if (check_broken_sc1()) { + memcpy((void *) start, &hv_rtas_broken_sc1, + (unsigned long) &hv_rtas_broken_sc1_end - + (unsigned long) &hv_rtas_broken_sc1); + } else { + memcpy((void *) start, &hv_rtas, + (unsigned long) &hv_rtas_end - (unsigned long) &hv_rtas); + } +MIRP + +PRIM(hv_X2d_rtas_X2d_size) + PUSH; + if (check_broken_sc1()) { + TOS.u = (unsigned long) &hv_rtas_broken_sc1_end - + (unsigned long) &hv_rtas_broken_sc1; + } else { + TOS.u = (unsigned long) &hv_rtas_end - (unsigned long) &hv_rtas; + } +MIRP diff --git a/lib/libhvcall/hvcall.in b/lib/libhvcall/hvcall.in index 9193162dd8ce..4165c6bcab58 100644 --- a/lib/libhvcall/hvcall.in +++ b/lib/libhvcall/hvcall.in @@ -18,6 +18,8 @@ cod(hv-free-crq) cod(hv-send-crq) cod(hv-put-tce) cod(check-and-patch-sc1) +cod(hv-instantiate-rtas) +cod(hv-rtas-size) cod(RB@) cod(RB!)