diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2014-06-20 18:01:24 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2014-06-20 18:01:24 +0100 |
commit | 0a99aae5fab5ed260aab96049c274b0334eb4085 (patch) | |
tree | 7db67e570b622a37a2139da871b79b0386942e4b /include/hw | |
parent | 53001c148340127c2dca1f90329804cd0ac0e236 (diff) | |
parent | 705456c0d7f24fbd76733c891525b8eeea332e8b (diff) | |
download | hqemu-0a99aae5fab5ed260aab96049c274b0334eb4085.zip hqemu-0a99aae5fab5ed260aab96049c274b0334eb4085.tar.gz |
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
pc,pci,virtio,hotplug fixes, enhancements
numa work by Hu Tao and others
memory hotplug by Igor
vhost-user by Nikolay, Antonios and others
guest virtio announcements by Jason
qtest fixes by Sergey
qdev hotplug fixes by Paolo
misc other fixes mostly by myself
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
* remotes/mst/tags/for_upstream: (109 commits)
numa: use RAM_ADDR_FMT with ram_addr_t
qapi/string-output-visitor: fix bugs
tests: simplify code
qapi: fix input visitor bugs
acpi: rephrase comment
qmp: add ACPI_DEVICE_OST event handling
qmp: add query-acpi-ospm-status command
acpi: implement ospm_status() method for PIIX4/ICH9_LPC devices
acpi: introduce TYPE_ACPI_DEVICE_IF interface
qmp: add query-memory-devices command
numa: handle mmaped memory allocation failure correctly
pc: acpi: do not hardcode preprocessor
qmp: clean out whitespace
qdev: recursively unrealize devices when unrealizing bus
qdev: reorganize error reporting in bus_set_realized
qapi: fix build on glib < 2.28
qapi: make string output visitor parse int list
qapi: make string input visitor parse int list
tests: fix memory leak in test of string input visitor
hmp: add info memdev
...
Conflicts:
include/hw/i386/pc.h
[PMM: fixed minor conflict in pc.h]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'include/hw')
-rw-r--r-- | include/hw/acpi/acpi.h | 5 | ||||
-rw-r--r-- | include/hw/acpi/acpi_dev_interface.h | 43 | ||||
-rw-r--r-- | include/hw/acpi/cpu_hotplug.h | 2 | ||||
-rw-r--r-- | include/hw/acpi/cpu_hotplug_defs.h | 32 | ||||
-rw-r--r-- | include/hw/acpi/ich9.h | 7 | ||||
-rw-r--r-- | include/hw/acpi/memory_hotplug.h | 38 | ||||
-rw-r--r-- | include/hw/acpi/pc-hotplug.h | 56 | ||||
-rw-r--r-- | include/hw/boards.h | 16 | ||||
-rw-r--r-- | include/hw/i386/ich9.h | 2 | ||||
-rw-r--r-- | include/hw/i386/pc.h | 79 | ||||
-rw-r--r-- | include/hw/mem/pc-dimm.h | 81 | ||||
-rw-r--r-- | include/hw/virtio/vhost-backend.h | 38 | ||||
-rw-r--r-- | include/hw/virtio/vhost.h | 13 | ||||
-rw-r--r-- | include/hw/virtio/virtio-net.h | 17 |
14 files changed, 384 insertions, 45 deletions
diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h index a9fae9d..1f678b4 100644 --- a/include/hw/acpi/acpi.h +++ b/include/hw/acpi/acpi.h @@ -26,6 +26,11 @@ #include "exec/memory.h" #include "hw/irq.h" +/* + * current device naming scheme supports up to 256 memory devices + */ +#define ACPI_MAX_RAM_SLOTS 256 + /* from linux include/acpi/actype.h */ /* Default ACPI register widths */ diff --git a/include/hw/acpi/acpi_dev_interface.h b/include/hw/acpi/acpi_dev_interface.h new file mode 100644 index 0000000..f245f8d --- /dev/null +++ b/include/hw/acpi/acpi_dev_interface.h @@ -0,0 +1,43 @@ +#ifndef ACPI_DEV_INTERFACE_H +#define ACPI_DEV_INTERFACE_H + +#include "qom/object.h" +#include "qapi-types.h" + +#define TYPE_ACPI_DEVICE_IF "acpi-device-interface" + +#define ACPI_DEVICE_IF_CLASS(klass) \ + OBJECT_CLASS_CHECK(AcpiDeviceIfClass, (klass), \ + TYPE_ACPI_DEVICE_IF) +#define ACPI_DEVICE_IF_GET_CLASS(obj) \ + OBJECT_GET_CLASS(AcpiDeviceIfClass, (obj), \ + TYPE_ACPI_DEVICE_IF) +#define ACPI_DEVICE_IF(obj) \ + INTERFACE_CHECK(AcpiDeviceIf, (obj), \ + TYPE_ACPI_DEVICE_IF) + + +typedef struct AcpiDeviceIf { + /* <private> */ + Object Parent; +} AcpiDeviceIf; + +/** + * AcpiDeviceIfClass: + * + * ospm_status: returns status of ACPI device objects, reported + * via _OST method if device supports it. + * + * Interface is designed for providing unified interface + * to generic ACPI functionality that could be used without + * knowledge about internals of actual device that implements + * ACPI interface. + */ +typedef struct AcpiDeviceIfClass { + /* <private> */ + InterfaceClass parent_class; + + /* <public> */ + void (*ospm_status)(AcpiDeviceIf *adev, ACPIOSTInfoList ***list); +} AcpiDeviceIfClass; +#endif diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h index 4576400..9e5d30c 100644 --- a/include/hw/acpi/cpu_hotplug.h +++ b/include/hw/acpi/cpu_hotplug.h @@ -13,7 +13,7 @@ #define ACPI_HOTPLUG_H #include "hw/acpi/acpi.h" -#include "hw/acpi/cpu_hotplug_defs.h" +#include "hw/acpi/pc-hotplug.h" typedef struct AcpiCpuHotplug { MemoryRegion io; diff --git a/include/hw/acpi/cpu_hotplug_defs.h b/include/hw/acpi/cpu_hotplug_defs.h deleted file mode 100644 index 9f33663..0000000 --- a/include/hw/acpi/cpu_hotplug_defs.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * QEMU ACPI hotplug utilities shared defines - * - * Copyright (C) 2013 Red Hat Inc - * - * Authors: - * Igor Mammedov <imammedo@redhat.com> - * - * 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 ACPI_HOTPLUG_DEFS_H -#define ACPI_HOTPLUG_DEFS_H - -/* - * ONLY DEFINEs are permited in this file since it's shared - * between C and ASL code. - */ -#define ACPI_CPU_HOTPLUG_STATUS 4 - -/* Limit for CPU arch IDs for CPU hotplug. All hotpluggable CPUs should - * have CPUClass.get_arch_id() < ACPI_CPU_HOTPLUG_ID_LIMIT. - */ -#define ACPI_CPU_HOTPLUG_ID_LIMIT 256 - -/* 256 CPU IDs, 8 bits per entry: */ -#define ACPI_GPE_PROC_LEN 32 - -#define ICH9_CPU_HOTPLUG_IO_BASE 0x0CD8 -#define PIIX4_CPU_HOTPLUG_IO_BASE 0xaf00 - -#endif diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h index 104f419..7e42448 100644 --- a/include/hw/acpi/ich9.h +++ b/include/hw/acpi/ich9.h @@ -23,6 +23,8 @@ #include "hw/acpi/acpi.h" #include "hw/acpi/cpu_hotplug.h" +#include "hw/acpi/memory_hotplug.h" +#include "hw/acpi/acpi_dev_interface.h" typedef struct ICH9LPCPMRegs { /* @@ -46,6 +48,8 @@ typedef struct ICH9LPCPMRegs { AcpiCpuHotplug gpe_cpu; Notifier cpu_added_notifier; + + MemHotplugState acpi_memory_hotplug; } ICH9LPCPMRegs; void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, @@ -55,4 +59,7 @@ extern const VMStateDescription vmstate_ich9_pm; void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp); +void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp); + +void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list); #endif /* HW_ACPI_ICH9_H */ diff --git a/include/hw/acpi/memory_hotplug.h b/include/hw/acpi/memory_hotplug.h new file mode 100644 index 0000000..7bbf8a0 --- /dev/null +++ b/include/hw/acpi/memory_hotplug.h @@ -0,0 +1,38 @@ +#ifndef QEMU_HW_ACPI_MEMORY_HOTPLUG_H +#define QEMU_HW_ACPI_MEMORY_HOTPLUG_H + +#include "hw/qdev-core.h" +#include "hw/acpi/acpi.h" +#include "migration/vmstate.h" + +#define ACPI_MEMORY_HOTPLUG_STATUS 8 + +typedef struct MemStatus { + DeviceState *dimm; + bool is_enabled; + bool is_inserting; + uint32_t ost_event; + uint32_t ost_status; +} MemStatus; + +typedef struct MemHotplugState { + bool is_enabled; /* true if memory hotplug is supported */ + MemoryRegion io; + uint32_t selector; + uint32_t dev_count; + MemStatus *devs; +} MemHotplugState; + +void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner, + MemHotplugState *state); + +void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, + DeviceState *dev, Error **errp); + +extern const VMStateDescription vmstate_memory_hotplug; +#define VMSTATE_MEMORY_HOTPLUG(memhp, state) \ + VMSTATE_STRUCT(memhp, state, 1, \ + vmstate_memory_hotplug, MemHotplugState) + +void acpi_memory_ospm_status(MemHotplugState *mem_st, ACPIOSTInfoList ***list); +#endif diff --git a/include/hw/acpi/pc-hotplug.h b/include/hw/acpi/pc-hotplug.h new file mode 100644 index 0000000..bf5157d --- /dev/null +++ b/include/hw/acpi/pc-hotplug.h @@ -0,0 +1,56 @@ +/* + * QEMU ACPI hotplug utilities shared defines + * + * Copyright (C) 2014 Red Hat Inc + * + * Authors: + * Igor Mammedov <imammedo@redhat.com> + * + * 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 PC_HOTPLUG_H +#define PC_HOTPLUG_H + +/* + * ONLY DEFINEs are permited in this file since it's shared + * between C and ASL code. + */ +#define ACPI_CPU_HOTPLUG_STATUS 4 + +/* Limit for CPU arch IDs for CPU hotplug. All hotpluggable CPUs should + * have CPUClass.get_arch_id() < ACPI_CPU_HOTPLUG_ID_LIMIT. + */ +#define ACPI_CPU_HOTPLUG_ID_LIMIT 256 + +/* 256 CPU IDs, 8 bits per entry: */ +#define ACPI_GPE_PROC_LEN 32 + +#define ICH9_CPU_HOTPLUG_IO_BASE 0x0CD8 +#define PIIX4_CPU_HOTPLUG_IO_BASE 0xaf00 + +#define ACPI_MEMORY_HOTPLUG_IO_LEN 24 +#define ACPI_MEMORY_HOTPLUG_BASE 0x0a00 + +#define MEMORY_HOPTLUG_DEVICE MHPD +#define MEMORY_SLOTS_NUMBER MDNR +#define MEMORY_HOTPLUG_IO_REGION HPMR +#define MEMORY_SLOT_ADDR_LOW MRBL +#define MEMORY_SLOT_ADDR_HIGH MRBH +#define MEMORY_SLOT_SIZE_LOW MRLL +#define MEMORY_SLOT_SIZE_HIGH MRLH +#define MEMORY_SLOT_PROXIMITY MPX +#define MEMORY_SLOT_ENABLED MES +#define MEMORY_SLOT_INSERT_EVENT MINS +#define MEMORY_SLOT_SLECTOR MSEL +#define MEMORY_SLOT_OST_EVENT MOEV +#define MEMORY_SLOT_OST_STATUS MOSC +#define MEMORY_SLOT_LOCK MLCK +#define MEMORY_SLOT_STATUS_METHOD MRST +#define MEMORY_SLOT_CRS_METHOD MCRS +#define MEMORY_SLOT_OST_METHOD MOST +#define MEMORY_SLOT_PROXIMITY_METHOD MPXM +#define MEMORY_SLOT_NOTIFY_METHOD MTFY +#define MEMORY_SLOT_SCAN_METHOD MSCN + +#endif diff --git a/include/hw/boards.h b/include/hw/boards.h index 2d2e2be..605a970 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -43,9 +43,13 @@ struct QEMUMachine { const char *hw_version; }; -#define TYPE_MACHINE_SUFFIX "-machine" +void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner, + const char *name, + uint64_t ram_size); + int qemu_register_machine(QEMUMachine *m); +#define TYPE_MACHINE_SUFFIX "-machine" #define TYPE_MACHINE "machine" #undef MACHINE /* BSD defines it and QEMU does not use it */ #define MACHINE(obj) \ @@ -61,6 +65,11 @@ extern MachineState *current_machine; /** * MachineClass: * @qemu_machine: #QEMUMachine + * @get_hotplug_handler: this function is called during bus-less + * device hotplug. If defined it returns pointer to an instance + * of HotplugHandler object, which handles hotplug operation + * for a given @dev. It may return NULL if @dev doesn't require + * any actions to be performed by hotplug handler. */ struct MachineClass { /*< private >*/ @@ -90,6 +99,9 @@ struct MachineClass { const char *default_boot_order; GlobalProperty *compat_props; const char *hw_version; + + HotplugHandler *(*get_hotplug_handler)(MachineState *machine, + DeviceState *dev); }; /** @@ -113,6 +125,8 @@ struct MachineState { char *firmware; ram_addr_t ram_size; + ram_addr_t maxram_size; + uint64_t ram_slots; const char *boot_order; char *kernel_filename; char *kernel_cmdline; diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h index e191435..59ea25b 100644 --- a/include/hw/i386/ich9.h +++ b/include/hw/i386/ich9.h @@ -24,7 +24,7 @@ I2CBus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base); #define ICH9_CC_SIZE (16 * 1024) /* 16KB */ -#define TYPE_ICH9_LPC_DEVICE "ICH9 LPC" +#define TYPE_ICH9_LPC_DEVICE "ICH9-LPC" #define ICH9_LPC_DEVICE(obj) \ OBJECT_CHECK(ICH9LPCState, (obj), TYPE_ICH9_LPC_DEVICE) diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index ca7a0bd..19f78ea 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -3,6 +3,7 @@ #include "qemu-common.h" #include "exec/memory.h" +#include "hw/boards.h" #include "hw/isa/isa.h" #include "hw/block/fdc.h" #include "net/net.h" @@ -12,9 +13,57 @@ #include "qemu/bitmap.h" #include "sysemu/sysemu.h" #include "hw/pci/pci.h" +#include "hw/boards.h" #define HPET_INTCAP "hpet-intcap" +/** + * PCMachineState: + * @hotplug_memory_base: address in guest RAM address space where hotplug memory + * address space begins. + * @hotplug_memory: hotplug memory addess space container + * @acpi_dev: link to ACPI PM device that performs ACPI hotplug handling + */ +struct PCMachineState { + /*< private >*/ + MachineState parent_obj; + + /* <public> */ + ram_addr_t hotplug_memory_base; + MemoryRegion hotplug_memory; + + HotplugHandler *acpi_dev; +}; + +#define PC_MACHINE_ACPI_DEVICE_PROP "acpi-device" +#define PC_MACHINE_MEMHP_REGION_SIZE "hotplug-memory-region-size" + +/** + * PCMachineClass: + * @get_hotplug_handler: pointer to parent class callback @get_hotplug_handler + */ +struct PCMachineClass { + /*< private >*/ + MachineClass parent_class; + + /*< public >*/ + HotplugHandler *(*get_hotplug_handler)(MachineState *machine, + DeviceState *dev); +}; + +typedef struct PCMachineState PCMachineState; +typedef struct PCMachineClass PCMachineClass; + +#define TYPE_PC_MACHINE "generic-pc-machine" +#define PC_MACHINE(obj) \ + OBJECT_CHECK(PCMachineState, (obj), TYPE_PC_MACHINE) +#define PC_MACHINE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(PCMachineClass, (obj), TYPE_PC_MACHINE) +#define PC_MACHINE_CLASS(klass) \ + OBJECT_CLASS_CHECK(PCMachineClass, (klass), TYPE_PC_MACHINE) + +void qemu_register_pc_machine(QEMUMachine *m); + /* PC-style peripherals (also used by other machines). */ typedef struct PcPciInfo { @@ -43,6 +92,7 @@ struct PcGuestInfo { uint64_t *node_cpu; FWCfgState *fw_cfg; bool has_acpi_build; + bool has_reserved_memory; }; /* parallel.c */ @@ -134,10 +184,8 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size, void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory, MemoryRegion *pci_address_space); -FWCfgState *pc_memory_init(MemoryRegion *system_memory, - const char *kernel_filename, - const char *kernel_cmdline, - const char *initrd_filename, +FWCfgState *pc_memory_init(MachineState *machine, + MemoryRegion *system_memory, ram_addr_t below_4g_mem_size, ram_addr_t above_4g_mem_size, MemoryRegion *rom_memory, @@ -167,7 +215,8 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name); I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, qemu_irq sci_irq, qemu_irq smi_irq, - int kvm_enabled, FWCfgState *fw_cfg); + int kvm_enabled, FWCfgState *fw_cfg, + DeviceState **piix4_pm); void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr); /* hpet.c */ @@ -243,7 +292,12 @@ int e820_get_num_entries(void); bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); #define PC_Q35_COMPAT_2_0 \ - PC_COMPAT_2_0 + PC_COMPAT_2_0, \ + {\ + .driver = "ICH9-LPC",\ + .property = "memory-hotplug-support",\ + .value = "off",\ + } #define PC_Q35_COMPAT_1_7 \ PC_COMPAT_1_7, \ @@ -272,10 +326,16 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); .property = "any_layout",\ .value = "off",\ },{\ + .driver = "PIIX4_PM",\ + .property = "memory-hotplug-support",\ + .value = "off",\ + },\ + {\ .driver = "apic",\ .property = "version",\ .value = stringify(0x11),\ - },{\ + },\ + {\ .driver = "nec-usb-xhci",\ .property = "superspeed-ports-first",\ .value = "off",\ @@ -294,6 +354,11 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); .driver = "pci-serial-4x",\ .property = "prog_if",\ .value = stringify(0),\ + },\ + {\ + .driver = "virtio-net-pci",\ + .property = "guest_announce",\ + .value = "off",\ } #define PC_COMPAT_1_7 \ diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h new file mode 100644 index 0000000..761eeef --- /dev/null +++ b/include/hw/mem/pc-dimm.h @@ -0,0 +1,81 @@ +/* + * PC DIMM device + * + * Copyright ProfitBricks GmbH 2012 + * Copyright (C) 2013-2014 Red Hat Inc + * + * Authors: + * Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com> + * Igor Mammedov <imammedo@redhat.com> + * + * 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 QEMU_PC_DIMM_H +#define QEMU_PC_DIMM_H + +#include "exec/memory.h" +#include "sysemu/hostmem.h" +#include "hw/qdev.h" + +#define DEFAULT_PC_DIMMSIZE (1024*1024*1024) + +#define TYPE_PC_DIMM "pc-dimm" +#define PC_DIMM(obj) \ + OBJECT_CHECK(PCDIMMDevice, (obj), TYPE_PC_DIMM) +#define PC_DIMM_CLASS(oc) \ + OBJECT_CLASS_CHECK(PCDIMMDeviceClass, (oc), TYPE_PC_DIMM) +#define PC_DIMM_GET_CLASS(obj) \ + OBJECT_GET_CLASS(PCDIMMDeviceClass, (obj), TYPE_PC_DIMM) + +#define PC_DIMM_ADDR_PROP "addr" +#define PC_DIMM_SLOT_PROP "slot" +#define PC_DIMM_NODE_PROP "node" +#define PC_DIMM_SIZE_PROP "size" +#define PC_DIMM_MEMDEV_PROP "memdev" + +#define PC_DIMM_UNASSIGNED_SLOT -1 + +/** + * PCDIMMDevice: + * @addr: starting guest physical address, where @PCDIMMDevice is mapped. + * Default value: 0, means that address is auto-allocated. + * @node: numa node to which @PCDIMMDevice is attached. + * @slot: slot number into which @PCDIMMDevice is plugged in. + * Default value: -1, means that slot is auto-allocated. + * @hostmem: host memory backend providing memory for @PCDIMMDevice + */ +typedef struct PCDIMMDevice { + /* private */ + DeviceState parent_obj; + + /* public */ + uint64_t addr; + uint32_t node; + int32_t slot; + HostMemoryBackend *hostmem; +} PCDIMMDevice; + +/** + * PCDIMMDeviceClass: + * @get_memory_region: returns #MemoryRegion associated with @dimm + */ +typedef struct PCDIMMDeviceClass { + /* private */ + DeviceClass parent_class; + + /* public */ + MemoryRegion *(*get_memory_region)(PCDIMMDevice *dimm); +} PCDIMMDeviceClass; + +uint64_t pc_dimm_get_free_addr(uint64_t address_space_start, + uint64_t address_space_size, + uint64_t *hint, uint64_t size, + Error **errp); + +int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp); + +int qmp_pc_dimm_device_list(Object *obj, void *opaque); +#endif diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h new file mode 100644 index 0000000..d31768a --- /dev/null +++ b/include/hw/virtio/vhost-backend.h @@ -0,0 +1,38 @@ +/* + * vhost-backend + * + * Copyright (c) 2013 Virtual Open Systems Sarl. + * + * 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 VHOST_BACKEND_H_ +#define VHOST_BACKEND_H_ + +typedef enum VhostBackendType { + VHOST_BACKEND_TYPE_NONE = 0, + VHOST_BACKEND_TYPE_KERNEL = 1, + VHOST_BACKEND_TYPE_USER = 2, + VHOST_BACKEND_TYPE_MAX = 3, +} VhostBackendType; + +struct vhost_dev; + +typedef int (*vhost_call)(struct vhost_dev *dev, unsigned long int request, + void *arg); +typedef int (*vhost_backend_init)(struct vhost_dev *dev, void *opaque); +typedef int (*vhost_backend_cleanup)(struct vhost_dev *dev); + +typedef struct VhostOps { + VhostBackendType backend_type; + vhost_call vhost_call; + vhost_backend_init vhost_backend_init; + vhost_backend_cleanup vhost_backend_cleanup; +} VhostOps; + +int vhost_set_backend_type(struct vhost_dev *dev, + VhostBackendType backend_type); + +#endif /* VHOST_BACKEND_H_ */ diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h index de24746..33028ec 100644 --- a/include/hw/virtio/vhost.h +++ b/include/hw/virtio/vhost.h @@ -2,6 +2,7 @@ #define VHOST_H #include "hw/hw.h" +#include "hw/virtio/vhost-backend.h" #include "hw/virtio/virtio.h" #include "exec/memory.h" @@ -25,11 +26,11 @@ typedef unsigned long vhost_log_chunk_t; #define VHOST_LOG_PAGE 0x1000 #define VHOST_LOG_BITS (8 * sizeof(vhost_log_chunk_t)) #define VHOST_LOG_CHUNK (VHOST_LOG_PAGE * VHOST_LOG_BITS) +#define VHOST_INVALID_FEATURE_BIT (0xff) struct vhost_memory; struct vhost_dev { MemoryListener memory_listener; - int control; struct vhost_memory *mem; int n_mem_sections; MemoryRegionSection *mem_sections; @@ -48,10 +49,12 @@ struct vhost_dev { bool memory_changed; hwaddr mem_changed_start_addr; hwaddr mem_changed_end_addr; + const VhostOps *vhost_ops; + void *opaque; }; -int vhost_dev_init(struct vhost_dev *hdev, int devfd, const char *devpath, - bool force); +int vhost_dev_init(struct vhost_dev *hdev, void *opaque, + VhostBackendType backend_type, bool force); void vhost_dev_cleanup(struct vhost_dev *hdev); bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev); int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev); @@ -68,4 +71,8 @@ bool vhost_virtqueue_pending(struct vhost_dev *hdev, int n); */ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n, bool mask); +unsigned vhost_get_features(struct vhost_dev *hdev, const int *feature_bits, + unsigned features); +void vhost_ack_features(struct vhost_dev *hdev, const int *feature_bits, + unsigned features); #endif diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h index 4b32440..f7fccc0 100644 --- a/include/hw/virtio/virtio-net.h +++ b/include/hw/virtio/virtio-net.h @@ -49,12 +49,14 @@ #define VIRTIO_NET_F_CTRL_RX 18 /* Control channel RX mode support */ #define VIRTIO_NET_F_CTRL_VLAN 19 /* Control channel VLAN filtering */ #define VIRTIO_NET_F_CTRL_RX_EXTRA 20 /* Extra RX mode control support */ +#define VIRTIO_NET_F_GUEST_ANNOUNCE 21 /* Guest can announce itself */ #define VIRTIO_NET_F_MQ 22 /* Device supports Receive Flow * Steering */ #define VIRTIO_NET_F_CTRL_MAC_ADDR 23 /* Set MAC address */ #define VIRTIO_NET_S_LINK_UP 1 /* Link is up */ +#define VIRTIO_NET_S_ANNOUNCE 2 /* Announcement is needed */ #define TX_TIMER_INTERVAL 150000 /* 150 us */ @@ -193,6 +195,8 @@ typedef struct VirtIONet { char *netclient_name; char *netclient_type; uint64_t curr_guest_offloads; + QEMUTimer *announce_timer; + int announce_counter; } VirtIONet; #define VIRTIO_NET_CTRL_MAC 1 @@ -213,6 +217,18 @@ typedef struct VirtIONet { #define VIRTIO_NET_CTRL_VLAN_DEL 1 /* + * Control link announce acknowledgement + * + * VIRTIO_NET_S_ANNOUNCE bit in the status field requests link announcement from + * guest driver. The driver is notified by config space change interrupt. The + * command VIRTIO_NET_CTRL_ANNOUNCE_ACK is used to indicate that the driver has + * received the notification. It makes the device clear the bit + * VIRTIO_NET_S_ANNOUNCE in the status field. + */ +#define VIRTIO_NET_CTRL_ANNOUNCE 3 + #define VIRTIO_NET_CTRL_ANNOUNCE_ACK 0 + +/* * Control Multiqueue * * The command VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET @@ -251,6 +267,7 @@ struct virtio_net_ctrl_mq { DEFINE_PROP_BIT("guest_tso6", _state, _field, VIRTIO_NET_F_GUEST_TSO6, true), \ DEFINE_PROP_BIT("guest_ecn", _state, _field, VIRTIO_NET_F_GUEST_ECN, true), \ DEFINE_PROP_BIT("guest_ufo", _state, _field, VIRTIO_NET_F_GUEST_UFO, true), \ + DEFINE_PROP_BIT("guest_announce", _state, _field, VIRTIO_NET_F_GUEST_ANNOUNCE, true), \ DEFINE_PROP_BIT("host_tso4", _state, _field, VIRTIO_NET_F_HOST_TSO4, true), \ DEFINE_PROP_BIT("host_tso6", _state, _field, VIRTIO_NET_F_HOST_TSO6, true), \ DEFINE_PROP_BIT("host_ecn", _state, _field, VIRTIO_NET_F_HOST_ECN, true), \ |