aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSheng Yang <sheng@linux.intel.com>2009-01-06 03:25:11 -0500
committerAvi Kivity <avi@redhat.com>2009-03-24 05:03:02 -0400
commit17071fe74fe0fbfdb03cd9b82f2490447cf1f986 (patch)
tree1090267522ecf64960c0745ccf6dca32927e481d
parent67346440e83d2a2f2e9801f370b6240317c7d9bd (diff)
KVM: Add support to disable MSI for assigned device
MSI is always enabled by default for msi2intx=1. But if msi2intx=0, we have to disable MSI if guest require to do so. The patch also discard unnecessary msi2intx judgment if guest want to update MSI state. Notice KVM_DEV_IRQ_ASSIGN_MSI_ACTION is a mask which should cover all MSI related operations, though we only got one for now. Signed-off-by: Sheng Yang <sheng@linux.intel.com> Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--include/linux/kvm.h1
-rw-r--r--virt/kvm/kvm_main.c18
2 files changed, 17 insertions, 2 deletions
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index ae7a12c77427..73f348066866 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -550,6 +550,7 @@ struct kvm_assigned_irq {
550 550
551#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) 551#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)
552 552
553#define KVM_DEV_IRQ_ASSIGN_MSI_ACTION KVM_DEV_IRQ_ASSIGN_ENABLE_MSI
553#define KVM_DEV_IRQ_ASSIGN_ENABLE_MSI (1 << 0) 554#define KVM_DEV_IRQ_ASSIGN_ENABLE_MSI (1 << 0)
554 555
555#endif 556#endif
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index f83ef9c7e89b..04401e17c758 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -343,6 +343,14 @@ static int assigned_device_update_msi(struct kvm *kvm,
343 adev->irq_requested_type &= ~KVM_ASSIGNED_DEV_GUEST_MSI; 343 adev->irq_requested_type &= ~KVM_ASSIGNED_DEV_GUEST_MSI;
344 adev->guest_irq = airq->guest_irq; 344 adev->guest_irq = airq->guest_irq;
345 adev->ack_notifier.gsi = airq->guest_irq; 345 adev->ack_notifier.gsi = airq->guest_irq;
346 } else {
347 /*
348 * Guest require to disable device MSI, we disable MSI and
349 * re-enable INTx by default again. Notice it's only for
350 * non-msi2intx.
351 */
352 assigned_device_update_intx(kvm, adev, airq);
353 return 0;
346 } 354 }
347 355
348 if (adev->irq_requested_type & KVM_ASSIGNED_DEV_HOST_MSI) 356 if (adev->irq_requested_type & KVM_ASSIGNED_DEV_HOST_MSI)
@@ -379,6 +387,7 @@ static int kvm_vm_ioctl_assign_irq(struct kvm *kvm,
379{ 387{
380 int r = 0; 388 int r = 0;
381 struct kvm_assigned_dev_kernel *match; 389 struct kvm_assigned_dev_kernel *match;
390 u32 current_flags = 0, changed_flags;
382 391
383 mutex_lock(&kvm->lock); 392 mutex_lock(&kvm->lock);
384 393
@@ -416,8 +425,13 @@ static int kvm_vm_ioctl_assign_irq(struct kvm *kvm,
416 } 425 }
417 } 426 }
418 427
419 if ((!msi2intx && 428 if ((match->irq_requested_type & KVM_ASSIGNED_DEV_HOST_MSI) &&
420 (assigned_irq->flags & KVM_DEV_IRQ_ASSIGN_ENABLE_MSI)) || 429 (match->irq_requested_type & KVM_ASSIGNED_DEV_GUEST_MSI))
430 current_flags |= KVM_DEV_IRQ_ASSIGN_ENABLE_MSI;
431
432 changed_flags = assigned_irq->flags ^ current_flags;
433
434 if ((changed_flags & KVM_DEV_IRQ_ASSIGN_MSI_ACTION) ||
421 (msi2intx && match->dev->msi_enabled)) { 435 (msi2intx && match->dev->msi_enabled)) {
422#ifdef CONFIG_X86 436#ifdef CONFIG_X86
423 r = assigned_device_update_msi(kvm, match, assigned_irq); 437 r = assigned_device_update_msi(kvm, match, assigned_irq);