Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:FrontRunner
qemu.18973
0083-nvdimm-add-unarmed-option.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0083-nvdimm-add-unarmed-option.patch of Package qemu.18973
From: Haozhong Zhang <haozhong.zhang@intel.com> Date: Mon, 11 Dec 2017 15:28:06 +0800 Subject: nvdimm: add 'unarmed' option Include-If: %if 0%{?suse_version} == 1315 Currently the only vNVDIMM backend can guarantee the guest write persistence is device DAX on Linux, because no host-side kernel cache is involved in the guest access to it. The approach to detect whether the backend is device DAX needs to access sysfs, which may not work with SELinux. Instead, we add the 'unarmed' option to device 'nvdimm', so that users or management utils, which have enough knowledge about the backend, can control the unarmed flag in guest ACPI NFIT via this option. The guest Linux NVDIMM driver, for example, will mark the corresponding vNVDIMM device read-only if the unarmed flag in guest NFIT is set. The default value of 'unarmed' option is 'off' in order to keep the backwards compatibility. Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com> Message-Id: <20171211072806.2812-4-haozhong.zhang@intel.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> (cherry picked from commit cb836434cda103fac3c06174e70bf5c9b7083b8e) [BR: FATE#325135] Signed-off-by: Bruce Rogers <brogers@suse.com> --- docs/nvdimm.txt | 15 +++++++++++++++ hw/acpi/nvdimm.c | 7 +++++++ hw/mem/nvdimm.c | 26 ++++++++++++++++++++++++++ include/hw/mem/nvdimm.h | 9 +++++++++ 4 files changed, 57 insertions(+) diff --git a/docs/nvdimm.txt b/docs/nvdimm.txt index 21249dd0626aea3e49c244e5bfd3..e903d8bb093b53b8d9ae71c89d52 100644 --- a/docs/nvdimm.txt +++ b/docs/nvdimm.txt @@ -138,3 +138,18 @@ 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. diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c index 6ceea196e70ab8d5ef0c5e7750fb..59d6e4254ccde9d2534d4bee7f31 100644 --- a/hw/acpi/nvdimm.c +++ b/hw/acpi/nvdimm.c @@ -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); + } } /* diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c index 618c3d677b06b679e7216ed2a719..61e677f92ff2d407b01f60d0c95e 100644 --- a/hw/mem/nvdimm.c +++ b/hw/mem/nvdimm.c @@ -25,6 +25,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qapi/visitor.h" +#include "qapi-visit.h" #include "hw/mem/nvdimm.h" static void nvdimm_get_label_size(Object *obj, Visitor *v, const char *name, @@ -64,11 +65,36 @@ out: error_propagate(errp, local_err); } +static bool nvdimm_get_unarmed(Object *obj, Error **errp) +{ + NVDIMMDevice *nvdimm = NVDIMM(obj); + + return nvdimm->unarmed; +} + +static void nvdimm_set_unarmed(Object *obj, bool value, Error **errp) +{ + NVDIMMDevice *nvdimm = NVDIMM(obj); + Error *local_err = NULL; + + if (memory_region_size(&nvdimm->nvdimm_mr)) { + error_setg(&local_err, "cannot change property value"); + goto out; + } + + nvdimm->unarmed = value; + + out: + error_propagate(errp, local_err); +} + static void nvdimm_init(Object *obj) { object_property_add(obj, NVDIMM_LABLE_SIZE_PROP, "int", nvdimm_get_label_size, nvdimm_set_label_size, NULL, NULL, NULL); + object_property_add_bool(obj, NVDIMM_UNARMED_PROP, + nvdimm_get_unarmed, nvdimm_set_unarmed, NULL); } static MemoryRegion *nvdimm_get_memory_region(PCDIMMDevice *dimm, Error **errp) diff --git a/include/hw/mem/nvdimm.h b/include/hw/mem/nvdimm.h index 28e68ddf59c705fb9e54ec4ed46d..7fd87c4e1cef470e4727b724f359 100644 --- a/include/hw/mem/nvdimm.h +++ b/include/hw/mem/nvdimm.h @@ -49,6 +49,7 @@ TYPE_NVDIMM) #define NVDIMM_LABLE_SIZE_PROP "label-size" +#define NVDIMM_UNARMED_PROP "unarmed" struct NVDIMMDevice { /* private */ @@ -74,6 +75,14 @@ struct NVDIMMDevice { * guest via ACPI NFIT and _FIT method if NVDIMM hotplug is supported. */ MemoryRegion nvdimm_mr; + + /* + * The 'on' value results in the unarmed flag set in ACPI NFIT, + * which can be used to notify guest implicitly that the host + * backend (e.g., files on HDD, /dev/pmemX, etc.) cannot guarantee + * the guest write persistence. + */ + bool unarmed; }; typedef struct NVDIMMDevice NVDIMMDevice;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor