From 3e996cc58334be1c3f1be524b4f048566eccbb1d Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Fri, 29 Jan 2016 13:18:56 +0000 Subject: Fix virtio migration I misunderstood the vmstate macro definition when I reworked the virtio .get/.put. The VMSTATE_STRUCT_VARRAY_KNOWN, was described as being for "a variable length array (i.e. _type *_field) but we know the length". However it actually specified operation for arrays embedded in the struct (i.e. _type _field[]) since it lacked the VMS_POINTER flag. This caused offset calculation to be completely off, examining and potentially sending random data instead of the VirtQueue content. Replace the otherwise unused VMSTATE_STRUCT_VARRAY_KNOWN with a VMSTATE_STRUCT_VARRAY_POINTER_KNOWN that includes the VMS_POINTER flag (so now actually doing what it advertises) and use it in the virtio migration code. Fixes and description as per Sascha's suggestions/debug. Signed-off-by: Dr. David Alan Gilbert Reported-by: Sascha Silbe Tested-By: Sascha Silbe Reviewed-By: Sascha Silbe Fixes: 50e5ae4dc3e4f21e874512f9e87b93b5472d26e0 Fixes: 2cf0148674430b6693c60d42b7eef721bfa9509f Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Tested-by: Cornelia Huck --- include/migration/vmstate.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index a4b81bb..7246f29 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -386,26 +386,26 @@ extern const VMStateInfo vmstate_info_bitmap; .offset = vmstate_offset_array(_state, _field, _type, _num),\ } -/* a variable length array (i.e. _type *_field) but we know the - * length - */ -#define VMSTATE_STRUCT_VARRAY_KNOWN(_field, _state, _num, _version, _vmsd, _type) { \ +#define VMSTATE_STRUCT_VARRAY_UINT8(_field, _state, _field_num, _version, _vmsd, _type) { \ .name = (stringify(_field)), \ - .num = (_num), \ + .num_offset = vmstate_offset_value(_state, _field_num, uint8_t), \ .version_id = (_version), \ .vmsd = &(_vmsd), \ .size = sizeof(_type), \ - .flags = VMS_STRUCT|VMS_ARRAY, \ + .flags = VMS_STRUCT|VMS_VARRAY_UINT8, \ .offset = offsetof(_state, _field), \ } -#define VMSTATE_STRUCT_VARRAY_UINT8(_field, _state, _field_num, _version, _vmsd, _type) { \ +/* a variable length array (i.e. _type *_field) but we know the + * length + */ +#define VMSTATE_STRUCT_VARRAY_POINTER_KNOWN(_field, _state, _num, _version, _vmsd, _type) { \ .name = (stringify(_field)), \ - .num_offset = vmstate_offset_value(_state, _field_num, uint8_t), \ + .num = (_num), \ .version_id = (_version), \ .vmsd = &(_vmsd), \ .size = sizeof(_type), \ - .flags = VMS_STRUCT|VMS_VARRAY_UINT8, \ + .flags = VMS_STRUCT|VMS_ARRAY|VMS_POINTER, \ .offset = offsetof(_state, _field), \ } -- cgit v1.1 From 6aa46d8ff1ee7e9ca0c4a54d75c74108bee22124 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Sun, 31 Jan 2016 11:28:57 +0100 Subject: virtio: move VirtQueueElement at the beginning of the structs The next patch will make virtqueue_pop/vring_pop allocate memory for the VirtQueueElement. In some cases (blk, scsi, gpu) the device wants to extend VirtQueueElement with device-specific fields and, until now, the place of the VirtQueueElement within the containing struct didn't matter. When allocating the entire block in virtqueue_pop/vring_pop, however, the containing struct must basically be a "subclass" of VirtQueueElement, with the VirtQueueElement as the first field. Make that the case for blk and scsi; gpu is already doing it. Signed-off-by: Paolo Bonzini Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Cornelia Huck --- include/hw/virtio/virtio-blk.h | 2 +- include/hw/virtio/virtio-scsi.h | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h index ae11a63..403ab86 100644 --- a/include/hw/virtio/virtio-blk.h +++ b/include/hw/virtio/virtio-blk.h @@ -60,9 +60,9 @@ typedef struct VirtIOBlock { } VirtIOBlock; typedef struct VirtIOBlockReq { + VirtQueueElement elem; int64_t sector_num; VirtIOBlock *dev; - VirtQueueElement elem; struct virtio_blk_inhdr *in; struct virtio_blk_outhdr out; QEMUIOVector qiov; diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h index 0394eb2..eb9d25b 100644 --- a/include/hw/virtio/virtio-scsi.h +++ b/include/hw/virtio/virtio-scsi.h @@ -112,18 +112,17 @@ typedef struct VirtIOSCSI { } VirtIOSCSI; typedef struct VirtIOSCSIReq { + /* Note: + * - fields up to resp_iov are initialized by virtio_scsi_init_req; + * - fields starting at vring are zeroed by virtio_scsi_init_req. + * */ + VirtQueueElement elem; + VirtIOSCSI *dev; VirtQueue *vq; QEMUSGList qsgl; QEMUIOVector resp_iov; - /* Note: - * - fields before elem are initialized by virtio_scsi_init_req; - * - elem is uninitialized at the time of allocation. - * - fields after elem are zeroed by virtio_scsi_init_req. - * */ - - VirtQueueElement elem; /* Set by dataplane code. */ VirtIOSCSIVring *vring; -- cgit v1.1 From 51b19ebe4320f3dcd93cea71235c1219318ddfd2 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 4 Feb 2016 16:26:51 +0200 Subject: virtio: move allocation to virtqueue_pop/vring_pop The return code of virtqueue_pop/vring_pop is unused except to check for errors or 0. We can thus easily move allocation inside the functions and just return a pointer to the VirtQueueElement. The advantage is that we will be able to allocate only the space that is needed for the actual size of the s/g list instead of the full VIRTQUEUE_MAX_SIZE items. Currently VirtQueueElement takes about 48K of memory, and this kind of allocation puts a lot of stress on malloc. By cutting the size by two or three orders of magnitude, malloc can use much more efficient algorithms. The patch is pretty large, but changes to each device are testable more or less independently. Splitting it would mostly add churn. Signed-off-by: Paolo Bonzini Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Cornelia Huck --- include/hw/virtio/dataplane/vring.h | 2 +- include/hw/virtio/virtio-balloon.h | 2 +- include/hw/virtio/virtio-blk.h | 3 +-- include/hw/virtio/virtio-net.h | 2 +- include/hw/virtio/virtio-scsi.h | 2 +- include/hw/virtio/virtio-serial.h | 2 +- include/hw/virtio/virtio.h | 2 +- 7 files changed, 7 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/hw/virtio/dataplane/vring.h b/include/hw/virtio/dataplane/vring.h index a596e4c..e80985e 100644 --- a/include/hw/virtio/dataplane/vring.h +++ b/include/hw/virtio/dataplane/vring.h @@ -44,7 +44,7 @@ void vring_teardown(Vring *vring, VirtIODevice *vdev, int n); void vring_disable_notification(VirtIODevice *vdev, Vring *vring); bool vring_enable_notification(VirtIODevice *vdev, Vring *vring); bool vring_should_notify(VirtIODevice *vdev, Vring *vring); -int vring_pop(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem); +void *vring_pop(VirtIODevice *vdev, Vring *vring, size_t sz); void vring_push(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem, int len); diff --git a/include/hw/virtio/virtio-balloon.h b/include/hw/virtio/virtio-balloon.h index 09c2ce4..35f62ac 100644 --- a/include/hw/virtio/virtio-balloon.h +++ b/include/hw/virtio/virtio-balloon.h @@ -37,7 +37,7 @@ typedef struct VirtIOBalloon { uint32_t num_pages; uint32_t actual; uint64_t stats[VIRTIO_BALLOON_S_NR]; - VirtQueueElement stats_vq_elem; + VirtQueueElement *stats_vq_elem; size_t stats_vq_offset; QEMUTimer *stats_timer; int64_t stats_last_update; diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h index 403ab86..199bb0e 100644 --- a/include/hw/virtio/virtio-blk.h +++ b/include/hw/virtio/virtio-blk.h @@ -80,8 +80,7 @@ typedef struct MultiReqBuffer { bool is_write; } MultiReqBuffer; -VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s); - +void virtio_blk_init_request(VirtIOBlock *s, VirtIOBlockReq *req); void virtio_blk_free_request(VirtIOBlockReq *req); void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb); diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h index f3cc25f..2ce3b03 100644 --- a/include/hw/virtio/virtio-net.h +++ b/include/hw/virtio/virtio-net.h @@ -47,7 +47,7 @@ typedef struct VirtIONetQueue { QEMUBH *tx_bh; int tx_waiting; struct { - VirtQueueElement elem; + VirtQueueElement *elem; } async_tx; struct VirtIONet *n; } VirtIONetQueue; diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h index eb9d25b..a8029aa 100644 --- a/include/hw/virtio/virtio-scsi.h +++ b/include/hw/virtio/virtio-scsi.h @@ -160,7 +160,7 @@ void virtio_scsi_common_unrealize(DeviceState *dev, Error **errp); void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req); bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req); void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req); -VirtIOSCSIReq *virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq); +void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq *req); void virtio_scsi_free_req(VirtIOSCSIReq *req); void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev, uint32_t event, uint32_t reason); diff --git a/include/hw/virtio/virtio-serial.h b/include/hw/virtio/virtio-serial.h index 527d0bf..12a55a1 100644 --- a/include/hw/virtio/virtio-serial.h +++ b/include/hw/virtio/virtio-serial.h @@ -122,7 +122,7 @@ struct VirtIOSerialPort { * element popped and continue consuming it once the backend * becomes writable again. */ - VirtQueueElement elem; + VirtQueueElement *elem; /* * The index and the offset into the iov buffer that was popped in diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 205fadf..21fda17 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -152,7 +152,7 @@ void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem, unsigned int len, unsigned int idx); void virtqueue_map(VirtQueueElement *elem); -int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem); +void *virtqueue_pop(VirtQueue *vq, size_t sz); int virtqueue_avail_bytes(VirtQueue *vq, unsigned int in_bytes, unsigned int out_bytes); void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes, -- cgit v1.1 From ab281c1781add112a257c15924d670616a99c41a Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Sun, 31 Jan 2016 11:28:59 +0100 Subject: virtio: introduce qemu_get/put_virtqueue_element Move allocation to virtio functions also when loading/saving a VirtQueueElement. This will also let the load/save functions keep backwards compatibility when the VirtQueueElement layout is changed. Reviewed-by: Cornelia Huck Signed-off-by: Paolo Bonzini Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/virtio/virtio.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 21fda17..44da9a8 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -153,6 +153,8 @@ void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem, void virtqueue_map(VirtQueueElement *elem); void *virtqueue_pop(VirtQueue *vq, size_t sz); +void *qemu_get_virtqueue_element(QEMUFile *f, size_t sz); +void qemu_put_virtqueue_element(QEMUFile *f, VirtQueueElement *elem); int virtqueue_avail_bytes(VirtQueue *vq, unsigned int in_bytes, unsigned int out_bytes); void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes, -- cgit v1.1 From 3724650db07057333879484c8bc7d900b5c1bf8e Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Sun, 31 Jan 2016 11:29:00 +0100 Subject: virtio: introduce virtqueue_alloc_element Allocate the arrays for in_addr/out_addr/in_sg/out_sg outside the VirtQueueElement. For now, virtqueue_pop and vring_pop keep allocating a very large VirtQueueElement. Reviewed-by: Cornelia Huck Signed-off-by: Paolo Bonzini Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/virtio/virtio.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 44da9a8..108cdb0 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -46,10 +46,10 @@ typedef struct VirtQueueElement unsigned int index; unsigned int out_num; unsigned int in_num; - hwaddr in_addr[VIRTQUEUE_MAX_SIZE]; - hwaddr out_addr[VIRTQUEUE_MAX_SIZE]; - struct iovec in_sg[VIRTQUEUE_MAX_SIZE]; - struct iovec out_sg[VIRTQUEUE_MAX_SIZE]; + hwaddr *in_addr; + hwaddr *out_addr; + struct iovec *in_sg; + struct iovec *out_sg; } VirtQueueElement; #define VIRTIO_QUEUE_MAX 1024 @@ -143,6 +143,7 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, void virtio_del_queue(VirtIODevice *vdev, int n); +void *virtqueue_alloc_element(size_t sz, unsigned out_num, unsigned in_num); void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem, unsigned int len); void virtqueue_flush(VirtQueue *vq, unsigned int count); -- cgit v1.1 From a2295f0a5871e2b9d8ea24bc3a1d2e02bda6ef2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 25 Jan 2016 15:07:31 +0100 Subject: ipmi: introduce a struct ipmi_sdr_compact MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, sdr attributes are identified using byte offsets and this can be a bit confusing. This patch adds a struct ipmi_sdr_compact conforming to the IPMI specs and replaces byte offsets with names. It also introduces and uses a struct ipmi_sdr_header in sections of the code where no assumption is made on the type of SDR. This leave rooms to potential usage of other types in the future. Signed-off-by: Cédric Le Goater Acked-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/ipmi/ipmi.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'include') diff --git a/include/hw/ipmi/ipmi.h b/include/hw/ipmi/ipmi.h index 32bac0f..74a2b5a 100644 --- a/include/hw/ipmi/ipmi.h +++ b/include/hw/ipmi/ipmi.h @@ -210,4 +210,49 @@ IPMIFwInfo *ipmi_next_fwinfo(IPMIFwInfo *current); #define ipmi_debug(fs, ...) #endif +struct ipmi_sdr_header { + uint8_t rec_id[2]; + uint8_t sdr_version; /* 0x51 */ + uint8_t rec_type; + uint8_t rec_length; +}; +#define IPMI_SDR_HEADER_SIZE sizeof(struct ipmi_sdr_header) + +#define ipmi_sdr_recid(sdr) ((sdr)->rec_id[0] | ((sdr)->rec_id[1] << 8)) +#define ipmi_sdr_length(sdr) ((sdr)->rec_length + IPMI_SDR_HEADER_SIZE) + +/* + * 43.2 SDR Type 02h. Compact Sensor Record + */ +#define IPMI_SDR_COMPACT_TYPE 2 + +struct ipmi_sdr_compact { + struct ipmi_sdr_header header; + + uint8_t sensor_owner_id; + uint8_t sensor_owner_lun; + uint8_t sensor_owner_number; /* byte 8 */ + uint8_t entity_id; + uint8_t entity_instance; + uint8_t sensor_init; + uint8_t sensor_caps; + uint8_t sensor_type; + uint8_t reading_type; + uint8_t assert_mask[2]; /* byte 16 */ + uint8_t deassert_mask[2]; + uint8_t discrete_mask[2]; + uint8_t sensor_unit1; + uint8_t sensor_unit2; + uint8_t sensor_unit3; + uint8_t sensor_direction[2]; /* byte 24 */ + uint8_t positive_threshold; + uint8_t negative_threshold; + uint8_t reserved[3]; + uint8_t oem; + uint8_t id_str_len; /* byte 32 */ + uint8_t id_string[16]; +}; + +typedef uint8_t ipmi_sdr_compact_buffer[sizeof(struct ipmi_sdr_compact)]; + #endif -- cgit v1.1 From 281b104702af40b08b29b621995830c0c0177a41 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 11 Dec 2015 16:42:22 -0200 Subject: pc: Move PcGuestInfo declaration to top of file The struct will be used inside PCMachineState. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Marcel Apfelbaum --- include/hw/i386/pc.h | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'include') diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 65e8f24..212eb7d 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -33,6 +33,22 @@ #define kvm_ioapic_in_kernel() 0 #endif +/* Machine info for ACPI build: */ +struct PcGuestInfo { + bool isapc_ram_fw; + hwaddr ram_size, ram_size_below_4g; + unsigned apic_id_limit; + bool apic_xrupt_override; + uint64_t numa_nodes; + uint64_t *node_mem; + uint64_t *node_cpu; + FWCfgState *fw_cfg; + int legacy_acpi_table_size; + bool has_acpi_build; + bool has_reserved_memory; + bool rsdp_in_ram; +}; + /** * PCMachineState: * @acpi_dev: link to ACPI PM device that performs ACPI hotplug handling @@ -151,21 +167,6 @@ typedef struct PcPciInfo { #define ACPI_PM_PROP_GPE0_BLK_LEN "gpe0_blk_len" #define ACPI_PM_PROP_TCO_ENABLED "enable_tco" -struct PcGuestInfo { - bool isapc_ram_fw; - hwaddr ram_size, ram_size_below_4g; - unsigned apic_id_limit; - bool apic_xrupt_override; - uint64_t numa_nodes; - uint64_t *node_mem; - uint64_t *node_cpu; - FWCfgState *fw_cfg; - int legacy_acpi_table_size; - bool has_acpi_build; - bool has_reserved_memory; - bool rsdp_in_ram; -}; - /* parallel.c */ void parallel_hds_isa_init(ISABus *bus, int n); -- cgit v1.1 From 9ebeed0c1efe4994c7c129e8469a797bcde9f81a Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 11 Dec 2015 16:42:23 -0200 Subject: pc: Eliminate struct PcGuestInfoState Instead of allocating a new struct just for PcGuestInfo and the mchine_done Notifier, place them inside PCMachineState. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Marcel Apfelbaum --- include/hw/i386/pc.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 212eb7d..9d0b004 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -61,6 +61,8 @@ struct PCMachineState { /* State for other subsystems/APIs: */ MemoryHotplugState hotplug_memory; + PcGuestInfo acpi_guest_info; + Notifier machine_done; /* Pointers to devices and objects: */ HotplugHandler *acpi_dev; -- cgit v1.1 From 5934e2169a383cdb059f8ccd83f7e1c4d410c9b3 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 11 Dec 2015 16:42:24 -0200 Subject: pc: Simplify pc_memory_init() signature We can get the PcGuestInfo struct directly from PCMachineState, and the return value is not needed at all. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Marcel Apfelbaum --- include/hw/i386/pc.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 9d0b004..5b21d01 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -250,11 +250,10 @@ void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory, FWCfgState *xen_load_linux(PCMachineState *pcms, PcGuestInfo *guest_info); -FWCfgState *pc_memory_init(PCMachineState *pcms, - MemoryRegion *system_memory, - MemoryRegion *rom_memory, - MemoryRegion **ram_memory, - PcGuestInfo *guest_info); +void pc_memory_init(PCMachineState *pcms, + MemoryRegion *system_memory, + MemoryRegion *rom_memory, + MemoryRegion **ram_memory); qemu_irq pc_allocate_cpu_irq(void); DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus); void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, -- cgit v1.1 From 7bc35e0f20a1e6f1b00edc85618437a495873bbd Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 11 Dec 2015 16:42:25 -0200 Subject: pc: Simplify xen_load_linux() signature We can get the PcGuestInfo struct directly from PCMachineState, and the return value is not needed at all. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Marcel Apfelbaum --- include/hw/i386/pc.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 5b21d01..223621a 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -248,8 +248,7 @@ PcGuestInfo *pc_guest_info_init(PCMachineState *pcms); void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory, MemoryRegion *pci_address_space); -FWCfgState *xen_load_linux(PCMachineState *pcms, - PcGuestInfo *guest_info); +void xen_load_linux(PCMachineState *pcms); void pc_memory_init(PCMachineState *pcms, MemoryRegion *system_memory, MemoryRegion *rom_memory, -- cgit v1.1 From bb292f5a9b944e47fae88a20767967e7e20122b4 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 11 Dec 2015 16:42:28 -0200 Subject: pc: Remove compat fields from PcGuestInfo Remove the fields: legacy_acpi_table_size, has_acpi_build, has_reserved_memory, and rsdp_in_ram from PcGuestInfo, and let the existing code use the PCMachineClass fields directly. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Marcel Apfelbaum --- include/hw/i386/pc.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include') diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 223621a..4480409 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -43,10 +43,6 @@ struct PcGuestInfo { uint64_t *node_mem; uint64_t *node_cpu; FWCfgState *fw_cfg; - int legacy_acpi_table_size; - bool has_acpi_build; - bool has_reserved_memory; - bool rsdp_in_ram; }; /** -- cgit v1.1 From 5299f1c70aa7ebc89383363cd3d47fc4f5dc2163 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 11 Dec 2015 16:42:29 -0200 Subject: pc: Remove RAM size fields from PcGuestInfo The ACPI code can use the PCMachineState fields directly. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Marcel Apfelbaum --- include/hw/i386/pc.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 4480409..c27e680 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -36,7 +36,6 @@ /* Machine info for ACPI build: */ struct PcGuestInfo { bool isapc_ram_fw; - hwaddr ram_size, ram_size_below_4g; unsigned apic_id_limit; bool apic_xrupt_override; uint64_t numa_nodes; -- cgit v1.1 From 5db3f0deaf165bd0ff247fcea042cb2e60671e43 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 11 Dec 2015 16:42:30 -0200 Subject: pc: Remove PcGuestInfo.isapc_ram_fw field The code can use the PCMachineClass.pci_enabled field directly. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Marcel Apfelbaum --- include/hw/i386/pc.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index c27e680..6a5c4da 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -35,7 +35,6 @@ /* Machine info for ACPI build: */ struct PcGuestInfo { - bool isapc_ram_fw; unsigned apic_id_limit; bool apic_xrupt_override; uint64_t numa_nodes; -- cgit v1.1 From f264d360e0bebf4fae054e624bf7204788aff99d Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 11 Dec 2015 16:42:31 -0200 Subject: pc: Move PcGuestInfo.fw_cfg to PCMachineState Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Marcel Apfelbaum --- include/hw/i386/pc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 6a5c4da..40249b6 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -40,7 +40,6 @@ struct PcGuestInfo { uint64_t numa_nodes; uint64_t *node_mem; uint64_t *node_cpu; - FWCfgState *fw_cfg; }; /** @@ -62,6 +61,7 @@ struct PCMachineState { HotplugHandler *acpi_dev; ISADevice *rtc; PCIBus *bus; + FWCfgState *fw_cfg; /* Configuration options: */ uint64_t max_ram_below_4g; -- cgit v1.1 From dd4c2f01ab92ae0a158958a8fc61fcd09e34987a Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 11 Dec 2015 16:42:32 -0200 Subject: pc: Move APIC and NUMA data from PcGuestInfo to PCMachineState Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Marcel Apfelbaum --- include/hw/i386/pc.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 40249b6..0cf67ed 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -35,11 +35,6 @@ /* Machine info for ACPI build: */ struct PcGuestInfo { - unsigned apic_id_limit; - bool apic_xrupt_override; - uint64_t numa_nodes; - uint64_t *node_mem; - uint64_t *node_cpu; }; /** @@ -71,6 +66,15 @@ struct PCMachineState { /* RAM information (sizes, addresses, configuration): */ ram_addr_t below_4g_mem_size, above_4g_mem_size; + + /* CPU and apic information: */ + bool apic_xrupt_override; + unsigned apic_id_limit; + + /* NUMA information: */ + uint64_t numa_nodes; + uint64_t *node_mem; + uint64_t *node_cpu; }; #define PC_MACHINE_ACPI_DEVICE_PROP "acpi-device" -- cgit v1.1 From e4e8ba04c2007d3d05d8a29857f95ae80951f5a3 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 11 Dec 2015 16:42:33 -0200 Subject: pc: Eliminate PcGuestInfo struct The struct is not used for anything, now. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/i386/pc.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'include') diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 0cf67ed..8b3546e 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -33,10 +33,6 @@ #define kvm_ioapic_in_kernel() 0 #endif -/* Machine info for ACPI build: */ -struct PcGuestInfo { -}; - /** * PCMachineState: * @acpi_dev: link to ACPI PM device that performs ACPI hotplug handling @@ -49,7 +45,6 @@ struct PCMachineState { /* State for other subsystems/APIs: */ MemoryHotplugState hotplug_memory; - PcGuestInfo acpi_guest_info; Notifier machine_done; /* Pointers to devices and objects: */ @@ -233,7 +228,7 @@ void pc_cpus_init(PCMachineState *pcms); void pc_hot_add_cpu(const int64_t id, Error **errp); void pc_acpi_init(const char *default_dsdt); -PcGuestInfo *pc_guest_info_init(PCMachineState *pcms); +void pc_guest_info_init(PCMachineState *pcms); #define PCI_HOST_PROP_PCI_HOLE_START "pci-hole-start" #define PCI_HOST_PROP_PCI_HOLE_END "pci-hole-end" -- cgit v1.1 From 37ad223c515da2fe9f1c679768cb5ccaa42e57e1 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Mon, 18 Jan 2016 15:12:10 +0100 Subject: acpi: take oem_id in build_header(), optionally This patch is the continuation of commit 8870ca0e94f2 ("acpi: support specified oem table id for build_header"). It will allow us to control the OEM ID field too in the SDT header. Cc: "Michael S. Tsirkin" (supporter:ACPI/SMBIOS) Cc: Igor Mammedov (supporter:ACPI/SMBIOS) Cc: Xiao Guangrong (maintainer:NVDIMM) Cc: Shannon Zhao (maintainer:ARM ACPI Subsystem) Cc: Paolo Bonzini (maintainer:X86) Cc: Richard W.M. Jones Cc: Aleksei Kovura Cc: Michael Tokarev Cc: Steven Newbury RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1248758 LP: https://bugs.launchpad.net/qemu/+bug/1533848 Signed-off-by: Laszlo Ersek Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Shannon Zhao --- include/hw/acpi/aml-build.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 6d6f705..c460bdd 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -357,7 +357,7 @@ Aml *aml_sizeof(Aml *arg); void build_header(GArray *linker, GArray *table_data, AcpiTableHeader *h, const char *sig, int len, uint8_t rev, - const char *oem_table_id); + const char *oem_id, const char *oem_table_id); void *acpi_data_push(GArray *table_data, unsigned size); unsigned acpi_data_len(GArray *table); void acpi_add_table(GArray *table_offsets, GArray *table_data); -- cgit v1.1 From 5151355898699eb66fad0a710b8b6011690a0dfc Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Mon, 18 Jan 2016 15:12:11 +0100 Subject: acpi: expose oem_id and oem_table_id in build_rsdt() Since build_rsdt() is implemented as common utility code (in "hw/acpi/aml-build.c"), it should expose -- and forward -- the oem_id and oem_table_id parameters between board code and the generic build_header() function. Cc: "Michael S. Tsirkin" (supporter:ACPI/SMBIOS) Cc: Igor Mammedov (supporter:ACPI/SMBIOS) Cc: Shannon Zhao (maintainer:ARM ACPI Subsystem) Cc: Paolo Bonzini (maintainer:X86) Cc: Richard W.M. Jones Cc: Aleksei Kovura Cc: Michael Tokarev Cc: Steven Newbury RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1248758 LP: https://bugs.launchpad.net/qemu/+bug/1533848 Signed-off-by: Laszlo Ersek Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Shannon Zhao --- include/hw/acpi/aml-build.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index c460bdd..aa29d30 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -364,6 +364,7 @@ void acpi_add_table(GArray *table_offsets, GArray *table_data); void acpi_build_tables_init(AcpiBuildTables *tables); void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre); void -build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets); +build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets, + const char *oem_id, const char *oem_table_id); #endif -- cgit v1.1 From 88594e4fd1e916b778968b2bdd8d7375ca2fe8d8 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Mon, 18 Jan 2016 15:12:12 +0100 Subject: acpi: add function to extract oem_id and oem_table_id from the user's SLIC The acpi_get_slic_oem() function stores pointers to these fields in the (first) SLIC table that the user passes in with the -acpitable switch. Cc: "Michael S. Tsirkin" (supporter:ACPI/SMBIOS) Cc: Igor Mammedov (supporter:ACPI/SMBIOS) Cc: Richard W.M. Jones Cc: Aleksei Kovura Cc: Michael Tokarev Cc: Steven Newbury RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1248758 LP: https://bugs.launchpad.net/qemu/+bug/1533848 Signed-off-by: Laszlo Ersek Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Steven Newbury --- include/hw/acpi/acpi.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include') diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h index b20bd55..2de3021 100644 --- a/include/hw/acpi/acpi.h +++ b/include/hw/acpi/acpi.h @@ -196,4 +196,11 @@ unsigned acpi_table_len(void *current); void acpi_table_add(const QemuOpts *opts, Error **errp); void acpi_table_add_builtin(const QemuOpts *opts, Error **errp); +typedef struct AcpiSlicOem AcpiSlicOem; +struct AcpiSlicOem { + char *id; + char *table_id; +}; +int acpi_get_slic_oem(AcpiSlicOem *oem); + #endif /* !QEMU_HW_ACPI_H */ -- cgit v1.1 From adcb4ee660cf579f003e9d4afd61b608259091c6 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 21 Jan 2016 12:37:51 +1100 Subject: dimm: Correct type of MemoryHotplugState->base The 'base' field of MemoryHotplugState is ram_addr_t, which indicates that it exists in the abstract address space of RAM regions. However, the actual usage of this field indicates that it is a concrete physical address (it's passed as an offset to memory_region_add_subgregion for example). So, correct its type to 'hwaddr'. Signed-off-by: David Gibson Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Igor Mammedov Acked-by: Eduardo Habkost --- include/hw/mem/pc-dimm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h index d83bf30..218dfb0 100644 --- a/include/hw/mem/pc-dimm.h +++ b/include/hw/mem/pc-dimm.h @@ -77,7 +77,7 @@ typedef struct PCDIMMDeviceClass { * @mr: hotplug memory address space container */ typedef struct MemoryHotplugState { - ram_addr_t base; + hwaddr base; MemoryRegion mr; } MemoryHotplugState; -- cgit v1.1 From d66b969b0d9c8eefdcbff4b48535b0fe1501d139 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Thu, 14 Jan 2016 00:47:24 -0500 Subject: intel_iommu: large page support Current intel_iommu only supports 4K page which may not be sufficient to cover guest working set. This patch tries to enable 2M and 1G mapping for intel_iommu. This is also useful for future device IOTLB implementation to have a better hit rate. Major work is adding a page mask field on IOTLB entry to make it support large page. And also use the slpte level as key to do IOTLB lookup. MAMV was increased to 18 to support direct invalidation for 1G mapping. Cc: Michael S. Tsirkin Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Signed-off-by: Jason Wang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/i386/intel_iommu.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index 5dbadb7..b024ffa 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -83,6 +83,7 @@ struct VTDIOTLBEntry { uint64_t gfn; uint16_t domain_id; uint64_t slpte; + uint64_t mask; bool read_flags; bool write_flags; }; -- cgit v1.1 From 428c3ece97179557f2753071fb0ca97a03437267 Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Wed, 13 Jan 2016 14:59:09 +0000 Subject: fix MSI injection on Xen On Xen MSIs can be remapped into pirqs, which are a type of event channels. It's mostly for the benefit of PCI passthrough devices, to avoid the overhead of interacting with the emulated lapic. However remapping interrupts and MSIs is also supported for emulated devices, such as the e1000 and virtio-net. When an interrupt or an MSI is remapped into a pirq, masking and unmasking is done by masking and unmasking the event channel. The masking bit on the PCI config space or MSI-X table should be ignored, but it isn't at the moment. As a consequence emulated devices which use MSI or MSI-X, such as virtio-net, don't work properly (the guest doesn't receive any notifications). The mechanism was working properly when xen_apic was introduced, but I haven't narrowed down which commit in particular is causing the regression. Fix the issue by ignoring the masking bit for MSI and MSI-X which have been remapped into pirqs. Signed-off-by: Stefano Stabellini Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/xen/xen.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h index 1b81b4b..c577354 100644 --- a/include/hw/xen/xen.h +++ b/include/hw/xen/xen.h @@ -33,6 +33,7 @@ int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num); void xen_piix3_set_irq(void *opaque, int irq_num, int level); void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len); void xen_hvm_inject_msi(uint64_t addr, uint32_t data); +int xen_is_pirq_msi(uint32_t msi_data); qemu_irq *xen_interrupt_controller_init(void); -- cgit v1.1