Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5eec43a1 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge tag 'kvmarm-for-v4.18' of...

Merge tag 'kvmarm-for-v4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD

KVM/ARM updates for 4.18

- Lazy context-switching of FPSIMD registers on arm64
- Allow virtual redistributors to be part of two or more MMIO ranges
parents 75025cc9 e25028c8
Loading
Loading
Loading
Loading
+28 −2
Original line number Diff line number Diff line
@@ -27,16 +27,42 @@ Groups:
      VCPU and all of the redistributor pages are contiguous.
      Only valid for KVM_DEV_TYPE_ARM_VGIC_V3.
      This address needs to be 64K aligned.

    KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION (rw, 64-bit)
      The attribute data pointed to by kvm_device_attr.addr is a __u64 value:
      bits:     | 63   ....  52  |  51   ....   16 | 15 - 12  |11 - 0
      values:   |     count      |       base      |  flags   | index
      - index encodes the unique redistributor region index
      - flags: reserved for future use, currently 0
      - base field encodes bits [51:16] of the guest physical base address
        of the first redistributor in the region.
      - count encodes the number of redistributors in the region. Must be
        greater than 0.
      There are two 64K pages for each redistributor in the region and
      redistributors are laid out contiguously within the region. Regions
      are filled with redistributors in the index order. The sum of all
      region count fields must be greater than or equal to the number of
      VCPUs. Redistributor regions must be registered in the incremental
      index order, starting from index 0.
      The characteristics of a specific redistributor region can be read
      by presetting the index field in the attr data.
      Only valid for KVM_DEV_TYPE_ARM_VGIC_V3.

  It is invalid to mix calls with KVM_VGIC_V3_ADDR_TYPE_REDIST and
  KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION attributes.

  Errors:
    -E2BIG:  Address outside of addressable IPA range
    -EINVAL: Incorrectly aligned address
    -EINVAL: Incorrectly aligned address, bad redistributor region
             count/index, mixed redistributor region attribute usage
    -EEXIST: Address already configured
    -ENOENT: Attempt to read the characteristics of a non existing
             redistributor region
    -ENXIO:  The group or attribute is unknown/unsupported for this device
             or hardware support is missing.
    -EFAULT: Invalid user pointer for attr->addr.



  KVM_DEV_ARM_VGIC_GRP_DIST_REGS
  KVM_DEV_ARM_VGIC_GRP_REDIST_REGS
  Attributes:
+8 −2
Original line number Diff line number Diff line
@@ -280,6 +280,7 @@ void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);

struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);

static inline bool kvm_arch_check_sve_has_vhe(void) { return true; }
static inline void kvm_arch_hardware_unsetup(void) {}
static inline void kvm_arch_sync_events(struct kvm *kvm) {}
static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
@@ -303,8 +304,13 @@ int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu,
int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu,
			       struct kvm_device_attr *attr);

/* All host FP/SIMD state is restored on guest exit, so nothing to save: */
static inline void kvm_fpsimd_flush_cpu_state(void) {}
/*
 * VFP/NEON switching is all done by the hyp switch code, so no need to
 * coordinate with host context handling for this state:
 */
static inline void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu) {}
static inline void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu) {}
static inline void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu) {}

static inline void kvm_arm_vhe_guest_enter(void) {}
static inline void kvm_arm_vhe_guest_exit(void) {}
+1 −0
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ struct kvm_regs {
#define KVM_VGIC_V3_ADDR_TYPE_DIST	2
#define KVM_VGIC_V3_ADDR_TYPE_REDIST	3
#define KVM_VGIC_ITS_ADDR_TYPE		4
#define KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION	5

#define KVM_VGIC_V3_DIST_SIZE		SZ_64K
#define KVM_VGIC_V3_REDIST_SIZE		(2 * SZ_64K)
+7 −0
Original line number Diff line number Diff line
@@ -1130,6 +1130,7 @@ endmenu
config ARM64_SVE
	bool "ARM Scalable Vector Extension support"
	default y
	depends on !KVM || ARM64_VHE
	help
	  The Scalable Vector Extension (SVE) is an extension to the AArch64
	  execution state which complements and extends the SIMD functionality
@@ -1155,6 +1156,12 @@ config ARM64_SVE
	  booting the kernel.  If unsure and you are not observing these
	  symptoms, you should assume that it is safe to say Y.

	  CPUs that support SVE are architecturally required to support the
	  Virtualization Host Extensions (VHE), so the kernel makes no
	  provision for supporting SVE alongside KVM without VHE enabled.
	  Thus, you will need to enable CONFIG_ARM64_VHE if you want to support
	  KVM in the same kernel image.

config ARM64_MODULE_PLTS
	bool
	select HAVE_MOD_ARCH_SPECIFIC
+0 −29
Original line number Diff line number Diff line
@@ -11,9 +11,7 @@

#include <asm/cpucaps.h>
#include <asm/cputype.h>
#include <asm/fpsimd.h>
#include <asm/hwcap.h>
#include <asm/sigcontext.h>
#include <asm/sysreg.h>

/*
@@ -510,33 +508,6 @@ static inline bool system_supports_sve(void)
		cpus_have_const_cap(ARM64_SVE);
}

/*
 * Read the pseudo-ZCR used by cpufeatures to identify the supported SVE
 * vector length.
 *
 * Use only if SVE is present.
 * This function clobbers the SVE vector length.
 */
static inline u64 read_zcr_features(void)
{
	u64 zcr;
	unsigned int vq_max;

	/*
	 * Set the maximum possible VL, and write zeroes to all other
	 * bits to see if they stick.
	 */
	sve_kernel_enable(NULL);
	write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL1);

	zcr = read_sysreg_s(SYS_ZCR_EL1);
	zcr &= ~(u64)ZCR_ELx_LEN_MASK; /* find sticky 1s outside LEN field */
	vq_max = sve_vq_from_vl(sve_get_vl());
	zcr |= vq_max - 1; /* set LEN field to maximum effective value */

	return zcr;
}

#endif /* __ASSEMBLY__ */

#endif
Loading