[RFC PATCH 1/7] KVM: arm64: Detect and enable PBHA for stage2

James Morse james.morse at arm.com
Mon Oct 18 10:26:34 PDT 2021


Hi Marc,

On 16/10/2021 14:27, Marc Zyngier wrote:
> On Fri, 15 Oct 2021 17:14:10 +0100,
> James Morse <james.morse at arm.com> wrote:
>>
>> Page Based Hardware Attributes (PBHA, aka HPDS2) allow a page table entry
>> to specify up to four bits that can be used by the hardware for some
>> implementation defined purpose.
>>
>> This is a problem for KVM guests as the host may swap guest memory using
>> a different combination of PBHA bits than the guest used when writing the
>> data. Without knowing what the PBHA bits do, its not possible to know if
>> this will corrupt the guest's data.
>>
>> The arm-arm doesn't describe how the PBHA bits are combined between stage1
>> and stage2. Arm's Cortex CPUs appear to all do the same thing: stage2 wins.
>>
>> Enable PBHA for stage2, where the configured value is zero. This has no
>> effect if PBHA isn't in use. On Cortex cores that have the 'stage2 wins'
>> behaviour, this disables whatever the guest may be doing. For any other
>> core with a sensible combination policy, it should be harmless.

> So the other side of the above is whether it has the potential to be
> harmful on systems that combine PBHA bits differently. Specially if
> they use VTCR_EL2.PBHA bits as a indication that they can OR S1 and S2
> instead of a direct S2 override, thus letting the S1 bits that would
> otherwise not being conveyed outside of the core.

xor-ing them together would be more fun - and equally valid in this imp-def world!


> I guess we have no way to know until someone reports really bad memory
> corruption and loss of data. The architecture is totally broken here.

The alternative is to make this depend on the list of CPUs where we know the combining
behaviour. That isn't great either, as its an unmaintainable-and-outdated list of
all-cortex-cores.


>> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
>> index f8ceebe4982e..7bd90ea1c61f 100644
>> --- a/arch/arm64/kvm/hyp/pgtable.c
>> +++ b/arch/arm64/kvm/hyp/pgtable.c
>> @@ -540,6 +540,15 @@ u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift)
>>  	 */
>>  	vtcr |= VTCR_EL2_HA;
>>  
>> +	/*
>> +	 * Enable PBHA for stage2 on systems that support it. The configured
>> +	 * value will always be 0, which is defined as the safe default
>> +	 * setting. On Cortex cores, enabling PBHA for stage2 effectively
>> +	 * disables it for stage1.
>> +	 */
>> +	if (cpus_have_final_cap(ARM64_HAS_PBHA))
>> +		vtcr = FIELD_PREP(VTCR_EL2_PBHA_MASK, 0xf);

> Err... Surely you mean 'vtcr |= FIELD_PREP(...)' here, right?

Gah!. I'm off to the stationery cupboard for a brown paper bag....



Thanks,

James



More information about the linux-arm-kernel mailing list