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

Commit b0a75281 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull KVM fixes from Radim Krčmář:
 "A bunch of small fixes for x86"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  kvm: x86: hyperv: avoid livelock in oneshot SynIC timers
  KVM: VMX: Fix invalid guest state detection after task-switch emulation
  x86: add MULTIUSER dependency for KVM
  KVM: nVMX: Disallow VM-entry in MOV-SS shadow
  KVM: nVMX: track NMI blocking state separately for each VMCS
  KVM: x86: masking out upper bits
parents 10fc9554 f1ff89ec
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -22,7 +22,7 @@ config KVM
	depends on HAVE_KVM
	depends on HAVE_KVM
	depends on HIGH_RES_TIMERS
	depends on HIGH_RES_TIMERS
	# for TASKSTATS/TASK_DELAY_ACCT:
	# for TASKSTATS/TASK_DELAY_ACCT:
	depends on NET
	depends on NET && MULTIUSER
	select PREEMPT_NOTIFIERS
	select PREEMPT_NOTIFIERS
	select MMU_NOTIFIER
	select MMU_NOTIFIER
	select ANON_INODES
	select ANON_INODES
+4 −3
Original line number Original line Diff line number Diff line
@@ -649,9 +649,10 @@ void kvm_hv_process_stimers(struct kvm_vcpu *vcpu)
				}
				}


				if ((stimer->config & HV_STIMER_ENABLE) &&
				if ((stimer->config & HV_STIMER_ENABLE) &&
				    stimer->count)
				    stimer->count) {
					if (!stimer->msg_pending)
						stimer_start(stimer);
						stimer_start(stimer);
				else
				} else
					stimer_cleanup(stimer);
					stimer_cleanup(stimer);
			}
			}
		}
		}
+31 −15
Original line number Original line Diff line number Diff line
@@ -198,7 +198,8 @@ struct loaded_vmcs {
	struct vmcs *vmcs;
	struct vmcs *vmcs;
	struct vmcs *shadow_vmcs;
	struct vmcs *shadow_vmcs;
	int cpu;
	int cpu;
	int launched;
	bool launched;
	bool nmi_known_unmasked;
	struct list_head loaded_vmcss_on_cpu_link;
	struct list_head loaded_vmcss_on_cpu_link;
};
};


@@ -2326,6 +2327,11 @@ static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
	__vmx_load_host_state(to_vmx(vcpu));
	__vmx_load_host_state(to_vmx(vcpu));
}
}


static bool emulation_required(struct kvm_vcpu *vcpu)
{
	return emulate_invalid_guest_state && !guest_state_valid(vcpu);
}

static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu);
static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu);


