Commit 94686c3c authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm

Pull KVM fixes from Radim Krčmář:

 - fix build without CONFIG_HAVE_KVM_IRQ_ROUTING

 - fix NULL access in x86 CR access

 - fix race with VMX posted interrups

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  KVM: VMX: remove WARN_ON_ONCE in kvm_vcpu_trigger_posted_interrupt
  KVM: VMX: do not change SN bit in vmx_update_pi_irte()
  KVM: x86: Fix the NULL pointer parameter in check_cr_write()
  Revert "KVM: Don't accept obviously wrong gsi values via KVM_IRQFD"
parents 12fcf66e 5753743f
...@@ -4102,10 +4102,12 @@ static int check_cr_write(struct x86_emulate_ctxt *ctxt) ...@@ -4102,10 +4102,12 @@ static int check_cr_write(struct x86_emulate_ctxt *ctxt)
ctxt->ops->get_msr(ctxt, MSR_EFER, &efer); ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
if (efer & EFER_LMA) { if (efer & EFER_LMA) {
u64 maxphyaddr; u64 maxphyaddr;
u32 eax = 0x80000008; u32 eax, ebx, ecx, edx;
if (ctxt->ops->get_cpuid(ctxt, &eax, NULL, NULL, eax = 0x80000008;
NULL, false)) ecx = 0;
if (ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx,
&edx, false))
maxphyaddr = eax & 0xff; maxphyaddr = eax & 0xff;
else else
maxphyaddr = 36; maxphyaddr = 36;
......
...@@ -5077,21 +5077,30 @@ static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu, ...@@ -5077,21 +5077,30 @@ static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu,
int pi_vec = nested ? POSTED_INTR_NESTED_VECTOR : POSTED_INTR_VECTOR; int pi_vec = nested ? POSTED_INTR_NESTED_VECTOR : POSTED_INTR_VECTOR;
if (vcpu->mode == IN_GUEST_MODE) { if (vcpu->mode == IN_GUEST_MODE) {
struct vcpu_vmx *vmx = to_vmx(vcpu);
/* /*
* Currently, we don't support urgent interrupt, * The vector of interrupt to be delivered to vcpu had
* all interrupts are recognized as non-urgent * been set in PIR before this function.
* interrupt, so we cannot post interrupts when *
* 'SN' is set. * Following cases will be reached in this block, and
* we always send a notification event in all cases as
* explained below.
*
* Case 1: vcpu keeps in non-root mode. Sending a
* notification event posts the interrupt to vcpu.
* *
* If the vcpu is in guest mode, it means it is * Case 2: vcpu exits to root mode and is still
* running instead of being scheduled out and * runnable. PIR will be synced to vIRR before the
* waiting in the run queue, and that's the only * next vcpu entry. Sending a notification event in
* case when 'SN' is set currently, warning if * this case has no effect, as vcpu is not in root
* 'SN' is set. * mode.
*
* Case 3: vcpu exits to root mode and is blocked.
* vcpu_block() has already synced PIR to vIRR and
* never blocks vcpu if vIRR is not cleared. Therefore,
* a blocked vcpu here does not wait for any requested
* interrupts in PIR, and sending a notification event
* which has no effect is safe here.
*/ */
WARN_ON_ONCE(pi_test_sn(&vmx->pi_desc));
apic->send_IPI_mask(get_cpu_mask(vcpu->cpu), pi_vec); apic->send_IPI_mask(get_cpu_mask(vcpu->cpu), pi_vec);
return true; return true;
...@@ -11911,12 +11920,8 @@ static int vmx_update_pi_irte(struct kvm *kvm, unsigned int host_irq, ...@@ -11911,12 +11920,8 @@ static int vmx_update_pi_irte(struct kvm *kvm, unsigned int host_irq,
if (set) if (set)
ret = irq_set_vcpu_affinity(host_irq, &vcpu_info); ret = irq_set_vcpu_affinity(host_irq, &vcpu_info);
else { else
/* suppress notification event before unposting */
pi_set_sn(vcpu_to_pi_desc(vcpu));
ret = irq_set_vcpu_affinity(host_irq, NULL); ret = irq_set_vcpu_affinity(host_irq, NULL);
pi_clear_sn(vcpu_to_pi_desc(vcpu));
}
if (ret < 0) { if (ret < 0) {
printk(KERN_INFO "%s: failed to update PI IRTE\n", printk(KERN_INFO "%s: failed to update PI IRTE\n",
......
...@@ -565,8 +565,6 @@ kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args) ...@@ -565,8 +565,6 @@ kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args)
{ {
if (args->flags & ~(KVM_IRQFD_FLAG_DEASSIGN | KVM_IRQFD_FLAG_RESAMPLE)) if (args->flags & ~(KVM_IRQFD_FLAG_DEASSIGN | KVM_IRQFD_FLAG_RESAMPLE))
return -EINVAL; return -EINVAL;
if (args->gsi >= KVM_MAX_IRQ_ROUTES)
return -EINVAL;
if (args->flags & KVM_IRQFD_FLAG_DEASSIGN) if (args->flags & KVM_IRQFD_FLAG_DEASSIGN)
return kvm_irqfd_deassign(kvm, args); return kvm_irqfd_deassign(kvm, args);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment