Commit b384cd95 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/ehabkost/tags/machine-next-pull-request' into staging



machine queue, 2018-01-19

# gpg: Signature made Fri 19 Jan 2018 16:30:19 GMT
# gpg:                using RSA key 0x2807936F984DC5A6
# gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>"
# Primary key fingerprint: 5A32 2FD5 ABC4 D3DB ACCF  D1AA 2807 936F 984D C5A6

* remotes/ehabkost/tags/machine-next-pull-request:
  fw_cfg: fix memory corruption when all fw_cfg slots are used
  possible_cpus: add CPUArchId::type field
  nvdimm: add 'unarmed' option
  nvdimm: add a macro for property "label-size"
  hostmem-file: add "align" option
  scripts: Remove fixed entries from the device-crash-test
  qdev: Check for the availability of a hotplug controller before adding a device
  qdev_monitor: Simplify error handling in qdev_device_add()
  q35: Allow only supported dynamic sysbus devices
  xen: Add only xen-sysdev to dynamic sysbus device list
  spapr: Allow only supported dynamic sysbus devices
  ppc: e500: Allow only supported dynamic sysbus devices
  hw/arm/virt: Allow only supported dynamic sysbus devices
  machine: Replace has_dynamic_sysbus with list of allowed devices
  numa: fix missing '-numa cpu' in '-help' output
  qemu-options: document memory-backend-ram
  qemu-options: document missing memory-backend-file options
  memfd: remove needless include
  memfd: split qemu_memfd_alloc()

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 3e5bdc65 d6b6abc5
Loading
Loading
Loading
Loading
+40 −1
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ struct HostMemoryBackendFile {
    bool share;
    bool discard_data;
    char *mem_path;
    uint64_t align;
};

static void
@@ -58,7 +59,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
        path = object_get_canonical_path(OBJECT(backend));
        memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
                                 path,
                                 backend->size, fb->share,
                                 backend->size, fb->align, fb->share,
                                 fb->mem_path, errp);
        g_free(path);
    }
@@ -115,6 +116,40 @@ static void file_memory_backend_set_discard_data(Object *o, bool value,
    MEMORY_BACKEND_FILE(o)->discard_data = value;
}

static void file_memory_backend_get_align(Object *o, Visitor *v,
                                          const char *name, void *opaque,
                                          Error **errp)
{
    HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
    uint64_t val = fb->align;

    visit_type_size(v, name, &val, errp);
}

static void file_memory_backend_set_align(Object *o, Visitor *v,
                                          const char *name, void *opaque,
                                          Error **errp)
{
    HostMemoryBackend *backend = MEMORY_BACKEND(o);
    HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
    Error *local_err = NULL;
    uint64_t val;

    if (host_memory_backend_mr_inited(backend)) {
        error_setg(&local_err, "cannot change property value");
        goto out;
    }

    visit_type_size(v, name, &val, &local_err);
    if (local_err) {
        goto out;
    }
    fb->align = val;

 out:
    error_propagate(errp, local_err);
}

static void file_backend_unparent(Object *obj)
{
    HostMemoryBackend *backend = MEMORY_BACKEND(obj);
@@ -145,6 +180,10 @@ file_backend_class_init(ObjectClass *oc, void *data)
    object_class_property_add_str(oc, "mem-path",
        get_mem_path, set_mem_path,
        &error_abort);
    object_class_property_add(oc, "align", "int",
        file_memory_backend_get_align,
        file_memory_backend_set_align,
        NULL, NULL, &error_abort);
}

static void file_backend_instance_finalize(Object *o)
+31 −0
Original line number Diff line number Diff line
@@ -122,3 +122,34 @@ Note:
     M >= size of RAM devices +
          size of statically plugged vNVDIMM devices +
          size of hotplugged vNVDIMM devices

Alignment
---------

QEMU uses mmap(2) to maps vNVDIMM backends and aligns the mapping
address to the page size (getpagesize(2)) by default. However, some
types of backends may require an alignment different than the page
size. In that case, QEMU v2.12.0 and later provide 'align' option to
memory-backend-file to allow users to specify the proper alignment.

For example, device dax require the 2 MB alignment, so we can use
following QEMU command line options to use it (/dev/dax0.0) as the
backend of vNVDIMM:

 -object memory-backend-file,id=mem1,share=on,mem-path=/dev/dax0.0,size=4G,align=2M
 -device nvdimm,id=nvdimm1,memdev=mem1