/*
/*
@@ -2363,6 +2369,8 @@ static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu)


static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
{
{
	unsigned long old_rflags = vmx_get_rflags(vcpu);

	__set_bit(VCPU_EXREG_RFLAGS, (ulong *)&vcpu->arch.regs_avail);
	__set_bit(VCPU_EXREG_RFLAGS, (ulong *)&vcpu->arch.regs_avail);
	to_vmx(vcpu)->rflags = rflags;
	to_vmx(vcpu)->rflags = rflags;
	if (to_vmx(vcpu)->rmode.vm86_active) {
	if (to_vmx(vcpu)->rmode.vm86_active) {
@@ -2370,6 +2378,9 @@ static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
		rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
		rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
	}
	}
	vmcs_writel(GUEST_RFLAGS, rflags);
	vmcs_writel(GUEST_RFLAGS, rflags);

	if ((old_rflags ^ to_vmx(vcpu)->rflags) & X86_EFLAGS_VM)
		to_vmx(vcpu)->emulation_required = emulation_required(vcpu);
}
}


static u32 vmx_get_pkru(struct kvm_vcpu *vcpu)
static u32 vmx_get_pkru(struct kvm_vcpu *vcpu)
@@ -3857,11 +3868,6 @@ static __init int alloc_kvm_area(void)
	return 0;
	return 0;
}
}


static bool emulation_required(struct kvm_vcpu *vcpu)
{
	return emulate_invalid_guest_state && !guest_state_valid(vcpu);
}

static void fix_pmode_seg(struct kvm_vcpu *vcpu, int seg,
static void fix_pmode_seg(struct kvm_vcpu *vcpu, int seg,
		struct kvm_segment *save)
		struct kvm_segment *save)
{
{
@@ -5510,10 +5516,8 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu)
{
{
	struct vcpu_vmx *vmx = to_vmx(vcpu);
	struct vcpu_vmx *vmx = to_vmx(vcpu);


	if (!is_guest_mode(vcpu)) {
	++vcpu->stat.nmi_injections;
	++vcpu->stat.nmi_injections;
		vmx->nmi_known_unmasked = false;
	vmx->loaded_vmcs->nmi_known_unmasked = false;
	}


	if (vmx->rmode.vm86_active) {
	if (vmx->rmode.vm86_active) {
		if (kvm_inject_realmode_interrupt(vcpu, NMI_VECTOR, 0) != EMULATE_DONE)
		if (kvm_inject_realmode_interrupt(vcpu, NMI_VECTOR, 0) != EMULATE_DONE)
@@ -5527,16 +5531,21 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu)


static bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu)
static bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu)
{
{
	if (to_vmx(vcpu)->nmi_known_unmasked)
	struct vcpu_vmx *vmx = to_vmx(vcpu);
	bool masked;

	if (vmx->loaded_vmcs->nmi_known_unmasked)
		return false;
		return false;
	return vmcs_read32(GUEST_INTERRUPTIBILITY_INFO)	& GUEST_INTR_STATE_NMI;
	masked = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & GUEST_INTR_STATE_NMI;
	vmx->loaded_vmcs->nmi_known_unmasked = !masked;
	return masked;
}
}


static void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked)
static void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked)
{
{
	struct vcpu_vmx *vmx = to_vmx(vcpu);
	struct vcpu_vmx *vmx = to_vmx(vcpu);


	vmx->nmi_known_unmasked = !masked;
	vmx->loaded_vmcs->nmi_known_unmasked = !masked;
	if (masked)
	if (masked)
		vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
		vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
			      GUEST_INTR_STATE_NMI);
			      GUEST_INTR_STATE_NMI);
@@ -8736,7 +8745,7 @@ static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx)


	idtv_info_valid = vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK;
	idtv_info_valid = vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK;


	if (vmx->nmi_known_unmasked)
	if (vmx->loaded_vmcs->nmi_known_unmasked)
		return;
		return;
	/*
	/*
	 * Can't use vmx->exit_intr_info since we're not sure what
	 * Can't use vmx->exit_intr_info since we're not sure what
@@ -8760,7 +8769,7 @@ static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx)
		vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
		vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
			      GUEST_INTR_STATE_NMI);
			      GUEST_INTR_STATE_NMI);
	else
	else
		vmx->nmi_known_unmasked =
		vmx->loaded_vmcs->nmi_known_unmasked =
			!(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO)
			!(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO)
			  & GUEST_INTR_STATE_NMI);
			  & GUEST_INTR_STATE_NMI);
}
}
@@ -10488,6 +10497,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
{
{
	struct vmcs12 *vmcs12;
	struct vmcs12 *vmcs12;
	struct vcpu_vmx *vmx = to_vmx(vcpu);
	struct vcpu_vmx *vmx = to_vmx(vcpu);
	u32 interrupt_shadow = vmx_get_interrupt_shadow(vcpu);
	u32 exit_qual;
	u32 exit_qual;
	int ret;
	int ret;


@@ -10512,6 +10522,12 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
	 * for misconfigurations which will anyway be caught by the processor
	 * for misconfigurations which will anyway be caught by the processor
	 * when using the merged vmcs02.
	 * when using the merged vmcs02.
	 */
	 */
	if (interrupt_shadow & KVM_X86_SHADOW_INT_MOV_SS) {
		nested_vmx_failValid(vcpu,
				     VMXERR_ENTRY_EVENTS_BLOCKED_BY_MOV_SS);
		goto out;
	}

	if (vmcs12->launch_state == launch) {
	if (vmcs12->launch_state == launch) {
		nested_vmx_failValid(vcpu,
		nested_vmx_failValid(vcpu,
			launch ? VMXERR_VMLAUNCH_NONCLEAR_VMCS
			launch ? VMXERR_VMLAUNCH_NONCLEAR_VMCS
+2 −2
Original line number Original line Diff line number Diff line
@@ -597,8 +597,8 @@ bool pdptrs_changed(struct kvm_vcpu *vcpu)
		      (unsigned long *)&vcpu->arch.regs_avail))
		      (unsigned long *)&vcpu->arch.regs_avail))
		return true;
		return true;


	gfn = (kvm_read_cr3(vcpu) & ~31u) >> PAGE_SHIFT;
	gfn = (kvm_read_cr3(vcpu) & ~31ul) >> PAGE_SHIFT;
	offset = (kvm_read_cr3(vcpu) & ~31u) & (PAGE_SIZE - 1);
	offset = (kvm_read_cr3(vcpu) & ~31ul) & (PAGE_SIZE - 1);
	r = kvm_read_nested_guest_page(vcpu, gfn, pdpte, offset, sizeof(pdpte),
	r = kvm_read_nested_guest_page(vcpu, gfn, pdpte, offset, sizeof(pdpte),
				       PFERR_USER_MASK | PFERR_WRITE_MASK);
				       PFERR_USER_MASK | PFERR_WRITE_MASK);
	if (r < 0)
	if (r < 0)