mbox series

[v2,00/11] KVM: arm64: Handle the lack of GICv3 exposed to a guest

Message ID 20240827152517.3909653-1-maz@kernel.org (mailing list archive)
Headers show
Series KVM: arm64: Handle the lack of GICv3 exposed to a guest | expand

Message

Marc Zyngier Aug. 27, 2024, 3:25 p.m. UTC
It recently appeared that, when running on a GICv3-equipped platform
(which is what non-ancient arm64 HW has), *not* configuring a GICv3
for the guest could result in less than desirable outcomes.

We have multiple issues to fix:

- for registers that *always* trap (the SGI registers) or that *may*
  trap (the SRE register), we need to check whether a GICv3 has been
  instantiated before acting upon the trap.

- for registers that only conditionally trap, we must actively trap
  them even in the absence of a GICv3 being instantiated, and handle
  those traps accordingly.

- finally, ID registers must reflect the absence of a GICv3, so that
  we are consistent.

This series goes through all these requirements. The main complexity
here is to apply a GICv3 configuration on the host in the absence of a
GICv3 in the guest. This is pretty hackish, but I don't have a much
better solution so far.

As part of making wider use of of the trap bits, we fully define the
trap routing as per the architecture, something that we eventually
need for NV anyway.

Finally, I have added two additional changes:

- a file-wide cleanup of sys_regs.c, unifying the way we inject an
  UNDEF from the trap handling array

- a selftest that checks for the implemented trapping behaviour (yes,
  I actually wrote a test -- hated every minute of it).

Note that the effects of this series when a GICv2 is configured on a
GICv3 host capable of emulation are imperfect: For some of the
registers, the guest may take a system register trap at EL1 (EC=0x18),
and there is nothing that KVM can do about it (this is a consequence
of ICC_SRE_EL1.SRE being 0, which GICv2 requires). But at least that's
a guest problem, not the host's.

Patches on top of v6.11-rc5, tested on the usual lot of terrible HW:
Synquacer, TX1 and M1.

* From v1 [1]:

  - Drop the first patch of the series, as Oliver picked it up and
    ferried it into 6.11-rc5.

  - Fixed a number of comments involving GICv2

  - Rewrote kvm_has_gicv3() to look at the ID registers instead of the
    internal condition soup.

  - Hacked more of the selftest so that we check that even when
    ICC_SRE_EL1 doesn't trap, it is still RAO/WI.


[1] https://lore.kernel.org/r/20240820100349.3544850-1-maz@kernel.org

Marc Zyngier (11):
  KVM: arm64: Move GICv3 trap configuration to kvm_calculate_traps()
  KVM: arm64: Force SRE traps when SRE access is not enabled
  KVM: arm64: Force GICv3 trap activation when no irqchip is configured
    on VHE
  KVM: arm64: Add helper for last ditch idreg adjustments
  KVM: arm64: Zero ID_AA64PFR0_EL1.GIC when no GICv3 is presented to the
    guest
  KVM: arm64: Add ICH_HCR_EL2 to the vcpu state
  KVM: arm64: Add trap routing information for ICH_HCR_EL2
  KVM: arm64: Honor guest requested traps in GICv3 emulation
  KVM: arm64: Make most GICv3 accesses UNDEF if they trap
  KVM: arm64: Unify UNDEF injection helpers
  KVM: arm64: Add selftest checking how the absence of GICv3 is handled

 arch/arm64/include/asm/kvm_host.h             |   2 +
 arch/arm64/kvm/arm.c                          |  14 +-
 arch/arm64/kvm/emulate-nested.c               |  71 +++++-
 arch/arm64/kvm/hyp/vgic-v3-sr.c               |  97 ++++++-
 arch/arm64/kvm/nested.c                       |  15 +-
 arch/arm64/kvm/sys_regs.c                     | 240 ++++++++++--------
 arch/arm64/kvm/sys_regs.h                     |   9 +
 arch/arm64/kvm/vgic/vgic-v3.c                 |  12 +
 arch/arm64/kvm/vgic/vgic.c                    |  14 +-
 arch/arm64/kvm/vgic/vgic.h                    |   6 +-
 tools/testing/selftests/kvm/Makefile          |   1 +
 .../selftests/kvm/aarch64/no-vgic-v3.c        | 175 +++++++++++++
 12 files changed, 521 insertions(+), 135 deletions(-)
 create mode 100644 tools/testing/selftests/kvm/aarch64/no-vgic-v3.c

