All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: Jan Kiszka <jan.kiszka@web.de>
Cc: Avi Kivity <avi@redhat.com>,
	Marcelo Tosatti <mtosatti@redhat.com>,
	kvm@vger.kernel.org
Subject: Re: [PATCH 7/7] qemu-kvm: Add in-kernel irqchip support for MSI
Date: Wed, 27 Apr 2011 16:31:40 +0300	[thread overview]
Message-ID: <20110427133140.GG15788@redhat.com> (raw)
In-Reply-To: <53b0668cfa13be4c3f842512c0852bc44a90f45d.1303554218.git.jan.kiszka@web.de>

On Sat, Apr 23, 2011 at 12:23:40PM +0200, Jan Kiszka wrote:
> From: Jan Kiszka <jan.kiszka@siemens.com>
> 
> This adds the required bits to map classic MSI vectors on KVM IRQ
> routing entries and deliver them via the irqchip if enabled.
> 
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> ---
>  hw/msi.c |  111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  hw/pci.h |    4 ++
>  2 files changed, 115 insertions(+), 0 deletions(-)
> 
> diff --git a/hw/msi.c b/hw/msi.c
> index 3dc3a24..18f683b 100644
> --- a/hw/msi.c
> +++ b/hw/msi.c
> @@ -20,6 +20,7 @@
>  
>  #include "msi.h"
>  #include "range.h"
> +#include "kvm.h"
>  
>  /* Eventually those constants should go to Linux pci_regs.h */
>  #define PCI_MSI_PENDING_32      0x10
> @@ -109,6 +110,92 @@ bool msi_enabled(const PCIDevice *dev)
>           PCI_MSI_FLAGS_ENABLE);
>  }
>  
> +static void kvm_msi_message_from_vector(PCIDevice *dev, unsigned vector,
> +                                        KVMMsiMessage *kmm)
> +{
> +    uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));
> +    bool msi64bit = flags & PCI_MSI_FLAGS_64BIT;
> +    unsigned int nr_vectors = msi_nr_vectors(flags);
> +
> +    kmm->addr_lo = pci_get_long(dev->config + msi_address_lo_off(dev));
> +    if (msi64bit) {
> +        kmm->addr_hi = pci_get_long(dev->config + msi_address_hi_off(dev));
> +    } else {
> +        kmm->addr_hi = 0;
> +    }
> +
> +    kmm->data = pci_get_word(dev->config + msi_data_off(dev, msi64bit));
> +    if (nr_vectors > 1) {
> +        kmm->data &= ~(nr_vectors - 1);
> +        kmm->data |= vector;
> +    }

msi_notify already has similar logic.
Let's add msi_get_vector_address and msi_get_vector_data


> +}
> +
> +static void kvm_msi_update(PCIDevice *dev)
> +{
> +    uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));
> +    unsigned int nr_vectors = msi_nr_vectors(flags);
> +    KVMMsiMessage new_entry, *entry;
> +    bool changed = false;
> +    unsigned int vector;
> +    int r;
> +
> +    for (vector = 0; vector < 32; vector++) {

I'd say up to log_max_vecs: the array is allocated
with nr_vectors.

> +        entry = dev->msi_irq_entries + vector;
> +
> +        if (vector >= nr_vectors) {
> +            if (vector < dev->msi_entries_nr) {
> +                kvm_msi_message_del(entry);
> +                changed = true;
> +            }
> +        } else if (vector >= dev->msi_entries_nr) {
> +            kvm_msi_message_from_vector(dev, vector, entry);
> +            r = kvm_msi_message_add(entry);
> +            if (r) {
> +                fprintf(stderr, "%s: kvm_msi_add failed: %s\n", __func__,
> +                        strerror(-r));
> +                exit(1);
> +            }
> +            changed = true;
> +        } else {
> +            kvm_msi_message_from_vector(dev, vector, &new_entry);
> +            r = kvm_msi_message_update(entry, &new_entry);
> +            if (r < 0) {
> +                fprintf(stderr, "%s: kvm_update_msi failed: %s\n",
> +                        __func__, strerror(-r));
> +                exit(1);
> +            }
> +            if (r > 0) {
> +                *entry = new_entry;
> +                changed = true;
> +            }
> +        }
> +    }
> +    dev->msi_entries_nr = nr_vectors;
> +    if (changed) {
> +        r = kvm_commit_irq_routes();
> +        if (r) {
> +            fprintf(stderr, "%s: kvm_commit_irq_routes failed: %s\n", __func__,
> +                    strerror(-r));
> +            exit(1);
> +        }
> +    }
> +}
> +
> +/* KVM specific MSI helpers */
> +static void kvm_msi_free(PCIDevice *dev)
> +{
> +    unsigned int vector;
> +
> +    for (vector = 0; vector < dev->msi_entries_nr; ++vector) {
> +        kvm_msi_message_del(&dev->msi_irq_entries[vector]);
> +    }
> +    if (dev->msi_entries_nr > 0) {
> +        kvm_commit_irq_routes();
> +    }
> +    dev->msi_entries_nr = 0;
> +}
> +
>  int msi_init(struct PCIDevice *dev, uint8_t offset,
>               unsigned int nr_vectors, bool msi64bit, bool msi_per_vector_mask)
>  {
> @@ -159,6 +246,12 @@ int msi_init(struct PCIDevice *dev, uint8_t offset,
>          pci_set_long(dev->wmask + msi_mask_off(dev, msi64bit),
>                       0xffffffff >> (PCI_MSI_VECTORS_MAX - nr_vectors));
>      }
> +
> +    if (kvm_enabled() && kvm_irqchip_in_kernel()) {
> +        dev->msi_irq_entries = qemu_malloc(nr_vectors *
> +                                           sizeof(*dev->msix_irq_entries));
> +    }
> +
>      return config_offset;
>  }
>  
> @@ -166,6 +259,11 @@ void msi_uninit(struct PCIDevice *dev)
>  {
>      uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));
>      uint8_t cap_size = msi_cap_sizeof(flags);
> +
> +    if (kvm_enabled() && kvm_irqchip_in_kernel()) {
> +        kvm_msi_free(dev);
> +        qemu_free(dev->msi_irq_entries);
> +    }
>      pci_del_capability(dev, PCI_CAP_ID_MSIX, cap_size);
>      MSI_DEV_PRINTF(dev, "uninit\n");
>  }
> @@ -175,6 +273,10 @@ void msi_reset(PCIDevice *dev)
>      uint16_t flags;
>      bool msi64bit;
>  
> +    if (kvm_enabled() && kvm_irqchip_in_kernel()) {
> +        kvm_msi_free(dev);
> +    }
> +
>      flags = pci_get_word(dev->config + msi_flags_off(dev));
>      flags &= ~(PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE);
>      msi64bit = flags & PCI_MSI_FLAGS_64BIT;
> @@ -224,6 +326,11 @@ void msi_notify(PCIDevice *dev, unsigned int vector)
>          return;
>      }
>  
> +    if (kvm_enabled() && kvm_irqchip_in_kernel()) {
> +        kvm_set_irq(dev->msi_irq_entries[vector].gsi, 1, NULL);
> +        return;
> +    }
> +
>      if (msi64bit) {
>          address = pci_get_quad(dev->config + msi_address_lo_off(dev));
>      } else {
> @@ -312,6 +419,10 @@ void msi_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, int len)
>          pci_set_word(dev->config + msi_flags_off(dev), flags);
>      }
>  
> +    if (kvm_enabled() && kvm_irqchip_in_kernel()) {
> +        kvm_msi_update(dev);
> +    }
> +

Does this ignore per vector masking then?

>      if (!msi_per_vector_mask) {
>          /* if per vector masking isn't supported,
>             there is no pending interrupt. */
> diff --git a/hw/pci.h b/hw/pci.h
> index dc5df17..1a18bc8 100644
> --- a/hw/pci.h
> +++ b/hw/pci.h
> @@ -195,6 +195,10 @@ struct PCIDevice {
>      ram_addr_t rom_offset;
>      uint32_t rom_bar;
>  
> +    /* MSI entries */
> +    int msi_entries_nr;
> +    struct KVMMsiMessage *msi_irq_entries;
> +
>      /* How much space does an MSIX table need. */
>      /* The spec requires giving the table structure
>       * a 4K aligned region all by itself. Align it to
> -- 
> 1.7.1

  reply	other threads:[~2011-04-27 13:31 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-23 10:23 [PATCH 0/7] qemu-kvm: Clean up and enhance MSI irqchip support Jan Kiszka
2011-04-23 10:23 ` [PATCH 1/7] qemu-kvm: Drop unneeded kvm_irq_routing_entry declaration Jan Kiszka
2011-04-23 10:23 ` [PATCH 2/7] qemu-kvm: Rename kvm_msix_message to KVMMsiMessage Jan Kiszka
2011-04-27 13:34   ` Michael S. Tsirkin
2011-04-27 14:04     ` Jan Kiszka
2011-04-27 14:29       ` Avi Kivity
2011-04-27 14:30         ` Jan Kiszka
2011-04-27 14:40           ` Avi Kivity
2011-04-27 14:47             ` Jan Kiszka
2011-04-27 14:36         ` Michael S. Tsirkin
2011-04-27 14:35       ` Michael S. Tsirkin
2011-04-23 10:23 ` [PATCH 3/7] qemu-kvm: Refactor MSI core API of KVM Jan Kiszka
2011-04-23 10:23 ` [PATCH 4/7] qemu-kvm: Fix and clean up msix vector use/unuse hooks Jan Kiszka
2011-04-27 12:06   ` Michael S. Tsirkin
2011-04-23 10:23 ` [PATCH 5/7] qemu-kvm: Move gsi bits from kvm_msix_vector_add to kvm_msi_add_message Jan Kiszka
2011-04-27 12:54   ` Michael S. Tsirkin
2011-04-27 13:29     ` Jan Kiszka
2011-04-27 13:36       ` Michael S. Tsirkin
2011-04-23 10:23 ` [PATCH 6/7] qemu-kvm: Move entry comparison into kvm_msi_update_message Jan Kiszka
2011-04-23 10:23 ` [PATCH 7/7] qemu-kvm: Add in-kernel irqchip support for MSI Jan Kiszka
2011-04-27 13:31   ` Michael S. Tsirkin [this message]
2011-04-27 14:44     ` Jan Kiszka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110427133140.GG15788@redhat.com \
    --to=mst@redhat.com \
    --cc=avi@redhat.com \
    --cc=jan.kiszka@web.de \
    --cc=kvm@vger.kernel.org \
    --cc=mtosatti@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.