Hi,
On 1/8/20 11:12 AM, Mark Rutland wrote:
> Hi Alex,
>
> On Fri, Dec 27, 2019 at 01:01:57PM +0000, Alexandru Elisei wrote:
>> On 12/20/19 3:05 PM, Mark Rutland wrote:
>>> When KVM injects an exception into a guest, it generates the PSTATE
>>> value from scratch, configuring PSTATE.{M[4:0],DAIF}, and setting all
>>> other bits to zero.
>>>
>>> This isn't correct, as the architecture specifies that some PSTATE bits
>>> are (conditionally) cleared or set upon an exception, and others are
>>> unchanged from the original context.
>>>
>>> This patch adds logic to match the architectural behaviour. To make this
>>> simple to follow/audit/extend, documentation references are provided,
>>> and bits are configured in order of their layout in SPSR_EL2. This
>>> layout can be seen in the diagram on ARM DDI 0487E.a page C5-429.
>>> +/*
>>> + * When an exception is taken, most PSTATE fields are left unchanged in the
>>> + * handler. However, some are explicitly overridden (e.g. M[4:0]). Luckily
>>> all
>>> + * of the inherited bits have the same position in the AArch64/AArch32
>>> SPSR_ELx
>>> + * layouts, so we don't need to shuffle these for exceptions from AArch32
>>> EL0.
>>> + *
>>> + * For the SPSR_ELx layout for AArch64, see ARM DDI 0487E.a page C5-429.
>>> + * For the SPSR_ELx layout for AArch32, see ARM DDI 0487E.a page C5-426.
>> The commit message mentions only the SPSR_ELx layout for AArch64.
> That was intentional; there I was only providing rationale for how to
> review the patch...
>
>>> + * Here we manipulate the fields in order of the AArch64 SPSR_ELx layout,
>>> from
>>> + * MSB to LSB.
> ... as also commented here.
>
> I can drop the reference from the commit message, if that's confusing?
It's fine as it is, no need to change it.
>
>>> + */
>>> +static unsigned long get_except64_pstate(struct kvm_vcpu *vcpu)
>>> +{
>>> + unsigned long sctlr = vcpu_read_sys_reg(vcpu, SCTLR_EL1);
>>> + unsigned long old, new;
>>> +
>>> + old = *vcpu_cpsr(vcpu);
>>> + new = 0;
>>> +
>>> + new |= (old & PSR_N_BIT);
>>> + new |= (old & PSR_Z_BIT);
>>> + new |= (old & PSR_C_BIT);
>>> + new |= (old & PSR_V_BIT);
>>> +
>>> + // TODO: TCO (if/when ARMv8.5-MemTag is exposed to guests)
>>> +
>>> + new |= (old & PSR_DIT_BIT);
>>> +
>>> + // PSTATE.UAO is set to zero upon any exception to AArch64
>>> + // See ARM DDI 0487E.a, page D5-2579.
>>> +
>>> + // PSTATE.PAN is unchanged unless overridden by SCTLR_ELx.SPAN
>>> + // See ARM DDI 0487E.a, page D5-2578.
>>> + new |= (old & PSR_PAN_BIT);
>>> + if (sctlr & SCTLR_EL1_SPAN)
>>> + new |= PSR_PAN_BIT;
>> On page D13-3264, it is stated that the PAN bit is set unconditionally if
>> SCTLR_EL1.SPAN is clear, not set.
> very good spot, and that's a much better reference.
>
> I had mistakenly assumed SPAN took effect when 0b1, since it wasn't
> called nSPAN, and page D5-2578 doesn't mention the polarity of the bit:
>
> | When ARMv8.1-PAN is implemented, the SCTLR_EL1.SPAN and SCTLR_EL2.SPAN
> | bits are used to control whether the PAN bit is set on an exception to
> | EL1 or EL2.
>
> I've updated this to be:
>
> | // PSTATE.PAN is unchanged unless SCTLR_ELx.SPAN == 0b0
> | // SCTLR_ELx.SPAN is RES1 when ARMv8.1-PAN is not implemented
> | // See ARM DDI 0487E.a, page D13-3264.
> | new |= (old & PSR_PAN_BIT);
> | if (!(sctlr & SCTLR_EL1_SPAN))
> | new |= PSR_PAN_BIT;
Looks good.
>
> [...]
>
>> I've also checked the ARM ARM pages mentioned in the comments, and the
>> references are correct. The SPSR_EL2 layouts for exceptions taken from
>> AArch64,
>> respectively AArch32, states are compatible with the way we create the
>> SPSR_EL2
>> that will be used for eret'ing to the guest, just like the comment says.
> Thanks for confirming this!
>
>> I have a suggestion. I think that in ARM ARM, shuffling things between
>> sections
>> happens a lot less often than adding/removing things from one particular
>> section, so the pages referenced are more likely to change in later versions.
>> How about referencing the section instead of the exact page? Something like:
>> "This layout can be seen in the diagram on ARM DDI 0487E.a, section C5.2.18,
>> when an exception is taken from AArch64 state"?
> I did something like that initially, but the comments got very verbose,
> and so I moved to doc + page/section numbers alone.
>
> The section numbers and headings also vary between revisions of the ARM
> ARM, so I'd prefer to leave this as-is for now. I think it's always
> going to be necessary to look at the referenced version of the ARM ARM
> (in addition to a subsequent revision when updating things).
Makes sense.
Thanks,
Alex
>
> Thanks,
> Mark
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm