Commit 0586e28a authored by Marc Zyngier's avatar Marc Zyngier
Browse files

Merge branch kvm-arm64/hcall-selection into kvmarm-master/next



* kvm-arm64/hcall-selection:
  : .
  : Introduce a new set of virtual sysregs for userspace to
  : select the hypercalls it wants to see exposed to the guest.
  :
  : Patches courtesy of Raghavendra and Oliver.
  : .
  KVM: arm64: Fix hypercall bitmap writeback when vcpus have already run
  KVM: arm64: Hide KVM_REG_ARM_*_BMAP_BIT_COUNT from userspace
  Documentation: Fix index.rst after psci.rst renaming
  selftests: KVM: aarch64: Add the bitmap firmware registers to get-reg-list
  selftests: KVM: aarch64: Introduce hypercall ABI test
  selftests: KVM: Create helper for making SMCCC calls
  selftests: KVM: Rename psci_cpu_on_test to psci_test
  tools: Import ARM SMCCC definitions
  Docs: KVM: Add doc for the bitmap firmware registers
  Docs: KVM: Rename psci.rst to hypercalls.rst
  KVM: arm64: Add vendor hypervisor firmware register
  KVM: arm64: Add standard hypervisor firmware register
  KVM: arm64: Setup a framework for hypercall bitmap firmware registers
  KVM: arm64: Factor out firmware register handling from psci.c

Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parents d25f30fe 528ada28
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -2601,6 +2601,24 @@ EINVAL.
After the vcpu's SVE configuration is finalized, further attempts to
write this register will fail with EPERM.

arm64 bitmap feature firmware pseudo-registers have the following bit pattern::

  0x6030 0000 0016 <regno:16>

The bitmap feature firmware registers exposes the hypercall services that
are available for userspace to configure. The set bits corresponds to the
services that are available for the guests to access. By default, KVM
sets all the supported bits during VM initialization. The userspace can
discover the available services via KVM_GET_ONE_REG, and write back the
bitmap corresponding to the features that it wishes guests to see via
KVM_SET_ONE_REG.

Note: These registers are immutable once any of the vCPUs of the VM has
run at least once. A KVM_SET_ONE_REG in such a scenario will return
a -EBUSY to userspace.

(See Documentation/virt/kvm/arm/hypercalls.rst for more details.)


MIPS registers are mapped using the lower 32 bits.  The upper 16 of that is
the register group type:
+78 −17
Original line number Diff line number Diff line
.. SPDX-License-Identifier: GPL-2.0

=========================================
Power State Coordination Interface (PSCI)
=========================================
=======================
ARM Hypercall Interface
=======================

KVM implements the PSCI (Power State Coordination Interface)
specification in order to provide services such as CPU on/off, reset
and power-off to the guest.

The PSCI specification is regularly updated to provide new features,
and KVM implements these updates if they make sense from a virtualization
point of view.
KVM handles the hypercall services as requested by the guests. New hypercall
services are regularly made available by the ARM specification or by KVM (as
vendor services) if they make sense from a virtualization point of view.

This means that a guest booted on two different versions of KVM can
observe two different "firmware" revisions. This could cause issues if
a given guest is tied to a particular PSCI revision (unlikely), or if
a migration causes a different PSCI version to be exposed out of the
blue to an unsuspecting guest.
This means that a guest booted on two different versions of KVM can observe
two different "firmware" revisions. This could cause issues if a given guest
is tied to a particular version of a hypercall service, or if a migration
causes a different version to be exposed out of the blue to an unsuspecting
guest.

In order to remedy this situation, KVM exposes a set of "firmware
pseudo-registers" that can be manipulated using the GET/SET_ONE_REG
interface. These registers can be saved/restored by userspace, and set
to a convenient value if required.
to a convenient value as required.

The following register is defined:
The following registers are defined:

* KVM_REG_ARM_PSCI_VERSION:

  KVM implements the PSCI (Power State Coordination Interface)
  specification in order to provide services such as CPU on/off, reset
  and power-off to the guest.

  - Only valid if the vcpu has the KVM_ARM_VCPU_PSCI_0_2 feature set
    (and thus has already been initialized)
  - Returns the current PSCI version on GET_ONE_REG (defaulting to the
@@ -74,4 +74,65 @@ The following register is defined:
    KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED:
      The workaround is always active on this vCPU or it is not needed.


Bitmap Feature Firmware Registers
---------------------------------

Contrary to the above registers, the following registers exposes the
hypercall services in the form of a feature-bitmap to the userspace. This
bitmap is translated to the services that are available to the guest.
There is a register defined per service call owner and can be accessed via
GET/SET_ONE_REG interface.

By default, these registers are set with the upper limit of the features
that are supported. This way userspace can discover all the usable
hypercall services via GET_ONE_REG. The user-space can write-back the
desired bitmap back via SET_ONE_REG. The features for the registers that
are untouched, probably because userspace isn't aware of them, will be
exposed as is to the guest.

Note that KVM will not allow the userspace to configure the registers
anymore once any of the vCPUs has run at least once. Instead, it will
return a -EBUSY.

The pseudo-firmware bitmap register are as follows:

* KVM_REG_ARM_STD_BMAP:
    Controls the bitmap of the ARM Standard Secure Service Calls.

  The following bits are accepted:

    Bit-0: KVM_REG_ARM_STD_BIT_TRNG_V1_0:
      The bit represents the services offered under v1.0 of ARM True Random
      Number Generator (TRNG) specification, ARM DEN0098.

* KVM_REG_ARM_STD_HYP_BMAP:
    Controls the bitmap of the ARM Standard Hypervisor Service Calls.

  The following bits are accepted:

    Bit-0: KVM_REG_ARM_STD_HYP_BIT_PV_TIME:
      The bit represents the Paravirtualized Time service as represented by
      ARM DEN0057A.

* KVM_REG_ARM_VENDOR_HYP_BMAP:
    Controls the bitmap of the Vendor specific Hypervisor Service Calls.

  The following bits are accepted:

    Bit-0: KVM_REG_ARM_VENDOR_HYP_BIT_FUNC_FEAT
      The bit represents the ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID
      and ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID function-ids.

    Bit-1: KVM_REG_ARM_VENDOR_HYP_BIT_PTP:
      The bit represents the Precision Time Protocol KVM service.

Errors:

    =======  =============================================================
    -ENOENT   Unknown register accessed.
    -EBUSY    Attempt a 'write' to the register after the VM has started.
    -EINVAL   Invalid bitmap written to the register.
    =======  =============================================================

.. [1] https://developer.arm.com/-/media/developer/pdf/ARM_DEN_0070A_Firmware_interfaces_for_mitigating_CVE-2017-5715.pdf
+1 −1
Original line number Diff line number Diff line
@@ -8,6 +8,6 @@ ARM
   :maxdepth: 2

   hyp-abi
   psci
   hypercalls
   pvtime
   ptp_kvm
+16 −0
Original line number Diff line number Diff line
@@ -101,6 +101,19 @@ struct kvm_s2_mmu {
struct kvm_arch_memory_slot {
};

/**
 * struct kvm_smccc_features: Descriptor of the hypercall services exposed to the guests
 *
 * @std_bmap: Bitmap of standard secure service calls
 * @std_hyp_bmap: Bitmap of standard hypervisor service calls
 * @vendor_hyp_bmap: Bitmap of vendor specific hypervisor service calls
 */
struct kvm_smccc_features {
	unsigned long std_bmap;
	unsigned long std_hyp_bmap;
	unsigned long vendor_hyp_bmap;
};

struct kvm_arch {
	struct kvm_s2_mmu mmu;

@@ -150,6 +163,9 @@ struct kvm_arch {

	u8 pfr0_csv2;
	u8 pfr0_csv3;

	/* Hypercall features firmware registers' descriptor */
	struct kvm_smccc_features smccc_feat;
};

struct kvm_vcpu_fault_info {
+34 −0
Original line number Diff line number Diff line
@@ -332,6 +332,40 @@ struct kvm_arm_copy_mte_tags {
#define KVM_ARM64_SVE_VLS_WORDS	\
	((KVM_ARM64_SVE_VQ_MAX - KVM_ARM64_SVE_VQ_MIN) / 64 + 1)

/* Bitmap feature firmware registers */
#define KVM_REG_ARM_FW_FEAT_BMAP		(0x0016 << KVM_REG_ARM_COPROC_SHIFT)
#define KVM_REG_ARM_FW_FEAT_BMAP_REG(r)		(KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
						KVM_REG_ARM_FW_FEAT_BMAP |	\
						((r) & 0xffff))

#define KVM_REG_ARM_STD_BMAP			KVM_REG_ARM_FW_FEAT_BMAP_REG(0)

enum {
	KVM_REG_ARM_STD_BIT_TRNG_V1_0	= 0,
#ifdef __KERNEL__
	KVM_REG_ARM_STD_BMAP_BIT_COUNT,
#endif
};

#define KVM_REG_ARM_STD_HYP_BMAP		KVM_REG_ARM_FW_FEAT_BMAP_REG(1)

enum {
	KVM_REG_ARM_STD_HYP_BIT_PV_TIME	= 0,
#ifdef __KERNEL__
	KVM_REG_ARM_STD_HYP_BMAP_BIT_COUNT,
#endif
};

#define KVM_REG_ARM_VENDOR_HYP_BMAP		KVM_REG_ARM_FW_FEAT_BMAP_REG(2)

enum {
	KVM_REG_ARM_VENDOR_HYP_BIT_FUNC_FEAT	= 0,
	KVM_REG_ARM_VENDOR_HYP_BIT_PTP		= 1,
#ifdef __KERNEL__
	KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_COUNT,
#endif
};

/* Device Control API: ARM VGIC */
#define KVM_DEV_ARM_VGIC_GRP_ADDR	0
#define KVM_DEV_ARM_VGIC_GRP_DIST_REGS	1
Loading