Comments

Oliver Upton Aug. 27, 2024, 5:01 p.m. UTC | #1
On Tue, Aug 27, 2024 at 04:25:06PM +0100, Marc Zyngier wrote:
> It recently appeared that, when running on a GICv3-equipped platform
> (which is what non-ancient arm64 HW has), *not* configuring a GICv3
> for the guest could result in less than desirable outcomes.
> 
> We have multiple issues to fix:
> 
> - for registers that *always* trap (the SGI registers) or that *may*
>   trap (the SRE register), we need to check whether a GICv3 has been
>   instantiated before acting upon the trap.
> 
> - for registers that only conditionally trap, we must actively trap
>   them even in the absence of a GICv3 being instantiated, and handle
>   those traps accordingly.
> 
> - finally, ID registers must reflect the absence of a GICv3, so that
>   we are consistent.
> 
> This series goes through all these requirements. The main complexity
> here is to apply a GICv3 configuration on the host in the absence of a
> GICv3 in the guest. This is pretty hackish, but I don't have a much
> better solution so far.

LGTM, thanks for respinning.

Reviewed-by: Oliver Upton <oliver.upton@linux.dev>
Marc Zyngier Aug. 27, 2024, 5:41 p.m. UTC | #2
On Tue, 27 Aug 2024 16:25:06 +0100, Marc Zyngier wrote:
> It recently appeared that, when running on a GICv3-equipped platform
> (which is what non-ancient arm64 HW has), *not* configuring a GICv3
> for the guest could result in less than desirable outcomes.
> 
> We have multiple issues to fix:
> 
> - for registers that *always* trap (the SGI registers) or that *may*
>   trap (the SRE register), we need to check whether a GICv3 has been
>   instantiated before acting upon the trap.
> 
> [...]

Applied to next, thanks!

[01/11] KVM: arm64: Move GICv3 trap configuration to kvm_calculate_traps()
        commit: d2137ba8d8fe56cd2470c82b98e494cbcababd76
[02/11] KVM: arm64: Force SRE traps when SRE access is not enabled
        commit: 5739a961b542530626cb3afb721efa688b290cce
[03/11] KVM: arm64: Force GICv3 trap activation when no irqchip is configured on VHE
        commit: 8d917e0a8651377321c06513f42e2ab9a86161f4
[04/11] KVM: arm64: Add helper for last ditch idreg adjustments
        commit: 795a0bbaeee2aa993338166bc063fe3c89373d2a
[05/11] KVM: arm64: Zero ID_AA64PFR0_EL1.GIC when no GICv3 is presented to the guest
        commit: 5cb57a1aff7551bcb3b800d33141b06ef0ac178b
[06/11] KVM: arm64: Add ICH_HCR_EL2 to the vcpu state
        commit: 9f5deace58da737d67ec9c2d23534a475be68481
[07/11] KVM: arm64: Add trap routing information for ICH_HCR_EL2
        commit: 15a1ba8d049855c5ae454c84e6dd2d7657bacbe8
[08/11] KVM: arm64: Honor guest requested traps in GICv3 emulation
        commit: 59af011d001b836aa52a3dbb5c54daf6fffb511e
[09/11] KVM: arm64: Make most GICv3 accesses UNDEF if they trap
        commit: 4a999a1d7ae52592723a9a219aaa7a3406d66dd6
[10/11] KVM: arm64: Unify UNDEF injection helpers
        commit: cd08d3216fc4e684f05fe4cf696a275a975f6499
[11/11] KVM: arm64: Add selftest checking how the absence of GICv3 is handled
        commit: de2e75209303b98d3169a249a1bc847be9657d9b

Cheers,

	M.