• Marc Zyngier's avatar
    arm64: KVM: Fix AArch32 to AArch64 register mapping · c0f09634
    Marc Zyngier authored
    When running a 32bit guest under a 64bit hypervisor, the ARMv8
    architecture defines a mapping of the 32bit registers in the 64bit
    space. This includes banked registers that are being demultiplexed
    over the 64bit ones.
    
    On exceptions caused by an operation involving a 32bit register, the
    HW exposes the register number in the ESR_EL2 register. It was so
    far understood that SW had to distinguish between AArch32 and AArch64
    accesses (based on the current AArch32 mode and register number).
    
    It turns out that I misinterpreted the ARM ARM, and the clue is in
    D1.20.1: "For some exceptions, the exception syndrome given in the
    ESR_ELx identifies one or more register numbers from the issued
    instruction that generated the exception. Where the exception is
    taken from an Exception level using AArch32 these register numbers
    give the AArch64 view of the register."
    
    Which means that the HW is already giving us the translated version,
    and that we shouldn't try to interpret it at all (for example, doing
    an MMIO operation from the IRQ mode using the LR register leads to
    very unexpected behaviours).
    
    The fix is thus not to perform a call to vcpu_reg32() at all from
    vcpu_reg(), and use whatever register number is supplied directly.
    The only case we need to find out about the mapping is when we
    actively generate a register access, which only occurs when injecting
    a fault in a guest.
    
    Cc: stable@vger.kernel.org
    Reviewed-by: default avatarRobin Murphy <robin.murphy@arm.com>
    Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
    Signed-off-by: default avatarChristoffer Dall <christoffer.dall@linaro.org>
    c0f09634
inject_fault.c 5.45 KB