diff --git a/xen/drivers/passthrough/io.c b/xen/drivers/passthrough/io.c index ffeaf70be6..7e63007fbf 100644 --- a/xen/drivers/passthrough/io.c +++ b/xen/drivers/passthrough/io.c @@ -343,13 +343,16 @@ int pt_irq_create_bind( uint8_t dest, dest_mode, delivery_mode; int dest_vcpu_id; const struct vcpu *vcpu; + uint32_t gflags = pt_irq_bind->u.msi.gflags & ~VMSI_UNMASKED; + struct irq_desc *desc; + unsigned long flags; if ( !(pirq_dpci->flags & HVM_IRQ_DPCI_MAPPED) ) { pirq_dpci->flags = HVM_IRQ_DPCI_MAPPED | HVM_IRQ_DPCI_MACH_MSI | HVM_IRQ_DPCI_GUEST_MSI; pirq_dpci->gmsi.gvec = pt_irq_bind->u.msi.gvec; - pirq_dpci->gmsi.gflags = pt_irq_bind->u.msi.gflags; + pirq_dpci->gmsi.gflags = gflags; /* * 'pt_irq_create_bind' can be called after 'pt_irq_destroy_bind'. * The 'pirq_cleanup_check' which would free the structure is only @@ -402,13 +405,13 @@ int pt_irq_create_bind( /* If pirq is already mapped as vmsi, update guest data/addr. */ if ( pirq_dpci->gmsi.gvec != pt_irq_bind->u.msi.gvec || - pirq_dpci->gmsi.gflags != pt_irq_bind->u.msi.gflags ) + pirq_dpci->gmsi.gflags != gflags ) { /* Directly clear pending EOIs before enabling new MSI info. */ pirq_guest_eoi(info); pirq_dpci->gmsi.gvec = pt_irq_bind->u.msi.gvec; - pirq_dpci->gmsi.gflags = pt_irq_bind->u.msi.gflags; + pirq_dpci->gmsi.gflags = gflags; } } /* Calculate dest_vcpu_id for MSI-type pirq migration. */ @@ -439,6 +442,13 @@ int pt_irq_create_bind( pi_update_irte(vcpu ? &vcpu->arch.hvm_vmx.pi_desc : NULL, info, pirq_dpci->gmsi.gvec); + desc = irq_to_desc(info->arch.irq); + ASSERT(desc); + + spin_lock_irqsave(&desc->lock, flags); + guest_mask_msi_irq(desc, !(pt_irq_bind->u.msi.gflags & VMSI_UNMASKED)); + spin_unlock_irqrestore(&desc->lock, flags); + break; } diff --git a/xen/include/xen/hvm/irq.h b/xen/include/xen/hvm/irq.h index 0d2c72c109..bdc843fb9a 100644 --- a/xen/include/xen/hvm/irq.h +++ b/xen/include/xen/hvm/irq.h @@ -56,6 +56,7 @@ struct dev_intx_gsi_link { #define VMSI_DM_MASK 0x200 #define VMSI_DELIV_MASK 0x7000 #define VMSI_TRIG_MODE 0x8000 +#define VMSI_UNMASKED 0x10000 #define GFLAGS_SHIFT_RH 8 #define GFLAGS_SHIFT_DELIV_MODE 12