Subject: Re: [PATCH 6/6] powerpc/rtas: constrain user region allocation to RMA

From: Nathan Lynch <[email-masked]>
Date: Tue, 19 Jan 2021 15:00:48 -0600

Michael Ellerman <[email-masked]> writes:
> Nathan Lynch <[email-masked]> writes:
>> Memory locations passed as arguments from the OS to RTAS usually need
>> to be addressable in 32-bit mode and must reside in the Real Mode
>> Area. On PAPR guests, the RMA starts at logical address 0 and is the
>> first logical memory block reported in the LPAR’s device tree.
>>
>> On powerpc targets with RTAS, Linux makes available to user space a
>> region of memory suitable for arguments to be passed to RTAS via
>> sys_rtas(). This region (rtas_rmo_buf) is allocated via the memblock
>> API during boot in order to ensure that it satisfies the requirements
>> described above.
>>
>> With radix MMU, the upper limit supplied to the memblock allocation
>> can exceed the bounds of the first logical memory block, since
>> ppc64_rma_size is ULONG_MAX and RTAS_INSTANTIATE_MAX is 1GB.
>
> Why does the size of the first memory block matter for radix?

Here is my understanding: in the platform architecture, the size of the
first memory block equals the RMA, regardless of the MMU mode. It just
so happens that when using radix, Linux can pass ibm,configure-connector
a work area address outside of the RMA because the allocation
constraints for the work area are computed differently. It would be
wrong of the OS to pass RTAS arguments outside of this region with hash
MMU as well.

> The 1GB limit is sufficient to make it accessible by 32-bit code.

But the requirement is that memory arguments passed to RTAS reside in
the RMA, which may be less than 1GB.

>> (512MB is a common size of the first memory block according to a small sample of
>> LPARs I have checked.)
>
> That's the minimum we request, see prom_init.c:
>
> 	/* option vector 2: Open Firmware options supported */
> 	.vec2 = {
> 		.byte1 = OV2_REAL_MODE,
> 		.reserved = 0,
> 		.real_base = cpu_to_be32(0xffffffff),
> 		.real_size = cpu_to_be32(0xffffffff),
> 		.virt_base = cpu_to_be32(0xffffffff),
> 		.virt_size = cpu_to_be32(0xffffffff),
> 		.load_base = cpu_to_be32(0xffffffff),
> 		.min_rma = cpu_to_be32(512),		/* 512MB min RMA */
>
> Since v4.12 in 2017.

Thanks for the pointer, I had been trying to find this without success.