On Tue, Oct 18, 2016 at 03:55:11PM -0600, Logan Gunthorpe wrote: > An iopmem device is one which exposes volatile or non-volatile memory mapped > directly to a BAR region. One purpose is to provide buffers to do peer > to peer transfers on the bus. As such this device uses QEMU's drive > backing store to simulate non-volatile memory and provides through a > mapped BAR window. > > This patch creates an emulated device which helps to test and debug the > kernel driver for iopmem while hardware availability is poor. A kernel > patch for a driver is being prepared simultaneously. > > Signed-off-by: Logan Gunthorpe <log...@deltatee.com> > Signed-off-by: Stephen Bates <sba...@raithlin.com>
QEMU already has NVDIMM support (https://pmem.io/). It can be used both for passthrough and fake non-volatile memory: qemu-system-x86_64 \ -M pc,nvdimm=on \ -m 1024,maxmem=$((4096 * 1024 * 1024)),slots=2 \ -object memory-backend-file,id=mem0,mem-path=/tmp/foo,size=$((64 * 1024 * 1024)) \ -device nvdimm,memdev=mem0 Please explain where iopmem comes from, where the hardware spec is, etc? Perhaps you could use nvdimm instead of adding a new device? > --- > default-configs/pci.mak | 1 + > hw/block/Makefile.objs | 1 + > hw/block/iopmem.c | 141 > +++++++++++++++++++++++++++++++++++++++++++++++ > include/hw/pci/pci_ids.h | 2 + > 4 files changed, 145 insertions(+) > create mode 100644 hw/block/iopmem.c > > diff --git a/default-configs/pci.mak b/default-configs/pci.mak > index fff7ce3..aef2b35 100644 > --- a/default-configs/pci.mak > +++ b/default-configs/pci.mak > @@ -39,3 +39,4 @@ CONFIG_VGA=y > CONFIG_VGA_PCI=y > CONFIG_IVSHMEM=$(CONFIG_EVENTFD) > CONFIG_ROCKER=y > +CONFIG_IOPMEM_PCI=y > diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs > index d4c3ab7..1c8044b 100644 > --- a/hw/block/Makefile.objs > +++ b/hw/block/Makefile.objs > @@ -8,6 +8,7 @@ common-obj-$(CONFIG_XEN_BACKEND) += xen_disk.o > common-obj-$(CONFIG_ECC) += ecc.o > common-obj-$(CONFIG_ONENAND) += onenand.o > common-obj-$(CONFIG_NVME_PCI) += nvme.o > +common-obj-$(CONFIG_IOPMEM_PCI) += iopmem.o > > obj-$(CONFIG_SH4) += tc58128.o > > diff --git a/hw/block/iopmem.c b/hw/block/iopmem.c > new file mode 100644 > index 0000000..9c2d716 > --- /dev/null > +++ b/hw/block/iopmem.c > @@ -0,0 +1,141 @@ > +/* > + * QEMU iopmem Controller > + * > + * Copyright (c) 2016, Microsemi Corporation > + * > + * Written by Logan Gunthorpe <log...@deltatee.com> > + * > + * This code is licensed under the GNU GPL v2 or later. > + */ > + > + > +/** > + * Usage: add options: > + * -drive file=<file>,if=none,id=<drive_id> > + * -device iopmem,drive=<drive_id>,id=<id[optional]> > + */ > + > +#include "qemu/osdep.h" > +#include "hw/pci/pci.h" > +#include "sysemu/block-backend.h" > + > +typedef struct IoPmemCtrl { > + PCIDevice parent_obj; > + MemoryRegion iomem; > + BlockBackend *blk; > + uint64_t size; > +} IoPmemCtrl; > + > +#define TYPE_IOPMEM "iopmem" > +#define IOPMEM(obj) \ > + OBJECT_CHECK(IoPmemCtrl, (obj), TYPE_IOPMEM) > + > +static uint64_t iopmem_bar_read(void *opaque, hwaddr addr, unsigned size) > +{ > + IoPmemCtrl *ipm = (IoPmemCtrl *)opaque; > + uint64_t val; > + > + blk_pread(ipm->blk, addr, &val, size); > + > + return val; > +} > + > +static void iopmem_bar_write(void *opaque, hwaddr addr, uint64_t data, > + unsigned size) > +{ > + IoPmemCtrl *ipm = (IoPmemCtrl *)opaque; > + > + if (addr & 3) { > + return; > + } > + > + blk_pwrite(ipm->blk, addr, &data, size, 0); > +} This has terrible performance because blk_pread()/blk_pwrite() are synchronous operations. The vcpu thread is paused while QEMU is waiting for I/O.
signature.asc
Description: PGP signature