Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into sta…
Browse files Browse the repository at this point in the history
…ging

pc, virtio enhancements

Memory hot-unplug support for pc, MSI-X
mapping update speedup for virtio-pci,
misc refactorings and bugfixes.

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

# gpg: Signature made Mon May 11 08:23:43 2015 BST using RSA key ID D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>"

* remotes/mst/tags/for_upstream: (28 commits)
  acpi: update expected files for memory unplug
  virtio-scsi: Move DEFINE_VIRTIO_SCSI_FEATURES to virtio-scsi
  virtio-net: Move DEFINE_VIRTIO_NET_FEATURES to virtio-net
  pci: Merge pci_nic_init() into pci_nic_init_nofail()
  acpi: add a missing backslash to the \_SB scope.
  qmp-event: add event notification for memory hot unplug error
  acpi: add hardware implementation for memory hot unplug
  acpi: fix "Memory device control fields" register
  acpi: extend aml_field() to support UpdateRule
  acpi, mem-hotplug: add unplug cb for memory device
  acpi, mem-hotplug: add unplug request cb for memory device
  acpi, mem-hotplug: add acpi_memory_slot_status() to get MemStatus
  docs: update documentation for memory hot unplug
  virtio: coding style tweak
  pci: remove hard-coded bar size in msix_init_exclusive_bar()
  virtio-pci: speedup MSI-X masking and unmasking
  virtio: introduce vector to virtqueues mapping
  virtio-ccw: using VIRTIO_NO_VECTOR instead of 0 for invalid virtqueue
  monitor: check return value of qemu_find_net_clients_except()
  monitor: replace the magic number 255 with MAX_QUEUE_NUM
  ...

Conflicts:
	hw/s390x/s390-virtio-bus.c

[PMM: fixed conflict in s390_virtio_scsi_properties and
s390_virtio_net_properties arrays; since the result of the
two conflicting patches is to empty the property arrays
completely, the conflict resolution is to remove them entirely.]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed May 11, 2015
2 parents 266745c + bc1f7c4 commit 0403b0f
Show file tree
Hide file tree
Showing 42 changed files with 673 additions and 221 deletions.
23 changes: 20 additions & 3 deletions docs/memory-hotplug.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ QEMU memory hotplug
This document explains how to use the memory hotplug feature in QEMU,
which is present since v2.1.0.

Please, note that memory hotunplug is not supported yet. This means
that you're able to add memory, but you're not able to remove it.
Also, proper guest support is required for memory hotplug to work.
Guest support is required for memory hotplug to work.

Basic RAM hotplug
-----------------
Expand Down Expand Up @@ -74,3 +72,22 @@ comes from regular RAM, 1GB is a 1GB hugepage page and 256MB is from
-device pc-dimm,id=dimm1,memdev=mem1 \
-object memory-backend-file,id=mem2,size=256M,mem-path=/mnt/hugepages-2MB \
-device pc-dimm,id=dimm2,memdev=mem2


RAM hot-unplug
---------------

In order to be able to hot unplug pc-dimm device, QEMU has to be told the ids
of pc-dimm device and memory backend object. The ids were assigned when you hot
plugged memory.

Two monitor commands are used to hot unplug memory:

- "device_del": deletes a front-end pc-dimm device
- "object_del": deletes a memory backend object

For example, assuming that the pc-dimm device with id "dimm1" exists, and its memory
backend is "mem1", the following commands tries to remove it.

(qemu) device_del dimm1
(qemu) object_del mem1
17 changes: 17 additions & 0 deletions docs/qmp/qmp-events.txt
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,23 @@ Example:
{ "event": "GUEST_PANICKED",
"data": { "action": "pause" } }

MEM_HOT_UNPLUG_ERROR
--------------------
Emitted when memory hot unplug error occurs.

Data:

- "device": device name (json-string)
- "msg": Informative message (e.g., reason for the error) (json-string)

Example:

