[PATCH 08/11] KVM: arm64: Inject AArch32 exceptions from HYP

Marc Zyngier maz at kernel.org
Tue Oct 27 15:21:55 EDT 2020


On 2020-10-27 17:41, James Morse wrote:
> Hi Marc,
> 
> On 26/10/2020 13:34, Marc Zyngier wrote:
>> Similarily to what has been done for AArch64, move the AArch32 
>> exception
>> inhjection to HYP.
>> 
>> In order to not use the regmap selection code at EL2, simplify the 
>> code
>> populating the target mode's LR register by harcoding the two possible
>> LR registers (LR_abt in X20, LR_und in X22).
> 
> 
>> diff --git a/arch/arm64/kvm/hyp/exception.c 
>> b/arch/arm64/kvm/hyp/exception.c
>> index cd6e643639e8..8d1d1bcd9e69 100644
>> --- a/arch/arm64/kvm/hyp/exception.c
>> +++ b/arch/arm64/kvm/hyp/exception.c
>> @@ -57,10 +67,25 @@ static void __vcpu_write_spsr(struct kvm_vcpu 
>> *vcpu, u64 val)
> 
>> +static inline u32 __vcpu_read_cp15(const struct kvm_vcpu *vcpu, int 
>> reg)
>> +{
>> +	return __vcpu_read_sys_reg(vcpu, reg / 2);
>> +}
> 
> Doesn't this re-implement the issue 3204be4109ad biased?

I don't think it does. The issue existed when accessing the 32bit 
shadow,
and we had to pick which side of the 64bit register had our 32bit value.
Here, we directly access the 64bit file, which is safe.

But thinking of it, we may as well change the call sites to directly
use the 64bit enum, rather than playing games (we used to use the
32bit definition for the sake of the defunct 32bit port).

> 
> 
>> @@ -155,23 +180,189 @@ static void enter_exception64(struct kvm_vcpu 
>> *vcpu, unsigned long target_mode,
> 
>> +static void enter_exception32(struct kvm_vcpu *vcpu, u32 mode, u32 
>> vect_offset)
>> +{
> 
>> +	/*
>> +	 * Table D1-27 of DDI 0487F.c shows the GPR mapping between
>> +	 * AArch32 and AArch64. We only deal with ABT/UND.
> 
> (to check I understand : because these are the only two KVM ever 
> injects?)

Yes, that's indeed the reason. I'll try to clarify.

> 
> 
>> +	 */
>> +	switch(mode) {
>> +	case PSR_AA32_MODE_ABT:
>> +		__vcpu_write_spsr_abt(vcpu, host_spsr_to_spsr32(spsr));
>> +		lr = 20;
>>  		break;
>> +
> 
> (two bonus tabs!)
> 
> 
>> +	case PSR_AA32_MODE_UND:
>> +		__vcpu_write_spsr_und(vcpu, host_spsr_to_spsr32(spsr));
>> +		lr = 22;
>>  		break;
>>  	}> +
>> +	vcpu_set_reg(vcpu, lr, *vcpu_pc(vcpu) + return_offset);
> 
> 
> Can we, abuse, the compat_lr_abt definitions to do something like:
> 
> |	u32 return_address = *vcpu_pc(vcpu) + return_offset;
> [..]
> |	switch(mode) {
> |	case PSR_AA32_MODE_ABT:>
> |		__vcpu_write_spsr_abt(vcpu, host_spsr_to_spsr32(spsr));
> |		vcpu_gp_regs(vcpu)->compat_lr_abt = return_address;
> |		break;
> |	case PSR_AA32_MODE_UND:
> |		__vcpu_write_spsr_und(vcpu, host_spsr_to_spsr32(spsr));
> |		vcpu_gp_regs(vcpu)->compat_lr_und = return_address;
> |		break;
> 
> ...as someone who has no clue about 32bit, this hides all the worrying
> magic-14==magic-22!

Ah, I totally forgot about them (the only use was in the file I delete
two patches later...)!

Thanks,

         M.
-- 
Jazz is not dead. It just smells funny...



More information about the linux-arm-kernel mailing list