mbox series

[00/16] target/riscv, KVM: fixes and enhancements

Message ID 20230530194623.272652-1-dbarboza@ventanamicro.com
Headers show
Series target/riscv, KVM: fixes and enhancements | expand

Message

Daniel Henrique Barboza May 30, 2023, 7:46 p.m. UTC
Hi,

This is a series that does a lot of design changes w.r.t KVM support in
the RISC-V machines. 

The most straightforward patches are patches 1 and 2, which are bug fixes
that allows the KVM 'host' CPU to boot.

For the remaining 14 patches I'll describe in text form the changes
intended:

- machine_ids (mvendorid, marchid, mimpid) changes

  - for named CPUs: can't be changed from the value previously set by
    their cpu_init()
  - for the KVM 'host' CPU: can't be changed from the host value
  - for generic CPUs (both TCG and KVM): can be changed at will, as
    long as marchid has a valid value


- KVM extension discovery during init

  We want extensions to be validated in user option callbacks to
  alleaviate the work we need to do during kvm_arch_init_vcpu().

  This can only be done if we discover host capabilities sooner than
  realize() time. We're borrowing a solution from ARM called 'scratch
  CPU', where we initialize KVM fds to be able to read host capabilities
  and discard the CPU afterwards. This scratch CPU is spinned during
  cpu_init() time to fill in default values for KVM extensions. It's
  also possible to error out right away depending on the errors found
  during this process.

- KVM specific user options

  The current design of user options for TCG is not enough to implement
  error handling in KVM because we don't know whether the user set an
  specific option or not. This is crucial to determine whether we should
  error out or keep going when facing a KVM side error.

  KVM options have a 'user_set' flag to determine if the user changed
  that specific config option or not. They also have specific KVM
  attributes such as kvm_reg_id and 'supported' that are also used for
  error handling.

- KVM extensions error handling changes

  We determine if a case is serious enough to error out or not based on
  two factors: user input and KVM support. KVM support is determined by
  the error code that KVM might thrown our way. RISC-V KVM uses 'EINVAL'
  to tell that a given reg is not available to be read/written by the
  kvm_get/set_one_reg() ioctl. Searching for the EINVAL error allow us
  to determine if a given extension is not supported during the KVM
  feature discovery step.

  As a rule we don't error out in two scenarios:

  - The user is setting an extension to the same value as present in the
    host. In this case we just ignore the option altogether;
  - The user is disabling an extension (i.e. turning off) that is not
    supported by KVM. E.g the user sets 'zbb=false' and KVM is not able
    to read/write 'zbb'. We don't error out because this is a common
    case that can happen when running QEMU with older KVM versions.

  We error out in the following scenariosn:

  - All errors that happens when user tries to enable an extension.
    Failing to enable an extension is bad because there are user
    expectations with enabled extensions and how the guest will behave; 

  - User disables an extension that KVM support and KVM throws an error
    when trying to disable it. We rrror out because, unlike the case
    where KVM is alien to the extension, this indicates either a KVM
    limitation or any other error that the user should be aware of. For
    instance, as of Linux 6.4 rc1, RISC-V KVM doesn't allow 'ssaia',
    'sstc', 'svinval', 'zihintpause' and 'zbb' to be disabled. Thus a
    failure in disabling 'zbb' is something that is worth aborting the
    launch.

- Difference between single-letter and multi-letter extensions handling

  We don't support enabling a single-letter extension that is not
  already enabled in the host. In other words we just support disabling
  existing single-letter extensions.

  The same doesn't apply for multi-letter extensions because, although
  it's not the case for KVM at this moment, KVM is likely to have cases
  where certain extensions are disabled by vendors but can be enabled by
  users that want to try it out. We're already supporting this case to
  avoid changing the design later.


Things that are known to be missing/pending:

- named CPU KVM support: I want to forbid this use case entirely, but
  refrained to do it in this series because it's a bit too overloaded
  with changes as is;

- documentation changes: it would be nice to have these design decisions
  documented. I'll work in it as a follow-up.


Daniel Henrique Barboza (16):
  target/riscv: skip features setup for KVM CPUs
  hw/riscv/virt.c: skip 'mmu-type' FDT if satp mode not set
  target/riscv/cpu.c: restrict 'mvendorid' value
  target/riscv/cpu.c: restrict 'mimpid' value
  target/riscv/cpu.c: restrict 'marchid' value
  target/riscv: use KVM scratch CPUs to init KVM properties
  target/riscv: read marchid/mimpid in kvm_riscv_init_machine_ids()
  target/riscv: handle mvendorid/marchid/mimpid for KVM CPUs
  linux-headers: Update to v6.4-rc1
  target/riscv/kvm.c: init 'misa_ext_mask' with scratch CPU
  target/riscv: add KVM specific MISA properties
  target/riscv/kvm.c: update KVM MISA bits
  target/riscv/kvm.c: add multi-letter extension KVM properties
  target/riscv: adapt 'riscv_isa_string' for KVM
  target/riscv: update multi-letter extension KVM properties
  target/riscv/kvm.c: read/write (cbom|cboz)_blocksize in KVM

 hw/riscv/virt.c                               |  14 +-
 include/standard-headers/linux/const.h        |   2 +-
 include/standard-headers/linux/virtio_blk.h   |  18 +-
 .../standard-headers/linux/virtio_config.h    |   6 +
 include/standard-headers/linux/virtio_net.h   |   1 +
 linux-headers/asm-arm64/kvm.h                 |  33 ++
 linux-headers/asm-riscv/kvm.h                 |  53 +-
 linux-headers/asm-riscv/unistd.h              |   9 +
 linux-headers/asm-s390/unistd_32.h            |   1 +
 linux-headers/asm-s390/unistd_64.h            |   1 +
 linux-headers/asm-x86/kvm.h                   |   3 +
 linux-headers/linux/const.h                   |   2 +-
 linux-headers/linux/kvm.h                     |  12 +-
 linux-headers/linux/psp-sev.h                 |   7 +
 linux-headers/linux/userfaultfd.h             |  17 +-
 target/riscv/cpu.c                            | 171 +++++-
 target/riscv/kvm.c                            | 553 +++++++++++++++++-
 target/riscv/kvm_riscv.h                      |   3 +
 18 files changed, 855 insertions(+), 51 deletions(-)