From nobody Sun Apr 28 21:19:13 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507823809262286.4773268213811; Thu, 12 Oct 2017 08:56:49 -0700 (PDT) Received: from localhost ([::1]:46194 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2fqb-00076p-Hw for importer@patchew.org; Thu, 12 Oct 2017 11:56:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40009) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2flM-0003F7-QP for qemu-devel@nongnu.org; Thu, 12 Oct 2017 11:51:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2flI-0001PK-PX for qemu-devel@nongnu.org; Thu, 12 Oct 2017 11:51:08 -0400 Received: from mx1.redhat.com ([209.132.183.28]:52734) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2flI-0001Oq-HI for qemu-devel@nongnu.org; Thu, 12 Oct 2017 11:51:04 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 63AC3A0C01; Thu, 12 Oct 2017 15:51:03 +0000 (UTC) Received: from dhcp201-121.englab.pnq.redhat.com (ovpn-116-26.sin2.redhat.com [10.67.116.26]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1A569413E; Thu, 12 Oct 2017 15:50:50 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 63AC3A0C01 Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=pagupta@redhat.com From: Pankaj Gupta To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, qemu-devel@nongnu.org, linux-nvdimm@ml01.01.org, linux-mm@kvack.org Date: Thu, 12 Oct 2017 21:20:25 +0530 Message-Id: <20171012155027.3277-2-pagupta@redhat.com> In-Reply-To: <20171012155027.3277-1-pagupta@redhat.com> References: <20171012155027.3277-1-pagupta@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 12 Oct 2017 15:51:03 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC 1/2] pmem: Move reusable code to base header files X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, haozhong.zhang@intel.com, jack@suse.cz, xiaoguangrong.eric@gmail.com, david@redhat.com, pagupta@redhat.com, ross.zwisler@intel.com, stefanha@redhat.com, pbonzini@redhat.com, dan.j.williams@intel.com, nilal@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This patch moves common code to base header files so that it can be used for both ACPI pmem and VIRTIO pmem drivers. More common code needs to be moved out in future based on functionality required for virtio_pmem driver and=20 coupling of code with existing ACPI pmem driver. Signed-off-by: Pankaj Gupta --- drivers/nvdimm/pfn.h | 14 ------------ drivers/nvdimm/pfn_devs.c | 20 ----------------- drivers/nvdimm/pmem.c | 40 ---------------------------------- drivers/nvdimm/pmem.h | 5 +---- include/linux/memremap.h | 23 ++++++++++++++++++++ include/linux/pfn.h | 15 +++++++++++++ include/linux/pmem_common.h | 52 +++++++++++++++++++++++++++++++++++++++++= ++++ 7 files changed, 91 insertions(+), 78 deletions(-) create mode 100644 include/linux/pmem_common.h diff --git a/drivers/nvdimm/pfn.h b/drivers/nvdimm/pfn.h index dde9853453d3..1a853f651faf 100644 --- a/drivers/nvdimm/pfn.h +++ b/drivers/nvdimm/pfn.h @@ -40,18 +40,4 @@ struct nd_pfn_sb { __le64 checksum; }; =20 -#ifdef CONFIG_SPARSEMEM -#define PFN_SECTION_ALIGN_DOWN(x) SECTION_ALIGN_DOWN(x) -#define PFN_SECTION_ALIGN_UP(x) SECTION_ALIGN_UP(x) -#else -/* - * In this case ZONE_DEVICE=3Dn and we will disable 'pfn' device support, - * but we still want pmem to compile. - */ -#define PFN_SECTION_ALIGN_DOWN(x) (x) -#define PFN_SECTION_ALIGN_UP(x) (x) -#endif - -#define PHYS_SECTION_ALIGN_DOWN(x) PFN_PHYS(PFN_SECTION_ALIGN_DOWN(PHYS_PF= N(x))) -#define PHYS_SECTION_ALIGN_UP(x) PFN_PHYS(PFN_SECTION_ALIGN_UP(PHYS_PFN(x)= )) #endif /* __NVDIMM_PFN_H */ diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c index 9576c444f0ab..52d6923e92fc 100644 --- a/drivers/nvdimm/pfn_devs.c +++ b/drivers/nvdimm/pfn_devs.c @@ -513,26 +513,6 @@ int nd_pfn_probe(struct device *dev, struct nd_namespa= ce_common *ndns) } EXPORT_SYMBOL(nd_pfn_probe); =20 -/* - * We hotplug memory at section granularity, pad the reserved area from - * the previous section base to the namespace base address. - */ -static unsigned long init_altmap_base(resource_size_t base) -{ - unsigned long base_pfn =3D PHYS_PFN(base); - - return PFN_SECTION_ALIGN_DOWN(base_pfn); -} - -static unsigned long init_altmap_reserve(resource_size_t base) -{ - unsigned long reserve =3D PHYS_PFN(SZ_8K); - unsigned long base_pfn =3D PHYS_PFN(base); - - reserve +=3D base_pfn - PFN_SECTION_ALIGN_DOWN(base_pfn); - return reserve; -} - static struct vmem_altmap *__nvdimm_setup_pfn(struct nd_pfn *nd_pfn, struct resource *res, struct vmem_altmap *altmap) { diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 39dfd7affa31..5075131b715b 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -77,46 +77,6 @@ static blk_status_t pmem_clear_poison(struct pmem_device= *pmem, return rc; } =20 -static void write_pmem(void *pmem_addr, struct page *page, - unsigned int off, unsigned int len) -{ - unsigned int chunk; - void *mem; - - while (len) { - mem =3D kmap_atomic(page); - chunk =3D min_t(unsigned int, len, PAGE_SIZE); - memcpy_flushcache(pmem_addr, mem + off, chunk); - kunmap_atomic(mem); - len -=3D chunk; - off =3D 0; - page++; - pmem_addr +=3D PAGE_SIZE; - } -} - -static blk_status_t read_pmem(struct page *page, unsigned int off, - void *pmem_addr, unsigned int len) -{ - unsigned int chunk; - int rc; - void *mem; - - while (len) { - mem =3D kmap_atomic(page); - chunk =3D min_t(unsigned int, len, PAGE_SIZE); - rc =3D memcpy_mcsafe(mem + off, pmem_addr, chunk); - kunmap_atomic(mem); - if (rc) - return BLK_STS_IOERR; - len -=3D chunk; - off =3D 0; - page++; - pmem_addr +=3D PAGE_SIZE; - } - return BLK_STS_OK; -} - static blk_status_t pmem_do_bvec(struct pmem_device *pmem, struct page *pa= ge, unsigned int len, unsigned int off, bool is_write, sector_t sector) diff --git a/drivers/nvdimm/pmem.h b/drivers/nvdimm/pmem.h index c5917f040fa7..8c5620614ec0 100644 --- a/drivers/nvdimm/pmem.h +++ b/drivers/nvdimm/pmem.h @@ -1,9 +1,6 @@ #ifndef __NVDIMM_PMEM_H__ #define __NVDIMM_PMEM_H__ -#include -#include -#include -#include +#include =20 /* this definition is in it's own header for tools/testing/nvdimm to consu= me */ struct pmem_device { diff --git a/include/linux/memremap.h b/include/linux/memremap.h index 79f8ba7c3894..e4eb81020306 100644 --- a/include/linux/memremap.h +++ b/include/linux/memremap.h @@ -3,12 +3,35 @@ #include #include #include +#include +#include =20 #include =20 struct resource; struct device; =20 +/* + * We hotplug memory at section granularity, pad the reserved area from + * the previous section base to the namespace base address. + */ +static inline unsigned long init_altmap_base(resource_size_t base) +{ + unsigned long base_pfn =3D PHYS_PFN(base); + + return PFN_SECTION_ALIGN_DOWN(base_pfn); +} + +static inline unsigned long init_altmap_reserve(resource_size_t base) +{ + unsigned long reserve =3D PHYS_PFN(SZ_8K); + unsigned long base_pfn =3D PHYS_PFN(base); + + reserve +=3D base_pfn - PFN_SECTION_ALIGN_DOWN(base_pfn); + return reserve; +} + + /** * struct vmem_altmap - pre-allocated storage for vmemmap_populate * @base_pfn: base of the entire dev_pagemap mapping diff --git a/include/linux/pfn.h b/include/linux/pfn.h index 1132953235c0..2d8f69cc1470 100644 --- a/include/linux/pfn.h +++ b/include/linux/pfn.h @@ -20,4 +20,19 @@ typedef struct { #define PFN_PHYS(x) ((phys_addr_t)(x) << PAGE_SHIFT) #define PHYS_PFN(x) ((unsigned long)((x) >> PAGE_SHIFT)) =20 +#ifdef CONFIG_SPARSEMEM +#define PFN_SECTION_ALIGN_DOWN(x) SECTION_ALIGN_DOWN(x) +#define PFN_SECTION_ALIGN_UP(x) SECTION_ALIGN_UP(x) +#else +/* + * In this case ZONE_DEVICE=3Dn and we will disable 'pfn' device support, + * but we still want pmem to compile. + */ +#define PFN_SECTION_ALIGN_DOWN(x) (x) +#define PFN_SECTION_ALIGN_UP(x) (x) +#endif + +#define PHYS_SECTION_ALIGN_DOWN(x) PFN_PHYS(PFN_SECTION_ALIGN_DOWN(PHYS_PF= N(x))) +#define PHYS_SECTION_ALIGN_UP(x) PFN_PHYS(PFN_SECTION_ALIGN_UP(PHYS_PFN(x)= )) + #endif diff --git a/include/linux/pmem_common.h b/include/linux/pmem_common.h new file mode 100644 index 000000000000..e2e718c74b3f --- /dev/null +++ b/include/linux/pmem_common.h @@ -0,0 +1,52 @@ +#ifndef __PMEM_COMMON_H__ +#define __PMEM_COMMON_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void write_pmem(void *pmem_addr, struct page *page, + unsigned int off, unsigned int len) +{ + void *mem =3D kmap_atomic(page); + + memcpy_flushcache(pmem_addr, mem + off, len); + kunmap_atomic(mem); +} + +static blk_status_t read_pmem(struct page *page, unsigned int off, + void *pmem_addr, unsigned int len) +{ + int rc; + void *mem =3D kmap_atomic(page); + + rc =3D memcpy_mcsafe(mem + off, pmem_addr, len); + kunmap_atomic(mem); + if (rc) + return BLK_STS_IOERR; + return BLK_STS_OK; +} + +#endif /* __PMEM_COMMON_H__ */ + +#ifdef CONFIG_ARCH_HAS_PMEM_API +#define ARCH_MEMREMAP_PMEM MEMREMAP_WB +void arch_wb_cache_pmem(void *addr, size_t size); +void arch_invalidate_pmem(void *addr, size_t size); +#else +#define ARCH_MEMREMAP_PMEM MEMREMAP_WT +static inline void arch_wb_cache_pmem(void *addr, size_t size) +{ +} +static inline void arch_invalidate_pmem(void *addr, size_t size) +{ +} +#endif --=20 2.13.0 From nobody Sun Apr 28 21:19:13 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507823874648507.70787229362077; Thu, 12 Oct 2017 08:57:54 -0700 (PDT) Received: from localhost ([::1]:46200 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2frm-0007mH-Hd for importer@patchew.org; Thu, 12 Oct 2017 11:57:46 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40098) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2fla-0003Nh-OS for qemu-devel@nongnu.org; Thu, 12 Oct 2017 11:51:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2flY-0001bm-Vq for qemu-devel@nongnu.org; Thu, 12 Oct 2017 11:51:22 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40172) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2flY-0001bP-Md for qemu-devel@nongnu.org; Thu, 12 Oct 2017 11:51:20 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 98E212C975F; Thu, 12 Oct 2017 15:51:19 +0000 (UTC) Received: from dhcp201-121.englab.pnq.redhat.com (ovpn-116-26.sin2.redhat.com [10.67.116.26]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1B9D517ADC; Thu, 12 Oct 2017 15:51:03 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 98E212C975F Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=pagupta@redhat.com From: Pankaj Gupta To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, qemu-devel@nongnu.org, linux-nvdimm@ml01.01.org, linux-mm@kvack.org Date: Thu, 12 Oct 2017 21:20:26 +0530 Message-Id: <20171012155027.3277-3-pagupta@redhat.com> In-Reply-To: <20171012155027.3277-1-pagupta@redhat.com> References: <20171012155027.3277-1-pagupta@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Thu, 12 Oct 2017 15:51:19 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC 2/2] KVM: add virtio-pmem driver X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, haozhong.zhang@intel.com, jack@suse.cz, xiaoguangrong.eric@gmail.com, david@redhat.com, pagupta@redhat.com, ross.zwisler@intel.com, stefanha@redhat.com, pbonzini@redhat.com, dan.j.williams@intel.com, nilal@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This patch adds virtio-pmem driver for KVM guest. Guest reads the persistent memory range information over virtio bus from Qemu and reserves the range as persistent memory. Guest also allocates a block device corresponding to the pmem range which later can be accessed with DAX compatible file systems. Idea is to use the virtio channel between guest and host to perform the block device flush for guest pmem=20 DAX device. There is work to do including DAX file system support=20 and other advanced features. Signed-off-by: Pankaj Gupta --- drivers/virtio/Kconfig | 10 ++ drivers/virtio/Makefile | 1 + drivers/virtio/virtio_pmem.c | 322 +++++++++++++++++++++++++++++++++++= ++++ include/uapi/linux/virtio_pmem.h | 55 +++++++ 4 files changed, 388 insertions(+) create mode 100644 drivers/virtio/virtio_pmem.c create mode 100644 include/uapi/linux/virtio_pmem.h diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig index cff773f15b7e..0192c4bda54b 100644 --- a/drivers/virtio/Kconfig +++ b/drivers/virtio/Kconfig @@ -38,6 +38,16 @@ config VIRTIO_PCI_LEGACY =20 If unsure, say Y. =20 +config VIRTIO_PMEM + tristate "Virtio pmem driver" + depends on VIRTIO + ---help--- + This driver adds persistent memory range within a KVM guest. + It also associates a block device corresponding to the pmem + range. + + If unsure, say M. + config VIRTIO_BALLOON tristate "Virtio balloon driver" depends on VIRTIO diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile index 41e30e3dc842..032ade725cc2 100644 --- a/drivers/virtio/Makefile +++ b/drivers/virtio/Makefile @@ -5,3 +5,4 @@ virtio_pci-y :=3D virtio_pci_modern.o virtio_pci_common.o virtio_pci-$(CONFIG_VIRTIO_PCI_LEGACY) +=3D virtio_pci_legacy.o obj-$(CONFIG_VIRTIO_BALLOON) +=3D virtio_balloon.o obj-$(CONFIG_VIRTIO_INPUT) +=3D virtio_input.o +obj-$(CONFIG_VIRTIO_PMEM) +=3D virtio_pmem.o diff --git a/drivers/virtio/virtio_pmem.c b/drivers/virtio/virtio_pmem.c new file mode 100644 index 000000000000..74e47cae0e24 --- /dev/null +++ b/drivers/virtio/virtio_pmem.c @@ -0,0 +1,322 @@ +/* + * virtio-pmem driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void devm_vpmem_disable(struct device *dev, struct resource *res, void *ad= dr) +{ + devm_memunmap(dev, addr); + devm_release_mem_region(dev, res->start, resource_size(res)); +} + +static void pmem_flush_done(struct virtqueue *vq) +{ + return; +}; + +static void virtio_pmem_release_queue(void *q) +{ + blk_cleanup_queue(q); +} + +static void virtio_pmem_freeze_queue(void *q) +{ + blk_freeze_queue_start(q); +} + +static void virtio_pmem_release_disk(void *__pmem) +{ + struct virtio_pmem *pmem =3D __pmem; + + del_gendisk(pmem->disk); + put_disk(pmem->disk); +} + +static int init_vq(struct virtio_pmem *vpmem) +{ + struct virtqueue *vq; + + /* single vq */ + vq =3D virtio_find_single_vq(vpmem->vdev, pmem_flush_done, "flush_queue"); + + if (IS_ERR(vq)) + return PTR_ERR(vq); + + return 0; +} + +static struct vmem_altmap *setup_pmem_pfn(struct virtio_pmem *vpmem, + struct resource *res, struct vmem_altmap *altmap) +{ + u32 start_pad =3D 0, end_trunc =3D 0; + resource_size_t start, size; + unsigned long npfns; + phys_addr_t offset; + + size =3D resource_size(res); + start =3D PHYS_SECTION_ALIGN_DOWN(res->start); + + if (region_intersects(start, size, IORESOURCE_SYSTEM_RAM, + IORES_DESC_NONE) =3D=3D REGION_MIXED) { + + start =3D res->start; + start_pad =3D PHYS_SECTION_ALIGN_UP(start) - start; + } + start =3D res->start; + size =3D PHYS_SECTION_ALIGN_UP(start + size) - start; + + if (region_intersects(start, size, IORESOURCE_SYSTEM_RAM, + IORES_DESC_NONE) =3D=3D REGION_MIXED) { + + size =3D resource_size(res); + end_trunc =3D start + size - + PHYS_SECTION_ALIGN_DOWN(start + size); + } + + start +=3D start_pad; + size =3D resource_size(res); + npfns =3D PFN_SECTION_ALIGN_UP((size - start_pad - end_trunc - SZ_8K) + / PAGE_SIZE); + + /* + * vmemmap_populate_hugepages() allocates the memmap array in + * HPAGE_SIZE chunks. + */ + offset =3D ALIGN(start + SZ_8K + 64 * npfns, HPAGE_SIZE) - start; + vpmem->data_offset =3D offset; + + struct vmem_altmap __altmap =3D { + .base_pfn =3D init_altmap_base(start+start_pad), + .reserve =3D init_altmap_reserve(start+start_pad), + }; + + res->start +=3D start_pad; + res->end -=3D end_trunc; + memcpy(altmap, &__altmap, sizeof(*altmap)); + altmap->free =3D PHYS_PFN(offset - SZ_8K); + altmap->alloc =3D 0; + + return altmap; +} + +static blk_status_t pmem_do_bvec(struct virtio_pmem *pmem, struct page *pa= ge, + unsigned int len, unsigned int off, bool is_write, + sector_t sector) +{ + blk_status_t rc =3D BLK_STS_OK; + phys_addr_t pmem_off =3D sector * 512 + pmem->data_offset; + void *pmem_addr =3D pmem->virt_addr + pmem_off; + + if (!is_write) { + rc =3D read_pmem(page, off, pmem_addr, len); + flush_dcache_page(page); + } else { + flush_dcache_page(page); + write_pmem(pmem_addr, page, off, len); + } + + return rc; +} + +static int vpmem_rw_page(struct block_device *bdev, sector_t sector, + struct page *page, bool is_write) +{ + struct virtio_pmem *pmem =3D bdev->bd_queue->queuedata; + blk_status_t rc; + + rc =3D pmem_do_bvec(pmem, page, hpage_nr_pages(page) * PAGE_SIZE, + 0, is_write, sector); + + if (rc =3D=3D 0) + page_endio(page, is_write, 0); + + return blk_status_to_errno(rc); +} + +#ifndef REQ_FLUSH +#define REQ_FLUSH REQ_PREFLUSH +#endif + +static blk_qc_t virtio_pmem_make_request(struct request_queue *q, + struct bio *bio) +{ + blk_status_t rc =3D 0; + struct bio_vec bvec; + struct bvec_iter iter; + struct virtio_pmem *pmem =3D q->queuedata; + + if (bio->bi_opf & REQ_FLUSH) + //todo host flush command + + bio_for_each_segment(bvec, bio, iter) { + rc =3D pmem_do_bvec(pmem, bvec.bv_page, bvec.bv_len, + bvec.bv_offset, op_is_write(bio_op(bio)), + iter.bi_sector); + if (rc) { + bio->bi_status =3D rc; + break; + } + } + + bio_endio(bio); + return BLK_QC_T_NONE; +} + +static const struct block_device_operations pmem_fops =3D { + .owner =3D THIS_MODULE, + .rw_page =3D vpmem_rw_page, + //.revalidate_disk =3D nvdimm_revalidate_disk, +}; + +static int virtio_pmem_probe(struct virtio_device *vdev) +{ + struct virtio_pmem *vpmem; + int err =3D 0; + void *addr; + struct resource *res, res_pfn; + struct request_queue *q; + struct vmem_altmap __altmap, *altmap =3D NULL; + struct gendisk *disk; + struct device *gendev; + int nid =3D dev_to_node(&vdev->dev); + + if (!vdev->config->get) { + dev_err(&vdev->dev, "%s failure: config disabled\n", + __func__); + return -EINVAL; + } + + vdev->priv =3D vpmem =3D devm_kzalloc(&vdev->dev, sizeof(*vpmem), + GFP_KERNEL); + + if (!vpmem) { + err =3D -ENOMEM; + goto out; + } + + dev_set_drvdata(&vdev->dev, vpmem); + + vpmem->vdev =3D vdev; + err =3D init_vq(vpmem); + if (err) + goto out; + + if (!virtio_has_feature(vdev, VIRTIO_PMEM_PLUG)) { + dev_err(&vdev->dev, "%s : pmem not supported\n", + __func__); + goto out; + } + + virtio_cread(vpmem->vdev, struct virtio_pmem_config, + start, &vpmem->start); + virtio_cread(vpmem->vdev, struct virtio_pmem_config, + size, &vpmem->size); + + res_pfn.start =3D vpmem->start; + res_pfn.end =3D vpmem->start + vpmem->size-1; + + /* used for allocating memmap in the pmem device */ + altmap =3D setup_pmem_pfn(vpmem, &res_pfn, &__altmap); + + res =3D devm_request_mem_region(&vdev->dev, + res_pfn.start, resource_size(&res_pfn), "virtio-pmem"); + + if (!res) { + dev_warn(&vdev->dev, "could not reserve region "); + return -EBUSY; + } + + q =3D blk_alloc_queue_node(GFP_KERNEL, dev_to_node(&vdev->dev)); + + if (!q) + return -ENOMEM; + + if (devm_add_action_or_reset(&vdev->dev, + virtio_pmem_release_queue, q)) + return -ENOMEM; + + vpmem->pfn_flags =3D PFN_DEV; + + /* allocate memap in pmem device itself */ + if (IS_ENABLED(CONFIG_ZONE_DEVICE)) { + + addr =3D devm_memremap_pages(&vdev->dev, res, + &q->q_usage_counter, altmap); + vpmem->pfn_flags |=3D PFN_MAP; + } else + addr =3D devm_memremap(&vdev->dev, vpmem->start, + vpmem->size, ARCH_MEMREMAP_PMEM); + + /* + * At release time the queue must be frozen before + * devm_memremap_pages is unwound + */ + if (devm_add_action_or_reset(&vdev->dev, + virtio_pmem_freeze_queue, q)) + return -ENOMEM; + + if (IS_ERR(addr)) + return PTR_ERR(addr); + + vpmem->virt_addr =3D addr; + blk_queue_write_cache(q, 0, 0); + blk_queue_make_request(q, virtio_pmem_make_request); + blk_queue_physical_block_size(q, PAGE_SIZE); + blk_queue_logical_block_size(q, 512); + blk_queue_max_hw_sectors(q, UINT_MAX); + queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q); + queue_flag_set_unlocked(QUEUE_FLAG_DAX, q); + q->queuedata =3D vpmem; + + disk =3D alloc_disk_node(0, nid); + if (!disk) + return -ENOMEM; + vpmem->disk =3D disk; + + disk->fops =3D &pmem_fops; + disk->queue =3D q; + disk->flags =3D GENHD_FL_EXT_DEVT; + strcpy(disk->disk_name, "vpmem"); + set_capacity(disk, vpmem->size/512); + gendev =3D disk_to_dev(disk); + + virtio_device_ready(vdev); + device_add_disk(&vdev->dev, disk); + + if (devm_add_action_or_reset(&vdev->dev, + virtio_pmem_release_disk, vpmem)) + return -ENOMEM; + + revalidate_disk(disk); + return 0; +out: + vdev->config->del_vqs(vdev); + return err; +} + +static struct virtio_driver virtio_pmem_driver =3D { + .feature_table =3D features, + .feature_table_size =3D ARRAY_SIZE(features), + .driver.name =3D KBUILD_MODNAME, + .driver.owner =3D THIS_MODULE, + .id_table =3D id_table, + .probe =3D virtio_pmem_probe, + //.remove =3D virtio_pmem_remove, +}; + +module_virtio_driver(virtio_pmem_driver); +MODULE_DEVICE_TABLE(virtio, id_table); +MODULE_DESCRIPTION("Virtio pmem driver"); +MODULE_LICENSE("GPL"); diff --git a/include/uapi/linux/virtio_pmem.h b/include/uapi/linux/virtio_p= mem.h new file mode 100644 index 000000000000..ec0c728c79ba --- /dev/null +++ b/include/uapi/linux/virtio_pmem.h @@ -0,0 +1,55 @@ +/* + * Virtio pmem Device + * + * + */ + +#ifndef _LINUX_VIRTIO_PMEM_H +#define _LINUX_VIRTIO_PMEM_H + +#include +#include +#include +#include +#include +#include +#include +#include + +bool pmem_should_map_pages(struct device *dev); + +#define VIRTIO_PMEM_PLUG 0 + +struct virtio_pmem_config { + +uint64_t start; +uint64_t size; +uint64_t align; +uint64_t data_offset; +}; + +struct virtio_pmem { + + struct virtio_device *vdev; + struct virtqueue *req_vq; + + uint64_t start; + uint64_t size; + uint64_t align; + uint64_t data_offset; + u64 pfn_flags; + void *virt_addr; + struct gendisk *disk; +} __packed; + +static struct virtio_device_id id_table[] =3D { + { VIRTIO_ID_PMEM, VIRTIO_DEV_ANY_ID }, + { 0 }, +}; + +static unsigned int features[] =3D { + VIRTIO_PMEM_PLUG, +}; + +#endif + --=20 2.13.0 From nobody Sun Apr 28 21:19:13 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507823751540724.8458981088886; Thu, 12 Oct 2017 08:55:51 -0700 (PDT) Received: from localhost ([::1]:46192 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2fpp-0006OL-OQ for importer@patchew.org; Thu, 12 Oct 2017 11:55:45 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40178) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2flq-0003gf-4i for qemu-devel@nongnu.org; Thu, 12 Oct 2017 11:51:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2flm-0001mC-26 for qemu-devel@nongnu.org; Thu, 12 Oct 2017 11:51:38 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55194) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2fll-0001kk-PM for qemu-devel@nongnu.org; Thu, 12 Oct 2017 11:51:33 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B238A780CA; Thu, 12 Oct 2017 15:51:32 +0000 (UTC) Received: from dhcp201-121.englab.pnq.redhat.com (ovpn-116-26.sin2.redhat.com [10.67.116.26]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5FF385D9CC; Thu, 12 Oct 2017 15:51:19 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com B238A780CA Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=pagupta@redhat.com From: Pankaj Gupta To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, qemu-devel@nongnu.org, linux-nvdimm@ml01.01.org, linux-mm@kvack.org Date: Thu, 12 Oct 2017 21:20:27 +0530 Message-Id: <20171012155027.3277-4-pagupta@redhat.com> In-Reply-To: <20171012155027.3277-1-pagupta@redhat.com> References: <20171012155027.3277-1-pagupta@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Thu, 12 Oct 2017 15:51:32 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC] QEMU: Add virtio pmem device X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, haozhong.zhang@intel.com, jack@suse.cz, xiaoguangrong.eric@gmail.com, david@redhat.com, pagupta@redhat.com, ross.zwisler@intel.com, stefanha@redhat.com, pbonzini@redhat.com, dan.j.williams@intel.com, nilal@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This patch adds virtio-pmem Qemu device. This device configures memory address range information with file backend type. It acts like persistent memory device for KVM guest. It presents the memory address range to virtio-pmem driver over virtio channel and does the block flush whenever there is request from guest to flush/sync. (later part is yet to be implemented). Current code is a prototype to support guest with persistent=20 memory range & DAX. Signed-off-by: Pankaj Gupta --- hw/virtio/Makefile.objs | 2 +- hw/virtio/virtio-pci.c | 44 ++++++++++ hw/virtio/virtio-pci.h | 14 +++ hw/virtio/virtio-pmem.c | 130 ++++++++++++++++++++++++= ++++ include/hw/pci/pci.h | 1 + include/hw/virtio/virtio-pmem.h | 42 +++++++++ include/standard-headers/linux/virtio_ids.h | 1 + 7 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 hw/virtio/virtio-pmem.c create mode 100644 include/hw/virtio/virtio-pmem.h diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs index 765d363c1f..bb5573d2ef 100644 --- a/hw/virtio/Makefile.objs +++ b/hw/virtio/Makefile.objs @@ -5,7 +5,7 @@ common-obj-y +=3D virtio-bus.o common-obj-y +=3D virtio-mmio.o =20 obj-y +=3D virtio.o virtio-balloon.o=20 -obj-$(CONFIG_LINUX) +=3D vhost.o vhost-backend.o vhost-user.o +obj-$(CONFIG_LINUX) +=3D vhost.o vhost-backend.o vhost-user.o virtio-pmem.o obj-$(CONFIG_VHOST_VSOCK) +=3D vhost-vsock.o obj-y +=3D virtio-crypto.o obj-$(CONFIG_VIRTIO_PCI) +=3D virtio-crypto-pci.o diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 8b0d6b69cd..eb56afb290 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -2473,6 +2473,49 @@ static const TypeInfo virtio_rng_pci_info =3D { .class_init =3D virtio_rng_pci_class_init, }; =20 +/* virtio-pmem-pci */ + +static void virtio_pmem_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) +{ + VirtIOPMEMPCI *vpmem =3D VIRTIO_PMEM_PCI(vpci_dev); + DeviceState *vdev =3D DEVICE(&vpmem->vdev); + + qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus)); + object_property_set_bool(OBJECT(vdev), true, "realized", errp); +} + +static void virtio_pmem_pci_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + VirtioPCIClass *k =3D VIRTIO_PCI_CLASS(klass); + PCIDeviceClass *pcidev_k =3D PCI_DEVICE_CLASS(klass); + k->realize =3D virtio_pmem_pci_realize; + set_bit(DEVICE_CATEGORY_MISC, dc->categories); + pcidev_k->vendor_id =3D PCI_VENDOR_ID_REDHAT_QUMRANET; + pcidev_k->device_id =3D PCI_DEVICE_ID_VIRTIO_PMEM; + pcidev_k->revision =3D VIRTIO_PCI_ABI_VERSION; + pcidev_k->class_id =3D PCI_CLASS_OTHERS; +} + +static void virtio_pmem_pci_instance_init(Object *obj) +{ + VirtIOPMEMPCI *dev =3D VIRTIO_PMEM_PCI(obj); + + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VIRTIO_PMEM); + object_property_add_alias(obj, "memdev", OBJECT(&dev->vdev), "memdev", + &error_abort); +} + +static const TypeInfo virtio_pmem_pci_info =3D { + .name =3D TYPE_VIRTIO_PMEM_PCI, + .parent =3D TYPE_VIRTIO_PCI, + .instance_size =3D sizeof(VirtIOPMEMPCI), + .instance_init =3D virtio_pmem_pci_instance_init, + .class_init =3D virtio_pmem_pci_class_init, +}; + + /* virtio-input-pci */ =20 static Property virtio_input_pci_properties[] =3D { @@ -2662,6 +2705,7 @@ static void virtio_pci_register_types(void) type_register_static(&virtio_balloon_pci_info); type_register_static(&virtio_serial_pci_info); type_register_static(&virtio_net_pci_info); + type_register_static(&virtio_pmem_pci_info); #ifdef CONFIG_VHOST_SCSI type_register_static(&vhost_scsi_pci_info); #endif diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h index 69f5959623..37f0eeabd2 100644 --- a/hw/virtio/virtio-pci.h +++ b/hw/virtio/virtio-pci.h @@ -19,6 +19,7 @@ #include "hw/virtio/virtio-blk.h" #include "hw/virtio/virtio-net.h" #include "hw/virtio/virtio-rng.h" +#include "hw/virtio/virtio-pmem.h" #include "hw/virtio/virtio-serial.h" #include "hw/virtio/virtio-scsi.h" #include "hw/virtio/virtio-balloon.h" @@ -53,6 +54,7 @@ typedef struct VirtIOInputHostPCI VirtIOInputHostPCI; typedef struct VirtIOGPUPCI VirtIOGPUPCI; typedef struct VHostVSockPCI VHostVSockPCI; typedef struct VirtIOCryptoPCI VirtIOCryptoPCI; +typedef struct VirtIOPMEMPCI VirtIOPMEMPCI; =20 /* virtio-pci-bus */ =20 @@ -254,6 +256,18 @@ struct VirtIOBlkPCI { }; =20 /* + * virtio-pmem-pci: This extends VirtioPCIProxy. + */ +#define TYPE_VIRTIO_PMEM_PCI "virtio-pmem-pci" +#define VIRTIO_PMEM_PCI(obj) \ + OBJECT_CHECK(VirtIOPMEMPCI, (obj), TYPE_VIRTIO_PMEM_PCI) + +struct VirtIOPMEMPCI { + VirtIOPCIProxy parent_obj; + VirtIOPMEM vdev; +}; + +/* * virtio-balloon-pci: This extends VirtioPCIProxy. */ #define TYPE_VIRTIO_BALLOON_PCI "virtio-balloon-pci" diff --git a/hw/virtio/virtio-pmem.c b/hw/virtio/virtio-pmem.c new file mode 100644 index 0000000000..6ba1fd1614 --- /dev/null +++ b/hw/virtio/virtio-pmem.c @@ -0,0 +1,130 @@ +/* + * Virtio pmem device + * + * + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "qemu/error-report.h" +#include "hw/virtio/virtio-pmem.h" + + +static void virtio_pmem_system_reset(void *opaque) +{ + +} + +static void virtio_pmem_flush(VirtIODevice *vdev, VirtQueue *vq) +{ + /* VirtIOPMEM *vm =3D VIRTIO_PMEM(vdev); */ +} + + +static void virtio_pmem_get_config(VirtIODevice *vdev, uint8_t *config) +{ + VirtIOPMEM *pmem =3D VIRTIO_PMEM(vdev); + struct virtio_pmem_config *pmemcfg =3D (struct virtio_pmem_config *) c= onfig; + + pmemcfg->start =3D pmem->start; + pmemcfg->size =3D pmem->size; + pmemcfg->align =3D pmem->align; +} + +static uint64_t virtio_pmem_get_features(VirtIODevice *vdev, uint64_t feat= ures, + Error **errp) +{ + virtio_add_feature(&features, VIRTIO_PMEM_PLUG); + return features; +} + + + +static void virtio_pmem_realize(DeviceState *dev, Error **errp) +{ + VirtIODevice *vdev =3D VIRTIO_DEVICE(dev); + VirtIOPMEM *pmem =3D VIRTIO_PMEM(dev); + MachineState *ms =3D MACHINE(qdev_get_machine()); + MemoryRegion *mr; + PCMachineState *pcms =3D + PC_MACHINE(object_dynamic_cast(OBJECT(ms), TYPE_PC_MACHINE)); + + if (!pmem->memdev) { + error_setg(errp, "virtio-pmem not set"); + return; + } + + pmem->start =3D pcms->hotplug_memory.base; + + /*if (!pcmc->broken_reserved_end) { + pmem->size =3D memory_region_size(&pcms->hotplug_memory.mr); + }*/ + + + mr =3D host_memory_backend_get_memory(pmem->memdev, errp= ); + pmem->size =3D memory_region_size(mr); + pmem->align =3D memory_region_get_alignment(mr); + + virtio_init(vdev, TYPE_VIRTIO_PMEM, VIRTIO_ID_PMEM, + sizeof(struct virtio_pmem_config)); + + pmem->rq_vq =3D virtio_add_queue(vdev, 128, virtio_pmem_flush); + + host_memory_backend_set_mapped(pmem->memdev, true); + qemu_register_reset(virtio_pmem_system_reset, pmem); +} + +static void virtio_mem_check_memdev(Object *obj, const char *name, Object = *val, + Error **errp) +{ + + if (host_memory_backend_is_mapped(MEMORY_BACKEND(val))) { + + char *path =3D object_get_canonical_path_component(val); + error_setg(errp, "Can't use already busy memdev: %s", path); + g_free(path); + return; + } + + qdev_prop_allow_set_link_before_realize(obj, name, val, errp); +} + +static void virtio_pmem_instance_init(Object *obj) +{ + + VirtIOPMEM *vm =3D VIRTIO_PMEM(obj); + + object_property_add_link(obj, "memdev", TYPE_MEMORY_BACKEND, + (Object **)&vm->memdev, + (void *) virtio_mem_check_memdev, + OBJ_PROP_LINK_UNREF_ON_RELEASE, + &error_abort); + +} + + +static void virtio_pmem_class_init(ObjectClass *klass, void *data) +{ + VirtioDeviceClass *vdc =3D VIRTIO_DEVICE_CLASS(klass); + + vdc->realize =3D virtio_pmem_realize; + vdc->get_config =3D virtio_pmem_get_config; + vdc->get_features =3D virtio_pmem_get_features; +} + +static TypeInfo virtio_pmem_info =3D { + .name =3D TYPE_VIRTIO_PMEM, + .parent =3D TYPE_VIRTIO_DEVICE, + .class_size =3D sizeof(VirtIOPMEM), + .class_init =3D virtio_pmem_class_init, + .instance_init =3D virtio_pmem_instance_init, +}; + + +static void virtio_register_types(void) +{ + type_register_static(&virtio_pmem_info); +} + +type_init(virtio_register_types) diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 8bb6449dd7..b9bfb79a11 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -85,6 +85,7 @@ extern bool pci_available; #define PCI_DEVICE_ID_VIRTIO_RNG 0x1005 #define PCI_DEVICE_ID_VIRTIO_9P 0x1009 #define PCI_DEVICE_ID_VIRTIO_VSOCK 0x1012 +#define PCI_DEVICE_ID_VIRTIO_PMEM 0x1013 =20 #define PCI_VENDOR_ID_REDHAT 0x1b36 #define PCI_DEVICE_ID_REDHAT_BRIDGE 0x0001 diff --git a/include/hw/virtio/virtio-pmem.h b/include/hw/virtio/virtio-pme= m.h new file mode 100644 index 0000000000..0d0642ed82 --- /dev/null +++ b/include/hw/virtio/virtio-pmem.h @@ -0,0 +1,42 @@ +/* + * Virtio pmem Device + * + * + */ + +#ifndef QEMU_VIRTIO_PMEM_H +#define QEMU_VIRTIO_PMEM_H + +#include "hw/virtio/virtio.h" +#include "exec/memory.h" +#include "sysemu/hostmem.h" +#include "standard-headers/linux/virtio_ids.h" +#include "hw/boards.h" +#include "hw/i386/pc.h" + +#define VIRTIO_PMEM_PLUG 0 + +#define TYPE_VIRTIO_PMEM "virtio-pmem" + +#define VIRTIO_PMEM(obj) \ + OBJECT_CHECK(VirtIOPMEM, (obj), TYPE_VIRTIO_PMEM) + +typedef struct VirtIOPMEM { + + VirtIODevice parent_obj; + uint64_t start; + uint64_t size; + uint64_t align; + + VirtQueue *rq_vq; + MemoryRegion *mr; + HostMemoryBackend *memdev; +} VirtIOPMEM; + +struct virtio_pmem_config { + + uint64_t start; + uint64_t size; + uint64_t align; +}; +#endif diff --git a/include/standard-headers/linux/virtio_ids.h b/include/standard= -headers/linux/virtio_ids.h index 6d5c3b2d4f..5ebd04980d 100644 --- a/include/standard-headers/linux/virtio_ids.h +++ b/include/standard-headers/linux/virtio_ids.h @@ -43,5 +43,6 @@ #define VIRTIO_ID_INPUT 18 /* virtio input */ #define VIRTIO_ID_VSOCK 19 /* virtio vsock transport */ #define VIRTIO_ID_CRYPTO 20 /* virtio crypto */ +#define VIRTIO_ID_PMEM 21 /* virtio pmem */ =20 #endif /* _LINUX_VIRTIO_IDS_H */ --=20 2.13.0