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

   - Rework of system register accessors for system registers that are
     directly writen to memory, so that sanitisation of the in-memory
     value happens at the correct time (after the read, or before the
     write). For convenience, RMW-style accessors are also provided.

   - Multiple fixes for the so-called "arch-timer-edge-cases' selftest,
     which was always broken.

  x86:

   - Make KVM_PRE_FAULT_MEMORY stricter for TDX, allowing userspace to
     pass only the "untouched" addresses and flipping the shared/private
     bit in the implementation.

   - Disable SEV-SNP support on initialization failure

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  KVM: x86/mmu: Reject direct bits in gpa passed to KVM_PRE_FAULT_MEMORY
  KVM: x86/mmu: Embed direct bits into gpa for KVM_PRE_FAULT_MEMORY
  KVM: SEV: Disable SEV-SNP support on initialization failure
  KVM: arm64: selftests: Determine effective counter width in arch_timer_edge_cases
  KVM: arm64: selftests: Fix xVAL init in arch_timer_edge_cases
  KVM: arm64: selftests: Fix thread migration in arch_timer_edge_cases
  KVM: arm64: selftests: Fix help text for arch_timer_edge_cases
  KVM: arm64: Make __vcpu_sys_reg() a pure rvalue operand
  KVM: arm64: Don't use __vcpu_sys_reg() to get the address of a sysreg
  KVM: arm64: Add RMW specific sysreg accessor
  KVM: arm64: Add assignment-specific sysreg accessor
parents ad615908 8046d29d
Loading
Loading
Loading
Loading
+27 −5
Original line number Diff line number Diff line
@@ -1107,14 +1107,36 @@ static inline u64 *___ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
#define ctxt_sys_reg(c,r)	(*__ctxt_sys_reg(c,r))

u64 kvm_vcpu_apply_reg_masks(const struct kvm_vcpu *, enum vcpu_sysreg, u64);

#define __vcpu_assign_sys_reg(v, r, val)				\
	do {								\
		const struct kvm_cpu_context *ctxt = &(v)->arch.ctxt;	\
		u64 __v = (val);					\
		if (vcpu_has_nv((v)) && (r) >= __SANITISED_REG_START__)	\
			__v = kvm_vcpu_apply_reg_masks((v), (r), __v);	\
									\
		ctxt_sys_reg(ctxt, (r)) = __v;				\
	} while (0)

#define __vcpu_rmw_sys_reg(v, r, op, val)				\
	do {								\
		const struct kvm_cpu_context *ctxt = &(v)->arch.ctxt;	\
		u64 __v = ctxt_sys_reg(ctxt, (r));			\
		__v op (val);						\
		if (vcpu_has_nv((v)) && (r) >= __SANITISED_REG_START__)	\
			__v = kvm_vcpu_apply_reg_masks((v), (r), __v);	\
									\
		ctxt_sys_reg(ctxt, (r)) = __v;				\
	} while (0)

#define __vcpu_sys_reg(v,r)						\
	(*({								\
	({								\
		const struct kvm_cpu_context *ctxt = &(v)->arch.ctxt;	\
		u64 *__r = __ctxt_sys_reg(ctxt, (r));			\
		u64 __v = ctxt_sys_reg(ctxt, (r));			\
		if (vcpu_has_nv((v)) && (r) >= __SANITISED_REG_START__)	\
			*__r = kvm_vcpu_apply_reg_masks((v), (r), *__r);\
		__r;							\
	}))
			__v = kvm_vcpu_apply_reg_masks((v), (r), __v);	\
		__v;							\
	})

