pc, pci, virtio: new features, cleanups, fixes
- interrupt remapping for intel iommus - a bunch of virtio cleanups - fixes all over the place Signed-off-by: Michael S. Tsirkin <mst@redhat.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJXkQsqAAoJECgfDbjSjVRpanoIAJ9JVlc1aEjt9sa0cSBcs+NQ J7JmgU9FqFsj+4FrNTouO3AxTjHurd1UAULP1WMPD+V3JpbnHct8r6SCBLQ5EBMN VOjYo4DwWs1g+DqnQ9WZmbadu06XvYi/yiAKNUzWfZk0MR11D0D/S5hmarNKw0Kq tGHeTWjGeY4WqFLV7m+qB4+cqkAByn6um99UtUvgLL05RgIEIP2IEMKYZ+rXvAa9 iGUvzqlO7mbq/+LbL18kaWywa4TCwbbd2eSGWaqhX4CuB62Rl33mWTXFcfaYhkyp Z3FgwaJ09h0lAjSVEbyAuLFMfO/BnMcsoKqwl4xc4vkn/xBCqFtgH9JcEVm3O8U= =ge2D -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging pc, pci, virtio: new features, cleanups, fixes - interrupt remapping for intel iommus - a bunch of virtio cleanups - fixes all over the place Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Thu 21 Jul 2016 18:49:30 BST # gpg: using RSA key 0x281F0DB8D28D5469 # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" # Primary key fingerprint: 0270 606B 6F3C DF3D 0B17 0970 C350 3912 AFBE 8E67 # Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA 8A0D 281F 0DB8 D28D 5469 * remotes/mst/tags/for_upstream: (57 commits) intel_iommu: avoid unnamed fields virtio: Update migration docs virtio-gpu: Wrap in vmstate virtio-gpu: Use migrate_add_blocker for virgl migration blocking virtio-input: Wrap in vmstate 9pfs: Wrap in vmstate virtio-serial: Wrap in vmstate virtio-net: Wrap in vmstate virtio-balloon: Wrap in vmstate virtio-rng: Wrap in vmstate virtio-blk: Wrap in vmstate virtio-scsi: Wrap in vmstate virtio: Migration helper function and macro virtio-serial: Remove old migration version support virtio-net: Remove old migration version support virtio-scsi: Replace HandleOutput typedef Revert "mirror: Workaround for unexpected iohandler events during completion" virtio-scsi: Call virtio_add_queue_aio virtio-blk: Call virtio_add_queue_aio virtio: Introduce virtio_add_queue_aio ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
206d0c2436
55 changed files with 1478 additions and 349 deletions
|
|
@ -571,6 +571,18 @@ enum {
|
|||
/*
|
||||
* Sub-structures for DMAR
|
||||
*/
|
||||
|
||||
/* Device scope structure for DRHD. */
|
||||
struct AcpiDmarDeviceScope {
|
||||
uint8_t entry_type;
|
||||
uint8_t length;
|
||||
uint16_t reserved;
|
||||
uint8_t enumeration_id;
|
||||
uint8_t bus;
|
||||
uint16_t path[0]; /* list of dev:func pairs */
|
||||
} QEMU_PACKED;
|
||||
typedef struct AcpiDmarDeviceScope AcpiDmarDeviceScope;
|
||||
|
||||
/* Type 0: Hardware Unit Definition */
|
||||
struct AcpiDmarHardwareUnit {
|
||||
uint16_t type;
|
||||
|
|
@ -579,6 +591,7 @@ struct AcpiDmarHardwareUnit {
|
|||
uint8_t reserved;
|
||||
uint16_t pci_segment; /* The PCI Segment associated with this unit */
|
||||
uint64_t address; /* Base address of remapping hardware register-set */
|
||||
AcpiDmarDeviceScope scope[0];
|
||||
} QEMU_PACKED;
|
||||
typedef struct AcpiDmarHardwareUnit AcpiDmarHardwareUnit;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#define MSI_ADDR_REDIRECTION_SHIFT 3
|
||||
|
||||
#define MSI_ADDR_DEST_ID_SHIFT 12
|
||||
#define MSI_ADDR_DEST_IDX_SHIFT 4
|
||||
#define MSI_ADDR_DEST_ID_MASK 0x00ffff0
|
||||
|
||||
#endif /* HW_APIC_MSIDEF_H */
|
||||
|
|
|
|||
|
|
@ -23,6 +23,10 @@
|
|||
#define INTEL_IOMMU_H
|
||||
#include "hw/qdev.h"
|
||||
#include "sysemu/dma.h"
|
||||
#include "hw/i386/x86-iommu.h"
|
||||
#include "hw/i386/ioapic.h"
|
||||
#include "hw/pci/msi.h"
|
||||
#include "hw/sysbus.h"
|
||||
|
||||
#define TYPE_INTEL_IOMMU_DEVICE "intel-iommu"
|
||||
#define INTEL_IOMMU_DEVICE(obj) \
|
||||
|
|
@ -34,7 +38,6 @@
|
|||
#define VTD_PCI_BUS_MAX 256
|
||||
#define VTD_PCI_SLOT_MAX 32
|
||||
#define VTD_PCI_FUNC_MAX 8
|
||||
#define VTD_PCI_DEVFN_MAX 256
|
||||
#define VTD_PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
|
||||
#define VTD_PCI_FUNC(devfn) ((devfn) & 0x07)
|
||||
#define VTD_SID_TO_BUS(sid) (((sid) >> 8) & 0xff)
|
||||
|
|
@ -44,12 +47,22 @@
|
|||
#define VTD_HOST_ADDRESS_WIDTH 39
|
||||
#define VTD_HAW_MASK ((1ULL << VTD_HOST_ADDRESS_WIDTH) - 1)
|
||||
|
||||
#define DMAR_REPORT_F_INTR (1)
|
||||
|
||||
#define VTD_MSI_ADDR_HI_MASK (0xffffffff00000000ULL)
|
||||
#define VTD_MSI_ADDR_HI_SHIFT (32)
|
||||
#define VTD_MSI_ADDR_LO_MASK (0x00000000ffffffffULL)
|
||||
|
||||
typedef struct VTDContextEntry VTDContextEntry;
|
||||
typedef struct VTDContextCacheEntry VTDContextCacheEntry;
|
||||
typedef struct IntelIOMMUState IntelIOMMUState;
|
||||
typedef struct VTDAddressSpace VTDAddressSpace;
|
||||
typedef struct VTDIOTLBEntry VTDIOTLBEntry;
|
||||
typedef struct VTDBus VTDBus;
|
||||
typedef union VTD_IR_TableEntry VTD_IR_TableEntry;
|
||||
typedef union VTD_IR_MSIAddress VTD_IR_MSIAddress;
|
||||
typedef struct VTDIrq VTDIrq;
|
||||
typedef struct VTD_MSIMessage VTD_MSIMessage;
|
||||
|
||||
/* Context-Entry */
|
||||
struct VTDContextEntry {
|
||||
|
|
@ -70,6 +83,7 @@ struct VTDAddressSpace {
|
|||
uint8_t devfn;
|
||||
AddressSpace as;
|
||||
MemoryRegion iommu;
|
||||
MemoryRegion iommu_ir; /* Interrupt region: 0xfeeXXXXX */
|
||||
IntelIOMMUState *iommu_state;
|
||||
VTDContextCacheEntry context_cache_entry;
|
||||
};
|
||||
|
|
@ -88,9 +102,155 @@ struct VTDIOTLBEntry {
|
|||
bool write_flags;
|
||||
};
|
||||
|
||||
/* VT-d Source-ID Qualifier types */
|
||||
enum {
|
||||
VTD_SQ_FULL = 0x00, /* Full SID verification */
|
||||
VTD_SQ_IGN_3 = 0x01, /* Ignore bit 3 */
|
||||
VTD_SQ_IGN_2_3 = 0x02, /* Ignore bits 2 & 3 */
|
||||
VTD_SQ_IGN_1_3 = 0x03, /* Ignore bits 1-3 */
|
||||
VTD_SQ_MAX,
|
||||
};
|
||||
|
||||
/* VT-d Source Validation Types */
|
||||
enum {
|
||||
VTD_SVT_NONE = 0x00, /* No validation */
|
||||
VTD_SVT_ALL = 0x01, /* Do full validation */
|
||||
VTD_SVT_BUS = 0x02, /* Validate bus range */
|
||||
VTD_SVT_MAX,
|
||||
};
|
||||
|
||||
/* Interrupt Remapping Table Entry Definition */
|
||||
union VTD_IR_TableEntry {
|
||||
struct {
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
uint32_t dest_id:32; /* Destination ID */
|
||||
uint32_t __reserved_1:8; /* Reserved 1 */
|
||||
uint32_t vector:8; /* Interrupt Vector */
|
||||
uint32_t irte_mode:1; /* IRTE Mode */
|
||||
uint32_t __reserved_0:3; /* Reserved 0 */
|
||||
uint32_t __avail:4; /* Available spaces for software */
|
||||
uint32_t delivery_mode:3; /* Delivery Mode */
|
||||
uint32_t trigger_mode:1; /* Trigger Mode */
|
||||
uint32_t redir_hint:1; /* Redirection Hint */
|
||||
uint32_t dest_mode:1; /* Destination Mode */
|
||||
uint32_t fault_disable:1; /* Fault Processing Disable */
|
||||
uint32_t present:1; /* Whether entry present/available */
|
||||
#else
|
||||
uint32_t present:1; /* Whether entry present/available */
|
||||
uint32_t fault_disable:1; /* Fault Processing Disable */
|
||||
uint32_t dest_mode:1; /* Destination Mode */
|
||||
uint32_t redir_hint:1; /* Redirection Hint */
|
||||
uint32_t trigger_mode:1; /* Trigger Mode */
|
||||
uint32_t delivery_mode:3; /* Delivery Mode */
|
||||
uint32_t __avail:4; /* Available spaces for software */
|
||||
uint32_t __reserved_0:3; /* Reserved 0 */
|
||||
uint32_t irte_mode:1; /* IRTE Mode */
|
||||
uint32_t vector:8; /* Interrupt Vector */
|
||||
uint32_t __reserved_1:8; /* Reserved 1 */
|
||||
uint32_t dest_id:32; /* Destination ID */
|
||||
#endif
|
||||
uint16_t source_id:16; /* Source-ID */
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
uint64_t __reserved_2:44; /* Reserved 2 */
|
||||
uint64_t sid_vtype:2; /* Source-ID Validation Type */
|
||||
uint64_t sid_q:2; /* Source-ID Qualifier */
|
||||
#else
|
||||
uint64_t sid_q:2; /* Source-ID Qualifier */
|
||||
uint64_t sid_vtype:2; /* Source-ID Validation Type */
|
||||
uint64_t __reserved_2:44; /* Reserved 2 */
|
||||
#endif
|
||||
} QEMU_PACKED irte;
|
||||
uint64_t data[2];
|
||||
};
|
||||
|
||||
#define VTD_IR_INT_FORMAT_COMPAT (0) /* Compatible Interrupt */
|
||||
#define VTD_IR_INT_FORMAT_REMAP (1) /* Remappable Interrupt */
|
||||
|
||||
/* Programming format for MSI/MSI-X addresses */
|
||||
union VTD_IR_MSIAddress {
|
||||
struct {
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
uint32_t __head:12; /* Should always be: 0x0fee */
|
||||
uint32_t index_l:15; /* Interrupt index bit 14-0 */
|
||||
uint32_t int_mode:1; /* Interrupt format */
|
||||
uint32_t sub_valid:1; /* SHV: Sub-Handle Valid bit */
|
||||
uint32_t index_h:1; /* Interrupt index bit 15 */
|
||||
uint32_t __not_care:2;
|
||||
#else
|
||||
uint32_t __not_care:2;
|
||||
uint32_t index_h:1; /* Interrupt index bit 15 */
|
||||
uint32_t sub_valid:1; /* SHV: Sub-Handle Valid bit */
|
||||
uint32_t int_mode:1; /* Interrupt format */
|
||||
uint32_t index_l:15; /* Interrupt index bit 14-0 */
|
||||
uint32_t __head:12; /* Should always be: 0x0fee */
|
||||
#endif
|
||||
} QEMU_PACKED addr;
|
||||
uint32_t data;
|
||||
};
|
||||
|
||||
/* Generic IRQ entry information */
|
||||
struct VTDIrq {
|
||||
/* Used by both IOAPIC/MSI interrupt remapping */
|
||||
uint8_t trigger_mode;
|
||||
uint8_t vector;
|
||||
uint8_t delivery_mode;
|
||||
uint32_t dest;
|
||||
uint8_t dest_mode;
|
||||
|
||||
/* only used by MSI interrupt remapping */
|
||||
uint8_t redir_hint;
|
||||
uint8_t msi_addr_last_bits;
|
||||
};
|
||||
|
||||
struct VTD_MSIMessage {
|
||||
union {
|
||||
struct {
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
uint32_t __addr_head:12; /* 0xfee */
|
||||
uint32_t dest:8;
|
||||
uint32_t __reserved:8;
|
||||
uint32_t redir_hint:1;
|
||||
uint32_t dest_mode:1;
|
||||
uint32_t __not_used:2;
|
||||
#else
|
||||
uint32_t __not_used:2;
|
||||
uint32_t dest_mode:1;
|
||||
uint32_t redir_hint:1;
|
||||
uint32_t __reserved:8;
|
||||
uint32_t dest:8;
|
||||
uint32_t __addr_head:12; /* 0xfee */
|
||||
#endif
|
||||
uint32_t __addr_hi:32;
|
||||
} QEMU_PACKED;
|
||||
uint64_t msi_addr;
|
||||
};
|
||||
union {
|
||||
struct {
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
uint16_t trigger_mode:1;
|
||||
uint16_t level:1;
|
||||
uint16_t __resved:3;
|
||||
uint16_t delivery_mode:3;
|
||||
uint16_t vector:8;
|
||||
#else
|
||||
uint16_t vector:8;
|
||||
uint16_t delivery_mode:3;
|
||||
uint16_t __resved:3;
|
||||
uint16_t level:1;
|
||||
uint16_t trigger_mode:1;
|
||||
#endif
|
||||
uint16_t __resved1:16;
|
||||
} QEMU_PACKED;
|
||||
uint32_t msi_data;
|
||||
};
|
||||
};
|
||||
|
||||
/* When IR is enabled, all MSI/MSI-X data bits should be zero */
|
||||
#define VTD_IR_MSI_DATA (0)
|
||||
|
||||
/* The iommu (DMAR) device state struct */
|
||||
struct IntelIOMMUState {
|
||||
SysBusDevice busdev;
|
||||
X86IOMMUState x86_iommu;
|
||||
MemoryRegion csrmem;
|
||||
uint8_t csr[DMAR_REG_SIZE]; /* register values */
|
||||
uint8_t wmask[DMAR_REG_SIZE]; /* R/W bytes */
|
||||
|
|
@ -123,6 +283,12 @@ struct IntelIOMMUState {
|
|||
MemoryRegionIOMMUOps iommu_ops;
|
||||
GHashTable *vtd_as_by_busptr; /* VTDBus objects indexed by PCIBus* reference */
|
||||
VTDBus *vtd_as_by_bus_num[VTD_PCI_BUS_MAX]; /* VTDBus objects indexed by bus number */
|
||||
|
||||
/* interrupt remapping */
|
||||
bool intr_enabled; /* Whether guest enabled IR */
|
||||
dma_addr_t intr_root; /* Interrupt remapping table pointer */
|
||||
uint32_t intr_size; /* Number of IR table entries */
|
||||
bool intr_eime; /* Extended interrupt mode enabled */
|
||||
};
|
||||
|
||||
/* Find the VTD Address space associated with the given bus pointer,
|
||||
|
|
|
|||
|
|
@ -25,12 +25,14 @@
|
|||
#include "hw/hw.h"
|
||||
#include "exec/memory.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "qemu/notify.h"
|
||||
|
||||
#define MAX_IOAPICS 1
|
||||
|
||||
#define IOAPIC_VERSION 0x11
|
||||
|
||||
#define IOAPIC_LVT_DEST_SHIFT 56
|
||||
#define IOAPIC_LVT_DEST_IDX_SHIFT 48
|
||||
#define IOAPIC_LVT_MASKED_SHIFT 16
|
||||
#define IOAPIC_LVT_TRIGGER_MODE_SHIFT 15
|
||||
#define IOAPIC_LVT_REMOTE_IRR_SHIFT 14
|
||||
|
|
@ -106,6 +108,7 @@ struct IOAPICCommonState {
|
|||
uint8_t ioregsel;
|
||||
uint32_t irr;
|
||||
uint64_t ioredtbl[IOAPIC_NUM_PINS];
|
||||
Notifier machine_done;
|
||||
};
|
||||
|
||||
void ioapic_reset_common(DeviceState *dev);
|
||||
|
|
|
|||
|
|
@ -72,6 +72,10 @@ struct PCMachineState {
|
|||
/* NUMA information: */
|
||||
uint64_t numa_nodes;
|
||||
uint64_t *node_mem;
|
||||
|
||||
/* Address space used by IOAPIC device. All IOAPIC interrupts
|
||||
* will be translated to MSI messages in the address space. */
|
||||
AddressSpace *ioapic_as;
|
||||
};
|
||||
|
||||
#define PC_MACHINE_ACPI_DEVICE_PROP "acpi-device"
|
||||
|
|
|
|||
100
include/hw/i386/x86-iommu.h
Normal file
100
include/hw/i386/x86-iommu.h
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Common IOMMU interface for X86 platform
|
||||
*
|
||||
* Copyright (C) 2016 Peter Xu, Red Hat <peterx@redhat.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef IOMMU_COMMON_H
|
||||
#define IOMMU_COMMON_H
|
||||
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/pci/pci.h"
|
||||
|
||||
#define TYPE_X86_IOMMU_DEVICE ("x86-iommu")
|
||||
#define X86_IOMMU_DEVICE(obj) \
|
||||
OBJECT_CHECK(X86IOMMUState, (obj), TYPE_X86_IOMMU_DEVICE)
|
||||
#define X86_IOMMU_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(X86IOMMUClass, (klass), TYPE_X86_IOMMU_DEVICE)
|
||||
#define X86_IOMMU_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(X86IOMMUClass, obj, TYPE_X86_IOMMU_DEVICE)
|
||||
|
||||
#define X86_IOMMU_PCI_DEVFN_MAX 256
|
||||
#define X86_IOMMU_SID_INVALID (0xffff)
|
||||
|
||||
typedef struct X86IOMMUState X86IOMMUState;
|
||||
typedef struct X86IOMMUClass X86IOMMUClass;
|
||||
|
||||
struct X86IOMMUClass {
|
||||
SysBusDeviceClass parent;
|
||||
/* Intel/AMD specific realize() hook */
|
||||
DeviceRealize realize;
|
||||
/* MSI-based interrupt remapping */
|
||||
int (*int_remap)(X86IOMMUState *iommu, MSIMessage *src,
|
||||
MSIMessage *dst, uint16_t sid);
|
||||
};
|
||||
|
||||
/**
|
||||
* iec_notify_fn - IEC (Interrupt Entry Cache) notifier hook,
|
||||
* triggered when IR invalidation happens.
|
||||
* @private: private data
|
||||
* @global: whether this is a global IEC invalidation
|
||||
* @index: IRTE index to invalidate (start from)
|
||||
* @mask: invalidation mask
|
||||
*/
|
||||
typedef void (*iec_notify_fn)(void *private, bool global,
|
||||
uint32_t index, uint32_t mask);
|
||||
|
||||
struct IEC_Notifier {
|
||||
iec_notify_fn iec_notify;
|
||||
void *private;
|
||||
QLIST_ENTRY(IEC_Notifier) list;
|
||||
};
|
||||
typedef struct IEC_Notifier IEC_Notifier;
|
||||
|
||||
struct X86IOMMUState {
|
||||
SysBusDevice busdev;
|
||||
bool intr_supported; /* Whether vIOMMU supports IR */
|
||||
QLIST_HEAD(, IEC_Notifier) iec_notifiers; /* IEC notify list */
|
||||
};
|
||||
|
||||
/**
|
||||
* x86_iommu_get_default - get default IOMMU device
|
||||
* @return: pointer to default IOMMU device
|
||||
*/
|
||||
X86IOMMUState *x86_iommu_get_default(void);
|
||||
|
||||
/**
|
||||
* x86_iommu_iec_register_notifier - register IEC (Interrupt Entry
|
||||
* Cache) notifiers
|
||||
* @iommu: IOMMU device to register
|
||||
* @fn: IEC notifier hook function
|
||||
* @data: notifier private data
|
||||
*/
|
||||
void x86_iommu_iec_register_notifier(X86IOMMUState *iommu,
|
||||
iec_notify_fn fn, void *data);
|
||||
|
||||
/**
|
||||
* x86_iommu_iec_notify_all - Notify IEC invalidations
|
||||
* @iommu: IOMMU device that sends the notification
|
||||
* @global: whether this is a global invalidation. If true, @index
|
||||
* and @mask are undefined.
|
||||
* @index: starting index of interrupt entry to invalidate
|
||||
* @mask: index mask for the invalidation
|
||||
*/
|
||||
void x86_iommu_iec_notify_all(X86IOMMUState *iommu, bool global,
|
||||
uint32_t index, uint32_t mask);
|
||||
|
||||
#endif
|
||||
|
|
@ -179,4 +179,12 @@ typedef struct Q35PCIHost {
|
|||
|
||||
uint64_t mch_mcfg_base(void);
|
||||
|
||||
/*
|
||||
* Arbitary but unique BNF number for IOAPIC device.
|
||||
*
|
||||
* TODO: make sure there would have no conflict with real PCI bus
|
||||
*/
|
||||
#define Q35_PSEUDO_BUS_PLATFORM (0xff)
|
||||
#define Q35_PSEUDO_DEVFN_IOAPIC (0x00)
|
||||
|
||||
#endif /* HW_Q35_H */
|
||||
|
|
|
|||
|
|
@ -805,4 +805,6 @@ extern const VMStateDescription vmstate_pci_device;
|
|||
.offset = vmstate_offset_pointer(_state, _field, PCIDevice), \
|
||||
}
|
||||
|
||||
MSIMessage pci_get_msi_message(PCIDevice *dev, int vector);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -118,6 +118,8 @@ typedef struct VirtIOGPU {
|
|||
uint32_t req_3d;
|
||||
uint32_t bytes_3d;
|
||||
} stats;
|
||||
|
||||
Error *migration_blocker;
|
||||
} VirtIOGPU;
|
||||
|
||||
extern const GraphicHwOps virtio_gpu_ops;
|
||||
|
|
|
|||
|
|
@ -121,11 +121,9 @@ typedef struct VirtIOSCSIReq {
|
|||
} req;
|
||||
} VirtIOSCSIReq;
|
||||
|
||||
typedef void (*HandleOutput)(VirtIODevice *, VirtQueue *);
|
||||
|
||||
void virtio_scsi_common_realize(DeviceState *dev, Error **errp,
|
||||
HandleOutput ctrl, HandleOutput evt,
|
||||
HandleOutput cmd);
|
||||
VirtIOHandleOutput ctrl, VirtIOHandleOutput evt,
|
||||
VirtIOHandleOutput cmd);
|
||||
|
||||
void virtio_scsi_common_unrealize(DeviceState *dev, Error **errp);
|
||||
void virtio_scsi_handle_event_vq(VirtIOSCSI *s, VirtQueue *vq);
|
||||
|
|
|
|||
|
|
@ -138,9 +138,13 @@ void virtio_cleanup(VirtIODevice *vdev);
|
|||
/* Set the child bus name. */
|
||||
void virtio_device_set_child_bus_name(VirtIODevice *vdev, char *bus_name);
|
||||
|
||||
typedef void (*VirtIOHandleOutput)(VirtIODevice *, VirtQueue *);
|
||||
|
||||
VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
|
||||
void (*handle_output)(VirtIODevice *,
|
||||
VirtQueue *));
|
||||
VirtIOHandleOutput handle_output);
|
||||
|
||||
VirtQueue *virtio_add_queue_aio(VirtIODevice *vdev, int queue_size,
|
||||
VirtIOHandleOutput handle_output);
|
||||
|
||||
void virtio_del_queue(VirtIODevice *vdev, int n);
|
||||
|
||||
|
|
@ -167,6 +171,26 @@ bool virtio_should_notify(VirtIODevice *vdev, VirtQueue *vq);
|
|||
void virtio_notify(VirtIODevice *vdev, VirtQueue *vq);
|
||||
|
||||
void virtio_save(VirtIODevice *vdev, QEMUFile *f);
|
||||
void virtio_vmstate_save(QEMUFile *f, void *opaque, size_t size);
|
||||
|
||||
#define VMSTATE_VIRTIO_DEVICE(devname, v, getf, putf) \
|
||||
static const VMStateDescription vmstate_virtio_ ## devname = { \
|
||||
.name = "virtio-" #devname , \
|
||||
.minimum_version_id = v, \
|
||||
.version_id = v, \
|
||||
.fields = (VMStateField[]) { \
|
||||
{ \
|
||||
.name = "virtio", \
|
||||
.info = &(const VMStateInfo) {\
|
||||
.name = "virtio", \
|
||||
.get = getf, \
|
||||
.put = putf, \
|
||||
}, \
|
||||
.flags = VMS_SINGLE, \
|
||||
}, \
|
||||
VMSTATE_END_OF_LIST() \
|
||||
} \
|
||||
}
|
||||
|
||||
int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id);
|
||||
|
||||
|
|
|
|||
|
|
@ -359,13 +359,18 @@ void kvm_arch_init_irq_routing(KVMState *s);
|
|||
int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
|
||||
uint64_t address, uint32_t data, PCIDevice *dev);
|
||||
|
||||
/* Notify arch about newly added MSI routes */
|
||||
int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
|
||||
int vector, PCIDevice *dev);
|
||||
/* Notify arch about released MSI routes */
|
||||
int kvm_arch_release_virq_post(int virq);
|
||||
|
||||
int kvm_arch_msi_data_to_gsi(uint32_t data);
|
||||
|
||||
int kvm_set_irq(KVMState *s, int irq, int level);
|
||||
int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg);
|
||||
|
||||
void kvm_irqchip_add_irq_route(KVMState *s, int gsi, int irqchip, int pin);
|
||||
void kvm_irqchip_commit_routes(KVMState *s);
|
||||
|
||||
void kvm_put_apic_state(DeviceState *d, struct kvm_lapic_state *kapic);
|
||||
void kvm_get_apic_state(DeviceState *d, struct kvm_lapic_state *kapic);
|
||||
|
|
@ -474,9 +479,21 @@ static inline void cpu_synchronize_post_init(CPUState *cpu)
|
|||
}
|
||||
}
|
||||
|
||||
int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg, PCIDevice *dev);
|
||||
/**
|
||||
* kvm_irqchip_add_msi_route - Add MSI route for specific vector
|
||||
* @s: KVM state
|
||||
* @vector: which vector to add. This can be either MSI/MSIX
|
||||
* vector. The function will automatically detect whether
|
||||
* MSI/MSIX is enabled, and fetch corresponding MSI
|
||||
* message.
|
||||
* @dev: Owner PCI device to add the route. If @dev is specified
|
||||
* as @NULL, an empty MSI message will be inited.
|
||||
* @return: virq (>=0) when success, errno (<0) when failed.
|
||||
*/
|
||||
int kvm_irqchip_add_msi_route(KVMState *s, int vector, PCIDevice *dev);
|
||||
int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg,
|
||||
PCIDevice *dev);
|
||||
void kvm_irqchip_commit_routes(KVMState *s);
|
||||
void kvm_irqchip_release_virq(KVMState *s, int virq);
|
||||
|
||||
int kvm_irqchip_add_adapter_route(KVMState *s, AdapterInfo *adapter);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue