qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 14/49] virtio: combine write of an entry into used ring
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
@ 2016-02-04 21:50 ` Michael S. Tsirkin
  2016-02-04 21:50 ` [Qemu-devel] [PULL 01/49] Fix virtio migration Michael S. Tsirkin
                   ` (48 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:50 UTC (permalink / raw)
  To: qemu-devel
  Cc: Cornelia Huck, Peter Maydell, Eduardo Habkost, Vincenzo Maffione,
	Paolo Bonzini

From: Vincenzo Maffione <v.maffione@gmail.com>

Fill in an element of the used ring with a single combined access to the
guest physical memory, rather than using two separated accesses.
This reduces the overhead due to expensive address translation.

Signed-off-by: Vincenzo Maffione <v.maffione@gmail.com>
Message-Id: <e4a89a767a4a92cbb6bcc551e151487eb36e1722.1450218353.git.v.maffione@gmail.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/virtio/virtio.c | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 9608358..90f2545 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -153,18 +153,15 @@ static inline uint16_t vring_get_used_event(VirtQueue *vq)
     return vring_avail_ring(vq, vq->vring.num);
 }
 
-static inline void vring_used_ring_id(VirtQueue *vq, int i, uint32_t val)
+static inline void vring_used_write(VirtQueue *vq, VRingUsedElem *uelem,
+                                    int i)
 {
     hwaddr pa;
-    pa = vq->vring.used + offsetof(VRingUsed, ring[i].id);
-    virtio_stl_phys(vq->vdev, pa, val);
-}
-
-static inline void vring_used_ring_len(VirtQueue *vq, int i, uint32_t val)
-{
-    hwaddr pa;
-    pa = vq->vring.used + offsetof(VRingUsed, ring[i].len);
-    virtio_stl_phys(vq->vdev, pa, val);
+    virtio_tswap32s(vq->vdev, &uelem->id);
+    virtio_tswap32s(vq->vdev, &uelem->len);
+    pa = vq->vring.used + offsetof(VRingUsed, ring[i]);
+    address_space_write(&address_space_memory, pa, MEMTXATTRS_UNSPECIFIED,
+                       (void *)uelem, sizeof(VRingUsedElem));
 }
 
 static uint16_t vring_used_idx(VirtQueue *vq)
@@ -273,15 +270,17 @@ void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem,
 void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
                     unsigned int len, unsigned int idx)
 {
+    VRingUsedElem uelem;
+
     trace_virtqueue_fill(vq, elem, len, idx);
 
     virtqueue_unmap_sg(vq, elem, len);
 
     idx = (idx + vq->used_idx) % vq->vring.num;
 
-    /* Get a pointer to the next entry in the used ring. */
-    vring_used_ring_id(vq, idx, elem->index);
-    vring_used_ring_len(vq, idx, len);
+    uelem.id = elem->index;
+    uelem.len = len;
+    vring_used_write(vq, &uelem, idx);
 }
 
 void virtqueue_flush(VirtQueue *vq, unsigned int count)
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations
@ 2016-02-04 21:50 Michael S. Tsirkin
  2016-02-04 21:50 ` [Qemu-devel] [PULL 14/49] virtio: combine write of an entry into used ring Michael S. Tsirkin
                   ` (49 more replies)
  0 siblings, 50 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Eduardo Habkost

The following changes since commit 382d34ff9fcc534db32d54eb82590de7c04f9b33:

  Merge remote-tracking branch 'remotes/stefanha/tags/tracing-pull-request' into staging (2016-02-03 19:00:33 +0000)

are available in the git repository at:

  git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream

for you to fetch changes up to 32db7f56a0df015362fabd73c2d43dab7196fa64:

  acpi: update expected DSDT (2016-02-04 20:54:21 +0200)

----------------------------------------------------------------
pc and misc cleanups and fixes, virtio optimizations

Included here:
Refactoring and bugfix patches in PC/ACPI.
New commands for ipmi.
Virtio optimizations.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

----------------------------------------------------------------
Cédric Le Goater (8):
      ipmi: replace goto by a return statement
      ipmi: replace *_MAXCMD defines
      ipmi: cleanup error_report messages
      ipmi: fix SDR length value
      ipmi: introduce a struct ipmi_sdr_compact
      ipmi: add get and set SENSOR_TYPE commands
      ipmi: add GET_SYS_RESTART_CAUSE chassis command
      ipmi: add ACPI power and GUID commands

David Gibson (1):
      dimm: Correct type of MemoryHotplugState->base

Dr. David Alan Gilbert (1):
      Fix virtio migration

Eduardo Habkost (12):
      pc: Move PcGuestInfo declaration to top of file
      pc: Eliminate struct PcGuestInfoState
      pc: Simplify pc_memory_init() signature
      pc: Simplify xen_load_linux() signature
      acpi: Remove guest_info parameters from functions
      acpi: Don't save PcGuestInfo on AcpiBuildState
      pc: Remove compat fields from PcGuestInfo
      pc: Remove RAM size fields from PcGuestInfo
      pc: Remove PcGuestInfo.isapc_ram_fw field
      pc: Move PcGuestInfo.fw_cfg to PCMachineState
      pc: Move APIC and NUMA data from PcGuestInfo to PCMachineState
      pc: Eliminate PcGuestInfo struct

Igor Mammedov (3):
      pc: acpi: merge SSDT into DSDT
      tests: pc: acpi: drop not needed 'expected SSDT' blobs
      tests: pc: acpi: add expected DSDT.bridge blobs and update DSDT blobs

Jason Wang (1):
      intel_iommu: large page support

Laszlo Ersek (4):
      acpi: take oem_id in build_header(), optionally
      acpi: expose oem_id and oem_table_id in build_rsdt()
      acpi: add function to extract oem_id and oem_table_id from the user's SLIC
      pc: set the OEM fields in the RSDT and the FADT from the SLIC

Laurent Vivier (1):
      net: set endianness on all backend devices

Marcel Apfelbaum (2):
      hw/pxb: add pxb devices to the bridge category
      hw/pci: ensure that only PCI/PCIe bridges can be attached to pxb/pxb-pcie devices

Michael S. Tsirkin (1):
      acpi: update expected DSDT

Paolo Bonzini (8):
      virtio: move VirtQueueElement at the beginning of the structs
      virtio: move allocation to virtqueue_pop/vring_pop
      virtio: introduce qemu_get/put_virtqueue_element
      virtio: introduce virtqueue_alloc_element
      virtio: slim down allocation of VirtQueueElements
      vring: slim down allocation of VirtQueueElements
      virtio: combine the read of a descriptor
      vhost-user-test: use correct ROM to speed up and avoid spurious failures

Roman Kagan (3):
      i386/acpi: make floppy controller object dynamic
      expose floppy drive geometry and CMOS type
      i386: populate floppy drive information in DSDT

Stefano Stabellini (1):
      fix MSI injection on Xen

Vincenzo Maffione (3):
      virtio: cache used_idx in a VirtQueue field
      virtio: read avail_idx from VQ only when necessary
      virtio: combine write of an entry into used ring

 hw/9pfs/virtio-9p.h                                |   2 +-
 hw/i386/acpi-build.h                               |   2 +-
 hw/i386/intel_iommu_internal.h                     |   6 +-
 include/hw/acpi/acpi.h                             |   7 +
 include/hw/acpi/aml-build.h                        |   5 +-
 include/hw/block/fdc.h                             |   2 +
 include/hw/i386/intel_iommu.h                      |   1 +
 include/hw/i386/pc.h                               |  41 +-
 include/hw/ipmi/ipmi.h                             |  45 +++
 include/hw/mem/pc-dimm.h                           |   2 +-
 include/hw/virtio/dataplane/vring.h                |   2 +-
 include/hw/virtio/virtio-balloon.h                 |   2 +-
 include/hw/virtio/virtio-blk.h                     |   5 +-
 include/hw/virtio/virtio-net.h                     |   2 +-
 include/hw/virtio/virtio-scsi.h                    |  15 +-
 include/hw/virtio/virtio-serial.h                  |   2 +-
 include/hw/virtio/virtio.h                         |  13 +-
 include/hw/xen/xen.h                               |   1 +
 include/migration/vmstate.h                        |  18 +-
 hw/9pfs/9p.c                                       |   2 +-
 hw/9pfs/virtio-9p-device.c                         |  17 +-
 hw/acpi/aml-build.c                                |  14 +-
 hw/acpi/core.c                                     |  16 +
 hw/acpi/nvdimm.c                                   |   4 +-
 hw/arm/virt-acpi-build.c                           |  14 +-
 hw/block/dataplane/virtio-blk.c                    |  11 +-
 hw/block/fdc.c                                     |  11 +
 hw/block/virtio-blk.c                              |  23 +-
 hw/char/virtio-serial-bus.c                        |  78 ++--
 hw/display/virtio-gpu.c                            |  21 +-
 hw/i386/acpi-build.c                               | 430 +++++++++++----------
 hw/i386/intel_iommu.c                              |  76 ++--
 hw/i386/pc.c                                       |  79 ++--
 hw/i386/pc_piix.c                                  |  14 +-
 hw/i386/pc_q35.c                                   |  14 +-
 hw/input/virtio-input.c                            |  24 +-
 hw/ipmi/ipmi_bmc_sim.c                             | 351 ++++++++++-------
 hw/net/vhost_net.c                                 |  23 +-
 hw/net/virtio-net.c                                |  69 ++--
 hw/pci-bridge/pci_expander_bridge.c                |   2 +
 hw/pci/msi.c                                       |   9 +-
 hw/pci/msix.c                                      |  12 +-
 hw/pci/pci.c                                       |   7 +
 hw/scsi/virtio-scsi-dataplane.c                    |  15 +-
 hw/scsi/virtio-scsi.c                              |  26 +-
 hw/virtio/dataplane/vring.c                        |  62 ++-
 hw/virtio/virtio-balloon.c                         |  22 +-
 hw/virtio/virtio-rng.c                             |  10 +-
 hw/virtio/virtio.c                                 | 348 +++++++++++------
 hw/xen/xen_pt_msi.c                                |   4 +-
 tests/vhost-user-test.c                            |   5 +-
 xen-hvm-stub.c                                     |   5 +
 xen-hvm.c                                          |   9 +
 qemu-options.hx                                    |   4 +
 roms/seabios                                       |   2 +-
 tests/acpi-test-data/pc/DSDT                       | Bin 3028 -> 5533 bytes
 .../acpi-test-data/pc/{SSDT.bridge => DSDT.bridge} | Bin 4345 -> 7392 bytes
 tests/acpi-test-data/pc/SSDT                       | Bin 2486 -> 0 bytes
 tests/acpi-test-data/q35/DSDT                      | Bin 7666 -> 8233 bytes
 tests/acpi-test-data/q35/DSDT.bridge               | Bin 0 -> 8250 bytes
 tests/acpi-test-data/q35/SSDT                      | Bin 691 -> 0 bytes
 tests/acpi-test-data/q35/SSDT.bridge               | Bin 708 -> 0 bytes
 62 files changed, 1204 insertions(+), 802 deletions(-)
 rename tests/acpi-test-data/pc/{SSDT.bridge => DSDT.bridge} (57%)
 delete mode 100644 tests/acpi-test-data/pc/SSDT
 create mode 100644 tests/acpi-test-data/q35/DSDT.bridge
 delete mode 100644 tests/acpi-test-data/q35/SSDT
 delete mode 100644 tests/acpi-test-data/q35/SSDT.bridge

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 01/49] Fix virtio migration
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
  2016-02-04 21:50 ` [Qemu-devel] [PULL 14/49] virtio: combine write of an entry into used ring Michael S. Tsirkin
@ 2016-02-04 21:50 ` Michael S. Tsirkin
  2016-02-04 21:50 ` [Qemu-devel] [PULL 02/49] pc: acpi: merge SSDT into DSDT Michael S. Tsirkin
                   ` (47 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:50 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Eduardo Habkost, Juan Quintela,
	Dr. David Alan Gilbert, Amit Shah, Cornelia Huck, Sascha Silbe

From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>

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 <dgilbert@redhat.com>
Reported-by: Sascha Silbe <silbe@linux.vnet.ibm.com>
Tested-By: Sascha Silbe <silbe@linux.vnet.ibm.com>
Reviewed-By: Sascha Silbe <silbe@linux.vnet.ibm.com>

Fixes: 50e5ae4dc3e4f21e874512f9e87b93b5472d26e0
Fixes: 2cf0148674430b6693c60d42b7eef721bfa9509f
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Tested-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 include/migration/vmstate.h | 18 +++++++++---------
 hw/virtio/virtio.c          |  8 ++++----
 2 files changed, 13 insertions(+), 13 deletions(-)

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),                          \
 }
 
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 63a7b6d..0603793 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -1143,8 +1143,8 @@ static const VMStateDescription vmstate_virtio_virtqueues = {
     .minimum_version_id = 1,
     .needed = &virtio_virtqueue_needed,
     .fields = (VMStateField[]) {
-        VMSTATE_STRUCT_VARRAY_KNOWN(vq, struct VirtIODevice, VIRTIO_QUEUE_MAX,
-                      0, vmstate_virtqueue, VirtQueue),
+        VMSTATE_STRUCT_VARRAY_POINTER_KNOWN(vq, struct VirtIODevice,
+                      VIRTIO_QUEUE_MAX, 0, vmstate_virtqueue, VirtQueue),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -1165,8 +1165,8 @@ static const VMStateDescription vmstate_virtio_ringsize = {
     .minimum_version_id = 1,
     .needed = &virtio_ringsize_needed,
     .fields = (VMStateField[]) {
-        VMSTATE_STRUCT_VARRAY_KNOWN(vq, struct VirtIODevice, VIRTIO_QUEUE_MAX,
-                      0, vmstate_ringsize, VirtQueue),
+        VMSTATE_STRUCT_VARRAY_POINTER_KNOWN(vq, struct VirtIODevice,
+                      VIRTIO_QUEUE_MAX, 0, vmstate_ringsize, VirtQueue),
         VMSTATE_END_OF_LIST()
     }
 };
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 02/49] pc: acpi: merge SSDT into DSDT
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
  2016-02-04 21:50 ` [Qemu-devel] [PULL 14/49] virtio: combine write of an entry into used ring Michael S. Tsirkin
  2016-02-04 21:50 ` [Qemu-devel] [PULL 01/49] Fix virtio migration Michael S. Tsirkin
@ 2016-02-04 21:50 ` Michael S. Tsirkin
  2016-02-04 21:51 ` [Qemu-devel] [PULL 03/49] tests: pc: acpi: drop not needed 'expected SSDT' blobs Michael S. Tsirkin
                   ` (46 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:50 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Richard Henderson, Paolo Bonzini, Eduardo Habkost,
	Igor Mammedov

From: Igor Mammedov <imammedo@redhat.com>

Since both tables are built dynamically now,
there is no point in keeping ASL in them in separate
tables.
So do the same as we do for ARM where we have only
DSDT table, i.e. move SSDT ASL into DSDT and
drop SSDT altogether.
This patch doesn't change moved SSDT ASL in any way,
but it opens a way to relatively independently simplify
generated ASL on per device/subsystem basis in
followup series.
It also simplifies bios-tables-test where expected
SSDT blobs could be dropped and only DSDT ones
have to be maintained.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/i386/acpi-build.c | 246 +++++++++++++++++++++++----------------------------
 1 file changed, 111 insertions(+), 135 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 739cfa3..2028ed7 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1935,24 +1935,113 @@ static Aml *build_q35_osc_method(void)
 }
 
 static void
-build_ssdt(GArray *table_data, GArray *linker,
+build_dsdt(GArray *table_data, GArray *linker,
            AcpiCpuInfo *cpu, AcpiPmInfo *pm, AcpiMiscInfo *misc,
            PcPciInfo *pci, PcGuestInfo *guest_info)
 {
+    CrsRangeEntry *entry;
+    Aml *dsdt, *sb_scope, *scope, *dev, *method, *field, *pkg, *crs;
+    GPtrArray *mem_ranges = g_ptr_array_new_with_free_func(crs_range_free);
+    GPtrArray *io_ranges = g_ptr_array_new_with_free_func(crs_range_free);
     MachineState *machine = MACHINE(qdev_get_machine());
     uint32_t nr_mem = machine->ram_slots;
-    Aml *ssdt, *sb_scope, *scope, *pkg, *dev, *method, *crs, *field;
-    PCIBus *bus = NULL;
-    GPtrArray *io_ranges = g_ptr_array_new_with_free_func(crs_range_free);
-    GPtrArray *mem_ranges = g_ptr_array_new_with_free_func(crs_range_free);
-    CrsRangeEntry *entry;
     int root_bus_limit = 0xFF;
+    PCIBus *bus = NULL;
     int i;
 
-    ssdt = init_aml_allocator();
+    dsdt = init_aml_allocator();
 
     /* Reserve space for header */
-    acpi_data_push(ssdt->buf, sizeof(AcpiTableHeader));
+    acpi_data_push(dsdt->buf, sizeof(AcpiTableHeader));
+
+    build_dbg_aml(dsdt);
+    if (misc->is_piix4) {
+        sb_scope = aml_scope("_SB");
+        dev = aml_device("PCI0");
+        aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03")));
+        aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
+        aml_append(dev, aml_name_decl("_UID", aml_int(1)));
+        aml_append(sb_scope, dev);
+        aml_append(dsdt, sb_scope);
+
+        build_hpet_aml(dsdt);
+        build_piix4_pm(dsdt);
+        build_piix4_isa_bridge(dsdt);
+        build_isa_devices_aml(dsdt);
+        build_piix4_pci_hotplug(dsdt);
+        build_piix4_pci0_int(dsdt);
+    } else {
+        sb_scope = aml_scope("_SB");
+        aml_append(sb_scope,
+            aml_operation_region("PCST", AML_SYSTEM_IO, 0xae00, 0x0c));
+        aml_append(sb_scope,
+            aml_operation_region("PCSB", AML_SYSTEM_IO, 0xae0c, 0x01));
+        field = aml_field("PCSB", AML_ANY_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
+        aml_append(field, aml_named_field("PCIB", 8));
+        aml_append(sb_scope, field);
+        aml_append(dsdt, sb_scope);
+
+        sb_scope = aml_scope("_SB");
+        dev = aml_device("PCI0");
+        aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08")));
+        aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03")));
+        aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
+        aml_append(dev, aml_name_decl("_UID", aml_int(1)));
+        aml_append(dev, aml_name_decl("SUPP", aml_int(0)));
+        aml_append(dev, aml_name_decl("CTRL", aml_int(0)));
+        aml_append(dev, build_q35_osc_method());
+        aml_append(sb_scope, dev);
+        aml_append(dsdt, sb_scope);
+
+        build_hpet_aml(dsdt);
+        build_q35_isa_bridge(dsdt);
+        build_isa_devices_aml(dsdt);
+        build_q35_pci0_int(dsdt);
+    }
+
+    build_cpu_hotplug_aml(dsdt);
+    build_memory_hotplug_aml(dsdt, nr_mem, pm->mem_hp_io_base,
+                             pm->mem_hp_io_len);
+
+    scope =  aml_scope("_GPE");
+    {
+        aml_append(scope, aml_name_decl("_HID", aml_string("ACPI0006")));
+
+        aml_append(scope, aml_method("_L00", 0, AML_NOTSERIALIZED));
+
+        if (misc->is_piix4) {
+            method = aml_method("_E01", 0, AML_NOTSERIALIZED);
+            aml_append(method,
+                aml_acquire(aml_name("\\_SB.PCI0.BLCK"), 0xFFFF));
+            aml_append(method, aml_call0("\\_SB.PCI0.PCNT"));
+            aml_append(method, aml_release(aml_name("\\_SB.PCI0.BLCK")));
+            aml_append(scope, method);
+        } else {
+            aml_append(scope, aml_method("_L01", 0, AML_NOTSERIALIZED));
+        }
+
+        method = aml_method("_E02", 0, AML_NOTSERIALIZED);
+        aml_append(method, aml_call0("\\_SB." CPU_SCAN_METHOD));
+        aml_append(scope, method);
+
+        method = aml_method("_E03", 0, AML_NOTSERIALIZED);
+        aml_append(method, aml_call0(MEMORY_HOTPLUG_HANDLER_PATH));
+        aml_append(scope, method);
+
+        aml_append(scope, aml_method("_L04", 0, AML_NOTSERIALIZED));
+        aml_append(scope, aml_method("_L05", 0, AML_NOTSERIALIZED));
+        aml_append(scope, aml_method("_L06", 0, AML_NOTSERIALIZED));
+        aml_append(scope, aml_method("_L07", 0, AML_NOTSERIALIZED));
+        aml_append(scope, aml_method("_L08", 0, AML_NOTSERIALIZED));
+        aml_append(scope, aml_method("_L09", 0, AML_NOTSERIALIZED));
+        aml_append(scope, aml_method("_L0A", 0, AML_NOTSERIALIZED));
+        aml_append(scope, aml_method("_L0B", 0, AML_NOTSERIALIZED));
+        aml_append(scope, aml_method("_L0C", 0, AML_NOTSERIALIZED));
+        aml_append(scope, aml_method("_L0D", 0, AML_NOTSERIALIZED));
+        aml_append(scope, aml_method("_L0E", 0, AML_NOTSERIALIZED));
+        aml_append(scope, aml_method("_L0F", 0, AML_NOTSERIALIZED));
+    }
+    aml_append(dsdt, scope);
 
     bus = PC_MACHINE(machine)->bus;
     if (bus) {
@@ -1984,7 +2073,7 @@ build_ssdt(GArray *table_data, GArray *linker,
                             io_ranges, mem_ranges);
             aml_append(dev, aml_name_decl("_CRS", crs));
             aml_append(scope, dev);
-            aml_append(ssdt, scope);
+            aml_append(dsdt, scope);
         }
     }
 
@@ -2068,7 +2157,7 @@ build_ssdt(GArray *table_data, GArray *linker,
         aml_append(dev, aml_name_decl("_CRS", crs));
         aml_append(scope, dev);
     }
-    aml_append(ssdt, scope);
+    aml_append(dsdt, scope);
 
     /*  create S3_ / S4_ / S5_ packages if necessary */
     scope = aml_scope("\\");
@@ -2097,7 +2186,7 @@ build_ssdt(GArray *table_data, GArray *linker,
     aml_append(pkg, aml_int(0)); /* reserved */
     aml_append(pkg, aml_int(0)); /* reserved */
     aml_append(scope, aml_name_decl("_S5", pkg));
-    aml_append(ssdt, scope);
+    aml_append(dsdt, scope);
 
     if (misc->applesmc_io_base) {
         scope = aml_scope("\\_SB.PCI0.ISA");
@@ -2116,7 +2205,7 @@ build_ssdt(GArray *table_data, GArray *linker,
         aml_append(dev, aml_name_decl("_CRS", crs));
 
         aml_append(scope, dev);
-        aml_append(ssdt, scope);
+        aml_append(dsdt, scope);
     }
 
     if (misc->pvpanic_port) {
@@ -2150,7 +2239,7 @@ build_ssdt(GArray *table_data, GArray *linker,
         aml_append(dev, method);
 
         aml_append(scope, dev);
-        aml_append(ssdt, scope);
+        aml_append(dsdt, scope);
     }
 
     sb_scope = aml_scope("\\_SB");
@@ -2189,14 +2278,14 @@ build_ssdt(GArray *table_data, GArray *linker,
                 aml_append(sb_scope, scope);
             }
         }
-        aml_append(ssdt, sb_scope);
+        aml_append(dsdt, sb_scope);
     }
 
     /* copy AML table into ACPI tables blob and patch header there */
-    g_array_append_vals(table_data, ssdt->buf->data, ssdt->buf->len);
+    g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len);
     build_header(linker, table_data,
-        (void *)(table_data->data + table_data->len - ssdt->buf->len),
-        "SSDT", ssdt->buf->len, 1, NULL);
+        (void *)(table_data->data + table_data->len - dsdt->buf->len),
+        "DSDT", dsdt->buf->len, 1, NULL);
     free_aml_allocator();
 }
 
@@ -2422,116 +2511,6 @@ build_dmar_q35(GArray *table_data, GArray *linker)
                  "DMAR", table_data->len - dmar_start, 1, NULL);
 }
 
-static void
-build_dsdt(GArray *table_data, GArray *linker,
-           AcpiPmInfo *pm, AcpiMiscInfo *misc)
-{
-    Aml *dsdt, *sb_scope, *scope, *dev, *method, *field;
-    MachineState *machine = MACHINE(qdev_get_machine());
-    uint32_t nr_mem = machine->ram_slots;
-
-    dsdt = init_aml_allocator();
-
-    /* Reserve space for header */
-    acpi_data_push(dsdt->buf, sizeof(AcpiTableHeader));
-
-    build_dbg_aml(dsdt);
-    if (misc->is_piix4) {
-        sb_scope = aml_scope("_SB");
-        dev = aml_device("PCI0");
-        aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03")));
-        aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
-        aml_append(dev, aml_name_decl("_UID", aml_int(1)));
-        aml_append(sb_scope, dev);
-        aml_append(dsdt, sb_scope);
-
-        build_hpet_aml(dsdt);
-        build_piix4_pm(dsdt);
-        build_piix4_isa_bridge(dsdt);
-        build_isa_devices_aml(dsdt);
-        build_piix4_pci_hotplug(dsdt);
-        build_piix4_pci0_int(dsdt);
-    } else {
-        sb_scope = aml_scope("_SB");
-        aml_append(sb_scope,
-            aml_operation_region("PCST", AML_SYSTEM_IO, 0xae00, 0x0c));
-        aml_append(sb_scope,
-            aml_operation_region("PCSB", AML_SYSTEM_IO, 0xae0c, 0x01));
-        field = aml_field("PCSB", AML_ANY_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
-        aml_append(field, aml_named_field("PCIB", 8));
-        aml_append(sb_scope, field);
-        aml_append(dsdt, sb_scope);
-
-        sb_scope = aml_scope("_SB");
-        dev = aml_device("PCI0");
-        aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08")));
-        aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03")));
-        aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
-        aml_append(dev, aml_name_decl("_UID", aml_int(1)));
-        aml_append(dev, aml_name_decl("SUPP", aml_int(0)));
-        aml_append(dev, aml_name_decl("CTRL", aml_int(0)));
-        aml_append(dev, build_q35_osc_method());
-        aml_append(sb_scope, dev);
-        aml_append(dsdt, sb_scope);
-
-        build_hpet_aml(dsdt);
-        build_q35_isa_bridge(dsdt);
-        build_isa_devices_aml(dsdt);
-        build_q35_pci0_int(dsdt);
-    }
-
-    build_cpu_hotplug_aml(dsdt);
-    build_memory_hotplug_aml(dsdt, nr_mem, pm->mem_hp_io_base,
-                             pm->mem_hp_io_len);
-
-    scope =  aml_scope("_GPE");
-    {
-        aml_append(scope, aml_name_decl("_HID", aml_string("ACPI0006")));
-
-        aml_append(scope, aml_method("_L00", 0, AML_NOTSERIALIZED));
-
-        if (misc->is_piix4) {
-            method = aml_method("_E01", 0, AML_NOTSERIALIZED);
-            aml_append(method,
-                aml_acquire(aml_name("\\_SB.PCI0.BLCK"), 0xFFFF));
-            aml_append(method, aml_call0("\\_SB.PCI0.PCNT"));
-            aml_append(method, aml_release(aml_name("\\_SB.PCI0.BLCK")));
-            aml_append(scope, method);
-        } else {
-            aml_append(scope, aml_method("_L01", 0, AML_NOTSERIALIZED));
-        }
-
-        method = aml_method("_E02", 0, AML_NOTSERIALIZED);
-        aml_append(method, aml_call0("\\_SB." CPU_SCAN_METHOD));
-        aml_append(scope, method);
-
-        method = aml_method("_E03", 0, AML_NOTSERIALIZED);
-        aml_append(method, aml_call0(MEMORY_HOTPLUG_HANDLER_PATH));
-        aml_append(scope, method);
-
-        aml_append(scope, aml_method("_L04", 0, AML_NOTSERIALIZED));
-        aml_append(scope, aml_method("_L05", 0, AML_NOTSERIALIZED));
-        aml_append(scope, aml_method("_L06", 0, AML_NOTSERIALIZED));
-        aml_append(scope, aml_method("_L07", 0, AML_NOTSERIALIZED));
-        aml_append(scope, aml_method("_L08", 0, AML_NOTSERIALIZED));
-        aml_append(scope, aml_method("_L09", 0, AML_NOTSERIALIZED));
-        aml_append(scope, aml_method("_L0A", 0, AML_NOTSERIALIZED));
-        aml_append(scope, aml_method("_L0B", 0, AML_NOTSERIALIZED));
-        aml_append(scope, aml_method("_L0C", 0, AML_NOTSERIALIZED));
-        aml_append(scope, aml_method("_L0D", 0, AML_NOTSERIALIZED));
-        aml_append(scope, aml_method("_L0E", 0, AML_NOTSERIALIZED));
-        aml_append(scope, aml_method("_L0F", 0, AML_NOTSERIALIZED));
-    }
-    aml_append(dsdt, scope);
-
-    /* copy AML table into ACPI tables blob and patch header there */
-    g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len);
-    build_header(linker, table_data,
-        (void *)(table_data->data + table_data->len - dsdt->buf->len),
-        "DSDT", dsdt->buf->len, 1, NULL);
-    free_aml_allocator();
-}
-
 static GArray *
 build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
 {
@@ -2611,7 +2590,7 @@ static
 void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
 {
     GArray *table_offsets;
-    unsigned facs, ssdt, dsdt, rsdt;
+    unsigned facs, dsdt, rsdt, fadt;
     AcpiCpuInfo cpu;
     AcpiPmInfo pm;
     AcpiMiscInfo misc;
@@ -2644,7 +2623,8 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
 
     /* DSDT is pointed to by FADT */
     dsdt = tables_blob->len;
-    build_dsdt(tables_blob, tables->linker, &pm, &misc);
+    build_dsdt(tables_blob, tables->linker, &cpu, &pm, &misc, &pci,
+               guest_info);
 
     /* Count the size of the DSDT and SSDT, we will need it for legacy
      * sizing of ACPI tables.
@@ -2652,14 +2632,10 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
     aml_len += tables_blob->len - dsdt;
 
     /* ACPI tables pointed to by RSDT */
+    fadt = tables_blob->len;
     acpi_add_table(table_offsets, tables_blob);
     build_fadt(tables_blob, tables->linker, &pm, facs, dsdt);
-
-    ssdt = tables_blob->len;
-    acpi_add_table(table_offsets, tables_blob);
-    build_ssdt(tables_blob, tables->linker, &cpu, &pm, &misc, &pci,
-               guest_info);
-    aml_len += tables_blob->len - ssdt;
+    aml_len += tables_blob->len - fadt;
 
     acpi_add_table(table_offsets, tables_blob);
     build_madt(tables_blob, tables->linker, &cpu, guest_info);
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 03/49] tests: pc: acpi: drop not needed 'expected SSDT' blobs
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (2 preceding siblings ...)
  2016-02-04 21:50 ` [Qemu-devel] [PULL 02/49] pc: acpi: merge SSDT into DSDT Michael S. Tsirkin
@ 2016-02-04 21:51 ` Michael S. Tsirkin
  2016-02-04 21:51 ` [Qemu-devel] [PULL 04/49] tests: pc: acpi: add expected DSDT.bridge blobs and update DSDT blobs Michael S. Tsirkin
                   ` (45 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Eduardo Habkost, Igor Mammedov

From: Igor Mammedov <imammedo@redhat.com>

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 tests/acpi-test-data/pc/SSDT         | Bin 2486 -> 0 bytes
 tests/acpi-test-data/pc/SSDT.bridge  | Bin 4345 -> 0 bytes
 tests/acpi-test-data/q35/SSDT        | Bin 691 -> 0 bytes
 tests/acpi-test-data/q35/SSDT.bridge | Bin 708 -> 0 bytes
 4 files changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 tests/acpi-test-data/pc/SSDT
 delete mode 100644 tests/acpi-test-data/pc/SSDT.bridge
 delete mode 100644 tests/acpi-test-data/q35/SSDT
 delete mode 100644 tests/acpi-test-data/q35/SSDT.bridge

diff --git a/tests/acpi-test-data/pc/SSDT b/tests/acpi-test-data/pc/SSDT
deleted file mode 100644
index 210d6a71e58aa34ce8e94121d25bcf58c3bd503c..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 2486
zcma)-Pjk~o7{=eVMWU=_A{&JSLWr(#pbjB{-fT-EjvFaES~~;d%;?ZzYGyhO1LeTv
zl7zwSy<dO>XMF3m{RqAF%6I5Yn^WEQmHaw6upNAm_tEp)XaBFX4tu{Y0Ej=^`$0$h
z?I$YG_)Y)-mFeG&YKQkS-Og07+px1B)wTA#{Nd*+lpM4HCiD<H;@mlRgpKcoQ>It{
zpndMlbag`DUq3Aa6h452$)rLk{z{NL)FS=t$>g_xi{kHpzk$J7VC|>~+wbg#Rh6hl
ztFaAs)<;F}{g=;P9ld_}?Xy?-QukW2QuMSc<&O9?{xlXAg>)^|QR(MGaBzO-=*Jh|
zzy9ujv*06q6y6(f?;KJ~n^}F%64+@hKgjB~B}=lDt1WV90B-BuAx+=l>>KMI&7n#o
zop-@${UPUyF$AjrWzCOaEPNcwiAr@(RA4Oq!KsrAd}K{`@OCp$jYctbo|DC`9()K?
z+yWFhGbD5mylNJ88v;etg`rnVdXJx$-pgNxFrw<u?Lh4(^|BCdY#)AA=Jk&|DzxJ;
zNpZlm6Y}}Rb(F9|o$9DK#ZF1NGB{l)QI6C0o{x_XKK7`zhb8qS!(Oiu(1NCnBb|wO
zH_;+a;{y>#-AoKlmx}s2!dm;$0X}r#dvh^$)Qykw-PlGKm$jlBjm*wkVT$6e-k1v9
ze<kp6Wi~?ikQeTAVUr4jvpag@5mwawM3(dVSfvbJJ)avDL|tltY(no-ETI;omJ#LD
zD~w(-p_`nFI{^oP9hftsoI20wya|24sWzjw5#`hcMi)%z7N<%^r4i*+Jcz}xDkgNB
zQyoSfBg&~&Myn?DA*Wtt^r{i%)I~-YP3R*|bs2SyD5usKt(nlTIknDc-H3APHAb(Q
z&=#lS5h#|xGoqZj#ORU<ZFA~%Mz0%DPF-en*@On1y29v+5#`hyjNUMzA*bGC^rjKz
z)Kx}TO=!faw-~);L^*Yh(KQqLm{V^vdfSL{>N=zApF_RQYIu<JO7ETHp|oK{cir<`
zxG3;8D}+yiohAyrkqYO81Uc2?VFd&#yjG^FL~7<)sPJ-_deqj|%%jHeh)+FgZF}ZX
zb9hjv9<}$7yv5@o-h=p69cesptns^w`ohPr>qz6#Vc*X6h3}HaL%_bD>kGe08n-k1
zC%L}x^AY35WFJ2!BOP4wY1FvIW<HHOyyVl!akI>PpY$cai5i!E=AV#8-&<Ef(t{V!
RPWmw|A%5%nVp<4g`9EqZL>~YE

diff --git a/tests/acpi-test-data/pc/SSDT.bridge b/tests/acpi-test-data/pc/SSDT.bridge
deleted file mode 100644
index 6e6660b1fbe0bdb7fe0b257cb53c31fa9bb21a14..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 4345
zcmeH}KX2Pc7{>1;#%4}bOeu8iIC0FOL!H5u<3DjXNhD)gG3f(OG7``zha#u~6itvc
z1p+U&3aH)t1w3SqK0^Bu`Vlhp8x&}rrRw{VdSws3qGJYWpzh)G<8yc9@m?zBcRt#T
zakqKkwUpa@B0UA?IAaXk_-_Z5qqS5uQ|ay1%+!ljr8z6U`?<^t7TAo9@W6NZxpi)F
z6V7w1h^PJr``nu7@(95{e_CKH_ZbsxG%6tqzXHn~>=A$FX!PqpdGoiw-m;|c8M`uo
z{#$!~Sw^zfsBJSd?SjJd?yG07U%Yws^|RM-Qgs@ll#jG5#4i6Z{4nGOhO`aYlJQj`
zFgdsN;`^81zWL@qv)Fs~o;z=uy?TT_ZKTy1gTtVqy_r@`Lli_IQ(NfZ1Z@A~5#GL}
z|JYc=dnn^TWkawUzl)iC4xa4(zwU=@$X%GqiHuc;m)KCa$*GkIIHYwu`EkROwOW4b
z94ieQ9rn(XVS|ByJA*=Xm{U%Jc8!Aw+N|ePqRykIg){L>j}7qh=cXqQqH2+IJ2a2J
zDAMx}Thcc}KZ;?(xDvAa3(rxoMI2O1hA|9Eh{fb|1w}E8oBJ*tT5#CM);_f4lN3h1
zj6j3cMHr}*hkKFYVH_UvFleVdIi1h1R{>mg5FElmd9E`P;y~^CAK7Ybf(wteq-wR)
zOdEa-;=WoR3s`>z=D?F#_u0Fw@qii|*hu;ZKdAMc{7Qg}%)~&R^gqi3RX2ipVysim
zZkP0eHX<oFN&j<I!;7KKGYTU3)#PeECLl$DP#D@(p@5D<MUl{=4t;<##Z-e(LyJ=C
zHA1iH&<#q3#R-##Y0YR+N}VNiR)=m<s!6D+MJe?<q1Scj7NrV8g%+h$*c<X`m2~Jf
zrCNkqT9i`DgqC&aLrT3t=nXAOsdI$R>ChcYwF$MgD5X{it?1A%DYZ&yRf|&UO+s(#
z&<3T#TbVxsM~hPGJfZVCv`MMA2)(66DRqI+1s&>9>LQ_wT9i_66M9>R`jomv=#mzt
z)H{UU(V+pQ-X-*|7Nyi>LYH;uBTBtT=shh;sVju8T!lK(vVRzL3TLI`9%lpGWuKo}
z$33W-Aa=&W00Db=?wBaZu|dF|mpd*Ba_S&p-^!g66zG(XdnMSD2MRWyvBI7<CmwbM
zTgceMzP2VFb_N^4*u&noCmwbOuk+Z${vM(?cihX00BCqENy7&L=nEe{3kC{aF!Iez
zU-<ArHc;@Yknd*t!mp!-MNj@orZ4<##;|<JhblNw-X$Mr4GVGN<GlS#KF%DL)WmmD
zU-IjqVR20S6V%{4E7FTP>?LnT-4Gu%6zMJ>H+)e{`m6Z(rX?%C1JjZ<Em_l&^{JPv
g$4hz1!ZJ0jKUm*B-TJed*B_>-KVPlkrvx(p0-RC(E&u=k

diff --git a/tests/acpi-test-data/q35/SSDT b/tests/acpi-test-data/q35/SSDT
deleted file mode 100644
index 0970c67ddb1456707c0111f7e5e659ef385af408..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 691
zcmaJ<&2G~`5S~pUV{JB)8wF7g2w&k)41tOhs=apOgsijjx>b=Q?EzI33AL!DhaQkf
zkbpZcz@cxz1HdD2%zJPkC(MjZIkJcG_sx&K`LQu^@wElO-bOQ-8b3PF(x8t40Ac!i
zV=>>dCbC+N1J}yjY(&@i@uwcN1cm`BGHk@wVl9}9ekR)F`i0@O_{Vz{CI0+)1E7fm
zaHy&-rQ&Nr9U(<}->d4|@4xWL1(ZwK8R-P|({bF>nGV8W8(h1GjQsxT;n~Ug>GQ)g
zbebaM-KNtX=OgAjzQeo=@b1hhI<$SK!%ztEL)&*dyv1<`$R1IIM7_z)IgMN{pLVur
zZk;El))wIp?lihm@A>J;o7b<-U;I~oC02s@IKw-gn}T&$g8St{)C7&)@yho@se_;y
zcOa|^3%Hb8g@6R7Az}&`^lUN-7?NZHM}v*5*nQUe!apCu2P%K*N<GW^ZN@z1&hNFa
zZl+QlyDH9d9FeY9?*w<xVUwClwaQr+INvN6w~4e>9!-5TDViyvDI$GfvFlru5W)^u
ziLp$LGs9G__L)j1mX(X^O}$C5YL@JyG14D6iW>EHJG9Ai*)>66T^q(Zp7pK?9ybL4
X76t>n!u=R7Yw+L-3~S(MnHBH{@bQ-c

diff --git a/tests/acpi-test-data/q35/SSDT.bridge b/tests/acpi-test-data/q35/SSDT.bridge
deleted file mode 100644
index a77868861754ce0b3333b2b7bc8091c03a53754d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 708
zcmaJ<&2G~`5T12{u{ImwMn+Uf6~4luxC9U<RA+7Cq*-_6b*myr+5@U65~8T3hu%n#
zfIBb1q3;0)9)M%sg9ABXX5yA3dl-M;{OFq>8<Uhj900a4*p-<H2M1aj^f3S+OkaN_
zrkmCbtd^t5v$8O2gX{dw=Poz`!vHlIHe^e&6wE_E6D@N6#_&@7<K3DPe|@?I(8K{a
z)OCka@j0-HkRrYBb^YznC471g)m*lRIz|0#lyr5jqd0mDp4~%6{_y1R^!V)L#o;MB
zO&Rk}(`lFUAq(BmW&Sz%cc&EX+n(EID1`W-?RjnPaNGg1M-(AZf9Lj;My}>N?M<3n
z7pYlki})vZ8(pdQ!tD6n+t+6=|0}-`3&BF1;k_<Q$vO+c!)hj01dZMHs}Fstqo^4-
z5LU${Tu7~AK!Vc{F(m|Dn~o!fBpt(1u$Gt4o;zRpmm~N{<*z)cck^D0F<*Jp`>m^+
zsZ1xHO7a3nr0cDAg1hIiPEBQ66|4iCuUE4>L|UpCOhPmnnhBu^B7I=7>kUeXVVkSe
zSf)m~VX9F3Or>MXs@ct^-lSNyo9?4AG7MZrjrzlDw8?7TF;Qea8z%*x^`42IGz9+^
g1_54SD}jp@cyI;!1giNBvvpaBxef%bmU#((0Zb>F0RR91

-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 04/49] tests: pc: acpi: add expected DSDT.bridge blobs and update DSDT blobs
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (3 preceding siblings ...)
  2016-02-04 21:51 ` [Qemu-devel] [PULL 03/49] tests: pc: acpi: drop not needed 'expected SSDT' blobs Michael S. Tsirkin
@ 2016-02-04 21:51 ` Michael S. Tsirkin
  2016-02-04 21:51 ` [Qemu-devel] [PULL 05/49] virtio: move VirtQueueElement at the beginning of the structs Michael S. Tsirkin
                   ` (44 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Eduardo Habkost, Igor Mammedov

From: Igor Mammedov <imammedo@redhat.com>

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 tests/acpi-test-data/pc/DSDT         | Bin 3028 -> 5478 bytes
 tests/acpi-test-data/pc/DSDT.bridge  | Bin 0 -> 7337 bytes
 tests/acpi-test-data/q35/DSDT        | Bin 7666 -> 8321 bytes
 tests/acpi-test-data/q35/DSDT.bridge | Bin 0 -> 8338 bytes
 4 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 tests/acpi-test-data/pc/DSDT.bridge
 create mode 100644 tests/acpi-test-data/q35/DSDT.bridge

diff --git a/tests/acpi-test-data/pc/DSDT b/tests/acpi-test-data/pc/DSDT
index c658203db94a7e7db7c36fde99a7075a8d75498d..ec0e642b06967d3ec4d7a7d252b82b916f37a5e0 100644
GIT binary patch
delta 2489
zcma)-zi!)B6voe$6q~uCVoIT7Cyrw+9g-oHqu6mbNhEDqHI)lp$!H-19E!9uP}D)v
z41ovQE~<9#3wX#Jp-<4xojUXZGUWvdw4SP-L+Z$`kPDOpaX)@Pe)k^UKm23q{R8Q1
zzx(APfO!A2{4F0lLGj>Wq#Kd)b}Lrob#$>YFTeS*02v$T8q-behzt9|78X7ic9tIf
zjrN5-)rB#EfBvupkoo`;#^XGpcx51QM5@3VkAL}x+A+Ydf4zqOnU~v90S=(K>laj8
zRqB;Zu%aF+dR~6<?B&s`7hgPki4S$RF7xS73sUZgccXVBk)x1SPBm5MLm^mQxq0;M
z^RHih^`ESGHVodvTj9P2=l%h8RgFq>If28*_T#8z<zz-?6171NmEhFBKcElTKl?QI
zkiMeo1UeamUH@IqrA2tE_doj|!AO*`m=o2}U6F^8EcZ|CMBpu|IsNado~l%+YXH}d
z!g?3pcq*)uz;a0FF1Up#XjKG?palcB*zRtBo;jC44PZ#GA6lMz+AhUeA)L@U_&CdJ
zAZ#k%3jKBmOQzM3d}5qS3ClF9rV2YaDk+!yr)wm#VW+WI##<9_d(_&)mijEhVXqQU
zhnfrn9f@$atwq=g_eB`ABGErxY^s<7bbzlt4fgS-y|OzO(omi7C|QyXba86)x>AX(
zsP1=AJkaYCfr~H$E>6z64{wsjBW_fw(LcMd*SGLR-D}Hi@;<(j1-F!Z9Tj^)i+UiR
z*hiF0Y>wI7l$}L6_8OztOlXx;aW!BCID)we8VfZOTjkh!X6H?@k2%(2)H0%+dY#eh
z2^!-PnH|9f$4X|UDRzTnaX+So<xS`&r`n9#h{owO%zT4Qjx8`-FvULM*c*)AFru8g
zz~}<Rybxwau*I<svyLfti(`w77ES0UoLXWuE*V*ly~*rN6I$n3+z9C`xJHyy7gH3^
z-$fJK;MiLnd&`J&>=L6(Ce-89WkO@x49iBAV{dcpZ4>Hq>>Wn$7*S4Lv7$KrUMnUx
z;Mltyd)J6^>?)(HCUl!q@5RjCGqN1J#^~CIP`A0_@3*^|bNhH8Ef~_NcbEtV1s-du
zD3f5P2E$n6*_2u*XyM^=cwRUj<Uydq^JStkq^4dD6&?~3k2=G1V4|ou-0BlW-Qi}Q
zDC|$;ew`@l?@3JN!tnrC0sdr%8uuM*{LP}i^zmmq)VPD#w-SBnJEU<duwPE}rC%eB
zYnuHN(sAPwNNUFA$pHRYhT6O0Q{A}Erao2fU-7ASTrg9=O!|snLyc2E^-o~<k={nY
ZT~l7W3(uj^?u9gs_~+}1NyC@fe*yRDOW6Pb

delta 19
acmaE+bw!-ZCD<k83O54-W6MUaQ``VTv<4{v

diff --git a/tests/acpi-test-data/pc/DSDT.bridge b/tests/acpi-test-data/pc/DSDT.bridge
new file mode 100644
index 0000000000000000000000000000000000000000..7b1c14b529f9f63fc3731c02225ce37c5cfbc0db
GIT binary patch
literal 7337
zcmeHL&2Jmm5ueAUq~#+iEv2<Bf5n9C#Bo~N{E%e_C<>9glt`INZMc--VvX!ll2N*7
zn}re=afARe12|4@DeIuU(FQNQ*ndKM>@j~r3iK~X(Z;<*o!Q4nv5FQ*Z#kHNcHhkW
z-f!O5%)FK9n5{pb0bp0l>qgbdmT%jJi8=-V)TXyqi{Alv&n&NcEE$V4_hB+@<D;zV
zKQ+r6tL%>*|4ZNh;8UNq1K50~J=tsrpFH+Afk5{+1J0?TEqG4ZbGxT)qn1;>YRycQ
zzT%4NmCPon-bT%2nxzU%MXlPEmIN^bp&5r!wObaX0KWPz332zKM)KUPO2f?BP1DQj
zOP<pzK|mTmAXWP#pKE?U^+nHzo}b*`A3%Tli(VW4&`!bM|1~jy0iRJlqv>QaeELxW
zXN=?!2Y3M5>sM$rG+eiP(!QN9hGR`Bz;GybzG%dN?`ta)W3XDh=9D~v!-XZ>V$O(h
zpW|@fc=rmiP)~sBRhX*Vl?H<wpco};C`K7y>WYa^t$zBdBHa_G+r8Xu8AvS_E{RJ<
zqn_u-R#^Z6Xt4!gt852$AU62`-0t<8Wpe~q6g?5H&1kw|M<0A(*lQcM@x2hkS-ahf
z*80Y%<ILRQjw+v60F8ia@fFh;ZRHf`^J4jF0)BrImwW(E<0Fr!`TQ#TM)^j8_$vEW
z`4-o4VHw_vhfaT9w_78p@eviR&=FJ`Pp`5Ml@AqFUDylzSK`LHm6xkC!Nh@*Bck<<
zqIs#jR6t$OLYft#DIB8Vu@Mh$P$W<6Wej;#<k70?!I{{z4X4GD@SLl7Vo5OYNNr^C
zVP@Sur?Q5Tr9P(vk|e<>=PGMxC^xJoOKQSEf>Ca4SXq~q>&8vcU$>3QTFgC9(*AzX
zA!G1>-2>|GUL^GZv<5~*+0$-vI>oxlJ-gY0U^cer2he_2PCRMzz2KuZkHKcJyVKqT
zuE17b>un(@fl*Lz+%#dkf1$U<`k7vv$46=hwx6a)QVBts-WHFIH07a28EFjI4nBUc
z$u+<@gvZ+e!EPJ<J>F&zY(MtfaKAn9-G>*hDl}R;^b|bIZoZRK@sX!TfgVLwpR2ut
ztJ+WO^1TkmaALrd`cmy3qnSWJGnbj>$<HPsK`9J3<a5&T34GT2$tNA0bBEdkQoG&y
z6i%}wH$8><fU=E>Yvp8)^SRHaA)!nl568b`$fwVUV4^|L@brvl)*Sel+I%n6%usm3
zfQA&xCp@R=u+KYU6quZvHPR2gmk)Wz^ZSFn=f}L~L+^PU-?;a@ezf<z+qG!!#v$)K
z_J6o9jJYp_?hA+97b4sjhVIS7?lIs0;Mo_)+!sUl#Y66k5$=m_cRh}?cMiLc3-|H}
zQBimRqcoV*C&SIwlVXi&sHmdd)vOeSn|{r(trEi;XxQtG4){SP$yHF12Y>CL^OyoI
zd?^t4D8*sW)=wEW9_fQ#{Rtm)=Tl_>IyY<z_67boeQgr`8Gr}K@$O=|4Zwf4GV#R!
zlza_4`_S(5U7t_EN1JT(X$sYMu@EXiQNGDA!WVwuYi|Wx;Q)Q;bBymsYvmU{d#Z+S
zuH5&v#^r-7)-7GOs<zmvwB4|CrQDLJ+G*?VZ{FK^knOzpLGbJQzs&C3egD1tJ6m_(
z2YoJ#l76CRnT;kE0}N7^Sz-DrO<Io8fCC%O!#z*7{rzV@d*V}%z_*-Ay+7BpY7K{3
z;rIeZ!qek@y=OJ8TSChfRHL-xGvB>PBm<^jwwkn@2eiSTIuH^jdsfBqSiol_+Sg0-
z7Dh}$4nbm7tGTq8De~OsKLNnXf9Ut!zW7P?P~69iLml}v4z@0uv)HVP<{R~j)V_ty
zq4u~{x;@06!e%wFn&m2WqDGyFuu-p42Wr%bWQWw$puQx8X6oJ7pOB91J0!DEnF*Eb
zgOP?>b+Xm_=2VZ=fKx6OGUxc2Pfv_bnWjq9q$!5eD;79MdJpG>&1vjAY#zq}c>#GQ
zb3o)|3}~EW8txEv8#R{}^$V7L+hT_|AV95muuX4T>rN~FJ<vUCy>ct~6&ejesV`WS
zwH%g5aiZjQ;xWMrD<E1W?XB9CF!<9Y!>;9Wc%(6s>$x20Z+n$o9^CVH4sKzh(vB%?
zqtS9NjwuMCYuK{@cSPu5sOl$CQG`2J<MKL3fkdZ2^tC8lUK6k30Imz^hIqX#UM2A=
zi<co@rg&AvYX!7QX6QP+Wz!Y0JjH+eI1MqpH`D&n1Fw89Q!i6YMLiS8`dc)=OpWAp
zxZD36KLZ^1p2{EnVh~!w@`|FmzyFu-LIeEu-*h!J;<&WpYIrDHkbW#j;Dx_c;z@Ct
zO>@4=zJBrb3l<mmOS@_}#RmOv%E9|Vw)(w%^L;LO4$qm67qUxtFj+Z8Z+0@yaM0LZ
z^k&sKk6|Jv=^9yR0-E`sJG4)3_h$SGT|?|<WmF*eWOy}58}`NzbN>Qfuq;jmuLR*8
z@CDDh4^yE)`FmM&KPehEp11I)r#!3Ff&o<zK!LtxP;gqHr#(E*428-Xbo316=on`0
z4m_gn_f$&$vkIdxsIl`HX6!Kcj;$|VV>ryypsF_AFoE-V_u)Ab6v{MN$~*X|Q>%_G
z3_u+9Spt+`nTNR(BO5bvn1Jd2>OMRs`eVM%QY_-bF|zt3CGD8D{0~}5wTxCg8%ZaZ
z!>c}h_PO1+ocvJ0^A`gh_abj%sh~zdHj321YW+JWe?#;{Fkae;kh$Fpg3#G$;8qf?
zJ{v9<-H-|5p~daK>Ex(0w()X>D5PLVBQJ?DA(Ada0*XUBiWH$k(&3kEIIsw4fo4jq
zc)<{?_@Q$&YeBM3Na#cqv?y8ea0=GRNT_6;l2H6;J9+?%l2w&ZH4-XW6B3$;f?kuX
zTtayyRI*}j5YtLVL6;<JN<veSP|2E>&~y~^x@4V}(CJ91WW`ShG1i$V=ncuLNvIYH
zm8=;F%|t=pmaMZ9IvWX<taB1N7X>XzRt!clEj<z{S&vERu_$O+vL2Vv<B?FwdO|`^
zL_rP7IxnH~kx<EcQbJEgK~2eeN<vRXLM7{I2|XPJtw`205_%>QDp}7;=-DXfie!CF
zLSKu7O4f4{dhRHw-Z*RCYP4eg<Zg$-Bg(S(`l;Ox)=U&`423ufn8SrdB|%y=6foxr
zOO^y_Sw;c#may!RK$i4wCy6=vk%P%+D3Pbdk&Rqo3K`nS*R_$2oM9pu+Q{3|$VTok
zoQF2@cb#lAyPdEIpp0QDWxNoed|=0G!6OF)Oxp1?4&?*8Mlyzqv}Z&4z`jf}9(rlt
z3*`fQIAc7%(vDT|kz<V6Y1ViUM|PUGIcBGs<B=NKvm}q%mr=&UF|zNGjCTDTU0@+#
z^sgh@Xe`njY}hcl;&w05_Pr`uVg+86tXC!LRmu9Xm#mwoM9HEu^{W0*ef#m&pG%_t
OKt%m{_X=Gl2=iY>7yVlR

literal 0
HcmV?d00001

diff --git a/tests/acpi-test-data/q35/DSDT b/tests/acpi-test-data/q35/DSDT
index 4723e5954dccb00995ccaf521b7daf6bf15cf1d4..b492f04b8866ae82eaded81aa0ea2d3a4969dc5c 100644
GIT binary patch
delta 680
zcmaJ<&2G~`5S~pUV{JB)8yQg!6~4lu7y<|h3DvRPI3eq<ylw?@q&-v>MM4y{^w5(@
zkbpZcz@aa|6VNj!j(G&ma3CkljIDBH52Np!ncZ)G_UEH{z#|>ya}R)h`@(;0l+IYp
zHjN${6^?z|gqdC&Ug57k_MjzzPDO@|*h;Jfv(e8)n_Ry!yb}L-ucE|XAFcs3aR3fg
z)umKCEvO@`VQ^7ZU;hv;0WKb&L9qxsBNbx-$vEn%RQZAb0Bp01jQrm5!O79-@&3UH
zI&~iKZc}QH^AYnb&tlFQI5%e$9hkn=VW@=op6S~i-r}vA-KPktI+N=&>bY2yPdb~_
zxyoW)i;Lhpw;JJ4?Rv@4o7XQ-pZ`~XDVBnH*u-0v>6~?!f_ueW)C7&$a*B6@Q29Pd
z1GvJ-Acyl%$pA`Z*bgzCgWEIl#Ait22^_j>X}<le^_hP<g!gp+g&nG$wBKgTk@oC%
z`*LkEQIRd9G{cr@f%Q~y{2bP)szk|*b%FEsVt#{2TV}(lhbHk#nN0~!6HltA2J7CS
zi~zQ{jJ08MoN6XBxyNKYF|3$hZ644u-r9-x(CE-}ElHI++Z~!^vFK{wH?|3)3^#jA
d`wts}KZb#eYq=A_c@6HmmuOG}OND6;e*yABm`VTu

delta 19
acmZp4{AA7L66_N4NtS_u@z6%D7qS3EV+Okb

diff --git a/tests/acpi-test-data/q35/DSDT.bridge b/tests/acpi-test-data/q35/DSDT.bridge
new file mode 100644
index 0000000000000000000000000000000000000000..3b72e250fa866ec34c315450643025e03c8c8cab
GIT binary patch
literal 8338
zcmb7J&u`qu86EDfR@CfD;!3nE%XYL-i>68IWMw%{TC{<8$^B(7C3<(Aq*wz>$#JVB
zZ9^zFki-aJD?onuP#{(uw6|5DbN+?q*kf)D&{MBHrYP)F)c4JBq!}s#;ysY_4d45|
zc|&p@m-Ksn|3R5C>&@Dl*XosPuZ5nEK8rC%ZQ48S+;uj%>(`n?tB}cAgL?(h#-?Vw
zzw~R@n$}-8qc5W9*2j^x9<z-vorfFi@rR#88;n4=H)77I;XE_!)rNz+q1WqM1@;v$
zigwK^6u+Xh=&xN0y>`uZ)`|kU-7F%m*uz%aFIK<dwmtM@D{Bv{ewW$9Yi-}Md)LB{
z*<QcfVXi+hT<dwc`)@JNe|34(7~k0}&2ncD{A=aW;+acdyn3tp^>6?A`}=S4902FB
zx3OP|DWE*mSfNyRXv5FacH}(RdBgeuN0tS8c{KN6N8x0*LkD95Q~z#J_EL%Ey|<je
zmU`-TE3EgG9t$cke#~ww><6sK*f-x7SZ;97p?LO{`l??JyZ*53UL5xNRTfiE6jRsw
z`w@4dQSq~#i0wp${rx>Qn)+;KoqfJuWdHu(*dE*C)0nMpuT<hwA5GvyB00-3_8xOO
z<ImA>Xle)BYx#DsIuz510W4xLVY_=Z!y`I99b69?ewSwk_sY~}-da%2G7GyJcAc>A
zXIQ4;10}%q4Bsa30>E|VRqLykSHq?gV$<-kaXP1;&#LNFd9Z!1+xIX4d5#M>r!?w$
zexhl`EM`t-iCIl+i*2z?{yjF>e(_4pKY(Ym?u3||1G$12v4~k<z0O|8eklXhgYBn-
zwQC2&>De^V=3`6DA>id46dhc3<IJ6x(@z4TQ65vi$98iE6;Jc|ruAL+yDZB!tw-5M
zn3$zY?Ae?s`ZDI|plI$O6-~$wq;mLV(|R}iZq~M!?h1ZAhq+!>vomJND_)I=X85=?
zkF$@n%wBRtng*pgpGw0s2YGOkj?I&KoIxHNdF-(5HJDo*VsFKp6ghvnX3^<%y#I(>
zHSG4onJe$yohjsSRkF_Nl{%Ac3+)D*DN;YrAZV%}i=f43CUeF8eJnW=mqf$@a7rE%
zJU~@QOyn2Xj9>zrM8s6k3=>R11rs4LF&cr*3Z@zXUDqP3fMz8VP!$qWRl)rvu_8}S
zFcmZ>nQHI|b)92|&N0DM&@stWgGZ?A%o{rMf~lZ+Qzt@Q=eVJB+|W60>O`pPv<;oM
zq0=^XBGh$a<<Vw(!q7Qk>O`pP<c3ae=;WqOgu2dxp|fD<ESNeG>N>FkYUi_P=q#E#
z5$ZZ84V{yQ&Ph`zLS5&Sp>xX6Ic4fZsOy|IbWR&Or%jy*b)Al((=l{9rcQ*q&XS?C
zWauoJIuYtRXAGS)hRzvNCqiB4tf6z(&^c@BM5ya@4V|u`(=~M>)ODUPbe=GDo-lPH
z)OF4oI_C_XbEZy&y3Uh^&Xb1Dlcr9Dy3Tn+=e(hF-qeXu*Lg}XtI0}uN-%55Vs}b1
zy~B{0eu7;vm<tAT!DJ%TnWqirX@hy%WFpj=XAI^UgL%eeBGj2@4dz*cdDdhi)R|8S
zrgE951XHc?Pf4a)xDgUlImx0?bJ3`|Xx2n1YuYf-s%D_gUi-j6(MI9KKoOv<46+DR
zQ5dMi2}`o@>?DB7F*6dXLSiauFi?qA2C6~HKqXW#$v_ceG|E6FHi@XF@>()b2|X}S
zgc!QO!ayZ9iHNBtmkd-w1(OUEq0$Khl~}=qfof1PPze=GGEjs{Ck#|#1rr9ULCHWR
zR4~av5h|T9P>B^x7^ns%1C>z0Bm+gLbizO-Rxn|p8k7uFLIsly6rs`y1C?08gn?>M
zGEfN>Ofpb}N+%3dVg(ZhszJ#>B~&oUKoKgPFi?pVOc<yJB?FaE!6XAksC2?WB~~zD
zpc<46R6+%l3>2Z#2?Lc_!GwWoP%=;n6-+Wvgi0q2RAL1a2C6~HKqXW#$v_b*oiI>|
z6-*eY1|<WPP{AYvMW}SbKqXc%VW1k63{*k|lMEE0(g_2VSiyvWYEUvz2^CB-P=rb+
z3{+wT69%e5$v`DkFv&m>DxEM;i4{y3s0Jkil~BPX14XEG!ayZfFkzq?lnhit1(OUE
zq0$Khl~}=qfof1PPze=GGEjs{Ck#|#1rr9ULCHWRR4~av5h|T9P>B^x7^ns%1C>z0
zBm+gLbizO-Rxn|p8k7uFLIsly6rs`y14X16C?efJ5$XntP%}`C2?N!bWS|<83{+#n
zKs6=|RAZ8XYD_XvjR^zQm@rU{Nd~Gh$v`zG3{+#nKs6>AsKz7%)tE3)MC$CqKoQ}L
ziOD1bMTpa&LSm}9g@Gbca|;7Sq~?|k6rq}1GEjs*a~FoNP&O*=h(D`)^oMjePrK^i
z-mjm}(!W%C??7)ktgw5v3dg-#qm4%!-)4B{a<xwF25p+OY1!^<`zl^rjVA8!yPJ5q
zGO@=C?uGVMuR8%iw^Ewog-`Qrf?k>7pYna`<73#i<2##tno$db=;Dn_XB^K6RrO!I
zh}Sgq63E7|d!;!(`{@*$$im$i)^CQD7}?xu`Hq8zfYDUl($H`B*ay_+cSX-My)|Kb
zG$0Y59QL|B>;7gk1}abeN%dN)I$kUM=;}4CdQDWXVSIY^n)}1mYlH28w0o)QJo5zQ
zJ*~Va%6qBu-ZAC9q`aRlkJoTNTD`B8_eFU>Ro*|Qyq}b>r_1M_pnP2`Ul--;sq*z>
z%GZ<fjdc03Cn(?0$~Q#$Myh<{nDULJd^24>{{-cmTKT3Z-%OQn9#g)Vly9ZWk3T{A
zmR7zc%C}PGTgQ}d4Yun!TFO%8le=E69eApsw`}4CsM+V{#r>S5N#DMyG<d`~l1BEK
zY0~#$Dh-}Dj--)&W}5W<luCn#k0WVhpP43oU!>CDN#sZx*=MFnU*D-Tcq}=RM)sL$
z(${G!4W3bsq>+7Qn)LOSN`nWMBWYw`lEw+dmk{>_FAS;{KB{=(+Uh2Y;!=Uz4F4+V
zw;pePvd%M1?6NG55arn3y1U?o@T^1DXe`28>)q@gbGaARFJ}fz{2%V+JXSxC;k!a_
zcoW}mVitYb7<(9fOtlhn#MVdrPQ=IA`y1BAZV}x#@d*NNPB-E^8y34UT6(avej~mi
z1{kps-??F}_8Y&8tX*5|dG>bXte(@pJXFsGtx#S(li_Musa7sxdf<hV!OcItz4cys
z^X*&lA8-Gmymj-Pw{LIVxcLrqXN3`tCUydUwTsvAaN&U!bi6Cft>%NCx5^HWLC4@H
zbZmeB%ilbVh!ICYuihEW?gZ`Co)w7k#TEs-b0c>r=mxLIUY<oaqOHh^22WFxJ<B~8
zbZI&d)5d?>WFlc<C#d&^R?MdrI&!P?0Zeg14MAb;pnLH`X@ytr|AMh1CeZwSzb}8P
zHwpLgNI^tCg~4`Ya|X?pZ2qiMSG~`one@&D)z=d20-CKj=+;_9qDF@jq0wm(ff^l3
zvPIq0AT9;sFtJDOL+YdBTNGQOvm`pLTL(SV>d>*y$RFRKZU)IK=Sz$H%*VL44<(aS
zl1UPUyp{8uBmEGX(3}D{Y0hCl!<Z`5;h2)s!I;KLhmtcyw1eiw3+_*Y@U_57pMV&>
z!^6|`^I)yl&m9515v<i;iQmLQPo{L2g8Jo3<_OS2cQOE{#)r*Nu49u`FKkyTxTJ9>
zcPbURTV}2^tXIyn>+(LpednG+#|pdtd`^88qq~AGWkI|ki7&`qlI=wqy(D+PlDn$h
z)#T2TJ3J3l`MTUS@HMxXlosDr=}TK}od5ZgNtVH1cRCrg!I!hg#m7a<M!zLb*drW%
zTs(*;#i{$RenL4;Bt5RuFT=zU@i2_=>;3(|e=iQOuV1DwY+erYB)_nwZhh+4Zg_k*
z?N@n0TH++<O{<(Q=Pi7ubDp`5)uOjDoXO`b6hiyLaK_H@3|2ylUZ5jX)VZ>7o#uA1
zeI@rCJ^qK?dQTZK$MXj*IbL|J+&Z$}94-HC@!O(Rh6X%#(`W2&i@ZFzR}=v)pqHG%
zhbvx)6E1%ERu)wIY>$?2`fx^{aS`<T%$*$Kda@AIFSAXzM2lnw%jPEgi0E(FwEE6u
zEejuyuOEIg6-%aA{Iog2Uj@$QX;7^&=;GTt=ktSmixgz(Rxi_yk4=YK9kg%<VAN*`
zP-U06SiEp+VM!D#Ag*Y9kUt^$STM_UGhoy6%5I)k&5Y9=lb??Zy-Ee&H|b;iVEfr#
n<s}*5YO$D$>09=(N>k&!YOGLWusz*dPKdx}aD9f}YM=cdEnm!P

literal 0
HcmV?d00001

-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 05/49] virtio: move VirtQueueElement at the beginning of the structs
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (4 preceding siblings ...)
  2016-02-04 21:51 ` [Qemu-devel] [PULL 04/49] tests: pc: acpi: add expected DSDT.bridge blobs and update DSDT blobs Michael S. Tsirkin
@ 2016-02-04 21:51 ` Michael S. Tsirkin
  2016-02-04 21:51 ` [Qemu-devel] [PULL 06/49] virtio: move allocation to virtqueue_pop/vring_pop Michael S. Tsirkin
                   ` (43 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Cornelia Huck, Peter Maydell, Eduardo Habkost, Paolo Bonzini

From: Paolo Bonzini <pbonzini@redhat.com>

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 <pbonzini@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 include/hw/virtio/virtio-blk.h  |  2 +-
 include/hw/virtio/virtio-scsi.h | 13 ++++++-------
 hw/scsi/virtio-scsi.c           |  3 +--
 3 files changed, 8 insertions(+), 10 deletions(-)

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;
 
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 1500c42..7fdf6ad 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -45,8 +45,7 @@ VirtIOSCSIReq *virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq)
 {
     VirtIOSCSIReq *req;
     VirtIOSCSICommon *vs = (VirtIOSCSICommon *)s;
-    const size_t zero_skip = offsetof(VirtIOSCSIReq, elem)
-                             + sizeof(VirtQueueElement);
+    const size_t zero_skip = offsetof(VirtIOSCSIReq, vring);
 
     req = g_malloc(sizeof(*req) + vs->cdb_size);
     req->vq = vq;
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 06/49] virtio: move allocation to virtqueue_pop/vring_pop
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (5 preceding siblings ...)
  2016-02-04 21:51 ` [Qemu-devel] [PULL 05/49] virtio: move VirtQueueElement at the beginning of the structs Michael S. Tsirkin
@ 2016-02-04 21:51 ` Michael S. Tsirkin
  2016-02-05 12:52   ` Peter Maydell
  2016-02-04 21:51 ` [Qemu-devel] [PULL 07/49] virtio: introduce qemu_get/put_virtqueue_element Michael S. Tsirkin
                   ` (42 subsequent siblings)
  49 siblings, 1 reply; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Gerd Hoffmann, Eduardo Habkost,
	qemu-block, Jason Wang, Amit Shah, Aneesh Kumar K.V,
	Stefan Hajnoczi, Cornelia Huck, Paolo Bonzini, Greg Kurz

From: Paolo Bonzini <pbonzini@redhat.com>

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 <pbonzini@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
 hw/9pfs/virtio-9p.h                 |  2 +-
 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 +-
 hw/9pfs/9p.c                        |  2 +-
 hw/9pfs/virtio-9p-device.c          | 17 ++++----
 hw/block/dataplane/virtio-blk.c     | 11 +++--
 hw/block/virtio-blk.c               | 15 +++----
 hw/char/virtio-serial-bus.c         | 80 +++++++++++++++++++++++--------------
 hw/display/virtio-gpu.c             | 21 ++++++----
 hw/input/virtio-input.c             | 24 +++++++----
 hw/net/virtio-net.c                 | 69 ++++++++++++++++++++------------
 hw/scsi/virtio-scsi-dataplane.c     | 15 +++----
 hw/scsi/virtio-scsi.c               | 18 ++++-----
 hw/virtio/dataplane/vring.c         | 18 +++++----
 hw/virtio/virtio-balloon.c          | 22 ++++++----
 hw/virtio/virtio-rng.c              | 10 +++--
 hw/virtio/virtio.c                  | 12 ++++--
 roms/seabios                        |  2 +-
 23 files changed, 210 insertions(+), 143 deletions(-)

diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 1cdf0a2..7f6d885 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -11,7 +11,7 @@ typedef struct V9fsVirtioState
     VirtQueue *vq;
     size_t config_size;
     V9fsPDU pdus[MAX_REQ];
-    VirtQueueElement elems[MAX_REQ];
+    VirtQueueElement *elems[MAX_REQ];
     V9fsState state;
 } V9fsVirtioState;
 
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,
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index 15fb0ab..db5f478 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -1587,7 +1587,7 @@ static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,
     int read_count;
     int64_t xattr_len;
     V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
-    VirtQueueElement *elem = &v->elems[pdu->idx];
+    VirtQueueElement *elem = v->elems[pdu->idx];
 
     xattr_len = fidp->fs.xattr.len;
     read_count = xattr_len - off;
diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index c5f7b92..a38850e 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -26,10 +26,12 @@ void virtio_9p_push_and_notify(V9fsPDU *pdu)
 {
     V9fsState *s = pdu->s;
     V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
-    VirtQueueElement *elem = &v->elems[pdu->idx];
+    VirtQueueElement *elem = v->elems[pdu->idx];
 
     /* push onto queue and notify */
     virtqueue_push(v->vq, elem, pdu->size);
+    g_free(elem);
+    v->elems[pdu->idx] = NULL;
 
     /* FIXME: we should batch these completions */
     virtio_notify(VIRTIO_DEVICE(v), v->vq);
@@ -48,10 +50,10 @@ static void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq)
             uint8_t id;
             uint16_t tag_le;
         } QEMU_PACKED out;
-        VirtQueueElement *elem = &v->elems[pdu->idx];
+        VirtQueueElement *elem;
 
-        len = virtqueue_pop(vq, elem);
-        if (!len) {
+        elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
+        if (!elem) {
             pdu_free(pdu);
             break;
         }
@@ -59,6 +61,7 @@ static void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq)
         BUG_ON(elem->out_num == 0 || elem->in_num == 0);
         QEMU_BUILD_BUG_ON(sizeof out != 7);
 
+        v->elems[pdu->idx] = elem;
         len = iov_to_buf(elem->out_sg, elem->out_num, 0,
                          &out, sizeof out);
         BUG_ON(len != sizeof out);
@@ -141,7 +144,7 @@ ssize_t virtio_pdu_vmarshal(V9fsPDU *pdu, size_t offset,
 {
     V9fsState *s = pdu->s;
     V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
-    VirtQueueElement *elem = &v->elems[pdu->idx];
+    VirtQueueElement *elem = v->elems[pdu->idx];
 
     return v9fs_iov_vmarshal(elem->in_sg, elem->in_num, offset, 1, fmt, ap);
 }
@@ -151,7 +154,7 @@ ssize_t virtio_pdu_vunmarshal(V9fsPDU *pdu, size_t offset,
 {
     V9fsState *s = pdu->s;
     V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
-    VirtQueueElement *elem = &v->elems[pdu->idx];
+    VirtQueueElement *elem = v->elems[pdu->idx];
 
     return v9fs_iov_vunmarshal(elem->out_sg, elem->out_num, offset, 1, fmt, ap);
 }
@@ -161,7 +164,7 @@ void virtio_init_iov_from_pdu(V9fsPDU *pdu, struct iovec **piov,
 {
     V9fsState *s = pdu->s;
     V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
-    VirtQueueElement *elem = &v->elems[pdu->idx];
+    VirtQueueElement *elem = v->elems[pdu->idx];
 
     if (is_write) {
         *piov = elem->out_sg;
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index ee0c4d4..0d99781 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -100,20 +100,19 @@ static void handle_notify(EventNotifier *e)
     blk_io_plug(s->conf->conf.blk);
     for (;;) {
         MultiReqBuffer mrb = {};
-        int ret;
 
         /* Disable guest->host notifies to avoid unnecessary vmexits */
         vring_disable_notification(s->vdev, &s->vring);
 
         for (;;) {
-            VirtIOBlockReq *req = virtio_blk_alloc_request(vblk);
+            VirtIOBlockReq *req = vring_pop(s->vdev, &s->vring,
+                                            sizeof(VirtIOBlockReq));
 
-            ret = vring_pop(s->vdev, &s->vring, &req->elem);
-            if (ret < 0) {
-                virtio_blk_free_request(req);
+            if (req == NULL) {
                 break; /* no more requests */
             }
 
+            virtio_blk_init_request(vblk, req);
             trace_virtio_blk_data_plane_process_request(s, req->elem.out_num,
                                                         req->elem.in_num,
                                                         req->elem.index);
@@ -125,7 +124,7 @@ static void handle_notify(EventNotifier *e)
             virtio_blk_submit_multireq(s->conf->conf.blk, &mrb);
         }
 
-        if (likely(ret == -EAGAIN)) { /* vring emptied */
+        if (likely(!vring_more_avail(s->vdev, &s->vring))) { /* vring emptied */
             /* Re-enable guest->host notifies and stop processing the vring.
              * But if the guest has snuck in more descriptors, keep processing.
              */
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 11bedff..bf70b52 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -29,15 +29,13 @@
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/virtio-access.h"
 
-VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s)
+void virtio_blk_init_request(VirtIOBlock *s, VirtIOBlockReq *req)
 {
-    VirtIOBlockReq *req = g_new(VirtIOBlockReq, 1);
     req->dev = s;
     req->qiov.size = 0;
     req->in_len = 0;
     req->next = NULL;
     req->mr_next = NULL;
-    return req;
 }
 
 void virtio_blk_free_request(VirtIOBlockReq *req)
@@ -193,13 +191,11 @@ out:
 
 static VirtIOBlockReq *virtio_blk_get_request(VirtIOBlock *s)
 {
-    VirtIOBlockReq *req = virtio_blk_alloc_request(s);
+    VirtIOBlockReq *req = virtqueue_pop(s->vq, sizeof(VirtIOBlockReq));
 
-    if (!virtqueue_pop(s->vq, &req->elem)) {
-        virtio_blk_free_request(req);
-        return NULL;
+    if (req) {
+        virtio_blk_init_request(s, req);
     }
-
     return req;
 }
 
@@ -836,7 +832,8 @@ static int virtio_blk_load_device(VirtIODevice *vdev, QEMUFile *f,
     VirtIOBlock *s = VIRTIO_BLK(vdev);
 
     while (qemu_get_sbyte(f)) {
-        VirtIOBlockReq *req = virtio_blk_alloc_request(s);
+        VirtIOBlockReq *req = g_new(VirtIOBlockReq, 1);
+        virtio_blk_init_request(s, req);
         qemu_get_buffer(f, (unsigned char *)&req->elem,
                         sizeof(VirtQueueElement));
         req->next = s->rq;
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index 8d5c740..cf3d12b 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -83,7 +83,7 @@ static bool use_multiport(VirtIOSerial *vser)
 static size_t write_to_port(VirtIOSerialPort *port,
                             const uint8_t *buf, size_t size)
 {
-    VirtQueueElement elem;
+    VirtQueueElement *elem;
     VirtQueue *vq;
     size_t offset;
 
@@ -96,15 +96,17 @@ static size_t write_to_port(VirtIOSerialPort *port,
     while (offset < size) {
         size_t len;
 
-        if (!virtqueue_pop(vq, &elem)) {
+        elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
+        if (!elem) {
             break;
         }
 
-        len = iov_from_buf(elem.in_sg, elem.in_num, 0,
+        len = iov_from_buf(elem->in_sg, elem->in_num, 0,
                            buf + offset, size - offset);
         offset += len;
 
-        virtqueue_push(vq, &elem, len);
+        virtqueue_push(vq, elem, len);
+        g_free(elem);
     }
 
     virtio_notify(VIRTIO_DEVICE(port->vser), vq);
@@ -113,13 +115,18 @@ static size_t write_to_port(VirtIOSerialPort *port,
 
 static void discard_vq_data(VirtQueue *vq, VirtIODevice *vdev)
 {
-    VirtQueueElement elem;
+    VirtQueueElement *elem;
 
     if (!virtio_queue_ready(vq)) {
         return;
     }
-    while (virtqueue_pop(vq, &elem)) {
-        virtqueue_push(vq, &elem, 0);
+    for (;;) {
+        elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
+        if (!elem) {
+            break;
+        }
+        virtqueue_push(vq, elem, 0);
+        g_free(elem);
     }
     virtio_notify(vdev, vq);
 }
@@ -138,21 +145,22 @@ static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
         unsigned int i;
 
         /* Pop an elem only if we haven't left off a previous one mid-way */
-        if (!port->elem.out_num) {
-            if (!virtqueue_pop(vq, &port->elem)) {
+        if (!port->elem) {
+            port->elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
+            if (!port->elem) {
                 break;
             }
             port->iov_idx = 0;
             port->iov_offset = 0;
         }
 
-        for (i = port->iov_idx; i < port->elem.out_num; i++) {
+        for (i = port->iov_idx; i < port->elem->out_num; i++) {
             size_t buf_size;
             ssize_t ret;
 
-            buf_size = port->elem.out_sg[i].iov_len - port->iov_offset;
+            buf_size = port->elem->out_sg[i].iov_len - port->iov_offset;
             ret = vsc->have_data(port,
-                                  port->elem.out_sg[i].iov_base
+                                  port->elem->out_sg[i].iov_base
                                   + port->iov_offset,
                                   buf_size);
             if (port->throttled) {
@@ -167,8 +175,9 @@ static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
         if (port->throttled) {
             break;
         }
-        virtqueue_push(vq, &port->elem, 0);
-        port->elem.out_num = 0;
+        virtqueue_push(vq, port->elem, 0);
+        g_free(port->elem);
+        port->elem = NULL;
     }
     virtio_notify(vdev, vq);
 }
@@ -185,22 +194,26 @@ static void flush_queued_data(VirtIOSerialPort *port)
 
 static size_t send_control_msg(VirtIOSerial *vser, void *buf, size_t len)
 {
-    VirtQueueElement elem;
+    VirtQueueElement *elem;
     VirtQueue *vq;
 
     vq = vser->c_ivq;
     if (!virtio_queue_ready(vq)) {
         return 0;
     }
-    if (!virtqueue_pop(vq, &elem)) {
+
+    elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
+    if (!elem) {
         return 0;
     }
 
     /* TODO: detect a buffer that's too short, set NEEDS_RESET */
-    iov_from_buf(elem.in_sg, elem.in_num, 0, buf, len);
+    iov_from_buf(elem->in_sg, elem->in_num, 0, buf, len);
 
-    virtqueue_push(vq, &elem, len);
+    virtqueue_push(vq, elem, len);
     virtio_notify(VIRTIO_DEVICE(vser), vq);
+    g_free(elem);
+
     return len;
 }
 
@@ -414,7 +427,7 @@ static void control_in(VirtIODevice *vdev, VirtQueue *vq)
 
 static void control_out(VirtIODevice *vdev, VirtQueue *vq)
 {
-    VirtQueueElement elem;
+    VirtQueueElement *elem;
     VirtIOSerial *vser;
     uint8_t *buf;
     size_t len;
@@ -423,10 +436,15 @@ static void control_out(VirtIODevice *vdev, VirtQueue *vq)
 
     len = 0;
     buf = NULL;
-    while (virtqueue_pop(vq, &elem)) {
+    for (;;) {
         size_t cur_len;
 
-        cur_len = iov_size(elem.out_sg, elem.out_num);
+        elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
+        if (!elem) {
+            break;
+        }
+
+        cur_len = iov_size(elem->out_sg, elem->out_num);
         /*
          * Allocate a new buf only if we didn't have one previously or
          * if the size of the buf differs
@@ -437,10 +455,11 @@ static void control_out(VirtIODevice *vdev, VirtQueue *vq)
             buf = g_malloc(cur_len);
             len = cur_len;
         }
-        iov_to_buf(elem.out_sg, elem.out_num, 0, buf, cur_len);
+        iov_to_buf(elem->out_sg, elem->out_num, 0, buf, cur_len);
 
         handle_control_message(vser, buf, cur_len);
-        virtqueue_push(vq, &elem, 0);
+        virtqueue_push(vq, elem, 0);
+        g_free(elem);
     }
     g_free(buf);
     virtio_notify(vdev, vq);
@@ -620,7 +639,7 @@ static void virtio_serial_save_device(VirtIODevice *vdev, QEMUFile *f)
         qemu_put_byte(f, port->host_connected);
 
 	elem_popped = 0;
-        if (port->elem.out_num) {
+        if (port->elem) {
             elem_popped = 1;
         }
         qemu_put_be32s(f, &elem_popped);
@@ -628,8 +647,8 @@ static void virtio_serial_save_device(VirtIODevice *vdev, QEMUFile *f)
             qemu_put_be32s(f, &port->iov_idx);
             qemu_put_be64s(f, &port->iov_offset);
 
-            qemu_put_buffer(f, (unsigned char *)&port->elem,
-                            sizeof(port->elem));
+            qemu_put_buffer(f, (unsigned char *)port->elem,
+                            sizeof(VirtQueueElement));
         }
     }
 }
@@ -704,9 +723,10 @@ static int fetch_active_ports_list(QEMUFile *f, int version_id,
                 qemu_get_be32s(f, &port->iov_idx);
                 qemu_get_be64s(f, &port->iov_offset);
 
-                qemu_get_buffer(f, (unsigned char *)&port->elem,
-                                sizeof(port->elem));
-                virtqueue_map(&port->elem);
+                port->elem = g_new(VirtQueueElement, 1);
+                qemu_get_buffer(f, (unsigned char *)port->elem,
+                                sizeof(VirtQueueElement));
+                virtqueue_map(port->elem);
 
                 /*
                  *  Port was throttled on source machine.  Let's
@@ -928,7 +948,7 @@ static void virtser_port_device_realize(DeviceState *dev, Error **errp)
         return;
     }
 
-    port->elem.out_num = 0;
+    port->elem = NULL;
 }
 
 static void virtser_port_device_plug(HotplugHandler *hotplug_dev,
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 1cb4002..ddf3bfb 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -804,16 +804,15 @@ static void virtio_gpu_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
     }
 #endif
 
-    cmd = g_new(struct virtio_gpu_ctrl_command, 1);
-    while (virtqueue_pop(vq, &cmd->elem)) {
+    cmd = virtqueue_pop(vq, sizeof(struct virtio_gpu_ctrl_command));
+    while (cmd) {
         cmd->vq = vq;
         cmd->error = 0;
         cmd->finished = false;
         cmd->waiting = false;
         QTAILQ_INSERT_TAIL(&g->cmdq, cmd, next);
-        cmd = g_new(struct virtio_gpu_ctrl_command, 1);
+        cmd = virtqueue_pop(vq, sizeof(struct virtio_gpu_ctrl_command));
     }
-    g_free(cmd);
 
     virtio_gpu_process_cmdq(g);
 
@@ -833,15 +832,20 @@ static void virtio_gpu_ctrl_bh(void *opaque)
 static void virtio_gpu_handle_cursor(VirtIODevice *vdev, VirtQueue *vq)
 {
     VirtIOGPU *g = VIRTIO_GPU(vdev);
-    VirtQueueElement elem;
+    VirtQueueElement *elem;
     size_t s;
     struct virtio_gpu_update_cursor cursor_info;
 
     if (!virtio_queue_ready(vq)) {
         return;
     }
-    while (virtqueue_pop(vq, &elem)) {
-        s = iov_to_buf(elem.out_sg, elem.out_num, 0,
+    for (;;) {
+        elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
+        if (!elem) {
+            break;
+        }
+
+        s = iov_to_buf(elem->out_sg, elem->out_num, 0,
                        &cursor_info, sizeof(cursor_info));
         if (s != sizeof(cursor_info)) {
             qemu_log_mask(LOG_GUEST_ERROR,
@@ -850,8 +854,9 @@ static void virtio_gpu_handle_cursor(VirtIODevice *vdev, VirtQueue *vq)
         } else {
             update_cursor(g, &cursor_info);
         }
-        virtqueue_push(vq, &elem, 0);
+        virtqueue_push(vq, elem, 0);
         virtio_notify(vdev, vq);
+        g_free(elem);
     }
 }
 
diff --git a/hw/input/virtio-input.c b/hw/input/virtio-input.c
index f12ed8a..5061f4c 100644
--- a/hw/input/virtio-input.c
+++ b/hw/input/virtio-input.c
@@ -17,7 +17,7 @@
 
 void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event)
 {
-    VirtQueueElement elem;
+    VirtQueueElement *elem;
     unsigned have, need;
     int i, len;
 
@@ -50,14 +50,16 @@ void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event)
 
     /* ... and finally pass them to the guest */
     for (i = 0; i < vinput->qindex; i++) {
-        if (!virtqueue_pop(vinput->evt, &elem)) {
+        elem = virtqueue_pop(vinput->evt, sizeof(VirtQueueElement));
+        if (!elem) {
             /* should not happen, we've checked for space beforehand */
             fprintf(stderr, "%s: Huh?  No vq elem available ...\n", __func__);
             return;
         }
-        len = iov_from_buf(elem.in_sg, elem.in_num,
+        len = iov_from_buf(elem->in_sg, elem->in_num,
                            0, vinput->queue+i, sizeof(virtio_input_event));
-        virtqueue_push(vinput->evt, &elem, len);
+        virtqueue_push(vinput->evt, elem, len);
+        g_free(elem);
     }
     virtio_notify(VIRTIO_DEVICE(vinput), vinput->evt);
     vinput->qindex = 0;
@@ -73,17 +75,23 @@ static void virtio_input_handle_sts(VirtIODevice *vdev, VirtQueue *vq)
     VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(vdev);
     VirtIOInput *vinput = VIRTIO_INPUT(vdev);
     virtio_input_event event;
-    VirtQueueElement elem;
+    VirtQueueElement *elem;
     int len;
 
-    while (virtqueue_pop(vinput->sts, &elem)) {
+    for (;;) {
+        elem = virtqueue_pop(vinput->sts, sizeof(VirtQueueElement));
+        if (!elem) {
+            break;
+        }
+
         memset(&event, 0, sizeof(event));
-        len = iov_to_buf(elem.out_sg, elem.out_num,
+        len = iov_to_buf(elem->out_sg, elem->out_num,
                          0, &event, sizeof(event));
         if (vic->handle_status) {
             vic->handle_status(vinput, &event);
         }
-        virtqueue_push(vinput->sts, &elem, len);
+        virtqueue_push(vinput->sts, elem, len);
+        g_free(elem);
     }
     virtio_notify(vdev, vinput->sts);
 }
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index fde8dd3..de696e8 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -819,20 +819,24 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
     VirtIONet *n = VIRTIO_NET(vdev);
     struct virtio_net_ctrl_hdr ctrl;
     virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
-    VirtQueueElement elem;
+    VirtQueueElement *elem;
     size_t s;
     struct iovec *iov, *iov2;
     unsigned int iov_cnt;
 
-    while (virtqueue_pop(vq, &elem)) {
-        if (iov_size(elem.in_sg, elem.in_num) < sizeof(status) ||
-            iov_size(elem.out_sg, elem.out_num) < sizeof(ctrl)) {
+    for (;;) {
+        elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
+        if (!elem) {
+            break;
+        }
+        if (iov_size(elem->in_sg, elem->in_num) < sizeof(status) ||
+            iov_size(elem->out_sg, elem->out_num) < sizeof(ctrl)) {
             error_report("virtio-net ctrl missing headers");
             exit(1);
         }
 
-        iov_cnt = elem.out_num;
-        iov2 = iov = g_memdup(elem.out_sg, sizeof(struct iovec) * elem.out_num);
+        iov_cnt = elem->out_num;
+        iov2 = iov = g_memdup(elem->out_sg, sizeof(struct iovec) * elem->out_num);
         s = iov_to_buf(iov, iov_cnt, 0, &ctrl, sizeof(ctrl));
         iov_discard_front(&iov, &iov_cnt, sizeof(ctrl));
         if (s != sizeof(ctrl)) {
@@ -851,12 +855,13 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
             status = virtio_net_handle_offloads(n, ctrl.cmd, iov, iov_cnt);
         }
 
-        s = iov_from_buf(elem.in_sg, elem.in_num, 0, &status, sizeof(status));
+        s = iov_from_buf(elem->in_sg, elem->in_num, 0, &status, sizeof(status));
         assert(s == sizeof(status));
 
-        virtqueue_push(vq, &elem, sizeof(status));
+        virtqueue_push(vq, elem, sizeof(status));
         virtio_notify(vdev, vq);
         g_free(iov2);
+        g_free(elem);
     }
 }
 
@@ -1045,13 +1050,14 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t
     offset = i = 0;
 
     while (offset < size) {
-        VirtQueueElement elem;
+        VirtQueueElement *elem;
         int len, total;
-        const struct iovec *sg = elem.in_sg;
+        const struct iovec *sg;
 
         total = 0;
 
-        if (virtqueue_pop(q->rx_vq, &elem) == 0) {
+        elem = virtqueue_pop(q->rx_vq, sizeof(VirtQueueElement));
+        if (!elem) {
             if (i == 0)
                 return -1;
             error_report("virtio-net unexpected empty queue: "
@@ -1064,21 +1070,22 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t
             exit(1);
         }
 
-        if (elem.in_num < 1) {
+        if (elem->in_num < 1) {
             error_report("virtio-net receive queue contains no in buffers");
             exit(1);
         }
 
+        sg = elem->in_sg;
         if (i == 0) {
             assert(offset == 0);
             if (n->mergeable_rx_bufs) {
                 mhdr_cnt = iov_copy(mhdr_sg, ARRAY_SIZE(mhdr_sg),
-                                    sg, elem.in_num,
+                                    sg, elem->in_num,
                                     offsetof(typeof(mhdr), num_buffers),
                                     sizeof(mhdr.num_buffers));
             }
 
-            receive_header(n, sg, elem.in_num, buf, size);
+            receive_header(n, sg, elem->in_num, buf, size);
             offset = n->host_hdr_len;
             total += n->guest_hdr_len;
             guest_offset = n->guest_hdr_len;
@@ -1087,7 +1094,7 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t
         }
 
         /* copy in packet.  ugh */
-        len = iov_from_buf(sg, elem.in_num, guest_offset,
+        len = iov_from_buf(sg, elem->in_num, guest_offset,
                            buf + offset, size - offset);
         total += len;
         offset += len;
@@ -1095,12 +1102,14 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t
          * must have consumed the complete packet.
          * Otherwise, drop it. */
         if (!n->mergeable_rx_bufs && offset < size) {
-            virtqueue_discard(q->rx_vq, &elem, total);
+            virtqueue_discard(q->rx_vq, elem, total);
+            g_free(elem);
             return size;
         }
 
         /* signal other side */
-        virtqueue_fill(q->rx_vq, &elem, total, i++);
+        virtqueue_fill(q->rx_vq, elem, total, i++);
+        g_free(elem);
     }
 
     if (mhdr_cnt) {
@@ -1124,10 +1133,11 @@ static void virtio_net_tx_complete(NetClientState *nc, ssize_t len)
     VirtIONetQueue *q = virtio_net_get_subqueue(nc);
     VirtIODevice *vdev = VIRTIO_DEVICE(n);
 
-    virtqueue_push(q->tx_vq, &q->async_tx.elem, 0);
+    virtqueue_push(q->tx_vq, q->async_tx.elem, 0);
     virtio_notify(vdev, q->tx_vq);
 
-    q->async_tx.elem.out_num = 0;
+    g_free(q->async_tx.elem);
+    q->async_tx.elem = NULL;
 
     virtio_queue_set_notification(q->tx_vq, 1);
     virtio_net_flush_tx(q);
@@ -1138,25 +1148,31 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
 {
     VirtIONet *n = q->n;
     VirtIODevice *vdev = VIRTIO_DEVICE(n);
-    VirtQueueElement elem;
+    VirtQueueElement *elem;
     int32_t num_packets = 0;
     int queue_index = vq2q(virtio_get_queue_index(q->tx_vq));
     if (!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)) {
         return num_packets;
     }
 
-    if (q->async_tx.elem.out_num) {
+    if (q->async_tx.elem) {
         virtio_queue_set_notification(q->tx_vq, 0);
         return num_packets;
     }
 
-    while (virtqueue_pop(q->tx_vq, &elem)) {
+    for (;;) {
         ssize_t ret;
-        unsigned int out_num = elem.out_num;
-        struct iovec *out_sg = &elem.out_sg[0];
-        struct iovec sg[VIRTQUEUE_MAX_SIZE], sg2[VIRTQUEUE_MAX_SIZE + 1];
+        unsigned int out_num;
+        struct iovec sg[VIRTQUEUE_MAX_SIZE], sg2[VIRTQUEUE_MAX_SIZE + 1], *out_sg;
         struct virtio_net_hdr_mrg_rxbuf mhdr;
 
+        elem = virtqueue_pop(q->tx_vq, sizeof(VirtQueueElement));
+        if (!elem) {
+            break;
+        }
+
+        out_num = elem->out_num;
+        out_sg = elem->out_sg;
         if (out_num < 1) {
             error_report("virtio-net header not in first element");
             exit(1);
@@ -1208,8 +1224,9 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
         }
 
 drop:
-        virtqueue_push(q->tx_vq, &elem, 0);
+        virtqueue_push(q->tx_vq, elem, 0);
         virtio_notify(vdev, q->tx_vq);
+        g_free(elem);
 
         if (++num_packets >= n->tx_burst) {
             break;
diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c
index c77b3a1..8340326 100644
--- a/hw/scsi/virtio-scsi-dataplane.c
+++ b/hw/scsi/virtio-scsi-dataplane.c
@@ -81,15 +81,16 @@ fail_vring:
 VirtIOSCSIReq *virtio_scsi_pop_req_vring(VirtIOSCSI *s,
                                          VirtIOSCSIVring *vring)
 {
-    VirtIOSCSIReq *req = virtio_scsi_init_req(s, NULL);
-    int r;
+    VirtIOSCSICommon *vs = (VirtIOSCSICommon *)s;
+    VirtIOSCSIReq *req;
 
-    req->vring = vring;
-    r = vring_pop((VirtIODevice *)s, &vring->vring, &req->elem);
-    if (r < 0) {
-        virtio_scsi_free_req(req);
-        req = NULL;
+    req = vring_pop((VirtIODevice *)s, &vring->vring,
+                    sizeof(VirtIOSCSIReq) + vs->cdb_size);
+    if (!req) {
+        return NULL;
     }
+    virtio_scsi_init_req(s, NULL, req);
+    req->vring = vring;
     return req;
 }
 
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 7fdf6ad..50a3cb2 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -41,19 +41,15 @@ static inline SCSIDevice *virtio_scsi_device_find(VirtIOSCSI *s, uint8_t *lun)
     return scsi_device_find(&s->bus, 0, lun[1], virtio_scsi_get_lun(lun));
 }
 
-VirtIOSCSIReq *virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq)
+void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq *req)
 {
-    VirtIOSCSIReq *req;
-    VirtIOSCSICommon *vs = (VirtIOSCSICommon *)s;
     const size_t zero_skip = offsetof(VirtIOSCSIReq, vring);
 
-    req = g_malloc(sizeof(*req) + vs->cdb_size);
     req->vq = vq;
     req->dev = s;
     qemu_sglist_init(&req->qsgl, DEVICE(s), 8, &address_space_memory);
     qemu_iovec_init(&req->resp_iov, 1);
     memset((uint8_t *)req + zero_skip, 0, sizeof(*req) - zero_skip);
-    return req;
 }
 
 void virtio_scsi_free_req(VirtIOSCSIReq *req)
@@ -174,11 +170,14 @@ static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
 
 static VirtIOSCSIReq *virtio_scsi_pop_req(VirtIOSCSI *s, VirtQueue *vq)
 {
-    VirtIOSCSIReq *req = virtio_scsi_init_req(s, vq);
-    if (!virtqueue_pop(vq, &req->elem)) {
-        virtio_scsi_free_req(req);
+    VirtIOSCSICommon *vs = (VirtIOSCSICommon *)s;
+    VirtIOSCSIReq *req;
+
+    req = virtqueue_pop(vq, sizeof(VirtIOSCSIReq) + vs->cdb_size);
+    if (!req) {
         return NULL;
     }
+    virtio_scsi_init_req(s, vq, req);
     return req;
 }
 
@@ -203,8 +202,9 @@ static void *virtio_scsi_load_request(QEMUFile *f, SCSIRequest *sreq)
 
     qemu_get_be32s(f, &n);
     assert(n < vs->conf.num_queues);
-    req = virtio_scsi_init_req(s, vs->cmd_vqs[n]);
+    req = g_malloc(sizeof(VirtIOSCSIReq) + vs->cdb_size);
     qemu_get_buffer(f, (unsigned char *)&req->elem, sizeof(req->elem));
+    virtio_scsi_init_req(s, vs->cmd_vqs[n], req);
 
     virtqueue_map(&req->elem);
 
diff --git a/hw/virtio/dataplane/vring.c b/hw/virtio/dataplane/vring.c
index 1a78df1..4fb84bb 100644
--- a/hw/virtio/dataplane/vring.c
+++ b/hw/virtio/dataplane/vring.c
@@ -389,23 +389,26 @@ static void vring_unmap_element(VirtQueueElement *elem)
  *
  * Stolen from linux/drivers/vhost/vhost.c.
  */
-int vring_pop(VirtIODevice *vdev, Vring *vring,
-              VirtQueueElement *elem)
+void *vring_pop(VirtIODevice *vdev, Vring *vring, size_t sz)
 {
     struct vring_desc desc;
     unsigned int i, head, found = 0, num = vring->vr.num;
     uint16_t avail_idx, last_avail_idx;
+    VirtQueueElement *elem = NULL;
     int ret;
 
-    /* Initialize elem so it can be safely unmapped */
-    elem->in_num = elem->out_num = 0;
-
     /* If there was a fatal error then refuse operation */
     if (vring->broken) {
         ret = -EFAULT;
         goto out;
     }
 
+    assert(sz >= sizeof(VirtQueueElement));
+    elem = g_malloc(sz);
+
+    /* Initialize elem so it can be safely unmapped */
+    elem->in_num = elem->out_num = 0;
+
     /* Check it isn't doing very strange things with descriptor numbers. */
     last_avail_idx = vring->last_avail_idx;
     avail_idx = vring_get_avail_idx(vdev, vring);
@@ -481,7 +484,7 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
             virtio_tswap16(vdev, vring->last_avail_idx);
     }
 
-    return head;
+    return elem;
 
 out:
     assert(ret < 0);
@@ -489,7 +492,8 @@ out:
         vring->broken = true;
     }
     vring_unmap_element(elem);
-    return ret;
+    g_free(elem);
+    return NULL;
 }
 
 /* After we've used one of their buffers, we tell them about it.
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index f5f25a9..5c30203 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -107,8 +107,10 @@ static void balloon_stats_poll_cb(void *opaque)
         return;
     }
 
-    virtqueue_push(s->svq, &s->stats_vq_elem, s->stats_vq_offset);
+    virtqueue_push(s->svq, s->stats_vq_elem, s->stats_vq_offset);
     virtio_notify(vdev, s->svq);
+    g_free(s->stats_vq_elem);
+    s->stats_vq_elem = NULL;
 }
 
 static void balloon_stats_get_all(Object *obj, struct Visitor *v,
@@ -206,14 +208,18 @@ static void balloon_stats_set_poll_interval(Object *obj, struct Visitor *v,
 static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq)
 {
     VirtIOBalloon *s = VIRTIO_BALLOON(vdev);
-    VirtQueueElement elem;
+    VirtQueueElement *elem;
     MemoryRegionSection section;
 
-    while (virtqueue_pop(vq, &elem)) {
+    for (;;) {
         size_t offset = 0;
         uint32_t pfn;
+        elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
+        if (!elem) {
+            return;
+        }
 
-        while (iov_to_buf(elem.out_sg, elem.out_num, offset, &pfn, 4) == 4) {
+        while (iov_to_buf(elem->out_sg, elem->out_num, offset, &pfn, 4) == 4) {
             ram_addr_t pa;
             ram_addr_t addr;
             int p = virtio_ldl_p(vdev, &pfn);
@@ -236,20 +242,22 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq)
             memory_region_unref(section.mr);
         }
 
-        virtqueue_push(vq, &elem, offset);
+        virtqueue_push(vq, elem, offset);
         virtio_notify(vdev, vq);
+        g_free(elem);
     }
 }
 
 static void virtio_balloon_receive_stats(VirtIODevice *vdev, VirtQueue *vq)
 {
     VirtIOBalloon *s = VIRTIO_BALLOON(vdev);
-    VirtQueueElement *elem = &s->stats_vq_elem;
+    VirtQueueElement *elem;
     VirtIOBalloonStat stat;
     size_t offset = 0;
     qemu_timeval tv;
 
-    if (!virtqueue_pop(vq, elem)) {
+    s->stats_vq_elem = elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
+    if (!elem) {
         goto out;
     }
 
diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
index a80fb89..17da2f8 100644
--- a/hw/virtio/virtio-rng.c
+++ b/hw/virtio/virtio-rng.c
@@ -44,7 +44,7 @@ static void chr_read(void *opaque, const void *buf, size_t size)
 {
     VirtIORNG *vrng = opaque;
     VirtIODevice *vdev = VIRTIO_DEVICE(vrng);
-    VirtQueueElement elem;
+    VirtQueueElement *elem;
     size_t len;
     int offset;
 
@@ -56,15 +56,17 @@ static void chr_read(void *opaque, const void *buf, size_t size)
 
     offset = 0;
     while (offset < size) {
-        if (!virtqueue_pop(vrng->vq, &elem)) {
+        elem = virtqueue_pop(vrng->vq, sizeof(VirtQueueElement));
+        if (!elem) {
             break;
         }
-        len = iov_from_buf(elem.in_sg, elem.in_num,
+        len = iov_from_buf(elem->in_sg, elem->in_num,
                            0, buf + offset, size - offset);
         offset += len;
 
-        virtqueue_push(vrng->vq, &elem, len);
+        virtqueue_push(vrng->vq, elem, len);
         trace_virtio_rng_pushed(vrng, len);
+        g_free(elem);
     }
     virtio_notify(vdev, vrng->vq);
 }
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 0603793..229a092 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -501,16 +501,20 @@ void virtqueue_map(VirtQueueElement *elem)
                         0);
 }
 
-int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
+void *virtqueue_pop(VirtQueue *vq, size_t sz)
 {
     unsigned int i, head, max;
     hwaddr desc_pa = vq->vring.desc;
     VirtIODevice *vdev = vq->vdev;
+    VirtQueueElement *elem;
 
-    if (!virtqueue_num_heads(vq, vq->last_avail_idx))
-        return 0;
+    if (!virtqueue_num_heads(vq, vq->last_avail_idx)) {
+        return NULL;
+    }
 
     /* When we start there are none of either input nor output. */
+    assert(sz >= sizeof(VirtQueueElement));
+    elem = g_malloc(sz);
     elem->out_num = elem->in_num = 0;
 
     max = vq->vring.num;
@@ -569,7 +573,7 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
     vq->inuse++;
 
     trace_virtqueue_pop(vq, elem, elem->in_num, elem->out_num);
-    return elem->in_num + elem->out_num;
+    return elem;
 }
 
 /* virtio device */
diff --git a/roms/seabios b/roms/seabios
index 01a84be..33fbe13 160000
--- a/roms/seabios
+++ b/roms/seabios
@@ -1 +1 @@
-Subproject commit 01a84bea2d28a19d2405c1ecac4bdef17683cc0c
+Subproject commit 33fbe13a3e2a01e0ba1087a8feed801a0451db21
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 07/49] virtio: introduce qemu_get/put_virtqueue_element
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (6 preceding siblings ...)
  2016-02-04 21:51 ` [Qemu-devel] [PULL 06/49] virtio: move allocation to virtqueue_pop/vring_pop Michael S. Tsirkin
@ 2016-02-04 21:51 ` Michael S. Tsirkin
  2016-02-04 21:51 ` [Qemu-devel] [PULL 08/49] virtio: introduce virtqueue_alloc_element Michael S. Tsirkin
                   ` (41 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Eduardo Habkost, qemu-block,
	Amit Shah, Stefan Hajnoczi, Cornelia Huck, Paolo Bonzini

From: Paolo Bonzini <pbonzini@redhat.com>

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 <cornelia.huck@de.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 include/hw/virtio/virtio.h  |  2 ++
 hw/block/virtio-blk.c       | 10 +++-------
 hw/char/virtio-serial-bus.c | 10 +++-------
 hw/scsi/virtio-scsi.c       |  7 ++-----
 hw/virtio/virtio.c          | 13 +++++++++++++
 5 files changed, 23 insertions(+), 19 deletions(-)

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,
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index bf70b52..c427698 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -808,8 +808,7 @@ static void virtio_blk_save_device(VirtIODevice *vdev, QEMUFile *f)
 
     while (req) {
         qemu_put_sbyte(f, 1);
-        qemu_put_buffer(f, (unsigned char *)&req->elem,
-                        sizeof(VirtQueueElement));
+        qemu_put_virtqueue_element(f, &req->elem);
         req = req->next;
     }
     qemu_put_sbyte(f, 0);
@@ -832,14 +831,11 @@ static int virtio_blk_load_device(VirtIODevice *vdev, QEMUFile *f,
     VirtIOBlock *s = VIRTIO_BLK(vdev);
 
     while (qemu_get_sbyte(f)) {
-        VirtIOBlockReq *req = g_new(VirtIOBlockReq, 1);
+        VirtIOBlockReq *req;
+        req = qemu_get_virtqueue_element(f, sizeof(VirtIOBlockReq));
         virtio_blk_init_request(s, req);
-        qemu_get_buffer(f, (unsigned char *)&req->elem,
-                        sizeof(VirtQueueElement));
         req->next = s->rq;
         s->rq = req;
-
-        virtqueue_map(&req->elem);
     }
 
     return 0;
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index cf3d12b..99cb683 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -646,9 +646,7 @@ static void virtio_serial_save_device(VirtIODevice *vdev, QEMUFile *f)
         if (elem_popped) {
             qemu_put_be32s(f, &port->iov_idx);
             qemu_put_be64s(f, &port->iov_offset);
-
-            qemu_put_buffer(f, (unsigned char *)port->elem,
-                            sizeof(VirtQueueElement));
+            qemu_put_virtqueue_element(f, port->elem);
         }
     }
 }
@@ -723,10 +721,8 @@ static int fetch_active_ports_list(QEMUFile *f, int version_id,
                 qemu_get_be32s(f, &port->iov_idx);
                 qemu_get_be64s(f, &port->iov_offset);
 
-                port->elem = g_new(VirtQueueElement, 1);
-                qemu_get_buffer(f, (unsigned char *)port->elem,
-                                sizeof(VirtQueueElement));
-                virtqueue_map(port->elem);
+                port->elem =
+                    qemu_get_virtqueue_element(f, sizeof(VirtQueueElement));
 
                 /*
                  *  Port was throttled on source machine.  Let's
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 50a3cb2..5b29bac 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -189,7 +189,7 @@ static void virtio_scsi_save_request(QEMUFile *f, SCSIRequest *sreq)
 
     assert(n < vs->conf.num_queues);
     qemu_put_be32s(f, &n);
-    qemu_put_buffer(f, (unsigned char *)&req->elem, sizeof(req->elem));
+    qemu_put_virtqueue_element(f, &req->elem);
 }
 
 static void *virtio_scsi_load_request(QEMUFile *f, SCSIRequest *sreq)
@@ -202,12 +202,9 @@ static void *virtio_scsi_load_request(QEMUFile *f, SCSIRequest *sreq)
 
     qemu_get_be32s(f, &n);
     assert(n < vs->conf.num_queues);
-    req = g_malloc(sizeof(VirtIOSCSIReq) + vs->cdb_size);
-    qemu_get_buffer(f, (unsigned char *)&req->elem, sizeof(req->elem));
+    req = qemu_get_virtqueue_element(f, sizeof(VirtIOSCSIReq) + vs->cdb_size);
     virtio_scsi_init_req(s, vs->cmd_vqs[n], req);
 
-    virtqueue_map(&req->elem);
-
     if (virtio_scsi_parse_req(req, sizeof(VirtIOSCSICmdReq) + vs->cdb_size,
                               sizeof(VirtIOSCSICmdResp) + vs->sense_size) < 0) {
         error_report("invalid SCSI request migration data");
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 229a092..28fa7fe 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -576,6 +576,19 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
     return elem;
 }
 
+void *qemu_get_virtqueue_element(QEMUFile *f, size_t sz)
+{
+    VirtQueueElement *elem = g_malloc(sz);
+    qemu_get_buffer(f, (uint8_t *)elem, sizeof(VirtQueueElement));
+    virtqueue_map(elem);
+    return elem;
+}
+
+void qemu_put_virtqueue_element(QEMUFile *f, VirtQueueElement *elem)
+{
+    qemu_put_buffer(f, (uint8_t *)elem, sizeof(VirtQueueElement));
+}
+
 /* virtio device */
 static void virtio_notify_vector(VirtIODevice *vdev, uint16_t vector)
 {
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 08/49] virtio: introduce virtqueue_alloc_element
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (7 preceding siblings ...)
  2016-02-04 21:51 ` [Qemu-devel] [PULL 07/49] virtio: introduce qemu_get/put_virtqueue_element Michael S. Tsirkin
@ 2016-02-04 21:51 ` Michael S. Tsirkin
  2016-02-04 21:51 ` [Qemu-devel] [PULL 09/49] virtio: slim down allocation of VirtQueueElements Michael S. Tsirkin
                   ` (40 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Eduardo Habkost, qemu-block, Stefan Hajnoczi,
	Cornelia Huck, Paolo Bonzini

From: Paolo Bonzini <pbonzini@redhat.com>

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 <cornelia.huck@de.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 include/hw/virtio/virtio.h  |   9 ++--
 hw/virtio/dataplane/vring.c |   3 +-
 hw/virtio/virtio.c          | 110 +++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 105 insertions(+), 17 deletions(-)

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);
diff --git a/hw/virtio/dataplane/vring.c b/hw/virtio/dataplane/vring.c
index 4fb84bb..57ada3b 100644
--- a/hw/virtio/dataplane/vring.c
+++ b/hw/virtio/dataplane/vring.c
@@ -403,8 +403,7 @@ void *vring_pop(VirtIODevice *vdev, Vring *vring, size_t sz)
         goto out;
     }
 
-    assert(sz >= sizeof(VirtQueueElement));
-    elem = g_malloc(sz);
+    elem = virtqueue_alloc_element(sz, VIRTQUEUE_MAX_SIZE, VIRTQUEUE_MAX_SIZE);
 
     /* Initialize elem so it can be safely unmapped */
     elem->in_num = elem->out_num = 0;
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 28fa7fe..661a1e1 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -494,11 +494,30 @@ static void virtqueue_map_iovec(struct iovec *sg, hwaddr *addr,
 void virtqueue_map(VirtQueueElement *elem)
 {
     virtqueue_map_iovec(elem->in_sg, elem->in_addr, &elem->in_num,
-                        MIN(ARRAY_SIZE(elem->in_sg), ARRAY_SIZE(elem->in_addr)),
-                        1);
+                        VIRTQUEUE_MAX_SIZE, 1);
     virtqueue_map_iovec(elem->out_sg, elem->out_addr, &elem->out_num,
-                        MIN(ARRAY_SIZE(elem->out_sg), ARRAY_SIZE(elem->out_addr)),
-                        0);
+                        VIRTQUEUE_MAX_SIZE, 0);
+}
+
+void *virtqueue_alloc_element(size_t sz, unsigned out_num, unsigned in_num)
+{
+    VirtQueueElement *elem;
+    size_t in_addr_ofs = QEMU_ALIGN_UP(sz, __alignof__(elem->in_addr[0]));
+    size_t out_addr_ofs = in_addr_ofs + in_num * sizeof(elem->in_addr[0]);
+    size_t out_addr_end = out_addr_ofs + out_num * sizeof(elem->out_addr[0]);
+    size_t in_sg_ofs = QEMU_ALIGN_UP(out_addr_end, __alignof__(elem->in_sg[0]));
+    size_t out_sg_ofs = in_sg_ofs + in_num * sizeof(elem->in_sg[0]);
+    size_t out_sg_end = out_sg_ofs + out_num * sizeof(elem->out_sg[0]);
+
+    assert(sz >= sizeof(VirtQueueElement));
+    elem = g_malloc(out_sg_end);
+    elem->out_num = out_num;
+    elem->in_num = in_num;
+    elem->in_addr = (void *)elem + in_addr_ofs;
+    elem->out_addr = (void *)elem + out_addr_ofs;
+    elem->in_sg = (void *)elem + in_sg_ofs;
+    elem->out_sg = (void *)elem + out_sg_ofs;
+    return elem;
 }
 
 void *virtqueue_pop(VirtQueue *vq, size_t sz)
@@ -513,8 +532,7 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
     }
 
     /* When we start there are none of either input nor output. */
-    assert(sz >= sizeof(VirtQueueElement));
-    elem = g_malloc(sz);
+    elem = virtqueue_alloc_element(sz, VIRTQUEUE_MAX_SIZE, VIRTQUEUE_MAX_SIZE);
     elem->out_num = elem->in_num = 0;
 
     max = vq->vring.num;
@@ -541,14 +559,14 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
         struct iovec *sg;
 
         if (vring_desc_flags(vdev, desc_pa, i) & VRING_DESC_F_WRITE) {
-            if (elem->in_num >= ARRAY_SIZE(elem->in_sg)) {
+            if (elem->in_num >= VIRTQUEUE_MAX_SIZE) {
                 error_report("Too many write descriptors in indirect table");
                 exit(1);
             }
             elem->in_addr[elem->in_num] = vring_desc_addr(vdev, desc_pa, i);
             sg = &elem->in_sg[elem->in_num++];
         } else {
-            if (elem->out_num >= ARRAY_SIZE(elem->out_sg)) {
+            if (elem->out_num >= VIRTQUEUE_MAX_SIZE) {
                 error_report("Too many read descriptors in indirect table");
                 exit(1);
             }
@@ -576,17 +594,87 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
     return elem;
 }
 
+/* Reading and writing a structure directly to QEMUFile is *awful*, but
+ * it is what QEMU has always done by mistake.  We can change it sooner
+ * or later by bumping the version number of the affected vm states.
+ * In the meanwhile, since the in-memory layout of VirtQueueElement
+ * has changed, we need to marshal to and from the layout that was
+ * used before the change.
+ */
+typedef struct VirtQueueElementOld {
+    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];
+} VirtQueueElementOld;
+
 void *qemu_get_virtqueue_element(QEMUFile *f, size_t sz)
 {
-    VirtQueueElement *elem = g_malloc(sz);
-    qemu_get_buffer(f, (uint8_t *)elem, sizeof(VirtQueueElement));
+    VirtQueueElement *elem;
+    VirtQueueElementOld data;
+    int i;
+
+    qemu_get_buffer(f, (uint8_t *)&data, sizeof(VirtQueueElementOld));
+
+    elem = virtqueue_alloc_element(sz, data.out_num, data.in_num);
+    elem->index = data.index;
+
+    for (i = 0; i < elem->in_num; i++) {
+        elem->in_addr[i] = data.in_addr[i];
+    }
+
+    for (i = 0; i < elem->out_num; i++) {
+        elem->out_addr[i] = data.out_addr[i];
+    }
+
+    for (i = 0; i < elem->in_num; i++) {
+        /* Base is overwritten by virtqueue_map.  */
+        elem->in_sg[i].iov_base = 0;
+        elem->in_sg[i].iov_len = data.in_sg[i].iov_len;
+    }
+
+    for (i = 0; i < elem->out_num; i++) {
+        /* Base is overwritten by virtqueue_map.  */
+        elem->out_sg[i].iov_base = 0;
+        elem->out_sg[i].iov_len = data.out_sg[i].iov_len;
+    }
+
     virtqueue_map(elem);
     return elem;
 }
 
 void qemu_put_virtqueue_element(QEMUFile *f, VirtQueueElement *elem)
 {
-    qemu_put_buffer(f, (uint8_t *)elem, sizeof(VirtQueueElement));
+    VirtQueueElementOld data;
+    int i;
+
+    memset(&data, 0, sizeof(data));
+    data.index = elem->index;
+    data.in_num = elem->in_num;
+    data.out_num = elem->out_num;
+
+    for (i = 0; i < elem->in_num; i++) {
+        data.in_addr[i] = elem->in_addr[i];
+    }
+
+    for (i = 0; i < elem->out_num; i++) {
+        data.out_addr[i] = elem->out_addr[i];
+    }
+
+    for (i = 0; i < elem->in_num; i++) {
+        /* Base is overwritten by virtqueue_map when loading.  Do not
+         * save it, as it would leak the QEMU address space layout.  */
+        data.in_sg[i].iov_len = elem->in_sg[i].iov_len;
+    }
+
+    for (i = 0; i < elem->out_num; i++) {
+        /* Do not save iov_base as above.  */
+        data.out_sg[i].iov_len = elem->out_sg[i].iov_len;
+    }
+    qemu_put_buffer(f, (uint8_t *)&data, sizeof(VirtQueueElementOld));
 }
 
 /* virtio device */
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 09/49] virtio: slim down allocation of VirtQueueElements
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (8 preceding siblings ...)
  2016-02-04 21:51 ` [Qemu-devel] [PULL 08/49] virtio: introduce virtqueue_alloc_element Michael S. Tsirkin
@ 2016-02-04 21:51 ` Michael S. Tsirkin
  2016-02-04 21:51 ` [Qemu-devel] [PULL 10/49] vring: " Michael S. Tsirkin
                   ` (39 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Cornelia Huck, Peter Maydell, Eduardo Habkost, Paolo Bonzini

From: Paolo Bonzini <pbonzini@redhat.com>

Build the addresses and s/g lists on the stack, and then copy them
to a VirtQueueElement that is just as big as required to contain this
particular s/g list.  The cost of the copy is minimal compared to that
of a large malloc.

When virtqueue_map is used on the destination side of migration or on
loadvm, the iovecs have already been split at memory region boundary,
so we can just reuse the out_num/in_num we find in the file.

Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/virtio/virtio.c | 82 +++++++++++++++++++++++++++++++++---------------------
 1 file changed, 51 insertions(+), 31 deletions(-)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 661a1e1..c3e00a8 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -448,6 +448,32 @@ int virtqueue_avail_bytes(VirtQueue *vq, unsigned int in_bytes,
     return in_bytes <= in_total && out_bytes <= out_total;
 }
 
+static void virtqueue_map_desc(unsigned int *p_num_sg, hwaddr *addr, struct iovec *iov,
+                               unsigned int max_num_sg, bool is_write,
+                               hwaddr pa, size_t sz)
+{
+    unsigned num_sg = *p_num_sg;
+    assert(num_sg <= max_num_sg);
+
+    while (sz) {
+        hwaddr len = sz;
+
+        if (num_sg == max_num_sg) {
+            error_report("virtio: too many write descriptors in indirect table");
+            exit(1);
+        }
+
+        iov[num_sg].iov_base = cpu_physical_memory_map(pa, &len, is_write);
+        iov[num_sg].iov_len = len;
+        addr[num_sg] = pa;
+
+        sz -= len;
+        pa += len;
+        num_sg++;
+    }
+    *p_num_sg = num_sg;
+}
+
 static void virtqueue_map_iovec(struct iovec *sg, hwaddr *addr,
                                 unsigned int *num_sg, unsigned int max_size,
                                 int is_write)
@@ -474,20 +500,10 @@ static void virtqueue_map_iovec(struct iovec *sg, hwaddr *addr,
             error_report("virtio: error trying to map MMIO memory");
             exit(1);
         }
-        if (len == sg[i].iov_len) {
-            continue;
-        }
-        if (*num_sg >= max_size) {
-            error_report("virtio: memory split makes iovec too large");
+        if (len != sg[i].iov_len) {
+            error_report("virtio: unexpected memory split");
             exit(1);
         }
-        memmove(sg + i + 1, sg + i, sizeof(*sg) * (*num_sg - i));
-        memmove(addr + i + 1, addr + i, sizeof(*addr) * (*num_sg - i));
-        assert(len < sg[i + 1].iov_len);
-        sg[i].iov_len = len;
-        addr[i + 1] += len;
-        sg[i + 1].iov_len -= len;
-        ++*num_sg;
     }
 }
 
@@ -526,14 +542,16 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
     hwaddr desc_pa = vq->vring.desc;
     VirtIODevice *vdev = vq->vdev;
     VirtQueueElement *elem;
+    unsigned out_num, in_num;
+    hwaddr addr[VIRTQUEUE_MAX_SIZE];
+    struct iovec iov[VIRTQUEUE_MAX_SIZE];
 
     if (!virtqueue_num_heads(vq, vq->last_avail_idx)) {
         return NULL;
     }
 
     /* When we start there are none of either input nor output. */
-    elem = virtqueue_alloc_element(sz, VIRTQUEUE_MAX_SIZE, VIRTQUEUE_MAX_SIZE);
-    elem->out_num = elem->in_num = 0;
+    out_num = in_num = 0;
 
     max = vq->vring.num;
 
@@ -556,37 +574,39 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
 
     /* Collect all the descriptors */
     do {
-        struct iovec *sg;
+        hwaddr pa = vring_desc_addr(vdev, desc_pa, i);
+        size_t len = vring_desc_len(vdev, desc_pa, i);
 
         if (vring_desc_flags(vdev, desc_pa, i) & VRING_DESC_F_WRITE) {
-            if (elem->in_num >= VIRTQUEUE_MAX_SIZE) {
-                error_report("Too many write descriptors in indirect table");
-                exit(1);
-            }
-            elem->in_addr[elem->in_num] = vring_desc_addr(vdev, desc_pa, i);
-            sg = &elem->in_sg[elem->in_num++];
+            virtqueue_map_desc(&in_num, addr + out_num, iov + out_num,
+                               VIRTQUEUE_MAX_SIZE - out_num, true, pa, len);
         } else {
-            if (elem->out_num >= VIRTQUEUE_MAX_SIZE) {
-                error_report("Too many read descriptors in indirect table");
+            if (in_num) {
+                error_report("Incorrect order for descriptors");
                 exit(1);
             }
-            elem->out_addr[elem->out_num] = vring_desc_addr(vdev, desc_pa, i);
-            sg = &elem->out_sg[elem->out_num++];
+            virtqueue_map_desc(&out_num, addr, iov,
+                               VIRTQUEUE_MAX_SIZE, false, pa, len);
         }
 
-        sg->iov_len = vring_desc_len(vdev, desc_pa, i);
-
         /* If we've got too many, that implies a descriptor loop. */
-        if ((elem->in_num + elem->out_num) > max) {
+        if ((in_num + out_num) > max) {
             error_report("Looped descriptor");
             exit(1);
         }
     } while ((i = virtqueue_next_desc(vdev, desc_pa, i, max)) != max);
 
-    /* Now map what we have collected */
-    virtqueue_map(elem);
-
+    /* Now copy what we have collected and mapped */
+    elem = virtqueue_alloc_element(sz, out_num, in_num);
     elem->index = head;
+    for (i = 0; i < out_num; i++) {
+        elem->out_addr[i] = addr[i];
+        elem->out_sg[i] = iov[i];
+    }
+    for (i = 0; i < in_num; i++) {
+        elem->in_addr[i] = addr[out_num + i];
+        elem->in_sg[i] = iov[out_num + i];
+    }
 
     vq->inuse++;
 
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 10/49] vring: slim down allocation of VirtQueueElements
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (9 preceding siblings ...)
  2016-02-04 21:51 ` [Qemu-devel] [PULL 09/49] virtio: slim down allocation of VirtQueueElements Michael S. Tsirkin
@ 2016-02-04 21:51 ` Michael S. Tsirkin
  2016-02-04 21:51 ` [Qemu-devel] [PULL 11/49] virtio: combine the read of a descriptor Michael S. Tsirkin
                   ` (38 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Eduardo Habkost, qemu-block, Stefan Hajnoczi,
	Cornelia Huck, Paolo Bonzini

From: Paolo Bonzini <pbonzini@redhat.com>

Build the addresses and s/g lists on the stack, and then copy them
to a VirtQueueElement that is just as big as required to contain this
particular s/g list.  The cost of the copy is minimal compared to that
of a large malloc.

Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/virtio/dataplane/vring.c | 53 ++++++++++++++++++++++++++++++---------------
 1 file changed, 36 insertions(+), 17 deletions(-)

diff --git a/hw/virtio/dataplane/vring.c b/hw/virtio/dataplane/vring.c
index 57ada3b..4308d9f 100644
--- a/hw/virtio/dataplane/vring.c
+++ b/hw/virtio/dataplane/vring.c
@@ -218,8 +218,14 @@ bool vring_should_notify(VirtIODevice *vdev, Vring *vring)
                             new, old);
 }
 
-
-static int get_desc(Vring *vring, VirtQueueElement *elem,
+typedef struct VirtQueueCurrentElement {
+    unsigned in_num;
+    unsigned out_num;
+    hwaddr addr[VIRTQUEUE_MAX_SIZE];
+    struct iovec iov[VIRTQUEUE_MAX_SIZE];
+} VirtQueueCurrentElement;
+
+static int get_desc(Vring *vring, VirtQueueCurrentElement *elem,
                     struct vring_desc *desc)
 {
     unsigned *num;
@@ -230,12 +236,12 @@ static int get_desc(Vring *vring, VirtQueueElement *elem,
 
     if (desc->flags & VRING_DESC_F_WRITE) {
         num = &elem->in_num;
-        iov = &elem->in_sg[*num];
-        addr = &elem->in_addr[*num];
+        iov = &elem->iov[elem->out_num + *num];
+        addr = &elem->addr[elem->out_num + *num];
     } else {
         num = &elem->out_num;
-        iov = &elem->out_sg[*num];
-        addr = &elem->out_addr[*num];
+        iov = &elem->iov[*num];
+        addr = &elem->addr[*num];
 
         /* If it's an output descriptor, they're all supposed
          * to come before any input descriptors. */
@@ -299,7 +305,8 @@ static bool read_vring_desc(VirtIODevice *vdev,
 
 /* This is stolen from linux/drivers/vhost/vhost.c. */
 static int get_indirect(VirtIODevice *vdev, Vring *vring,
-                        VirtQueueElement *elem, struct vring_desc *indirect)
+                        VirtQueueCurrentElement *cur_elem,
+                        struct vring_desc *indirect)
 {
     struct vring_desc desc;
     unsigned int i = 0, count, found = 0;
@@ -351,7 +358,7 @@ static int get_indirect(VirtIODevice *vdev, Vring *vring,
             return -EFAULT;
         }
 
-        ret = get_desc(vring, elem, &desc);
+        ret = get_desc(vring, cur_elem, &desc);
         if (ret < 0) {
             vring->broken |= (ret == -EFAULT);
             return ret;
@@ -394,6 +401,7 @@ void *vring_pop(VirtIODevice *vdev, Vring *vring, size_t sz)
     struct vring_desc desc;
     unsigned int i, head, found = 0, num = vring->vr.num;
     uint16_t avail_idx, last_avail_idx;
+    VirtQueueCurrentElement cur_elem;
     VirtQueueElement *elem = NULL;
     int ret;
 
@@ -403,10 +411,7 @@ void *vring_pop(VirtIODevice *vdev, Vring *vring, size_t sz)
         goto out;
     }
 
-    elem = virtqueue_alloc_element(sz, VIRTQUEUE_MAX_SIZE, VIRTQUEUE_MAX_SIZE);
-
-    /* Initialize elem so it can be safely unmapped */
-    elem->in_num = elem->out_num = 0;
+    cur_elem.in_num = cur_elem.out_num = 0;
 
     /* Check it isn't doing very strange things with descriptor numbers. */
     last_avail_idx = vring->last_avail_idx;
@@ -433,8 +438,6 @@ void *vring_pop(VirtIODevice *vdev, Vring *vring, size_t sz)
      * the index we've seen. */
     head = vring_get_avail_ring(vdev, vring, last_avail_idx % num);
 
-    elem->index = head;
-
     /* If their number is silly, that's an error. */
     if (unlikely(head >= num)) {
         error_report("Guest says index %u > %u is available", head, num);
@@ -461,14 +464,14 @@ void *vring_pop(VirtIODevice *vdev, Vring *vring, size_t sz)
         barrier();
 
         if (desc.flags & VRING_DESC_F_INDIRECT) {
-            ret = get_indirect(vdev, vring, elem, &desc);
+            ret = get_indirect(vdev, vring, &cur_elem, &desc);
             if (ret < 0) {
                 goto out;
             }
             continue;
         }
 
-        ret = get_desc(vring, elem, &desc);
+        ret = get_desc(vring, &cur_elem, &desc);
         if (ret < 0) {
             goto out;
         }
@@ -483,6 +486,18 @@ void *vring_pop(VirtIODevice *vdev, Vring *vring, size_t sz)
             virtio_tswap16(vdev, vring->last_avail_idx);
     }
 
+    /* Now copy what we have collected and mapped */
+    elem = virtqueue_alloc_element(sz, cur_elem.out_num, cur_elem.in_num);
+    elem->index = head;
+    for (i = 0; i < cur_elem.out_num; i++) {
+        elem->out_addr[i] = cur_elem.addr[i];
+        elem->out_sg[i] = cur_elem.iov[i];
+    }
+    for (i = 0; i < cur_elem.in_num; i++) {
+        elem->in_addr[i] = cur_elem.addr[cur_elem.out_num + i];
+        elem->in_sg[i] = cur_elem.iov[cur_elem.out_num + i];
+    }
+
     return elem;
 
 out:
@@ -490,7 +505,11 @@ out:
     if (ret == -EFAULT) {
         vring->broken = true;
     }
-    vring_unmap_element(elem);
+
+    for (i = 0; i < cur_elem.out_num + cur_elem.in_num; i++) {
+        vring_unmap(cur_elem.iov[i].iov_base, false);
+    }
+
     g_free(elem);
     return NULL;
 }
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 11/49] virtio: combine the read of a descriptor
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (10 preceding siblings ...)
  2016-02-04 21:51 ` [Qemu-devel] [PULL 10/49] vring: " Michael S. Tsirkin
@ 2016-02-04 21:51 ` Michael S. Tsirkin
  2016-02-04 21:51 ` [Qemu-devel] [PULL 12/49] virtio: cache used_idx in a VirtQueue field Michael S. Tsirkin
                   ` (37 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Cornelia Huck, Peter Maydell, Eduardo Habkost, Paolo Bonzini

From: Paolo Bonzini <pbonzini@redhat.com>

Compared to vring, virtio has a performance penalty of 10%.  Fix it
by combining all the reads for a descriptor in a single address_space_read
call.  This also simplifies the code nicely.

Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/virtio/virtio.c | 86 ++++++++++++++++++++++--------------------------------
 1 file changed, 35 insertions(+), 51 deletions(-)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index c3e00a8..225ee6d 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -107,35 +107,15 @@ void virtio_queue_update_rings(VirtIODevice *vdev, int n)
                               vring->align);
 }
 
-static inline uint64_t vring_desc_addr(VirtIODevice *vdev, hwaddr desc_pa,
-                                       int i)
+static void vring_desc_read(VirtIODevice *vdev, VRingDesc *desc,
+                            hwaddr desc_pa, int i)
 {
-    hwaddr pa;
-    pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, addr);
-    return virtio_ldq_phys(vdev, pa);
-}
-
-static inline uint32_t vring_desc_len(VirtIODevice *vdev, hwaddr desc_pa, int i)
-{
-    hwaddr pa;
-    pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, len);
-    return virtio_ldl_phys(vdev, pa);
-}
-
-static inline uint16_t vring_desc_flags(VirtIODevice *vdev, hwaddr desc_pa,
-                                        int i)
-{
-    hwaddr pa;
-    pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, flags);
-    return virtio_lduw_phys(vdev, pa);
-}
-
-static inline uint16_t vring_desc_next(VirtIODevice *vdev, hwaddr desc_pa,
-                                       int i)
-{
-    hwaddr pa;
-    pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, next);
-    return virtio_lduw_phys(vdev, pa);
+    address_space_read(&address_space_memory, desc_pa + i * sizeof(VRingDesc),
+                       MEMTXATTRS_UNSPECIFIED, (void *)desc, sizeof(VRingDesc));
+    virtio_tswap64s(vdev, &desc->addr);
+    virtio_tswap32s(vdev, &desc->len);
+    virtio_tswap16s(vdev, &desc->flags);
+    virtio_tswap16s(vdev, &desc->next);
 }
 
 static inline uint16_t vring_avail_flags(VirtQueue *vq)
@@ -345,18 +325,18 @@ static unsigned int virtqueue_get_head(VirtQueue *vq, unsigned int idx)
     return head;
 }
 
-static unsigned virtqueue_next_desc(VirtIODevice *vdev, hwaddr desc_pa,
-                                    unsigned int i, unsigned int max)
+static unsigned virtqueue_read_next_desc(VirtIODevice *vdev, VRingDesc *desc,
+                                         hwaddr desc_pa, unsigned int max)
 {
     unsigned int next;
 
     /* If this descriptor says it doesn't chain, we're done. */
-    if (!(vring_desc_flags(vdev, desc_pa, i) & VRING_DESC_F_NEXT)) {
+    if (!(desc->flags & VRING_DESC_F_NEXT)) {
         return max;
     }
 
     /* Check they're not leading us off end of descriptors. */
-    next = vring_desc_next(vdev, desc_pa, i);
+    next = desc->next;
     /* Make sure compiler knows to grab that: we don't want it changing! */
     smp_wmb();
 
@@ -365,6 +345,7 @@ static unsigned virtqueue_next_desc(VirtIODevice *vdev, hwaddr desc_pa,
         exit(1);
     }
 
+    vring_desc_read(vdev, desc, desc_pa, next);
     return next;
 }
 
@@ -381,6 +362,7 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
     while (virtqueue_num_heads(vq, idx)) {
         VirtIODevice *vdev = vq->vdev;
         unsigned int max, num_bufs, indirect = 0;
+        VRingDesc desc;
         hwaddr desc_pa;
         int i;
 
@@ -388,9 +370,10 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
         num_bufs = total_bufs;
         i = virtqueue_get_head(vq, idx++);
         desc_pa = vq->vring.desc;
+        vring_desc_read(vdev, &desc, desc_pa, i);
 
-        if (vring_desc_flags(vdev, desc_pa, i) & VRING_DESC_F_INDIRECT) {
-            if (vring_desc_len(vdev, desc_pa, i) % sizeof(VRingDesc)) {
+        if (desc.flags & VRING_DESC_F_INDIRECT) {
+            if (desc.len % sizeof(VRingDesc)) {
                 error_report("Invalid size for indirect buffer table");
                 exit(1);
             }
@@ -403,9 +386,10 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
 
             /* loop over the indirect descriptor table */
             indirect = 1;
-            max = vring_desc_len(vdev, desc_pa, i) / sizeof(VRingDesc);
-            desc_pa = vring_desc_addr(vdev, desc_pa, i);
+            max = desc.len / sizeof(VRingDesc);
+            desc_pa = desc.addr;
             num_bufs = i = 0;
+            vring_desc_read(vdev, &desc, desc_pa, i);
         }
 
         do {
@@ -415,15 +399,15 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
                 exit(1);
             }
 
-            if (vring_desc_flags(vdev, desc_pa, i) & VRING_DESC_F_WRITE) {
-                in_total += vring_desc_len(vdev, desc_pa, i);
+            if (desc.flags & VRING_DESC_F_WRITE) {
+                in_total += desc.len;
             } else {
-                out_total += vring_desc_len(vdev, desc_pa, i);
+                out_total += desc.len;
             }
             if (in_total >= max_in_bytes && out_total >= max_out_bytes) {
                 goto done;
             }
-        } while ((i = virtqueue_next_desc(vdev, desc_pa, i, max)) != max);
+        } while ((i = virtqueue_read_next_desc(vdev, &desc, desc_pa, max)) != max);
 
         if (!indirect)
             total_bufs = num_bufs;
@@ -545,6 +529,7 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
     unsigned out_num, in_num;
     hwaddr addr[VIRTQUEUE_MAX_SIZE];
     struct iovec iov[VIRTQUEUE_MAX_SIZE];
+    VRingDesc desc;
 
     if (!virtqueue_num_heads(vq, vq->last_avail_idx)) {
         return NULL;
@@ -560,33 +545,32 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
         vring_set_avail_event(vq, vq->last_avail_idx);
     }
 
-    if (vring_desc_flags(vdev, desc_pa, i) & VRING_DESC_F_INDIRECT) {
-        if (vring_desc_len(vdev, desc_pa, i) % sizeof(VRingDesc)) {
+    vring_desc_read(vdev, &desc, desc_pa, i);
+    if (desc.flags & VRING_DESC_F_INDIRECT) {
+        if (desc.len % sizeof(VRingDesc)) {
             error_report("Invalid size for indirect buffer table");
             exit(1);
         }
 
         /* loop over the indirect descriptor table */
-        max = vring_desc_len(vdev, desc_pa, i) / sizeof(VRingDesc);
-        desc_pa = vring_desc_addr(vdev, desc_pa, i);
+        max = desc.len / sizeof(VRingDesc);
+        desc_pa = desc.addr;
         i = 0;
+        vring_desc_read(vdev, &desc, desc_pa, i);
     }
 
     /* Collect all the descriptors */
     do {
-        hwaddr pa = vring_desc_addr(vdev, desc_pa, i);
-        size_t len = vring_desc_len(vdev, desc_pa, i);
-
-        if (vring_desc_flags(vdev, desc_pa, i) & VRING_DESC_F_WRITE) {
+        if (desc.flags & VRING_DESC_F_WRITE) {
             virtqueue_map_desc(&in_num, addr + out_num, iov + out_num,
-                               VIRTQUEUE_MAX_SIZE - out_num, true, pa, len);
+                               VIRTQUEUE_MAX_SIZE - out_num, true, desc.addr, desc.len);
         } else {
             if (in_num) {
                 error_report("Incorrect order for descriptors");
                 exit(1);
             }
             virtqueue_map_desc(&out_num, addr, iov,
-                               VIRTQUEUE_MAX_SIZE, false, pa, len);
+                               VIRTQUEUE_MAX_SIZE, false, desc.addr, desc.len);
         }
 
         /* If we've got too many, that implies a descriptor loop. */
@@ -594,7 +578,7 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
             error_report("Looped descriptor");
             exit(1);
         }
-    } while ((i = virtqueue_next_desc(vdev, desc_pa, i, max)) != max);
+    } while ((i = virtqueue_read_next_desc(vdev, &desc, desc_pa, max)) != max);
 
     /* Now copy what we have collected and mapped */
     elem = virtqueue_alloc_element(sz, out_num, in_num);
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 12/49] virtio: cache used_idx in a VirtQueue field
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (11 preceding siblings ...)
  2016-02-04 21:51 ` [Qemu-devel] [PULL 11/49] virtio: combine the read of a descriptor Michael S. Tsirkin
@ 2016-02-04 21:51 ` Michael S. Tsirkin
  2016-02-04 21:51 ` [Qemu-devel] [PULL 13/49] virtio: read avail_idx from VQ only when necessary Michael S. Tsirkin
                   ` (36 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: Cornelia Huck, Peter Maydell, Eduardo Habkost, Vincenzo Maffione,
	Paolo Bonzini

From: Vincenzo Maffione <v.maffione@gmail.com>

Accessing used_idx in the VQ requires an expensive access to
guest physical memory. Before this patch, 3 accesses are normally
done for each pop/push/notify call. However, since the used_idx is
only written by us, we can track it in our internal data structure.

Signed-off-by: Vincenzo Maffione <v.maffione@gmail.com>
Message-Id: <3d062ec54e9a7bf9fb325c1fd693564951f2b319.1450218353.git.v.maffione@gmail.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/virtio/virtio.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 225ee6d..82e6414 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -71,6 +71,9 @@ struct VirtQueue
 {
     VRing vring;
     uint16_t last_avail_idx;
+
+    uint16_t used_idx;
+
     /* Last used index value we have signalled on */
     uint16_t signalled_used;
 
@@ -170,6 +173,7 @@ static inline void vring_used_idx_set(VirtQueue *vq, uint16_t val)
     hwaddr pa;
     pa = vq->vring.used + offsetof(VRingUsed, idx);
     virtio_stw_phys(vq->vdev, pa, val);
+    vq->used_idx = val;
 }
 
 static inline void vring_used_flags_set_bit(VirtQueue *vq, int mask)
@@ -261,7 +265,7 @@ void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
 
     virtqueue_unmap_sg(vq, elem, len);
 
-    idx = (idx + vring_used_idx(vq)) % vq->vring.num;
+    idx = (idx + vq->used_idx) % vq->vring.num;
 
     /* Get a pointer to the next entry in the used ring. */
     vring_used_ring_id(vq, idx, elem->index);
@@ -274,7 +278,7 @@ void virtqueue_flush(VirtQueue *vq, unsigned int count)
     /* Make sure buffer is written before we update index. */
     smp_wmb();
     trace_virtqueue_flush(vq, count);
-    old = vring_used_idx(vq);
+    old = vq->used_idx;
     new = old + count;
     vring_used_idx_set(vq, new);
     vq->inuse -= count;
@@ -782,6 +786,7 @@ void virtio_reset(void *opaque)
         vdev->vq[i].vring.avail = 0;
         vdev->vq[i].vring.used = 0;
         vdev->vq[i].last_avail_idx = 0;
+        vdev->vq[i].used_idx = 0;
         virtio_queue_set_vector(vdev, i, VIRTIO_NO_VECTOR);
         vdev->vq[i].signalled_used = 0;
         vdev->vq[i].signalled_used_valid = false;
@@ -1161,7 +1166,7 @@ static bool vring_notify(VirtIODevice *vdev, VirtQueue *vq)
     v = vq->signalled_used_valid;
     vq->signalled_used_valid = true;
     old = vq->signalled_used;
-    new = vq->signalled_used = vring_used_idx(vq);
+    new = vq->signalled_used = vq->used_idx;
     return !v || vring_need_event(vring_get_used_event(vq), new, old);
 }
 
@@ -1573,6 +1578,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
                              vdev->vq[i].last_avail_idx, nheads);
                 return -1;
             }
+            vdev->vq[i].used_idx = vring_used_idx(&vdev->vq[i]);
         }
     }
 
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 13/49] virtio: read avail_idx from VQ only when necessary
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (12 preceding siblings ...)
  2016-02-04 21:51 ` [Qemu-devel] [PULL 12/49] virtio: cache used_idx in a VirtQueue field Michael S. Tsirkin
@ 2016-02-04 21:51 ` Michael S. Tsirkin
  2016-02-04 21:51 ` [Qemu-devel] [PULL 15/49] hw/pxb: add pxb devices to the bridge category Michael S. Tsirkin
                   ` (35 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: Cornelia Huck, Peter Maydell, Eduardo Habkost, Vincenzo Maffione,
	Paolo Bonzini

From: Vincenzo Maffione <v.maffione@gmail.com>

The virtqueue_pop() implementation needs to check if the avail ring
contains some pending buffers. To perform this check, it is not
always necessary to fetch the avail_idx in the VQ memory, which is
expensive. This patch introduces a shadow variable tracking avail_idx
and modifies virtio_queue_empty() to access avail_idx in physical
memory only when necessary.

Signed-off-by: Vincenzo Maffione <v.maffione@gmail.com>
Message-Id: <b617d6459902773d9f4ab843bfaca764f5af8eda.1450218353.git.v.maffione@gmail.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/virtio/virtio.c | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 82e6414..9608358 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -70,8 +70,13 @@ typedef struct VRing
 struct VirtQueue
 {
     VRing vring;
+
+    /* Next head to pop */
     uint16_t last_avail_idx;
 
+    /* Last avail_idx read from VQ. */
+    uint16_t shadow_avail_idx;
+
     uint16_t used_idx;
 
     /* Last used index value we have signalled on */
@@ -132,7 +137,8 @@ static inline uint16_t vring_avail_idx(VirtQueue *vq)
 {
     hwaddr pa;
     pa = vq->vring.avail + offsetof(VRingAvail, idx);
-    return virtio_lduw_phys(vq->vdev, pa);
+    vq->shadow_avail_idx = virtio_lduw_phys(vq->vdev, pa);
+    return vq->shadow_avail_idx;
 }
 
 static inline uint16_t vring_avail_ring(VirtQueue *vq, int i)
@@ -223,8 +229,14 @@ int virtio_queue_ready(VirtQueue *vq)
     return vq->vring.avail != 0;
 }
 
+/* Fetch avail_idx from VQ memory only when we really need to know if
+ * guest has added some buffers. */
 int virtio_queue_empty(VirtQueue *vq)
 {
+    if (vq->shadow_avail_idx != vq->last_avail_idx) {
+        return 0;
+    }
+
     return vring_avail_idx(vq) == vq->last_avail_idx;
 }
 
@@ -300,7 +312,7 @@ static int virtqueue_num_heads(VirtQueue *vq, unsigned int idx)
     /* Check it isn't doing very strange things with descriptor numbers. */
     if (num_heads > vq->vring.num) {
         error_report("Guest moved used index from %u to %u",
-                     idx, vring_avail_idx(vq));
+                     idx, vq->shadow_avail_idx);
         exit(1);
     }
     /* On success, callers read a descriptor at vq->last_avail_idx.
@@ -535,9 +547,12 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
     struct iovec iov[VIRTQUEUE_MAX_SIZE];
     VRingDesc desc;
 
-    if (!virtqueue_num_heads(vq, vq->last_avail_idx)) {
+    if (virtio_queue_empty(vq)) {
         return NULL;
     }
+    /* Needed after virtio_queue_empty(), see comment in
+     * virtqueue_num_heads(). */
+    smp_rmb();
 
     /* When we start there are none of either input nor output. */
     out_num = in_num = 0;
@@ -786,6 +801,7 @@ void virtio_reset(void *opaque)
         vdev->vq[i].vring.avail = 0;
         vdev->vq[i].vring.used = 0;
         vdev->vq[i].last_avail_idx = 0;
+        vdev->vq[i].shadow_avail_idx = 0;
         vdev->vq[i].used_idx = 0;
         virtio_queue_set_vector(vdev, i, VIRTIO_NO_VECTOR);
         vdev->vq[i].signalled_used = 0;
@@ -1155,7 +1171,7 @@ static bool vring_notify(VirtIODevice *vdev, VirtQueue *vq)
     smp_mb();
     /* Always notify when queue is empty (when feature acknowledge) */
     if (virtio_vdev_has_feature(vdev, VIRTIO_F_NOTIFY_ON_EMPTY) &&
-        !vq->inuse && vring_avail_idx(vq) == vq->last_avail_idx) {
+        !vq->inuse && virtio_queue_empty(vq)) {
         return true;
     }
 
@@ -1579,6 +1595,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
                 return -1;
             }
             vdev->vq[i].used_idx = vring_used_idx(&vdev->vq[i]);
+            vdev->vq[i].shadow_avail_idx = vring_avail_idx(&vdev->vq[i]);
         }
     }
 
@@ -1714,6 +1731,7 @@ uint16_t virtio_queue_get_last_avail_idx(VirtIODevice *vdev, int n)
 void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n, uint16_t idx)
 {
     vdev->vq[n].last_avail_idx = idx;
+    vdev->vq[n].shadow_avail_idx = idx;
 }
 
 void virtio_queue_invalidate_signalled_used(VirtIODevice *vdev, int n)
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 15/49] hw/pxb: add pxb devices to the bridge category
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (13 preceding siblings ...)
  2016-02-04 21:51 ` [Qemu-devel] [PULL 13/49] virtio: read avail_idx from VQ only when necessary Michael S. Tsirkin
@ 2016-02-04 21:51 ` Michael S. Tsirkin
  2016-02-04 21:52 ` [Qemu-devel] [PULL 16/49] vhost-user-test: use correct ROM to speed up and avoid spurious failures Michael S. Tsirkin
                   ` (34 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marcel Apfelbaum, Peter Maydell, Eduardo Habkost

From: Marcel Apfelbaum <marcel@redhat.com>

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/pci-bridge/pci_expander_bridge.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c
index 62fd29d..d23b8da 100644
--- a/hw/pci-bridge/pci_expander_bridge.c
+++ b/hw/pci-bridge/pci_expander_bridge.c
@@ -302,6 +302,7 @@ static void pxb_dev_class_init(ObjectClass *klass, void *data)
 
     dc->desc = "PCI Expander Bridge";
     dc->props = pxb_dev_properties;
+    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
 }
 
 static const TypeInfo pxb_dev_info = {
@@ -334,6 +335,7 @@ static void pxb_pcie_dev_class_init(ObjectClass *klass, void *data)
 
     dc->desc = "PCI Express Expander Bridge";
     dc->props = pxb_dev_properties;
+    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
 }
 
 static const TypeInfo pxb_pcie_dev_info = {
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 16/49] vhost-user-test: use correct ROM to speed up and avoid spurious failures
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (14 preceding siblings ...)
  2016-02-04 21:51 ` [Qemu-devel] [PULL 15/49] hw/pxb: add pxb devices to the bridge category Michael S. Tsirkin
@ 2016-02-04 21:52 ` Michael S. Tsirkin
  2016-02-04 21:52 ` [Qemu-devel] [PULL 17/49] hw/pci: ensure that only PCI/PCIe bridges can be attached to pxb/pxb-pcie devices Michael S. Tsirkin
                   ` (33 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Yuanhan Liu, Eduardo Habkost, Markus Armbruster,
	Paolo Bonzini, =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?=

From: Paolo Bonzini <pbonzini@redhat.com>

The mechanism to get the option ROM for virtio-net does not block the
PCI ROM from being loaded. Therefore, in vhost-user-test there are
two entries in the boot menu for the virtio-net card: one as an
embedded option ROM, one from the ROM BAR.

The embedded option ROM in vhost-user-test is the non-EFI-enabled,
while the ROM BAR has an EFI-enabled ROM. The two are compiled with
slightly different parameters, where only the old BIOS-only one doesn't
have a timeout for the "Press Ctrl-B" banner. When using a new
machine type, therefore, the vhost-user-test has to wait for the
EFI-enabled ROM's banner to go away. There are several ways to fix
this:

1) fix the ROMs to have the same configuration

2) add ",romfile=" to the -device line

3) remove --option-rom and add the ROM file name to the -device line

4) use an old machine type

This patch chooses 3. In addition, the file name was wrong because
qtest runs QEMU relative to the top build directory, not to the
x86_64-softmmu/ subdirectory, which is fixed too.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 tests/vhost-user-test.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index 95f35af..e30b7f4 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -35,11 +35,10 @@
                         "mem-path=%s,share=on -numa node,memdev=mem"
 #define QEMU_CMD_CHR    " -chardev socket,id=%s,path=%s"
 #define QEMU_CMD_NETDEV " -netdev vhost-user,id=net0,chardev=%s,vhostforce"
-#define QEMU_CMD_NET    " -device virtio-net-pci,netdev=net0 "
-#define QEMU_CMD_ROM    " -option-rom ../pc-bios/pxe-virtio.rom"
+#define QEMU_CMD_NET    " -device virtio-net-pci,netdev=net0,romfile=./pc-bios/pxe-virtio.rom"
 
 #define QEMU_CMD        QEMU_CMD_ACCEL QEMU_CMD_MEM QEMU_CMD_CHR \
-                        QEMU_CMD_NETDEV QEMU_CMD_NET QEMU_CMD_ROM
+                        QEMU_CMD_NETDEV QEMU_CMD_NET
 
 #define HUGETLBFS_MAGIC       0x958458f6
 
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 17/49] hw/pci: ensure that only PCI/PCIe bridges can be attached to pxb/pxb-pcie devices
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (15 preceding siblings ...)
  2016-02-04 21:52 ` [Qemu-devel] [PULL 16/49] vhost-user-test: use correct ROM to speed up and avoid spurious failures Michael S. Tsirkin
@ 2016-02-04 21:52 ` Michael S. Tsirkin
  2016-02-04 21:52 ` [Qemu-devel] [PULL 18/49] ipmi: replace goto by a return statement Michael S. Tsirkin
                   ` (32 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marcel Apfelbaum, Peter Maydell, Eduardo Habkost

From: Marcel Apfelbaum <marcel@redhat.com>

PCI devices can't be plugged directly into PCI extra root bridges
because their resources can't be computed by firmware before the ACPI
tables are loaded.

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/pci/pci.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index d940f79..b282120 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -851,6 +851,13 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
     DeviceState *dev = DEVICE(pci_dev);
 
     pci_dev->bus = bus;
+    /* Only pci bridges can be attached to extra PCI root buses */
+    if (pci_bus_is_root(bus) && bus->parent_dev && !pc->is_bridge) {
+        error_setg(errp,
+                   "PCI: Only PCI/PCIe bridges can be plugged into %s",
+                    bus->parent_dev->name);
+        return NULL;
+    }
 
     if (devfn < 0) {
         for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices);
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 18/49] ipmi: replace goto by a return statement
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (16 preceding siblings ...)
  2016-02-04 21:52 ` [Qemu-devel] [PULL 17/49] hw/pci: ensure that only PCI/PCIe bridges can be attached to pxb/pxb-pcie devices Michael S. Tsirkin
@ 2016-02-04 21:52 ` Michael S. Tsirkin
  2016-02-04 21:52 ` [Qemu-devel] [PULL 19/49] ipmi: replace *_MAXCMD defines Michael S. Tsirkin
                   ` (31 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Eduardo Habkost, Corey Minyard,
	=?UTF-8?q?C=C3=A9dric=20Le=20Goater?=,
	Marcel Apfelbaum, Greg Kurz

From: Cédric Le Goater <clg@fr.ibm.com>

Each routine using the IPMI_ADD_RSP_DATA, IPMI_CHECK_CMD_LEN or
IPMI_CHECK_RESERVATION macros needs to define a goto label 'out' to
handle hidden errors. Using directly a return statement has the same
effect and it removes the fact that 'out' needs to be defined.

The code exits in ipmi_sim_handle_command() are a little different
from the rest and a "possible" error in the macro IPMI_ADD_RSP_DATA is
handled before making use of it. This might be a bit excessive as a
minimum response len is currently 300 bytes and the patch checks that
at least 3 are available.

Signed-off-by: Cédric Le Goater <clg@fr.ibm.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
Reviewed-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Reviewed-by: Corey Minyard <cminyard@mvista.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/ipmi/ipmi_bmc_sim.c | 140 +++++++++++++++----------------------------------
 1 file changed, 41 insertions(+), 99 deletions(-)

diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
index dcdab03..1f06dfc 100644
--- a/hw/ipmi/ipmi_bmc_sim.c
+++ b/hw/ipmi/ipmi_bmc_sim.c
@@ -256,7 +256,7 @@ struct IPMIBmcSim {
     do {                                                   \
         if (*rsp_len >= max_rsp_len) {                     \
             rsp[2] = IPMI_CC_REQUEST_DATA_TRUNCATED;       \
-            goto out;                                      \
+            return;                                        \
         }                                                  \
         rsp[(*rsp_len)++] = (b);                           \
     } while (0)
@@ -265,7 +265,7 @@ struct IPMIBmcSim {
 #define IPMI_CHECK_CMD_LEN(l) \
     if (cmd_len < l) {                                     \
         rsp[2] = IPMI_CC_REQUEST_DATA_LENGTH_INVALID;      \
-        goto out; \
+        return; \
     }
 
 /* Check that the reservation in the command is valid. */
@@ -273,7 +273,7 @@ struct IPMIBmcSim {
     do {                                                   \
         if ((cmd[off] | (cmd[off + 1] << 8)) != r) {       \
             rsp[2] = IPMI_CC_INVALID_RESERVATION;          \
-            goto out;                                      \
+            return;                                        \
         }                                                  \
     } while (0)
 
@@ -451,14 +451,12 @@ static void gen_event(IPMIBmcSim *ibs, unsigned int sens_num, uint8_t deassert,
     }
 
     if (ibs->msg_flags & IPMI_BMC_MSG_FLAG_EVT_BUF_FULL) {
-        goto out;
+        return;
     }
 
     memcpy(ibs->evtbuf, evt, 16);
     ibs->msg_flags |= IPMI_BMC_MSG_FLAG_EVT_BUF_FULL;
     k->set_atn(s, 1, attn_irq_enabled(ibs));
- out:
-    return;
 }
 
 static void sensor_set_discrete_bit(IPMIBmcSim *ibs, unsigned int sensor,
@@ -579,6 +577,11 @@ static void ipmi_sim_handle_command(IPMIBmc *b,
 
     /* Set up the response, set the low bit of NETFN. */
     /* Note that max_rsp_len must be at least 3 */
+    if (max_rsp_len < 3) {
+        rsp[2] = IPMI_CC_REQUEST_DATA_TRUNCATED;
+        goto out;
+    }
+
     IPMI_ADD_RSP_DATA(cmd[0] | 0x04);
     IPMI_ADD_RSP_DATA(cmd[1]);
     IPMI_ADD_RSP_DATA(0); /* Assume success */
@@ -696,8 +699,6 @@ static void chassis_capabilities(IPMIBmcSim *ibs,
     IPMI_ADD_RSP_DATA(ibs->parent.slave_addr);
     IPMI_ADD_RSP_DATA(ibs->parent.slave_addr);
     IPMI_ADD_RSP_DATA(ibs->parent.slave_addr);
- out:
-    return;
 }
 
 static void chassis_status(IPMIBmcSim *ibs,
@@ -709,8 +710,6 @@ static void chassis_status(IPMIBmcSim *ibs,
     IPMI_ADD_RSP_DATA(0);
     IPMI_ADD_RSP_DATA(0);
     IPMI_ADD_RSP_DATA(0);
- out:
-    return;
 }
 
 static void chassis_control(IPMIBmcSim *ibs,
@@ -744,10 +743,8 @@ static void chassis_control(IPMIBmcSim *ibs,
         break;
     default:
         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
-        goto out;
+        return;
     }
- out:
-    return;
 }
 
 static void get_device_id(IPMIBmcSim *ibs,
@@ -766,8 +763,6 @@ static void get_device_id(IPMIBmcSim *ibs,
     IPMI_ADD_RSP_DATA(ibs->mfg_id[2]);
     IPMI_ADD_RSP_DATA(ibs->product_id[0]);
     IPMI_ADD_RSP_DATA(ibs->product_id[1]);
- out:
-    return;
 }
 
 static void set_global_enables(IPMIBmcSim *ibs, uint8_t val)
@@ -820,8 +815,6 @@ static void set_bmc_global_enables(IPMIBmcSim *ibs,
 {
     IPMI_CHECK_CMD_LEN(3);
     set_global_enables(ibs, cmd[2]);
- out:
-    return;
 }
 
 static void get_bmc_global_enables(IPMIBmcSim *ibs,
@@ -830,8 +823,6 @@ static void get_bmc_global_enables(IPMIBmcSim *ibs,
                                    unsigned int max_rsp_len)
 {
     IPMI_ADD_RSP_DATA(ibs->bmc_global_enables);
- out:
-    return;
 }
 
 static void clr_msg_flags(IPMIBmcSim *ibs,
@@ -845,8 +836,6 @@ static void clr_msg_flags(IPMIBmcSim *ibs,
     IPMI_CHECK_CMD_LEN(3);
     ibs->msg_flags &= ~cmd[2];
     k->set_atn(s, attn_set(ibs), attn_irq_enabled(ibs));
- out:
-    return;
 }
 
 static void get_msg_flags(IPMIBmcSim *ibs,
@@ -855,8 +844,6 @@ static void get_msg_flags(IPMIBmcSim *ibs,
                           unsigned int max_rsp_len)
 {
     IPMI_ADD_RSP_DATA(ibs->msg_flags);
- out:
-    return;
 }
 
 static void read_evt_msg_buf(IPMIBmcSim *ibs,
@@ -870,15 +857,13 @@ static void read_evt_msg_buf(IPMIBmcSim *ibs,
 
     if (!(ibs->msg_flags & IPMI_BMC_MSG_FLAG_EVT_BUF_FULL)) {
         rsp[2] = 0x80;
-        goto out;
+        return;
     }
     for (i = 0; i < 16; i++) {
         IPMI_ADD_RSP_DATA(ibs->evtbuf[i]);
     }
     ibs->msg_flags &= ~IPMI_BMC_MSG_FLAG_EVT_BUF_FULL;
     k->set_atn(s, attn_set(ibs), attn_irq_enabled(ibs));
- out:
-    return;
 }
 
 static void get_msg(IPMIBmcSim *ibs,
@@ -909,7 +894,7 @@ static void get_msg(IPMIBmcSim *ibs,
         k->set_atn(s, attn_set(ibs), attn_irq_enabled(ibs));
     }
 
- out:
+out:
     qemu_mutex_unlock(&ibs->lock);
     return;
 }
@@ -940,14 +925,14 @@ static void send_msg(IPMIBmcSim *ibs,
     if (cmd[2] != 0) {
         /* We only handle channel 0 with no options */
         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
-        goto out;
+        return;
     }
 
     IPMI_CHECK_CMD_LEN(10);
     if (cmd[3] != 0x40) {
         /* We only emulate a MC at address 0x40. */
         rsp[2] = 0x83; /* NAK on write */
-        goto out;
+        return;
     }
 
     cmd += 3; /* Skip the header. */
@@ -959,7 +944,7 @@ static void send_msg(IPMIBmcSim *ibs,
      */
     if (ipmb_checksum(cmd, cmd_len, 0) != 0 ||
         cmd[3] != 0x20) { /* Improper response address */
-        goto out; /* No response */
+        return; /* No response */
     }
 
     netfn = cmd[1] >> 2;
@@ -969,7 +954,7 @@ static void send_msg(IPMIBmcSim *ibs,
 
     if (rqLun != 2) {
         /* We only support LUN 2 coming back to us. */
-        goto out;
+        return;
     }
 
     msg = g_malloc(sizeof(*msg));
@@ -1009,9 +994,6 @@ static void send_msg(IPMIBmcSim *ibs,
     ibs->msg_flags |= IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE;
     k->set_atn(s, 1, attn_irq_enabled(ibs));
     qemu_mutex_unlock(&ibs->lock);
-
- out:
-    return;
 }
 
 static void do_watchdog_reset(IPMIBmcSim *ibs)
@@ -1040,11 +1022,9 @@ static void reset_watchdog_timer(IPMIBmcSim *ibs,
 {
     if (!ibs->watchdog_initialized) {
         rsp[2] = 0x80;
-        goto out;
+        return;
     }
     do_watchdog_reset(ibs);
- out:
-    return;
 }
 
 static void set_watchdog_timer(IPMIBmcSim *ibs,
@@ -1060,7 +1040,7 @@ static void set_watchdog_timer(IPMIBmcSim *ibs,
     val = cmd[2] & 0x7; /* Validate use */
     if (val == 0 || val > 5) {
         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
-        goto out;
+        return;
     }
     val = cmd[3] & 0x7; /* Validate action */
     switch (val) {
@@ -1084,7 +1064,7 @@ static void set_watchdog_timer(IPMIBmcSim *ibs,
     }
     if (rsp[2]) {
         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
-        goto out;
+        return;
     }
 
     val = (cmd[3] >> 4) & 0x7; /* Validate preaction */
@@ -1097,12 +1077,12 @@ static void set_watchdog_timer(IPMIBmcSim *ibs,
         if (!k->do_hw_op(s, IPMI_SEND_NMI, 1)) {
             /* NMI not supported. */
             rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
-            goto out;
+            return;
         }
     default:
         /* We don't support PRE_SMI */
         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
-        goto out;
+        return;
     }
 
     ibs->watchdog_initialized = 1;
@@ -1116,8 +1096,6 @@ static void set_watchdog_timer(IPMIBmcSim *ibs,
     } else {
         ibs->watchdog_running = 0;
     }
- out:
-    return;
 }
 
 static void get_watchdog_timer(IPMIBmcSim *ibs,
@@ -1139,8 +1117,6 @@ static void get_watchdog_timer(IPMIBmcSim *ibs,
         IPMI_ADD_RSP_DATA(0);
         IPMI_ADD_RSP_DATA(0);
     }
- out:
-    return;
 }
 
 static void get_sdr_rep_info(IPMIBmcSim *ibs,
@@ -1163,8 +1139,6 @@ static void get_sdr_rep_info(IPMIBmcSim *ibs,
     }
     /* Only modal support, reserve supported */
     IPMI_ADD_RSP_DATA((ibs->sdr.overflow << 7) | 0x22);
- out:
-    return;
 }
 
 static void reserve_sdr_rep(IPMIBmcSim *ibs,
@@ -1174,8 +1148,6 @@ static void reserve_sdr_rep(IPMIBmcSim *ibs,
 {
     IPMI_ADD_RSP_DATA(ibs->sdr.reservation & 0xff);
     IPMI_ADD_RSP_DATA((ibs->sdr.reservation >> 8) & 0xff);
- out:
-    return;
 }
 
 static void get_sdr(IPMIBmcSim *ibs,
@@ -1194,11 +1166,11 @@ static void get_sdr(IPMIBmcSim *ibs,
     if (sdr_find_entry(&ibs->sdr, cmd[4] | (cmd[5] << 8),
                        &pos, &nextrec)) {
         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
-        goto out;
+        return;
     }
     if (cmd[6] > (ibs->sdr.sdr[pos + 4])) {
         rsp[2] = IPMI_CC_PARM_OUT_OF_RANGE;
-        goto out;
+        return;
     }
 
     IPMI_ADD_RSP_DATA(nextrec & 0xff);
@@ -1210,12 +1182,10 @@ static void get_sdr(IPMIBmcSim *ibs,
 
     if ((cmd[7] + *rsp_len) > max_rsp_len) {
         rsp[2] = IPMI_CC_CANNOT_RETURN_REQ_NUM_BYTES;
-        goto out;
+        return;
     }
     memcpy(rsp + *rsp_len, ibs->sdr.sdr + pos + cmd[6], cmd[7]);
     *rsp_len += cmd[7];
- out:
-    return;
 }
 
 static void add_sdr(IPMIBmcSim *ibs,
@@ -1227,12 +1197,10 @@ static void add_sdr(IPMIBmcSim *ibs,
 
     if (sdr_add_entry(ibs, cmd + 2, cmd_len - 2, &recid)) {
         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
-        goto out;
+        return;
     }
     IPMI_ADD_RSP_DATA(recid & 0xff);
     IPMI_ADD_RSP_DATA((recid >> 8) & 0xff);
- out:
-    return;
 }
 
 static void clear_sdr_rep(IPMIBmcSim *ibs,
@@ -1244,7 +1212,7 @@ static void clear_sdr_rep(IPMIBmcSim *ibs,
     IPMI_CHECK_RESERVATION(2, ibs->sdr.reservation);
     if (cmd[4] != 'C' || cmd[5] != 'L' || cmd[6] != 'R') {
         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
-        goto out;
+        return;
     }
     if (cmd[7] == 0xaa) {
         ibs->sdr.next_free = 0;
@@ -1256,10 +1224,8 @@ static void clear_sdr_rep(IPMIBmcSim *ibs,
         IPMI_ADD_RSP_DATA(1); /* Erasure complete */
     } else {
         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
-        goto out;
+        return;
     }
- out:
-    return;
 }
 
 static void get_sel_info(IPMIBmcSim *ibs,
@@ -1283,8 +1249,6 @@ static void get_sel_info(IPMIBmcSim *ibs,
     }
     /* Only support Reserve SEL */
     IPMI_ADD_RSP_DATA((ibs->sel.overflow << 7) | 0x02);
- out:
-    return;
 }
 
 static void reserve_sel(IPMIBmcSim *ibs,
@@ -1294,8 +1258,6 @@ static void reserve_sel(IPMIBmcSim *ibs,
 {
     IPMI_ADD_RSP_DATA(ibs->sel.reservation & 0xff);
     IPMI_ADD_RSP_DATA((ibs->sel.reservation >> 8) & 0xff);
- out:
-    return;
 }
 
 static void get_sel_entry(IPMIBmcSim *ibs,
@@ -1311,17 +1273,17 @@ static void get_sel_entry(IPMIBmcSim *ibs,
     }
     if (ibs->sel.next_free == 0) {
         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
-        goto out;
+        return;
     }
     if (cmd[6] > 15) {
         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
-        goto out;
+        return;
     }
     if (cmd[7] == 0xff) {
         cmd[7] = 16;
     } else if ((cmd[7] + cmd[6]) > 16) {
         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
-        goto out;
+        return;
     } else {
         cmd[7] += cmd[6];
     }
@@ -1331,7 +1293,7 @@ static void get_sel_entry(IPMIBmcSim *ibs,
         val = ibs->sel.next_free - 1;
     } else if (val >= ibs->sel.next_free) {
         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
-        goto out;
+        return;
     }
     if ((val + 1) == ibs->sel.next_free) {
         IPMI_ADD_RSP_DATA(0xff);
@@ -1343,8 +1305,6 @@ static void get_sel_entry(IPMIBmcSim *ibs,
     for (; cmd[6] < cmd[7]; cmd[6]++) {
         IPMI_ADD_RSP_DATA(ibs->sel.sel[val][cmd[6]]);
     }
- out:
-    return;
 }
 
 static void add_sel_entry(IPMIBmcSim *ibs,
@@ -1355,13 +1315,11 @@ static void add_sel_entry(IPMIBmcSim *ibs,
     IPMI_CHECK_CMD_LEN(18);
     if (sel_add_event(ibs, cmd + 2)) {
         rsp[2] = IPMI_CC_OUT_OF_SPACE;
-        goto out;
+        return;
     }
     /* sel_add_event fills in the record number. */
     IPMI_ADD_RSP_DATA(cmd[2]);
     IPMI_ADD_RSP_DATA(cmd[3]);
- out:
-    return;
 }
 
 static void clear_sel(IPMIBmcSim *ibs,
@@ -1373,7 +1331,7 @@ static void clear_sel(IPMIBmcSim *ibs,
     IPMI_CHECK_RESERVATION(2, ibs->sel.reservation);
     if (cmd[4] != 'C' || cmd[5] != 'L' || cmd[6] != 'R') {
         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
-        goto out;
+        return;
     }
     if (cmd[7] == 0xaa) {
         ibs->sel.next_free = 0;
@@ -1385,10 +1343,8 @@ static void clear_sel(IPMIBmcSim *ibs,
         IPMI_ADD_RSP_DATA(1); /* Erasure complete */
     } else {
         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
-        goto out;
+        return;
     }
- out:
-    return;
 }
 
 static void get_sel_time(IPMIBmcSim *ibs,
@@ -1405,8 +1361,6 @@ static void get_sel_time(IPMIBmcSim *ibs,
     IPMI_ADD_RSP_DATA((val >> 8) & 0xff);
     IPMI_ADD_RSP_DATA((val >> 16) & 0xff);
     IPMI_ADD_RSP_DATA((val >> 24) & 0xff);
- out:
-    return;
 }
 
 static void set_sel_time(IPMIBmcSim *ibs,
@@ -1421,8 +1375,6 @@ static void set_sel_time(IPMIBmcSim *ibs,
     val = cmd[2] | (cmd[3] << 8) | (cmd[4] << 16) | (cmd[5] << 24);
     ipmi_gettime(&now);
     ibs->sel.time_offset = now.tv_sec - ((long) val);
- out:
-    return;
 }
 
 static void set_sensor_evt_enable(IPMIBmcSim *ibs,
@@ -1436,7 +1388,7 @@ static void set_sensor_evt_enable(IPMIBmcSim *ibs,
     if ((cmd[2] > MAX_SENSORS) ||
             !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
-        goto out;
+        return;
     }
     sens = ibs->sensors + cmd[2];
     switch ((cmd[3] >> 4) & 0x3) {
@@ -1472,11 +1424,9 @@ static void set_sensor_evt_enable(IPMIBmcSim *ibs,
         break;
     case 3:
         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
-        goto out;
+        return;
     }
     IPMI_SENSOR_SET_RET_STATUS(sens, cmd[3]);
- out:
-    return;
 }
 
 static void get_sensor_evt_enable(IPMIBmcSim *ibs,
@@ -1490,7 +1440,7 @@ static void get_sensor_evt_enable(IPMIBmcSim *ibs,
     if ((cmd[2] > MAX_SENSORS) ||
         !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
-        goto out;
+        return;
     }
     sens = ibs->sensors + cmd[2];
     IPMI_ADD_RSP_DATA(IPMI_SENSOR_GET_RET_STATUS(sens));
@@ -1498,8 +1448,6 @@ static void get_sensor_evt_enable(IPMIBmcSim *ibs,
     IPMI_ADD_RSP_DATA((sens->assert_enable >> 8) & 0xff);
     IPMI_ADD_RSP_DATA(sens->deassert_enable & 0xff);
     IPMI_ADD_RSP_DATA((sens->deassert_enable >> 8) & 0xff);
- out:
-    return;
 }
 
 static void rearm_sensor_evts(IPMIBmcSim *ibs,
@@ -1513,17 +1461,15 @@ static void rearm_sensor_evts(IPMIBmcSim *ibs,
     if ((cmd[2] > MAX_SENSORS) ||
         !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
-        goto out;
+        return;
     }
     sens = ibs->sensors + cmd[2];
 
     if ((cmd[3] & 0x80) == 0) {
         /* Just clear everything */
         sens->states = 0;
-        goto out;
+        return;
     }
- out:
-    return;
 }
 
 static void get_sensor_evt_status(IPMIBmcSim *ibs,
@@ -1537,7 +1483,7 @@ static void get_sensor_evt_status(IPMIBmcSim *ibs,
     if ((cmd[2] > MAX_SENSORS) ||
         !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
-        goto out;
+        return;
     }
     sens = ibs->sensors + cmd[2];
     IPMI_ADD_RSP_DATA(sens->reading);
@@ -1546,8 +1492,6 @@ static void get_sensor_evt_status(IPMIBmcSim *ibs,
     IPMI_ADD_RSP_DATA((sens->assert_states >> 8) & 0xff);
     IPMI_ADD_RSP_DATA(sens->deassert_states & 0xff);
     IPMI_ADD_RSP_DATA((sens->deassert_states >> 8) & 0xff);
- out:
-    return;
 }
 
 static void get_sensor_reading(IPMIBmcSim *ibs,
@@ -1561,7 +1505,7 @@ static void get_sensor_reading(IPMIBmcSim *ibs,
     if ((cmd[2] > MAX_SENSORS) ||
             !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
-        goto out;
+        return;
     }
     sens = ibs->sensors + cmd[2];
     IPMI_ADD_RSP_DATA(sens->reading);
@@ -1570,8 +1514,6 @@ static void get_sensor_reading(IPMIBmcSim *ibs,
     if (IPMI_SENSOR_IS_DISCRETE(sens)) {
         IPMI_ADD_RSP_DATA((sens->states >> 8) & 0xff);
     }
- out:
-    return;
 }
 
 static const IPMICmdHandler chassis_cmds[IPMI_NETFN_CHASSIS_MAXCMD] = {
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 19/49] ipmi: replace *_MAXCMD defines
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (17 preceding siblings ...)
  2016-02-04 21:52 ` [Qemu-devel] [PULL 18/49] ipmi: replace goto by a return statement Michael S. Tsirkin
@ 2016-02-04 21:52 ` Michael S. Tsirkin
  2016-02-04 21:52 ` [Qemu-devel] [PULL 20/49] ipmi: cleanup error_report messages Michael S. Tsirkin
                   ` (30 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Eduardo Habkost, Corey Minyard,
	=?UTF-8?q?C=C3=A9dric=20Le=20Goater?=,
	Marcel Apfelbaum, Greg Kurz

From: Cédric Le Goater <clg@fr.ibm.com>

ARRAY_SIZE() is simple to use and removes the need to pre-define
the size of the command arrays.

Signed-off-by: Cédric Le Goater <clg@fr.ibm.com>
Reviewed-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/ipmi/ipmi_bmc_sim.c | 21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
index 1f06dfc..f7e87b4 100644
--- a/hw/ipmi/ipmi_bmc_sim.c
+++ b/hw/ipmi/ipmi_bmc_sim.c
@@ -28,14 +28,12 @@
 #include "qemu/error-report.h"
 
 #define IPMI_NETFN_CHASSIS            0x00
-#define IPMI_NETFN_CHASSIS_MAXCMD         0x03
 
 #define IPMI_CMD_GET_CHASSIS_CAPABILITIES 0x00
 #define IPMI_CMD_GET_CHASSIS_STATUS       0x01
 #define IPMI_CMD_CHASSIS_CONTROL          0x02
 
 #define IPMI_NETFN_SENSOR_EVENT       0x04
-#define IPMI_NETFN_SENSOR_EVENT_MAXCMD    0x2e
 
 #define IPMI_CMD_SET_SENSOR_EVT_ENABLE    0x28
 #define IPMI_CMD_GET_SENSOR_EVT_ENABLE    0x29
@@ -44,7 +42,6 @@
 #define IPMI_CMD_GET_SENSOR_READING       0x2d
 
 /* #define IPMI_NETFN_APP             0x06 In ipmi.h */
-#define IPMI_NETFN_APP_MAXCMD             0x36
 
 #define IPMI_CMD_GET_DEVICE_ID            0x01
 #define IPMI_CMD_COLD_RESET               0x02
@@ -61,7 +58,6 @@
 #define IPMI_CMD_READ_EVT_MSG_BUF         0x35
 
 #define IPMI_NETFN_STORAGE            0x0a
-#define IPMI_NETFN_STORAGE_MAXCMD         0x4a
 
 #define IPMI_CMD_GET_SDR_REP_INFO         0x20
 #define IPMI_CMD_GET_SDR_REP_ALLOC_INFO   0x21
@@ -1516,18 +1512,17 @@ static void get_sensor_reading(IPMIBmcSim *ibs,
     }
 }
 
-static const IPMICmdHandler chassis_cmds[IPMI_NETFN_CHASSIS_MAXCMD] = {
+static const IPMICmdHandler chassis_cmds[] = {
     [IPMI_CMD_GET_CHASSIS_CAPABILITIES] = chassis_capabilities,
     [IPMI_CMD_GET_CHASSIS_STATUS] = chassis_status,
     [IPMI_CMD_CHASSIS_CONTROL] = chassis_control
 };
 static const IPMINetfn chassis_netfn = {
-    .cmd_nums = IPMI_NETFN_CHASSIS_MAXCMD,
+    .cmd_nums = ARRAY_SIZE(chassis_cmds),
     .cmd_handlers = chassis_cmds
 };
 
-static const IPMICmdHandler
-sensor_event_cmds[IPMI_NETFN_SENSOR_EVENT_MAXCMD] = {
+static const IPMICmdHandler sensor_event_cmds[] = {
     [IPMI_CMD_SET_SENSOR_EVT_ENABLE] = set_sensor_evt_enable,
     [IPMI_CMD_GET_SENSOR_EVT_ENABLE] = get_sensor_evt_enable,
     [IPMI_CMD_REARM_SENSOR_EVTS] = rearm_sensor_evts,
@@ -1535,11 +1530,11 @@ sensor_event_cmds[IPMI_NETFN_SENSOR_EVENT_MAXCMD] = {
     [IPMI_CMD_GET_SENSOR_READING] = get_sensor_reading
 };
 static const IPMINetfn sensor_event_netfn = {
-    .cmd_nums = IPMI_NETFN_SENSOR_EVENT_MAXCMD,
+    .cmd_nums = ARRAY_SIZE(sensor_event_cmds),
     .cmd_handlers = sensor_event_cmds
 };
 
-static const IPMICmdHandler app_cmds[IPMI_NETFN_APP_MAXCMD] = {
+static const IPMICmdHandler app_cmds[] = {
     [IPMI_CMD_GET_DEVICE_ID] = get_device_id,
     [IPMI_CMD_COLD_RESET] = cold_reset,
     [IPMI_CMD_WARM_RESET] = warm_reset,
@@ -1555,11 +1550,11 @@ static const IPMICmdHandler app_cmds[IPMI_NETFN_APP_MAXCMD] = {
     [IPMI_CMD_GET_WATCHDOG_TIMER] = get_watchdog_timer,
 };
 static const IPMINetfn app_netfn = {
-    .cmd_nums = IPMI_NETFN_APP_MAXCMD,
+    .cmd_nums = ARRAY_SIZE(app_cmds),
     .cmd_handlers = app_cmds
 };
 
-static const IPMICmdHandler storage_cmds[IPMI_NETFN_STORAGE_MAXCMD] = {
+static const IPMICmdHandler storage_cmds[] = {
     [IPMI_CMD_GET_SDR_REP_INFO] = get_sdr_rep_info,
     [IPMI_CMD_RESERVE_SDR_REP] = reserve_sdr_rep,
     [IPMI_CMD_GET_SDR] = get_sdr,
@@ -1575,7 +1570,7 @@ static const IPMICmdHandler storage_cmds[IPMI_NETFN_STORAGE_MAXCMD] = {
 };
 
 static const IPMINetfn storage_netfn = {
-    .cmd_nums = IPMI_NETFN_STORAGE_MAXCMD,
+    .cmd_nums = ARRAY_SIZE(storage_cmds),
     .cmd_handlers = storage_cmds
 };
 
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 20/49] ipmi: cleanup error_report messages
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (18 preceding siblings ...)
  2016-02-04 21:52 ` [Qemu-devel] [PULL 19/49] ipmi: replace *_MAXCMD defines Michael S. Tsirkin
@ 2016-02-04 21:52 ` Michael S. Tsirkin
  2016-02-04 21:52 ` [Qemu-devel] [PULL 21/49] ipmi: fix SDR length value Michael S. Tsirkin
                   ` (29 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Eduardo Habkost, Corey Minyard,
	=?UTF-8?q?C=C3=A9dric=20Le=20Goater?=,
	Marcel Apfelbaum, Greg Kurz

From: Cédric Le Goater <clg@fr.ibm.com>

Signed-off-by: Cédric Le Goater <clg@fr.ibm.com>
Cc: Greg Kurz <gkurz@linux.vnet.ibm.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/ipmi/ipmi_bmc_sim.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
index f7e87b4..d8ca76a 100644
--- a/hw/ipmi/ipmi_bmc_sim.c
+++ b/hw/ipmi/ipmi_bmc_sim.c
@@ -1644,7 +1644,7 @@ static void ipmi_sim_init(Object *obj)
     for (i = 0;;) {
         int len;
         if ((i + 5) > sizeof(init_sdrs)) {
-            error_report("Problem with recid 0x%4.4x: \n", i);
+            error_report("Problem with recid 0x%4.4x", i);
             return;
         }
         len = init_sdrs[i + 4];
@@ -1653,7 +1653,7 @@ static void ipmi_sim_init(Object *obj)
             break;
         }
         if ((i + len + 5) > sizeof(init_sdrs)) {
-            error_report("Problem with recid 0x%4.4x\n", i);
+            error_report("Problem with recid 0x%4.4x", i);
             return;
         }
         sdr_add_entry(ibs, init_sdrs + i, len, NULL);
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 21/49] ipmi: fix SDR length value
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (19 preceding siblings ...)
  2016-02-04 21:52 ` [Qemu-devel] [PULL 20/49] ipmi: cleanup error_report messages Michael S. Tsirkin
@ 2016-02-04 21:52 ` Michael S. Tsirkin
  2016-02-04 21:52 ` [Qemu-devel] [PULL 22/49] ipmi: introduce a struct ipmi_sdr_compact Michael S. Tsirkin
                   ` (28 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Eduardo Habkost, Corey Minyard,
	=?UTF-8?q?C=C3=A9dric=20Le=20Goater?=,
	Marcel Apfelbaum, Greg Kurz

From: Cédric Le Goater <clg@fr.ibm.com>

The IPMI BMC simulator populates the SDR table with a set of initial
SDRs. The length of each SDR is taken from the record itself (byte 4)
which does not include the size of the header. But, the full length
(header + data) is required by the sdr_add_entry() routine.

Signed-off-by: Cédric Le Goater <clg@fr.ibm.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/ipmi/ipmi_bmc_sim.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
index d8ca76a..73a4f6a 100644
--- a/hw/ipmi/ipmi_bmc_sim.c
+++ b/hw/ipmi/ipmi_bmc_sim.c
@@ -356,7 +356,7 @@ static int sdr_find_entry(IPMISdr *sdr, uint16_t recid,
 
     while (pos < sdr->next_free) {
         uint16_t trec = sdr->sdr[pos] | (sdr->sdr[pos + 1] << 8);
-        unsigned int nextpos = pos + sdr->sdr[pos + 4];
+        unsigned int nextpos = pos + sdr->sdr[pos + 4] + 5;
 
         if (trec == recid) {
             if (nextrec) {
@@ -1164,7 +1164,7 @@ static void get_sdr(IPMIBmcSim *ibs,
         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
         return;
     }
-    if (cmd[6] > (ibs->sdr.sdr[pos + 4])) {
+    if (cmd[6] > (ibs->sdr.sdr[pos + 4] + 5)) {
         rsp[2] = IPMI_CC_PARM_OUT_OF_RANGE;
         return;
     }
@@ -1173,7 +1173,7 @@ static void get_sdr(IPMIBmcSim *ibs,
     IPMI_ADD_RSP_DATA((nextrec >> 8) & 0xff);
 
     if (cmd[7] == 0xff) {
-        cmd[7] = ibs->sdr.sdr[pos + 4] - cmd[6];
+        cmd[7] = ibs->sdr.sdr[pos + 4] + 5 - cmd[6];
     }
 
     if ((cmd[7] + *rsp_len) > max_rsp_len) {
@@ -1647,17 +1647,17 @@ static void ipmi_sim_init(Object *obj)
             error_report("Problem with recid 0x%4.4x", i);
             return;
         }
-        len = init_sdrs[i + 4];
+        len = init_sdrs[i + 4] + 5;
         recid = init_sdrs[i] | (init_sdrs[i + 1] << 8);
         if (recid == 0xffff) {
             break;
         }
-        if ((i + len + 5) > sizeof(init_sdrs)) {
+        if ((i + len) > sizeof(init_sdrs)) {
             error_report("Problem with recid 0x%4.4x", i);
             return;
         }
         sdr_add_entry(ibs, init_sdrs + i, len, NULL);
-        i += len + 5;
+        i += len;
     }
 
     ipmi_init_sensors_from_sdrs(ibs);
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 22/49] ipmi: introduce a struct ipmi_sdr_compact
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (20 preceding siblings ...)
  2016-02-04 21:52 ` [Qemu-devel] [PULL 21/49] ipmi: fix SDR length value Michael S. Tsirkin
@ 2016-02-04 21:52 ` Michael S. Tsirkin
  2016-02-04 21:52 ` [Qemu-devel] [PULL 23/49] ipmi: add get and set SENSOR_TYPE commands Michael S. Tsirkin
                   ` (27 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Eduardo Habkost, Corey Minyard,
	=?UTF-8?q?C=C3=A9dric=20Le=20Goater?=,
	Marcel Apfelbaum, Greg Kurz

From: Cédric Le Goater <clg@fr.ibm.com>

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 <clg@fr.ibm.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 include/hw/ipmi/ipmi.h | 45 +++++++++++++++++++++++++++++++
 hw/ipmi/ipmi_bmc_sim.c | 72 ++++++++++++++++++++++++++++++--------------------
 2 files changed, 89 insertions(+), 28 deletions(-)

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
diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
index 73a4f6a..84fbcd2 100644
--- a/hw/ipmi/ipmi_bmc_sim.c
+++ b/hw/ipmi/ipmi_bmc_sim.c
@@ -318,14 +318,18 @@ static void sdr_inc_reservation(IPMISdr *sdr)
     }
 }
 
-static int sdr_add_entry(IPMIBmcSim *ibs, const uint8_t *entry,
+static int sdr_add_entry(IPMIBmcSim *ibs,
+                         const struct ipmi_sdr_header *sdrh_entry,
                          unsigned int len, uint16_t *recid)
 {
-    if ((len < 5) || (len > 255)) {
+    struct ipmi_sdr_header *sdrh =
+        (struct ipmi_sdr_header *) &ibs->sdr.sdr[ibs->sdr.next_free];
+
+    if ((len < IPMI_SDR_HEADER_SIZE) || (len > 255)) {
         return 1;
     }
 
-    if (entry[4] != len - 5) {
+    if (ipmi_sdr_length(sdrh_entry) != len) {
         return 1;
     }
 
@@ -334,10 +338,10 @@ static int sdr_add_entry(IPMIBmcSim *ibs, const uint8_t *entry,
         return 1;
     }
 
-    memcpy(ibs->sdr.sdr + ibs->sdr.next_free, entry, len);
-    ibs->sdr.sdr[ibs->sdr.next_free] = ibs->sdr.next_rec_id & 0xff;
-    ibs->sdr.sdr[ibs->sdr.next_free+1] = (ibs->sdr.next_rec_id >> 8) & 0xff;
-    ibs->sdr.sdr[ibs->sdr.next_free+2] = 0x51; /* Conform to IPMI 1.5 spec */
+    memcpy(sdrh, sdrh_entry, len);
+    sdrh->rec_id[0] = ibs->sdr.next_rec_id & 0xff;
+    sdrh->rec_id[1] = (ibs->sdr.next_rec_id >> 8) & 0xff;
+    sdrh->sdr_version = 0x51; /* Conform to IPMI 1.5 spec */
 
     if (recid) {
         *recid = ibs->sdr.next_rec_id;
@@ -355,8 +359,10 @@ static int sdr_find_entry(IPMISdr *sdr, uint16_t recid,
     unsigned int pos = *retpos;
 
     while (pos < sdr->next_free) {
-        uint16_t trec = sdr->sdr[pos] | (sdr->sdr[pos + 1] << 8);
-        unsigned int nextpos = pos + sdr->sdr[pos + 4] + 5;
+        struct ipmi_sdr_header *sdrh =
+            (struct ipmi_sdr_header *) &sdr->sdr[pos];
+        uint16_t trec = ipmi_sdr_recid(sdrh);
+        unsigned int nextpos = pos + ipmi_sdr_length(sdrh);
 
         if (trec == recid) {
             if (nextrec) {
@@ -505,29 +511,32 @@ static void ipmi_init_sensors_from_sdrs(IPMIBmcSim *s)
 
     pos = 0;
     for (i = 0; !sdr_find_entry(&s->sdr, i, &pos, NULL); i++) {
-        uint8_t *sdr = s->sdr.sdr + pos;
-        unsigned int len = sdr[4];
+        struct ipmi_sdr_compact *sdr =
+            (struct ipmi_sdr_compact *) &s->sdr.sdr[pos];
+        unsigned int len = sdr->header.rec_length;
 
         if (len < 20) {
             continue;
         }
-        if ((sdr[3] < 1) || (sdr[3] > 2)) {
+        if (sdr->header.rec_type != IPMI_SDR_COMPACT_TYPE) {
             continue; /* Not a sensor SDR we set from */
         }
 
-        if (sdr[7] > MAX_SENSORS) {
+        if (sdr->sensor_owner_number > MAX_SENSORS) {
             continue;
         }
-        sens = s->sensors + sdr[7];
+        sens = s->sensors + sdr->sensor_owner_number;
 
         IPMI_SENSOR_SET_PRESENT(sens, 1);
-        IPMI_SENSOR_SET_SCAN_ON(sens, (sdr[10] >> 6) & 1);
-        IPMI_SENSOR_SET_EVENTS_ON(sens, (sdr[10] >> 5) & 1);
-        sens->assert_suppt = sdr[14] | (sdr[15] << 8);
-        sens->deassert_suppt = sdr[16] | (sdr[17] << 8);
-        sens->states_suppt = sdr[18] | (sdr[19] << 8);
-        sens->sensor_type = sdr[12];
-        sens->evt_reading_type_code = sdr[13] & 0x7f;
+        IPMI_SENSOR_SET_SCAN_ON(sens, (sdr->sensor_init >> 6) & 1);
+        IPMI_SENSOR_SET_EVENTS_ON(sens, (sdr->sensor_init >> 5) & 1);
+        sens->assert_suppt = sdr->assert_mask[0] | (sdr->assert_mask[1] << 8);
+        sens->deassert_suppt =
+            sdr->deassert_mask[0] | (sdr->deassert_mask[1] << 8);
+        sens->states_suppt =
+            sdr->discrete_mask[0] | (sdr->discrete_mask[1] << 8);
+        sens->sensor_type = sdr->sensor_type;
+        sens->evt_reading_type_code = sdr->reading_type & 0x7f;
 
         /* Enable all the events that are supported. */
         sens->assert_enable = sens->assert_suppt;
@@ -1153,6 +1162,7 @@ static void get_sdr(IPMIBmcSim *ibs,
 {
     unsigned int pos;
     uint16_t nextrec;
+    struct ipmi_sdr_header *sdrh;
 
     IPMI_CHECK_CMD_LEN(8);
     if (cmd[6]) {
@@ -1164,7 +1174,10 @@ static void get_sdr(IPMIBmcSim *ibs,
         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
         return;
     }
-    if (cmd[6] > (ibs->sdr.sdr[pos + 4] + 5)) {
+
+    sdrh = (struct ipmi_sdr_header *) &ibs->sdr.sdr[pos];
+
+    if (cmd[6] > ipmi_sdr_length(sdrh)) {
         rsp[2] = IPMI_CC_PARM_OUT_OF_RANGE;
         return;
     }
@@ -1173,7 +1186,7 @@ static void get_sdr(IPMIBmcSim *ibs,
     IPMI_ADD_RSP_DATA((nextrec >> 8) & 0xff);
 
     if (cmd[7] == 0xff) {
-        cmd[7] = ibs->sdr.sdr[pos + 4] + 5 - cmd[6];
+        cmd[7] = ipmi_sdr_length(sdrh) - cmd[6];
     }
 
     if ((cmd[7] + *rsp_len) > max_rsp_len) {
@@ -1190,8 +1203,9 @@ static void add_sdr(IPMIBmcSim *ibs,
                     unsigned int max_rsp_len)
 {
     uint16_t recid;
+    struct ipmi_sdr_header *sdrh = (struct ipmi_sdr_header *) cmd + 2;
 
-    if (sdr_add_entry(ibs, cmd + 2, cmd_len - 2, &recid)) {
+    if (sdr_add_entry(ibs, sdrh, cmd_len - 2, &recid)) {
         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
         return;
     }
@@ -1642,13 +1656,15 @@ static void ipmi_sim_init(Object *obj)
     }
 
     for (i = 0;;) {
+        struct ipmi_sdr_header *sdrh;
         int len;
-        if ((i + 5) > sizeof(init_sdrs)) {
+        if ((i + IPMI_SDR_HEADER_SIZE) > sizeof(init_sdrs)) {
             error_report("Problem with recid 0x%4.4x", i);
             return;
         }
-        len = init_sdrs[i + 4] + 5;
-        recid = init_sdrs[i] | (init_sdrs[i + 1] << 8);
+        sdrh = (struct ipmi_sdr_header *) &init_sdrs[i];
+        len = ipmi_sdr_length(sdrh);
+        recid = ipmi_sdr_recid(sdrh);
         if (recid == 0xffff) {
             break;
         }
@@ -1656,7 +1672,7 @@ static void ipmi_sim_init(Object *obj)
             error_report("Problem with recid 0x%4.4x", i);
             return;
         }
-        sdr_add_entry(ibs, init_sdrs + i, len, NULL);
+        sdr_add_entry(ibs, sdrh, len, NULL);
         i += len;
     }
 
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 23/49] ipmi: add get and set SENSOR_TYPE commands
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (21 preceding siblings ...)
  2016-02-04 21:52 ` [Qemu-devel] [PULL 22/49] ipmi: introduce a struct ipmi_sdr_compact Michael S. Tsirkin
@ 2016-02-04 21:52 ` Michael S. Tsirkin
  2016-02-04 21:52 ` [Qemu-devel] [PULL 24/49] ipmi: add GET_SYS_RESTART_CAUSE chassis command Michael S. Tsirkin
                   ` (26 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, =?UTF-8?q?C=C3=A9dric=20Le=20Goater?=,
	Eduardo Habkost, Greg Kurz, Corey Minyard

From: Cédric Le Goater <clg@fr.ibm.com>

Signed-off-by: Cédric Le Goater <clg@fr.ibm.com>
Acked-by: Corey Minyard <cminyard@mvista.com>
Reviewed-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/ipmi/ipmi_bmc_sim.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
index 84fbcd2..24a4b32 100644
--- a/hw/ipmi/ipmi_bmc_sim.c
+++ b/hw/ipmi/ipmi_bmc_sim.c
@@ -40,6 +40,8 @@
 #define IPMI_CMD_REARM_SENSOR_EVTS        0x2a
 #define IPMI_CMD_GET_SENSOR_EVT_STATUS    0x2b
 #define IPMI_CMD_GET_SENSOR_READING       0x2d
+#define IPMI_CMD_SET_SENSOR_TYPE          0x2e
+#define IPMI_CMD_GET_SENSOR_TYPE          0x2f
 
 /* #define IPMI_NETFN_APP             0x06 In ipmi.h */
 
@@ -1526,6 +1528,45 @@ static void get_sensor_reading(IPMIBmcSim *ibs,
     }
 }
 
+static void set_sensor_type(IPMIBmcSim *ibs,
+                               uint8_t *cmd, unsigned int cmd_len,
+                               uint8_t *rsp, unsigned int *rsp_len,
+                               unsigned int max_rsp_len)
+{
+    IPMISensor *sens;
+
+
+    IPMI_CHECK_CMD_LEN(5);
+    if ((cmd[2] > MAX_SENSORS) ||
+            !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
+        rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
+        return;
+    }
+    sens = ibs->sensors + cmd[2];
+    sens->sensor_type = cmd[3];
+    sens->evt_reading_type_code = cmd[4] & 0x7f;
+}
+
+static void get_sensor_type(IPMIBmcSim *ibs,
+                               uint8_t *cmd, unsigned int cmd_len,
+                               uint8_t *rsp, unsigned int *rsp_len,
+                               unsigned int max_rsp_len)
+{
+    IPMISensor *sens;
+
+
+    IPMI_CHECK_CMD_LEN(3);
+    if ((cmd[2] > MAX_SENSORS) ||
+            !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
+        rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
+        return;
+    }
+    sens = ibs->sensors + cmd[2];
+    IPMI_ADD_RSP_DATA(sens->sensor_type);
+    IPMI_ADD_RSP_DATA(sens->evt_reading_type_code);
+}
+
+
 static const IPMICmdHandler chassis_cmds[] = {
     [IPMI_CMD_GET_CHASSIS_CAPABILITIES] = chassis_capabilities,
     [IPMI_CMD_GET_CHASSIS_STATUS] = chassis_status,
@@ -1541,7 +1582,9 @@ static const IPMICmdHandler sensor_event_cmds[] = {
     [IPMI_CMD_GET_SENSOR_EVT_ENABLE] = get_sensor_evt_enable,
     [IPMI_CMD_REARM_SENSOR_EVTS] = rearm_sensor_evts,
     [IPMI_CMD_GET_SENSOR_EVT_STATUS] = get_sensor_evt_status,
-    [IPMI_CMD_GET_SENSOR_READING] = get_sensor_reading
+    [IPMI_CMD_GET_SENSOR_READING] = get_sensor_reading,
+    [IPMI_CMD_SET_SENSOR_TYPE] = set_sensor_type,
+    [IPMI_CMD_GET_SENSOR_TYPE] = get_sensor_type,
 };
 static const IPMINetfn sensor_event_netfn = {
     .cmd_nums = ARRAY_SIZE(sensor_event_cmds),
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 24/49] ipmi: add GET_SYS_RESTART_CAUSE chassis command
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (22 preceding siblings ...)
  2016-02-04 21:52 ` [Qemu-devel] [PULL 23/49] ipmi: add get and set SENSOR_TYPE commands Michael S. Tsirkin
@ 2016-02-04 21:52 ` Michael S. Tsirkin
  2016-02-04 21:52 ` [Qemu-devel] [PULL 25/49] ipmi: add ACPI power and GUID commands Michael S. Tsirkin
                   ` (25 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Eduardo Habkost, Corey Minyard,
	=?UTF-8?q?C=C3=A9dric=20Le=20Goater?=,
	Marcel Apfelbaum, Greg Kurz

From: Cédric Le Goater <clg@fr.ibm.com>

This is a simulator. Just return an unknown cause (0).

Signed-off-by: Cédric Le Goater <clg@fr.ibm.com>
Acked-by: Corey Minyard <cminyard@mvista.com>
Reviewed-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/ipmi/ipmi_bmc_sim.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
index 24a4b32..29224dd 100644
--- a/hw/ipmi/ipmi_bmc_sim.c
+++ b/hw/ipmi/ipmi_bmc_sim.c
@@ -32,6 +32,7 @@
 #define IPMI_CMD_GET_CHASSIS_CAPABILITIES 0x00
 #define IPMI_CMD_GET_CHASSIS_STATUS       0x01
 #define IPMI_CMD_CHASSIS_CONTROL          0x02
+#define IPMI_CMD_GET_SYS_RESTART_CAUSE    0x09
 
 #define IPMI_NETFN_SENSOR_EVENT       0x04
 
@@ -195,6 +196,8 @@ struct IPMIBmcSim {
     uint8_t mfg_id[3];
     uint8_t product_id[2];
 
+    uint8_t restart_cause;
+
     IPMISel sel;
     IPMISdr sdr;
     IPMISensor sensors[MAX_SENSORS];
@@ -754,6 +757,15 @@ static void chassis_control(IPMIBmcSim *ibs,
     }
 }
 
+static void chassis_get_sys_restart_cause(IPMIBmcSim *ibs,
+                           uint8_t *cmd, unsigned int cmd_len,
+                           uint8_t *rsp, unsigned int *rsp_len,
+                           unsigned int max_rsp_len)
+{
+    IPMI_ADD_RSP_DATA(ibs->restart_cause & 0xf); /* Restart Cause */
+    IPMI_ADD_RSP_DATA(0);  /* Channel 0 */
+}
+
 static void get_device_id(IPMIBmcSim *ibs,
                           uint8_t *cmd, unsigned int cmd_len,
                           uint8_t *rsp, unsigned int *rsp_len,
@@ -1570,7 +1582,8 @@ static void get_sensor_type(IPMIBmcSim *ibs,
 static const IPMICmdHandler chassis_cmds[] = {
     [IPMI_CMD_GET_CHASSIS_CAPABILITIES] = chassis_capabilities,
     [IPMI_CMD_GET_CHASSIS_STATUS] = chassis_status,
-    [IPMI_CMD_CHASSIS_CONTROL] = chassis_control
+    [IPMI_CMD_CHASSIS_CONTROL] = chassis_control,
+    [IPMI_CMD_GET_SYS_RESTART_CAUSE] = chassis_get_sys_restart_cause
 };
 static const IPMINetfn chassis_netfn = {
     .cmd_nums = ARRAY_SIZE(chassis_cmds),
@@ -1691,6 +1704,7 @@ static void ipmi_sim_init(Object *obj)
     ibs->bmc_global_enables = (1 << IPMI_BMC_EVENT_LOG_BIT);
     ibs->device_id = 0x20;
     ibs->ipmi_version = 0x02; /* IPMI 2.0 */
+    ibs->restart_cause = 0;
     for (i = 0; i < 4; i++) {
         ibs->sel.last_addition[i] = 0xff;
         ibs->sel.last_clear[i] = 0xff;
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 25/49] ipmi: add ACPI power and GUID commands
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (23 preceding siblings ...)
  2016-02-04 21:52 ` [Qemu-devel] [PULL 24/49] ipmi: add GET_SYS_RESTART_CAUSE chassis command Michael S. Tsirkin
@ 2016-02-04 21:52 ` Michael S. Tsirkin
  2016-02-04 21:52 ` [Qemu-devel] [PULL 26/49] pc: Move PcGuestInfo declaration to top of file Michael S. Tsirkin
                   ` (24 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Eduardo Habkost, Corey Minyard,
	=?UTF-8?q?C=C3=A9dric=20Le=20Goater?=,
	Marcel Apfelbaum, Greg Kurz

From: Cédric Le Goater <clg@fr.ibm.com>

>From the specs (20.8 Get Device GUID Command), the command needs to
return a GUID (Globally Unique ID), or UUID, that should never change
over the lifetime of the device. qemu_uuid looked like a good
candidate to start with but we could use a specific BMC property also
if needed.

Signed-off-by: Cédric Le Goater <clg@fr.ibm.com>
Acked-by: Corey Minyard <cminyard@mvista.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/ipmi/ipmi_bmc_sim.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
index 29224dd..e1ad19b 100644
--- a/hw/ipmi/ipmi_bmc_sim.c
+++ b/hw/ipmi/ipmi_bmc_sim.c
@@ -23,6 +23,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "sysemu/sysemu.h"
 #include "qemu/timer.h"
 #include "hw/ipmi/ipmi.h"
 #include "qemu/error-report.h"
@@ -49,6 +50,9 @@
 #define IPMI_CMD_GET_DEVICE_ID            0x01
 #define IPMI_CMD_COLD_RESET               0x02
 #define IPMI_CMD_WARM_RESET               0x03
+#define IPMI_CMD_SET_ACPI_POWER_STATE     0x06
+#define IPMI_CMD_GET_ACPI_POWER_STATE     0x07
+#define IPMI_CMD_GET_DEVICE_GUID          0x08
 #define IPMI_CMD_RESET_WATCHDOG_TIMER     0x22
 #define IPMI_CMD_SET_WATCHDOG_TIMER       0x24
 #define IPMI_CMD_GET_WATCHDOG_TIMER       0x25
@@ -198,6 +202,9 @@ struct IPMIBmcSim {
 
     uint8_t restart_cause;
 
+    uint8_t acpi_power_state[2];
+    uint8_t uuid[16];
+
     IPMISel sel;
     IPMISdr sdr;
     IPMISensor sensors[MAX_SENSORS];
@@ -826,6 +833,36 @@ static void warm_reset(IPMIBmcSim *ibs,
         k->reset(s, false);
     }
 }
+static void set_acpi_power_state(IPMIBmcSim *ibs,
+                          uint8_t *cmd, unsigned int cmd_len,
+                          uint8_t *rsp, unsigned int *rsp_len,
+                          unsigned int max_rsp_len)
+{
+    IPMI_CHECK_CMD_LEN(4);
+    ibs->acpi_power_state[0] = cmd[2];
+    ibs->acpi_power_state[1] = cmd[3];
+}
+
+static void get_acpi_power_state(IPMIBmcSim *ibs,
+                          uint8_t *cmd, unsigned int cmd_len,
+                          uint8_t *rsp, unsigned int *rsp_len,
+                          unsigned int max_rsp_len)
+{
+    IPMI_ADD_RSP_DATA(ibs->acpi_power_state[0]);
+    IPMI_ADD_RSP_DATA(ibs->acpi_power_state[1]);
+}
+
+static void get_device_guid(IPMIBmcSim *ibs,
+                          uint8_t *cmd, unsigned int cmd_len,
+                          uint8_t *rsp, unsigned int *rsp_len,
+                          unsigned int max_rsp_len)
+{
+    unsigned int i;
+
+    for (i = 0; i < 16; i++) {
+        IPMI_ADD_RSP_DATA(ibs->uuid[i]);
+    }
+}
 
 static void set_bmc_global_enables(IPMIBmcSim *ibs,
                                    uint8_t *cmd, unsigned int cmd_len,
@@ -1608,6 +1645,9 @@ static const IPMICmdHandler app_cmds[] = {
     [IPMI_CMD_GET_DEVICE_ID] = get_device_id,
     [IPMI_CMD_COLD_RESET] = cold_reset,
     [IPMI_CMD_WARM_RESET] = warm_reset,
+    [IPMI_CMD_SET_ACPI_POWER_STATE] = set_acpi_power_state,
+    [IPMI_CMD_GET_ACPI_POWER_STATE] = get_acpi_power_state,
+    [IPMI_CMD_GET_DEVICE_GUID] = get_device_guid,
     [IPMI_CMD_SET_BMC_GLOBAL_ENABLES] = set_bmc_global_enables,
     [IPMI_CMD_GET_BMC_GLOBAL_ENABLES] = get_bmc_global_enables,
     [IPMI_CMD_CLR_MSG_FLAGS] = clr_msg_flags,
@@ -1733,6 +1773,15 @@ static void ipmi_sim_init(Object *obj)
         i += len;
     }
 
+    ibs->acpi_power_state[0] = 0;
+    ibs->acpi_power_state[1] = 0;
+
+    if (qemu_uuid_set) {
+        memcpy(&ibs->uuid, qemu_uuid, 16);
+    } else {
+        memset(&ibs->uuid, 0, 16);
+    }
+
     ipmi_init_sensors_from_sdrs(ibs);
     register_cmds(ibs);
 
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 26/49] pc: Move PcGuestInfo declaration to top of file
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (24 preceding siblings ...)
  2016-02-04 21:52 ` [Qemu-devel] [PULL 25/49] ipmi: add ACPI power and GUID commands Michael S. Tsirkin
@ 2016-02-04 21:52 ` Michael S. Tsirkin
  2016-02-04 21:52 ` [Qemu-devel] [PULL 27/49] pc: Eliminate struct PcGuestInfoState Michael S. Tsirkin
                   ` (23 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marcel Apfelbaum, Peter Maydell, Eduardo Habkost

From: Eduardo Habkost <ehabkost@redhat.com>

The struct will be used inside PCMachineState.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
---
 include/hw/i386/pc.h | 31 ++++++++++++++++---------------
 1 file changed, 16 insertions(+), 15 deletions(-)

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);
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 27/49] pc: Eliminate struct PcGuestInfoState
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (25 preceding siblings ...)
  2016-02-04 21:52 ` [Qemu-devel] [PULL 26/49] pc: Move PcGuestInfo declaration to top of file Michael S. Tsirkin
@ 2016-02-04 21:52 ` Michael S. Tsirkin
  2016-02-04 21:52 ` [Qemu-devel] [PULL 28/49] pc: Simplify pc_memory_init() signature Michael S. Tsirkin
                   ` (22 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marcel Apfelbaum, Peter Maydell, Richard Henderson,
	Eduardo Habkost, Paolo Bonzini

From: Eduardo Habkost <ehabkost@redhat.com>

Instead of allocating a new struct just for PcGuestInfo and the
mchine_done Notifier, place them inside PCMachineState.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
---
 include/hw/i386/pc.h |  2 ++
 hw/i386/pc.c         | 27 ++++++++++-----------------
 2 files changed, 12 insertions(+), 17 deletions(-)

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;
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 942ac06..c421d2c 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1156,18 +1156,12 @@ typedef struct PcRomPciInfo {
     uint64_t w64_max;
 } PcRomPciInfo;
 
-typedef struct PcGuestInfoState {
-    PcGuestInfo info;
-    Notifier machine_done;
-} PcGuestInfoState;
-
 static
-void pc_guest_info_machine_done(Notifier *notifier, void *data)
+void pc_machine_done(Notifier *notifier, void *data)
 {
-    PcGuestInfoState *guest_info_state = container_of(notifier,
-                                                      PcGuestInfoState,
-                                                      machine_done);
-    PCIBus *bus = PC_MACHINE(qdev_get_machine())->bus;
+    PCMachineState *pcms = container_of(notifier,
+                                        PCMachineState, machine_done);
+    PCIBus *bus = pcms->bus;
 
     if (bus) {
         int extra_hosts = 0;
@@ -1178,21 +1172,20 @@ void pc_guest_info_machine_done(Notifier *notifier, void *data)
                 extra_hosts++;
             }
         }
-        if (extra_hosts && guest_info_state->info.fw_cfg) {
+        if (extra_hosts && pcms->acpi_guest_info.fw_cfg) {
             uint64_t *val = g_malloc(sizeof(*val));
             *val = cpu_to_le64(extra_hosts);
-            fw_cfg_add_file(guest_info_state->info.fw_cfg,
+            fw_cfg_add_file(pcms->acpi_guest_info.fw_cfg,
                     "etc/extra-pci-roots", val, sizeof(*val));
         }
     }
 
-    acpi_setup(&guest_info_state->info);
+    acpi_setup(&pcms->acpi_guest_info);
 }
 
 PcGuestInfo *pc_guest_info_init(PCMachineState *pcms)
 {
-    PcGuestInfoState *guest_info_state = g_malloc0(sizeof *guest_info_state);
-    PcGuestInfo *guest_info = &guest_info_state->info;
+    PcGuestInfo *guest_info = &pcms->acpi_guest_info;
     int i, j;
 
     guest_info->ram_size_below_4g = pcms->below_4g_mem_size;
@@ -1220,8 +1213,8 @@ PcGuestInfo *pc_guest_info_init(PCMachineState *pcms)
         }
     }
 
-    guest_info_state->machine_done.notify = pc_guest_info_machine_done;
-    qemu_add_machine_init_done_notifier(&guest_info_state->machine_done);
+    pcms->machine_done.notify = pc_machine_done;
+    qemu_add_machine_init_done_notifier(&pcms->machine_done);
     return guest_info;
 }
 
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 28/49] pc: Simplify pc_memory_init() signature
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (26 preceding siblings ...)
  2016-02-04 21:52 ` [Qemu-devel] [PULL 27/49] pc: Eliminate struct PcGuestInfoState Michael S. Tsirkin
@ 2016-02-04 21:52 ` Michael S. Tsirkin
  2016-02-04 21:52 ` [Qemu-devel] [PULL 29/49] pc: Simplify xen_load_linux() signature Michael S. Tsirkin
                   ` (21 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marcel Apfelbaum, Peter Maydell, Richard Henderson,
	Eduardo Habkost, Paolo Bonzini

From: Eduardo Habkost <ehabkost@redhat.com>

We can get the PcGuestInfo struct directly from PCMachineState,
and the return value is not needed at all.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
---
 include/hw/i386/pc.h |  9 ++++-----
 hw/i386/pc.c         | 11 +++++------
 hw/i386/pc_piix.c    |  2 +-
 hw/i386/pc_q35.c     |  2 +-
 4 files changed, 11 insertions(+), 13 deletions(-)

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,
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index c421d2c..fbdad88 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1276,12 +1276,12 @@ FWCfgState *xen_load_linux(PCMachineState *pcms,
     return fw_cfg;
 }
 
-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)
 {
+    PcGuestInfo *guest_info = &pcms->acpi_guest_info;
     int linux_boot, i;
     MemoryRegion *ram, *option_rom_mr;
     MemoryRegion *ram_below_4g, *ram_above_4g;
@@ -1403,7 +1403,6 @@ FWCfgState *pc_memory_init(PCMachineState *pcms,
         rom_add_option(option_rom[i].name, option_rom[i].bootindex);
     }
     guest_info->fw_cfg = fw_cfg;
-    return fw_cfg;
 }
 
 qemu_irq pc_allocate_cpu_irq(void)
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 9951d6e..ad51fd6 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -162,7 +162,7 @@ static void pc_init1(MachineState *machine,
     /* allocate ram and load rom/bios */
     if (!xen_enabled()) {
         pc_memory_init(pcms, system_memory,
-                       rom_memory, &ram_memory, guest_info);
+                       rom_memory, &ram_memory);
     } else if (machine->kernel_filename != NULL) {
         /* For xen HVM direct kernel boot, load linux here */
         xen_load_linux(pcms, guest_info);
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 56be9b1..0c156e2 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -156,7 +156,7 @@ static void pc_q35_init(MachineState *machine)
     /* allocate ram and load rom/bios */
     if (!xen_enabled()) {
         pc_memory_init(pcms, get_system_memory(),
-                       rom_memory, &ram_memory, guest_info);
+                       rom_memory, &ram_memory);
     }
 
     /* irq lines */
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 29/49] pc: Simplify xen_load_linux() signature
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (27 preceding siblings ...)
  2016-02-04 21:52 ` [Qemu-devel] [PULL 28/49] pc: Simplify pc_memory_init() signature Michael S. Tsirkin
@ 2016-02-04 21:52 ` Michael S. Tsirkin
  2016-02-04 21:52 ` [Qemu-devel] [PULL 30/49] acpi: Remove guest_info parameters from functions Michael S. Tsirkin
                   ` (20 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marcel Apfelbaum, Peter Maydell, Richard Henderson,
	Eduardo Habkost, Paolo Bonzini

From: Eduardo Habkost <ehabkost@redhat.com>

We can get the PcGuestInfo struct directly from PCMachineState,
and the return value is not needed at all.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
---
 include/hw/i386/pc.h | 3 +--
 hw/i386/pc.c         | 5 ++---
 hw/i386/pc_piix.c    | 2 +-
 3 files changed, 4 insertions(+), 6 deletions(-)

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,
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index fbdad88..9745dca 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1255,11 +1255,11 @@ void pc_acpi_init(const char *default_dsdt)
     }
 }
 
-FWCfgState *xen_load_linux(PCMachineState *pcms,
-                           PcGuestInfo *guest_info)
+void xen_load_linux(PCMachineState *pcms)
 {
     int i;
     FWCfgState *fw_cfg;
+    PcGuestInfo *guest_info = &pcms->acpi_guest_info;
 
     assert(MACHINE(pcms)->kernel_filename != NULL);
 
@@ -1273,7 +1273,6 @@ FWCfgState *xen_load_linux(PCMachineState *pcms,
         rom_add_option(option_rom[i].name, option_rom[i].bootindex);
     }
     guest_info->fw_cfg = fw_cfg;
-    return fw_cfg;
 }
 
 void pc_memory_init(PCMachineState *pcms,
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index ad51fd6..4262c32 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -165,7 +165,7 @@ static void pc_init1(MachineState *machine,
                        rom_memory, &ram_memory);
     } else if (machine->kernel_filename != NULL) {
         /* For xen HVM direct kernel boot, load linux here */
-        xen_load_linux(pcms, guest_info);
+        xen_load_linux(pcms);
     }
 
     gsi_state = g_malloc0(sizeof(*gsi_state));
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 30/49] acpi: Remove guest_info parameters from functions
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (28 preceding siblings ...)
  2016-02-04 21:52 ` [Qemu-devel] [PULL 29/49] pc: Simplify xen_load_linux() signature Michael S. Tsirkin
@ 2016-02-04 21:52 ` Michael S. Tsirkin
  2016-02-04 21:53 ` [Qemu-devel] [PULL 31/49] acpi: Don't save PcGuestInfo on AcpiBuildState Michael S. Tsirkin
                   ` (19 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Richard Henderson, Paolo Bonzini, Eduardo Habkost,
	Igor Mammedov

From: Eduardo Habkost <ehabkost@redhat.com>

We can use PC_MACHINE(qdev_get_machine())->acpi_guest_info to get
guest_info.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/i386/acpi-build.c | 35 +++++++++++++++++++++--------------
 1 file changed, 21 insertions(+), 14 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 2028ed7..e41a2ae 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -290,7 +290,7 @@ static void acpi_align_size(GArray *blob, unsigned align)
 
 /* FACS */
 static void
-build_facs(GArray *table_data, GArray *linker, PcGuestInfo *guest_info)
+build_facs(GArray *table_data, GArray *linker)
 {
     AcpiFacsDescriptorRev1 *facs = acpi_data_push(table_data, sizeof *facs);
     memcpy(&facs->signature, "FACS", 4);
@@ -361,9 +361,10 @@ build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm,
 }
 
 static void
-build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu,
-           PcGuestInfo *guest_info)
+build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu)
 {
+    PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
+    PcGuestInfo *guest_info = &pcms->acpi_guest_info;
     int madt_start = table_data->len;
 
     AcpiMultipleApicTable *madt;
@@ -1937,13 +1938,15 @@ static Aml *build_q35_osc_method(void)
 static void
 build_dsdt(GArray *table_data, GArray *linker,
            AcpiCpuInfo *cpu, AcpiPmInfo *pm, AcpiMiscInfo *misc,
-           PcPciInfo *pci, PcGuestInfo *guest_info)
+           PcPciInfo *pci)
 {
     CrsRangeEntry *entry;
     Aml *dsdt, *sb_scope, *scope, *dev, *method, *field, *pkg, *crs;
     GPtrArray *mem_ranges = g_ptr_array_new_with_free_func(crs_range_free);
     GPtrArray *io_ranges = g_ptr_array_new_with_free_func(crs_range_free);
     MachineState *machine = MACHINE(qdev_get_machine());
+    PCMachineState *pcms = PC_MACHINE(machine);
+    PcGuestInfo *guest_info = &pcms->acpi_guest_info;
     uint32_t nr_mem = machine->ram_slots;
     int root_bus_limit = 0xFF;
     PCIBus *bus = NULL;
@@ -2365,7 +2368,7 @@ acpi_build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
 }
 
 static void
-build_srat(GArray *table_data, GArray *linker, PcGuestInfo *guest_info)
+build_srat(GArray *table_data, GArray *linker)
 {
     AcpiSystemResourceAffinityTable *srat;
     AcpiSratProcessorAffinity *core;
@@ -2376,6 +2379,7 @@ build_srat(GArray *table_data, GArray *linker, PcGuestInfo *guest_info)
     int srat_start, numa_start, slots;
     uint64_t mem_len, mem_base, next_base;
     PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
+    PcGuestInfo *guest_info = &pcms->acpi_guest_info;
     ram_addr_t hotplugabble_address_space_size =
         object_property_get_int(OBJECT(pcms), PC_MACHINE_MEMHP_REGION_SIZE,
                                 NULL);
@@ -2587,8 +2591,10 @@ static bool acpi_has_nvdimm(void)
 }
 
 static
-void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
+void acpi_build(AcpiBuildTables *tables)
 {
+    PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
+    PcGuestInfo *guest_info = &pcms->acpi_guest_info;
     GArray *table_offsets;
     unsigned facs, dsdt, rsdt, fadt;
     AcpiCpuInfo cpu;
@@ -2619,12 +2625,11 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
      * requirements.
      */
     facs = tables_blob->len;
-    build_facs(tables_blob, tables->linker, guest_info);
+    build_facs(tables_blob, tables->linker);
 
     /* DSDT is pointed to by FADT */
     dsdt = tables_blob->len;
-    build_dsdt(tables_blob, tables->linker, &cpu, &pm, &misc, &pci,
-               guest_info);
+    build_dsdt(tables_blob, tables->linker, &cpu, &pm, &misc, &pci);
 
     /* Count the size of the DSDT and SSDT, we will need it for legacy
      * sizing of ACPI tables.
@@ -2638,7 +2643,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
     aml_len += tables_blob->len - fadt;
 
     acpi_add_table(table_offsets, tables_blob);
-    build_madt(tables_blob, tables->linker, &cpu, guest_info);
+    build_madt(tables_blob, tables->linker, &cpu);
 
     if (misc.has_hpet) {
         acpi_add_table(table_offsets, tables_blob);
@@ -2655,7 +2660,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
     }
     if (guest_info->numa_nodes) {
         acpi_add_table(table_offsets, tables_blob);
-        build_srat(tables_blob, tables->linker, guest_info);
+        build_srat(tables_blob, tables->linker);
     }
     if (acpi_get_mcfg(&mcfg)) {
         acpi_add_table(table_offsets, tables_blob);
@@ -2759,7 +2764,7 @@ static void acpi_build_update(void *build_opaque)
 
     acpi_build_tables_init(&tables);
 
-    acpi_build(build_state->guest_info, &tables);
+    acpi_build(&tables);
 
     acpi_ram_update(build_state->table_mr, tables.table_data);
 
@@ -2797,8 +2802,10 @@ static const VMStateDescription vmstate_acpi_build = {
     },
 };
 
-void acpi_setup(PcGuestInfo *guest_info)
+void acpi_setup(void)
 {
+    PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
+    PcGuestInfo *guest_info = &pcms->acpi_guest_info;
     AcpiBuildTables tables;
     AcpiBuildState *build_state;
 
@@ -2824,7 +2831,7 @@ void acpi_setup(PcGuestInfo *guest_info)
     acpi_set_pci_info();
 
     acpi_build_tables_init(&tables);
-    acpi_build(build_state->guest_info, &tables);
+    acpi_build(&tables);
 
     /* Now expose it all to Guest */
     build_state->table_mr = acpi_add_rom_blob(build_state, tables.table_data,
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 31/49] acpi: Don't save PcGuestInfo on AcpiBuildState
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (29 preceding siblings ...)
  2016-02-04 21:52 ` [Qemu-devel] [PULL 30/49] acpi: Remove guest_info parameters from functions Michael S. Tsirkin
@ 2016-02-04 21:53 ` Michael S. Tsirkin
  2016-02-04 21:53 ` [Qemu-devel] [PULL 32/49] pc: Remove compat fields from PcGuestInfo Michael S. Tsirkin
                   ` (18 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Eduardo Habkost, Igor Mammedov, Marcel Apfelbaum,
	Paolo Bonzini, Richard Henderson

From: Eduardo Habkost <ehabkost@redhat.com>

We don't need to save the pointer on AcpiBuildState, as it is not
used anymore.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/i386/acpi-build.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index e41a2ae..45c07ca 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2545,7 +2545,6 @@ struct AcpiBuildState {
     MemoryRegion *table_mr;
     /* Is table patched? */
     uint8_t patched;
-    PcGuestInfo *guest_info;
     void *rsdp;
     MemoryRegion *rsdp_mr;
     MemoryRegion *linker_mr;
@@ -2826,8 +2825,6 @@ void acpi_setup(void)
 
     build_state = g_malloc0(sizeof *build_state);
 
-    build_state->guest_info = guest_info;
-
     acpi_set_pci_info();
 
     acpi_build_tables_init(&tables);
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 32/49] pc: Remove compat fields from PcGuestInfo
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (30 preceding siblings ...)
  2016-02-04 21:53 ` [Qemu-devel] [PULL 31/49] acpi: Don't save PcGuestInfo on AcpiBuildState Michael S. Tsirkin
@ 2016-02-04 21:53 ` Michael S. Tsirkin
  2016-02-04 21:53 ` [Qemu-devel] [PULL 33/49] pc: Remove RAM size " Michael S. Tsirkin
                   ` (17 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Eduardo Habkost, Igor Mammedov, Marcel Apfelbaum,
	Paolo Bonzini, Richard Henderson

From: Eduardo Habkost <ehabkost@redhat.com>

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 <ehabkost@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/i386/acpi-build.h |  2 +-
 include/hw/i386/pc.h |  4 ----
 hw/i386/acpi-build.c | 10 ++++++----
 hw/i386/pc.c         |  8 ++++----
 hw/i386/pc_piix.c    |  5 -----
 hw/i386/pc_q35.c     |  8 --------
 6 files changed, 11 insertions(+), 26 deletions(-)

diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h
index e57b1aa..148c0f9 100644
--- a/hw/i386/acpi-build.h
+++ b/hw/i386/acpi-build.h
@@ -4,6 +4,6 @@
 
 #include "qemu/typedefs.h"
 
-void acpi_setup(PcGuestInfo *);
+void acpi_setup(void);
 
 #endif
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;
 };
 
 /**
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 45c07ca..7f574f2 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2593,6 +2593,7 @@ static
 void acpi_build(AcpiBuildTables *tables)
 {
     PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
+    PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
     PcGuestInfo *guest_info = &pcms->acpi_guest_info;
     GArray *table_offsets;
     unsigned facs, dsdt, rsdt, fadt;
@@ -2706,12 +2707,12 @@ void acpi_build(AcpiBuildTables *tables)
      *
      * All this is for PIIX4, since QEMU 2.0 didn't support Q35 migration.
      */
-    if (guest_info->legacy_acpi_table_size) {
+    if (pcmc->legacy_acpi_table_size) {
         /* Subtracting aml_len gives the size of fixed tables.  Then add the
          * size of the PIIX4 DSDT/SSDT in QEMU 2.0.
          */
         int legacy_aml_len =
-            guest_info->legacy_acpi_table_size +
+            pcmc->legacy_acpi_table_size +
             ACPI_BUILD_LEGACY_CPU_AML_SIZE * max_cpus;
         int legacy_table_size =
             ROUND_UP(tables_blob->len - aml_len + legacy_aml_len,
@@ -2804,6 +2805,7 @@ static const VMStateDescription vmstate_acpi_build = {
 void acpi_setup(void)
 {
     PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
+    PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
     PcGuestInfo *guest_info = &pcms->acpi_guest_info;
     AcpiBuildTables tables;
     AcpiBuildState *build_state;
@@ -2813,7 +2815,7 @@ void acpi_setup(void)
         return;
     }
 
-    if (!guest_info->has_acpi_build) {
+    if (!pcmc->has_acpi_build) {
         ACPI_BUILD_DPRINTF("ACPI build disabled. Bailing out.\n");
         return;
     }
@@ -2842,7 +2844,7 @@ void acpi_setup(void)
     fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE,
                     tables.tcpalog->data, acpi_data_len(tables.tcpalog));
 
-    if (!guest_info->rsdp_in_ram) {
+    if (!pcmc->rsdp_in_ram) {
         /*
          * Keep for compatibility with old machine types.
          * Though RSDP is small, its contents isn't immutable, so
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 9745dca..3c59500 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1180,7 +1180,7 @@ void pc_machine_done(Notifier *notifier, void *data)
         }
     }
 
-    acpi_setup(&pcms->acpi_guest_info);
+    acpi_setup();
 }
 
 PcGuestInfo *pc_guest_info_init(PCMachineState *pcms)
@@ -1316,7 +1316,7 @@ void pc_memory_init(PCMachineState *pcms,
         e820_add_entry(0x100000000ULL, pcms->above_4g_mem_size, E820_RAM);
     }
 
-    if (!guest_info->has_reserved_memory &&
+    if (!pcmc->has_reserved_memory &&
         (machine->ram_slots ||
          (machine->maxram_size > machine->ram_size))) {
         MachineClass *mc = MACHINE_GET_CLASS(machine);
@@ -1327,7 +1327,7 @@ void pc_memory_init(PCMachineState *pcms,
     }
 
     /* initialize hotplug memory address space */
-    if (guest_info->has_reserved_memory &&
+    if (pcmc->has_reserved_memory &&
         (machine->ram_size < machine->maxram_size)) {
         ram_addr_t hotplug_mem_size =
             machine->maxram_size - machine->ram_size;
@@ -1382,7 +1382,7 @@ void pc_memory_init(PCMachineState *pcms,
 
     rom_set_fw(fw_cfg);
 
-    if (guest_info->has_reserved_memory && pcms->hotplug_memory.base) {
+    if (pcmc->has_reserved_memory && pcms->hotplug_memory.base) {
         uint64_t *val = g_malloc(sizeof(*val));
         PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
         uint64_t res_mem_end = pcms->hotplug_memory.base;
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 4262c32..584441a 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -143,12 +143,7 @@ static void pc_init1(MachineState *machine,
 
     guest_info = pc_guest_info_init(pcms);
 
-    guest_info->has_acpi_build = pcmc->has_acpi_build;
-    guest_info->legacy_acpi_table_size = pcmc->legacy_acpi_table_size;
-
     guest_info->isapc_ram_fw = !pcmc->pci_enabled;
-    guest_info->has_reserved_memory = pcmc->has_reserved_memory;
-    guest_info->rsdp_in_ram = pcmc->rsdp_in_ram;
 
     if (pcmc->smbios_defaults) {
         MachineClass *mc = MACHINE_GET_CLASS(machine);
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 0c156e2..45e05f4 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -136,14 +136,6 @@ static void pc_q35_init(MachineState *machine)
 
     guest_info = pc_guest_info_init(pcms);
     guest_info->isapc_ram_fw = false;
-    guest_info->has_acpi_build = pcmc->has_acpi_build;
-    guest_info->has_reserved_memory = pcmc->has_reserved_memory;
-    guest_info->rsdp_in_ram = pcmc->rsdp_in_ram;
-
-    /* Migration was not supported in 2.0 for Q35, so do not bother
-     * with this hack (see hw/i386/acpi-build.c).
-     */
-    guest_info->legacy_acpi_table_size = 0;
 
     if (pcmc->smbios_defaults) {
         /* These values are guest ABI, do not change */
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 33/49] pc: Remove RAM size fields from PcGuestInfo
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (31 preceding siblings ...)
  2016-02-04 21:53 ` [Qemu-devel] [PULL 32/49] pc: Remove compat fields from PcGuestInfo Michael S. Tsirkin
@ 2016-02-04 21:53 ` Michael S. Tsirkin
  2016-02-04 21:53 ` [Qemu-devel] [PULL 34/49] pc: Remove PcGuestInfo.isapc_ram_fw field Michael S. Tsirkin
                   ` (16 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Eduardo Habkost, Igor Mammedov, Marcel Apfelbaum,
	Paolo Bonzini, Richard Henderson

From: Eduardo Habkost <ehabkost@redhat.com>

The ACPI code can use the PCMachineState fields directly.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
---
 include/hw/i386/pc.h |  1 -
 hw/i386/acpi-build.c | 10 +++++-----
 hw/i386/pc.c         |  2 --
 3 files changed, 5 insertions(+), 8 deletions(-)

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;
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 7f574f2..dac7137 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2421,17 +2421,17 @@ build_srat(GArray *table_data, GArray *linker)
         next_base = mem_base + mem_len;
 
         /* Cut out the ACPI_PCI hole */
-        if (mem_base <= guest_info->ram_size_below_4g &&
-            next_base > guest_info->ram_size_below_4g) {
-            mem_len -= next_base - guest_info->ram_size_below_4g;
+        if (mem_base <= pcms->below_4g_mem_size &&
+            next_base > pcms->below_4g_mem_size) {
+            mem_len -= next_base - pcms->below_4g_mem_size;
             if (mem_len > 0) {
                 numamem = acpi_data_push(table_data, sizeof *numamem);
                 acpi_build_srat_memory(numamem, mem_base, mem_len, i - 1,
                                        MEM_AFFINITY_ENABLED);
             }
             mem_base = 1ULL << 32;
-            mem_len = next_base - guest_info->ram_size_below_4g;
-            next_base += (1ULL << 32) - guest_info->ram_size_below_4g;
+            mem_len = next_base - pcms->below_4g_mem_size;
+            next_base += (1ULL << 32) - pcms->below_4g_mem_size;
         }
         numamem = acpi_data_push(table_data, sizeof *numamem);
         acpi_build_srat_memory(numamem, mem_base, mem_len, i - 1,
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 3c59500..f3fd0ed 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1188,8 +1188,6 @@ PcGuestInfo *pc_guest_info_init(PCMachineState *pcms)
     PcGuestInfo *guest_info = &pcms->acpi_guest_info;
     int i, j;
 
-    guest_info->ram_size_below_4g = pcms->below_4g_mem_size;
-    guest_info->ram_size = pcms->below_4g_mem_size + pcms->above_4g_mem_size;
     guest_info->apic_id_limit = pc_apic_id_limit(max_cpus);
     guest_info->apic_xrupt_override = kvm_allows_irq0_override();
     guest_info->numa_nodes = nb_numa_nodes;
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 34/49] pc: Remove PcGuestInfo.isapc_ram_fw field
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (32 preceding siblings ...)
  2016-02-04 21:53 ` [Qemu-devel] [PULL 33/49] pc: Remove RAM size " Michael S. Tsirkin
@ 2016-02-04 21:53 ` Michael S. Tsirkin
  2016-02-04 21:53 ` [Qemu-devel] [PULL 35/49] pc: Move PcGuestInfo.fw_cfg to PCMachineState Michael S. Tsirkin
                   ` (15 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marcel Apfelbaum, Peter Maydell, Richard Henderson,
	Eduardo Habkost, Paolo Bonzini

From: Eduardo Habkost <ehabkost@redhat.com>

The code can use the PCMachineClass.pci_enabled field directly.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
---
 include/hw/i386/pc.h | 1 -
 hw/i386/pc.c         | 2 +-
 hw/i386/pc_piix.c    | 5 +----
 hw/i386/pc_q35.c     | 4 +---
 4 files changed, 3 insertions(+), 9 deletions(-)

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;
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index f3fd0ed..dc0ade4 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1365,7 +1365,7 @@ void pc_memory_init(PCMachineState *pcms,
     }
 
     /* Initialize PC system firmware */
-    pc_system_firmware_init(rom_memory, guest_info->isapc_ram_fw);
+    pc_system_firmware_init(rom_memory, !pcmc->pci_enabled);
 
     option_rom_mr = g_malloc(sizeof(*option_rom_mr));
     memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE,
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 584441a..6f8c2cd 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -85,7 +85,6 @@ static void pc_init1(MachineState *machine,
     MemoryRegion *ram_memory;
     MemoryRegion *pci_memory;
     MemoryRegion *rom_memory;
-    PcGuestInfo *guest_info;
     ram_addr_t lowmem;
 
     /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory).
@@ -141,9 +140,7 @@ static void pc_init1(MachineState *machine,
         rom_memory = system_memory;
     }
 
-    guest_info = pc_guest_info_init(pcms);
-
-    guest_info->isapc_ram_fw = !pcmc->pci_enabled;
+    pc_guest_info_init(pcms);
 
     if (pcmc->smbios_defaults) {
         MachineClass *mc = MACHINE_GET_CLASS(machine);
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 45e05f4..208a224 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -71,7 +71,6 @@ static void pc_q35_init(MachineState *machine)
     int i;
     ICH9LPCState *ich9_lpc;
     PCIDevice *ahci;
-    PcGuestInfo *guest_info;
     ram_addr_t lowmem;
     DriveInfo *hd[MAX_SATA_PORTS];
     MachineClass *mc = MACHINE_GET_CLASS(machine);
@@ -134,8 +133,7 @@ static void pc_q35_init(MachineState *machine)
         rom_memory = get_system_memory();
     }
 
-    guest_info = pc_guest_info_init(pcms);
-    guest_info->isapc_ram_fw = false;
+    pc_guest_info_init(pcms);
 
     if (pcmc->smbios_defaults) {
         /* These values are guest ABI, do not change */
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 35/49] pc: Move PcGuestInfo.fw_cfg to PCMachineState
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (33 preceding siblings ...)
  2016-02-04 21:53 ` [Qemu-devel] [PULL 34/49] pc: Remove PcGuestInfo.isapc_ram_fw field Michael S. Tsirkin
@ 2016-02-04 21:53 ` Michael S. Tsirkin
  2016-02-04 21:53 ` [Qemu-devel] [PULL 36/49] pc: Move APIC and NUMA data from PcGuestInfo " Michael S. Tsirkin
                   ` (14 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Eduardo Habkost, Igor Mammedov, Marcel Apfelbaum,
	Paolo Bonzini, Richard Henderson

From: Eduardo Habkost <ehabkost@redhat.com>

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
---
 include/hw/i386/pc.h |  2 +-
 hw/i386/acpi-build.c |  7 +++----
 hw/i386/pc.c         | 10 ++++------
 3 files changed, 8 insertions(+), 11 deletions(-)

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;
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index dac7137..86baf63 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2806,11 +2806,10 @@ void acpi_setup(void)
 {
     PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
     PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
-    PcGuestInfo *guest_info = &pcms->acpi_guest_info;
     AcpiBuildTables tables;
     AcpiBuildState *build_state;
 
-    if (!guest_info->fw_cfg) {
+    if (!pcms->fw_cfg) {
         ACPI_BUILD_DPRINTF("No fw cfg. Bailing out.\n");
         return;
     }
@@ -2841,7 +2840,7 @@ void acpi_setup(void)
     build_state->linker_mr =
         acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0);
 
-    fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE,
+    fw_cfg_add_file(pcms->fw_cfg, ACPI_BUILD_TPMLOG_FILE,
                     tables.tcpalog->data, acpi_data_len(tables.tcpalog));
 
     if (!pcmc->rsdp_in_ram) {
@@ -2853,7 +2852,7 @@ void acpi_setup(void)
         uint32_t rsdp_size = acpi_data_len(tables.rsdp);
 
         build_state->rsdp = g_memdup(tables.rsdp->data, rsdp_size);
-        fw_cfg_add_file_callback(guest_info->fw_cfg, ACPI_BUILD_RSDP_FILE,
+        fw_cfg_add_file_callback(pcms->fw_cfg, ACPI_BUILD_RSDP_FILE,
                                  acpi_build_update, build_state,
                                  build_state->rsdp, rsdp_size);
         build_state->rsdp_mr = NULL;
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index dc0ade4..a47784a 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1172,10 +1172,10 @@ void pc_machine_done(Notifier *notifier, void *data)
                 extra_hosts++;
             }
         }
-        if (extra_hosts && pcms->acpi_guest_info.fw_cfg) {
+        if (extra_hosts && pcms->fw_cfg) {
             uint64_t *val = g_malloc(sizeof(*val));
             *val = cpu_to_le64(extra_hosts);
-            fw_cfg_add_file(pcms->acpi_guest_info.fw_cfg,
+            fw_cfg_add_file(pcms->fw_cfg,
                     "etc/extra-pci-roots", val, sizeof(*val));
         }
     }
@@ -1257,7 +1257,6 @@ void xen_load_linux(PCMachineState *pcms)
 {
     int i;
     FWCfgState *fw_cfg;
-    PcGuestInfo *guest_info = &pcms->acpi_guest_info;
 
     assert(MACHINE(pcms)->kernel_filename != NULL);
 
@@ -1270,7 +1269,7 @@ void xen_load_linux(PCMachineState *pcms)
                !strcmp(option_rom[i].name, "multiboot.bin"));
         rom_add_option(option_rom[i].name, option_rom[i].bootindex);
     }
-    guest_info->fw_cfg = fw_cfg;
+    pcms->fw_cfg = fw_cfg;
 }
 
 void pc_memory_init(PCMachineState *pcms,
@@ -1278,7 +1277,6 @@ void pc_memory_init(PCMachineState *pcms,
                     MemoryRegion *rom_memory,
                     MemoryRegion **ram_memory)
 {
-    PcGuestInfo *guest_info = &pcms->acpi_guest_info;
     int linux_boot, i;
     MemoryRegion *ram, *option_rom_mr;
     MemoryRegion *ram_below_4g, *ram_above_4g;
@@ -1399,7 +1397,7 @@ void pc_memory_init(PCMachineState *pcms,
     for (i = 0; i < nb_option_roms; i++) {
         rom_add_option(option_rom[i].name, option_rom[i].bootindex);
     }
-    guest_info->fw_cfg = fw_cfg;
+    pcms->fw_cfg = fw_cfg;
 }
 
 qemu_irq pc_allocate_cpu_irq(void)
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 36/49] pc: Move APIC and NUMA data from PcGuestInfo to PCMachineState
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (34 preceding siblings ...)
  2016-02-04 21:53 ` [Qemu-devel] [PULL 35/49] pc: Move PcGuestInfo.fw_cfg to PCMachineState Michael S. Tsirkin
@ 2016-02-04 21:53 ` Michael S. Tsirkin
  2016-02-04 21:53 ` [Qemu-devel] [PULL 37/49] pc: Eliminate PcGuestInfo struct Michael S. Tsirkin
                   ` (13 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Eduardo Habkost, Igor Mammedov, Marcel Apfelbaum,
	Paolo Bonzini, Richard Henderson

From: Eduardo Habkost <ehabkost@redhat.com>

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
---
 include/hw/i386/pc.h | 14 +++++++++-----
 hw/i386/acpi-build.c | 22 +++++++++-------------
 hw/i386/pc.c         | 20 ++++++++++----------
 3 files changed, 28 insertions(+), 28 deletions(-)

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"
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 86baf63..35582a7 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -364,7 +364,6 @@ static void
 build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu)
 {
     PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
-    PcGuestInfo *guest_info = &pcms->acpi_guest_info;
     int madt_start = table_data->len;
 
     AcpiMultipleApicTable *madt;
@@ -377,7 +376,7 @@ build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu)
     madt->local_apic_address = cpu_to_le32(APIC_DEFAULT_ADDRESS);
     madt->flags = cpu_to_le32(1);
 
-    for (i = 0; i < guest_info->apic_id_limit; i++) {
+    for (i = 0; i < pcms->apic_id_limit; i++) {
         AcpiMadtProcessorApic *apic = acpi_data_push(table_data, sizeof *apic);
         apic->type = ACPI_APIC_PROCESSOR;
         apic->length = sizeof(*apic);
@@ -397,7 +396,7 @@ build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu)
     io_apic->address = cpu_to_le32(IO_APIC_DEFAULT_ADDRESS);
     io_apic->interrupt = cpu_to_le32(0);
 
-    if (guest_info->apic_xrupt_override) {
+    if (pcms->apic_xrupt_override) {
         intsrcovr = acpi_data_push(table_data, sizeof *intsrcovr);
         intsrcovr->type   = ACPI_APIC_XRUPT_OVERRIDE;
         intsrcovr->length = sizeof(*intsrcovr);
@@ -1946,7 +1945,6 @@ build_dsdt(GArray *table_data, GArray *linker,
     GPtrArray *io_ranges = g_ptr_array_new_with_free_func(crs_range_free);
     MachineState *machine = MACHINE(qdev_get_machine());
     PCMachineState *pcms = PC_MACHINE(machine);
-    PcGuestInfo *guest_info = &pcms->acpi_guest_info;
     uint32_t nr_mem = machine->ram_slots;
     int root_bus_limit = 0xFF;
     PCIBus *bus = NULL;
@@ -2247,7 +2245,7 @@ build_dsdt(GArray *table_data, GArray *linker,
 
     sb_scope = aml_scope("\\_SB");
     {
-        build_processor_devices(sb_scope, guest_info->apic_id_limit, cpu, pm);
+        build_processor_devices(sb_scope, pcms->apic_id_limit, cpu, pm);
 
         build_memory_devices(sb_scope, nr_mem, pm->mem_hp_io_base,
                              pm->mem_hp_io_len);
@@ -2379,7 +2377,6 @@ build_srat(GArray *table_data, GArray *linker)
     int srat_start, numa_start, slots;
     uint64_t mem_len, mem_base, next_base;
     PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
-    PcGuestInfo *guest_info = &pcms->acpi_guest_info;
     ram_addr_t hotplugabble_address_space_size =
         object_property_get_int(OBJECT(pcms), PC_MACHINE_MEMHP_REGION_SIZE,
                                 NULL);
@@ -2390,12 +2387,12 @@ build_srat(GArray *table_data, GArray *linker)
     srat->reserved1 = cpu_to_le32(1);
     core = (void *)(srat + 1);
 
-    for (i = 0; i < guest_info->apic_id_limit; ++i) {
+    for (i = 0; i < pcms->apic_id_limit; ++i) {
         core = acpi_data_push(table_data, sizeof *core);
         core->type = ACPI_SRAT_PROCESSOR;
         core->length = sizeof(*core);
         core->local_apic_id = i;
-        curnode = guest_info->node_cpu[i];
+        curnode = pcms->node_cpu[i];
         core->proximity_lo = curnode;
         memset(core->proximity_hi, 0, 3);
         core->local_sapic_eid = 0;
@@ -2412,9 +2409,9 @@ build_srat(GArray *table_data, GArray *linker)
     numamem = acpi_data_push(table_data, sizeof *numamem);
     acpi_build_srat_memory(numamem, 0, 640*1024, 0, MEM_AFFINITY_ENABLED);
     next_base = 1024 * 1024;
-    for (i = 1; i < guest_info->numa_nodes + 1; ++i) {
+    for (i = 1; i < pcms->numa_nodes + 1; ++i) {
         mem_base = next_base;
-        mem_len = guest_info->node_mem[i - 1];
+        mem_len = pcms->node_mem[i - 1];
         if (i == 1) {
             mem_len -= 1024 * 1024;
         }
@@ -2438,7 +2435,7 @@ build_srat(GArray *table_data, GArray *linker)
                                MEM_AFFINITY_ENABLED);
     }
     slots = (table_data->len - numa_start) / sizeof *numamem;
-    for (; slots < guest_info->numa_nodes + 2; slots++) {
+    for (; slots < pcms->numa_nodes + 2; slots++) {
         numamem = acpi_data_push(table_data, sizeof *numamem);
         acpi_build_srat_memory(numamem, 0, 0, 0, MEM_AFFINITY_NOFLAGS);
     }
@@ -2594,7 +2591,6 @@ void acpi_build(AcpiBuildTables *tables)
 {
     PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
     PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
-    PcGuestInfo *guest_info = &pcms->acpi_guest_info;
     GArray *table_offsets;
     unsigned facs, dsdt, rsdt, fadt;
     AcpiCpuInfo cpu;
@@ -2658,7 +2654,7 @@ void acpi_build(AcpiBuildTables *tables)
             build_tpm2(tables_blob, tables->linker);
         }
     }
-    if (guest_info->numa_nodes) {
+    if (pcms->numa_nodes) {
         acpi_add_table(table_offsets, tables_blob);
         build_srat(tables_blob, tables->linker);
     }
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index a47784a..66f7bb9 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1188,24 +1188,24 @@ PcGuestInfo *pc_guest_info_init(PCMachineState *pcms)
     PcGuestInfo *guest_info = &pcms->acpi_guest_info;
     int i, j;
 
-    guest_info->apic_id_limit = pc_apic_id_limit(max_cpus);
-    guest_info->apic_xrupt_override = kvm_allows_irq0_override();
-    guest_info->numa_nodes = nb_numa_nodes;
-    guest_info->node_mem = g_malloc0(guest_info->numa_nodes *
-                                    sizeof *guest_info->node_mem);
+    pcms->apic_id_limit = pc_apic_id_limit(max_cpus);
+    pcms->apic_xrupt_override = kvm_allows_irq0_override();
+    pcms->numa_nodes = nb_numa_nodes;
+    pcms->node_mem = g_malloc0(pcms->numa_nodes *
+                                    sizeof *pcms->node_mem);
     for (i = 0; i < nb_numa_nodes; i++) {
-        guest_info->node_mem[i] = numa_info[i].node_mem;
+        pcms->node_mem[i] = numa_info[i].node_mem;
     }
 
-    guest_info->node_cpu = g_malloc0(guest_info->apic_id_limit *
-                                     sizeof *guest_info->node_cpu);
+    pcms->node_cpu = g_malloc0(pcms->apic_id_limit *
+                                     sizeof *pcms->node_cpu);
 
     for (i = 0; i < max_cpus; i++) {
         unsigned int apic_id = x86_cpu_apic_id_from_index(i);
-        assert(apic_id < guest_info->apic_id_limit);
+        assert(apic_id < pcms->apic_id_limit);
         for (j = 0; j < nb_numa_nodes; j++) {
             if (test_bit(i, numa_info[j].node_cpu)) {
-                guest_info->node_cpu[apic_id] = j;
+                pcms->node_cpu[apic_id] = j;
                 break;
             }
         }
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 37/49] pc: Eliminate PcGuestInfo struct
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (35 preceding siblings ...)
  2016-02-04 21:53 ` [Qemu-devel] [PULL 36/49] pc: Move APIC and NUMA data from PcGuestInfo " Michael S. Tsirkin
@ 2016-02-04 21:53 ` Michael S. Tsirkin
  2016-02-04 21:53 ` [Qemu-devel] [PULL 38/49] acpi: take oem_id in build_header(), optionally Michael S. Tsirkin
                   ` (12 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Richard Henderson, Eduardo Habkost, Paolo Bonzini

From: Eduardo Habkost <ehabkost@redhat.com>

The struct is not used for anything, now.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 include/hw/i386/pc.h | 7 +------
 hw/i386/pc.c         | 4 +---
 2 files changed, 2 insertions(+), 9 deletions(-)

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"
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 66f7bb9..ce185bb 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1183,9 +1183,8 @@ void pc_machine_done(Notifier *notifier, void *data)
     acpi_setup();
 }
 
-PcGuestInfo *pc_guest_info_init(PCMachineState *pcms)
+void pc_guest_info_init(PCMachineState *pcms)
 {
-    PcGuestInfo *guest_info = &pcms->acpi_guest_info;
     int i, j;
 
     pcms->apic_id_limit = pc_apic_id_limit(max_cpus);
@@ -1213,7 +1212,6 @@ PcGuestInfo *pc_guest_info_init(PCMachineState *pcms)
 
     pcms->machine_done.notify = pc_machine_done;
     qemu_add_machine_init_done_notifier(&pcms->machine_done);
-    return guest_info;
 }
 
 /* setup pci memory address space mapping into system address space */
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 38/49] acpi: take oem_id in build_header(), optionally
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (36 preceding siblings ...)
  2016-02-04 21:53 ` [Qemu-devel] [PULL 37/49] pc: Eliminate PcGuestInfo struct Michael S. Tsirkin
@ 2016-02-04 21:53 ` Michael S. Tsirkin
  2016-02-04 22:25   ` Laszlo Ersek
  2016-02-04 21:53 ` [Qemu-devel] [PULL 39/49] acpi: expose oem_id and oem_table_id in build_rsdt() Michael S. Tsirkin
                   ` (11 subsequent siblings)
  49 siblings, 1 reply; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Xiao Guangrong, Eduardo Habkost, Aleksei Kovura,
	Steven Newbury, Michael Tokarev, Richard W . M . Jones,
	Paolo Bonzini, Shannon Zhao, qemu-arm, Shannon Zhao,
	Igor Mammedov, Laszlo Ersek, Richard Henderson

From: Laszlo Ersek <lersek@redhat.com>

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" <mst@redhat.com> (supporter:ACPI/SMBIOS)
Cc: Igor Mammedov <imammedo@redhat.com> (supporter:ACPI/SMBIOS)
Cc: Xiao Guangrong <guangrong.xiao@linux.intel.com> (maintainer:NVDIMM)
Cc: Shannon Zhao <zhaoshenglong@huawei.com> (maintainer:ARM ACPI Subsystem)
Cc: Paolo Bonzini <pbonzini@redhat.com> (maintainer:X86)
Cc: Richard W.M. Jones <rjones@redhat.com>
Cc: Aleksei Kovura <alex3kov@zoho.com>
Cc: Michael Tokarev <mjt@tls.msk.ru>
Cc: Steven Newbury <steve@snewbury.org.uk>
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1248758
LP: https://bugs.launchpad.net/qemu/+bug/1533848
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Shannon Zhao <shannon.zhao@linaro.org>
---
 include/hw/acpi/aml-build.h |  2 +-
 hw/acpi/aml-build.c         | 11 ++++++++---
 hw/acpi/nvdimm.c            |  4 ++--
 hw/arm/virt-acpi-build.c    | 12 ++++++------
 hw/i386/acpi-build.c        | 18 +++++++++---------
 5 files changed, 26 insertions(+), 21 deletions(-)

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);
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 21d2ea0..e4b6c0c 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1426,12 +1426,17 @@ Aml *aml_alias(const char *source_object, const char *alias_object)
 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)
 {
     memcpy(&h->signature, sig, 4);
     h->length = cpu_to_le32(len);
     h->revision = rev;
-    memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
+
+    if (oem_id) {
+        strncpy((char *)h->oem_id, oem_id, sizeof h->oem_id);
+    } else {
+        memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
+    }
 
     if (oem_table_id) {
         strncpy((char *)h->oem_table_id, oem_table_id, sizeof(h->oem_table_id));
@@ -1506,5 +1511,5 @@ build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
                                        sizeof(uint32_t));
     }
     build_header(linker, table_data,
-                 (void *)rsdt, "RSDT", rsdt_len, 1, NULL);
+                 (void *)rsdt, "RSDT", rsdt_len, 1, NULL, NULL);
 }
diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
index 7ee7e16..49ee68e 100644
--- a/hw/acpi/nvdimm.c
+++ b/hw/acpi/nvdimm.c
@@ -366,7 +366,7 @@ static void nvdimm_build_nfit(GSList *device_list, GArray *table_offsets,
 
     build_header(linker, table_data,
                  (void *)(table_data->data + header), "NFIT",
-                 sizeof(NvdimmNfitHeader) + structures->len, 1, NULL);
+                 sizeof(NvdimmNfitHeader) + structures->len, 1, NULL, NULL);
     g_array_free(structures, true);
 }
 
@@ -471,7 +471,7 @@ static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets,
     g_array_append_vals(table_data, ssdt->buf->data, ssdt->buf->len);
     build_header(linker, table_data,
         (void *)(table_data->data + table_data->len - ssdt->buf->len),
-        "SSDT", ssdt->buf->len, 1, "NVDIMM");
+        "SSDT", ssdt->buf->len, 1, NULL, "NVDIMM");
     free_aml_allocator();
 }
 
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 87fbe7c..8017b12 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -408,7 +408,7 @@ build_spcr(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
     spcr->pci_vendor_id = 0xffff;  /* PCI Vendor ID: not a PCI device */
 
     build_header(linker, table_data, (void *)spcr, "SPCR", sizeof(*spcr), 2,
-                 NULL);
+                 NULL, NULL);
 }
 
 static void
@@ -427,7 +427,7 @@ build_mcfg(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
     mcfg->allocation[0].end_bus_number = (memmap[VIRT_PCIE_ECAM].size
                                           / PCIE_MMCFG_SIZE_MIN) - 1;
 
-    build_header(linker, table_data, (void *)mcfg, "MCFG", len, 1, NULL);
+    build_header(linker, table_data, (void *)mcfg, "MCFG", len, 1, NULL, NULL);
 }
 
 /* GTDT */
@@ -453,7 +453,7 @@ build_gtdt(GArray *table_data, GArray *linker)
 
     build_header(linker, table_data,
                  (void *)(table_data->data + gtdt_start), "GTDT",
-                 table_data->len - gtdt_start, 2, NULL);
+                 table_data->len - gtdt_start, 2, NULL, NULL);
 }
 
 /* MADT */
@@ -515,7 +515,7 @@ build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info,
 
     build_header(linker, table_data,
                  (void *)(table_data->data + madt_start), "APIC",
-                 table_data->len - madt_start, 3, NULL);
+                 table_data->len - madt_start, 3, NULL, NULL);
 }
 
 /* FADT */
@@ -540,7 +540,7 @@ build_fadt(GArray *table_data, GArray *linker, unsigned dsdt)
                                    sizeof fadt->dsdt);
 
     build_header(linker, table_data,
-                 (void *)fadt, "FACP", sizeof(*fadt), 5, NULL);
+                 (void *)fadt, "FACP", sizeof(*fadt), 5, NULL, NULL);
 }
 
 /* DSDT */
@@ -579,7 +579,7 @@ build_dsdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
     g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len);
     build_header(linker, table_data,
         (void *)(table_data->data + table_data->len - dsdt->buf->len),
-        "DSDT", dsdt->buf->len, 2, NULL);
+        "DSDT", dsdt->buf->len, 2, NULL, NULL);
     free_aml_allocator();
 }
 
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 35582a7..061a9cb 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -357,7 +357,7 @@ build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm,
     fadt_setup(fadt, pm);
 
     build_header(linker, table_data,
-                 (void *)fadt, "FACP", sizeof(*fadt), 1, NULL);
+                 (void *)fadt, "FACP", sizeof(*fadt), 1, NULL, NULL);
 }
 
 static void
@@ -427,7 +427,7 @@ build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu)
 
     build_header(linker, table_data,
                  (void *)(table_data->data + madt_start), "APIC",
-                 table_data->len - madt_start, 1, NULL);
+                 table_data->len - madt_start, 1, NULL, NULL);
 }
 
 /* Assign BSEL property to all buses.  In the future, this can be changed
@@ -2286,7 +2286,7 @@ build_dsdt(GArray *table_data, GArray *linker,
     g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len);
     build_header(linker, table_data,
         (void *)(table_data->data + table_data->len - dsdt->buf->len),
-        "DSDT", dsdt->buf->len, 1, NULL);
+        "DSDT", dsdt->buf->len, 1, NULL, NULL);
     free_aml_allocator();
 }
 
@@ -2302,7 +2302,7 @@ build_hpet(GArray *table_data, GArray *linker)
     hpet->timer_block_id = cpu_to_le32(0x8086a201);
     hpet->addr.address = cpu_to_le64(HPET_BASE);
     build_header(linker, table_data,
-                 (void *)hpet, "HPET", sizeof(*hpet), 1, NULL);
+                 (void *)hpet, "HPET", sizeof(*hpet), 1, NULL, NULL);
 }
 
 static void
@@ -2325,7 +2325,7 @@ build_tpm_tcpa(GArray *table_data, GArray *linker, GArray *tcpalog)
                                    sizeof(tcpa->log_area_start_address));
 
     build_header(linker, table_data,
-                 (void *)tcpa, "TCPA", sizeof(*tcpa), 2, NULL);
+                 (void *)tcpa, "TCPA", sizeof(*tcpa), 2, NULL, NULL);
 
     acpi_data_push(tcpalog, TPM_LOG_AREA_MINIMUM_SIZE);
 }
@@ -2342,7 +2342,7 @@ build_tpm2(GArray *table_data, GArray *linker)
     tpm2_ptr->start_method = cpu_to_le32(TPM2_START_METHOD_MMIO);
 
     build_header(linker, table_data,
-                 (void *)tpm2_ptr, "TPM2", sizeof(*tpm2_ptr), 4, NULL);
+                 (void *)tpm2_ptr, "TPM2", sizeof(*tpm2_ptr), 4, NULL, NULL);
 }
 
 typedef enum {
@@ -2456,7 +2456,7 @@ build_srat(GArray *table_data, GArray *linker)
     build_header(linker, table_data,
                  (void *)(table_data->data + srat_start),
                  "SRAT",
-                 table_data->len - srat_start, 1, NULL);
+                 table_data->len - srat_start, 1, NULL, NULL);
 }
 
 static void
@@ -2485,7 +2485,7 @@ build_mcfg_q35(GArray *table_data, GArray *linker, AcpiMcfgInfo *info)
     } else {
         sig = "MCFG";
     }
-    build_header(linker, table_data, (void *)mcfg, sig, len, 1, NULL);
+    build_header(linker, table_data, (void *)mcfg, sig, len, 1, NULL, NULL);
 }
 
 static void
@@ -2509,7 +2509,7 @@ build_dmar_q35(GArray *table_data, GArray *linker)
     drhd->address = cpu_to_le64(Q35_HOST_BRIDGE_IOMMU_ADDR);
 
     build_header(linker, table_data, (void *)(table_data->data + dmar_start),
-                 "DMAR", table_data->len - dmar_start, 1, NULL);
+                 "DMAR", table_data->len - dmar_start, 1, NULL, NULL);
 }
 
 static GArray *
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 39/49] acpi: expose oem_id and oem_table_id in build_rsdt()
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (37 preceding siblings ...)
  2016-02-04 21:53 ` [Qemu-devel] [PULL 38/49] acpi: take oem_id in build_header(), optionally Michael S. Tsirkin
@ 2016-02-04 21:53 ` Michael S. Tsirkin
  2016-02-04 21:53 ` [Qemu-devel] [PULL 40/49] acpi: add function to extract oem_id and oem_table_id from the user's SLIC Michael S. Tsirkin
                   ` (10 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Eduardo Habkost, Igor Mammedov, Steven Newbury,
	Michael Tokarev, Richard W . M . Jones, Aleksei Kovura, qemu-arm,
	Shannon Zhao, Shannon Zhao, Paolo Bonzini, Laszlo Ersek,
	Richard Henderson

From: Laszlo Ersek <lersek@redhat.com>

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" <mst@redhat.com> (supporter:ACPI/SMBIOS)
Cc: Igor Mammedov <imammedo@redhat.com> (supporter:ACPI/SMBIOS)
Cc: Shannon Zhao <zhaoshenglong@huawei.com> (maintainer:ARM ACPI Subsystem)
Cc: Paolo Bonzini <pbonzini@redhat.com> (maintainer:X86)
Cc: Richard W.M. Jones <rjones@redhat.com>
Cc: Aleksei Kovura <alex3kov@zoho.com>
Cc: Michael Tokarev <mjt@tls.msk.ru>
Cc: Steven Newbury <steve@snewbury.org.uk>
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1248758
LP: https://bugs.launchpad.net/qemu/+bug/1533848
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Shannon Zhao <shannon.zhao@linaro.org>
---
 include/hw/acpi/aml-build.h | 3 ++-
 hw/acpi/aml-build.c         | 5 +++--
 hw/arm/virt-acpi-build.c    | 2 +-
 hw/i386/acpi-build.c        | 2 +-
 4 files changed, 7 insertions(+), 5 deletions(-)

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
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index e4b6c0c..603068b 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1492,7 +1492,8 @@ void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
 
 /* Build rsdt table */
 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)
 {
     AcpiRsdtDescriptorRev1 *rsdt;
     size_t rsdt_len;
@@ -1511,5 +1512,5 @@ build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
                                        sizeof(uint32_t));
     }
     build_header(linker, table_data,
-                 (void *)rsdt, "RSDT", rsdt_len, 1, NULL, NULL);
+                 (void *)rsdt, "RSDT", rsdt_len, 1, oem_id, oem_table_id);
 }
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 8017b12..560764f 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -643,7 +643,7 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
 
     /* RSDT is pointed to by RSDP */
     rsdt = tables_blob->len;
-    build_rsdt(tables_blob, tables->linker, table_offsets);
+    build_rsdt(tables_blob, tables->linker, table_offsets, NULL, NULL);
 
     /* RSDP is in FSEG memory, so allocate it separately */
     build_rsdp(tables->rsdp, tables->linker, rsdt);
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 061a9cb..705d12f 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2681,7 +2681,7 @@ void acpi_build(AcpiBuildTables *tables)
 
     /* RSDT is pointed to by RSDP */
     rsdt = tables_blob->len;
-    build_rsdt(tables_blob, tables->linker, table_offsets);
+    build_rsdt(tables_blob, tables->linker, table_offsets, NULL, NULL);
 
     /* RSDP is in FSEG memory, so allocate it separately */
     build_rsdp(tables->rsdp, tables->linker, rsdt);
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 40/49] acpi: add function to extract oem_id and oem_table_id from the user's SLIC
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (38 preceding siblings ...)
  2016-02-04 21:53 ` [Qemu-devel] [PULL 39/49] acpi: expose oem_id and oem_table_id in build_rsdt() Michael S. Tsirkin
@ 2016-02-04 21:53 ` Michael S. Tsirkin
  2016-02-04 21:53 ` [Qemu-devel] [PULL 41/49] pc: set the OEM fields in the RSDT and the FADT from the SLIC Michael S. Tsirkin
                   ` (9 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aleksei Kovura, Eduardo Habkost, Peter Maydell, Steven Newbury,
	Michael Tokarev, Richard W . M . Jones, Igor Mammedov,
	Laszlo Ersek

From: Laszlo Ersek <lersek@redhat.com>

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" <mst@redhat.com> (supporter:ACPI/SMBIOS)
Cc: Igor Mammedov <imammedo@redhat.com> (supporter:ACPI/SMBIOS)
Cc: Richard W.M. Jones <rjones@redhat.com>
Cc: Aleksei Kovura <alex3kov@zoho.com>
Cc: Michael Tokarev <mjt@tls.msk.ru>
Cc: Steven Newbury <steve@snewbury.org.uk>
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1248758
LP: https://bugs.launchpad.net/qemu/+bug/1533848
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Steven Newbury <steve@snewbury.org.uk>
---
 include/hw/acpi/acpi.h |  7 +++++++
 hw/acpi/core.c         | 16 ++++++++++++++++
 2 files changed, 23 insertions(+)

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 */
diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index 397e6da..edf3f96 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -350,6 +350,22 @@ uint8_t *acpi_table_next(uint8_t *current)
     }
 }
 
+int acpi_get_slic_oem(AcpiSlicOem *oem)
+{
+    uint8_t *u;
+
+    for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
+        struct acpi_table_header *hdr = (void *)(u - sizeof(hdr->_length));
+
+        if (memcmp(hdr->sig, "SLIC", 4) == 0) {
+            oem->id = hdr->oem_id;
+            oem->table_id = hdr->oem_table_id;
+            return 0;
+        }
+    }
+    return -1;
+}
+
 static void acpi_notify_wakeup(Notifier *notifier, void *data)
 {
     ACPIREGS *ar = container_of(notifier, ACPIREGS, wakeup);
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 41/49] pc: set the OEM fields in the RSDT and the FADT from the SLIC
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (39 preceding siblings ...)
  2016-02-04 21:53 ` [Qemu-devel] [PULL 40/49] acpi: add function to extract oem_id and oem_table_id from the user's SLIC Michael S. Tsirkin
@ 2016-02-04 21:53 ` Michael S. Tsirkin
  2016-02-04 21:53 ` [Qemu-devel] [PULL 42/49] dimm: Correct type of MemoryHotplugState->base Michael S. Tsirkin
                   ` (8 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Eduardo Habkost, Aleksei Kovura, Steven Newbury,
	Michael Tokarev, Richard W . M . Jones, Igor Mammedov,
	Paolo Bonzini, Laszlo Ersek, Richard Henderson

From: Laszlo Ersek <lersek@redhat.com>

The Microsoft spec about the SLIC and MSDM ACPI tables at
<http://go.microsoft.com/fwlink/p/?LinkId=234834> requires the OEM ID and
OEM Table ID fields to be consistent between the SLIC and the RSDT/XSDT.
That further affects the FADT, because a similar match between the FADT
and the RSDT/XSDT is required by the ACPI spec in general.

This patch wires up the previous three patches.

Cc: "Michael S. Tsirkin" <mst@redhat.com> (supporter:ACPI/SMBIOS)
Cc: Igor Mammedov <imammedo@redhat.com> (supporter:ACPI/SMBIOS)
Cc: Paolo Bonzini <pbonzini@redhat.com> (maintainer:X86)
Cc: Richard W.M. Jones <rjones@redhat.com>
Cc: Aleksei Kovura <alex3kov@zoho.com>
Cc: Michael Tokarev <mjt@tls.msk.ru>
Cc: Steven Newbury <steve@snewbury.org.uk>
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1248758
LP: https://bugs.launchpad.net/qemu/+bug/1533848
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Steven Newbury <steve@snewbury.org.uk>
---
 hw/i386/acpi-build.c | 13 +++++++++----
 qemu-options.hx      |  4 ++++
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 705d12f..4554eb8 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -336,7 +336,8 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
 /* FADT */
 static void
 build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm,
-           unsigned facs, unsigned dsdt)
+           unsigned facs, unsigned dsdt,
+           const char *oem_id, const char *oem_table_id)
 {
     AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
 
@@ -357,7 +358,7 @@ build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm,
     fadt_setup(fadt, pm);
 
     build_header(linker, table_data,
-                 (void *)fadt, "FACP", sizeof(*fadt), 1, NULL, NULL);
+                 (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id);
 }
 
 static void
@@ -2601,11 +2602,13 @@ void acpi_build(AcpiBuildTables *tables)
     uint8_t *u;
     size_t aml_len = 0;
     GArray *tables_blob = tables->table_data;
+    AcpiSlicOem slic_oem = { .id = NULL, .table_id = NULL };
 
     acpi_get_cpu_info(&cpu);
     acpi_get_pm_info(&pm);
     acpi_get_misc_info(&misc);
     acpi_get_pci_info(&pci);
+    acpi_get_slic_oem(&slic_oem);
 
     table_offsets = g_array_new(false, true /* clear */,
                                         sizeof(uint32_t));
@@ -2635,7 +2638,8 @@ void acpi_build(AcpiBuildTables *tables)
     /* ACPI tables pointed to by RSDT */
     fadt = tables_blob->len;
     acpi_add_table(table_offsets, tables_blob);
-    build_fadt(tables_blob, tables->linker, &pm, facs, dsdt);
+    build_fadt(tables_blob, tables->linker, &pm, facs, dsdt,
+               slic_oem.id, slic_oem.table_id);
     aml_len += tables_blob->len - fadt;
 
     acpi_add_table(table_offsets, tables_blob);
@@ -2681,7 +2685,8 @@ void acpi_build(AcpiBuildTables *tables)
 
     /* RSDT is pointed to by RSDP */
     rsdt = tables_blob->len;
-    build_rsdt(tables_blob, tables->linker, table_offsets, NULL, NULL);
+    build_rsdt(tables_blob, tables->linker, table_offsets,
+               slic_oem.id, slic_oem.table_id);
 
     /* RSDP is in FSEG memory, so allocate it separately */
     build_rsdp(tables->rsdp, tables->linker, rsdt);
diff --git a/qemu-options.hx b/qemu-options.hx
index 733a194..2f0465e 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1472,6 +1472,10 @@ ACPI headers (possible overridden by other options).
 For data=, only data
 portion of the table is used, all header information is specified in the
 command line.
+If a SLIC table is supplied to QEMU, then the SLIC's oem_id and oem_table_id
+fields will override the same in the RSDT and the FADT (a.k.a. FACP), in order
+to ensure the field matches required by the Microsoft SLIC spec and the ACPI
+spec.
 ETEXI
 
 DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 42/49] dimm: Correct type of MemoryHotplugState->base
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (40 preceding siblings ...)
  2016-02-04 21:53 ` [Qemu-devel] [PULL 41/49] pc: set the OEM fields in the RSDT and the FADT from the SLIC Michael S. Tsirkin
@ 2016-02-04 21:53 ` Michael S. Tsirkin
  2016-02-04 21:53 ` [Qemu-devel] [PULL 43/49] intel_iommu: large page support Michael S. Tsirkin
                   ` (7 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Igor Mammedov, Bharata B Rao, Eduardo Habkost,
	David Gibson

From: David Gibson <david@gibson.dropbear.id.au>

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 <david@gibson.dropbear.id.au>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com>
---
 include/hw/mem/pc-dimm.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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;
 
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 43/49] intel_iommu: large page support
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (41 preceding siblings ...)
  2016-02-04 21:53 ` [Qemu-devel] [PULL 42/49] dimm: Correct type of MemoryHotplugState->base Michael S. Tsirkin
@ 2016-02-04 21:53 ` Michael S. Tsirkin
  2016-02-04 21:53 ` [Qemu-devel] [PULL 44/49] fix MSI injection on Xen Michael S. Tsirkin
                   ` (6 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Jason Wang, Richard Henderson, Eduardo Habkost,
	Paolo Bonzini

From: Jason Wang <jasowang@redhat.com>

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 <mst@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/i386/intel_iommu_internal.h |  6 ++--
 include/hw/i386/intel_iommu.h  |  1 +
 hw/i386/intel_iommu.c          | 76 ++++++++++++++++++++++++++++++------------
 3 files changed, 59 insertions(+), 24 deletions(-)

diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index ba288ab..e5f514c 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -113,6 +113,7 @@
 
 /* The shift of source_id in the key of IOTLB hash table */
 #define VTD_IOTLB_SID_SHIFT         36
+#define VTD_IOTLB_LVL_SHIFT         44
 #define VTD_IOTLB_MAX_SIZE          1024    /* Max size of the hash table */
 
 /* IOTLB_REG */
@@ -185,9 +186,10 @@
 #define VTD_CAP_ND                  (((VTD_DOMAIN_ID_SHIFT - 4) / 2) & 7ULL)
 #define VTD_MGAW                    39  /* Maximum Guest Address Width */
 #define VTD_CAP_MGAW                (((VTD_MGAW - 1) & 0x3fULL) << 16)
-#define VTD_MAMV                    9ULL
+#define VTD_MAMV                    18ULL
 #define VTD_CAP_MAMV                (VTD_MAMV << 48)
 #define VTD_CAP_PSI                 (1ULL << 39)
+#define VTD_CAP_SLLPS               ((1ULL << 34) | (1ULL << 35))
 
 /* Supported Adjusted Guest Address Widths */
 #define VTD_CAP_SAGAW_SHIFT         8
@@ -320,7 +322,7 @@ typedef struct VTDInvDesc VTDInvDesc;
 /* Information about page-selective IOTLB invalidate */
 struct VTDIOTLBPageInvInfo {
     uint16_t domain_id;
-    uint64_t gfn;
+    uint64_t addr;
     uint8_t mask;
 };
 typedef struct VTDIOTLBPageInvInfo VTDIOTLBPageInvInfo;
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;
 };
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index c25b1fd..347718f 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -153,14 +153,27 @@ static gboolean vtd_hash_remove_by_domain(gpointer key, gpointer value,
     return entry->domain_id == domain_id;
 }
 
+/* The shift of an addr for a certain level of paging structure */
+static inline uint32_t vtd_slpt_level_shift(uint32_t level)
+{
+    return VTD_PAGE_SHIFT_4K + (level - 1) * VTD_SL_LEVEL_BITS;
+}
+
+static inline uint64_t vtd_slpt_level_page_mask(uint32_t level)
+{
+    return ~((1ULL << vtd_slpt_level_shift(level)) - 1);
+}
+
 static gboolean vtd_hash_remove_by_page(gpointer key, gpointer value,
                                         gpointer user_data)
 {
     VTDIOTLBEntry *entry = (VTDIOTLBEntry *)value;
     VTDIOTLBPageInvInfo *info = (VTDIOTLBPageInvInfo *)user_data;
-    uint64_t gfn = info->gfn & info->mask;
+    uint64_t gfn = (info->addr >> VTD_PAGE_SHIFT_4K) & info->mask;
+    uint64_t gfn_tlb = (info->addr & entry->mask) >> VTD_PAGE_SHIFT_4K;
     return (entry->domain_id == info->domain_id) &&
-            ((entry->gfn & info->mask) == gfn);
+            (((entry->gfn & info->mask) == gfn) ||
+             (entry->gfn == gfn_tlb));
 }
 
 /* Reset all the gen of VTDAddressSpace to zero and set the gen of
@@ -194,24 +207,46 @@ static void vtd_reset_iotlb(IntelIOMMUState *s)
     g_hash_table_remove_all(s->iotlb);
 }
 
+static uint64_t vtd_get_iotlb_key(uint64_t gfn, uint8_t source_id,
+                                  uint32_t level)
+{
+    return gfn | ((uint64_t)(source_id) << VTD_IOTLB_SID_SHIFT) |
+           ((uint64_t)(level) << VTD_IOTLB_LVL_SHIFT);
+}
+
+static uint64_t vtd_get_iotlb_gfn(hwaddr addr, uint32_t level)
+{
+    return (addr & vtd_slpt_level_page_mask(level)) >> VTD_PAGE_SHIFT_4K;
+}
+
 static VTDIOTLBEntry *vtd_lookup_iotlb(IntelIOMMUState *s, uint16_t source_id,
                                        hwaddr addr)
 {
+    VTDIOTLBEntry *entry;
     uint64_t key;
+    int level;
+
+    for (level = VTD_SL_PT_LEVEL; level < VTD_SL_PML4_LEVEL; level++) {
+        key = vtd_get_iotlb_key(vtd_get_iotlb_gfn(addr, level),
+                                source_id, level);
+        entry = g_hash_table_lookup(s->iotlb, &key);
+        if (entry) {
+            goto out;
+        }
+    }
 
-    key = (addr >> VTD_PAGE_SHIFT_4K) |
-           ((uint64_t)(source_id) << VTD_IOTLB_SID_SHIFT);
-    return g_hash_table_lookup(s->iotlb, &key);
-
+out:
+    return entry;
 }
 
 static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t source_id,
                              uint16_t domain_id, hwaddr addr, uint64_t slpte,
-                             bool read_flags, bool write_flags)
+                             bool read_flags, bool write_flags,
+                             uint32_t level)
 {
     VTDIOTLBEntry *entry = g_malloc(sizeof(*entry));
     uint64_t *key = g_malloc(sizeof(*key));
-    uint64_t gfn = addr >> VTD_PAGE_SHIFT_4K;
+    uint64_t gfn = vtd_get_iotlb_gfn(addr, level);
 
     VTD_DPRINTF(CACHE, "update iotlb sid 0x%"PRIx16 " gpa 0x%"PRIx64
                 " slpte 0x%"PRIx64 " did 0x%"PRIx16, source_id, addr, slpte,
@@ -226,7 +261,8 @@ static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t source_id,
     entry->slpte = slpte;
     entry->read_flags = read_flags;
     entry->write_flags = write_flags;
-    *key = gfn | ((uint64_t)(source_id) << VTD_IOTLB_SID_SHIFT);
+    entry->mask = vtd_slpt_level_page_mask(level);
+    *key = vtd_get_iotlb_key(gfn, source_id, level);
     g_hash_table_replace(s->iotlb, key, entry);
 }
 
@@ -501,12 +537,6 @@ static inline dma_addr_t vtd_get_slpt_base_from_context(VTDContextEntry *ce)
     return ce->lo & VTD_CONTEXT_ENTRY_SLPTPTR;
 }
 
-/* The shift of an addr for a certain level of paging structure */
-static inline uint32_t vtd_slpt_level_shift(uint32_t level)
-{
-    return VTD_PAGE_SHIFT_4K + (level - 1) * VTD_SL_LEVEL_BITS;
-}
-
 static inline uint64_t vtd_get_slpte_addr(uint64_t slpte)
 {
     return slpte & VTD_SL_PT_BASE_ADDR_MASK;
@@ -762,7 +792,7 @@ static void vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
     VTDContextEntry ce;
     uint8_t bus_num = pci_bus_num(bus);
     VTDContextCacheEntry *cc_entry = &vtd_as->context_cache_entry;
-    uint64_t slpte;
+    uint64_t slpte, page_mask;
     uint32_t level;
     uint16_t source_id = vtd_make_source_id(bus_num, devfn);
     int ret_fr;
@@ -802,6 +832,7 @@ static void vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
         slpte = iotlb_entry->slpte;
         reads = iotlb_entry->read_flags;
         writes = iotlb_entry->write_flags;
+        page_mask = iotlb_entry->mask;
         goto out;
     }
     /* Try to fetch context-entry from cache first */
@@ -848,12 +879,13 @@ static void vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
         return;
     }
 
+    page_mask = vtd_slpt_level_page_mask(level);
     vtd_update_iotlb(s, source_id, VTD_CONTEXT_ENTRY_DID(ce.hi), addr, slpte,
-                     reads, writes);
+                     reads, writes, level);
 out:
-    entry->iova = addr & VTD_PAGE_MASK_4K;
-    entry->translated_addr = vtd_get_slpte_addr(slpte) & VTD_PAGE_MASK_4K;
-    entry->addr_mask = ~VTD_PAGE_MASK_4K;
+    entry->iova = addr & page_mask;
+    entry->translated_addr = vtd_get_slpte_addr(slpte) & page_mask;
+    entry->addr_mask = ~page_mask;
     entry->perm = (writes ? 2 : 0) + (reads ? 1 : 0);
 }
 
@@ -991,7 +1023,7 @@ static void vtd_iotlb_page_invalidate(IntelIOMMUState *s, uint16_t domain_id,
 
     assert(am <= VTD_MAMV);
     info.domain_id = domain_id;
-    info.gfn = addr >> VTD_PAGE_SHIFT_4K;
+    info.addr = addr;
     info.mask = ~((1 << am) - 1);
     g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_page, &info);
 }
@@ -1917,7 +1949,7 @@ static void vtd_init(IntelIOMMUState *s)
     s->iq_last_desc_type = VTD_INV_DESC_NONE;
     s->next_frcd_reg = 0;
     s->cap = VTD_CAP_FRO | VTD_CAP_NFR | VTD_CAP_ND | VTD_CAP_MGAW |
-             VTD_CAP_SAGAW | VTD_CAP_MAMV | VTD_CAP_PSI;
+             VTD_CAP_SAGAW | VTD_CAP_MAMV | VTD_CAP_PSI | VTD_CAP_SLLPS;
     s->ecap = VTD_ECAP_QI | VTD_ECAP_IRO;
 
     vtd_reset_context_cache(s);
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 44/49] fix MSI injection on Xen
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (42 preceding siblings ...)
  2016-02-04 21:53 ` [Qemu-devel] [PULL 43/49] intel_iommu: large page support Michael S. Tsirkin
@ 2016-02-04 21:53 ` Michael S. Tsirkin
  2016-02-04 21:54 ` [Qemu-devel] [PULL 45/49] net: set endianness on all backend devices Michael S. Tsirkin
                   ` (5 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, xen-devel, Eduardo Habkost, Stefano Stabellini

From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

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 <stefano.stabellini@eu.citrix.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 include/hw/xen/xen.h |  1 +
 hw/pci/msi.c         |  9 ++++++++-
 hw/pci/msix.c        | 12 ++++++++++--
 hw/xen/xen_pt_msi.c  |  4 +---
 xen-hvm-stub.c       |  5 +++++
 xen-hvm.c            |  9 +++++++++
 6 files changed, 34 insertions(+), 6 deletions(-)

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);
 
diff --git a/hw/pci/msi.c b/hw/pci/msi.c
index 8efa23d..85f21b8 100644
--- a/hw/pci/msi.c
+++ b/hw/pci/msi.c
@@ -20,6 +20,7 @@
 
 #include "qemu/osdep.h"
 #include "hw/pci/msi.h"
+#include "hw/xen/xen.h"
 #include "qemu/range.h"
 
 /* PCI_MSI_ADDRESS_LO */
@@ -254,13 +255,19 @@ void msi_reset(PCIDevice *dev)
 static bool msi_is_masked(const PCIDevice *dev, unsigned int vector)
 {
     uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));
-    uint32_t mask;
+    uint32_t mask, data;
+    bool msi64bit = flags & PCI_MSI_FLAGS_64BIT;
     assert(vector < PCI_MSI_VECTORS_MAX);
 
     if (!(flags & PCI_MSI_FLAGS_MASKBIT)) {
         return false;
     }
 
+    data = pci_get_word(dev->config + msi_data_off(dev, msi64bit));
+    if (xen_is_pirq_msi(data)) {
+        return false;
+    }
+
     mask = pci_get_long(dev->config +
                         msi_mask_off(dev, flags & PCI_MSI_FLAGS_64BIT));
     return mask & (1U << vector);
diff --git a/hw/pci/msix.c b/hw/pci/msix.c
index 4fea7ed..eb4ef11 100644
--- a/hw/pci/msix.c
+++ b/hw/pci/msix.c
@@ -19,6 +19,7 @@
 #include "hw/pci/msi.h"
 #include "hw/pci/msix.h"
 #include "hw/pci/pci.h"
+#include "hw/xen/xen.h"
 #include "qemu/range.h"
 
 #define MSIX_CAP_LENGTH 12
@@ -78,8 +79,15 @@ static void msix_clr_pending(PCIDevice *dev, int vector)
 
 static bool msix_vector_masked(PCIDevice *dev, unsigned int vector, bool fmask)
 {
-    unsigned offset = vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL;
-    return fmask || dev->msix_table[offset] & PCI_MSIX_ENTRY_CTRL_MASKBIT;
+    unsigned offset = vector * PCI_MSIX_ENTRY_SIZE;
+    uint32_t *data = (uint32_t *)&dev->msix_table[offset + PCI_MSIX_ENTRY_DATA];
+    /* MSIs on Xen can be remapped into pirqs. In those cases, masking
+     * and unmasking go through the PV evtchn path. */
+    if (xen_is_pirq_msi(*data)) {
+        return false;
+    }
+    return fmask || dev->msix_table[offset + PCI_MSIX_ENTRY_VECTOR_CTRL] &
+        PCI_MSIX_ENTRY_CTRL_MASKBIT;
 }
 
 bool msix_is_masked(PCIDevice *dev, unsigned int vector)
diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c
index 5624685..9a16f2b 100644
--- a/hw/xen/xen_pt_msi.c
+++ b/hw/xen/xen_pt_msi.c
@@ -115,9 +115,7 @@ static int msi_msix_setup(XenPCIPassthroughState *s,
 
     assert((!is_msix && msix_entry == 0) || is_msix);
 
-    if (gvec == 0) {
-        /* if gvec is 0, the guest is asking for a particular pirq that
-         * is passed as dest_id */
+    if (xen_is_pirq_msi(data)) {
         *ppirq = msi_ext_dest_id(addr >> 32) | msi_dest_id(addr);
         if (!*ppirq) {
             /* this probably identifies an misconfiguration of the guest,
diff --git a/xen-hvm-stub.c b/xen-hvm-stub.c
index a6cb5d3..c500325 100644
--- a/xen-hvm-stub.c
+++ b/xen-hvm-stub.c
@@ -31,6 +31,11 @@ void xen_hvm_inject_msi(uint64_t addr, uint32_t data)
 {
 }
 
+int xen_is_pirq_msi(uint32_t msi_data)
+{
+    return 0;
+}
+
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
                    Error **errp)
 {
diff --git a/xen-hvm.c b/xen-hvm.c
index 1c9fb12..6861c51 100644
--- a/xen-hvm.c
+++ b/xen-hvm.c
@@ -13,6 +13,7 @@
 
 #include "hw/pci/pci.h"
 #include "hw/i386/pc.h"
+#include "hw/i386/apic-msidef.h"
 #include "hw/xen/xen_common.h"
 #include "hw/xen/xen_backend.h"
 #include "qmp-commands.h"
@@ -158,6 +159,14 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
     }
 }
 
+int xen_is_pirq_msi(uint32_t msi_data)
+{
+    /* If vector is 0, the msi is remapped into a pirq, passed as
+     * dest_id.
+     */
+    return ((msi_data & MSI_DATA_VECTOR_MASK) >> MSI_DATA_VECTOR_SHIFT) == 0;
+}
+
 void xen_hvm_inject_msi(uint64_t addr, uint32_t data)
 {
     xen_xc_hvm_inject_msi(xen_xc, xen_domid, addr, data);
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 45/49] net: set endianness on all backend devices
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (43 preceding siblings ...)
  2016-02-04 21:53 ` [Qemu-devel] [PULL 44/49] fix MSI injection on Xen Michael S. Tsirkin
@ 2016-02-04 21:54 ` Michael S. Tsirkin
  2016-02-05  8:54   ` Greg Kurz
  2016-02-04 21:54 ` [Qemu-devel] [PULL 46/49] i386/acpi: make floppy controller object dynamic Michael S. Tsirkin
                   ` (4 subsequent siblings)
  49 siblings, 1 reply; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: Laurent Vivier, Peter Maydell, Eduardo Habkost, Jason Wang,
	Cornelia Huck, Greg Kurz

From: Laurent Vivier <lvivier@redhat.com>

commit 5be7d9f1b1452613b95c6ba70b8d7ad3d0797991
       vhost-net: tell tap backend about the vnet endianness

makes vhost net to set the endianness of the device, but only for
the first device.

In case of multiqueue, we have multiple devices... This patch sets the
endianness for all the devices of the interface.

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
---
 hw/net/vhost_net.c | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 0bd5131..3940a04 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -298,21 +298,19 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
     BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(dev)));
     VirtioBusState *vbus = VIRTIO_BUS(qbus);
     VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
-    int r, e, i;
+    int r, e, i, j;
 
     if (!k->set_guest_notifiers) {
         error_report("binding does not support guest notifiers");
-        r = -ENOSYS;
-        goto err;
+        return -ENOSYS;
     }
 
-    r = vhost_net_set_vnet_endian(dev, ncs[0].peer, true);
-    if (r < 0) {
-        goto err;
-    }
-
-    for (i = 0; i < total_queues; i++) {
-        vhost_net_set_vq_index(get_vhost_net(ncs[i].peer), i * 2);
+    for (j = 0; j < total_queues; j++) {
+        r = vhost_net_set_vnet_endian(dev, ncs[j].peer, true);
+        if (r < 0) {
+            goto err_endian;
+        }
+        vhost_net_set_vq_index(get_vhost_net(ncs[j].peer), j * 2);
     }
 
     r = k->set_guest_notifiers(qbus->parent, total_queues * 2, true);
@@ -341,8 +339,9 @@ err_start:
         fflush(stderr);
     }
 err_endian:
-    vhost_net_set_vnet_endian(dev, ncs[0].peer, false);
-err:
+    while (--j >= 0) {
+        vhost_net_set_vnet_endian(dev, ncs[j].peer, false);
+    }
     return r;
 }
 
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 46/49] i386/acpi: make floppy controller object dynamic
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (44 preceding siblings ...)
  2016-02-04 21:54 ` [Qemu-devel] [PULL 45/49] net: set endianness on all backend devices Michael S. Tsirkin
@ 2016-02-04 21:54 ` Michael S. Tsirkin
  2016-02-04 21:54 ` [Qemu-devel] [PULL 47/49] expose floppy drive geometry and CMOS type Michael S. Tsirkin
                   ` (3 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Eduardo Habkost, Roman Kagan, Paolo Bonzini,
	Igor Mammedov, Richard Henderson

From: Roman Kagan <rkagan@virtuozzo.com>

Instead of statically declaring the floppy controller in DSDT, with its
_STA method depending on some obscure bit in the parent ISA bridge, add
the object dynamically to DSDT via AML API only when the controller is
present.

The _STA method is no longer necessary and is therefore dropped.  So are
the declarations of the fields indicating whether the contoller is
enabled.

Signed-off-by: Roman Kagan <rkagan@virtuozzo.com>
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/i386/acpi-build.c | 27 +++------------------------
 1 file changed, 3 insertions(+), 24 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 4554eb8..842c731 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1231,29 +1231,10 @@ static Aml *build_fdc_device_aml(void)
 {
     Aml *dev;
     Aml *crs;
-    Aml *method;
-    Aml *if_ctx;
-    Aml *else_ctx;
-    Aml *zero = aml_int(0);
-    Aml *is_present = aml_local(0);
 
     dev = aml_device("FDC0");
     aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0700")));
 
-    method = aml_method("_STA", 0, AML_NOTSERIALIZED);
-    aml_append(method, aml_store(aml_name("FDEN"), is_present));
-    if_ctx = aml_if(aml_equal(is_present, zero));
-    {
-        aml_append(if_ctx, aml_return(aml_int(0x00)));
-    }
-    aml_append(method, if_ctx);
-    else_ctx = aml_else();
-    {
-        aml_append(else_ctx, aml_return(aml_int(0x0f)));
-    }
-    aml_append(method, else_ctx);
-    aml_append(dev, method);
-
     crs = aml_resource_template();
     aml_append(crs, aml_io(AML_DECODE16, 0x03F2, 0x03F2, 0x00, 0x04));
     aml_append(crs, aml_io(AML_DECODE16, 0x03F7, 0x03F7, 0x00, 0x01));
@@ -1411,7 +1392,9 @@ static void build_isa_devices_aml(Aml *table)
     aml_append(scope, build_rtc_device_aml());
     aml_append(scope, build_kbd_device_aml());
     aml_append(scope, build_mouse_device_aml());
-    aml_append(scope, build_fdc_device_aml());
+    if (!!pc_find_fdc0()) {
+        aml_append(scope, build_fdc_device_aml());
+    }
     aml_append(scope, build_lpt_device_aml());
     aml_append(scope, build_com_device_aml(1));
     aml_append(scope, build_com_device_aml(2));
@@ -1780,8 +1763,6 @@ static void build_q35_isa_bridge(Aml *table)
     aml_append(field, aml_named_field("COMB", 3));
     aml_append(field, aml_reserved_field(1));
     aml_append(field, aml_named_field("LPTD", 2));
-    aml_append(field, aml_reserved_field(2));
-    aml_append(field, aml_named_field("FDCD", 2));
     aml_append(dev, field);
 
     aml_append(dev, aml_operation_region("LPCE", AML_PCI_CONFIG,
@@ -1791,7 +1772,6 @@ static void build_q35_isa_bridge(Aml *table)
     aml_append(field, aml_named_field("CAEN", 1));
     aml_append(field, aml_named_field("CBEN", 1));
     aml_append(field, aml_named_field("LPEN", 1));
-    aml_append(field, aml_named_field("FDEN", 1));
     aml_append(dev, field);
 
     aml_append(scope, dev);
@@ -1839,7 +1819,6 @@ static void build_piix4_isa_bridge(Aml *table)
     aml_append(field, aml_reserved_field(3));
     aml_append(field, aml_named_field("CBEN", 1));
     aml_append(dev, field);
-    aml_append(dev, aml_name_decl("FDEN", aml_int(1)));
 
     aml_append(scope, dev);
     aml_append(table, scope);
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 47/49] expose floppy drive geometry and CMOS type
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (45 preceding siblings ...)
  2016-02-04 21:54 ` [Qemu-devel] [PULL 46/49] i386/acpi: make floppy controller object dynamic Michael S. Tsirkin
@ 2016-02-04 21:54 ` Michael S. Tsirkin
  2016-02-04 21:54 ` [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT Michael S. Tsirkin
                   ` (2 subsequent siblings)
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Eduardo Habkost, qemu-block,
	Roman Kagan, Paolo Bonzini, Igor Mammedov, John Snow,
	Richard Henderson

From: Roman Kagan <rkagan@virtuozzo.com>

Make it possible to query the geometry and the CMOS type of a floppy
drive outside of the respective source files.

It will be useful, in particular, when dynamically building ACPI tables,
and will allow to properly populate the corresponding ACPI objects and
thus enable BIOS-less systems to access the floppy drives.

Signed-off-by: Roman Kagan <rkagan@virtuozzo.com>
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 include/hw/block/fdc.h |  2 ++
 include/hw/i386/pc.h   |  1 +
 hw/block/fdc.c         | 11 +++++++++++
 hw/i386/pc.c           |  2 +-
 4 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/include/hw/block/fdc.h b/include/hw/block/fdc.h
index adce14f..d87859e 100644
--- a/include/hw/block/fdc.h
+++ b/include/hw/block/fdc.h
@@ -15,5 +15,7 @@ void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base,
                        DriveInfo **fds, qemu_irq *fdc_tc);
 
 FloppyDriveType isa_fdc_get_drive_type(ISADevice *fdc, int i);
+void isa_fdc_get_drive_geometry(ISADevice *fdc, int i, uint8_t *cylinders,
+                                uint8_t *heads, uint8_t *sectors);
 
 #endif
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 8b3546e..472754c 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -265,6 +265,7 @@ typedef void (*cpu_set_smm_t)(int smm, void *arg);
 void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
 
 ISADevice *pc_find_fdc0(void);
+int cmos_get_fd_drive_type(FloppyDriveType fd0);
 
 /* acpi_piix.c */
 
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 818e8a4..245184b 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -2509,6 +2509,17 @@ FloppyDriveType isa_fdc_get_drive_type(ISADevice *fdc, int i)
     return isa->state.drives[i].drive;
 }
 
+void isa_fdc_get_drive_geometry(ISADevice *fdc, int i, uint8_t *cylinders,
+                                uint8_t *heads, uint8_t *sectors)
+{
+    FDCtrlISABus *isa = ISA_FDC(fdc);
+    FDrive *drv = &isa->state.drives[i];
+
+    *cylinders = drv->max_track;
+    *heads = (drv->flags & FDISK_DBL_SIDES) ? 2 : 1;
+    *sectors = drv->last_sect;
+}
+
 static const VMStateDescription vmstate_isa_fdc ={
     .name = "fdc",
     .version_id = 2,
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index ce185bb..fd8524f 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -200,7 +200,7 @@ static void pic_irq_request(void *opaque, int irq, int level)
 
 #define REG_EQUIPMENT_BYTE          0x14
 
-static int cmos_get_fd_drive_type(FloppyDriveType fd0)
+int cmos_get_fd_drive_type(FloppyDriveType fd0)
 {
     int val;
 
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (46 preceding siblings ...)
  2016-02-04 21:54 ` [Qemu-devel] [PULL 47/49] expose floppy drive geometry and CMOS type Michael S. Tsirkin
@ 2016-02-04 21:54 ` Michael S. Tsirkin
  2016-02-05 18:25   ` Igor Mammedov
  2016-02-04 21:54 ` [Qemu-devel] [PULL 49/49] acpi: update expected DSDT Michael S. Tsirkin
  2016-02-05 15:03 ` [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Peter Maydell
  49 siblings, 1 reply; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Eduardo Habkost, Roman Kagan, Paolo Bonzini,
	Igor Mammedov, Richard Henderson

From: Roman Kagan <rkagan@virtuozzo.com>

On x86-based systems Linux determines the presence
and the type of floppy drives via a query of a CMOS field.
So does SeaBIOS when populating the return data for
int 0x13 function 0x08.

However Windows doesn't do it. Instead, it requests
this information from BIOS via int 0x13/0x08 or through
ACPI objects _FDE (Floppy Drive Enumerate) and _FDI
(Floppy Drive Information) of the floppy controller object.
On UEFI systems only ACPI-based detection is supported.

QEMU doesn't provide those objects in its ACPI tables
and as a result floppy drives aren't invisible to Windows
on UEFI/OVMF.

This patch adds those objects to the floppy controller
in DSDT, populating them with the information from
respective QEMU objects.

Signed-off-by: Roman Kagan <rkagan@virtuozzo.com>
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/i386/acpi-build.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 58 insertions(+), 3 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 842c731..caa2e87 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -37,6 +37,7 @@
 #include "hw/acpi/bios-linker-loader.h"
 #include "hw/loader.h"
 #include "hw/isa/isa.h"
+#include "hw/block/fdc.h"
 #include "hw/acpi/memory_hotplug.h"
 #include "hw/mem/nvdimm.h"
 #include "sysemu/tpm.h"
@@ -1227,10 +1228,47 @@ static void build_hpet_aml(Aml *table)
     aml_append(table, scope);
 }
 
-static Aml *build_fdc_device_aml(void)
+static Aml *build_fdinfo_aml(int idx, uint8_t type, uint8_t cylinders,
+                             uint8_t heads, uint8_t sectors)
+{
+    Aml *dev, *fdi;
+
+    dev = aml_device("FLP%c", 'A' + idx);
+
+    aml_append(dev, aml_name_decl("_ADR", aml_int(idx)));
+
+    fdi = aml_package(0x10);
+    aml_append(fdi, aml_int(idx));  /* Drive Number */
+    aml_append(fdi,
+        aml_int(cmos_get_fd_drive_type(type)));  /* Device Type */
+    aml_append(fdi,
+        aml_int(cylinders - 1));  /* Maximum Cylinder Number */
+    aml_append(fdi, aml_int(sectors));  /* Maximum Sector Number */
+    aml_append(fdi, aml_int(heads - 1));  /* Maximum Head Number */
+    /* SeaBIOS returns the below values for int 0x13 func 0x08 regardless of
+     * the drive type, so shall we */
+    aml_append(fdi, aml_int(0xAF));  /* disk_specify_1 */
+    aml_append(fdi, aml_int(0x02));  /* disk_specify_2 */
+    aml_append(fdi, aml_int(0x25));  /* disk_motor_wait */
+    aml_append(fdi, aml_int(0x02));  /* disk_sector_siz */
+    aml_append(fdi, aml_int(0x12));  /* disk_eot */
+    aml_append(fdi, aml_int(0x1B));  /* disk_rw_gap */
+    aml_append(fdi, aml_int(0xFF));  /* disk_dtl */
+    aml_append(fdi, aml_int(0x6C));  /* disk_formt_gap */
+    aml_append(fdi, aml_int(0xF6));  /* disk_fill */
+    aml_append(fdi, aml_int(0x0F));  /* disk_head_sttl */
+    aml_append(fdi, aml_int(0x08));  /* disk_motor_strt */
+
+    aml_append(dev, aml_name_decl("_FDI", fdi));
+    return dev;
+}
+
+static Aml *build_fdc_device_aml(ISADevice *fdc)
 {
+    int i;
     Aml *dev;
     Aml *crs;
+    uint32_t fde_buf[5] = {0, 0, 0, 0, cpu_to_le32(0x2)};
 
     dev = aml_device("FDC0");
     aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0700")));
@@ -1243,6 +1281,21 @@ static Aml *build_fdc_device_aml(void)
         aml_dma(AML_COMPATIBILITY, AML_NOTBUSMASTER, AML_TRANSFER8, 2));
     aml_append(dev, aml_name_decl("_CRS", crs));
 
+    for (i = 0; i < MAX_FD; i++) {
+        uint8_t type = isa_fdc_get_drive_type(fdc, i);
+
+        if (type < FLOPPY_DRIVE_TYPE_NONE) {
+            uint8_t cylinders, heads, sectors;
+
+            fde_buf[i] = cpu_to_le32(0x1);
+            isa_fdc_get_drive_geometry(fdc, i, &cylinders, &heads, &sectors);
+            aml_append(dev,
+                build_fdinfo_aml(i, type, cylinders, heads, sectors));
+        }
+    }
+    aml_append(dev, aml_name_decl("_FDE",
+               aml_buffer(sizeof(fde_buf), (uint8_t *) fde_buf)));
+
     return dev;
 }
 
@@ -1387,13 +1440,15 @@ static Aml *build_com_device_aml(uint8_t uid)
 
 static void build_isa_devices_aml(Aml *table)
 {
+    ISADevice *fdc = pc_find_fdc0();
+
     Aml *scope = aml_scope("_SB.PCI0.ISA");
 
     aml_append(scope, build_rtc_device_aml());
     aml_append(scope, build_kbd_device_aml());
     aml_append(scope, build_mouse_device_aml());
-    if (!!pc_find_fdc0()) {
-        aml_append(scope, build_fdc_device_aml());
+    if (!!fdc) {
+        aml_append(scope, build_fdc_device_aml(fdc));
     }
     aml_append(scope, build_lpt_device_aml());
     aml_append(scope, build_com_device_aml(1));
-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PULL 49/49] acpi: update expected DSDT
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (47 preceding siblings ...)
  2016-02-04 21:54 ` [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT Michael S. Tsirkin
@ 2016-02-04 21:54 ` Michael S. Tsirkin
  2016-02-05 15:03 ` [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Peter Maydell
  49 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-04 21:54 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Eduardo Habkost

Previous patches ("i386: populate floppy drive information in DSDT" and
("i386/acpi: make floppy controller object dynamic") change the floppy
description in DSDT (and remove the floppy device if it's not present).
Update expected files accordingly.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 tests/acpi-test-data/pc/DSDT         | Bin 5478 -> 5533 bytes
 tests/acpi-test-data/pc/DSDT.bridge  | Bin 7337 -> 7392 bytes
 tests/acpi-test-data/q35/DSDT        | Bin 8321 -> 8233 bytes
 tests/acpi-test-data/q35/DSDT.bridge | Bin 8338 -> 8250 bytes
 4 files changed, 0 insertions(+), 0 deletions(-)

diff --git a/tests/acpi-test-data/pc/DSDT b/tests/acpi-test-data/pc/DSDT
index ec0e642b06967d3ec4d7a7d252b82b916f37a5e0..d3466baa0c0c93d16c51879f611a8d88f21bc162 100644
GIT binary patch
delta 156
zcmaE+HCLO<CD<iot|$WoW5z}<8%90{R=xOOr}zM8PlM<t=gA?APRs(H@{{K?E);O*
zaC31s;E4C|bm4Klz|Jr^lSw()+|4Jzkt5#GC5V9|-p$2RNKJr&i<R#`6fiJwt><Fm
nQUzimE@`g+Tsd6dxcIp^Kx$nD#koWn8BhTe1H<M{rn^D_tav4q

delta 103
zcmbQM{Y;C?CD<h-O_YIw@!3W$8%91iR=xOOr}zM8PlM<t&&eT-PMjQWF0Ouz0zT4{
zXEH9-^kQ*yaW>$H_waP#alF9JAR-YT9OB4O08*5&fNgRD!xDytEK9ifCwnm|Z$8X)
GO9%j#W*kod

diff --git a/tests/acpi-test-data/pc/DSDT.bridge b/tests/acpi-test-data/pc/DSDT.bridge
index 7b1c14b529f9f63fc3731c02225ce37c5cfbc0db..179f5d5348fc9ce4ecf60ee6019aca58e29fad69 100644
GIT binary patch
delta 156
zcmZ2!`M{FPCD<k8feZr!<Hn6#HjI1@ta|amPVoWGo(9oP&XYqJotOnY<tNW)Tqxkq
z;pXCOz!C4^>B8f9ft_J;CX;foxtmXbBS*ZWOArG`yqk-skeUDk7c1X?C}3dVTF=GA
nr3%DCT+&?sxpKI^aq)9;fYiDQigSrDGN1w`28PX@ObSu}5}zfN

delta 103
zcmaE0xzdu$CD<ior3?cDqy9!N8%91iR=xOOr}zM8PlM<t&&eT-PMjQWF0Ouz0zT4{
zXEH9-^kQ*yaW>$H_waP#alF9JAR-YT9OB4O08*5&fNgRD!xDytEK9ifCwnm|Z$8W<
GD+K_4&Kpnw

diff --git a/tests/acpi-test-data/q35/DSDT b/tests/acpi-test-data/q35/DSDT
index b492f04b8866ae82eaded81aa0ea2d3a4969dc5c..93356ac51915897db1d6615a8b6cfd607c2a2ca7 100644
GIT binary patch
delta 91
zcmZp4T<O5&66_M9sldR%sJW5rEhC=;yIy>-Q+$B4r$Ka+^JG>gbw<g_x=a$P(G5NU
q&aO;cO<YXTjiMkngR`TnAEUDqknjlr5&{n5lgpSEZcb*FlLY_^$QDxo

delta 176
zcmZ4K(CEnJ66_MvsKCI$cxofpTSh(~cD?vur}zM8PlM<t|H-UO>Wm7Lb(tg#8JOH$
zoL!ir8+-zsU75I=xR|0Fr9f;3XGd2*MrS7=;S&HP++2W!fRFU#ET)AXUMxUe1|0Do
zo-RC&7uXp@B;tcZ92p8giV_yEO-^7~!myBK2^T*{ymL^npfs0+JL4zjPs|J~?u_4=
UzcVv1DmgG{u`q0AXI7F009TzV?EnA(

diff --git a/tests/acpi-test-data/q35/DSDT.bridge b/tests/acpi-test-data/q35/DSDT.bridge
index 3b72e250fa866ec34c315450643025e03c8c8cab..4f943e675cd4adc20ea237b9e97589ea56c5024e 100644
GIT binary patch
delta 91
zcmbQ_xXXddCD<jzN`Zla@#IFXw~Txa?0WIRPVoWGo(9oP&XZZ0)EOlw>oQ5GMmP8b
qIJ+`&HE}UTH;RJT49<?OevHmeK*A>gNC-HHPcCCxxH*|wUlssOa2GcK

delta 176
zcmdnxFv*e2CD<iok^%z*W7bBlw~Tx~?0WIRPVoWGo(9oP{*zgm)EN~f>oQ3gGBCNh
zIJ+=KH~0iNyE1V#aWO?VN`cr6&W^5rjLuF#!Y2SoxVZoc0UznfSxgH(yjXy`3^?LF
zJY9GkFR(L+NW=$+I5HG~6eTQRo1DO~gkd4e5-xs@c;}#CL1``tcg9c5pO_g~+!?<!
Ue`jW3RB~X@Vqw_K&TK3T06kPH(EtDd

-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 38/49] acpi: take oem_id in build_header(), optionally
  2016-02-04 21:53 ` [Qemu-devel] [PULL 38/49] acpi: take oem_id in build_header(), optionally Michael S. Tsirkin
@ 2016-02-04 22:25   ` Laszlo Ersek
  0 siblings, 0 replies; 75+ messages in thread
From: Laszlo Ersek @ 2016-02-04 22:25 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Peter Maydell, Xiao Guangrong, Eduardo Habkost, Aleksei Kovura,
	Steven Newbury, Michael Tokarev, qemu-devel,
	Richard W . M . Jones, Paolo Bonzini, Shannon Zhao, qemu-arm,
	Shannon Zhao, Igor Mammedov, Richard Henderson

Thank you for picking up my patches, and for rebasing them to the SSDT
removal (Igor's "[PULL 02/49] pc: acpi: merge SSDT into DSDT").

Laszlo

On 02/04/16 22:53, Michael S. Tsirkin wrote:
> From: Laszlo Ersek <lersek@redhat.com>
> 
> 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" <mst@redhat.com> (supporter:ACPI/SMBIOS)
> Cc: Igor Mammedov <imammedo@redhat.com> (supporter:ACPI/SMBIOS)
> Cc: Xiao Guangrong <guangrong.xiao@linux.intel.com> (maintainer:NVDIMM)
> Cc: Shannon Zhao <zhaoshenglong@huawei.com> (maintainer:ARM ACPI Subsystem)
> Cc: Paolo Bonzini <pbonzini@redhat.com> (maintainer:X86)
> Cc: Richard W.M. Jones <rjones@redhat.com>
> Cc: Aleksei Kovura <alex3kov@zoho.com>
> Cc: Michael Tokarev <mjt@tls.msk.ru>
> Cc: Steven Newbury <steve@snewbury.org.uk>
> RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1248758
> LP: https://bugs.launchpad.net/qemu/+bug/1533848
> Signed-off-by: Laszlo Ersek <lersek@redhat.com>
> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> Reviewed-by: Shannon Zhao <shannon.zhao@linaro.org>
> ---
>  include/hw/acpi/aml-build.h |  2 +-
>  hw/acpi/aml-build.c         | 11 ++++++++---
>  hw/acpi/nvdimm.c            |  4 ++--
>  hw/arm/virt-acpi-build.c    | 12 ++++++------
>  hw/i386/acpi-build.c        | 18 +++++++++---------
>  5 files changed, 26 insertions(+), 21 deletions(-)
> 
> 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);
> diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
> index 21d2ea0..e4b6c0c 100644
> --- a/hw/acpi/aml-build.c
> +++ b/hw/acpi/aml-build.c
> @@ -1426,12 +1426,17 @@ Aml *aml_alias(const char *source_object, const char *alias_object)
>  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)
>  {
>      memcpy(&h->signature, sig, 4);
>      h->length = cpu_to_le32(len);
>      h->revision = rev;
> -    memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
> +
> +    if (oem_id) {
> +        strncpy((char *)h->oem_id, oem_id, sizeof h->oem_id);
> +    } else {
> +        memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
> +    }
>  
>      if (oem_table_id) {
>          strncpy((char *)h->oem_table_id, oem_table_id, sizeof(h->oem_table_id));
> @@ -1506,5 +1511,5 @@ build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
>                                         sizeof(uint32_t));
>      }
>      build_header(linker, table_data,
> -                 (void *)rsdt, "RSDT", rsdt_len, 1, NULL);
> +                 (void *)rsdt, "RSDT", rsdt_len, 1, NULL, NULL);
>  }
> diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
> index 7ee7e16..49ee68e 100644
> --- a/hw/acpi/nvdimm.c
> +++ b/hw/acpi/nvdimm.c
> @@ -366,7 +366,7 @@ static void nvdimm_build_nfit(GSList *device_list, GArray *table_offsets,
>  
>      build_header(linker, table_data,
>                   (void *)(table_data->data + header), "NFIT",
> -                 sizeof(NvdimmNfitHeader) + structures->len, 1, NULL);
> +                 sizeof(NvdimmNfitHeader) + structures->len, 1, NULL, NULL);
>      g_array_free(structures, true);
>  }
>  
> @@ -471,7 +471,7 @@ static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets,
>      g_array_append_vals(table_data, ssdt->buf->data, ssdt->buf->len);
>      build_header(linker, table_data,
>          (void *)(table_data->data + table_data->len - ssdt->buf->len),
> -        "SSDT", ssdt->buf->len, 1, "NVDIMM");
> +        "SSDT", ssdt->buf->len, 1, NULL, "NVDIMM");
>      free_aml_allocator();
>  }
>  
> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> index 87fbe7c..8017b12 100644
> --- a/hw/arm/virt-acpi-build.c
> +++ b/hw/arm/virt-acpi-build.c
> @@ -408,7 +408,7 @@ build_spcr(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
>      spcr->pci_vendor_id = 0xffff;  /* PCI Vendor ID: not a PCI device */
>  
>      build_header(linker, table_data, (void *)spcr, "SPCR", sizeof(*spcr), 2,
> -                 NULL);
> +                 NULL, NULL);
>  }
>  
>  static void
> @@ -427,7 +427,7 @@ build_mcfg(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
>      mcfg->allocation[0].end_bus_number = (memmap[VIRT_PCIE_ECAM].size
>                                            / PCIE_MMCFG_SIZE_MIN) - 1;
>  
> -    build_header(linker, table_data, (void *)mcfg, "MCFG", len, 1, NULL);
> +    build_header(linker, table_data, (void *)mcfg, "MCFG", len, 1, NULL, NULL);
>  }
>  
>  /* GTDT */
> @@ -453,7 +453,7 @@ build_gtdt(GArray *table_data, GArray *linker)
>  
>      build_header(linker, table_data,
>                   (void *)(table_data->data + gtdt_start), "GTDT",
> -                 table_data->len - gtdt_start, 2, NULL);
> +                 table_data->len - gtdt_start, 2, NULL, NULL);
>  }
>  
>  /* MADT */
> @@ -515,7 +515,7 @@ build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info,
>  
>      build_header(linker, table_data,
>                   (void *)(table_data->data + madt_start), "APIC",
> -                 table_data->len - madt_start, 3, NULL);
> +                 table_data->len - madt_start, 3, NULL, NULL);
>  }
>  
>  /* FADT */
> @@ -540,7 +540,7 @@ build_fadt(GArray *table_data, GArray *linker, unsigned dsdt)
>                                     sizeof fadt->dsdt);
>  
>      build_header(linker, table_data,
> -                 (void *)fadt, "FACP", sizeof(*fadt), 5, NULL);
> +                 (void *)fadt, "FACP", sizeof(*fadt), 5, NULL, NULL);
>  }
>  
>  /* DSDT */
> @@ -579,7 +579,7 @@ build_dsdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
>      g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len);
>      build_header(linker, table_data,
>          (void *)(table_data->data + table_data->len - dsdt->buf->len),
> -        "DSDT", dsdt->buf->len, 2, NULL);
> +        "DSDT", dsdt->buf->len, 2, NULL, NULL);
>      free_aml_allocator();
>  }
>  
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 35582a7..061a9cb 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -357,7 +357,7 @@ build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm,
>      fadt_setup(fadt, pm);
>  
>      build_header(linker, table_data,
> -                 (void *)fadt, "FACP", sizeof(*fadt), 1, NULL);
> +                 (void *)fadt, "FACP", sizeof(*fadt), 1, NULL, NULL);
>  }
>  
>  static void
> @@ -427,7 +427,7 @@ build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu)
>  
>      build_header(linker, table_data,
>                   (void *)(table_data->data + madt_start), "APIC",
> -                 table_data->len - madt_start, 1, NULL);
> +                 table_data->len - madt_start, 1, NULL, NULL);
>  }
>  
>  /* Assign BSEL property to all buses.  In the future, this can be changed
> @@ -2286,7 +2286,7 @@ build_dsdt(GArray *table_data, GArray *linker,
>      g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len);
>      build_header(linker, table_data,
>          (void *)(table_data->data + table_data->len - dsdt->buf->len),
> -        "DSDT", dsdt->buf->len, 1, NULL);
> +        "DSDT", dsdt->buf->len, 1, NULL, NULL);
>      free_aml_allocator();
>  }
>  
> @@ -2302,7 +2302,7 @@ build_hpet(GArray *table_data, GArray *linker)
>      hpet->timer_block_id = cpu_to_le32(0x8086a201);
>      hpet->addr.address = cpu_to_le64(HPET_BASE);
>      build_header(linker, table_data,
> -                 (void *)hpet, "HPET", sizeof(*hpet), 1, NULL);
> +                 (void *)hpet, "HPET", sizeof(*hpet), 1, NULL, NULL);
>  }
>  
>  static void
> @@ -2325,7 +2325,7 @@ build_tpm_tcpa(GArray *table_data, GArray *linker, GArray *tcpalog)
>                                     sizeof(tcpa->log_area_start_address));
>  
>      build_header(linker, table_data,
> -                 (void *)tcpa, "TCPA", sizeof(*tcpa), 2, NULL);
> +                 (void *)tcpa, "TCPA", sizeof(*tcpa), 2, NULL, NULL);
>  
>      acpi_data_push(tcpalog, TPM_LOG_AREA_MINIMUM_SIZE);
>  }
> @@ -2342,7 +2342,7 @@ build_tpm2(GArray *table_data, GArray *linker)
>      tpm2_ptr->start_method = cpu_to_le32(TPM2_START_METHOD_MMIO);
>  
>      build_header(linker, table_data,
> -                 (void *)tpm2_ptr, "TPM2", sizeof(*tpm2_ptr), 4, NULL);
> +                 (void *)tpm2_ptr, "TPM2", sizeof(*tpm2_ptr), 4, NULL, NULL);
>  }
>  
>  typedef enum {
> @@ -2456,7 +2456,7 @@ build_srat(GArray *table_data, GArray *linker)
>      build_header(linker, table_data,
>                   (void *)(table_data->data + srat_start),
>                   "SRAT",
> -                 table_data->len - srat_start, 1, NULL);
> +                 table_data->len - srat_start, 1, NULL, NULL);
>  }
>  
>  static void
> @@ -2485,7 +2485,7 @@ build_mcfg_q35(GArray *table_data, GArray *linker, AcpiMcfgInfo *info)
>      } else {
>          sig = "MCFG";
>      }
> -    build_header(linker, table_data, (void *)mcfg, sig, len, 1, NULL);
> +    build_header(linker, table_data, (void *)mcfg, sig, len, 1, NULL, NULL);
>  }
>  
>  static void
> @@ -2509,7 +2509,7 @@ build_dmar_q35(GArray *table_data, GArray *linker)
>      drhd->address = cpu_to_le64(Q35_HOST_BRIDGE_IOMMU_ADDR);
>  
>      build_header(linker, table_data, (void *)(table_data->data + dmar_start),
> -                 "DMAR", table_data->len - dmar_start, 1, NULL);
> +                 "DMAR", table_data->len - dmar_start, 1, NULL, NULL);
>  }
>  
>  static GArray *
> 

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 45/49] net: set endianness on all backend devices
  2016-02-04 21:54 ` [Qemu-devel] [PULL 45/49] net: set endianness on all backend devices Michael S. Tsirkin
@ 2016-02-05  8:54   ` Greg Kurz
  0 siblings, 0 replies; 75+ messages in thread
From: Greg Kurz @ 2016-02-05  8:54 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Laurent Vivier, Peter Maydell, Eduardo Habkost, Jason Wang,
	qemu-devel, qemu-stable, Cornelia Huck

On Thu, 4 Feb 2016 23:54:01 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> From: Laurent Vivier <lvivier@redhat.com>
> 
> commit 5be7d9f1b1452613b95c6ba70b8d7ad3d0797991
>        vhost-net: tell tap backend about the vnet endianness
> 
> makes vhost net to set the endianness of the device, but only for
> the first device.
> 
> In case of multiqueue, we have multiple devices... This patch sets the
> endianness for all the devices of the interface.
> 
> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> Reviewed-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> Reviewed-by: Jason Wang <jasowang@redhat.com>
> ---

Cool ! 

Cc'ing stable since 2.4 and 2.5 need this fix as well.

Thanks.

--
Greg

>  hw/net/vhost_net.c | 23 +++++++++++------------
>  1 file changed, 11 insertions(+), 12 deletions(-)
> 
> diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
> index 0bd5131..3940a04 100644
> --- a/hw/net/vhost_net.c
> +++ b/hw/net/vhost_net.c
> @@ -298,21 +298,19 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
>      BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(dev)));
>      VirtioBusState *vbus = VIRTIO_BUS(qbus);
>      VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
> -    int r, e, i;
> +    int r, e, i, j;
> 
>      if (!k->set_guest_notifiers) {
>          error_report("binding does not support guest notifiers");
> -        r = -ENOSYS;
> -        goto err;
> +        return -ENOSYS;
>      }
> 
> -    r = vhost_net_set_vnet_endian(dev, ncs[0].peer, true);
> -    if (r < 0) {
> -        goto err;
> -    }
> -
> -    for (i = 0; i < total_queues; i++) {
> -        vhost_net_set_vq_index(get_vhost_net(ncs[i].peer), i * 2);
> +    for (j = 0; j < total_queues; j++) {
> +        r = vhost_net_set_vnet_endian(dev, ncs[j].peer, true);
> +        if (r < 0) {
> +            goto err_endian;
> +        }
> +        vhost_net_set_vq_index(get_vhost_net(ncs[j].peer), j * 2);
>      }
> 
>      r = k->set_guest_notifiers(qbus->parent, total_queues * 2, true);
> @@ -341,8 +339,9 @@ err_start:
>          fflush(stderr);
>      }
>  err_endian:
> -    vhost_net_set_vnet_endian(dev, ncs[0].peer, false);
> -err:
> +    while (--j >= 0) {
> +        vhost_net_set_vnet_endian(dev, ncs[j].peer, false);
> +    }
>      return r;
>  }
> 

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 06/49] virtio: move allocation to virtqueue_pop/vring_pop
  2016-02-04 21:51 ` [Qemu-devel] [PULL 06/49] virtio: move allocation to virtqueue_pop/vring_pop Michael S. Tsirkin
@ 2016-02-05 12:52   ` Peter Maydell
  2016-02-06 18:10     ` Michael S. Tsirkin
  0 siblings, 1 reply; 75+ messages in thread
From: Peter Maydell @ 2016-02-05 12:52 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Kevin Wolf, Gerd Hoffmann, Eduardo Habkost, Qemu-block,
	Jason Wang, QEMU Developers, Amit Shah, Aneesh Kumar K.V,
	Stefan Hajnoczi, Cornelia Huck, Paolo Bonzini, Greg Kurz

On 4 February 2016 at 21:51, Michael S. Tsirkin <mst@redhat.com> wrote:
> From: Paolo Bonzini <pbonzini@redhat.com>
>
> 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 <pbonzini@redhat.com>
> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> ---
>  hw/9pfs/virtio-9p.h                 |  2 +-
>  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 +-
>  hw/9pfs/9p.c                        |  2 +-
>  hw/9pfs/virtio-9p-device.c          | 17 ++++----
>  hw/block/dataplane/virtio-blk.c     | 11 +++--
>  hw/block/virtio-blk.c               | 15 +++----
>  hw/char/virtio-serial-bus.c         | 80 +++++++++++++++++++++++--------------
>  hw/display/virtio-gpu.c             | 21 ++++++----
>  hw/input/virtio-input.c             | 24 +++++++----
>  hw/net/virtio-net.c                 | 69 ++++++++++++++++++++------------
>  hw/scsi/virtio-scsi-dataplane.c     | 15 +++----
>  hw/scsi/virtio-scsi.c               | 18 ++++-----
>  hw/virtio/dataplane/vring.c         | 18 +++++----
>  hw/virtio/virtio-balloon.c          | 22 ++++++----
>  hw/virtio/virtio-rng.c              | 10 +++--
>  hw/virtio/virtio.c                  | 12 ++++--
>  roms/seabios                        |  2 +-
>  23 files changed, 210 insertions(+), 143 deletions(-)

> --- a/roms/seabios
> +++ b/roms/seabios
> @@ -1 +1 @@
> -Subproject commit 01a84bea2d28a19d2405c1ecac4bdef17683cc0c
> +Subproject commit 33fbe13a3e2a01e0ba1087a8feed801a0451db21
> --
> MST

Hi. This commit in this pull request includes a seabios submodule
update, but the commit message says nothing about it. Is it
really supposed to be here?

thanks
-- PMM

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations
  2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
                   ` (48 preceding siblings ...)
  2016-02-04 21:54 ` [Qemu-devel] [PULL 49/49] acpi: update expected DSDT Michael S. Tsirkin
@ 2016-02-05 15:03 ` Peter Maydell
  2016-02-05 18:19   ` Igor Mammedov
  49 siblings, 1 reply; 75+ messages in thread
From: Peter Maydell @ 2016-02-05 15:03 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: QEMU Developers, Eduardo Habkost

On 4 February 2016 at 21:50, Michael S. Tsirkin <mst@redhat.com> wrote:
> The following changes since commit 382d34ff9fcc534db32d54eb82590de7c04f9b33:
>
>   Merge remote-tracking branch 'remotes/stefanha/tags/tracing-pull-request' into staging (2016-02-03 19:00:33 +0000)
>
> are available in the git repository at:
>
>   git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream
>
> for you to fetch changes up to 32db7f56a0df015362fabd73c2d43dab7196fa64:
>
>   acpi: update expected DSDT (2016-02-04 20:54:21 +0200)
>
> ----------------------------------------------------------------
> pc and misc cleanups and fixes, virtio optimizations
>
> Included here:
> Refactoring and bugfix patches in PC/ACPI.
> New commands for ipmi.
> Virtio optimizations.
>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

>  roms/seabios                                       |   2 +-

Dropped from my pull request queue because of the accidental-looking
seabios update. Let me know if it's legit and I'll reprocess.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations
  2016-02-05 15:03 ` [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Peter Maydell
@ 2016-02-05 18:19   ` Igor Mammedov
  0 siblings, 0 replies; 75+ messages in thread
From: Igor Mammedov @ 2016-02-05 18:19 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers, Eduardo Habkost, Michael S. Tsirkin

On Fri, 5 Feb 2016 15:03:55 +0000
Peter Maydell <peter.maydell@linaro.org> wrote:

> On 4 February 2016 at 21:50, Michael S. Tsirkin <mst@redhat.com> wrote:
> > The following changes since commit 382d34ff9fcc534db32d54eb82590de7c04f9b33:
> >
> >   Merge remote-tracking branch 'remotes/stefanha/tags/tracing-pull-request' into staging (2016-02-03 19:00:33 +0000)
> >
> > are available in the git repository at:
> >
> >   git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream
> >
> > for you to fetch changes up to 32db7f56a0df015362fabd73c2d43dab7196fa64:
> >
> >   acpi: update expected DSDT (2016-02-04 20:54:21 +0200)
> >
> > ----------------------------------------------------------------
> > pc and misc cleanups and fixes, virtio optimizations
> >
> > Included here:
> > Refactoring and bugfix patches in PC/ACPI.
> > New commands for ipmi.
> > Virtio optimizations.
> >
> > Signed-off-by: Michael S. Tsirkin <mst@redhat.com>  
> 
> >  roms/seabios                                       |   2 +-  
> 
> Dropped from my pull request queue because of the accidental-looking
> seabios update. Let me know if it's legit and I'll reprocess.
Pls, don't pull this request,

following commit BSODs WinXP,
"i386: populate floppy drive information in DSDT"
looks like wrong fdc geometry so far, but I'm still investigating it.

> 
> thanks
> -- PMM
> 

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT
  2016-02-04 21:54 ` [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT Michael S. Tsirkin
@ 2016-02-05 18:25   ` Igor Mammedov
  2016-02-08 13:14     ` Roman Kagan
  0 siblings, 1 reply; 75+ messages in thread
From: Igor Mammedov @ 2016-02-05 18:25 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Peter Maydell, Eduardo Habkost, qemu-devel, Roman Kagan,
	Paolo Bonzini, John Snow, Richard Henderson

On Thu, 4 Feb 2016 23:54:13 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> From: Roman Kagan <rkagan@virtuozzo.com>
> 
> On x86-based systems Linux determines the presence
> and the type of floppy drives via a query of a CMOS field.
> So does SeaBIOS when populating the return data for
> int 0x13 function 0x08.
> 
> However Windows doesn't do it. Instead, it requests
> this information from BIOS via int 0x13/0x08 or through
> ACPI objects _FDE (Floppy Drive Enumerate) and _FDI
> (Floppy Drive Information) of the floppy controller object.
> On UEFI systems only ACPI-based detection is supported.
> 
> QEMU doesn't provide those objects in its ACPI tables
> and as a result floppy drives aren't invisible to Windows
> on UEFI/OVMF.
> 
> This patch adds those objects to the floppy controller
> in DSDT, populating them with the information from
> respective QEMU objects.
> 
> Signed-off-by: Roman Kagan <rkagan@virtuozzo.com>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> ---
>  hw/i386/acpi-build.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 58 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 842c731..caa2e87 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -37,6 +37,7 @@
>  #include "hw/acpi/bios-linker-loader.h"
>  #include "hw/loader.h"
>  #include "hw/isa/isa.h"
> +#include "hw/block/fdc.h"
>  #include "hw/acpi/memory_hotplug.h"
>  #include "hw/mem/nvdimm.h"
>  #include "sysemu/tpm.h"
> @@ -1227,10 +1228,47 @@ static void build_hpet_aml(Aml *table)
>      aml_append(table, scope);
>  }
>  
> -static Aml *build_fdc_device_aml(void)
> +static Aml *build_fdinfo_aml(int idx, uint8_t type, uint8_t cylinders,
> +                             uint8_t heads, uint8_t sectors)
> +{
> +    Aml *dev, *fdi;
> +
> +    dev = aml_device("FLP%c", 'A' + idx);
> +
> +    aml_append(dev, aml_name_decl("_ADR", aml_int(idx)));
> +
> +    fdi = aml_package(0x10);
> +    aml_append(fdi, aml_int(idx));  /* Drive Number */
> +    aml_append(fdi,
> +        aml_int(cmos_get_fd_drive_type(type)));  /* Device Type */
> +    aml_append(fdi,
> +        aml_int(cylinders - 1));  /* Maximum Cylinder Number */
this puts uint64_t(-1) in AML i.e. cylinders == 0 and overflow happens here

CCing Jon


> +    aml_append(fdi, aml_int(sectors));  /* Maximum Sector Number */
> +    aml_append(fdi, aml_int(heads - 1));  /* Maximum Head Number */
> +    /* SeaBIOS returns the below values for int 0x13 func 0x08 regardless of
> +     * the drive type, so shall we */
> +    aml_append(fdi, aml_int(0xAF));  /* disk_specify_1 */
> +    aml_append(fdi, aml_int(0x02));  /* disk_specify_2 */
> +    aml_append(fdi, aml_int(0x25));  /* disk_motor_wait */
> +    aml_append(fdi, aml_int(0x02));  /* disk_sector_siz */
> +    aml_append(fdi, aml_int(0x12));  /* disk_eot */
> +    aml_append(fdi, aml_int(0x1B));  /* disk_rw_gap */
> +    aml_append(fdi, aml_int(0xFF));  /* disk_dtl */
> +    aml_append(fdi, aml_int(0x6C));  /* disk_formt_gap */
> +    aml_append(fdi, aml_int(0xF6));  /* disk_fill */
> +    aml_append(fdi, aml_int(0x0F));  /* disk_head_sttl */
> +    aml_append(fdi, aml_int(0x08));  /* disk_motor_strt */
> +
> +    aml_append(dev, aml_name_decl("_FDI", fdi));
> +    return dev;
> +}
> +
> +static Aml *build_fdc_device_aml(ISADevice *fdc)
>  {
> +    int i;
>      Aml *dev;
>      Aml *crs;
> +    uint32_t fde_buf[5] = {0, 0, 0, 0, cpu_to_le32(0x2)};
>  
>      dev = aml_device("FDC0");
>      aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0700")));
> @@ -1243,6 +1281,21 @@ static Aml *build_fdc_device_aml(void)
>          aml_dma(AML_COMPATIBILITY, AML_NOTBUSMASTER, AML_TRANSFER8, 2));
>      aml_append(dev, aml_name_decl("_CRS", crs));
>  
> +    for (i = 0; i < MAX_FD; i++) {
> +        uint8_t type = isa_fdc_get_drive_type(fdc, i);
> +
> +        if (type < FLOPPY_DRIVE_TYPE_NONE) {
> +            uint8_t cylinders, heads, sectors;
> +
> +            fde_buf[i] = cpu_to_le32(0x1);
> +            isa_fdc_get_drive_geometry(fdc, i, &cylinders, &heads, &sectors);
> +            aml_append(dev,
> +                build_fdinfo_aml(i, type, cylinders, heads, sectors));
> +        }
> +    }
> +    aml_append(dev, aml_name_decl("_FDE",
> +               aml_buffer(sizeof(fde_buf), (uint8_t *) fde_buf)));
> +
>      return dev;
>  }
>  
> @@ -1387,13 +1440,15 @@ static Aml *build_com_device_aml(uint8_t uid)
>  
>  static void build_isa_devices_aml(Aml *table)
>  {
> +    ISADevice *fdc = pc_find_fdc0();
> +
>      Aml *scope = aml_scope("_SB.PCI0.ISA");
>  
>      aml_append(scope, build_rtc_device_aml());
>      aml_append(scope, build_kbd_device_aml());
>      aml_append(scope, build_mouse_device_aml());
> -    if (!!pc_find_fdc0()) {
> -        aml_append(scope, build_fdc_device_aml());
> +    if (!!fdc) {
> +        aml_append(scope, build_fdc_device_aml(fdc));
>      }
>      aml_append(scope, build_lpt_device_aml());
>      aml_append(scope, build_com_device_aml(1));

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 06/49] virtio: move allocation to virtqueue_pop/vring_pop
  2016-02-05 12:52   ` Peter Maydell
@ 2016-02-06 18:10     ` Michael S. Tsirkin
  0 siblings, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-06 18:10 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Kevin Wolf, Gerd Hoffmann, Eduardo Habkost, Qemu-block,
	Jason Wang, QEMU Developers, Amit Shah, Aneesh Kumar K.V,
	Stefan Hajnoczi, Cornelia Huck, Paolo Bonzini, Greg Kurz

On Fri, Feb 05, 2016 at 12:52:55PM +0000, Peter Maydell wrote:
> On 4 February 2016 at 21:51, Michael S. Tsirkin <mst@redhat.com> wrote:
> > From: Paolo Bonzini <pbonzini@redhat.com>
> >
> > 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 <pbonzini@redhat.com>
> > Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
> > Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> > Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> > ---
> >  hw/9pfs/virtio-9p.h                 |  2 +-
> >  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 +-
> >  hw/9pfs/9p.c                        |  2 +-
> >  hw/9pfs/virtio-9p-device.c          | 17 ++++----
> >  hw/block/dataplane/virtio-blk.c     | 11 +++--
> >  hw/block/virtio-blk.c               | 15 +++----
> >  hw/char/virtio-serial-bus.c         | 80 +++++++++++++++++++++++--------------
> >  hw/display/virtio-gpu.c             | 21 ++++++----
> >  hw/input/virtio-input.c             | 24 +++++++----
> >  hw/net/virtio-net.c                 | 69 ++++++++++++++++++++------------
> >  hw/scsi/virtio-scsi-dataplane.c     | 15 +++----
> >  hw/scsi/virtio-scsi.c               | 18 ++++-----
> >  hw/virtio/dataplane/vring.c         | 18 +++++----
> >  hw/virtio/virtio-balloon.c          | 22 ++++++----
> >  hw/virtio/virtio-rng.c              | 10 +++--
> >  hw/virtio/virtio.c                  | 12 ++++--
> >  roms/seabios                        |  2 +-
> >  23 files changed, 210 insertions(+), 143 deletions(-)
> 
> > --- a/roms/seabios
> > +++ b/roms/seabios
> > @@ -1 +1 @@
> > -Subproject commit 01a84bea2d28a19d2405c1ecac4bdef17683cc0c
> > +Subproject commit 33fbe13a3e2a01e0ba1087a8feed801a0451db21
> > --
> > MST
> 
> Hi. This commit in this pull request includes a seabios submodule
> update, but the commit message says nothing about it. Is it
> really supposed to be here?
> 
> thanks
> -- PMM

Not sure how it got here - I didn't notice.
I'll redo the pull request.

-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT
  2016-02-05 18:25   ` Igor Mammedov
@ 2016-02-08 13:14     ` Roman Kagan
  2016-02-08 20:20       ` John Snow
  0 siblings, 1 reply; 75+ messages in thread
From: Roman Kagan @ 2016-02-08 13:14 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Peter Maydell, Eduardo Habkost, Michael S. Tsirkin, qemu-devel,
	Paolo Bonzini, John Snow, Richard Henderson

On Fri, Feb 05, 2016 at 07:25:07PM +0100, Igor Mammedov wrote:
> On Thu, 4 Feb 2016 23:54:13 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > -static Aml *build_fdc_device_aml(void)
> > +static Aml *build_fdinfo_aml(int idx, uint8_t type, uint8_t cylinders,
> > +                             uint8_t heads, uint8_t sectors)
> > +{
> > +    Aml *dev, *fdi;
> > +
> > +    dev = aml_device("FLP%c", 'A' + idx);
> > +
> > +    aml_append(dev, aml_name_decl("_ADR", aml_int(idx)));
> > +
> > +    fdi = aml_package(0x10);
> > +    aml_append(fdi, aml_int(idx));  /* Drive Number */
> > +    aml_append(fdi,
> > +        aml_int(cmos_get_fd_drive_type(type)));  /* Device Type */
> > +    aml_append(fdi,
> > +        aml_int(cylinders - 1));  /* Maximum Cylinder Number */
> this puts uint64_t(-1) in AML i.e. cylinders == 0 and overflow happens here
> 
> CCing Jon

I guess this is the effect of John's fdc rework.  I used to think zero
geometry was impossible at the time this patch was developed.

I wonder if it hasn't been fixed already by

  commit fd9bdbd3459e5b9d51534f0747049bc5b6145e07
  Author: John Snow <jsnow@redhat.com>
  Date:   Wed Feb 3 11:28:55 2016 -0500

      fdc: fix detection under Linux
      
      Accidentally, I removed a "feature" where empty drives had geometry
      values applied to them, which allows seek on empty drives to work
      "by accident," as QEMU actually tries to disallow that.
      
      Seeks on empty drives should work, though, but the easiest thing is to
      restore the misfeature where empty drives have non-zero geometries
      applied.
      
      Document the hack accordingly.
      
      [Maintainer edit]
      
      This fix corrects a regression introduced in d5d47efc, where
      pick_geometry was modified such that it would not operate on empty
      drives, and as a result if there is no diskette inserted, QEMU
      no longer populates it with geometry bounds. As a result, seek fails
      when QEMU denies to move the current track, but reports success anyway.
      This can confuse the guest, leading to kernel panics in the guest.
      
      
      Signed-off-by: John Snow <jsnow@redhat.com>
      Reviewed-by: Eric Blake <eblake@redhat.com>
      Message-id: 1454106932-17236-1-git-send-email-jsnow@redhat.com

Roman.

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT
  2016-02-08 13:14     ` Roman Kagan
@ 2016-02-08 20:20       ` John Snow
  2016-02-09 15:52         ` Roman Kagan
  0 siblings, 1 reply; 75+ messages in thread
From: John Snow @ 2016-02-08 20:20 UTC (permalink / raw)
  To: Roman Kagan, Igor Mammedov, Michael S. Tsirkin, qemu-devel,
	Peter Maydell, Eduardo Habkost, Paolo Bonzini, Richard Henderson



On 02/08/2016 08:14 AM, Roman Kagan wrote:
> On Fri, Feb 05, 2016 at 07:25:07PM +0100, Igor Mammedov wrote:
>> On Thu, 4 Feb 2016 23:54:13 +0200
>> "Michael S. Tsirkin" <mst@redhat.com> wrote:
>>> -static Aml *build_fdc_device_aml(void)
>>> +static Aml *build_fdinfo_aml(int idx, uint8_t type, uint8_t cylinders,
>>> +                             uint8_t heads, uint8_t sectors)
>>> +{
>>> +    Aml *dev, *fdi;
>>> +
>>> +    dev = aml_device("FLP%c", 'A' + idx);
>>> +
>>> +    aml_append(dev, aml_name_decl("_ADR", aml_int(idx)));
>>> +
>>> +    fdi = aml_package(0x10);
>>> +    aml_append(fdi, aml_int(idx));  /* Drive Number */
>>> +    aml_append(fdi,
>>> +        aml_int(cmos_get_fd_drive_type(type)));  /* Device Type */
>>> +    aml_append(fdi,
>>> +        aml_int(cylinders - 1));  /* Maximum Cylinder Number */
>> this puts uint64_t(-1) in AML i.e. cylinders == 0 and overflow happens here
>>
>> CCing Jon
> 
> I guess this is the effect of John's fdc rework.  I used to think zero
> geometry was impossible at the time this patch was developed.
> 
> I wonder if it hasn't been fixed already by
> 
>   commit fd9bdbd3459e5b9d51534f0747049bc5b6145e07
>   Author: John Snow <jsnow@redhat.com>
>   Date:   Wed Feb 3 11:28:55 2016 -0500
> 
>       fdc: fix detection under Linux
>       
>       Accidentally, I removed a "feature" where empty drives had geometry
>       values applied to them, which allows seek on empty drives to work
>       "by accident," as QEMU actually tries to disallow that.
>       
>       Seeks on empty drives should work, though, but the easiest thing is to
>       restore the misfeature where empty drives have non-zero geometries
>       applied.
>       
>       Document the hack accordingly.
>       
>       [Maintainer edit]
>       
>       This fix corrects a regression introduced in d5d47efc, where
>       pick_geometry was modified such that it would not operate on empty
>       drives, and as a result if there is no diskette inserted, QEMU
>       no longer populates it with geometry bounds. As a result, seek fails
>       when QEMU denies to move the current track, but reports success anyway.
>       This can confuse the guest, leading to kernel panics in the guest.
>       
>       
>       Signed-off-by: John Snow <jsnow@redhat.com>
>       Reviewed-by: Eric Blake <eblake@redhat.com>
>       Message-id: 1454106932-17236-1-git-send-email-jsnow@redhat.com
> 
> Roman.
> 

Yes, hopefully solved on my end. The geometry values for an empty disk
are not well defined (they certainly don't have any *meaning*) so if you
are populating tables based on an empty drive, I just hope you also have
the mechanisms needed to update said tables when the media changes.

What do the guests use these values for? Are they fixed at boot?

--js

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT
  2016-02-08 20:20       ` John Snow
@ 2016-02-09 15:52         ` Roman Kagan
  2016-02-09 16:22           ` John Snow
  0 siblings, 1 reply; 75+ messages in thread
From: Roman Kagan @ 2016-02-09 15:52 UTC (permalink / raw)
  To: John Snow
  Cc: Peter Maydell, Eduardo Habkost, Michael S. Tsirkin, qemu-devel,
	Paolo Bonzini, Igor Mammedov, Richard Henderson

On Mon, Feb 08, 2016 at 03:20:47PM -0500, John Snow wrote:
> On 02/08/2016 08:14 AM, Roman Kagan wrote:
> > On Fri, Feb 05, 2016 at 07:25:07PM +0100, Igor Mammedov wrote:
> >>> +    aml_append(fdi,
> >>> +        aml_int(cylinders - 1));  /* Maximum Cylinder Number */
> >> this puts uint64_t(-1) in AML i.e. cylinders == 0 and overflow happens here
> >>
> >> CCing Jon
> > 
> > I guess this is the effect of John's fdc rework.  I used to think zero
> > geometry was impossible at the time this patch was developed.
> > 
> > I wonder if it hasn't been fixed already by
> > 
> >   commit fd9bdbd3459e5b9d51534f0747049bc5b6145e07
> >   Author: John Snow <jsnow@redhat.com>
> >   Date:   Wed Feb 3 11:28:55 2016 -0500
> > 
> >       fdc: fix detection under Linux
> 
> Yes, hopefully solved on my end. The geometry values for an empty disk
> are not well defined (they certainly don't have any *meaning*) so if you
> are populating tables based on an empty drive, I just hope you also have
> the mechanisms needed to update said tables when the media changes.

I don't.  At the time the patch was developed there basically were no
mechanisms to update the geometry at all (and this was what you patchset
addressed, in particular, wasn't it?) so I didn't care.

Now if it actually has to be fully dynamic it's gonna be more
involved...

> What do the guests use these values for? Are they fixed at boot?

Only Windows guests use it so it's hard to tell.  I can only claim that
if I stick bogus values into that ACPI object the guest fails to read
the floppy.

Roman.

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT
  2016-02-09 15:52         ` Roman Kagan
@ 2016-02-09 16:22           ` John Snow
  2016-02-09 18:36             ` Laszlo Ersek
  2016-02-10 16:57             ` Roman Kagan
  0 siblings, 2 replies; 75+ messages in thread
From: John Snow @ 2016-02-09 16:22 UTC (permalink / raw)
  To: Roman Kagan, Igor Mammedov, Michael S. Tsirkin, qemu-devel,
	Peter Maydell, Eduardo Habkost, Paolo Bonzini, Richard Henderson



On 02/09/2016 10:52 AM, Roman Kagan wrote:
> On Mon, Feb 08, 2016 at 03:20:47PM -0500, John Snow wrote:
>> On 02/08/2016 08:14 AM, Roman Kagan wrote:
>>> On Fri, Feb 05, 2016 at 07:25:07PM +0100, Igor Mammedov wrote:
>>>>> +    aml_append(fdi,
>>>>> +        aml_int(cylinders - 1));  /* Maximum Cylinder Number */
>>>> this puts uint64_t(-1) in AML i.e. cylinders == 0 and overflow happens here
>>>>
>>>> CCing Jon
>>>
>>> I guess this is the effect of John's fdc rework.  I used to think zero
>>> geometry was impossible at the time this patch was developed.
>>>
>>> I wonder if it hasn't been fixed already by
>>>
>>>   commit fd9bdbd3459e5b9d51534f0747049bc5b6145e07
>>>   Author: John Snow <jsnow@redhat.com>
>>>   Date:   Wed Feb 3 11:28:55 2016 -0500
>>>
>>>       fdc: fix detection under Linux
>>
>> Yes, hopefully solved on my end. The geometry values for an empty disk
>> are not well defined (they certainly don't have any *meaning*) so if you
>> are populating tables based on an empty drive, I just hope you also have
>> the mechanisms needed to update said tables when the media changes.
> 
> I don't.  At the time the patch was developed there basically were no
> mechanisms to update the geometry at all (and this was what you patchset
> addressed, in particular, wasn't it?) so I didn't care.
> 

That's not true.

You could swap different 1.44MB-class diskettes for other geometries,
check this out:

static const FDFormat fd_formats[] = {
    /* First entry is default format */
    /* 1.44 MB 3"1/2 floppy disks */
    { FDRIVE_DRV_144, 18, 80, 1, FDRIVE_RATE_500K, },
    { FDRIVE_DRV_144, 20, 80, 1, FDRIVE_RATE_500K, },
    { FDRIVE_DRV_144, 21, 80, 1, FDRIVE_RATE_500K, },
    { FDRIVE_DRV_144, 21, 82, 1, FDRIVE_RATE_500K, },
    { FDRIVE_DRV_144, 21, 83, 1, FDRIVE_RATE_500K, },
    { FDRIVE_DRV_144, 22, 80, 1, FDRIVE_RATE_500K, },
    { FDRIVE_DRV_144, 23, 80, 1, FDRIVE_RATE_500K, },
    { FDRIVE_DRV_144, 24, 80, 1, FDRIVE_RATE_500K, },
...

You absolutely could get different sector and track counts before my
patchset.


> Now if it actually has to be fully dynamic it's gonna be more
> involved...
> 
>> What do the guests use these values for? Are they fixed at boot?
> 
> Only Windows guests use it so it's hard to tell.  I can only claim that
> if I stick bogus values into that ACPI object the guest fails to read
> the floppy.
> 
> Roman.
> 

-- 
—js

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT
  2016-02-09 16:22           ` John Snow
@ 2016-02-09 18:36             ` Laszlo Ersek
  2016-02-09 18:48               ` Michael S. Tsirkin
                                 ` (2 more replies)
  2016-02-10 16:57             ` Roman Kagan
  1 sibling, 3 replies; 75+ messages in thread
From: Laszlo Ersek @ 2016-02-09 18:36 UTC (permalink / raw)
  To: Roman Kagan
  Cc: Peter Maydell, Eduardo Habkost, Michael S. Tsirkin, qemu-devel,
	Paolo Bonzini, Igor Mammedov, John Snow, Richard Henderson

On 02/09/16 17:22, John Snow wrote:
> 
> 
> On 02/09/2016 10:52 AM, Roman Kagan wrote:
>> On Mon, Feb 08, 2016 at 03:20:47PM -0500, John Snow wrote:
>>> On 02/08/2016 08:14 AM, Roman Kagan wrote:
>>>> On Fri, Feb 05, 2016 at 07:25:07PM +0100, Igor Mammedov wrote:
>>>>>> +    aml_append(fdi,
>>>>>> +        aml_int(cylinders - 1));  /* Maximum Cylinder Number */
>>>>> this puts uint64_t(-1) in AML i.e. cylinders == 0 and overflow happens here
>>>>>
>>>>> CCing Jon
>>>>
>>>> I guess this is the effect of John's fdc rework.  I used to think zero
>>>> geometry was impossible at the time this patch was developed.
>>>>
>>>> I wonder if it hasn't been fixed already by
>>>>
>>>>   commit fd9bdbd3459e5b9d51534f0747049bc5b6145e07
>>>>   Author: John Snow <jsnow@redhat.com>
>>>>   Date:   Wed Feb 3 11:28:55 2016 -0500
>>>>
>>>>       fdc: fix detection under Linux
>>>
>>> Yes, hopefully solved on my end. The geometry values for an empty disk
>>> are not well defined (they certainly don't have any *meaning*) so if you
>>> are populating tables based on an empty drive, I just hope you also have
>>> the mechanisms needed to update said tables when the media changes.
>>
>> I don't.  At the time the patch was developed there basically were no
>> mechanisms to update the geometry at all (and this was what you patchset
>> addressed, in particular, wasn't it?) so I didn't care.
>>
> 
> That's not true.
> 
> You could swap different 1.44MB-class diskettes for other geometries,
> check this out:
> 
> static const FDFormat fd_formats[] = {
>     /* First entry is default format */
>     /* 1.44 MB 3"1/2 floppy disks */
>     { FDRIVE_DRV_144, 18, 80, 1, FDRIVE_RATE_500K, },
>     { FDRIVE_DRV_144, 20, 80, 1, FDRIVE_RATE_500K, },
>     { FDRIVE_DRV_144, 21, 80, 1, FDRIVE_RATE_500K, },
>     { FDRIVE_DRV_144, 21, 82, 1, FDRIVE_RATE_500K, },
>     { FDRIVE_DRV_144, 21, 83, 1, FDRIVE_RATE_500K, },
>     { FDRIVE_DRV_144, 22, 80, 1, FDRIVE_RATE_500K, },
>     { FDRIVE_DRV_144, 23, 80, 1, FDRIVE_RATE_500K, },
>     { FDRIVE_DRV_144, 24, 80, 1, FDRIVE_RATE_500K, },
> ...
> 
> You absolutely could get different sector and track counts before my
> patchset.
> 
> 
>> Now if it actually has to be fully dynamic it's gonna be more
>> involved...
>>
>>> What do the guests use these values for? Are they fixed at boot?
>>
>> Only Windows guests use it so it's hard to tell.  I can only claim that
>> if I stick bogus values into that ACPI object the guest fails to read
>> the floppy.

We discussed this with John a bit on IRC.

In my opinion, the real mess in this case is in the ACPI spec itself. If
you re-read the _FDI control method's description, the Package that it
returns contains *dynamic* geometry data, about the *disk* (not *drive*):

- Maximum Cylinder Number // Integer (WORD)
- Maximum Sector Number   // Integer (WORD)
- Maximum Head Number     // Integer (WORD)

What this seems to require is: the firmware developer should write ACPI
code that
- dynamically accesses the floppy drive / controller (using MMIO or IO
  port registers),
- retrieves the geometry of the disk actually inserted,
- and returns the data nicely packaged.

In effect, an ACPI-level driver for the disk.

Now, John explained to me (and please keep in mind that this is my
personal account of his explanation, not a factual rendering thereof),
that there used to be no *standard* way to interrogate the current
disk's geometry, other than trial and error with seeking.

Apparently in UEFI Windows, Microsoft didn't want to implement this
trial and error seeking, so -- given there was also no portable
*hardware spec* to retrieve the same data, directly from the disk drive
or controller -- they punted the entire question to ACPI. That is, to
the firmware implementor.

This is entirely bogus. For one, it ties the platform firmware (the UEFI
binary in the flash chip on your motherboard) to your specific floppy
drive / controller. Say good-bye to any independently bought & installed
floppy drives.

In theory, a floppy controller that comes with a separate PCI card could
offer an option ROM with a UEFI driver in it, and that UEFI driver could
install a separate SSDT with the hardware-matching _FDI in it. Still an
unreasonable requirement, given that the *only* way Windows can be
installed unattended (with external device drivers) is to provide those
drivers on a floppy. Because, end-to-end,

  do you want unattended UEFI installation with 3rd party drivers?

translates to

  better have a PCI-based floppy controller such that its oprom
  installs an _FDI with dynamic hardware access,
  *or* have your platform firmware match your floppy hardware

Implementing this in QEMU would require:
- inventing virt-only registers for the FDC that provide the current
disk geometry,
- and generating AML code that reads those registers

*or*

- implementing the trial and error seeking in AML

Waste of time, don't do it. Microsoft have never documented their usage
of _FDI. (Their forums are full of confused users whose physical floppy
drives don't work under UEFI Windows!)

I'm quite sure the _FDI addition in the ACPI spec is actually from
Microsoft as well, but of course the *reasoning* / background for _FDI
is also not public. Microsoft seem to push stuff into the ACPI spec that
serves them, while conveniently ignoring non-optional parts of the spec
that they don't feel like supporting (I'm looking at you,
DataTableRegion). And their level of support is not public.

So, the last paragraph of Roman's email
<http://thread.gmane.org/gmane.comp.emulators.qemu.block/7978/focus=8081> remains
relevant -- do whatever ugly static hack is necessary in QEMU's AML
generator to restore the one use case to working state that matters:
unattended installation to a virtio disk.

Noone in their right mind uses floppy in the guest interactively, and
even for the unattended installation, floppy is used only because
Windows is too stupid to work off a CD-ROM fully automatically. (Where
everything one needs would be interrogable from on hardware / ATAPI / SCSI.)

IMHO, do the *absolute minimum* to adapt this AML generation patch to
John's FDC rework, and ignore all dynamic aspects (like media change).

Thanks
Laszlo

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT
  2016-02-09 18:36             ` Laszlo Ersek
@ 2016-02-09 18:48               ` Michael S. Tsirkin
  2016-02-10 16:14                 ` John Snow
  2016-02-10 17:10               ` Roman Kagan
  2016-02-13 17:26               ` Kevin O'Connor
  2 siblings, 1 reply; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-09 18:48 UTC (permalink / raw)
  To: Laszlo Ersek
  Cc: Peter Maydell, Eduardo Habkost, qemu-devel, Roman Kagan,
	Paolo Bonzini, Igor Mammedov, John Snow, Richard Henderson

On Tue, Feb 09, 2016 at 07:36:12PM +0100, Laszlo Ersek wrote:
> On 02/09/16 17:22, John Snow wrote:
> > 
> > 
> > On 02/09/2016 10:52 AM, Roman Kagan wrote:
> >> On Mon, Feb 08, 2016 at 03:20:47PM -0500, John Snow wrote:
> >>> On 02/08/2016 08:14 AM, Roman Kagan wrote:
> >>>> On Fri, Feb 05, 2016 at 07:25:07PM +0100, Igor Mammedov wrote:
> >>>>>> +    aml_append(fdi,
> >>>>>> +        aml_int(cylinders - 1));  /* Maximum Cylinder Number */
> >>>>> this puts uint64_t(-1) in AML i.e. cylinders == 0 and overflow happens here
> >>>>>
> >>>>> CCing Jon
> >>>>
> >>>> I guess this is the effect of John's fdc rework.  I used to think zero
> >>>> geometry was impossible at the time this patch was developed.
> >>>>
> >>>> I wonder if it hasn't been fixed already by
> >>>>
> >>>>   commit fd9bdbd3459e5b9d51534f0747049bc5b6145e07
> >>>>   Author: John Snow <jsnow@redhat.com>
> >>>>   Date:   Wed Feb 3 11:28:55 2016 -0500
> >>>>
> >>>>       fdc: fix detection under Linux
> >>>
> >>> Yes, hopefully solved on my end. The geometry values for an empty disk
> >>> are not well defined (they certainly don't have any *meaning*) so if you
> >>> are populating tables based on an empty drive, I just hope you also have
> >>> the mechanisms needed to update said tables when the media changes.
> >>
> >> I don't.  At the time the patch was developed there basically were no
> >> mechanisms to update the geometry at all (and this was what you patchset
> >> addressed, in particular, wasn't it?) so I didn't care.
> >>
> > 
> > That's not true.
> > 
> > You could swap different 1.44MB-class diskettes for other geometries,
> > check this out:
> > 
> > static const FDFormat fd_formats[] = {
> >     /* First entry is default format */
> >     /* 1.44 MB 3"1/2 floppy disks */
> >     { FDRIVE_DRV_144, 18, 80, 1, FDRIVE_RATE_500K, },
> >     { FDRIVE_DRV_144, 20, 80, 1, FDRIVE_RATE_500K, },
> >     { FDRIVE_DRV_144, 21, 80, 1, FDRIVE_RATE_500K, },
> >     { FDRIVE_DRV_144, 21, 82, 1, FDRIVE_RATE_500K, },
> >     { FDRIVE_DRV_144, 21, 83, 1, FDRIVE_RATE_500K, },
> >     { FDRIVE_DRV_144, 22, 80, 1, FDRIVE_RATE_500K, },
> >     { FDRIVE_DRV_144, 23, 80, 1, FDRIVE_RATE_500K, },
> >     { FDRIVE_DRV_144, 24, 80, 1, FDRIVE_RATE_500K, },
> > ...
> > 
> > You absolutely could get different sector and track counts before my
> > patchset.
> > 
> > 
> >> Now if it actually has to be fully dynamic it's gonna be more
> >> involved...
> >>
> >>> What do the guests use these values for? Are they fixed at boot?
> >>
> >> Only Windows guests use it so it's hard to tell.  I can only claim that
> >> if I stick bogus values into that ACPI object the guest fails to read
> >> the floppy.
> 
> We discussed this with John a bit on IRC.
> 
> In my opinion, the real mess in this case is in the ACPI spec itself. If
> you re-read the _FDI control method's description, the Package that it
> returns contains *dynamic* geometry data, about the *disk* (not *drive*):
> 
> - Maximum Cylinder Number // Integer (WORD)
> - Maximum Sector Number   // Integer (WORD)
> - Maximum Head Number     // Integer (WORD)
> 
> What this seems to require is: the firmware developer should write ACPI
> code that
> - dynamically accesses the floppy drive / controller (using MMIO or IO
>   port registers),
> - retrieves the geometry of the disk actually inserted,
> - and returns the data nicely packaged.
> 
> In effect, an ACPI-level driver for the disk.
> 
> Now, John explained to me (and please keep in mind that this is my
> personal account of his explanation, not a factual rendering thereof),
> that there used to be no *standard* way to interrogate the current
> disk's geometry, other than trial and error with seeking.
> 
> Apparently in UEFI Windows, Microsoft didn't want to implement this
> trial and error seeking, so -- given there was also no portable
> *hardware spec* to retrieve the same data, directly from the disk drive
> or controller -- they punted the entire question to ACPI. That is, to
> the firmware implementor.
> 
> This is entirely bogus. For one, it ties the platform firmware (the UEFI
> binary in the flash chip on your motherboard) to your specific floppy
> drive / controller. Say good-bye to any independently bought & installed
> floppy drives.
> 
> In theory, a floppy controller that comes with a separate PCI card could
> offer an option ROM with a UEFI driver in it, and that UEFI driver could
> install a separate SSDT with the hardware-matching _FDI in it. Still an
> unreasonable requirement, given that the *only* way Windows can be
> installed unattended (with external device drivers) is to provide those
> drivers on a floppy. Because, end-to-end,
> 
>   do you want unattended UEFI installation with 3rd party drivers?
> 
> translates to
> 
>   better have a PCI-based floppy controller such that its oprom
>   installs an _FDI with dynamic hardware access,
>   *or* have your platform firmware match your floppy hardware
> 
> Implementing this in QEMU would require:
> - inventing virt-only registers for the FDC that provide the current
> disk geometry,
> - and generating AML code that reads those registers
> 
> *or*
> 
> - implementing the trial and error seeking in AML
> 
> Waste of time, don't do it. Microsoft have never documented their usage
> of _FDI. (Their forums are full of confused users whose physical floppy
> drives don't work under UEFI Windows!)
> 
> I'm quite sure the _FDI addition in the ACPI spec is actually from
> Microsoft as well, but of course the *reasoning* / background for _FDI
> is also not public. Microsoft seem to push stuff into the ACPI spec that
> serves them, while conveniently ignoring non-optional parts of the spec
> that they don't feel like supporting (I'm looking at you,
> DataTableRegion). And their level of support is not public.
> 
> So, the last paragraph of Roman's email
> <http://thread.gmane.org/gmane.comp.emulators.qemu.block/7978/focus=8081> remains
> relevant -- do whatever ugly static hack is necessary in QEMU's AML
> generator to restore the one use case to working state that matters:
> unattended installation to a virtio disk.
> 
> Noone in their right mind uses floppy in the guest interactively, and
> even for the unattended installation, floppy is used only because
> Windows is too stupid to work off a CD-ROM fully automatically. (Where
> everything one needs would be interrogable from on hardware / ATAPI / SCSI.)
> 
> IMHO, do the *absolute minimum* to adapt this AML generation patch to
> John's FDC rework, and ignore all dynamic aspects (like media change).
> 
> Thanks
> Laszlo

I'm fine with reporting some static values that make windows work fine.
What I think is wrong is reporting geometry that happens to
match current windows.

-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT
  2016-02-09 18:48               ` Michael S. Tsirkin
@ 2016-02-10 16:14                 ` John Snow
  2016-02-10 16:48                   ` Michael S. Tsirkin
  2016-02-10 17:24                   ` Roman Kagan
  0 siblings, 2 replies; 75+ messages in thread
From: John Snow @ 2016-02-10 16:14 UTC (permalink / raw)
  To: Michael S. Tsirkin, Laszlo Ersek
  Cc: Peter Maydell, Eduardo Habkost, qemu-devel, Roman Kagan,
	Paolo Bonzini, Igor Mammedov, Richard Henderson



On 02/09/2016 01:48 PM, Michael S. Tsirkin wrote:
> On Tue, Feb 09, 2016 at 07:36:12PM +0100, Laszlo Ersek wrote:
>> On 02/09/16 17:22, John Snow wrote:
>>>
>>>
>>> On 02/09/2016 10:52 AM, Roman Kagan wrote:
>>>> On Mon, Feb 08, 2016 at 03:20:47PM -0500, John Snow wrote:
>>>>> On 02/08/2016 08:14 AM, Roman Kagan wrote:
>>>>>> On Fri, Feb 05, 2016 at 07:25:07PM +0100, Igor Mammedov wrote:
>>>>>>>> +    aml_append(fdi,
>>>>>>>> +        aml_int(cylinders - 1));  /* Maximum Cylinder Number */
>>>>>>> this puts uint64_t(-1) in AML i.e. cylinders == 0 and overflow happens here
>>>>>>>
>>>>>>> CCing Jon
>>>>>>
>>>>>> I guess this is the effect of John's fdc rework.  I used to think zero
>>>>>> geometry was impossible at the time this patch was developed.
>>>>>>
>>>>>> I wonder if it hasn't been fixed already by
>>>>>>
>>>>>>   commit fd9bdbd3459e5b9d51534f0747049bc5b6145e07
>>>>>>   Author: John Snow <jsnow@redhat.com>
>>>>>>   Date:   Wed Feb 3 11:28:55 2016 -0500
>>>>>>
>>>>>>       fdc: fix detection under Linux
>>>>>
>>>>> Yes, hopefully solved on my end. The geometry values for an empty disk
>>>>> are not well defined (they certainly don't have any *meaning*) so if you
>>>>> are populating tables based on an empty drive, I just hope you also have
>>>>> the mechanisms needed to update said tables when the media changes.
>>>>
>>>> I don't.  At the time the patch was developed there basically were no
>>>> mechanisms to update the geometry at all (and this was what you patchset
>>>> addressed, in particular, wasn't it?) so I didn't care.
>>>>
>>>
>>> That's not true.
>>>
>>> You could swap different 1.44MB-class diskettes for other geometries,
>>> check this out:
>>>
>>> static const FDFormat fd_formats[] = {
>>>     /* First entry is default format */
>>>     /* 1.44 MB 3"1/2 floppy disks */
>>>     { FDRIVE_DRV_144, 18, 80, 1, FDRIVE_RATE_500K, },
>>>     { FDRIVE_DRV_144, 20, 80, 1, FDRIVE_RATE_500K, },
>>>     { FDRIVE_DRV_144, 21, 80, 1, FDRIVE_RATE_500K, },
>>>     { FDRIVE_DRV_144, 21, 82, 1, FDRIVE_RATE_500K, },
>>>     { FDRIVE_DRV_144, 21, 83, 1, FDRIVE_RATE_500K, },
>>>     { FDRIVE_DRV_144, 22, 80, 1, FDRIVE_RATE_500K, },
>>>     { FDRIVE_DRV_144, 23, 80, 1, FDRIVE_RATE_500K, },
>>>     { FDRIVE_DRV_144, 24, 80, 1, FDRIVE_RATE_500K, },
>>> ...
>>>
>>> You absolutely could get different sector and track counts before my
>>> patchset.
>>>
>>>
>>>> Now if it actually has to be fully dynamic it's gonna be more
>>>> involved...
>>>>
>>>>> What do the guests use these values for? Are they fixed at boot?
>>>>
>>>> Only Windows guests use it so it's hard to tell.  I can only claim that
>>>> if I stick bogus values into that ACPI object the guest fails to read
>>>> the floppy.
>>
>> We discussed this with John a bit on IRC.
>>
>> In my opinion, the real mess in this case is in the ACPI spec itself. If
>> you re-read the _FDI control method's description, the Package that it
>> returns contains *dynamic* geometry data, about the *disk* (not *drive*):
>>
>> - Maximum Cylinder Number // Integer (WORD)
>> - Maximum Sector Number   // Integer (WORD)
>> - Maximum Head Number     // Integer (WORD)
>>
>> What this seems to require is: the firmware developer should write ACPI
>> code that
>> - dynamically accesses the floppy drive / controller (using MMIO or IO
>>   port registers),
>> - retrieves the geometry of the disk actually inserted,
>> - and returns the data nicely packaged.
>>
>> In effect, an ACPI-level driver for the disk.
>>
>> Now, John explained to me (and please keep in mind that this is my
>> personal account of his explanation, not a factual rendering thereof),
>> that there used to be no *standard* way to interrogate the current
>> disk's geometry, other than trial and error with seeking.
>>

At the very least, the Intel 82078 does not appear to be capable of
replying to any query with a CHS triplet. It *can* report back the total
number of sectors and the size of each sector, but that still requires
geometry guesswork outside of the drive.

>> Apparently in UEFI Windows, Microsoft didn't want to implement this
>> trial and error seeking, so -- given there was also no portable
>> *hardware spec* to retrieve the same data, directly from the disk drive
>> or controller -- they punted the entire question to ACPI. That is, to
>> the firmware implementor.
>>
>> This is entirely bogus. For one, it ties the platform firmware (the UEFI
>> binary in the flash chip on your motherboard) to your specific floppy
>> drive / controller. Say good-bye to any independently bought & installed
>> floppy drives.
>>
>> In theory, a floppy controller that comes with a separate PCI card could
>> offer an option ROM with a UEFI driver in it, and that UEFI driver could
>> install a separate SSDT with the hardware-matching _FDI in it. Still an
>> unreasonable requirement, given that the *only* way Windows can be
>> installed unattended (with external device drivers) is to provide those
>> drivers on a floppy. Because, end-to-end,
>>
>>   do you want unattended UEFI installation with 3rd party drivers?
>>
>> translates to
>>
>>   better have a PCI-based floppy controller such that its oprom
>>   installs an _FDI with dynamic hardware access,
>>   *or* have your platform firmware match your floppy hardware
>>
>> Implementing this in QEMU would require:
>> - inventing virt-only registers for the FDC that provide the current
>> disk geometry,

We do secretly have these registers, but of course there's no spec to
interpreting what they mean. For instance, what do they read when the
drive is empty? I am not sure that information is codified in the ACPI spec.

Could be wrong, you seemed to indicate that the ACPI spec said that the
info matches what you get from a certain legacy bios routine, but I
don't know the specifics of that routine, either.

>> - and generating AML code that reads those registers
>>
>> *or*
>>
>> - implementing the trial and error seeking in AML
>>
>> Waste of time, don't do it. Microsoft have never documented their usage
>> of _FDI. (Their forums are full of confused users whose physical floppy
>> drives don't work under UEFI Windows!)
>>
>> I'm quite sure the _FDI addition in the ACPI spec is actually from
>> Microsoft as well, but of course the *reasoning* / background for _FDI
>> is also not public. Microsoft seem to push stuff into the ACPI spec that
>> serves them, while conveniently ignoring non-optional parts of the spec
>> that they don't feel like supporting (I'm looking at you,
>> DataTableRegion). And their level of support is not public.
>>
>> So, the last paragraph of Roman's email
>> <http://thread.gmane.org/gmane.comp.emulators.qemu.block/7978/focus=8081> remains
>> relevant -- do whatever ugly static hack is necessary in QEMU's AML
>> generator to restore the one use case to working state that matters:
>> unattended installation to a virtio disk.
>>
>> Noone in their right mind uses floppy in the guest interactively, and
>> even for the unattended installation, floppy is used only because
>> Windows is too stupid to work off a CD-ROM fully automatically. (Where
>> everything one needs would be interrogable from on hardware / ATAPI / SCSI.)
>>
>> IMHO, do the *absolute minimum* to adapt this AML generation patch to
>> John's FDC rework, and ignore all dynamic aspects (like media change).
>>
>> Thanks
>> Laszlo
> 
> I'm fine with reporting some static values that make windows work fine.
> What I think is wrong is reporting geometry that happens to
> match current windows.
> 

Can you rephrase that last sentence? I don't follow, I'm sorry.


Roman, does the 0xFF "empty disk geometry" hack appear to work for
Windows 10?

Maybe it's fine enough as-is, as per Laszlo's good synopsis here.

--js

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT
  2016-02-10 16:14                 ` John Snow
@ 2016-02-10 16:48                   ` Michael S. Tsirkin
  2016-02-10 17:24                   ` Roman Kagan
  1 sibling, 0 replies; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-10 16:48 UTC (permalink / raw)
  To: John Snow
  Cc: Peter Maydell, Eduardo Habkost, qemu-devel, Roman Kagan,
	Paolo Bonzini, Igor Mammedov, Laszlo Ersek, Richard Henderson

On Wed, Feb 10, 2016 at 11:14:30AM -0500, John Snow wrote:
> 
> 
> On 02/09/2016 01:48 PM, Michael S. Tsirkin wrote:
> > On Tue, Feb 09, 2016 at 07:36:12PM +0100, Laszlo Ersek wrote:
> >> On 02/09/16 17:22, John Snow wrote:
> >>>
> >>>
> >>> On 02/09/2016 10:52 AM, Roman Kagan wrote:
> >>>> On Mon, Feb 08, 2016 at 03:20:47PM -0500, John Snow wrote:
> >>>>> On 02/08/2016 08:14 AM, Roman Kagan wrote:
> >>>>>> On Fri, Feb 05, 2016 at 07:25:07PM +0100, Igor Mammedov wrote:
> >>>>>>>> +    aml_append(fdi,
> >>>>>>>> +        aml_int(cylinders - 1));  /* Maximum Cylinder Number */
> >>>>>>> this puts uint64_t(-1) in AML i.e. cylinders == 0 and overflow happens here
> >>>>>>>
> >>>>>>> CCing Jon
> >>>>>>
> >>>>>> I guess this is the effect of John's fdc rework.  I used to think zero
> >>>>>> geometry was impossible at the time this patch was developed.
> >>>>>>
> >>>>>> I wonder if it hasn't been fixed already by
> >>>>>>
> >>>>>>   commit fd9bdbd3459e5b9d51534f0747049bc5b6145e07
> >>>>>>   Author: John Snow <jsnow@redhat.com>
> >>>>>>   Date:   Wed Feb 3 11:28:55 2016 -0500
> >>>>>>
> >>>>>>       fdc: fix detection under Linux
> >>>>>
> >>>>> Yes, hopefully solved on my end. The geometry values for an empty disk
> >>>>> are not well defined (they certainly don't have any *meaning*) so if you
> >>>>> are populating tables based on an empty drive, I just hope you also have
> >>>>> the mechanisms needed to update said tables when the media changes.
> >>>>
> >>>> I don't.  At the time the patch was developed there basically were no
> >>>> mechanisms to update the geometry at all (and this was what you patchset
> >>>> addressed, in particular, wasn't it?) so I didn't care.
> >>>>
> >>>
> >>> That's not true.
> >>>
> >>> You could swap different 1.44MB-class diskettes for other geometries,
> >>> check this out:
> >>>
> >>> static const FDFormat fd_formats[] = {
> >>>     /* First entry is default format */
> >>>     /* 1.44 MB 3"1/2 floppy disks */
> >>>     { FDRIVE_DRV_144, 18, 80, 1, FDRIVE_RATE_500K, },
> >>>     { FDRIVE_DRV_144, 20, 80, 1, FDRIVE_RATE_500K, },
> >>>     { FDRIVE_DRV_144, 21, 80, 1, FDRIVE_RATE_500K, },
> >>>     { FDRIVE_DRV_144, 21, 82, 1, FDRIVE_RATE_500K, },
> >>>     { FDRIVE_DRV_144, 21, 83, 1, FDRIVE_RATE_500K, },
> >>>     { FDRIVE_DRV_144, 22, 80, 1, FDRIVE_RATE_500K, },
> >>>     { FDRIVE_DRV_144, 23, 80, 1, FDRIVE_RATE_500K, },
> >>>     { FDRIVE_DRV_144, 24, 80, 1, FDRIVE_RATE_500K, },
> >>> ...
> >>>
> >>> You absolutely could get different sector and track counts before my
> >>> patchset.
> >>>
> >>>
> >>>> Now if it actually has to be fully dynamic it's gonna be more
> >>>> involved...
> >>>>
> >>>>> What do the guests use these values for? Are they fixed at boot?
> >>>>
> >>>> Only Windows guests use it so it's hard to tell.  I can only claim that
> >>>> if I stick bogus values into that ACPI object the guest fails to read
> >>>> the floppy.
> >>
> >> We discussed this with John a bit on IRC.
> >>
> >> In my opinion, the real mess in this case is in the ACPI spec itself. If
> >> you re-read the _FDI control method's description, the Package that it
> >> returns contains *dynamic* geometry data, about the *disk* (not *drive*):
> >>
> >> - Maximum Cylinder Number // Integer (WORD)
> >> - Maximum Sector Number   // Integer (WORD)
> >> - Maximum Head Number     // Integer (WORD)
> >>
> >> What this seems to require is: the firmware developer should write ACPI
> >> code that
> >> - dynamically accesses the floppy drive / controller (using MMIO or IO
> >>   port registers),
> >> - retrieves the geometry of the disk actually inserted,
> >> - and returns the data nicely packaged.
> >>
> >> In effect, an ACPI-level driver for the disk.
> >>
> >> Now, John explained to me (and please keep in mind that this is my
> >> personal account of his explanation, not a factual rendering thereof),
> >> that there used to be no *standard* way to interrogate the current
> >> disk's geometry, other than trial and error with seeking.
> >>
> 
> At the very least, the Intel 82078 does not appear to be capable of
> replying to any query with a CHS triplet. It *can* report back the total
> number of sectors and the size of each sector, but that still requires
> geometry guesswork outside of the drive.
> 
> >> Apparently in UEFI Windows, Microsoft didn't want to implement this
> >> trial and error seeking, so -- given there was also no portable
> >> *hardware spec* to retrieve the same data, directly from the disk drive
> >> or controller -- they punted the entire question to ACPI. That is, to
> >> the firmware implementor.
> >>
> >> This is entirely bogus. For one, it ties the platform firmware (the UEFI
> >> binary in the flash chip on your motherboard) to your specific floppy
> >> drive / controller. Say good-bye to any independently bought & installed
> >> floppy drives.
> >>
> >> In theory, a floppy controller that comes with a separate PCI card could
> >> offer an option ROM with a UEFI driver in it, and that UEFI driver could
> >> install a separate SSDT with the hardware-matching _FDI in it. Still an
> >> unreasonable requirement, given that the *only* way Windows can be
> >> installed unattended (with external device drivers) is to provide those
> >> drivers on a floppy. Because, end-to-end,
> >>
> >>   do you want unattended UEFI installation with 3rd party drivers?
> >>
> >> translates to
> >>
> >>   better have a PCI-based floppy controller such that its oprom
> >>   installs an _FDI with dynamic hardware access,
> >>   *or* have your platform firmware match your floppy hardware
> >>
> >> Implementing this in QEMU would require:
> >> - inventing virt-only registers for the FDC that provide the current
> >> disk geometry,
> 
> We do secretly have these registers, but of course there's no spec to
> interpreting what they mean. For instance, what do they read when the
> drive is empty? I am not sure that information is codified in the ACPI spec.
> 
> Could be wrong, you seemed to indicate that the ACPI spec said that the
> info matches what you get from a certain legacy bios routine, but I
> don't know the specifics of that routine, either.
> 
> >> - and generating AML code that reads those registers
> >>
> >> *or*
> >>
> >> - implementing the trial and error seeking in AML
> >>
> >> Waste of time, don't do it. Microsoft have never documented their usage
> >> of _FDI. (Their forums are full of confused users whose physical floppy
> >> drives don't work under UEFI Windows!)
> >>
> >> I'm quite sure the _FDI addition in the ACPI spec is actually from
> >> Microsoft as well, but of course the *reasoning* / background for _FDI
> >> is also not public. Microsoft seem to push stuff into the ACPI spec that
> >> serves them, while conveniently ignoring non-optional parts of the spec
> >> that they don't feel like supporting (I'm looking at you,
> >> DataTableRegion). And their level of support is not public.
> >>
> >> So, the last paragraph of Roman's email
> >> <http://thread.gmane.org/gmane.comp.emulators.qemu.block/7978/focus=8081> remains
> >> relevant -- do whatever ugly static hack is necessary in QEMU's AML
> >> generator to restore the one use case to working state that matters:
> >> unattended installation to a virtio disk.
> >>
> >> Noone in their right mind uses floppy in the guest interactively, and
> >> even for the unattended installation, floppy is used only because
> >> Windows is too stupid to work off a CD-ROM fully automatically. (Where
> >> everything one needs would be interrogable from on hardware / ATAPI / SCSI.)
> >>
> >> IMHO, do the *absolute minimum* to adapt this AML generation patch to
> >> John's FDC rework, and ignore all dynamic aspects (like media change).
> >>
> >> Thanks
> >> Laszlo
> > 
> > I'm fine with reporting some static values that make windows work fine.
> > What I think is wrong is reporting geometry that happens to
> > match current windows.
> > 
> 
> Can you rephrase that last sentence? I don't follow, I'm sorry.
> 
> 
> Roman, does the 0xFF "empty disk geometry" hack appear to work for
> Windows 10?
> 
> Maybe it's fine enough as-is, as per Laszlo's good synopsis here.
> 
> --js

Right. What I would like to avoid, if possible, is reporting the current
data for whatever diskette happens to be used at machine_done
time.  This just makes things fragile if you switch
to a different one.

-- 
MST

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT
  2016-02-09 16:22           ` John Snow
  2016-02-09 18:36             ` Laszlo Ersek
@ 2016-02-10 16:57             ` Roman Kagan
  1 sibling, 0 replies; 75+ messages in thread
From: Roman Kagan @ 2016-02-10 16:57 UTC (permalink / raw)
  To: John Snow
  Cc: Peter Maydell, Eduardo Habkost, Michael S. Tsirkin, qemu-devel,
	Paolo Bonzini, Igor Mammedov, Richard Henderson

On Tue, Feb 09, 2016 at 11:22:01AM -0500, John Snow wrote:
> > I don't.  At the time the patch was developed there basically were no
> > mechanisms to update the geometry at all (and this was what you patchset
> > addressed, in particular, wasn't it?) so I didn't care.
> 
> That's not true.
> 
> You could swap different 1.44MB-class diskettes for other geometries,
> check this out:
> 
> static const FDFormat fd_formats[] = {
>     /* First entry is default format */
>     /* 1.44 MB 3"1/2 floppy disks */
>     { FDRIVE_DRV_144, 18, 80, 1, FDRIVE_RATE_500K, },
>     { FDRIVE_DRV_144, 20, 80, 1, FDRIVE_RATE_500K, },
>     { FDRIVE_DRV_144, 21, 80, 1, FDRIVE_RATE_500K, },
>     { FDRIVE_DRV_144, 21, 82, 1, FDRIVE_RATE_500K, },
>     { FDRIVE_DRV_144, 21, 83, 1, FDRIVE_RATE_500K, },
>     { FDRIVE_DRV_144, 22, 80, 1, FDRIVE_RATE_500K, },
>     { FDRIVE_DRV_144, 23, 80, 1, FDRIVE_RATE_500K, },
>     { FDRIVE_DRV_144, 24, 80, 1, FDRIVE_RATE_500K, },
> ...
> 
> You absolutely could get different sector and track counts before my
> patchset.

Indeed (sorry the patch was developed a couple of months ago so I had to
look at the code to refresh my memory).

However, I tried to implement the part of ACPI spec that read

> 9.9.2 _FDI (Floppy Disk Information)
> ====================================
> This object returns information about a floppy disk drive. This
> information is the same as that returned by the INT 13 Function 08H on
> IA-PCs.

so I went ahead and looked into what SeaBIOS did for int 0x13/0x08.  And
what it did was read the CMOS at 0x10 and obtain the drive type, and
then return a hardcoded set of parameters (including geometry)
associated to that drive type.  So this was what I basically did here,
too.  (As a matter of fact the first patch I submitted was just pure ASL
which mimicked exactly the SeaBIOS behavior: read the CMOS and return
the corresponding Package with parameters.)

And IIRC the drive type couldn't change at runtime so I thought I wasn't
doing worse than it was.

As for what to do now, I'll try to check how tolerant the guests are of
changing the floppy geometry under them without updating _FDI, and then
decide.

Roman.

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT
  2016-02-09 18:36             ` Laszlo Ersek
  2016-02-09 18:48               ` Michael S. Tsirkin
@ 2016-02-10 17:10               ` Roman Kagan
  2016-02-10 17:16                 ` John Snow
  2016-02-13 17:26               ` Kevin O'Connor
  2 siblings, 1 reply; 75+ messages in thread
From: Roman Kagan @ 2016-02-10 17:10 UTC (permalink / raw)
  To: Laszlo Ersek
  Cc: Peter Maydell, Eduardo Habkost, Michael S. Tsirkin, qemu-devel,
	Paolo Bonzini, Igor Mammedov, John Snow, Richard Henderson

On Tue, Feb 09, 2016 at 07:36:12PM +0100, Laszlo Ersek wrote:
> In my opinion, the real mess in this case is in the ACPI spec itself. If
> you re-read the _FDI control method's description, the Package that it
> returns contains *dynamic* geometry data, about the *disk* (not *drive*):
> 
> - Maximum Cylinder Number // Integer (WORD)
> - Maximum Sector Number   // Integer (WORD)
> - Maximum Head Number     // Integer (WORD)
> 
> What this seems to require is: the firmware developer should write ACPI
> code that
> - dynamically accesses the floppy drive / controller (using MMIO or IO
>   port registers),
> - retrieves the geometry of the disk actually inserted,
> - and returns the data nicely packaged.
> 
> In effect, an ACPI-level driver for the disk.
> 
> Now, John explained to me (and please keep in mind that this is my
> personal account of his explanation, not a factual rendering thereof),
> that there used to be no *standard* way to interrogate the current
> disk's geometry, other than trial and error with seeking.
> 
> Apparently in UEFI Windows, Microsoft didn't want to implement this
> trial and error seeking, so -- given there was also no portable
> *hardware spec* to retrieve the same data, directly from the disk drive
> or controller -- they punted the entire question to ACPI. That is, to
> the firmware implementor.

Well, as I wrote in another mail, SeaBIOS, which is supposed to provide
the same information to int 0x13/0x08, populates it with static data
based only on the drive type as encoded in CMOS at initialization time,
and everyone seem to have been fine with that so far.  I'll need to
re-test it with real Windows guests, though.

> IMHO, do the *absolute minimum* to adapt this AML generation patch to
> John's FDC rework, and ignore all dynamic aspects (like media change).

Hopefully that'll suffice.

Roman.

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT
  2016-02-10 17:10               ` Roman Kagan
@ 2016-02-10 17:16                 ` John Snow
  2016-02-10 17:33                   ` Roman Kagan
  0 siblings, 1 reply; 75+ messages in thread
From: John Snow @ 2016-02-10 17:16 UTC (permalink / raw)
  To: Roman Kagan, Laszlo Ersek, Igor Mammedov, Michael S. Tsirkin,
	qemu-devel, Peter Maydell, Eduardo Habkost, Paolo Bonzini,
	Richard Henderson



On 02/10/2016 12:10 PM, Roman Kagan wrote:
> On Tue, Feb 09, 2016 at 07:36:12PM +0100, Laszlo Ersek wrote:
>> In my opinion, the real mess in this case is in the ACPI spec itself. If
>> you re-read the _FDI control method's description, the Package that it
>> returns contains *dynamic* geometry data, about the *disk* (not *drive*):
>>
>> - Maximum Cylinder Number // Integer (WORD)
>> - Maximum Sector Number   // Integer (WORD)
>> - Maximum Head Number     // Integer (WORD)
>>
>> What this seems to require is: the firmware developer should write ACPI
>> code that
>> - dynamically accesses the floppy drive / controller (using MMIO or IO
>>   port registers),
>> - retrieves the geometry of the disk actually inserted,
>> - and returns the data nicely packaged.
>>
>> In effect, an ACPI-level driver for the disk.
>>
>> Now, John explained to me (and please keep in mind that this is my
>> personal account of his explanation, not a factual rendering thereof),
>> that there used to be no *standard* way to interrogate the current
>> disk's geometry, other than trial and error with seeking.
>>
>> Apparently in UEFI Windows, Microsoft didn't want to implement this
>> trial and error seeking, so -- given there was also no portable
>> *hardware spec* to retrieve the same data, directly from the disk drive
>> or controller -- they punted the entire question to ACPI. That is, to
>> the firmware implementor.
> 
> Well, as I wrote in another mail, SeaBIOS, which is supposed to provide
> the same information to int 0x13/0x08, populates it with static data
> based only on the drive type as encoded in CMOS at initialization time,
> and everyone seem to have been fine with that so far.  I'll need to
> re-test it with real Windows guests, though.
> 

OK, but what we appear to be doing currently is polling the current
geometry values for a drive instead of some pre-chosen ones based on the
drive type.

What values does SeaBIOS use? (Can you point me to the table it uses?)

We could just duplicate those, probably.

>> IMHO, do the *absolute minimum* to adapt this AML generation patch to
>> John's FDC rework, and ignore all dynamic aspects (like media change).
> 
> Hopefully that'll suffice.
> 
> Roman.
> 

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT
  2016-02-10 16:14                 ` John Snow
  2016-02-10 16:48                   ` Michael S. Tsirkin
@ 2016-02-10 17:24                   ` Roman Kagan
  1 sibling, 0 replies; 75+ messages in thread
From: Roman Kagan @ 2016-02-10 17:24 UTC (permalink / raw)
  To: John Snow
  Cc: Peter Maydell, Eduardo Habkost, Michael S. Tsirkin, qemu-devel,
	Paolo Bonzini, Igor Mammedov, Laszlo Ersek, Richard Henderson

On Wed, Feb 10, 2016 at 11:14:30AM -0500, John Snow wrote:
> On 02/09/2016 01:48 PM, Michael S. Tsirkin wrote:
> > On Tue, Feb 09, 2016 at 07:36:12PM +0100, Laszlo Ersek wrote:
> >> Implementing this in QEMU would require:
> >> - inventing virt-only registers for the FDC that provide the current
> >> disk geometry,
> 
> We do secretly have these registers, but of course there's no spec to
> interpreting what they mean. For instance, what do they read when the
> drive is empty? I am not sure that information is codified in the ACPI spec.

There are various possibilities, like returning False for the
corresponding drive in _FDE (Floppy Disk Enumerate) object, or returning
0 aka unknown as drive type in _FDI.  Anyway I'd hate needing to expose
all of that in an ACPI-accessible form, this is going to become too fat.

> Could be wrong, you seemed to indicate that the ACPI spec said that the
> info matches what you get from a certain legacy bios routine, but I
> don't know the specifics of that routine, either.

Indeed, it's supposed to do the same as
https://en.wikipedia.org/wiki/INT_13H#INT_13h_AH.3D08h:_Read_Drive_Parameters

and, as I wrote in another mail, the SeaBIOS implementation here is
rather simplistic.

> Roman, does the 0xFF "empty disk geometry" hack appear to work for
> Windows 10?
> 
> Maybe it's fine enough as-is, as per Laszlo's good synopsis here.

I'll test and let you know.

Roman.

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT
  2016-02-10 17:16                 ` John Snow
@ 2016-02-10 17:33                   ` Roman Kagan
  2016-02-10 21:54                     ` John Snow
  0 siblings, 1 reply; 75+ messages in thread
From: Roman Kagan @ 2016-02-10 17:33 UTC (permalink / raw)
  To: John Snow
  Cc: Peter Maydell, Eduardo Habkost, Michael S. Tsirkin, qemu-devel,
	Paolo Bonzini, Igor Mammedov, Laszlo Ersek, Richard Henderson

On Wed, Feb 10, 2016 at 12:16:32PM -0500, John Snow wrote:
> On 02/10/2016 12:10 PM, Roman Kagan wrote:
> > Well, as I wrote in another mail, SeaBIOS, which is supposed to provide
> > the same information to int 0x13/0x08, populates it with static data
> > based only on the drive type as encoded in CMOS at initialization time,
> > and everyone seem to have been fine with that so far.  I'll need to
> > re-test it with real Windows guests, though.
> > 
> 
> OK, but what we appear to be doing currently is polling the current
> geometry values for a drive instead of some pre-chosen ones based on the
> drive type.
> 
> What values does SeaBIOS use? (Can you point me to the table it uses?)

src/hw/floppy.c:

struct floppyinfo_s FloppyInfo[] VARFSEG = {
    // Unknown
    { {0, 0, 0}, 0x00, 0x00},
    // 1 - 360KB, 5.25" - 2 heads, 40 tracks, 9 sectors
    { {2, 40, 9}, FLOPPY_SIZE_525, FLOPPY_RATE_300K},
    // 2 - 1.2MB, 5.25" - 2 heads, 80 tracks, 15 sectors
    { {2, 80, 15}, FLOPPY_SIZE_525, FLOPPY_RATE_500K},
    // 3 - 720KB, 3.5"  - 2 heads, 80 tracks, 9 sectors
    { {2, 80, 9}, FLOPPY_SIZE_350, FLOPPY_RATE_250K},
    // 4 - 1.44MB, 3.5" - 2 heads, 80 tracks, 18 sectors
    { {2, 80, 18}, FLOPPY_SIZE_350, FLOPPY_RATE_500K},
    // 5 - 2.88MB, 3.5" - 2 heads, 80 tracks, 36 sectors
    { {2, 80, 36}, FLOPPY_SIZE_350, FLOPPY_RATE_1M},
    // 6 - 160k, 5.25"  - 1 heads, 40 tracks, 8 sectors
    { {1, 40, 8}, FLOPPY_SIZE_525, FLOPPY_RATE_250K},
    // 7 - 180k, 5.25"  - 1 heads, 40 tracks, 9 sectors
    { {1, 40, 9}, FLOPPY_SIZE_525, FLOPPY_RATE_300K},
    // 8 - 320k, 5.25"  - 2 heads, 40 tracks, 8 sectors
    { {2, 40, 8}, FLOPPY_SIZE_525, FLOPPY_RATE_250K},
};

The array is indexed by the floppy drive type from CMOS

Roman.

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT
  2016-02-10 17:33                   ` Roman Kagan
@ 2016-02-10 21:54                     ` John Snow
  0 siblings, 0 replies; 75+ messages in thread
From: John Snow @ 2016-02-10 21:54 UTC (permalink / raw)
  To: Roman Kagan, Laszlo Ersek, Igor Mammedov, Michael S. Tsirkin,
	qemu-devel, Peter Maydell, Eduardo Habkost, Paolo Bonzini,
	Richard Henderson



On 02/10/2016 12:33 PM, Roman Kagan wrote:
> On Wed, Feb 10, 2016 at 12:16:32PM -0500, John Snow wrote:
>> On 02/10/2016 12:10 PM, Roman Kagan wrote:
>>> Well, as I wrote in another mail, SeaBIOS, which is supposed to provide
>>> the same information to int 0x13/0x08, populates it with static data
>>> based only on the drive type as encoded in CMOS at initialization time,
>>> and everyone seem to have been fine with that so far.  I'll need to
>>> re-test it with real Windows guests, though.
>>>
>>
>> OK, but what we appear to be doing currently is polling the current
>> geometry values for a drive instead of some pre-chosen ones based on the
>> drive type.
>>
>> What values does SeaBIOS use? (Can you point me to the table it uses?)
> 
> src/hw/floppy.c:
> 
> struct floppyinfo_s FloppyInfo[] VARFSEG = {
>     // Unknown
>     { {0, 0, 0}, 0x00, 0x00},
>     // 1 - 360KB, 5.25" - 2 heads, 40 tracks, 9 sectors
>     { {2, 40, 9}, FLOPPY_SIZE_525, FLOPPY_RATE_300K},
>     // 2 - 1.2MB, 5.25" - 2 heads, 80 tracks, 15 sectors
>     { {2, 80, 15}, FLOPPY_SIZE_525, FLOPPY_RATE_500K},
>     // 3 - 720KB, 3.5"  - 2 heads, 80 tracks, 9 sectors
>     { {2, 80, 9}, FLOPPY_SIZE_350, FLOPPY_RATE_250K},
>     // 4 - 1.44MB, 3.5" - 2 heads, 80 tracks, 18 sectors
>     { {2, 80, 18}, FLOPPY_SIZE_350, FLOPPY_RATE_500K},
>     // 5 - 2.88MB, 3.5" - 2 heads, 80 tracks, 36 sectors
>     { {2, 80, 36}, FLOPPY_SIZE_350, FLOPPY_RATE_1M},
>     // 6 - 160k, 5.25"  - 1 heads, 40 tracks, 8 sectors
>     { {1, 40, 8}, FLOPPY_SIZE_525, FLOPPY_RATE_250K},
>     // 7 - 180k, 5.25"  - 1 heads, 40 tracks, 9 sectors
>     { {1, 40, 9}, FLOPPY_SIZE_525, FLOPPY_RATE_300K},
>     // 8 - 320k, 5.25"  - 2 heads, 40 tracks, 8 sectors
>     { {2, 40, 8}, FLOPPY_SIZE_525, FLOPPY_RATE_250K},
> };
> 
> The array is indexed by the floppy drive type from CMOS
> 
> Roman.
> 

Hm, thanks. These seem like sane geometries, but looking at the QEMU
geometry table ... I'm not sure what these even mean anymore, or what it
might mean when they don't align with the SeaBIOS values. We probably
don't even try very often. Maybe nobody ever has.

    { FLOPPY_DRIVE_TYPE_288, 36, 80, 1, FDRIVE_RATE_1M, }, // 5760
    { FLOPPY_DRIVE_TYPE_288, 39, 80, 1, FDRIVE_RATE_1M, }, // 6240
    { FLOPPY_DRIVE_TYPE_288, 40, 80, 1, FDRIVE_RATE_1M, }, // 6400
    { FLOPPY_DRIVE_TYPE_288, 44, 80, 1, FDRIVE_RATE_1M, }, // 7040
    { FLOPPY_DRIVE_TYPE_288, 48, 80, 1, FDRIVE_RATE_1M, }, // 7680

If sectors are 512 bytes, the byte size of these diskettes range from
2.813 MiB (or 2.99 Mb; I just today discovered the only way to get an
even 2.88 is to count this as ((36 * 80 * 2) * 512 / 1000 / 1024), which
mixes x^2 and x^10 designations) up through a whopping 3.74MiB/"3.84MB"

QEMU seems to try to support some real funky formats. Not even really
sure where Fabrice got these numbers from.

Sigh, as long as things sort of seem to work. I'm not going to invest
any further effort into figuring out exactly what we should be doing. If
the UEFI guests are working I'm happy if you are.

--js

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT
  2016-02-09 18:36             ` Laszlo Ersek
  2016-02-09 18:48               ` Michael S. Tsirkin
  2016-02-10 17:10               ` Roman Kagan
@ 2016-02-13 17:26               ` Kevin O'Connor
  2016-02-14  6:45                 ` Laszlo Ersek
  2016-02-14 15:02                 ` Michael S. Tsirkin
  2 siblings, 2 replies; 75+ messages in thread
From: Kevin O'Connor @ 2016-02-13 17:26 UTC (permalink / raw)
  To: Laszlo Ersek
  Cc: Peter Maydell, Eduardo Habkost, Michael S. Tsirkin, qemu-devel,
	Roman Kagan, Igor Mammedov, Paolo Bonzini, John Snow,
	Richard Henderson

On Tue, Feb 09, 2016 at 07:36:12PM +0100, Laszlo Ersek wrote:
> On 02/09/16 17:22, John Snow wrote:
> > On 02/09/2016 10:52 AM, Roman Kagan wrote:
> >> On Mon, Feb 08, 2016 at 03:20:47PM -0500, John Snow wrote:
> >>> On 02/08/2016 08:14 AM, Roman Kagan wrote:
> >>>> On Fri, Feb 05, 2016 at 07:25:07PM +0100, Igor Mammedov wrote:
> >>>>>> +    aml_append(fdi,
> >>>>>> +        aml_int(cylinders - 1));  /* Maximum Cylinder Number */
> >>>>> this puts uint64_t(-1) in AML i.e. cylinders == 0 and overflow happens here
> >>>>>
> >>>>> CCing Jon
> >>>>
> >>>> I guess this is the effect of John's fdc rework.  I used to think zero
> >>>> geometry was impossible at the time this patch was developed.
> >>>>
> >>>> I wonder if it hasn't been fixed already by
> >>>>
> >>>>   commit fd9bdbd3459e5b9d51534f0747049bc5b6145e07
> >>>>   Author: John Snow <jsnow@redhat.com>
> >>>>   Date:   Wed Feb 3 11:28:55 2016 -0500
> >>>>
> >>>>       fdc: fix detection under Linux
> >>>
> >>> Yes, hopefully solved on my end. The geometry values for an empty disk
> >>> are not well defined (they certainly don't have any *meaning*) so if you
> >>> are populating tables based on an empty drive, I just hope you also have
> >>> the mechanisms needed to update said tables when the media changes.
> >>
> >> I don't.  At the time the patch was developed there basically were no
> >> mechanisms to update the geometry at all (and this was what you patchset
> >> addressed, in particular, wasn't it?) so I didn't care.
> >>
> > 
> > That's not true.
> > 
> > You could swap different 1.44MB-class diskettes for other geometries,
> > check this out:
> > 
> > static const FDFormat fd_formats[] = {
> >     /* First entry is default format */
> >     /* 1.44 MB 3"1/2 floppy disks */
> >     { FDRIVE_DRV_144, 18, 80, 1, FDRIVE_RATE_500K, },
> >     { FDRIVE_DRV_144, 20, 80, 1, FDRIVE_RATE_500K, },
> >     { FDRIVE_DRV_144, 21, 80, 1, FDRIVE_RATE_500K, },
> >     { FDRIVE_DRV_144, 21, 82, 1, FDRIVE_RATE_500K, },
> >     { FDRIVE_DRV_144, 21, 83, 1, FDRIVE_RATE_500K, },
> >     { FDRIVE_DRV_144, 22, 80, 1, FDRIVE_RATE_500K, },
> >     { FDRIVE_DRV_144, 23, 80, 1, FDRIVE_RATE_500K, },
> >     { FDRIVE_DRV_144, 24, 80, 1, FDRIVE_RATE_500K, },
> > ...
> > 
> > You absolutely could get different sector and track counts before my
> > patchset.
> > 
> > 
> >> Now if it actually has to be fully dynamic it's gonna be more
> >> involved...
> >>
> >>> What do the guests use these values for? Are they fixed at boot?
> >>
> >> Only Windows guests use it so it's hard to tell.  I can only claim that
> >> if I stick bogus values into that ACPI object the guest fails to read
> >> the floppy.
> 
> We discussed this with John a bit on IRC.
> 
> In my opinion, the real mess in this case is in the ACPI spec itself. If
> you re-read the _FDI control method's description, the Package that it
> returns contains *dynamic* geometry data, about the *disk* (not *drive*):
> 
> - Maximum Cylinder Number // Integer (WORD)
> - Maximum Sector Number   // Integer (WORD)
> - Maximum Head Number     // Integer (WORD)

FWIW, that's not how I read the ACPI specification.  I read it as
saying that the information should be filled with the maximum number
of CHS that the drive can support.  So, even if a smaller disk happens
to be in the drive the maximum the drive supports would not change.

Also, FWIW, SeaBIOS uses the standard 1.44MB floppy controller timing
information even if a 5.25 drive is found - as far as I know this
information is only ever used on PIO to the floppy controller and the
QEMU floppy controller doesn't care what timing parameters it is
programmed with.

-Kevin

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT
  2016-02-13 17:26               ` Kevin O'Connor
@ 2016-02-14  6:45                 ` Laszlo Ersek
  2016-02-14 15:02                 ` Michael S. Tsirkin
  1 sibling, 0 replies; 75+ messages in thread
From: Laszlo Ersek @ 2016-02-14  6:45 UTC (permalink / raw)
  To: Kevin O'Connor
  Cc: Peter Maydell, Eduardo Habkost, Michael S. Tsirkin, qemu-devel,
	Roman Kagan, Igor Mammedov, Paolo Bonzini, John Snow,
	Richard Henderson

On 02/13/16 18:26, Kevin O'Connor wrote:
> On Tue, Feb 09, 2016 at 07:36:12PM +0100, Laszlo Ersek wrote:
>> On 02/09/16 17:22, John Snow wrote:
>>> On 02/09/2016 10:52 AM, Roman Kagan wrote:
>>>> On Mon, Feb 08, 2016 at 03:20:47PM -0500, John Snow wrote:
>>>>> On 02/08/2016 08:14 AM, Roman Kagan wrote:
>>>>>> On Fri, Feb 05, 2016 at 07:25:07PM +0100, Igor Mammedov wrote:
>>>>>>>> +    aml_append(fdi,
>>>>>>>> +        aml_int(cylinders - 1));  /* Maximum Cylinder Number */
>>>>>>> this puts uint64_t(-1) in AML i.e. cylinders == 0 and overflow happens here
>>>>>>>
>>>>>>> CCing Jon
>>>>>>
>>>>>> I guess this is the effect of John's fdc rework.  I used to think zero
>>>>>> geometry was impossible at the time this patch was developed.
>>>>>>
>>>>>> I wonder if it hasn't been fixed already by
>>>>>>
>>>>>>   commit fd9bdbd3459e5b9d51534f0747049bc5b6145e07
>>>>>>   Author: John Snow <jsnow@redhat.com>
>>>>>>   Date:   Wed Feb 3 11:28:55 2016 -0500
>>>>>>
>>>>>>       fdc: fix detection under Linux
>>>>>
>>>>> Yes, hopefully solved on my end. The geometry values for an empty disk
>>>>> are not well defined (they certainly don't have any *meaning*) so if you
>>>>> are populating tables based on an empty drive, I just hope you also have
>>>>> the mechanisms needed to update said tables when the media changes.
>>>>
>>>> I don't.  At the time the patch was developed there basically were no
>>>> mechanisms to update the geometry at all (and this was what you patchset
>>>> addressed, in particular, wasn't it?) so I didn't care.
>>>>
>>>
>>> That's not true.
>>>
>>> You could swap different 1.44MB-class diskettes for other geometries,
>>> check this out:
>>>
>>> static const FDFormat fd_formats[] = {
>>>     /* First entry is default format */
>>>     /* 1.44 MB 3"1/2 floppy disks */
>>>     { FDRIVE_DRV_144, 18, 80, 1, FDRIVE_RATE_500K, },
>>>     { FDRIVE_DRV_144, 20, 80, 1, FDRIVE_RATE_500K, },
>>>     { FDRIVE_DRV_144, 21, 80, 1, FDRIVE_RATE_500K, },
>>>     { FDRIVE_DRV_144, 21, 82, 1, FDRIVE_RATE_500K, },
>>>     { FDRIVE_DRV_144, 21, 83, 1, FDRIVE_RATE_500K, },
>>>     { FDRIVE_DRV_144, 22, 80, 1, FDRIVE_RATE_500K, },
>>>     { FDRIVE_DRV_144, 23, 80, 1, FDRIVE_RATE_500K, },
>>>     { FDRIVE_DRV_144, 24, 80, 1, FDRIVE_RATE_500K, },
>>> ...
>>>
>>> You absolutely could get different sector and track counts before my
>>> patchset.
>>>
>>>
>>>> Now if it actually has to be fully dynamic it's gonna be more
>>>> involved...
>>>>
>>>>> What do the guests use these values for? Are they fixed at boot?
>>>>
>>>> Only Windows guests use it so it's hard to tell.  I can only claim that
>>>> if I stick bogus values into that ACPI object the guest fails to read
>>>> the floppy.
>>
>> We discussed this with John a bit on IRC.
>>
>> In my opinion, the real mess in this case is in the ACPI spec itself. If
>> you re-read the _FDI control method's description, the Package that it
>> returns contains *dynamic* geometry data, about the *disk* (not *drive*):
>>
>> - Maximum Cylinder Number // Integer (WORD)
>> - Maximum Sector Number   // Integer (WORD)
>> - Maximum Head Number     // Integer (WORD)
> 
> FWIW, that's not how I read the ACPI specification.  I read it as
> saying that the information should be filled with the maximum number
> of CHS that the drive can support.  So, even if a smaller disk happens
> to be in the drive the maximum the drive supports would not change.

If that works with Windows, I think it would be optimal for QEMU.

Thanks!
Laszlo

> 
> Also, FWIW, SeaBIOS uses the standard 1.44MB floppy controller timing
> information even if a 5.25 drive is found - as far as I know this
> information is only ever used on PIO to the floppy controller and the
> QEMU floppy controller doesn't care what timing parameters it is
> programmed with.
> 
> -Kevin
> 

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT
  2016-02-13 17:26               ` Kevin O'Connor
  2016-02-14  6:45                 ` Laszlo Ersek
@ 2016-02-14 15:02                 ` Michael S. Tsirkin
  2016-02-17 14:31                   ` Roman Kagan
  1 sibling, 1 reply; 75+ messages in thread
From: Michael S. Tsirkin @ 2016-02-14 15:02 UTC (permalink / raw)
  To: Kevin O'Connor
  Cc: Peter Maydell, Eduardo Habkost, John Snow, qemu-devel,
	Roman Kagan, Igor Mammedov, Paolo Bonzini, Laszlo Ersek,
	Richard Henderson

On Sat, Feb 13, 2016 at 12:26:53PM -0500, Kevin O'Connor wrote:
> On Tue, Feb 09, 2016 at 07:36:12PM +0100, Laszlo Ersek wrote:
> > On 02/09/16 17:22, John Snow wrote:
> > > On 02/09/2016 10:52 AM, Roman Kagan wrote:
> > >> On Mon, Feb 08, 2016 at 03:20:47PM -0500, John Snow wrote:
> > >>> On 02/08/2016 08:14 AM, Roman Kagan wrote:
> > >>>> On Fri, Feb 05, 2016 at 07:25:07PM +0100, Igor Mammedov wrote:
> > >>>>>> +    aml_append(fdi,
> > >>>>>> +        aml_int(cylinders - 1));  /* Maximum Cylinder Number */
> > >>>>> this puts uint64_t(-1) in AML i.e. cylinders == 0 and overflow happens here
> > >>>>>
> > >>>>> CCing Jon
> > >>>>
> > >>>> I guess this is the effect of John's fdc rework.  I used to think zero
> > >>>> geometry was impossible at the time this patch was developed.
> > >>>>
> > >>>> I wonder if it hasn't been fixed already by
> > >>>>
> > >>>>   commit fd9bdbd3459e5b9d51534f0747049bc5b6145e07
> > >>>>   Author: John Snow <jsnow@redhat.com>
> > >>>>   Date:   Wed Feb 3 11:28:55 2016 -0500
> > >>>>
> > >>>>       fdc: fix detection under Linux
> > >>>
> > >>> Yes, hopefully solved on my end. The geometry values for an empty disk
> > >>> are not well defined (they certainly don't have any *meaning*) so if you
> > >>> are populating tables based on an empty drive, I just hope you also have
> > >>> the mechanisms needed to update said tables when the media changes.
> > >>
> > >> I don't.  At the time the patch was developed there basically were no
> > >> mechanisms to update the geometry at all (and this was what you patchset
> > >> addressed, in particular, wasn't it?) so I didn't care.
> > >>
> > > 
> > > That's not true.
> > > 
> > > You could swap different 1.44MB-class diskettes for other geometries,
> > > check this out:
> > > 
> > > static const FDFormat fd_formats[] = {
> > >     /* First entry is default format */
> > >     /* 1.44 MB 3"1/2 floppy disks */
> > >     { FDRIVE_DRV_144, 18, 80, 1, FDRIVE_RATE_500K, },
> > >     { FDRIVE_DRV_144, 20, 80, 1, FDRIVE_RATE_500K, },
> > >     { FDRIVE_DRV_144, 21, 80, 1, FDRIVE_RATE_500K, },
> > >     { FDRIVE_DRV_144, 21, 82, 1, FDRIVE_RATE_500K, },
> > >     { FDRIVE_DRV_144, 21, 83, 1, FDRIVE_RATE_500K, },
> > >     { FDRIVE_DRV_144, 22, 80, 1, FDRIVE_RATE_500K, },
> > >     { FDRIVE_DRV_144, 23, 80, 1, FDRIVE_RATE_500K, },
> > >     { FDRIVE_DRV_144, 24, 80, 1, FDRIVE_RATE_500K, },
> > > ...
> > > 
> > > You absolutely could get different sector and track counts before my
> > > patchset.
> > > 
> > > 
> > >> Now if it actually has to be fully dynamic it's gonna be more
> > >> involved...
> > >>
> > >>> What do the guests use these values for? Are they fixed at boot?
> > >>
> > >> Only Windows guests use it so it's hard to tell.  I can only claim that
> > >> if I stick bogus values into that ACPI object the guest fails to read
> > >> the floppy.
> > 
> > We discussed this with John a bit on IRC.
> > 
> > In my opinion, the real mess in this case is in the ACPI spec itself. If
> > you re-read the _FDI control method's description, the Package that it
> > returns contains *dynamic* geometry data, about the *disk* (not *drive*):
> > 
> > - Maximum Cylinder Number // Integer (WORD)
> > - Maximum Sector Number   // Integer (WORD)
> > - Maximum Head Number     // Integer (WORD)
> 
> FWIW, that's not how I read the ACPI specification.  I read it as
> saying that the information should be filled with the maximum number
> of CHS that the drive can support.  So, even if a smaller disk happens
> to be in the drive the maximum the drive supports would not change.

I agree. It says:
	This object returns information about a floppy disk drive. This
	information is the same as
	that returned by the INT 13 Function 08H on Intel Architecture PCs.

So disk drive, not disk information.

And FWIW I have an old "the undocumented PC" book which says
this about int 13h function 8 (read diskette drive parameters):

"Remember this data is *not* the limits of the media in the drive,
but the maximum capability of the specified drive".

> Also, FWIW, SeaBIOS uses the standard 1.44MB floppy controller timing
> information even if a 5.25 drive is found - as far as I know this
> information is only ever used on PIO to the floppy controller and the
> QEMU floppy controller doesn't care what timing parameters it is
> programmed with.
> 
> -Kevin

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT
  2016-02-14 15:02                 ` Michael S. Tsirkin
@ 2016-02-17 14:31                   ` Roman Kagan
  0 siblings, 0 replies; 75+ messages in thread
From: Roman Kagan @ 2016-02-17 14:31 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Peter Maydell, Eduardo Habkost, John Snow, qemu-devel,
	Kevin O'Connor, Igor Mammedov, Paolo Bonzini, Laszlo Ersek,
	Richard Henderson

On Sun, Feb 14, 2016 at 05:02:14PM +0200, Michael S. Tsirkin wrote:
> On Sat, Feb 13, 2016 at 12:26:53PM -0500, Kevin O'Connor wrote:
> > On Tue, Feb 09, 2016 at 07:36:12PM +0100, Laszlo Ersek wrote:
> > > In my opinion, the real mess in this case is in the ACPI spec itself. If
> > > you re-read the _FDI control method's description, the Package that it
> > > returns contains *dynamic* geometry data, about the *disk* (not *drive*):
> > > 
> > > - Maximum Cylinder Number // Integer (WORD)
> > > - Maximum Sector Number   // Integer (WORD)
> > > - Maximum Head Number     // Integer (WORD)
> > 
> > FWIW, that's not how I read the ACPI specification.  I read it as
> > saying that the information should be filled with the maximum number
> > of CHS that the drive can support.  So, even if a smaller disk happens
> > to be in the drive the maximum the drive supports would not change.
> 
> I agree. It says:
> 	This object returns information about a floppy disk drive. This
> 	information is the same as
> 	that returned by the INT 13 Function 08H on Intel Architecture PCs.
> 
> So disk drive, not disk information.
> 
> And FWIW I have an old "the undocumented PC" book which says
> this about int 13h function 8 (read diskette drive parameters):
> 
> "Remember this data is *not* the limits of the media in the drive,
> but the maximum capability of the specified drive".

Thanks for the info, I've re-implemented the patchset according to it
and Windows guests (w2k12, w10) seem to be happy with it, including
dynamically (re-)inserting the "diskette" of compatible size.

I'll submit the patches shortly.

Thanks,
Roman.

^ permalink raw reply	[flat|nested] 75+ messages in thread

end of thread, other threads:[~2016-02-17 14:31 UTC | newest]

Thread overview: 75+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-04 21:50 [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Michael S. Tsirkin
2016-02-04 21:50 ` [Qemu-devel] [PULL 14/49] virtio: combine write of an entry into used ring Michael S. Tsirkin
2016-02-04 21:50 ` [Qemu-devel] [PULL 01/49] Fix virtio migration Michael S. Tsirkin
2016-02-04 21:50 ` [Qemu-devel] [PULL 02/49] pc: acpi: merge SSDT into DSDT Michael S. Tsirkin
2016-02-04 21:51 ` [Qemu-devel] [PULL 03/49] tests: pc: acpi: drop not needed 'expected SSDT' blobs Michael S. Tsirkin
2016-02-04 21:51 ` [Qemu-devel] [PULL 04/49] tests: pc: acpi: add expected DSDT.bridge blobs and update DSDT blobs Michael S. Tsirkin
2016-02-04 21:51 ` [Qemu-devel] [PULL 05/49] virtio: move VirtQueueElement at the beginning of the structs Michael S. Tsirkin
2016-02-04 21:51 ` [Qemu-devel] [PULL 06/49] virtio: move allocation to virtqueue_pop/vring_pop Michael S. Tsirkin
2016-02-05 12:52   ` Peter Maydell
2016-02-06 18:10     ` Michael S. Tsirkin
2016-02-04 21:51 ` [Qemu-devel] [PULL 07/49] virtio: introduce qemu_get/put_virtqueue_element Michael S. Tsirkin
2016-02-04 21:51 ` [Qemu-devel] [PULL 08/49] virtio: introduce virtqueue_alloc_element Michael S. Tsirkin
2016-02-04 21:51 ` [Qemu-devel] [PULL 09/49] virtio: slim down allocation of VirtQueueElements Michael S. Tsirkin
2016-02-04 21:51 ` [Qemu-devel] [PULL 10/49] vring: " Michael S. Tsirkin
2016-02-04 21:51 ` [Qemu-devel] [PULL 11/49] virtio: combine the read of a descriptor Michael S. Tsirkin
2016-02-04 21:51 ` [Qemu-devel] [PULL 12/49] virtio: cache used_idx in a VirtQueue field Michael S. Tsirkin
2016-02-04 21:51 ` [Qemu-devel] [PULL 13/49] virtio: read avail_idx from VQ only when necessary Michael S. Tsirkin
2016-02-04 21:51 ` [Qemu-devel] [PULL 15/49] hw/pxb: add pxb devices to the bridge category Michael S. Tsirkin
2016-02-04 21:52 ` [Qemu-devel] [PULL 16/49] vhost-user-test: use correct ROM to speed up and avoid spurious failures Michael S. Tsirkin
2016-02-04 21:52 ` [Qemu-devel] [PULL 17/49] hw/pci: ensure that only PCI/PCIe bridges can be attached to pxb/pxb-pcie devices Michael S. Tsirkin
2016-02-04 21:52 ` [Qemu-devel] [PULL 18/49] ipmi: replace goto by a return statement Michael S. Tsirkin
2016-02-04 21:52 ` [Qemu-devel] [PULL 19/49] ipmi: replace *_MAXCMD defines Michael S. Tsirkin
2016-02-04 21:52 ` [Qemu-devel] [PULL 20/49] ipmi: cleanup error_report messages Michael S. Tsirkin
2016-02-04 21:52 ` [Qemu-devel] [PULL 21/49] ipmi: fix SDR length value Michael S. Tsirkin
2016-02-04 21:52 ` [Qemu-devel] [PULL 22/49] ipmi: introduce a struct ipmi_sdr_compact Michael S. Tsirkin
2016-02-04 21:52 ` [Qemu-devel] [PULL 23/49] ipmi: add get and set SENSOR_TYPE commands Michael S. Tsirkin
2016-02-04 21:52 ` [Qemu-devel] [PULL 24/49] ipmi: add GET_SYS_RESTART_CAUSE chassis command Michael S. Tsirkin
2016-02-04 21:52 ` [Qemu-devel] [PULL 25/49] ipmi: add ACPI power and GUID commands Michael S. Tsirkin
2016-02-04 21:52 ` [Qemu-devel] [PULL 26/49] pc: Move PcGuestInfo declaration to top of file Michael S. Tsirkin
2016-02-04 21:52 ` [Qemu-devel] [PULL 27/49] pc: Eliminate struct PcGuestInfoState Michael S. Tsirkin
2016-02-04 21:52 ` [Qemu-devel] [PULL 28/49] pc: Simplify pc_memory_init() signature Michael S. Tsirkin
2016-02-04 21:52 ` [Qemu-devel] [PULL 29/49] pc: Simplify xen_load_linux() signature Michael S. Tsirkin
2016-02-04 21:52 ` [Qemu-devel] [PULL 30/49] acpi: Remove guest_info parameters from functions Michael S. Tsirkin
2016-02-04 21:53 ` [Qemu-devel] [PULL 31/49] acpi: Don't save PcGuestInfo on AcpiBuildState Michael S. Tsirkin
2016-02-04 21:53 ` [Qemu-devel] [PULL 32/49] pc: Remove compat fields from PcGuestInfo Michael S. Tsirkin
2016-02-04 21:53 ` [Qemu-devel] [PULL 33/49] pc: Remove RAM size " Michael S. Tsirkin
2016-02-04 21:53 ` [Qemu-devel] [PULL 34/49] pc: Remove PcGuestInfo.isapc_ram_fw field Michael S. Tsirkin
2016-02-04 21:53 ` [Qemu-devel] [PULL 35/49] pc: Move PcGuestInfo.fw_cfg to PCMachineState Michael S. Tsirkin
2016-02-04 21:53 ` [Qemu-devel] [PULL 36/49] pc: Move APIC and NUMA data from PcGuestInfo " Michael S. Tsirkin
2016-02-04 21:53 ` [Qemu-devel] [PULL 37/49] pc: Eliminate PcGuestInfo struct Michael S. Tsirkin
2016-02-04 21:53 ` [Qemu-devel] [PULL 38/49] acpi: take oem_id in build_header(), optionally Michael S. Tsirkin
2016-02-04 22:25   ` Laszlo Ersek
2016-02-04 21:53 ` [Qemu-devel] [PULL 39/49] acpi: expose oem_id and oem_table_id in build_rsdt() Michael S. Tsirkin
2016-02-04 21:53 ` [Qemu-devel] [PULL 40/49] acpi: add function to extract oem_id and oem_table_id from the user's SLIC Michael S. Tsirkin
2016-02-04 21:53 ` [Qemu-devel] [PULL 41/49] pc: set the OEM fields in the RSDT and the FADT from the SLIC Michael S. Tsirkin
2016-02-04 21:53 ` [Qemu-devel] [PULL 42/49] dimm: Correct type of MemoryHotplugState->base Michael S. Tsirkin
2016-02-04 21:53 ` [Qemu-devel] [PULL 43/49] intel_iommu: large page support Michael S. Tsirkin
2016-02-04 21:53 ` [Qemu-devel] [PULL 44/49] fix MSI injection on Xen Michael S. Tsirkin
2016-02-04 21:54 ` [Qemu-devel] [PULL 45/49] net: set endianness on all backend devices Michael S. Tsirkin
2016-02-05  8:54   ` Greg Kurz
2016-02-04 21:54 ` [Qemu-devel] [PULL 46/49] i386/acpi: make floppy controller object dynamic Michael S. Tsirkin
2016-02-04 21:54 ` [Qemu-devel] [PULL 47/49] expose floppy drive geometry and CMOS type Michael S. Tsirkin
2016-02-04 21:54 ` [Qemu-devel] [PULL 48/49] i386: populate floppy drive information in DSDT Michael S. Tsirkin
2016-02-05 18:25   ` Igor Mammedov
2016-02-08 13:14     ` Roman Kagan
2016-02-08 20:20       ` John Snow
2016-02-09 15:52         ` Roman Kagan
2016-02-09 16:22           ` John Snow
2016-02-09 18:36             ` Laszlo Ersek
2016-02-09 18:48               ` Michael S. Tsirkin
2016-02-10 16:14                 ` John Snow
2016-02-10 16:48                   ` Michael S. Tsirkin
2016-02-10 17:24                   ` Roman Kagan
2016-02-10 17:10               ` Roman Kagan
2016-02-10 17:16                 ` John Snow
2016-02-10 17:33                   ` Roman Kagan
2016-02-10 21:54                     ` John Snow
2016-02-13 17:26               ` Kevin O'Connor
2016-02-14  6:45                 ` Laszlo Ersek
2016-02-14 15:02                 ` Michael S. Tsirkin
2016-02-17 14:31                   ` Roman Kagan
2016-02-10 16:57             ` Roman Kagan
2016-02-04 21:54 ` [Qemu-devel] [PULL 49/49] acpi: update expected DSDT Michael S. Tsirkin
2016-02-05 15:03 ` [Qemu-devel] [PULL 00/49] pc and misc cleanups and fixes, virtio optimizations Peter Maydell
2016-02-05 18:19   ` Igor Mammedov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).