On 2018-04-27 09:01, Peng Fan wrote:
> Hi Jans,
> 
>> -----Original Message-----
>> From: Jan Kiszka [mailto:[email protected]]
>> Sent: 2018年4月26日 15:06
>> To: Peng Fan <[email protected]>; [email protected]; Claudio
>> Scordino <[email protected]>
>> Cc: [email protected]
>> Subject: Re: [PATCH] arm64: introduce CONFIG_CPU_PARANGE
>>
>> On 2018-04-20 12:08, Jan Kiszka wrote:
>>> On 2018-04-20 11:20, Peng Fan wrote:
>>>> Hi Jan,
>>>>
>>>>> -----Original Message-----
>>>>> From: Jan Kiszka [mailto:[email protected]]
>>>>> Sent: 2018年4月20日 16:19
>>>>> To: Peng Fan <[email protected]>; [email protected]
>>>>> Cc: [email protected]
>>>>> Subject: Re: [PATCH] arm64: introduce CONFIG_CPU_PARANGE
>>>>>
>>>>> On 2018-04-20 08:56, Peng Fan wrote:
>>>>>> In i.MX8QM, there are two types of Cortex-A CPUs, Cortex-A53 and
>>>>> Cortex-A72.
>>>>>> A53 ID_AA64MMFR0_EL1 shows its physical address range supported is
>>>>> 40bits.
>>>>>> A72 ID_AA64MMFR0_EL1 shows its physical address range supported is
>>>>> 44bits.
>>>>>
>>>>> So, such platforms will naturally be restricted to 40 bits PA for
>>>>> all cores and never attach resources at higher addresses, correct?
>>>>> Or are there asymmetric setups imaginable where only the A72 cores would
>> use such upper resources?
>>>>
>>>> This is not to set TCR_EL2.PS to 40, but restrict VTCR_EL2.PS to 40.
>>>> The issue is jailhouse use the PA to configure VTCR_EL2, it uses PA
>>>> range on A72 to configure A53, this is wrong.
>>>> My understanding is the VTCR_EL2 on all the cpus should use same
>>>> value and the PS field should use the minimal value supported by all the 
>>>> cpu
>> types.
>>>>
>>>> This link includes how xen handles this, but introducing such logic
>>>> in jailhouse is not that straight forward,
>>>> https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fxen
>>>>
>> bits.xen.org%2Fgitweb%2F%3Fp%3Dxen.git%3Ba%3Dblob%3Bf%3Dxen%2Farc
>> h%2F
>>>>
>> arm%2Fp2m.c%3Bh%3Dd43c3aa896ab857bd85387f09a3dfea05ca6bac1%3Bhb
>> %3DHEA
>>>>
>> D%23l1461&data=02%7C01%7Cpeng.fan%40nxp.com%7C39218e06782444bbd
>> c2808d
>>>>
>> 5ab4425e6%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63660323
>> 154382
>>>>
>> 8207&sdata=k6IYzTIGVU%2FTLaRL%2BFJ5nmgRnFNbApeHprBo3rUQC3k%3D&
>> reserve
>>>> d=0
>>>
>>> Sure, we would have to collect the configuration on each CPU first and
>>> only then start laying out the guest page tables. But Jailhouse does
>>> all this early on the first CPU that is initialized. Need to think if
>>> that could be changed (to the last CPU), but it would be a major
>>> overhaul, if possible at all.
>>
>> Thought about this again: What we could easily do without reworking the whole
>> beast (the parange information is already be used right after
>> paging_init) is to add another barrier:
>>
>> diff --git a/hypervisor/setup.c b/hypervisor/setup.c index 
>> 9eaac20ff..cb0ca7b14
>> 100644
>> --- a/hypervisor/setup.c
>> +++ b/hypervisor/setup.c
>> @@ -28,7 +28,7 @@ static const __attribute__((aligned(PAGE_SIZE))) u8
>> empty_page[PAGE_SIZE];
>>
>>  static DEFINE_SPINLOCK(init_lock);
>>  static unsigned int master_cpu_id = -1; -static volatile unsigned int
>> initialized_cpus;
>> +static volatile unsigned int entered_cpus, initialized_cpus;
>>  static volatile int error;
>>
>>  static void init_early(unsigned int cpu_id) @@ -177,6 +177,21 @@ int
>> entry(unsigned int cpu_id, struct per_cpu *cpu_data)
>>
>>      spin_lock(&init_lock);
>>
>> +    /*
>> +     * If this CPU is last, make sure everything was committed before we
>> +     * signal the other CPUs spinning on entered_cpus that they can
>> +     * continue.
>> +     */
>> +    memory_barrier();
>> +    entered_cpus++;
>> +
>> +    spin_unlock(&init_lock);
>> +
>> +    while (entered_cpus < hypervisor_header.online_cpus)
>> +            cpu_relax();
>> +
>> +    spin_lock(&init_lock);
>> +
>>      if (master_cpu_id == -1) {
>>              /* Only the master CPU, the first to enter this
>>               * function, performs system-wide initializations. */
>>
>> ...and write parange info during arch_entry to the per-cpu struct. Then
>> arch_paging_init could collect all value and use the minimum.
> 
> Based on your patch, I created a patch as you said above and tested on 
> i.MX8QM,
> It works. I add a new id_aa64mmfr0 in per_cpu, not the lower 4 bits for 
> parange,
> I think other fields of id_aa64mmfr0 might be needed in future.

Perfect!

> 
> diff --git a/hypervisor/arch/arm-common/paging.c 
> b/hypervisor/arch/arm-common/paging.c
> index 2ba7da6f..6e3af91c 100644
> --- a/hypervisor/arch/arm-common/paging.c
> +++ b/hypervisor/arch/arm-common/paging.c
> @@ -11,6 +11,7 @@
>   */
> 
>  #include <jailhouse/paging.h>
> +#include <asm/percpu.h>
> 
>  unsigned int cpu_parange = 0;
> 
> @@ -218,7 +219,37 @@ const struct paging *cell_paging;
> 
>  void arch_paging_init(void)
>  {
> -       cpu_parange = get_cpu_parange();
> +       int parange = 0x10;
> +       int i;

Both are used unsigned.

> +
> +       for (i = 0; i < hypervisor_header.online_cpus; i++) {
> +               if ((per_cpu(i)->id_aa64mmfr0 & 0xf) < parange)
> +                       parange = per_cpu(i)->id_aa64mmfr0 & 0xf;
> +       }

0xf may deserve some explanatory BITMASK constant.

> +
> +       switch (parange) {
> +       case PARANGE_32B:
> +               cpu_parange = 32;
> +               break;
> +       case PARANGE_36B:
> +               cpu_parange = 36;
> +               break;
> +       case PARANGE_40B:
> +               cpu_parange = 40;
> +               break;
> +       case PARANGE_42B:
> +               cpu_parange = 42;
> +               break;
> +       case PARANGE_44B:
> +               cpu_parange = 44;
> +               break;
> +       case PARANGE_48B:
> +               cpu_parange = 48;
> +               break;
> +       default:
> +               cpu_parange = 0;
> +               break;
> +       }

If this translation is irregular (no calculation possible), how about
using a table?

> 
>         if (cpu_parange < 44)
>                 /* 4 level page tables not supported for stage 2.
> diff --git a/hypervisor/arch/arm64/asm-defines.c 
> b/hypervisor/arch/arm64/asm-defines.c
> index 58669a4b..81141dc9 100644
> --- a/hypervisor/arch/arm64/asm-defines.c
> +++ b/hypervisor/arch/arm64/asm-defines.c
> @@ -27,6 +27,7 @@ void common(void)
>                debug_console.address);
>         OFFSET(SYSCONFIG_HYPERVISOR_PHYS, jailhouse_system,
>                hypervisor_memory.phys_start);
> +       OFFSET(PERCPU_ID_AA64MMFR0, per_cpu, id_aa64mmfr0);
>         BLANK();
> 
>         DEFINE(PERCPU_STACK_END,
> diff --git a/hypervisor/arch/arm64/entry.S b/hypervisor/arch/arm64/entry.S
> index 61c5dc49..d5b34f17 100644
> --- a/hypervisor/arch/arm64/entry.S
> +++ b/hypervisor/arch/arm64/entry.S
> @@ -157,6 +157,9 @@ el2_entry:
>          */
>         sub     sp, sp, 20 * 8
> 
> +       mrs     x29, id_aa64mmfr0_el1
> +       str     x29, [x1, #PERCPU_ID_AA64MMFR0]
> +
>         mov     x29, xzr        /* reset fp,lr */
>         mov     x30, xzr
> 
> diff --git a/hypervisor/arch/arm64/include/asm/percpu.h 
> b/hypervisor/arch/arm64/include/asm/percpu.h
> index a88ed477..f8b9f77b 100644
> --- a/hypervisor/arch/arm64/include/asm/percpu.h
> +++ b/hypervisor/arch/arm64/include/asm/percpu.h
> @@ -34,6 +34,7 @@ struct per_cpu {
>         u32 stats[JAILHOUSE_NUM_CPU_STATS];
>         int shutdown_state;
>         bool failed;
> +       unsigned long id_aa64mmfr0;
> 
>         struct pending_irqs pending_irqs;
> 
> -Peng.
> 

Looking forward to regular patches!

Jan

-- 
Siemens AG, Corporate Technology, CT RDA IOT SES-DE
Corporate Competence Center Embedded Linux

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to