mbox series

[00/18] KVM/arm64: Refactoring the vcpu flags

Message ID 20220528113829.1043361-1-maz@kernel.org (mailing list archive)
Headers show
Series KVM/arm64: Refactoring the vcpu flags | expand

Message

Marc Zyngier May 28, 2022, 11:38 a.m. UTC
While working on pKVM, it slowly became apparent that dealing with the
flags was a pain, as they serve multiple purposes:

- some flags are purely a configuration artefact,

- some are an input from the host kernel to the world switch,

- a bunch of them are bookkeeping information for the kernel itself,

- and finally some form a state machine between the host and the world
  switch.

Given that, it became pretty hard to clearly delineate what needed to
be conveyed between the host view of a vcpu and the shadow copy the
world switch deals with, both on entry and exit. This has led to a
flurry of bad bugs when developing the feature, and it is time to put
some order in this mess.

This series is roughly split in four parts:

- patch 1 addresses an embarrassing bug that would leave SVE enabled
  for host EL0 once the vcpu had the flag set (it was never cleared),
  and patch 2 fix the same bug for SME, as it copied the bad
  behaviour (both patches are fix candidates for -rc1, and the first
  one carries a Cc stable).

- patches 3 and 4 rid us of the FP flags altogether, as they really
  form a state machine that is better represented with an enum instead
  of dubious bit fiddling in both directions.

- patch 5 through to 14 split all the flags into three distinct
  categories: configuration, input to the world switch, and host
  state, using some ugly^Wbeautiful^Wquestionable cpp tricks.

- finally, the last patches add some cheap hardening and size
  optimisation to the new flags.

With that in place, it should be much easier to reason about which
flags need to be synchronised at runtime, and in which direction (for
pKVM, this is only a subset of the input flags, and nothing else).

This has been lightly tested on both VHE and nVHE systems, but not
with pKVM itself (there is a bit of work to rebase it on top of this
infrastructure). Patches on top of kvmarm-4.19 (there is a minor
conflict with Linus' current tree).

Marc Zyngier (18):
  KVM: arm64: Always start with clearing SVE flag on load
  KVM: arm64: Always start with clearing SME flag on load
  KVM: arm64: Drop FP_FOREIGN_STATE from the hypervisor code
  KVM: arm64: Move FP state ownership from flag to a tristate
  KVM: arm64: Add helpers to manipulate vcpu flags among a set
  KVM: arm64: Add three sets of flags to the vcpu state
  KVM: arm64: Move vcpu configuration flags into their own set
  KVM: arm64: Move vcpu PC/Exception flags to the input flag set
  KVM: arm64: Move vcpu debug/SPE/TRBE flags to the input flag set
  KVM: arm64: Move vcpu SVE/SME flags to the state flag set
  KVM: arm64: Move vcpu ON_UNSUPPORTED_CPU flag to the state flag set
  KVM: arm64: Move vcpu WFIT flag to the state flag set
  KVM: arm64: Kill unused vcpu flags field
  KVM: arm64: Convert vcpu sysregs_loaded_on_cpu to a state flag
  KVM: arm64: Warn when PENDING_EXCEPTION and INCREMENT_PC are set
    together
  KVM: arm64: Add build-time sanity checks for flags
  KVM: arm64: Reduce the size of the vcpu flag members
  KVM: arm64: Document why pause cannot be turned into a flag

 arch/arm64/include/asm/kvm_emulate.h       |   3 +-
 arch/arm64/include/asm/kvm_host.h          | 192 +++++++++++++++------
 arch/arm64/kvm/arch_timer.c                |   2 +-
 arch/arm64/kvm/arm.c                       |   6 +-
 arch/arm64/kvm/debug.c                     |  22 +--
 arch/arm64/kvm/fpsimd.c                    |  36 ++--
 arch/arm64/kvm/handle_exit.c               |   2 +-
 arch/arm64/kvm/hyp/exception.c             |  23 ++-
 arch/arm64/kvm/hyp/include/hyp/debug-sr.h  |   6 +-
 arch/arm64/kvm/hyp/include/hyp/switch.h    |  24 +--
 arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h |   4 +-
 arch/arm64/kvm/hyp/nvhe/debug-sr.c         |   8 +-
 arch/arm64/kvm/hyp/nvhe/switch.c           |   6 +-
 arch/arm64/kvm/hyp/nvhe/sys_regs.c         |   7 +-
 arch/arm64/kvm/hyp/vhe/switch.c            |   4 +-
 arch/arm64/kvm/hyp/vhe/sysreg-sr.c         |   4 +-
 arch/arm64/kvm/inject_fault.c              |  30 ++--
 arch/arm64/kvm/reset.c                     |   6 +-
 arch/arm64/kvm/sys_regs.c                  |  12 +-
 19 files changed, 238 insertions(+), 159 deletions(-)

Comments

Marc Zyngier May 30, 2022, 8:28 a.m. UTC | #1
On 2022-05-28 12:38, Marc Zyngier wrote:

[...]

> This has been lightly tested on both VHE and nVHE systems, but not
> with pKVM itself (there is a bit of work to rebase it on top of this
> infrastructure). Patches on top of kvmarm-4.19 (there is a minor
> conflict with Linus' current tree).

As Will just pointed out to me in private, this should really read
kvmarm-5.19, as that's what the patches are actually based on.

I guess I'm still suffering from a form of Stockholm syndrome...

         M.
Marc Zyngier June 7, 2022, 1:43 p.m. UTC | #2
On Sat, 28 May 2022 12:38:10 +0100, Marc Zyngier wrote:
> While working on pKVM, it slowly became apparent that dealing with the
> flags was a pain, as they serve multiple purposes:
> 
> - some flags are purely a configuration artefact,
> 
> - some are an input from the host kernel to the world switch,
> 
> [...]

Applied to fixes, thanks!

[01/18] KVM: arm64: Always start with clearing SVE flag on load
        commit: d52d165d67c5aa26c8c89909003c94a66492d23d
[02/18] KVM: arm64: Always start with clearing SME flag on load
        commit: 039f49c4cafb785504c678f28664d088e0108d35

Cheers,

	M.