u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg);
void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg);
+9 −9
Original line number Diff line number Diff line
@@ -108,16 +108,16 @@ static void timer_set_ctl(struct arch_timer_context *ctxt, u32 ctl)

	switch(arch_timer_ctx_index(ctxt)) {
	case TIMER_VTIMER:
		__vcpu_sys_reg(vcpu, CNTV_CTL_EL0) = ctl;
		__vcpu_assign_sys_reg(vcpu, CNTV_CTL_EL0, ctl);
		break;
	case TIMER_PTIMER:
		__vcpu_sys_reg(vcpu, CNTP_CTL_EL0) = ctl;
		__vcpu_assign_sys_reg(vcpu, CNTP_CTL_EL0, ctl);
		break;
	case TIMER_HVTIMER:
		__vcpu_sys_reg(vcpu, CNTHV_CTL_EL2) = ctl;
		__vcpu_assign_sys_reg(vcpu, CNTHV_CTL_EL2, ctl);
		break;
	case TIMER_HPTIMER:
		__vcpu_sys_reg(vcpu, CNTHP_CTL_EL2) = ctl;
		__vcpu_assign_sys_reg(vcpu, CNTHP_CTL_EL2, ctl);
		break;
	default:
		WARN_ON(1);
@@ -130,16 +130,16 @@ static void timer_set_cval(struct arch_timer_context *ctxt, u64 cval)

	switch(arch_timer_ctx_index(ctxt)) {
	case TIMER_VTIMER:
		__vcpu_sys_reg(vcpu, CNTV_CVAL_EL0) = cval;
		__vcpu_assign_sys_reg(vcpu, CNTV_CVAL_EL0, cval);
		break;
	case TIMER_PTIMER:
		__vcpu_sys_reg(vcpu, CNTP_CVAL_EL0) = cval;
		__vcpu_assign_sys_reg(vcpu, CNTP_CVAL_EL0, cval);
		break;
	case TIMER_HVTIMER:
		__vcpu_sys_reg(vcpu, CNTHV_CVAL_EL2) = cval;
		__vcpu_assign_sys_reg(vcpu, CNTHV_CVAL_EL2, cval);
		break;
	case TIMER_HPTIMER:
		__vcpu_sys_reg(vcpu, CNTHP_CVAL_EL2) = cval;
		__vcpu_assign_sys_reg(vcpu, CNTHP_CVAL_EL2, cval);
		break;
	default:
		WARN_ON(1);
@@ -1036,7 +1036,7 @@ void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu)
	if (vcpu_has_nv(vcpu)) {
		struct arch_timer_offset *offs = &vcpu_vtimer(vcpu)->offset;

		offs->vcpu_offset = &__vcpu_sys_reg(vcpu, CNTVOFF_EL2);
		offs->vcpu_offset = __ctxt_sys_reg(&vcpu->arch.ctxt, CNTVOFF_EL2);
		offs->vm_offset = &vcpu->kvm->arch.timer_data.poffset;
	}

+2 −2
Original line number Diff line number Diff line
@@ -216,9 +216,9 @@ void kvm_debug_set_guest_ownership(struct kvm_vcpu *vcpu)
void kvm_debug_handle_oslar(struct kvm_vcpu *vcpu, u64 val)
{
	if (val & OSLAR_EL1_OSLK)
		__vcpu_sys_reg(vcpu, OSLSR_EL1) |= OSLSR_EL1_OSLK;
		__vcpu_rmw_sys_reg(vcpu, OSLSR_EL1, |=, OSLSR_EL1_OSLK);
	else
		__vcpu_sys_reg(vcpu, OSLSR_EL1) &= ~OSLSR_EL1_OSLK;
		__vcpu_rmw_sys_reg(vcpu, OSLSR_EL1, &=, ~OSLSR_EL1_OSLK);

	preempt_disable();
	kvm_arch_vcpu_put(vcpu);
+2 −2
Original line number Diff line number Diff line
@@ -103,8 +103,8 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
		fp_state.sve_state = vcpu->arch.sve_state;
		fp_state.sve_vl = vcpu->arch.sve_max_vl;
		fp_state.sme_state = NULL;
		fp_state.svcr = &__vcpu_sys_reg(vcpu, SVCR);
		fp_state.fpmr = &__vcpu_sys_reg(vcpu, FPMR);
		fp_state.svcr = __ctxt_sys_reg(&vcpu->arch.ctxt, SVCR);
		fp_state.fpmr = __ctxt_sys_reg(&vcpu->arch.ctxt, FPMR);
		fp_state.fp_type = &vcpu->arch.fp_type;

		if (vcpu_has_sve(vcpu))
+2 −2
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ static inline void __vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
	if (unlikely(vcpu_has_nv(vcpu)))
		vcpu_write_sys_reg(vcpu, val, reg);
	else if (!__vcpu_write_sys_reg_to_cpu(val, reg))
		__vcpu_sys_reg(vcpu, reg) = val;
		__vcpu_assign_sys_reg(vcpu, reg, val);
}

static void __vcpu_write_spsr(struct kvm_vcpu *vcpu, unsigned long target_mode,
@@ -51,7 +51,7 @@ static void __vcpu_write_spsr(struct kvm_vcpu *vcpu, unsigned long target_mode,
	} else if (has_vhe()) {
		write_sysreg_el1(val, SYS_SPSR);
	} else {
		__vcpu_sys_reg(vcpu, SPSR_EL1) = val;
		__vcpu_assign_sys_reg(vcpu, SPSR_EL1, val);
	}
}

Loading