forked from qemu/qemu
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
multi-process: create IOHUB object to handle irq
IOHUB object is added to manage PCI IRQs. It uses KVM_IRQFD ioctl to create irqfd to injecting PCI interrupts to the guest. IOHUB object forwards the irqfd to the remote process. Remote process uses this fd to directly send interrupts to the guest, bypassing QEMU. Signed-off-by: John G Johnson <[email protected]> Signed-off-by: Jagannathan Raman <[email protected]> Signed-off-by: Elena Ufimtseva <[email protected]> Reviewed-by: Stefan Hajnoczi <[email protected]> Message-id: 51d5c3d54e28a68b002e3875c59599c9f5a424a1.1611938319.git.jag.raman@oracle.com Signed-off-by: Stefan Hajnoczi <[email protected]>
- Loading branch information
1 parent
c746b74
commit bd36adb
Showing
12 changed files
with
249 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
/* | ||
* Remote IO Hub | ||
* | ||
* Copyright © 2018, 2021 Oracle and/or its affiliates. | ||
* | ||
* This work is licensed under the terms of the GNU GPL, version 2 or later. | ||
* See the COPYING file in the top-level directory. | ||
* | ||
*/ | ||
|
||
#include "qemu/osdep.h" | ||
#include "qemu-common.h" | ||
|
||
#include "hw/pci/pci.h" | ||
#include "hw/pci/pci_ids.h" | ||
#include "hw/pci/pci_bus.h" | ||
#include "qemu/thread.h" | ||
#include "hw/boards.h" | ||
#include "hw/remote/machine.h" | ||
#include "hw/remote/iohub.h" | ||
#include "qemu/main-loop.h" | ||
|
||
void remote_iohub_init(RemoteIOHubState *iohub) | ||
{ | ||
int pirq; | ||
|
||
memset(&iohub->irqfds, 0, sizeof(iohub->irqfds)); | ||
memset(&iohub->resamplefds, 0, sizeof(iohub->resamplefds)); | ||
|
||
for (pirq = 0; pirq < REMOTE_IOHUB_NB_PIRQS; pirq++) { | ||
qemu_mutex_init(&iohub->irq_level_lock[pirq]); | ||
iohub->irq_level[pirq] = 0; | ||
event_notifier_init_fd(&iohub->irqfds[pirq], -1); | ||
event_notifier_init_fd(&iohub->resamplefds[pirq], -1); | ||
} | ||
} | ||
|
||
void remote_iohub_finalize(RemoteIOHubState *iohub) | ||
{ | ||
int pirq; | ||
|
||
for (pirq = 0; pirq < REMOTE_IOHUB_NB_PIRQS; pirq++) { | ||
qemu_set_fd_handler(event_notifier_get_fd(&iohub->resamplefds[pirq]), | ||
NULL, NULL, NULL); | ||
event_notifier_cleanup(&iohub->irqfds[pirq]); | ||
event_notifier_cleanup(&iohub->resamplefds[pirq]); | ||
qemu_mutex_destroy(&iohub->irq_level_lock[pirq]); | ||
} | ||
} | ||
|
||
int remote_iohub_map_irq(PCIDevice *pci_dev, int intx) | ||
{ | ||
return pci_dev->devfn; | ||
} | ||
|
||
void remote_iohub_set_irq(void *opaque, int pirq, int level) | ||
{ | ||
RemoteIOHubState *iohub = opaque; | ||
|
||
assert(pirq >= 0); | ||
assert(pirq < PCI_DEVFN_MAX); | ||
|
||
QEMU_LOCK_GUARD(&iohub->irq_level_lock[pirq]); | ||
|
||
if (level) { | ||
if (++iohub->irq_level[pirq] == 1) { | ||
event_notifier_set(&iohub->irqfds[pirq]); | ||
} | ||
} else if (iohub->irq_level[pirq] > 0) { | ||
iohub->irq_level[pirq]--; | ||
} | ||
} | ||
|
||
static void intr_resample_handler(void *opaque) | ||
{ | ||
ResampleToken *token = opaque; | ||
RemoteIOHubState *iohub = token->iohub; | ||
int pirq, s; | ||
|
||
pirq = token->pirq; | ||
|
||
s = event_notifier_test_and_clear(&iohub->resamplefds[pirq]); | ||
|
||
assert(s >= 0); | ||
|
||
QEMU_LOCK_GUARD(&iohub->irq_level_lock[pirq]); | ||
|
||
if (iohub->irq_level[pirq]) { | ||
event_notifier_set(&iohub->irqfds[pirq]); | ||
} | ||
} | ||
|
||
void process_set_irqfd_msg(PCIDevice *pci_dev, MPQemuMsg *msg) | ||
{ | ||
RemoteMachineState *machine = REMOTE_MACHINE(current_machine); | ||
RemoteIOHubState *iohub = &machine->iohub; | ||
int pirq, intx; | ||
|
||
intx = pci_get_byte(pci_dev->config + PCI_INTERRUPT_PIN) - 1; | ||
|
||
pirq = remote_iohub_map_irq(pci_dev, intx); | ||
|
||
if (event_notifier_get_fd(&iohub->irqfds[pirq]) != -1) { | ||
qemu_set_fd_handler(event_notifier_get_fd(&iohub->resamplefds[pirq]), | ||
NULL, NULL, NULL); | ||
event_notifier_cleanup(&iohub->irqfds[pirq]); | ||
event_notifier_cleanup(&iohub->resamplefds[pirq]); | ||
memset(&iohub->token[pirq], 0, sizeof(ResampleToken)); | ||
} | ||
|
||
event_notifier_init_fd(&iohub->irqfds[pirq], msg->fds[0]); | ||
event_notifier_init_fd(&iohub->resamplefds[pirq], msg->fds[1]); | ||
|
||
iohub->token[pirq].iohub = iohub; | ||
iohub->token[pirq].pirq = pirq; | ||
|
||
qemu_set_fd_handler(msg->fds[1], intr_resample_handler, NULL, | ||
&iohub->token[pirq]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/* | ||
* IO Hub for remote device | ||
* | ||
* Copyright © 2018, 2021 Oracle and/or its affiliates. | ||
* | ||
* This work is licensed under the terms of the GNU GPL, version 2 or later. | ||
* See the COPYING file in the top-level directory. | ||
* | ||
*/ | ||
|
||
#ifndef REMOTE_IOHUB_H | ||
#define REMOTE_IOHUB_H | ||
|
||
#include "hw/pci/pci.h" | ||
#include "qemu/event_notifier.h" | ||
#include "qemu/thread-posix.h" | ||
#include "hw/remote/mpqemu-link.h" | ||
|
||
#define REMOTE_IOHUB_NB_PIRQS PCI_DEVFN_MAX | ||
|
||
typedef struct ResampleToken { | ||
void *iohub; | ||
int pirq; | ||
} ResampleToken; | ||
|
||
typedef struct RemoteIOHubState { | ||
PCIDevice d; | ||
EventNotifier irqfds[REMOTE_IOHUB_NB_PIRQS]; | ||
EventNotifier resamplefds[REMOTE_IOHUB_NB_PIRQS]; | ||
unsigned int irq_level[REMOTE_IOHUB_NB_PIRQS]; | ||
ResampleToken token[REMOTE_IOHUB_NB_PIRQS]; | ||
QemuMutex irq_level_lock[REMOTE_IOHUB_NB_PIRQS]; | ||
} RemoteIOHubState; | ||
|
||
int remote_iohub_map_irq(PCIDevice *pci_dev, int intx); | ||
void remote_iohub_set_irq(void *opaque, int pirq, int level); | ||
void process_set_irqfd_msg(PCIDevice *pci_dev, MPQemuMsg *msg); | ||
|
||
void remote_iohub_init(RemoteIOHubState *iohub); | ||
void remote_iohub_finalize(RemoteIOHubState *iohub); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters