vmm: Add a "discard_writes=" to --pmem

This opens the backing file read-only, makes the pages in the mmap()
read-only and also makes the KVM mapping read-only. The file is also
mapped with MAP_PRIVATE to make the changes local to this process only.

This is functional alternative to having support for making a
virtio-pmem device readonly. Unfortunately there is no concept of
readonly virtio-pmem (or any type of NVDIMM/PMEM) in the Linux kernel so
to be able to have a block device that is appears readonly in the guest
requires significant specification and kernel changes.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford
2020-03-19 10:13:53 +00:00
committed by Sebastien Boeuf
parent d11a67b0fe
commit f7197e8415
4 changed files with 20 additions and 6 deletions

View File

@@ -27,7 +27,7 @@ use arch::layout::{APIC_START, IOAPIC_SIZE, IOAPIC_START};
use devices::{ioapic, BusDevice, HotPlugNotificationFlags};
use kvm_ioctls::*;
use libc::TIOCGWINSZ;
use libc::{MAP_NORESERVE, MAP_SHARED, O_RDONLY, O_TMPFILE, PROT_READ, PROT_WRITE};
use libc::{MAP_NORESERVE, MAP_PRIVATE, MAP_SHARED, O_TMPFILE, PROT_READ, PROT_WRITE};
#[cfg(feature = "pci_support")]
use pci::{
DeviceRelocation, PciBarRegionType, PciBus, PciConfigIo, PciConfigMmio, PciDevice, PciRoot,
@@ -1392,7 +1392,7 @@ impl DeviceManager {
let file = OpenOptions::new()
.read(true)
.write(true)
.write(!pmem_cfg.discard_writes)
.custom_flags(custom_flags)
.open(&pmem_cfg.file)
.map_err(DeviceManagerError::PmemFileOpen)?;
@@ -1406,12 +1406,17 @@ impl DeviceManager {
let mmap_region = MmapRegion::build(
Some(FileOffset::new(cloned_file, 0)),
size as usize,
if pmem_cfg.readonly {
if pmem_cfg.discard_writes {
PROT_READ
} else {
PROT_READ | PROT_WRITE
},
MAP_NORESERVE | MAP_SHARED,
MAP_NORESERVE
| if pmem_cfg.discard_writes {
MAP_PRIVATE
} else {
MAP_SHARED
},
)
.map_err(DeviceManagerError::NewMmapRegion)?;
let addr: u64 = mmap_region.as_ptr() as u64;
@@ -1426,7 +1431,7 @@ impl DeviceManager {
size,
addr,
pmem_cfg.mergeable,
false,
pmem_cfg.discard_writes,
)
.map_err(DeviceManagerError::MemoryManager)?;