From patchwork Wed Oct 20 08:26:30 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sheng Yang X-Patchwork-Id: 267991 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o9K8Po9K025954 for ; Wed, 20 Oct 2010 08:25:50 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751942Ab0JTIZk (ORCPT ); Wed, 20 Oct 2010 04:25:40 -0400 Received: from mga01.intel.com ([192.55.52.88]:16465 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751701Ab0JTIZa (ORCPT ); Wed, 20 Oct 2010 04:25:30 -0400 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP; 20 Oct 2010 01:25:29 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.57,354,1283756400"; d="scan'208";a="849020315" Received: from syang10-desktop.sh.intel.com (HELO syang10-desktop) ([10.239.13.14]) by fmsmga001.fm.intel.com with ESMTP; 20 Oct 2010 01:25:28 -0700 Received: from yasker by syang10-desktop with local (Exim 4.71) (envelope-from ) id 1P8U0J-0007jX-Ar; Wed, 20 Oct 2010 16:26:35 +0800 From: Sheng Yang To: Avi Kivity , Marcelo Tosatti Cc: kvm@vger.kernel.org, "Michael S. Tsirkin" , Sheng Yang Subject: [PATCH 6/8] KVM: assigned dev: Preparation for mask support in userspace Date: Wed, 20 Oct 2010 16:26:30 +0800 Message-Id: <1287563192-29685-7-git-send-email-sheng@linux.intel.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1287563192-29685-1-git-send-email-sheng@linux.intel.com> References: <1287563192-29685-1-git-send-email-sheng@linux.intel.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Wed, 20 Oct 2010 08:25:50 +0000 (UTC) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index e209078..2bb69ba 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -456,6 +456,8 @@ struct kvm_arch { /* fields used by HYPER-V emulation */ u64 hv_guest_os_id; u64 hv_hypercall; + + bool msix_flags_enabled; }; struct kvm_vm_stat { diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 919ae53..a699ec9 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -787,11 +787,15 @@ struct kvm_assigned_msix_nr { }; #define KVM_MAX_MSIX_PER_DEV 256 + +#define KVM_MSIX_FLAG_MASK 1 + struct kvm_assigned_msix_entry { __u32 assigned_dev_id; __u32 gsi; __u16 entry; /* The index of entry in the MSI-X table */ - __u16 padding[3]; + __u16 flags; + __u16 padding[2]; }; #endif /* __LINUX_KVM_H */ diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 30f83cd..81a6284 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -438,6 +438,7 @@ struct kvm_irq_ack_notifier { }; #define KVM_ASSIGNED_MSIX_PENDING 0x1 +#define KVM_ASSIGNED_MSIX_MASK 0x2 struct kvm_guest_msix_entry { u32 vector; u16 entry; diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c index 7c98928..bf96ea7 100644 --- a/virt/kvm/assigned-dev.c +++ b/virt/kvm/assigned-dev.c @@ -666,11 +666,35 @@ msix_nr_out: return r; } +static void update_msix_mask(struct kvm_assigned_dev_kernel *assigned_dev, + int index) +{ + int irq; + struct irq_desc *desc; + + if (!assigned_dev->dev->msix_enabled || + !(assigned_dev->irq_requested_type & KVM_DEV_IRQ_HOST_MSIX)) + return; + + irq = assigned_dev->host_msix_entries[index].vector; + BUG_ON(irq == 0); + desc = irq_to_desc(irq); + BUG_ON(!desc->msi_desc); + + if (assigned_dev->guest_msix_entries[index].flags & + KVM_ASSIGNED_MSIX_MASK) { + desc->chip->mask(irq); + flush_work(&assigned_dev->interrupt_work); + } else + desc->chip->unmask(irq); +} + static int kvm_vm_ioctl_set_msix_entry(struct kvm *kvm, struct kvm_assigned_msix_entry *entry) { int r = 0, i; struct kvm_assigned_dev_kernel *adev; + bool entry_masked; mutex_lock(&kvm->lock); @@ -688,6 +712,21 @@ static int kvm_vm_ioctl_set_msix_entry(struct kvm *kvm, adev->guest_msix_entries[i].entry = entry->entry; adev->guest_msix_entries[i].vector = entry->gsi; adev->host_msix_entries[i].entry = entry->entry; + if (!kvm->arch.msix_flags_enabled) + break; + entry_masked = adev->guest_msix_entries[i].flags & + KVM_ASSIGNED_MSIX_MASK; + if ((entry->flags & KVM_MSIX_FLAG_MASK) && + !entry_masked) { + adev->guest_msix_entries[i].flags |= + KVM_ASSIGNED_MSIX_MASK; + update_msix_mask(adev, i); + } else if (!(entry->flags & KVM_MSIX_FLAG_MASK) && + entry_masked) { + adev->guest_msix_entries[i].flags &= + ~KVM_ASSIGNED_MSIX_MASK; + update_msix_mask(adev, i); + } break; } if (i == adev->entries_nr) {