On 12/03/13 13:20, Christopher Covington wrote:

Hi Christopher,

> I noticed you went through the trouble of defining several constants in an
> earlier patch. Perhaps you could put them to use here?
> 
> On 03/04/2013 10:47 PM, Marc Zyngier wrote:
>> Implement the injection of a fault (undefined, data abort or
>> prefetch abort) into a 64bit guest.
>>
>> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
>> ---
>>  arch/arm64/kvm/inject_fault.c | 117 
>> ++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 117 insertions(+)
>>  create mode 100644 arch/arm64/kvm/inject_fault.c
> 
> [...]
> 
>> +static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long 
>> addr)
>> +{
>> +    unsigned long cpsr = *vcpu_cpsr(vcpu);
>> +    int is_aarch32;
>> +    u32 esr = 0;
>> +
>> +    is_aarch32 = vcpu_mode_is_32bit(vcpu);
>> +
>> +    *vcpu_spsr(vcpu) = cpsr;
>> +    vcpu->arch.regs.elr_el1 = *vcpu_pc(vcpu);
>> +
>> +    *vcpu_cpsr(vcpu) = PSR_MODE_EL1h | PSR_A_BIT | PSR_F_BIT | PSR_I_BIT;
>> +    *vcpu_pc(vcpu) = vcpu->arch.sys_regs[VBAR_EL1] + 0x200;
>> +
>> +    vcpu->arch.sys_regs[FAR_EL1] = addr;
>> +
>> +    /*
>> +     * Build an {i,d}abort, depending on the level and the
>> +     * instruction set. Report an external synchronous abort.
>> +     */
>> +    if (kvm_vcpu_trap_il_is32bit(vcpu))
>> +            esr |= (1 << 25);
> 
> ESR_EL2_IL

This is the illustration of what I was saying earlier about confusing
levels. Here, we're dealing with the guest's EL1. Using the _EL2 define
is semantically wrong, even if it has the same value.

> 
>> +    if (is_aarch32 || (cpsr & PSR_MODE_MASK) == PSR_MODE_EL0t)
>> +            esr |= (0x20 << 26);
> 
> ESR_EL2_EC_IABT << ESR_EL2_EC_SHIFT
> 
>> +    else
>> +            esr |= (0x21 << 26);
> 
> ESR_EL2_EC_IABT_HYP << ESR_EL2_EC_SHIFT

Even worse here. What this actually mean is "Exception at the current
level", which is EL1. Having _HYP here is completely misleading.

Now, maybe I should review all these defines and give them a more
general meaning. Then we'd be able to share the defines across levels
(arm/arch64/kernel/entry.S could use some defines too...). But overall,
I'm quite reluctant to start mixing ESR_EL1 and ESR_EL2.

>> +
>> +    if (!is_iabt)
>> +            esr |= (1 << 28);
> 
> ESR_EL2_EC_DABT << ESR_EL2_EC_SHIFT

Nasty. Works, but very nasty... ;-)

>> +
>> +    vcpu->arch.sys_regs[ESR_EL1] = esr | 0x10;
>> +}
>> +
>> +static void inject_undef64(struct kvm_vcpu *vcpu)
>> +{
>> +    unsigned long cpsr = *vcpu_cpsr(vcpu);
>> +    u32 esr = 0;
>> +
>> +    *vcpu_spsr(vcpu) = cpsr;
>> +    vcpu->arch.regs.elr_el1 = *vcpu_pc(vcpu);
>> +
>> +    *vcpu_cpsr(vcpu) = PSR_MODE_EL1h | PSR_F_BIT | PSR_I_BIT;
>> +    *vcpu_pc(vcpu) = vcpu->arch.sys_regs[VBAR_EL1] + 0x200;
>> +
>> +    /*
>> +     * Build an unknown exception, depending on the instruction
>> +     * set.
>> +     */
>> +    if (kvm_vcpu_trap_il_is32bit(vcpu))
>> +            esr |= (1 << 25);
> 
> ESR_EL2_IL
> 
>> +
>> +    vcpu->arch.sys_regs[ESR_EL1] = esr;
>> +}

Thanks for reviewing,

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

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to