From 3c86ab5ca38e6ea57ee5a5c09373fba6f39f933b Mon Sep 17 00:00:00 2001
From: armaan-chowfin-ub-11-host <armaanchowfin@gmail.com>
Date: Sun, 16 Mar 2025 21:06:36 +0530
Subject: [PATCH] qemu 9.2.1 with support for virtio-demo-pci

---
 .gitignore                                   |   3 +
 hw/virtio/Kconfig                            |   5 +
 hw/virtio/meson.build                        |   2 +
 hw/virtio/virtio-demo-pci.c                  | 152 +++++++++++++++
 hw/virtio/virtio-demo.c                      | 189 +++++++++++++++++++
 hw/virtio/virtio-pci.c                       |   6 +-
 hw/virtio/virtio-qmp.c                       |  19 ++
 hw/virtio/virtio.c                           |   3 +-
 include/hw/pci/pci.h                         |   1 +
 include/hw/virtio/virtio-demo.h              |  44 +++++
 include/standard-headers/linux/virtio_demo.h |  12 ++
 include/standard-headers/linux/virtio_ids.h  |   1 +
 12 files changed, 435 insertions(+), 2 deletions(-)
 create mode 100644 hw/virtio/virtio-demo-pci.c
 create mode 100644 hw/virtio/virtio-demo.c
 create mode 100644 include/hw/virtio/virtio-demo.h
 create mode 100644 include/standard-headers/linux/virtio_demo.h

diff --git a/.gitignore b/.gitignore
index 61fa39967b..f0a60e5c1e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
 /GNUmakefile
 /build/
+/build-0/
 /.cache/
 /.vscode/
 *.pyc
@@ -20,3 +21,5 @@ GTAGS
 *.swp
 *.patch
 *.gcov
+subprojects/libblkio/
+
diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig
index 70c77e183d..6fad36f1b0 100644
--- a/hw/virtio/Kconfig
+++ b/hw/virtio/Kconfig
@@ -6,6 +6,11 @@ config VIRTIO_RNG
     default y
     depends on VIRTIO
 