Guest Data Persistence
----------------------

Though QEMU supports multiple types of vNVDIMM backends on Linux,
currently the only one that can guarantee the guest write persistence
is the device DAX on the real NVDIMM device (e.g., /dev/dax0.0), to
which all guest access do not involve any host-side kernel cache.

When using other types of backends, it's suggested to set 'unarmed'
option of '-device nvdimm' to 'on', which sets the unarmed flag of the
guest NVDIMM region mapping structure.  This unarmed flag indicates
guest software that this vNVDIMM device contains a region that cannot
accept persistent writes. In result, for example, the guest Linux
NVDIMM driver, marks such vNVDIMM device as read-only.
+7 −1
Original line number Diff line number Diff line
@@ -1612,7 +1612,13 @@ static void *file_ram_alloc(RAMBlock *block,
    void *area;

    block->page_size = qemu_fd_getpagesize(fd);
    block->mr->align = block->page_size;
    if (block->mr->align % block->page_size) {
        error_setg(errp, "alignment 0x%" PRIx64
                   " must be multiples of page size 0x%zx",
                   block->mr->align, block->page_size);
        return NULL;
    }
    block->mr->align = MAX(block->page_size, block->mr->align);
#if defined(__s390x__)
    if (kvm_enabled()) {
        block->mr->align = MAX(block->mr->align, QEMU_VMALLOC_ALIGN);
+7 −0
Original line number Diff line number Diff line
@@ -138,6 +138,8 @@ struct NvdimmNfitMemDev {
} QEMU_PACKED;
typedef struct NvdimmNfitMemDev NvdimmNfitMemDev;

#define ACPI_NFIT_MEM_NOT_ARMED     (1 << 3)

/*
 * NVDIMM Control Region Structure
 *
@@ -284,6 +286,7 @@ static void
nvdimm_build_structure_memdev(GArray *structures, DeviceState *dev)
{
    NvdimmNfitMemDev *nfit_memdev;
    NVDIMMDevice *nvdimm = NVDIMM(OBJECT(dev));
    uint64_t size = object_property_get_uint(OBJECT(dev), PC_DIMM_SIZE_PROP,
                                             NULL);
    int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP,
@@ -312,6 +315,10 @@ nvdimm_build_structure_memdev(GArray *structures, DeviceState *dev)

    /* Only one interleave for PMEM. */
    nfit_memdev->interleave_ways = cpu_to_le16(1);

    if (nvdimm->unarmed) {
        nfit_memdev->flags |= cpu_to_le16(ACPI_NFIT_MEM_NOT_ARMED);
    }
}

/*
+6 −2
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@
#include "hw/arm/arm.h"
#include "hw/arm/primecell.h"
#include "hw/arm/virt.h"
#include "hw/vfio/vfio-calxeda-xgmac.h"
#include "hw/vfio/vfio-amd-xgbe.h"
#include "hw/devices.h"
#include "net/net.h"
#include "sysemu/block-backend.h"
@@ -1357,7 +1359,7 @@ static void machvirt_init(MachineState *machine)
            break;
        }

        cpuobj = object_new(machine->cpu_type);
        cpuobj = object_new(possible_cpus->cpus[n].type);
        object_property_set_int(cpuobj, possible_cpus->cpus[n].arch_id,
                                "mp-affinity", NULL);

@@ -1573,6 +1575,7 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
                                  sizeof(CPUArchId) * max_cpus);
    ms->possible_cpus->len = max_cpus;
    for (n = 0; n < ms->possible_cpus->len; n++) {
        ms->possible_cpus->cpus[n].type = ms->cpu_type;
        ms->possible_cpus->cpus[n].arch_id =
            virt_cpu_mp_affinity(vms, n);
        ms->possible_cpus->cpus[n].props.has_thread_id = true;
@@ -1591,7 +1594,8 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
     * configuration of the particular instance.
     */
    mc->max_cpus = 255;
    mc->has_dynamic_sysbus = true;
    machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_CALXEDA_XGMAC);
    machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_AMD_XGBE);
    mc->block_default_type = IF_VIRTIO;
    mc->no_cdrom = 1;
    mc->pci_allow_0_address = true;
Loading