Commit 5fdb2621 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull kvm fixes from Paolo Bonzini:
 "ARM:

   - A couple of fixes when handling an exception while a SError has
     been delivered

   - Workaround for Cortex-A510's single-step erratum

  RISC-V:

   - Make CY, TM, and IR counters accessible in VU mode

   - Fix SBI implementation version

  x86:

   - Report deprecation of x87 features in supported CPUID

   - Preparation for fixing an interrupt delivery race on AMD hardware

   - Sparse fix

  All except POWER and s390:

   - Rework guest entry code to correctly mark noinstr areas and fix
     vtime' accounting (for x86, this was already mostly correct but not
     entirely; for ARM, MIPS and RISC-V it wasn't)"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  KVM: x86: Use ERR_PTR_USR() to return -EFAULT as a __user pointer
  KVM: x86: Report deprecated x87 features in supported CPUID
  KVM: arm64: Workaround Cortex-A510's single-step and PAC trap errata
  KVM: arm64: Stop handle_exit() from handling HVC twice when an SError occurs
  KVM: arm64: Avoid consuming a stale esr value when SError occur
  RISC-V: KVM: Fix SBI implementation version
  RISC-V: KVM: make CY, TM, and IR counters accessible in VU mode
  kvm/riscv: rework guest entry logic
  kvm/arm64: rework guest entry logic
  kvm/x86: rework guest entry logic
  kvm/mips: rework guest entry logic
  kvm: add guest_state_{enter,exit}_irqoff()
  KVM: x86: Move delivery of non-APICv interrupt into vendor code
  kvm: Move KVM_GET_XSAVE2 IOCTL definition at the end of kvm.h
parents fbc04bf0 7e6a6b40
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -100,6 +100,8 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+
| ARM            | Cortex-A510     | #2051678        | ARM64_ERRATUM_2051678       |
+----------------+-----------------+-----------------+-----------------------------+
| ARM            | Cortex-A510     | #2077057        | ARM64_ERRATUM_2077057       |
+----------------+-----------------+-----------------+-----------------------------+
| ARM            | Cortex-A710     | #2119858        | ARM64_ERRATUM_2119858       |
+----------------+-----------------+-----------------+-----------------------------+
| ARM            | Cortex-A710     | #2054223        | ARM64_ERRATUM_2054223       |
+16 −0
Original line number Diff line number Diff line
@@ -680,6 +680,22 @@ config ARM64_ERRATUM_2051678

	  If unsure, say Y.

config ARM64_ERRATUM_2077057
	bool "Cortex-A510: 2077057: workaround software-step corrupting SPSR_EL2"
	help
	  This option adds the workaround for ARM Cortex-A510 erratum 2077057.
	  Affected Cortex-A510 may corrupt SPSR_EL2 when the a step exception is
	  expected, but a Pointer Authentication trap is taken instead. The
	  erratum causes SPSR_EL1 to be copied to SPSR_EL2, which could allow
	  EL1 to cause a return to EL2 with a guest controlled ELR_EL2.

	  This can only happen when EL2 is stepping EL1.

	  When these conditions occur, the SPSR_EL2 value is unchanged from the
	  previous guest entry, and can be restored from the in-memory copy.

	  If unsure, say Y.

config ARM64_ERRATUM_2119858
	bool "Cortex-A710/X2: 2119858: workaround TRBE overwriting trace data in FILL mode"
	default y
+8 −0
Original line number Diff line number Diff line
@@ -600,6 +600,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
		CAP_MIDR_RANGE_LIST(trbe_write_out_of_range_cpus),
	},
#endif
#ifdef CONFIG_ARM64_ERRATUM_2077057
	{
		.desc = "ARM erratum 2077057",
		.capability = ARM64_WORKAROUND_2077057,
		.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2),
	},
#endif
#ifdef CONFIG_ARM64_ERRATUM_2064142
	{
		.desc = "ARM erratum 2064142",
+33 −18
Original line number Diff line number Diff line
@@ -797,6 +797,24 @@ static bool kvm_vcpu_exit_request(struct kvm_vcpu *vcpu, int *ret)
			xfer_to_guest_mode_work_pending();
}

/*
 * Actually run the vCPU, entering an RCU extended quiescent state (EQS) while
 * the vCPU is running.
 *
 * This must be noinstr as instrumentation may make use of RCU, and this is not
 * safe during the EQS.
 */
static int noinstr kvm_arm_vcpu_enter_exit(struct kvm_vcpu *vcpu)
{
	int ret;

	guest_state_enter_irqoff();
	ret = kvm_call_hyp_ret(__kvm_vcpu_run, vcpu);
	guest_state_exit_irqoff();

	return ret;
}

/**
 * kvm_arch_vcpu_ioctl_run - the main VCPU run function to execute guest code
 * @vcpu:	The VCPU pointer
@@ -881,9 +899,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
		 * Enter the guest
		 */
		trace_kvm_entry(*vcpu_pc(vcpu));
		guest_enter_irqoff();
		guest_timing_enter_irqoff();

		ret = kvm_call_hyp_ret(__kvm_vcpu_run, vcpu);
		ret = kvm_arm_vcpu_enter_exit(vcpu);

		vcpu->mode = OUTSIDE_GUEST_MODE;
		vcpu->stat.exits++;
@@ -918,26 +936,23 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
		kvm_arch_vcpu_ctxsync_fp(vcpu);

		/*
		 * We may have taken a host interrupt in HYP mode (ie
		 * while executing the guest). This interrupt is still
		 * pending, as we haven't serviced it yet!
		 * We must ensure that any pending interrupts are taken before
		 * we exit guest timing so that timer ticks are accounted as
		 * guest time. Transiently unmask interrupts so that any
		 * pending interrupts are taken.
		 *
		 * We're now back in SVC mode, with interrupts
		 * disabled.  Enabling the interrupts now will have
		 * the effect of taking the interrupt again, in SVC
		 * mode this time.
		 * Per ARM DDI 0487G.b section D1.13.4, an ISB (or other
		 * context synchronization event) is necessary to ensure that
		 * pending interrupts are taken.
		 */
		local_irq_enable();
		isb();
		local_irq_disable();

		guest_timing_exit_irqoff();

		local_irq_enable();

		/*
		 * We do local_irq_enable() before calling guest_exit() so
		 * that if a timer interrupt hits while running the guest we
		 * account that tick as being spent in the guest.  We enable
		 * preemption after calling guest_exit() so that if we get
		 * preempted we make sure ticks after that is not counted as
		 * guest time.
		 */
		guest_exit();
		trace_kvm_exit(ret, kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));

		/* Exit types that need handling before we can be preempted */
+8 −0
Original line number Diff line number Diff line
@@ -228,6 +228,14 @@ int handle_exit(struct kvm_vcpu *vcpu, int exception_index)
{
	struct kvm_run *run = vcpu->run;

	if (ARM_SERROR_PENDING(exception_index)) {
		/*
		 * The SError is handled by handle_exit_early(). If the guest
		 * survives it will re-execute the original instruction.
		 */
		return 1;
	}

	exception_index = ARM_EXCEPTION_CODE(exception_index);

	switch (exception_index) {
Loading