+config VIRTIO_DEMO
+    bool
+    default y
+    depends on VIRTIO
+
 config VIRTIO_NSM
    bool
    depends on LIBCBOR && VIRTIO
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
index a5f9f7999d..b87e6764dd 100644
--- a/hw/virtio/meson.build
+++ b/hw/virtio/meson.build
@@ -58,6 +58,7 @@ specific_virtio_ss.add(when: 'CONFIG_VIRTIO_NSM', if_true: [files('virtio-nsm.c'
 specific_virtio_ss.add(when: 'CONFIG_VIRTIO_MEM', if_true: files('virtio-mem.c'))
 specific_virtio_ss.add(when: 'CONFIG_VHOST_USER_SCMI', if_true: files('vhost-user-scmi.c'))
 specific_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_SCMI'], if_true: files('vhost-user-scmi-pci.c'))
+specific_virtio_ss.add(when: 'CONFIG_VIRTIO_DEMO', if_true: files('virtio-demo.c'))
 
 virtio_pci_ss = ss.source_set()
 virtio_pci_ss.add(when: 'CONFIG_VHOST_VSOCK', if_true: files('vhost-vsock-pci.c'))
@@ -83,6 +84,7 @@ virtio_pci_ss.add(when: 'CONFIG_VIRTIO_IOMMU', if_true: files('virtio-iommu-pci.
 virtio_pci_ss.add(when: 'CONFIG_VIRTIO_MEM', if_true: files('virtio-mem-pci.c'))
 virtio_pci_ss.add(when: 'CONFIG_VHOST_VDPA_DEV', if_true: files('vdpa-dev-pci.c'))
 virtio_pci_ss.add(when: 'CONFIG_VIRTIO_MD', if_true: files('virtio-md-pci.c'))
+virtio_pci_ss.add(when: 'CONFIG_VIRTIO_DEMO', if_true: files('virtio-demo-pci.c'))
 
 specific_virtio_ss.add_all(when: 'CONFIG_VIRTIO_PCI', if_true: virtio_pci_ss)
 
diff --git a/hw/virtio/virtio-demo-pci.c b/hw/virtio/virtio-demo-pci.c
new file mode 100644
index 0000000000..1fbb510a4c
--- /dev/null
+++ b/hw/virtio/virtio-demo-pci.c
@@ -0,0 +1,152 @@
+/**
+ * FILE: virtio-demo-pci.c
+ * ------------------------
+ * PCI bindings for the virtio-demo device.
+ * - Used if <devicename>-pci is specified.
+ * - Unused if <devicename>-device is specified.
+ * Common backend is used by both pci and mmio
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/qdev-properties.h"
+#include "hw/virtio/virtio-demo.h"
+#include "qemu/module.h"
+#include "hw/virtio/virtio-pci.h"
+#include "qom/object.h"
+
+typedef struct VirtIODemoPCI VirtIODemoPCI;
+
+// enables usage of a new VIRTIO_DEMO_PCI() macro to 
+// create a reference to a VirtIODemoPCI struct.
+#define TYPE_VIRTIO_DEMO_PCI "virtio-demo-pci-base"
+DECLARE_INSTANCE_CHECKER(VirtIODemoPCI, VIRTIO_DEMO_PCI,
+                         TYPE_VIRTIO_DEMO_PCI)
+
+
+// template for any virtio-pci binding.
+// Virtio PCI devices must extend the VirtIOPCIProxy
+// base class.
+// https://www.qemu.org/docs/master/devel/virtio-backends.html
+struct VirtIODemoPCI {
+    VirtIOPCIProxy parent_obj;
+
+    // The .vdev is an object that represents a device backend
+    // for this device. Every virtio device backend is registered on
+    // the "virtio-bus", which itself is part of the pci bus.
+    // - I suspect the virtio-bus is mmio-based, which would make sense
+    // considering virtqueue notifs are handled by the device backend
+    // and not the pci-bindings file.
+    // -----------------------------------------------------
+    // Without pci bindings file, your device would be forced to use
+    // the virtio-mmio bus, which is only implemented in the
+    //  `microvm`machine. 
+    VirtIODemo vdev;
+};
+
+
+// Every VirtIOPCIProxy object will have
+// these properties, accessible via 
+// object_property_find().
+// - also accessible via 
+static Property virtio_demo_pci_properties[] = {
+    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
+                    VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
+    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
+                       DEV_NVECTORS_UNSPECIFIED),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+// This function is called by QEMU main code, starting from qdev_device_add()
+// and triggers the realization of the device backend, 
+// - Realization could involve several virtio-specific actions such
+// as initializing virtqueues an their notification handlers.
+static void virtio_demo_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) {
+    VirtIODemoPCI *dev = VIRTIO_DEMO_PCI(vpci_dev);
+
+    // not sure why cast to devicestate is valid
+    DeviceState *vdev = DEVICE(&dev->vdev); 
+
+    vpci_dev->class_code = PCI_CLASS_OTHERS;
+
+    // nvectors is added as a property, not sure why.
+    // not even sure what a vector is...
+    if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) {
+        vpci_dev->nvectors = 2;
+    }
+
+    // @imp: eventually calls the realize of the backend device
+    qdev_realize(vdev, BUS(&vpci_dev->bus), errp); 
+}
+
+
+// Declares the virtual methods and some attributes 
+// that belong to this class (and possibly parents). 
+// - Essentially helps to define 
+// the DEVICE_CLASS->PCI_DEVICE_CLASS->VIRTIO_PCI_CLASS 
+// inherited attributes and methods.
+static void virtio_demo_pci_class_init(ObjectClass *klass, void *data) {
+    // create direct references to all the 
+    // heirarchy classes to avoid an
+    // obj->parent->parent chain.
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+
+    // Register the properties
+    device_class_set_props(dc, virtio_demo_pci_properties);
+
+    // method to realize this pci device,
+    // which also realizes this pci device's backend.
+    k->realize = virtio_demo_pci_realize; 
+
+    // ensure that any device in this hierarchy is 
+    // classed as _MISC. (see qdev-core.h)
+    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+
+    // standard PCI device identifiers.
+    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
+    pcidev_k->class_id = PCI_CLASS_OTHERS;
+
+    // Technically not required when disable-legacy=on.
+    // Modern devices autogenerate the PCI device ID.
+    // - below val will be overwritten by QEMU.
+    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_DEMO; 
+}
+
+// QEMU cli_create_devices() triggers a instance creation
+// for the device type passed. Here also, the idea is to create a
+// object of .vdev type
+static void virtio_demo_pci_instance_init(Object *obj) {
+    VirtIODemoPCI *dev = VIRTIO_DEMO_PCI(obj);
+    
+    // creates the virtio backend for the virtio-bus
+    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+                                TYPE_VIRTIO_DEMO);
+
+}
+
+
+static const VirtioPCIDeviceTypeInfo virtio_demo_pci_info = {
+    .parent = TYPE_VIRTIO_PCI, // see virtio-pci.h. Allows reg on the pci bus.
+    .base_name = TYPE_VIRTIO_DEMO_PCI,
+    .generic_name = "virtio-demo-pci",
+    .transitional_name = "virtio-demo-pci-transitional",
+    .non_transitional_name = "virtio-demo-pci-non-transitional",
+    .instance_size = sizeof(VirtIODemoPCI),
+
+    .class_init = virtio_demo_pci_class_init,
+    .instance_init = virtio_demo_pci_instance_init,
+};
+
+// Boilerplate to register a qemu type
+static void virtio_demo_pci_register(void) {
+    virtio_pci_types_register(&virtio_demo_pci_info);
+}
+
+type_init(virtio_demo_pci_register);
+
+
+
+
diff --git a/hw/virtio/virtio-demo.c b/hw/virtio/virtio-demo.c
new file mode 100644
index 0000000000..3e4adef07f
--- /dev/null
+++ b/hw/virtio/virtio-demo.c
@@ -0,0 +1,189 @@
+/**
+ * FILE: virtio-demo.c
+ * --------------------
+ * VirtIO demo device backend.
+ */
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/iov.h"
+#include "qemu/module.h"
+#include "qemu/timer.h"
+#include "hw/virtio/virtio.h"
+#include "hw/qdev-properties.h"
+#include "hw/virtio/virtio-demo.h"
+#include "sysemu/rng.h"
+#include "sysemu/runstate.h"
+#include "qom/object_interfaces.h"
+#include "trace.h"
+
+// "host features": Every possible feature
+// result of negotiation is stored in guest and backend features
+static Property virtio_demo_properties[] = {
+    DEFINE_PROP_BIT64("in-order-buf", VirtIODemo, host_features,
+                      VIRTIO_F_IN_ORDER, true),
+    DEFINE_PROP_BIT64("test-feature", VirtIODemo, host_features,
+                      VIRTIO_F_DEMO_TEST, true),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+// Multiply via a device.
+struct mult_val12_t
+{
+    uint8_t val_1;
+    uint8_t val_2;
+};
+
+typedef struct multiplicands
+{
+    uint8_t val_1;
+    uint8_t val_2;
+} multiplicands_t;
+
+typedef uint16_t prod_t;
+
+typedef struct demoreq
+{
+    multiplicands_t m;
+    prod_t res;
+} demoreq_t;
+
+static void
+demo_read_outbuf(VirtIODevice *vdev, VirtQueue *vq)
+{
+    // VirtIODemo *s = VIRTIO_DEMO(vdev);
+    // print a message to console
+    printf("[%s] %s: Got a virtqueue message from guest\n", __FILE__, __func__);
+
+    VirtQueueElement *vqe;
+    // VirtQueueElement *vqe_rx;/
+
+    while (!virtio_queue_ready(vq))
+    {
+        printf("vq not ready\n");
+        return;
+    }
+
+    if (!runstate_check(RUN_STATE_RUNNING))
+    {
+        printf("not synced");
+        return;
+    }
+    
+    vqe = virtqueue_pop(vq, sizeof(VirtQueueElement)); // 2 multiplicands
+    if (!vqe)
+    {
+        printf("vqe not present\n");
+        return;
+    }
+
+    // printf("vqe index: %d\n", vqe_tx->index);
+    demoreq_t req;
+    iov_to_buf(vqe->out_sg, vqe->out_num, 0, &req, vqe->out_sg->iov_len); // iov len must be >= sizeof(m)
+    
+    // multiply!
+    uint16_t res = req.m.val_1 * req.m.val_2;
+    printf("mult res: %d\n", res);
+    
+    iov_from_buf(vqe->in_sg, vqe->in_num, 0, &res, vqe->in_sg->iov_len);
+
+    virtqueue_push(vq, vqe, vqe->in_sg->iov_len);
+    virtio_notify(vdev, vq);
+}
+
+// device realize can register custom actions based on
+// the host features
+static void virtio_demo_device_realize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    VirtIODemo *s = VIRTIO_DEMO(dev);
+
+    virtio_init(vdev, VIRTIO_ID_DEMO, 0); // config_size = 0, not sure of significance
+
+    // setup the virtqueues.
+    // register callback for a virtqueue ready event
+    // max 1 pending req/response in the queue.
+    // 64: # of entries in each vring (desc, avail, used)
+    // before wraparound
+    // must be a power of two (virtio spec)
+    // find_vqs() does mapping in this init order.
+    s->vq = virtio_add_queue(vdev, 64, demo_read_outbuf); // for driver outbufs
+
+    // callback is generally used when driver wants to retrieve
+    // data stored on device. The sequence is:
+    // 1. driver adds inbufs to queue and kicks.
+    // 2. the handler in device retrieves this data and copies to the inbuf
+    // 3. handler kicks inbuf queue, which is read by the driver.
+    // s->rx_vq = virtio_add_queue(vdev, 64, demo_fill_inbuf); // for driver inbufs
+}
+
+static void virtio_demo_device_unrealize(DeviceState *dev)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev); // parent class
+
+    VirtIODemo *s = VIRTIO_DEMO(dev); // our device
+    (void)s;
+
+    // seem like standard funcs.
+    virtio_del_queue(vdev, 0);
+    virtio_cleanup(vdev);
+}
+
+// initilialize attributes of the virtio-demo-device.
+// (non-virtqueue ops)
+static void virtio_demo_instance_init(Object *obj)
+{
+    VirtIODemo *s = VIRTIO_DEMO(obj);
+    (void)s;
+
+    // lowkey think instance init can be empty
+}
+
+static uint64_t virtio_demo_get_features(VirtIODevice *vdev, uint64_t features,
+                                          Error **errp)
+{
+    printf("requesting features\n");
+    VirtIODemo *dev = VIRTIO_DEMO(vdev);
+    features |= dev->host_features;
+    // virtio_add_feature(&features, VIRTIO_F_IN_ORDER);
+
+    return features;
+}
+
+// GOAL: Setup the methods of the parent (VirtioDeviceClass)
+// of this virtio-demo-device class. All these methods will
+// be inherited by the child.
+static void virtio_demo_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+
+    // can add additional class props as well.
+    // props must be part of your device struct.
+    device_class_set_props(dc, virtio_demo_properties);
+
+    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+
+    vdc->realize = virtio_demo_device_realize;
+    vdc->unrealize = virtio_demo_device_unrealize;
+    vdc->get_features = virtio_demo_get_features; // needed, else assert fail (virtio-bus.c)
+}
+
+static const TypeInfo virtio_demo_info = {
+    .name = TYPE_VIRTIO_DEMO,
+
+    // reg as virtio-mmio (virtio-bus) device.
+    // The device backend object will only inherit attributes
+    // and methods of the DEVICE_CLASS. (no pci stuff)
+    .parent = TYPE_VIRTIO_DEVICE,
+    .instance_size = sizeof(VirtIODemo),
+    .instance_init = virtio_demo_instance_init,
+    .class_init = virtio_demo_class_init,
+};
+
+// QEMU device boilerplate to register type
+static void virtio_register_types(void)
+{
+    type_register_static(&virtio_demo_info);
+}
+
+type_init(virtio_register_types)
\ No newline at end of file
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 5a394821da..adca9d0599 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -268,7 +268,11 @@ static const VirtIOPCIIDInfo virtio_pci_id_info[] = {
         .vdev_id = VIRTIO_ID_RNG,
         .trans_devid = PCI_DEVICE_ID_VIRTIO_RNG,
         .class_id = PCI_CLASS_OTHERS,
-    },
+    },{
+        .vdev_id = VIRTIO_ID_DEMO,
+        .trans_devid = PCI_DEVICE_ID_VIRTIO_DEMO,
+        .class_id = PCI_CLASS_OTHERS,
+    }
 };
 
 static const VirtIOPCIIDInfo *virtio_pci_get_id_info(uint16_t vdev_id)
