Commit faf8a13d authored by Junyan He's avatar Junyan He Committed by Michael S. Tsirkin
Browse files

mem/nvdimm: ensure write persistence to PMEM in label emulation



Guest writes to vNVDIMM labels are intercepted and performed on the
backend by QEMU. When the backend is a real persistent memort, QEMU
needs to take proper operations to ensure its write persistence on the
persistent memory. Otherwise, a host power failure may result in the
loss of guest label configurations.

Signed-off-by: default avatarHaozhong Zhang <haozhong.zhang@intel.com>
Reviewed-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: default avatarIgor Mammedov <imammedo@redhat.com>
Reviewed-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Reviewed-by: default avatarRichard Henderson <richard.henderson@linaro.org>
parent a4de8552
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
 */

#include "qemu/osdep.h"
#include "qemu/pmem.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "hw/mem/nvdimm.h"
@@ -164,11 +165,17 @@ static void nvdimm_write_label_data(NVDIMMDevice *nvdimm, const void *buf,
{
    MemoryRegion *mr;
    PCDIMMDevice *dimm = PC_DIMM(nvdimm);
    bool is_pmem = object_property_get_bool(OBJECT(dimm->hostmem),
                                            "pmem", NULL);
    uint64_t backend_offset;

    nvdimm_validate_rw_label_data(nvdimm, size, offset);

    if (!is_pmem) {
        memcpy(nvdimm->label_data + offset, buf, size);
    } else {
        pmem_memcpy_persist(nvdimm->label_data + offset, buf, size);
    }

    mr = host_memory_backend_get_memory(dimm->hostmem);
    backend_offset = memory_region_size(mr) - nvdimm->label_size + offset;

include/qemu/pmem.h

0 → 100644
+30 −0
Original line number Diff line number Diff line
/*
 * QEMU header file for libpmem.
 *
 * Copyright (c) 2018 Intel Corporation.
 *
 * Author: Haozhong Zhang <address@hidden>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#ifndef QEMU_PMEM_H
#define QEMU_PMEM_H

#ifdef CONFIG_LIBPMEM
#include <libpmem.h>
#else  /* !CONFIG_LIBPMEM */

static inline void *
pmem_memcpy_persist(void *pmemdest, const void *src, size_t len)
{
    /* If 'pmem' option is 'on', we should always have libpmem support,
       or qemu will report a error and exit, never come here. */
    g_assert_not_reached();
    return NULL;
}

#endif /* CONFIG_LIBPMEM */

#endif /* !QEMU_PMEM_H */