diff options
author | Sheng Yang <sheng@linux.intel.com> | 2009-01-06 03:25:11 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-03-24 05:03:02 -0400 |
commit | 17071fe74fe0fbfdb03cd9b82f2490447cf1f986 (patch) | |
tree | 1090267522ecf64960c0745ccf6dca32927e481d | |
parent | 67346440e83d2a2f2e9801f370b6240317c7d9bd (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.h | 1 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 18 |
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); |