[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC/PATCH v0 06/12] gunyah: Add IRQFD and IOEVENTFD functions
From: |
Srivatsa Vaddagiri |
Subject: |
[RFC/PATCH v0 06/12] gunyah: Add IRQFD and IOEVENTFD functions |
Date: |
Wed, 11 Oct 2023 16:52:28 +0000 |
IRQFD function allows registering of an @eventfd and @irq. @irq will be
injected inside guest when @eventfd is written into.
IOEVENTFD function allows registering an @eventfd and a guest physical
address, @addr, along with optional data. A poll() on @eventfd will be
woken up when guest attempts to access @addr.
Signed-off-by: Srivatsa Vaddagiri <quic_svaddagi@quicinc.com>
---
accel/gunyah/gunyah-all.c | 94 +++++++++++++++++++++++++++++++++++++
include/sysemu/gunyah_int.h | 1 +
2 files changed, 95 insertions(+)
diff --git a/accel/gunyah/gunyah-all.c b/accel/gunyah/gunyah-all.c
index 38d0a52b7f..6ec60aa8e8 100644
--- a/accel/gunyah/gunyah-all.c
+++ b/accel/gunyah/gunyah-all.c
@@ -23,11 +23,21 @@
#include "exec/memory.h"
#include "qemu/error-report.h"
#include "exec/address-spaces.h"
+#include "qapi/error.h"
+#include "qemu/event_notifier.h"
static void gunyah_region_add(MemoryListener *listener,
MemoryRegionSection *section);
static void gunyah_region_del(MemoryListener *listener,
MemoryRegionSection *section);
+static void gunyah_mem_ioeventfd_add(MemoryListener *listener,
+ MemoryRegionSection *section,
+ bool match_data, uint64_t data,
+ EventNotifier *e);
+static void gunyah_mem_ioeventfd_del(MemoryListener *listener,
+ MemoryRegionSection *section,
+ bool match_data, uint64_t data,
+ EventNotifier *e);
static int gunyah_ioctl(int type, ...)
{
@@ -64,6 +74,8 @@ static MemoryListener gunyah_memory_listener = {
.priority = MEMORY_LISTENER_PRIORITY_ACCEL,
.region_add = gunyah_region_add,
.region_del = gunyah_region_del,
+ .eventfd_add = gunyah_mem_ioeventfd_add,
+ .eventfd_del = gunyah_mem_ioeventfd_del,
};
int gunyah_create_vm(void)
@@ -316,3 +328,85 @@ static void gunyah_region_del(MemoryListener *listener,
gunyah_set_phys_mem(s, section, false);
}
+
+int gunyah_add_irqfd(int irqfd, int label, Error **errp)
+{
+ int ret;
+ struct gh_fn_desc fdesc;
+ struct gh_fn_irqfd_arg ghirqfd;
+
+ fdesc.type = GH_FN_IRQFD;
+ fdesc.arg_size = sizeof(struct gh_fn_irqfd_arg);
+ fdesc.arg = (__u64)(&ghirqfd);
+
+ ghirqfd.fd = irqfd;
+ ghirqfd.label = label;
+ ghirqfd.flags = GH_IRQFD_FLAGS_LEVEL;
+
+ ret = gunyah_vm_ioctl(GH_VM_ADD_FUNCTION, &fdesc);
+ if (ret) {
+ error_setg_errno(errp, errno, "GH_FN_IRQFD failed");
+ }
+
+ return ret;
+}
+
+static int gunyah_set_ioeventfd_mmio(int fd, hwaddr addr,
+ uint32_t size, uint32_t data, bool datamatch, bool assign)
+{
+ int ret;
+ struct gh_fn_ioeventfd_arg io;
+ struct gh_fn_desc fdesc;
+
+ io.fd = fd;
+ io.datamatch = datamatch ? data : 0;
+ io.len = size;
+ io.addr = addr;
+ io.flags = 0;
+
+ fdesc.type = GH_FN_IOEVENTFD;
+ fdesc.arg_size = sizeof(struct gh_fn_ioeventfd_arg);
+ fdesc.arg = (__u64)(&io);
+
+ if (assign) {
+ ret = gunyah_vm_ioctl(GH_VM_ADD_FUNCTION, &fdesc);
+ } else {
+ ret = gunyah_vm_ioctl(GH_VM_REMOVE_FUNCTION, &fdesc);
+ }
+
+ return ret;
+}
+
+static void gunyah_mem_ioeventfd_add(MemoryListener *listener,
+ MemoryRegionSection *section,
+ bool match_data, uint64_t data,
+ EventNotifier *e)
+{
+ int fd = event_notifier_get_fd(e);
+ int r;
+
+ r = gunyah_set_ioeventfd_mmio(fd, section->offset_within_address_space,
+ int128_get64(section->size), data, match_data,
+ true);
+ if (r < 0) {
+ error_report("error adding ioeventfd: %s", strerror(errno));
+ exit(1);
+ }
+}
+
+static void gunyah_mem_ioeventfd_del(MemoryListener *listener,
+ MemoryRegionSection *section,
+ bool match_data, uint64_t data,
+ EventNotifier *e)
+{
+ int fd = event_notifier_get_fd(e);
+ int r;
+
+ r = gunyah_set_ioeventfd_mmio(fd, section->offset_within_address_space,
+ int128_get64(section->size), data, match_data,
+ false);
+ if (r < 0) {
+ error_report("error deleting ioeventfd: %s", strerror(errno));
+ exit(1);
+ }
+}
diff --git a/include/sysemu/gunyah_int.h b/include/sysemu/gunyah_int.h
index 17b4ef9920..011b5a072c 100644
--- a/include/sysemu/gunyah_int.h
+++ b/include/sysemu/gunyah_int.h
@@ -50,5 +50,6 @@ struct GUNYAHState {
int gunyah_create_vm(void);
int gunyah_vm_ioctl(int type, ...);
void *gunyah_cpu_thread_fn(void *arg);
+int gunyah_add_irqfd(int irqfd, int label, Error **errp);
#endif /* GUNYAH_INT_H */
--
2.25.1
- Re: [RFC/PATCH v0 01/12] hw/arm/virt: Avoid NULL pointer de-reference, (continued)
- [RFC/PATCH v0 05/12] gunyah: Support memory assignment, Srivatsa Vaddagiri, 2023/10/11
- [RFC/PATCH v0 06/12] gunyah: Add IRQFD and IOEVENTFD functions,
Srivatsa Vaddagiri <=
- [RFC/PATCH v0 07/12] gunyah: Add gicv3 interrupt controller, Srivatsa Vaddagiri, 2023/10/11
- [RFC/PATCH v0 08/12] gunyah: Specific device-tree location, Srivatsa Vaddagiri, 2023/10/11
- [RFC/PATCH v0 09/12] gunyah: Customize device-tree, Srivatsa Vaddagiri, 2023/10/11
- [RFC/PATCH v0 10/12] gunyah: CPU execution loop, Srivatsa Vaddagiri, 2023/10/11
- [RFC/PATCH v0 11/12] gunyah: Workarounds (NOT FOR MERGE), Srivatsa Vaddagiri, 2023/10/11
- [RFC/PATCH v0 12/12] gunyah: Documentation, Srivatsa Vaddagiri, 2023/10/11