{ "event": "MEM_HOT_UNPLUG_ERROR"
"data": { "device": "dimm1",
"msg": "acpi: device unplug for unsupported device"
},
"timestamp": { "seconds": 1265044230, "microseconds": 450486 } }

NIC_RX_FILTER_CHANGED
---------------------

Expand Down
58 changes: 54 additions & 4 deletions docs/specs/acpi_mem_hotplug.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ QEMU<->ACPI BIOS memory hotplug interface
--------------------------------------

ACPI BIOS GPE.3 handler is dedicated for notifying OS about memory hot-add
events.
and hot-remove events.

Memory hot-plug interface (IO port 0xa00-0xa17, 1-4 byte access):
---------------------------------------------------------------
Expand All @@ -19,7 +19,9 @@ Memory hot-plug interface (IO port 0xa00-0xa17, 1-4 byte access):
1: Device insert event, used to distinguish device for which
no device check event to OSPM was issued.
It's valid only when bit 1 is set.
2-7: reserved and should be ignored by OSPM
2: Device remove event, used to distinguish device for which
no device eject request to OSPM was issued.
3-7: reserved and should be ignored by OSPM
[0x15-0x17] reserved

write access:
Expand All @@ -31,14 +33,62 @@ Memory hot-plug interface (IO port 0xa00-0xa17, 1-4 byte access):
[0xc-0x13] reserved, writes into it are ignored
[0x14] Memory device control fields
bits:
0: reserved, OSPM must clear it before writing to register
0: reserved, OSPM must clear it before writing to register.
Due to BUG in versions prior 2.4 that field isn't cleared
when other fields are written. Keep it reserved and don't
try to reuse it.
1: if set to 1 clears device insert event, set by OSPM
after it has emitted device check event for the
selected memory device
2-7: reserved, OSPM must clear them before writing to register
2: if set to 1 clears device remove event, set by OSPM
after it has emitted device eject request for the
selected memory device
3: if set to 1 initiates device eject, set by OSPM when it
triggers memory device removal and calls _EJ0 method
4-7: reserved, OSPM must clear them before writing to register

Selecting memory device slot beyond present range has no effect on platform:
- write accesses to memory hot-plug registers not documented above are
ignored
- read accesses to memory hot-plug registers not documented above return
all bits set to 1.

Memory hot remove process diagram:
----------------------------------
+-------------+     +-----------------------+      +------------------+     
 |  1. QEMU    |     | 2. QEMU               |      |3. QEMU           |     
 |  device_del +---->+ device unplug request +----->+Send SCI to guest,|     
 |             |     |         cb            |      |return control to |     
 +-------------+     +-----------------------+      |management        |     
                                                    +------------------+     

 +---------------------------------------------------------------------+     

 +---------------------+              +-------------------------+            
 | OSPM:               | remove event | OSPM:                   |            
 | send Eject Request, |              | Scan memory devices     |            
 | clear remove event  +<-------------+ for event flags         |            
 |                     |              |                         |            
 +---------------------+              +-------------------------+            
           |                                                                 
           |                                                                 
 +---------v--------+            +-----------------------+                   
 | Guest OS:        |  success   | OSPM:                 |                   
 | process Ejection +----------->+ Execute _EJ0 method,  |                   
 | request          |            | set eject bit in flags|                   
 +------------------+            +-----------------------+                   
           |failure                         |                                
           v                                v                                
 +------------------------+      +-----------------------+                   
 | OSPM:                  |      | QEMU:                 |                   
 | set OST event & status |      | call device unplug cb |                   
 | fields                 |      |                       |                   
 +------------------------+      +-----------------------+                   
          |                                  |                               
          v                                  v                               
 +------------------+              +-------------------+                     
 |QEMU:             |              |QEMU:              |                     
 |Send OST QMP event|              |Send device deleted|                     
 |                  |              |QMP event          |                     
 +------------------+              |                   |                     
                                   +-------------------+
62 changes: 61 additions & 1 deletion hw/acpi/aml-build.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <string.h>
#include "hw/acpi/aml-build.h"
#include "qemu/bswap.h"
#include "hw/acpi/bios-linker-loader.h"

