From: Alex Williamson <alex.williamson@redhat.com>
To: Anthony Liguori <anthony@codemonkey.ws>
Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, mst@redhat.com,
chrisw@redhat.com, ddutile@redhat.com
Subject: Re: [PATCH] APIC/IOAPIC EOI callback
Date: Sun, 31 Oct 2010 21:54:51 -0600 [thread overview]
Message-ID: <1288583691.20007.5.camel@x201> (raw)
In-Reply-To: <4CCB1E31.8020006@codemonkey.ws>
On Fri, 2010-10-29 at 14:19 -0500, Anthony Liguori wrote:
> On 10/29/2010 12:56 PM, Alex Williamson wrote:
> > For device assignment, we need to know when the VM writes an end
> > of interrupt to the APIC, which allows us to re-enable interrupts
> > on the physical device. Add a new wrapper for ioapic generated
> > interrupts with a callback on eoi and create an interface for
> > drivers to be notified on eoi.
> >
> > Signed-off-by: Alex Williamson<alex.williamson@redhat.com>
> > ---
> >
> > Note that the notifier and notifier_enabled eoi_client fields aren't
> > used here yet. I'll send an RFC patch showing how we make use of
> > these with the proposed KVM_EOI_EVENTFD patches.
> >
> > hw/apic.c | 18 ++++++++++++++++--
> > hw/apic.h | 4 ++++
> > hw/ioapic.c | 38 ++++++++++++++++++++++++++++++++++++--
> > hw/pc.h | 16 +++++++++++++++-
> > 4 files changed, 71 insertions(+), 5 deletions(-)
> >
> > diff --git a/hw/apic.c b/hw/apic.c
> > index 63d62c7..a24117b 100644
> > --- a/hw/apic.c
> > +++ b/hw/apic.c
> > @@ -22,6 +22,7 @@
> > #include "host-utils.h"
> > #include "sysbus.h"
> > #include "trace.h"
> > +#include "pc.h"
> >
> > /* APIC Local Vector Table */
> > #define APIC_LVT_TIMER 0
> > @@ -103,6 +104,7 @@ struct APICState {
> > int wait_for_sipi;
> > };
> >
> > +static uint8_t vector_to_gsi_map[256] = { 0xff };
> > static APICState *local_apics[MAX_APICS + 1];
> > static int apic_irq_delivered;
> >
> > @@ -292,6 +294,15 @@ void apic_deliver_irq(uint8_t dest, uint8_t dest_mode,
> > trigger_mode);
> > }
> >
> > +void apic_deliver_ioapic_irq(uint8_t dest, uint8_t dest_mode,
> > + uint8_t delivery_mode, uint8_t vector_num,
> > + uint8_t polarity, uint8_t trigger_mode, int gsi)
> > +{
> > + vector_to_gsi_map[vector_num] = gsi;
> > + apic_deliver_irq(dest, dest_mode, delivery_mode,
> > + vector_num, polarity, trigger_mode);
> > +}
> > +
> > void cpu_set_apic_base(DeviceState *d, uint64_t val)
> > {
> > APICState *s = DO_UPCAST(APICState, busdev.qdev, d);
> > @@ -420,8 +431,11 @@ static void apic_eoi(APICState *s)
> > if (isrv< 0)
> > return;
> > reset_bit(s->isr, isrv);
> > - /* XXX: send the EOI packet to the APIC bus to allow the I/O APIC to
> > - set the remote IRR bit for level triggered interrupts. */
> > +
> > + if (vector_to_gsi_map[isrv] != 0xff) {
> > + ioapic_eoi(vector_to_gsi_map[isrv]);
> > + vector_to_gsi_map[isrv] = 0xff;
> > + }
> > apic_update_irq(s);
> > }
> >
> > diff --git a/hw/apic.h b/hw/apic.h
> > index 8a0c9d0..59d0e37 100644
> > --- a/hw/apic.h
> > +++ b/hw/apic.h
> > @@ -8,6 +8,10 @@ void apic_deliver_irq(uint8_t dest, uint8_t dest_mode,
> > uint8_t delivery_mode,
> > uint8_t vector_num, uint8_t polarity,
> > uint8_t trigger_mode);
> > +void apic_deliver_ioapic_irq(uint8_t dest, uint8_t dest_mode,
> > + uint8_t delivery_mode,
> > + uint8_t vector_num, uint8_t polarity,
> > + uint8_t trigger_mode, int gsi);
> > int apic_accept_pic_intr(DeviceState *s);
> > void apic_deliver_pic_intr(DeviceState *s, int level);
> > int apic_get_interrupt(DeviceState *s);
> > diff --git a/hw/ioapic.c b/hw/ioapic.c
> > index 5ae21e9..ffd1c92 100644
> > --- a/hw/ioapic.c
> > +++ b/hw/ioapic.c
> > @@ -26,6 +26,7 @@
> > #include "qemu-timer.h"
> > #include "host-utils.h"
> > #include "sysbus.h"
> > +#include "qlist.h"
> >
> > //#define DEBUG_IOAPIC
> >
> > @@ -61,6 +62,39 @@ struct IOAPICState {
> > uint64_t ioredtbl[IOAPIC_NUM_PINS];
> > };
> >
> > +static QLIST_HEAD(ioapic_eoi_client_list,
> > + ioapic_eoi_client) ioapic_eoi_client_list =
> > + QLIST_HEAD_INITIALIZER(ioapic_eoi_client_list);
> > +
> > +int ioapic_register_eoi_client(ioapic_eoi_client *client)
> > +{
> > + QLIST_INSERT_HEAD(&ioapic_eoi_client_list, client, list);
> > + return 0;
> > +}
> > +
> > +void ioapic_unregister_eoi_client(ioapic_eoi_client *client)
> > +{
> > + QLIST_REMOVE(client, list);
> > +}
> > +
> > +int ioapic_eoi_client_get_fd(ioapic_eoi_client *client)
> > +{
> > + if (!client->notifier_enabled) {
> > + return -ENODEV;
> > + }
> > + return event_notifier_get_fd(&client->notifier);
> > +}
> > +
> > +void ioapic_eoi(int gsi)
> > +{
> > + ioapic_eoi_client *client;
> > + QLIST_FOREACH(client,&ioapic_eoi_client_list, list) {
> > + if (client->irq == gsi) {
> > + client->eoi(client);
> > + }
> > + }
> > +}
> >
>
> I think this all goes away with a NotifierList.
Are you thinking of an array of 256 NotifierLists, one per irq? I'm not
sure how else I could keep track of which Notifier is associated with
which irq. That seems a little excessive unless we start getting a lot
more users of this callback. Thanks,
Alex
WARNING: multiple messages have this Message-ID (diff)
From: Alex Williamson <alex.williamson@redhat.com>
To: Anthony Liguori <anthony@codemonkey.ws>
Cc: chrisw@redhat.com, ddutile@redhat.com, qemu-devel@nongnu.org,
kvm@vger.kernel.org, mst@redhat.com
Subject: [Qemu-devel] Re: [PATCH] APIC/IOAPIC EOI callback
Date: Sun, 31 Oct 2010 21:54:51 -0600 [thread overview]
Message-ID: <1288583691.20007.5.camel@x201> (raw)
In-Reply-To: <4CCB1E31.8020006@codemonkey.ws>
On Fri, 2010-10-29 at 14:19 -0500, Anthony Liguori wrote:
> On 10/29/2010 12:56 PM, Alex Williamson wrote:
> > For device assignment, we need to know when the VM writes an end
> > of interrupt to the APIC, which allows us to re-enable interrupts
> > on the physical device. Add a new wrapper for ioapic generated
> > interrupts with a callback on eoi and create an interface for
> > drivers to be notified on eoi.
> >
> > Signed-off-by: Alex Williamson<alex.williamson@redhat.com>
> > ---
> >
> > Note that the notifier and notifier_enabled eoi_client fields aren't
> > used here yet. I'll send an RFC patch showing how we make use of
> > these with the proposed KVM_EOI_EVENTFD patches.
> >
> > hw/apic.c | 18 ++++++++++++++++--
> > hw/apic.h | 4 ++++
> > hw/ioapic.c | 38 ++++++++++++++++++++++++++++++++++++--
> > hw/pc.h | 16 +++++++++++++++-
> > 4 files changed, 71 insertions(+), 5 deletions(-)
> >
> > diff --git a/hw/apic.c b/hw/apic.c
> > index 63d62c7..a24117b 100644
> > --- a/hw/apic.c
> > +++ b/hw/apic.c
> > @@ -22,6 +22,7 @@
> > #include "host-utils.h"
> > #include "sysbus.h"
> > #include "trace.h"
> > +#include "pc.h"
> >
> > /* APIC Local Vector Table */
> > #define APIC_LVT_TIMER 0
> > @@ -103,6 +104,7 @@ struct APICState {
> > int wait_for_sipi;
> > };
> >
> > +static uint8_t vector_to_gsi_map[256] = { 0xff };
> > static APICState *local_apics[MAX_APICS + 1];
> > static int apic_irq_delivered;
> >
> > @@ -292,6 +294,15 @@ void apic_deliver_irq(uint8_t dest, uint8_t dest_mode,
> > trigger_mode);
> > }
> >
> > +void apic_deliver_ioapic_irq(uint8_t dest, uint8_t dest_mode,
> > + uint8_t delivery_mode, uint8_t vector_num,
> > + uint8_t polarity, uint8_t trigger_mode, int gsi)
> > +{
> > + vector_to_gsi_map[vector_num] = gsi;
> > + apic_deliver_irq(dest, dest_mode, delivery_mode,
> > + vector_num, polarity, trigger_mode);
> > +}
> > +
> > void cpu_set_apic_base(DeviceState *d, uint64_t val)
> > {
> > APICState *s = DO_UPCAST(APICState, busdev.qdev, d);
> > @@ -420,8 +431,11 @@ static void apic_eoi(APICState *s)
> > if (isrv< 0)
> > return;
> > reset_bit(s->isr, isrv);
> > - /* XXX: send the EOI packet to the APIC bus to allow the I/O APIC to
> > - set the remote IRR bit for level triggered interrupts. */
> > +
> > + if (vector_to_gsi_map[isrv] != 0xff) {
> > + ioapic_eoi(vector_to_gsi_map[isrv]);
> > + vector_to_gsi_map[isrv] = 0xff;
> > + }
> > apic_update_irq(s);
> > }
> >
> > diff --git a/hw/apic.h b/hw/apic.h
> > index 8a0c9d0..59d0e37 100644
> > --- a/hw/apic.h
> > +++ b/hw/apic.h
> > @@ -8,6 +8,10 @@ void apic_deliver_irq(uint8_t dest, uint8_t dest_mode,
> > uint8_t delivery_mode,
> > uint8_t vector_num, uint8_t polarity,
> > uint8_t trigger_mode);
> > +void apic_deliver_ioapic_irq(uint8_t dest, uint8_t dest_mode,
> > + uint8_t delivery_mode,
> > + uint8_t vector_num, uint8_t polarity,
> > + uint8_t trigger_mode, int gsi);
> > int apic_accept_pic_intr(DeviceState *s);
> > void apic_deliver_pic_intr(DeviceState *s, int level);
> > int apic_get_interrupt(DeviceState *s);
> > diff --git a/hw/ioapic.c b/hw/ioapic.c
> > index 5ae21e9..ffd1c92 100644
> > --- a/hw/ioapic.c
> > +++ b/hw/ioapic.c
> > @@ -26,6 +26,7 @@
> > #include "qemu-timer.h"
> > #include "host-utils.h"
> > #include "sysbus.h"
> > +#include "qlist.h"
> >
> > //#define DEBUG_IOAPIC
> >
> > @@ -61,6 +62,39 @@ struct IOAPICState {
> > uint64_t ioredtbl[IOAPIC_NUM_PINS];
> > };
> >
> > +static QLIST_HEAD(ioapic_eoi_client_list,
> > + ioapic_eoi_client) ioapic_eoi_client_list =
> > + QLIST_HEAD_INITIALIZER(ioapic_eoi_client_list);
> > +
> > +int ioapic_register_eoi_client(ioapic_eoi_client *client)
> > +{
> > + QLIST_INSERT_HEAD(&ioapic_eoi_client_list, client, list);
> > + return 0;
> > +}
> > +
> > +void ioapic_unregister_eoi_client(ioapic_eoi_client *client)
> > +{
> > + QLIST_REMOVE(client, list);
> > +}
> > +
> > +int ioapic_eoi_client_get_fd(ioapic_eoi_client *client)
> > +{
> > + if (!client->notifier_enabled) {
> > + return -ENODEV;
> > + }
> > + return event_notifier_get_fd(&client->notifier);
> > +}
> > +
> > +void ioapic_eoi(int gsi)
> > +{
> > + ioapic_eoi_client *client;
> > + QLIST_FOREACH(client,&ioapic_eoi_client_list, list) {
> > + if (client->irq == gsi) {
> > + client->eoi(client);
> > + }
> > + }
> > +}
> >
>
> I think this all goes away with a NotifierList.
Are you thinking of an array of 256 NotifierLists, one per irq? I'm not
sure how else I could keep track of which Notifier is associated with
which irq. That seems a little excessive unless we start getting a lot
more users of this callback. Thanks,
Alex
next prev parent reply other threads:[~2010-11-01 3:54 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-10-29 17:56 [PATCH] APIC/IOAPIC EOI callback Alex Williamson
2010-10-29 17:56 ` [Qemu-devel] " Alex Williamson
2010-10-29 18:05 ` [RFC PATCH] kvm: KVM_EOI_EVENTFD support for eoi_client Alex Williamson
2010-10-29 18:05 ` [Qemu-devel] " Alex Williamson
2010-10-29 19:19 ` [PATCH] APIC/IOAPIC EOI callback Anthony Liguori
2010-10-29 19:19 ` [Qemu-devel] " Anthony Liguori
2010-11-01 3:54 ` Alex Williamson [this message]
2010-11-01 3:54 ` Alex Williamson
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=1288583691.20007.5.camel@x201 \
--to=alex.williamson@redhat.com \
--cc=anthony@codemonkey.ws \
--cc=chrisw@redhat.com \
--cc=ddutile@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=mst@redhat.com \
--cc=qemu-devel@nongnu.org \
/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.