[SLOF] [PATCH slof] rtas: Integrate RTAS blob

Thomas Huth thuth at redhat.com
Tue Jul 16 18:40:29 AEST 2019


 Hi Alexey!

On 16/07/2019 07.11, Alexey Kardashevskiy wrote:
> 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.

Likely a left-over from the time when it was possible to start a Linux
kernel directly, without SLOF. But since this is not possible anymore, I
think your patch is a nice clean-up, indeed.

[...]
> 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

I think I'd rather simplify that whole function now to:

s" /rtas" find-node to rtas-node

(no need to put this code into a function, and no need for device-end
anymore)

> @@ -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

Why do you create the "linux,..." properties here? SLOF should normally
not create anything with the "linux," prefix.

> +    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 at h
> +	ori	r3,r3,KVMPPC_H_RTAS at l
> +	HVCALL
> +	blr
> +	.globl hv_rtas_end
> +hv_rtas_end = .;

you could calculate the size here instead already, a la:

hv_rtas_code_size = . - 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_end
> +hv_rtas_broken_sc1_end = .;

... and:

hv_rtas_broken_sc1_size = . - 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..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);
> +    }

... then you can use the size here directly and don't have to deal with
the ugly casting to (unsigned long) all over the place.

> +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

Please indent C code with tabs, not with spaces.

> 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!)
> 

 Thomas


More information about the SLOF mailing list