static GArray *build_alloc_array(void)
{
Expand Down Expand Up @@ -635,9 +636,11 @@ Aml *aml_reserved_field(unsigned length)
}

/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefField */
Aml *aml_field(const char *name, AmlFieldFlags flags)
Aml *aml_field(const char *name, AmlAccessType type, AmlUpdateRule rule)
{
Aml *var = aml_bundle(0x81 /* FieldOp */, AML_EXT_PACKAGE);
uint8_t flags = rule << 5 | type;

build_append_namestring(var->buf, "%s", name);
build_append_byte(var->buf, flags);
return var;
Expand Down Expand Up @@ -891,3 +894,60 @@ Aml *aml_qword_memory(AmlDecode dec, AmlMinFixed min_fixed,
dec, addr_gran, addr_min, addr_max,
addr_trans, len, flags);
}

void
build_header(GArray *linker, GArray *table_data,
AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
{
memcpy(&h->signature, sig, 4);
h->length = cpu_to_le32(len);
h->revision = rev;
memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
memcpy(h->oem_table_id, ACPI_BUILD_APPNAME4, 4);
memcpy(h->oem_table_id + 4, sig, 4);
h->oem_revision = cpu_to_le32(1);
memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);
h->asl_compiler_revision = cpu_to_le32(1);
h->checksum = 0;
/* Checksum to be filled in by Guest linker */
bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE,
table_data->data, h, len, &h->checksum);
}

void *acpi_data_push(GArray *table_data, unsigned size)
{
unsigned off = table_data->len;
g_array_set_size(table_data, off + size);
return table_data->data + off;
}

unsigned acpi_data_len(GArray *table)
{
#if GLIB_CHECK_VERSION(2, 22, 0)
assert(g_array_get_element_size(table) == 1);
#endif
return table->len;
}

void acpi_add_table(GArray *table_offsets, GArray *table_data)
{
uint32_t offset = cpu_to_le32(table_data->len);
g_array_append_val(table_offsets, offset);
}

void acpi_build_tables_init(AcpiBuildTables *tables)
{
tables->rsdp = g_array_new(false, true /* clear */, 1);
tables->table_data = g_array_new(false, true /* clear */, 1);
tables->tcpalog = g_array_new(false, true /* clear */, 1);
tables->linker = bios_linker_loader_init();
}

void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
{
void *linker_data = bios_linker_loader_cleanup(tables->linker);
g_free(linker_data);
g_array_free(tables->rsdp, true);
g_array_free(tables->table_data, true);
g_array_free(tables->tcpalog, mfre);
}
19 changes: 15 additions & 4 deletions hw/acpi/ich9.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,15 +400,26 @@ void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp)
void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, DeviceState *dev,
Error **errp)
{
error_setg(errp, "acpi: device unplug request for not supported device"
" type: %s", object_get_typename(OBJECT(dev)));
if (pm->acpi_memory_hotplug.is_enabled &&
object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
acpi_memory_unplug_request_cb(&pm->acpi_regs, pm->irq,
&pm->acpi_memory_hotplug, dev, errp);
} else {
error_setg(errp, "acpi: device unplug request for not supported device"
" type: %s", object_get_typename(OBJECT(dev)));
}
}

void ich9_pm_device_unplug_cb(ICH9LPCPMRegs *pm, DeviceState *dev,
Error **errp)
{
error_setg(errp, "acpi: device unplug for not supported device"
" type: %s", object_get_typename(OBJECT(dev)));
if (pm->acpi_memory_hotplug.is_enabled &&
object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
acpi_memory_unplug_cb(&pm->acpi_memory_hotplug, dev, errp);
} else {
error_setg(errp, "acpi: device unplug for not supported device"
" type: %s", object_get_typename(OBJECT(dev)));
}
}

void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list)
Expand Down
Loading

0 comments on commit 0403b0f

Please sign in to comment.