The branch main has been updated by corvink:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=b11081dca76b8e283495632b86b41539ee013857

commit b11081dca76b8e283495632b86b41539ee013857
Author:     Corvin Köhne <corv...@freebsd.org>
AuthorDate: 2021-08-11 08:00:34 +0000
Commit:     Corvin Köhne <corv...@freebsd.org>
CommitDate: 2023-02-14 07:28:49 +0000

    bhyve: add emulation for qemu's fwcfg data port
    
    The data port returns the data of the fwcfg item.
    
    Reviewed by:            markj
    MFC after:              1 week
    Sponsored by:           Beckhoff Automation GmbH & Co. KG
    Differential Revision:  https://reviews.freebsd.org/D38333
---
 usr.sbin/bhyve/qemu_fwcfg.c | 40 ++++++++++++++++++++++++++++++++++++++++
 usr.sbin/bhyve/qemu_fwcfg.h |  8 ++++++++
 2 files changed, 48 insertions(+)

diff --git a/usr.sbin/bhyve/qemu_fwcfg.c b/usr.sbin/bhyve/qemu_fwcfg.c
index dec3fa83c493..13e21daca7ff 100644
--- a/usr.sbin/bhyve/qemu_fwcfg.c
+++ b/usr.sbin/bhyve/qemu_fwcfg.c
@@ -56,6 +56,8 @@ struct qemu_fwcfg_softc {
 
        uint32_t data_offset;
        union qemu_fwcfg_selector selector;
+       struct qemu_fwcfg_item items[QEMU_FWCFG_MAX_ARCHS]
+                                   [QEMU_FWCFG_MAX_ENTRIES];
 };
 
 static struct qemu_fwcfg_softc fwcfg_sc;
@@ -87,6 +89,44 @@ qemu_fwcfg_data_port_handler(struct vmctx *const ctx 
__unused, const int in,
     const int port __unused, const int bytes, uint32_t *const eax,
     void *const arg __unused)
 {
+       if (bytes != sizeof(uint8_t)) {
+               warnx("%s: invalid size (%d) of IO port access", __func__,
+                   bytes);
+               return (-1);
+       }
+
+       if (!in) {
+               warnx("%s: Writes to qemu fwcfg data port aren't allowed",
+                   __func__);
+               return (-1);
+       }
+
+       /* get fwcfg item */
+       struct qemu_fwcfg_item *const item =
+           &fwcfg_sc.items[fwcfg_sc.selector.architecture]
+                          [fwcfg_sc.selector.index];
+       if (item->data == NULL) {
+               warnx(
+                   "%s: qemu fwcfg item doesn't exist (architecture %s index 
0x%x)",
+                   __func__,
+                   fwcfg_sc.selector.architecture ? "specific" : "generic",
+                   fwcfg_sc.selector.index);
+               *eax = 0x00;
+               return (0);
+       } else if (fwcfg_sc.data_offset >= item->size) {
+               warnx(
+                   "%s: qemu fwcfg item read exceeds size (architecture %s 
index 0x%x size 0x%x offset 0x%x)",
+                   __func__,
+                   fwcfg_sc.selector.architecture ? "specific" : "generic",
+                   fwcfg_sc.selector.index, item->size, fwcfg_sc.data_offset);
+               *eax = 0x00;
+               return (0);
+       }
+
+       /* return item data */
+       *eax = item->data[fwcfg_sc.data_offset];
+       fwcfg_sc.data_offset++;
+
        return (0);
 }
 
diff --git a/usr.sbin/bhyve/qemu_fwcfg.h b/usr.sbin/bhyve/qemu_fwcfg.h
index 26c4db0ff71e..58ef5ed3c6bf 100644
--- a/usr.sbin/bhyve/qemu_fwcfg.h
+++ b/usr.sbin/bhyve/qemu_fwcfg.h
@@ -9,4 +9,12 @@
 
 #include <vmmapi.h>
 
+#define QEMU_FWCFG_MAX_ARCHS 0x2
+#define QEMU_FWCFG_MAX_ENTRIES 0x4000
+
+struct qemu_fwcfg_item {
+       uint32_t size;
+       uint8_t *data;
+};
+
 int qemu_fwcfg_init(struct vmctx *const ctx);

Reply via email to