diff --git a/hw/virtio/virtio-qmp.c b/hw/virtio/virtio-qmp.c
index cccc6fe761..50968ae6c6 100644
--- a/hw/virtio/virtio-qmp.c
+++ b/hw/virtio/virtio-qmp.c
@@ -32,6 +32,7 @@
 #include "standard-headers/linux/virtio_mem.h"
 #include "standard-headers/linux/virtio_vsock.h"
 #include "standard-headers/linux/virtio_gpio.h"
+#include "standard-headers/linux/virtio_demo.h"
 
 #include CONFIG_DEVICES
 
@@ -406,6 +407,16 @@ static const qmp_virtio_feature_map_t virtio_balloon_feature_map[] = {
 };
 #endif
 
+#ifdef CONFIG_VIRTIO_DEMO
+static const qmp_virtio_feature_map_t virtio_demo_feature_map[] = {
+     FEATURE_ENTRY(VIRTIO_F_DEMO_TEST, \
+                "VIRTIO_F_DEMO_TEST: Dummy feature to demonstrate virtio-spec \
+compliance using QEMU APIs"),
+     {-1, ""}
+};
+#endif
+
+
 /* virtio-crypto features mapping */
 #ifdef CONFIG_VIRTIO_CRYPTO
 static const qmp_virtio_feature_map_t virtio_crypto_feature_map[] = {
@@ -590,6 +601,14 @@ VirtioDeviceFeatures *qmp_decode_features(uint16_t device_id, uint64_t bitmap)
             CONVERT_FEATURES(strList, virtio_balloon_feature_map, 0, bitmap);
         break;
 #endif
+
+#ifdef CONFIG_VIRTIO_DEMO
+	case VIRTIO_ID_DEMO:
+		features->dev_features = 
+			CONVERT_FEATURES(strList, virtio_demo_feature_map, 0, bitmap);
+		break;
+#endif    
+
 #ifdef CONFIG_VIRTIO_IOMMU
     case VIRTIO_ID_IOMMU:
         features->dev_features =
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index f12c4aa81e..fe4fbc0f96 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -194,7 +194,8 @@ const char *virtio_device_names[] = {
     [VIRTIO_ID_PARAM_SERV] = "virtio-param-serv",
     [VIRTIO_ID_AUDIO_POLICY] = "virtio-audio-pol",
     [VIRTIO_ID_BT] = "virtio-bluetooth",
-    [VIRTIO_ID_GPIO] = "virtio-gpio"
+    [VIRTIO_ID_GPIO] = "virtio-gpio",
+    [VIRTIO_ID_DEMO] = "virtio-demo"
 };
 
 static const char *virtio_id_to_name(uint16_t device_id)
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index c0717e3121..be96713070 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -86,6 +86,7 @@ extern bool pci_available;
 #define PCI_DEVICE_ID_VIRTIO_RNG         0x1005
 #define PCI_DEVICE_ID_VIRTIO_9P          0x1009
 #define PCI_DEVICE_ID_VIRTIO_VSOCK       0x1012
+#define PCI_DEVICE_ID_VIRTIO_DEMO        0x1013
 
 /*
  * modern virtio-pci devices get their id assigned automatically,
diff --git a/include/hw/virtio/virtio-demo.h b/include/hw/virtio/virtio-demo.h
new file mode 100644
index 0000000000..867d1ea66b
--- /dev/null
+++ b/include/hw/virtio/virtio-demo.h
@@ -0,0 +1,44 @@
+/**
+ * FILE: virtio-demo.h
+ * --------------------
+ * Common header for the virtio-demo device.
+ */
+
+#ifndef QEMU_VIRTIO_DEMO_H
+#define QEMU_VIRTIO_DEMO_H
+
+#include "hw/virtio/virtio.h"
+#include "sysemu/iothread.h"
+#include "standard-headers/linux/virtio_demo.h"
+#include "qom/object.h"
+
+#define TYPE_VIRTIO_DEMO "virtio-demo-device"
+
+// Enables one to use a VIRTIO_DEMO()
+// macro to obtain reference to a
+// struct VirtIODemo from an Object.
+// -----------------------------------
+// - OBJECT_DECLARE_SIMPLE_TYPE() is used to define classes
+// that dont need additional virtual methods declared.
+// - OBJECT_DECLARE_TYPE() is used to declare classes
+// that need additional virtual methods. (see scsi-disk.c)
+OBJECT_DECLARE_SIMPLE_TYPE(VirtIODemo, VIRTIO_DEMO)
+
+// A struct to hold any local VirtIODemo device data.
+// Attributes depend on your device semantics.
+// - Usually contains the device virtqueues.
+// - Contains any data required to implement
+// the VirtioDeviceClass (see virtio.h) methods.
+struct VirtIODemo
+{
+    VirtIODevice parent_obj; // seems compulsory; not sure why
+    VirtQueue *vq;           // resps from host, reqs from guest.
+    uint64_t host_features;  // necessary by virtio spec
+};
+
+size_t virtio_demo_handle_mult_iov(VirtIODevice *vdev,
+                                    const struct iovec *in_sg, unsigned in_num,
+                                    const struct iovec *out_sg,
+                                    unsigned out_num);
+
+#endif
\ No newline at end of file
diff --git a/include/standard-headers/linux/virtio_demo.h b/include/standard-headers/linux/virtio_demo.h
new file mode 100644
index 0000000000..639d9ed567
--- /dev/null
+++ b/include/standard-headers/linux/virtio_demo.h
@@ -0,0 +1,12 @@
+#ifndef _LINUX_VIRTIO_DEMO_H
+#define _LINUX_VIRTIO_DEMO_H
+/* This header is BSD licensed so anyone can use the definitions to implement
+ * compatible drivers/servers. */
+#include "standard-headers/linux/virtio_ids.h"
+#include "standard-headers/linux/virtio_config.h"
+
+// Feature bitmap. Currently only bit 1
+// is meaningful.
+#define VIRTIO_F_DEMO_TEST 1
+
+#endif /* _LINUX_VIRTIO_DEMO_H */
\ No newline at end of file
diff --git a/include/standard-headers/linux/virtio_ids.h b/include/standard-headers/linux/virtio_ids.h
index 7aa2eb7662..194c320c21 100644
--- a/include/standard-headers/linux/virtio_ids.h
+++ b/include/standard-headers/linux/virtio_ids.h
@@ -68,6 +68,7 @@
 #define VIRTIO_ID_AUDIO_POLICY		39 /* virtio audio policy */
 #define VIRTIO_ID_BT			40 /* virtio bluetooth */
 #define VIRTIO_ID_GPIO			41 /* virtio gpio */
+#define VIRTIO_ID_DEMO         42 /* virtio demo */
 
 /*
  * Virtio Transitional IDs
-- 
2.43.0

