From nobody Wed Oct 29 23:02:01 2025 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 1526484364059868.8359183639158; Wed, 16 May 2018 08:26:04 -0700 (PDT) Received: from localhost ([::1]:51325 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fIyJO-00025f-KF for importer@patchew.org; Wed, 16 May 2018 11:25:54 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54110) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fIyFn-0007pN-2k for qemu-devel@nongnu.org; Wed, 16 May 2018 11:22:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fIyFl-0005mn-Ij for qemu-devel@nongnu.org; Wed, 16 May 2018 11:22:11 -0400 Received: from [45.249.212.32] (port=54404 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fIyFb-0005cu-Q7; Wed, 16 May 2018 11:22:00 -0400 Received: from DGGEMS404-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id 3B1826B686841; Wed, 16 May 2018 23:21:46 +0800 (CST) Received: from S00345302A-PC.china.huawei.com (10.202.227.237) by DGGEMS404-HUB.china.huawei.com (10.3.19.204) with Microsoft SMTP Server id 14.3.361.1; Wed, 16 May 2018 23:21:40 +0800 From: Shameer Kolothum To: , Date: Wed, 16 May 2018 16:20:21 +0100 Message-ID: <20180516152026.2920-2-shameerali.kolothum.thodi@huawei.com> X-Mailer: git-send-email 2.12.0.windows.1 In-Reply-To: <20180516152026.2920-1-shameerali.kolothum.thodi@huawei.com> References: <20180516152026.2920-1-shameerali.kolothum.thodi@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.202.227.237] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 45.249.212.32 Subject: [Qemu-devel] [RFC v2 1/6] hw/vfio: Retrieve valid iova ranges from kernel 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: peter.maydell@linaro.org, drjones@redhat.com, jonathan.cameron@huawei.com, linuxarm@huawei.com, Shameer Kolothum , eric.auger@redhat.com, alex.williamson@redhat.com, zhaoshenglong@huawei.com, imammedo@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 Content-Type: text/plain; charset="utf-8" This makes use of the newly introduced iova cap chains added to the type1 VFIO_IOMMU_GET_INFO ioctl. The retrieved iova info is stored in a list for later use. Signed-off-by: Shameer Kolothum --- hw/vfio/common.c | 108 ++++++++++++++++++++++++++++++++++++++= +--- include/hw/vfio/vfio-common.h | 7 +++ linux-headers/linux/vfio.h | 23 +++++++++ 3 files changed, 132 insertions(+), 6 deletions(-) diff --git a/hw/vfio/common.c b/hw/vfio/common.c index 07ffa0b..94d7b24 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -40,6 +40,8 @@ struct vfio_group_head vfio_group_list =3D QLIST_HEAD_INITIALIZER(vfio_group_list); struct vfio_as_head vfio_address_spaces =3D QLIST_HEAD_INITIALIZER(vfio_address_spaces); +struct vfio_iova_head vfio_iova_regions =3D + QLIST_HEAD_INITIALIZER(vfio_iova_regions); =20 #ifdef CONFIG_KVM /* @@ -1030,6 +1032,85 @@ static void vfio_put_address_space(VFIOAddressSpace = *space) } } =20 +static void vfio_iommu_get_iova_ranges(struct vfio_iommu_type1_info *info) +{ + struct vfio_info_cap_header *hdr; + struct vfio_iommu_type1_info_cap_iova_range *cap_iova; + VFIOIovaRange *iova, *tmp, *prev =3D NULL; + void *ptr =3D info; + bool found =3D false; + int i; + + if (!(info->flags & VFIO_IOMMU_INFO_CAPS)) { + return; + } + + for (hdr =3D ptr + info->cap_offset; hdr !=3D ptr; hdr =3D ptr + hdr->= next) { + if (hdr->id =3D=3D VFIO_IOMMU_TYPE1_INFO_CAP_IOVA_RANGE) { + found =3D true; + break; + } + } + + if (!found) { + return; + } + + /* purge the current iova list, if any */ + QLIST_FOREACH_SAFE(iova, &vfio_iova_regions, next, tmp) { + QLIST_REMOVE(iova, next); + g_free(iova); + } + + cap_iova =3D container_of(hdr, struct vfio_iommu_type1_info_cap_iova_r= ange, + header); + + /* populate the list */ + for (i =3D 0; i < cap_iova->nr_iovas; i++) { + iova =3D g_malloc0(sizeof(*iova)); + iova->start =3D cap_iova->iova_ranges[i].start; + iova->end =3D cap_iova->iova_ranges[i].end; + + if (prev) { + QLIST_INSERT_AFTER(prev, iova, next); + } else { + QLIST_INSERT_HEAD(&vfio_iova_regions, iova, next); + } + prev =3D iova; + } + + return; +} + +static int vfio_get_iommu_info(VFIOContainer *container, + struct vfio_iommu_type1_info **info) +{ + + size_t argsz =3D sizeof(struct vfio_iommu_type1_info); + + + *info =3D g_malloc0(argsz); + +retry: + (*info)->argsz =3D argsz; + + if (ioctl(container->fd, VFIO_IOMMU_GET_INFO, *info)) { + g_free(*info); + *info =3D NULL; + return -errno; + } + + if (((*info)->argsz > argsz)) { + argsz =3D (*info)->argsz; + *info =3D g_realloc(*info, argsz); + goto retry; + } + + vfio_iommu_get_iova_ranges(*info); + + return 0; +} + static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, Error **errp) { @@ -1044,6 +1125,15 @@ static int vfio_connect_container(VFIOGroup *group, = AddressSpace *as, group->container =3D container; QLIST_INSERT_HEAD(&container->group_list, group, container_nex= t); vfio_kvm_device_add_group(group); + + /* New group might change the valid iovas. Get the updated lis= t */ + if ((container->iommu_type =3D=3D VFIO_TYPE1_IOMMU) || + (container->iommu_type =3D=3D VFIO_TYPE1v2_IOMMU)) { + struct vfio_iommu_type1_info *info; + + vfio_get_iommu_info(container, &info); + g_free(info); + } return 0; } } @@ -1071,7 +1161,7 @@ static int vfio_connect_container(VFIOGroup *group, A= ddressSpace *as, if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU) || ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1v2_IOMMU)) { bool v2 =3D !!ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1v2_IOMMU); - struct vfio_iommu_type1_info info; + struct vfio_iommu_type1_info *info; =20 ret =3D ioctl(group->fd, VFIO_GROUP_SET_CONTAINER, &fd); if (ret) { @@ -1095,14 +1185,14 @@ static int vfio_connect_container(VFIOGroup *group,= AddressSpace *as, * existing Type1 IOMMUs generally support any IOVA we're * going to actually try in practice. */ - info.argsz =3D sizeof(info); - ret =3D ioctl(fd, VFIO_IOMMU_GET_INFO, &info); + ret =3D vfio_get_iommu_info(container, &info); /* Ignore errors */ - if (ret || !(info.flags & VFIO_IOMMU_INFO_PGSIZES)) { + if (ret || !(info->flags & VFIO_IOMMU_INFO_PGSIZES)) { /* Assume 4k IOVA page size */ - info.iova_pgsizes =3D 4096; + info->iova_pgsizes =3D 4096; } - vfio_host_win_add(container, 0, (hwaddr)-1, info.iova_pgsizes); + vfio_host_win_add(container, 0, (hwaddr)-1, info->iova_pgsizes); + g_free(info); } else if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_IOMMU) || ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_v2_IOMMU)) { struct vfio_iommu_spapr_tce_info info; @@ -1256,6 +1346,7 @@ static void vfio_disconnect_container(VFIOGroup *grou= p) if (QLIST_EMPTY(&container->group_list)) { VFIOAddressSpace *space =3D container->space; VFIOGuestIOMMU *giommu, *tmp; + VFIOIovaRange *iova, *next_iova; =20 QLIST_REMOVE(container, next); =20 @@ -1266,6 +1357,11 @@ static void vfio_disconnect_container(VFIOGroup *gro= up) g_free(giommu); } =20 + QLIST_FOREACH_SAFE(iova, &vfio_iova_regions, next, next_iova) { + QLIST_REMOVE(iova, next); + g_free(iova); + } + trace_vfio_disconnect_container(container->fd); close(container->fd); g_free(container); diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h index d936014..874fe2c 100644 --- a/include/hw/vfio/vfio-common.h +++ b/include/hw/vfio/vfio-common.h @@ -164,6 +164,12 @@ typedef struct VFIODisplay { } dmabuf; } VFIODisplay; =20 +typedef struct VFIOIovaRange { + uint64_t start; + uint64_t end; + QLIST_ENTRY(VFIOIovaRange) next; +} VFIOIovaRange; + void vfio_put_base_device(VFIODevice *vbasedev); void vfio_disable_irqindex(VFIODevice *vbasedev, int index); void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index); @@ -187,6 +193,7 @@ int vfio_get_device(VFIOGroup *group, const char *name, extern const MemoryRegionOps vfio_region_ops; extern QLIST_HEAD(vfio_group_head, VFIOGroup) vfio_group_list; extern QLIST_HEAD(vfio_as_head, VFIOAddressSpace) vfio_address_spaces; +extern QLIST_HEAD(vfio_iova_head, VFIOIovaRange) vfio_iova_regions; =20 #ifdef CONFIG_LINUX int vfio_get_region_info(VFIODevice *vbasedev, int index, diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h index 3a0a305..117341d 100644 --- a/linux-headers/linux/vfio.h +++ b/linux-headers/linux/vfio.h @@ -589,7 +589,30 @@ struct vfio_iommu_type1_info { __u32 argsz; __u32 flags; #define VFIO_IOMMU_INFO_PGSIZES (1 << 0) /* supported page sizes info */ +#define VFIO_IOMMU_INFO_CAPS (1 << 1) /* Info supports caps */ __u64 iova_pgsizes; /* Bitmap of supported page sizes */ + __u32 cap_offset; /* Offset within info struct of first cap */ +}; + +/* + * The IOVA capability allows to report the valid IOVA range(s) + * excluding any reserved regions associated with dev group. Any dma + * map attempt outside the valid iova range will return error. + * + * The structures below define version 1 of this capability. + */ +#define VFIO_IOMMU_TYPE1_INFO_CAP_IOVA_RANGE 1 + +struct vfio_iova_range { + __u64 start; + __u64 end; +}; + +struct vfio_iommu_type1_info_cap_iova_range { + struct vfio_info_cap_header header; + __u32 nr_iovas; + __u32 reserved; + struct vfio_iova_range iova_ranges[]; }; =20 #define VFIO_IOMMU_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 12) --=20 2.7.4 From nobody Wed Oct 29 23:02:01 2025 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 1526484265248335.6875296870603; Wed, 16 May 2018 08:24:25 -0700 (PDT) Received: from localhost ([::1]:51237 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fIyHw-0000jF-Fi for importer@patchew.org; Wed, 16 May 2018 11:24:24 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54185) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fIyFs-0007uZ-Vp for qemu-devel@nongnu.org; Wed, 16 May 2018 11:22:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fIyFm-0005nk-T1 for qemu-devel@nongnu.org; Wed, 16 May 2018 11:22:16 -0400 Received: from szxga04-in.huawei.com ([45.249.212.190]:2617 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fIyFj-0005iu-CG; Wed, 16 May 2018 11:22:08 -0400 Received: from DGGEMS404-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id C2EEEBB4595AC; Wed, 16 May 2018 23:21:51 +0800 (CST) Received: from S00345302A-PC.china.huawei.com (10.202.227.237) by DGGEMS404-HUB.china.huawei.com (10.3.19.204) with Microsoft SMTP Server id 14.3.361.1; Wed, 16 May 2018 23:21:44 +0800 From: Shameer Kolothum To: , Date: Wed, 16 May 2018 16:20:22 +0100 Message-ID: <20180516152026.2920-3-shameerali.kolothum.thodi@huawei.com> X-Mailer: git-send-email 2.12.0.windows.1 In-Reply-To: <20180516152026.2920-1-shameerali.kolothum.thodi@huawei.com> References: <20180516152026.2920-1-shameerali.kolothum.thodi@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.202.227.237] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 45.249.212.190 Subject: [Qemu-devel] [RFC v2 2/6] hw/arm/virt: Enable dynamic generation of guest RAM memory regions 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: peter.maydell@linaro.org, drjones@redhat.com, jonathan.cameron@huawei.com, linuxarm@huawei.com, Shameer Kolothum , eric.auger@redhat.com, alex.williamson@redhat.com, zhaoshenglong@huawei.com, imammedo@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 Content-Type: text/plain; charset="utf-8" Register ram_memory_region_init notifier to allocate memory region from system memory. Signed-off-by: Zhu Yijun Signed-off-by: Shameer Kolothum --- hw/arm/virt.c | 28 ++++++++++++++++++++++------ include/hw/arm/virt.h | 1 + 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 94dcb12..05fcb62 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1171,6 +1171,19 @@ void virt_machine_done(Notifier *notifier, void *dat= a) virt_build_smbios(vms); } =20 +static void virt_ram_memory_region_init(Notifier *notifier, void *data) +{ + MemoryRegion *sysmem =3D get_system_memory(); + MemoryRegion *ram =3D g_new(MemoryRegion, 1); + VirtMachineState *vms =3D container_of(notifier, VirtMachineState, + ram_memory_region_init); + MachineState *machine =3D MACHINE(vms); + + memory_region_allocate_system_memory(ram, NULL, "mach-virt.ram", + machine->ram_size); + memory_region_add_subregion(sysmem, vms->memmap[VIRT_MEM].base, ram); +} + static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx) { uint8_t clustersz =3D ARM_DEFAULT_CPUS_PER_CLUSTER; @@ -1204,7 +1217,6 @@ static void machvirt_init(MachineState *machine) MemoryRegion *sysmem =3D get_system_memory(); MemoryRegion *secure_sysmem =3D NULL; int n, virt_max_cpus; - MemoryRegion *ram =3D g_new(MemoryRegion, 1); bool firmware_loaded =3D bios_name || drive_get(IF_PFLASH, 0, 0); =20 /* We can probe only here because during property set @@ -1361,10 +1373,6 @@ static void machvirt_init(MachineState *machine) fdt_add_timer_nodes(vms); fdt_add_cpu_nodes(vms); =20 - memory_region_allocate_system_memory(ram, NULL, "mach-virt.ram", - machine->ram_size); - memory_region_add_subregion(sysmem, vms->memmap[VIRT_MEM].base, ram); - create_flash(vms, sysmem, secure_sysmem ? secure_sysmem : sysmem); =20 create_gic(vms, pic); @@ -1405,15 +1413,23 @@ static void machvirt_init(MachineState *machine) vms->bootinfo.loader_start =3D vms->memmap[VIRT_MEM].base; vms->bootinfo.get_dtb =3D machvirt_dtb; vms->bootinfo.firmware_loaded =3D firmware_loaded; + + /* Register notifiers. They are executed in registration reverse order= */ arm_load_kernel(ARM_CPU(first_cpu), &vms->bootinfo); =20 /* * arm_load_kernel machine init done notifier registration must * happen before the platform_bus_create call. In this latter, * another notifier is registered which adds platform bus nodes. - * Notifiers are executed in registration reverse order. */ create_platform_bus(vms, pic); + + /* + * Register memory region notifier last as this has to be executed + * first. + */ + vms->ram_memory_region_init.notify =3D virt_ram_memory_region_init; + qemu_add_machine_init_done_notifier(&vms->ram_memory_region_init); } =20 static bool virt_get_secure(Object *obj, Error **errp) diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index ba0c1a4..fc24f3a 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -91,6 +91,7 @@ typedef struct { typedef struct { MachineState parent; Notifier machine_done; + Notifier ram_memory_region_init; FWCfgState *fw_cfg; bool secure; bool highmem; --=20 2.7.4 From nobody Wed Oct 29 23:02:01 2025 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 1526487247050379.9435176117015; Wed, 16 May 2018 09:14:07 -0700 (PDT) Received: from localhost ([::1]:53414 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fIz42-0004Ta-4z for importer@patchew.org; Wed, 16 May 2018 12:14:06 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51900) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fIyzQ-0000oH-VU for qemu-devel@nongnu.org; Wed, 16 May 2018 12:09:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fIyzP-0004fT-Oe for qemu-devel@nongnu.org; Wed, 16 May 2018 12:09:20 -0400 Received: from [45.249.212.35] (port=58059 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fIyzK-0004au-W5; Wed, 16 May 2018 12:09:15 -0400 Received: from DGGEMS404-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id 6C751BB0E397D; Wed, 16 May 2018 23:21:56 +0800 (CST) Received: from S00345302A-PC.china.huawei.com (10.202.227.237) by DGGEMS404-HUB.china.huawei.com (10.3.19.204) with Microsoft SMTP Server id 14.3.361.1; Wed, 16 May 2018 23:21:49 +0800 From: Shameer Kolothum To: , Date: Wed, 16 May 2018 16:20:23 +0100 Message-ID: <20180516152026.2920-4-shameerali.kolothum.thodi@huawei.com> X-Mailer: git-send-email 2.12.0.windows.1 In-Reply-To: <20180516152026.2920-1-shameerali.kolothum.thodi@huawei.com> References: <20180516152026.2920-1-shameerali.kolothum.thodi@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.202.227.237] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 45.249.212.35 Subject: [Qemu-devel] [RFC v2 3/6] hw/arm/virt: Add pc-dimm mem hotplug framework 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: peter.maydell@linaro.org, drjones@redhat.com, jonathan.cameron@huawei.com, linuxarm@huawei.com, Shameer Kolothum , eric.auger@redhat.com, alex.williamson@redhat.com, zhaoshenglong@huawei.com, imammedo@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 Content-Type: text/plain; charset="utf-8" This will be used in subsequent patches to model a chunk of memory as pc-dimm(cold plug) if the valid iova regions are non-contiguous. This is not yet a full hotplug support. Signed-off-by: Shameer Kolothum --- default-configs/aarch64-softmmu.mak | 1 + hw/arm/virt.c | 82 +++++++++++++++++++++++++++++++++= ++++ include/hw/arm/virt.h | 2 + 3 files changed, 85 insertions(+) diff --git a/default-configs/aarch64-softmmu.mak b/default-configs/aarch64-= softmmu.mak index 9ddccf8..7a82ed8 100644 --- a/default-configs/aarch64-softmmu.mak +++ b/default-configs/aarch64-softmmu.mak @@ -8,3 +8,4 @@ CONFIG_DDC=3Dy CONFIG_DPCD=3Dy CONFIG_XLNX_ZYNQMP=3Dy CONFIG_XLNX_ZYNQMP_ARM=3Dy +CONFIG_MEM_HOTPLUG=3Dy diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 05fcb62..be3ad14 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1552,9 +1552,82 @@ static const CPUArchIdList *virt_possible_cpu_arch_i= ds(MachineState *ms) return ms->possible_cpus; } =20 +static void virt_dimm_plug(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + VirtMachineState *vms =3D VIRT_MACHINE(hotplug_dev); + PCDIMMDevice *dimm =3D PC_DIMM(dev); + PCDIMMDeviceClass *ddc =3D PC_DIMM_GET_CLASS(dimm); + MemoryRegion *mr; + uint64_t align; + Error *local_err =3D NULL; + + mr =3D ddc->get_memory_region(dimm, &local_err); + if (local_err) { + goto out; + } + + align =3D memory_region_get_alignment(mr); + pc_dimm_memory_plug(dev, &vms->hotplug_memory, mr, align, &local_err); + if (local_err) { + goto out; + } + +out: + error_propagate(errp, local_err); +} + +static void virt_dimm_unplug(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + VirtMachineState *vms =3D VIRT_MACHINE(hotplug_dev); + PCDIMMDevice *dimm =3D PC_DIMM(dev); + PCDIMMDeviceClass *ddc =3D PC_DIMM_GET_CLASS(dimm); + MemoryRegion *mr; + Error *local_err =3D NULL; + + mr =3D ddc->get_memory_region(dimm, &local_err); + pc_dimm_memory_unplug(dev, &vms->hotplug_memory, mr); + object_unparent(OBJECT(dev)); + + error_propagate(errp, local_err); +} + +static void virt_machinedevice_plug_cb(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { + virt_dimm_plug(hotplug_dev, dev, errp); + } else { + error_setg(errp, "device plug request for not supported device" + " type: %s", object_get_typename(OBJECT(dev))); + } +} + +static void virt_machinedevice_unplug_cb(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { + virt_dimm_unplug(hotplug_dev, dev, errp); + } else { + error_setg(errp, "device unplug for not supported device" + " type: %s", object_get_typename(OBJECT(dev))); + } +} + +static HotplugHandler *virt_get_hotplug_handler(MachineState *machine, + DeviceState *dev) +{ + if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { + return HOTPLUG_HANDLER(machine); + } + return NULL; +} + static void virt_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc =3D MACHINE_CLASS(oc); + HotplugHandlerClass *hc =3D HOTPLUG_HANDLER_CLASS(oc); =20 mc->init =3D machvirt_init; /* Start max_cpus at the maximum QEMU supports. We'll further restrict @@ -1573,6 +1646,11 @@ static void virt_machine_class_init(ObjectClass *oc,= void *data) mc->cpu_index_to_instance_props =3D virt_cpu_index_to_props; mc->default_cpu_type =3D ARM_CPU_TYPE_NAME("cortex-a15"); mc->get_default_cpu_node_id =3D virt_get_default_cpu_node_id; + + mc->get_hotplug_handler =3D virt_get_hotplug_handler; + hc->plug =3D virt_machinedevice_plug_cb; + hc->unplug =3D virt_machinedevice_unplug_cb; + } =20 static const TypeInfo virt_machine_info =3D { @@ -1582,6 +1660,10 @@ static const TypeInfo virt_machine_info =3D { .instance_size =3D sizeof(VirtMachineState), .class_size =3D sizeof(VirtMachineClass), .class_init =3D virt_machine_class_init, + .interfaces =3D (InterfaceInfo[]) { + { TYPE_HOTPLUG_HANDLER }, + { } + }, }; =20 static void machvirt_machine_init(void) diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index fc24f3a..a39f29e 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -35,6 +35,7 @@ #include "qemu/notify.h" #include "hw/boards.h" #include "hw/arm/arm.h" +#include "hw/mem/pc-dimm.h" =20 #define NUM_GICV2M_SPIS 64 #define NUM_VIRTIO_TRANSPORTS 32 @@ -108,6 +109,7 @@ typedef struct { uint32_t gic_phandle; uint32_t msi_phandle; int psci_conduit; + MemoryHotplugState hotplug_memory; } VirtMachineState; =20 #define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("virt") --=20 2.7.4 From nobody Wed Oct 29 23:02:01 2025 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 1526484431895377.2839742840472; Wed, 16 May 2018 08:27:11 -0700 (PDT) Received: from localhost ([::1]:51376 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fIyKd-0002qe-4n for importer@patchew.org; Wed, 16 May 2018 11:27:11 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54199) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fIyFt-0007vD-Kv for qemu-devel@nongnu.org; Wed, 16 May 2018 11:22:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fIyFs-0005rW-C5 for qemu-devel@nongnu.org; Wed, 16 May 2018 11:22:17 -0400 Received: from [45.249.212.32] (port=54447 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fIyFi-0005iq-Bm; Wed, 16 May 2018 11:22:07 -0400 Received: from DGGEMS404-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id 6E18C6500791A; Wed, 16 May 2018 23:22:01 +0800 (CST) Received: from S00345302A-PC.china.huawei.com (10.202.227.237) by DGGEMS404-HUB.china.huawei.com (10.3.19.204) with Microsoft SMTP Server id 14.3.361.1; Wed, 16 May 2018 23:21:53 +0800 From: Shameer Kolothum To: , Date: Wed, 16 May 2018 16:20:24 +0100 Message-ID: <20180516152026.2920-5-shameerali.kolothum.thodi@huawei.com> X-Mailer: git-send-email 2.12.0.windows.1 In-Reply-To: <20180516152026.2920-1-shameerali.kolothum.thodi@huawei.com> References: <20180516152026.2920-1-shameerali.kolothum.thodi@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.202.227.237] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 45.249.212.32 Subject: [Qemu-devel] [RFC v2 4/6] hw/arm: Changes required to accommodate non-contiguous DT mem nodes 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: peter.maydell@linaro.org, drjones@redhat.com, jonathan.cameron@huawei.com, linuxarm@huawei.com, Shameer Kolothum , eric.auger@redhat.com, alex.williamson@redhat.com, zhaoshenglong@huawei.com, imammedo@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 Content-Type: text/plain; charset="utf-8" This makes changes to the DT mem node creation such that its easier to add non-contiguous mem modeled as non-pluggable and a pc-dimm mem later. Signed-off-by: Shameer Kolothum --- hw/arm/boot.c | 91 ++++++++++++++++++++++++++++++++++++------------= ---- include/hw/arm/arm.h | 12 +++++++ 2 files changed, 75 insertions(+), 28 deletions(-) diff --git a/hw/arm/boot.c b/hw/arm/boot.c index 26184bc..73db0aa 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -486,6 +486,27 @@ static void fdt_add_psci_node(void *fdt) qemu_fdt_setprop_cell(fdt, "/psci", "migrate", migrate_fn); } =20 +static char *create_memory_fdt(void *fdt, uint32_t acells, hwaddr mem_base, + uint32_t scells, hwaddr mem_len) +{ + char *nodename =3D NULL; + int rc; + + nodename =3D g_strdup_printf("/memory@%" PRIx64, mem_base); + qemu_fdt_add_subnode(fdt, nodename); + qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory"); + rc =3D qemu_fdt_setprop_sized_cells(fdt, nodename, "reg", acells, mem_= base, + scells, mem_len); + if (rc < 0) { + fprintf(stderr, "couldn't set %s/reg\n", nodename); + g_free(nodename); + return NULL; + } + + return nodename; +} + + /** * load_dtb() - load a device tree binary image into memory * @addr: the address to load the image at @@ -567,50 +588,64 @@ static int load_dtb(hwaddr addr, const struct arm_boo= t_info *binfo, goto fail; } =20 + /* + * Turn the /memory node created before into a NOP node, then create + * /memory@addr nodes for all numa nodes respectively. + */ + qemu_fdt_nop_node(fdt, "/memory"); + if (nb_numa_nodes > 0) { - /* - * Turn the /memory node created before into a NOP node, then crea= te - * /memory@addr nodes for all numa nodes respectively. - */ - qemu_fdt_nop_node(fdt, "/memory"); + hwaddr mem_sz; + mem_base =3D binfo->loader_start; + mem_sz =3D binfo->ram_size; for (i =3D 0; i < nb_numa_nodes; i++) { - mem_len =3D numa_info[i].node_mem; - nodename =3D g_strdup_printf("/memory@%" PRIx64, mem_base); - qemu_fdt_add_subnode(fdt, nodename); - qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory"= ); - rc =3D qemu_fdt_setprop_sized_cells(fdt, nodename, "reg", - acells, mem_base, + mem_len =3D MIN(numa_info[i].node_mem, mem_sz); + + nodename =3D create_memory_fdt(fdt, acells, mem_base, scells, mem_len); - if (rc < 0) { - fprintf(stderr, "couldn't set %s/reg for node %d\n", noden= ame, - i); + if (!nodename) { goto fail; } =20 qemu_fdt_setprop_cell(fdt, nodename, "numa-node-id", i); - mem_base +=3D mem_len; g_free(nodename); + mem_base +=3D mem_len; + mem_sz -=3D mem_len; + if (!mem_sz) { + break; + } } - } else { - Error *err =3D NULL; =20 - rc =3D fdt_path_offset(fdt, "/memory"); - if (rc < 0) { - qemu_fdt_add_subnode(fdt, "/memory"); - } + /* Create the node for initial pc-dimm ram, if any */ + if (binfo->dimm_mem) { =20 - if (!qemu_fdt_getprop(fdt, "/memory", "device_type", NULL, &err)) { - qemu_fdt_setprop_string(fdt, "/memory", "device_type", "memory= "); + nodename =3D create_memory_fdt(fdt, acells, binfo->dimm_mem->b= ase, + scells, binfo->dimm_mem->siz= e); + if (!nodename) { + goto fail; + } + qemu_fdt_setprop_cell(fdt, nodename, "numa-node-id", + binfo->dimm_mem->node); + g_free(nodename); } =20 - rc =3D qemu_fdt_setprop_sized_cells(fdt, "/memory", "reg", - acells, binfo->loader_start, - scells, binfo->ram_size); - if (rc < 0) { - fprintf(stderr, "couldn't set /memory/reg\n"); + } else { + + nodename =3D create_memory_fdt(fdt, acells, binfo->loader_start, + scells, binfo->ram_size); + if (!nodename) { goto fail; } + + if (binfo->dimm_mem) { + nodename =3D create_memory_fdt(fdt, acells, binfo->dimm_mem->b= ase, + scells, binfo->dimm_mem->siz= e); + if (!nodename) { + goto fail; + } + g_free(nodename); + } } =20 rc =3D fdt_path_offset(fdt, "/chosen"); diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h index ce769bd..0ee3b4e 100644 --- a/include/hw/arm/arm.h +++ b/include/hw/arm/arm.h @@ -48,6 +48,12 @@ typedef struct { ARMCPU *cpu; /* handle to the first cpu object */ } ArmLoadKernelNotifier; =20 +struct dimm_mem_info { + int node; + hwaddr base; + hwaddr size; +}; + /* arm_boot.c */ struct arm_boot_info { uint64_t ram_size; @@ -124,6 +130,12 @@ struct arm_boot_info { bool secure_board_setup; =20 arm_endianness endianness; + + /* This is used to model a pc-dimm based mem if the valid iova region + * is non-contiguous. + */ + struct dimm_mem_info *dimm_mem; + }; =20 /** --=20 2.7.4 From nobody Wed Oct 29 23:02:01 2025 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 152648451867777.87025284249; Wed, 16 May 2018 08:28:38 -0700 (PDT) Received: from localhost ([::1]:51441 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fIyM1-0003oQ-Sb for importer@patchew.org; Wed, 16 May 2018 11:28:37 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54292) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fIyG5-000856-F3 for qemu-devel@nongnu.org; Wed, 16 May 2018 11:22:35 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fIyG4-0005x1-IE for qemu-devel@nongnu.org; Wed, 16 May 2018 11:22:29 -0400 Received: from szxga05-in.huawei.com ([45.249.212.191]:2097 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fIyFy-0005sq-4E; Wed, 16 May 2018 11:22:22 -0400 Received: from DGGEMS404-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id 274CED4DEFF90; Wed, 16 May 2018 23:22:06 +0800 (CST) Received: from S00345302A-PC.china.huawei.com (10.202.227.237) by DGGEMS404-HUB.china.huawei.com (10.3.19.204) with Microsoft SMTP Server id 14.3.361.1; Wed, 16 May 2018 23:21:57 +0800 From: Shameer Kolothum To: , Date: Wed, 16 May 2018 16:20:25 +0100 Message-ID: <20180516152026.2920-6-shameerali.kolothum.thodi@huawei.com> X-Mailer: git-send-email 2.12.0.windows.1 In-Reply-To: <20180516152026.2920-1-shameerali.kolothum.thodi@huawei.com> References: <20180516152026.2920-1-shameerali.kolothum.thodi@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.202.227.237] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 45.249.212.191 Subject: [Qemu-devel] [RFC v2 5/6] hw/arm: ACPI SRAT changes to accommodate non-contiguous mem 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: peter.maydell@linaro.org, drjones@redhat.com, jonathan.cameron@huawei.com, linuxarm@huawei.com, Shameer Kolothum , eric.auger@redhat.com, alex.williamson@redhat.com, zhaoshenglong@huawei.com, imammedo@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 Content-Type: text/plain; charset="utf-8" This is in preparation for the next patch where initial ram is split into a non-pluggable chunk and a pc-dimm modeled mem if the vaild iova regions are non-contiguous. Signed-off-by: Shameer Kolothum --- hw/arm/virt-acpi-build.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index c7c6a57..8d17b40 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -488,7 +488,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, Virt= MachineState *vms) AcpiSratProcessorGiccAffinity *core; AcpiSratMemoryAffinity *numamem; int i, srat_start; - uint64_t mem_base; + uint64_t mem_base, mem_sz, mem_len; MachineClass *mc =3D MACHINE_GET_CLASS(vms); const CPUArchIdList *cpu_list =3D mc->possible_cpu_arch_ids(MACHINE(vm= s)); =20 @@ -505,12 +505,28 @@ build_srat(GArray *table_data, BIOSLinker *linker, Vi= rtMachineState *vms) core->flags =3D cpu_to_le32(1); } =20 - mem_base =3D vms->memmap[VIRT_MEM].base; + mem_base =3D vms->bootinfo.loader_start; + mem_sz =3D vms->bootinfo.loader_start; for (i =3D 0; i < nb_numa_nodes; ++i) { numamem =3D acpi_data_push(table_data, sizeof(*numamem)); - build_srat_memory(numamem, mem_base, numa_info[i].node_mem, i, + mem_len =3D MIN(numa_info[i].node_mem, mem_sz); + build_srat_memory(numamem, mem_base, mem_len, i, MEM_AFFINITY_ENABLED); - mem_base +=3D numa_info[i].node_mem; + mem_base +=3D mem_len; + mem_sz -=3D mem_len; + if (!mem_sz) { + break; + } + } + + /* Create table for initial pc-dimm ram, if any */ + if (vms->bootinfo.dimm_mem) { + numamem =3D acpi_data_push(table_data, sizeof(*numamem)); + build_srat_memory(numamem, vms->bootinfo.dimm_mem->base, + vms->bootinfo.dimm_mem->size, + vms->bootinfo.dimm_mem->node, + MEM_AFFINITY_ENABLED); + } =20 build_header(linker, table_data, (void *)(table_data->data + srat_star= t), --=20 2.7.4 From nobody Wed Oct 29 23:02:01 2025 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 15264842692491018.1076365052555; Wed, 16 May 2018 08:24:29 -0700 (PDT) Received: from localhost ([::1]:51238 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fIyI0-0000nT-Du for importer@patchew.org; Wed, 16 May 2018 11:24:28 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54319) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fIyGE-0008BU-28 for qemu-devel@nongnu.org; Wed, 16 May 2018 11:22:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fIyG9-0005yW-7C for qemu-devel@nongnu.org; Wed, 16 May 2018 11:22:38 -0400 Received: from szxga05-in.huawei.com ([45.249.212.191]:2098 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fIyFz-0005sv-0U; Wed, 16 May 2018 11:22:24 -0400 Received: from DGGEMS404-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id 36BEBE5CA1DC9; Wed, 16 May 2018 23:22:06 +0800 (CST) Received: from S00345302A-PC.china.huawei.com (10.202.227.237) by DGGEMS404-HUB.china.huawei.com (10.3.19.204) with Microsoft SMTP Server id 14.3.361.1; Wed, 16 May 2018 23:22:01 +0800 From: Shameer Kolothum To: , Date: Wed, 16 May 2018 16:20:26 +0100 Message-ID: <20180516152026.2920-7-shameerali.kolothum.thodi@huawei.com> X-Mailer: git-send-email 2.12.0.windows.1 In-Reply-To: <20180516152026.2920-1-shameerali.kolothum.thodi@huawei.com> References: <20180516152026.2920-1-shameerali.kolothum.thodi@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.202.227.237] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 45.249.212.191 Subject: [Qemu-devel] [RFC v2 6/6] hw/arm: Populate non-contiguous memory regions 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: peter.maydell@linaro.org, drjones@redhat.com, jonathan.cameron@huawei.com, linuxarm@huawei.com, Shameer Kolothum , eric.auger@redhat.com, alex.williamson@redhat.com, zhaoshenglong@huawei.com, imammedo@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 Content-Type: text/plain; charset="utf-8" In case valid iova regions are non-contiguous, split the RAM mem into a 1GB non-pluggable dimm and remaining as a single pc-dimm mem. Signed-off-by: Shameer Kolothum --- hw/arm/virt.c | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++-- 1 file changed, 256 insertions(+), 5 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index be3ad14..562e389 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -58,6 +58,12 @@ #include "hw/smbios/smbios.h" #include "qapi/visitor.h" #include "standard-headers/linux/input.h" +#include "hw/vfio/vfio-common.h" +#include "qemu/config-file.h" +#include "monitor/qdev.h" +#include "qom/object_interfaces.h" +#include "qapi/qmp/qdict.h" +#include "qemu/option.h" =20 #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \ static void virt_##major##_##minor##_class_init(ObjectClass *oc, \ @@ -110,7 +116,10 @@ static ARMPlatformBusSystemParams platform_bus_params; * terabyte of physical address space.) */ #define RAMLIMIT_GB 255 -#define RAMLIMIT_BYTES (RAMLIMIT_GB * 1024ULL * 1024 * 1024) +#define SZ_1G (1024ULL * 1024 * 1024) +#define RAMLIMIT_BYTES (RAMLIMIT_GB * SZ_1G) + +#define ALIGN_1G (1ULL << 30) =20 /* Addresses and sizes of our components. * 0..128MB is space for a flash device so we can run bootrom code such as= UEFI. @@ -1171,6 +1180,236 @@ void virt_machine_done(Notifier *notifier, void *da= ta) virt_build_smbios(vms); } =20 +static void free_iova_copy(struct vfio_iova_head *iova_copy) +{ + VFIOIovaRange *iova, *tmp; + + QLIST_FOREACH_SAFE(iova, iova_copy, next, tmp) { + QLIST_REMOVE(iova, next); + g_free(iova); + } +} + +static void get_iova_copy(struct vfio_iova_head *iova_copy) +{ + VFIOIovaRange *iova, *new, *prev_iova =3D NULL; + + QLIST_FOREACH(iova, &vfio_iova_regions, next) { + new =3D g_malloc0(sizeof(*iova)); + new->start =3D iova->start; + new->end =3D iova->end; + + if (prev_iova) { + QLIST_INSERT_AFTER(prev_iova, new, next); + } else { + QLIST_INSERT_HEAD(iova_copy, new, next); + } + prev_iova =3D new; + } +} + +static hwaddr find_memory_chunk(VirtMachineState *vms, + struct vfio_iova_head *iova_copy, + hwaddr req_size, bool pcdimm) +{ + VFIOIovaRange *iova, *tmp; + hwaddr new_start, new_size, sz_align; + hwaddr virt_start =3D vms->memmap[VIRT_MEM].base; + hwaddr addr_align =3D ALIGN_1G; /* Set to max ARM64 hugepage size */ + + /* Size alignment */ + sz_align =3D (pcdimm) ? MAX(TARGET_PAGE_SIZE, QEMU_VMALLOC_ALIGN) : + TARGET_PAGE_SIZE; + + QLIST_FOREACH_SAFE(iova, iova_copy, next, tmp) { + if (virt_start >=3D iova->end) { + continue; + } + + /* Align addr */ + new_start =3D ROUND_UP(MAX(virt_start, iova->start), addr_align); + if (new_start >=3D iova->end) { + continue; + } + + if (req_size > iova->end - new_start + 1) { + continue; + } + + /* + * Check the region can hold any size alignment requirement. + */ + new_size =3D QEMU_ALIGN_UP(req_size, sz_align); + + if ((new_start + new_size - 1 > iova->end) || + (new_start + new_size >=3D virt_start + RAMLIMIT_BYTES)) { + continue; + } + + /* + * Modify the iova list entry for non pc-dimm case so that it + * is not used again for pc-dimm allocation. + */ + if (!pcdimm) { + if (new_size - req_size) { + iova->start =3D new_start + new_size; + } else { + QLIST_REMOVE(iova, next); + } + } + return new_start; + } + + return -1; +} + +static void update_memory_regions(VirtMachineState *vms) +{ + hwaddr addr; + VFIOIovaRange *iova; + MachineState *machine =3D MACHINE(vms); + hwaddr virt_start =3D vms->memmap[VIRT_MEM].base; + hwaddr req_size, ram_size =3D machine->ram_size; + struct vfio_iova_head iova_copy =3D QLIST_HEAD_INITIALIZER(iova_copy); + + /* No valid iova regions, use default */ + if (QLIST_EMPTY(&vfio_iova_regions)) { + vms->bootinfo.loader_start =3D vms->memmap[VIRT_MEM].base; + vms->bootinfo.ram_size =3D ram_size; + return; + } + + /* + * If valid iovas has only one entry, check the req size fits in + * and can have the loader start < 4GB. This will make sure platforms + * with no holes in mem will have the same mem model as before. + */ + req_size =3D ram_size; + iova =3D QLIST_NEXT(QLIST_FIRST(&vfio_iova_regions), next); + if (!iova) { + iova =3D QLIST_FIRST(&vfio_iova_regions); + addr =3D ROUND_UP(MAX(virt_start, iova->start), ALIGN_1G); + if ((addr < 4 * SZ_1G) && (ram_size <=3D iova->end - addr + 1) && + (addr + ram_size < virt_start + RAMLIMIT_BYTES)) { + vms->bootinfo.loader_start =3D addr; + vms->bootinfo.ram_size =3D ram_size; + return; + } + } + + /* Get a copy of valid iovas and work on it */ + get_iova_copy(&iova_copy); + + /* Split the mem as first 1GB non-pluggable and rest as pc-dimm */ + req_size =3D MIN(ram_size, SZ_1G); + addr =3D find_memory_chunk(vms, &iova_copy, req_size, false); + if (addr =3D=3D -1 || addr >=3D 4 * SZ_1G) { + goto out; + } + + /*Update non-pluggable mem details */ + machine->ram_size =3D req_size; + vms->bootinfo.loader_start =3D addr; + vms->bootinfo.ram_size =3D machine->ram_size; + + req_size =3D ram_size - req_size; + if (!req_size) { + goto done; + } + + /* Remaining memory is modeled as a pc-dimm. */ + addr =3D find_memory_chunk(vms, &iova_copy, req_size, true); + if (addr =3D=3D -1) { + goto out; + } + + /*Update pc-dimm mem details */ + vms->bootinfo.dimm_mem =3D g_new(struct dimm_mem_info, 1); + vms->bootinfo.dimm_mem->base =3D addr; + vms->bootinfo.dimm_mem->size =3D req_size; + machine->maxram_size =3D machine->ram_size + req_size; + machine->ram_slots +=3D 1; + +done: + free_iova_copy(&iova_copy); + return; + +out: + free_iova_copy(&iova_copy); + error_report("mach-virt: Not enough contiguous memory to model ram"); + exit(1); +} + +static void create_pcdimms(VirtMachineState *vms, + MemoryRegion *sysmem, + MemoryRegion *ram) +{ + hwaddr addr, size; + Error *local_err =3D NULL; + QDict *qdict; + QemuOpts *opts; + char *tmp; + + if (!vms->bootinfo.dimm_mem) { + return; + } + + addr =3D vms->bootinfo.dimm_mem->base; + size =3D vms->bootinfo.dimm_mem->size; + + /*Create hotplug address space */ + vms->hotplug_memory.base =3D ROUND_UP(addr, ALIGN_1G); + size =3D ROUND_UP(size, MAX(TARGET_PAGE_SIZE, QEMU_VMALLOC_ALIGN)); + + memory_region_init(&vms->hotplug_memory.mr, OBJECT(vms), + "hotplug-memory", size); + memory_region_add_subregion(sysmem, vms->hotplug_memory.base, + &vms->hotplug_memory.mr); + /* Create backend mem object */ + qdict =3D qdict_new(); + qdict_put_str(qdict, "qom-type", "memory-backend-ram"); + qdict_put_str(qdict, "id", "mem1"); + tmp =3D g_strdup_printf("%"PRIu64 "M", size / (1024 * 1024)); + qdict_put_str(qdict, "size", tmp); + g_free(tmp); + + opts =3D qemu_opts_from_qdict(qemu_find_opts("object"), qdict, &local_= err); + if (local_err) { + goto err; + } + + user_creatable_add_opts(opts, &local_err); + qemu_opts_del(opts); + QDECREF(qdict); + if (local_err) { + goto err; + } + + /* Create pc-dimm dev*/ + qdict =3D qdict_new(); + qdict_put_str(qdict, "driver", "pc-dimm"); + qdict_put_str(qdict, "id", "dimm1"); + qdict_put_str(qdict, "memdev", "mem1"); + + opts =3D qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &local_= err); + if (local_err) { + goto err; + } + + qdev_device_add(opts, &local_err); + qemu_opts_del(opts); + QDECREF(qdict); + if (local_err) { + goto err; + } + + return; + +err: + error_report_err(local_err); + exit(1); +} + static void virt_ram_memory_region_init(Notifier *notifier, void *data) { MemoryRegion *sysmem =3D get_system_memory(); @@ -1179,9 +1418,14 @@ static void virt_ram_memory_region_init(Notifier *no= tifier, void *data) ram_memory_region_init); MachineState *machine =3D MACHINE(vms); =20 + update_memory_regions(vms); memory_region_allocate_system_memory(ram, NULL, "mach-virt.ram", machine->ram_size); - memory_region_add_subregion(sysmem, vms->memmap[VIRT_MEM].base, ram); + memory_region_add_subregion(sysmem, vms->bootinfo.loader_start, ram); + + if (vms->bootinfo.dimm_mem) { + create_pcdimms(vms, sysmem, ram); + } } =20 static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx) @@ -1404,13 +1648,11 @@ static void machvirt_init(MachineState *machine) vms->machine_done.notify =3D virt_machine_done; qemu_add_machine_init_done_notifier(&vms->machine_done); =20 - vms->bootinfo.ram_size =3D machine->ram_size; vms->bootinfo.kernel_filename =3D machine->kernel_filename; vms->bootinfo.kernel_cmdline =3D machine->kernel_cmdline; vms->bootinfo.initrd_filename =3D machine->initrd_filename; vms->bootinfo.nb_cpus =3D smp_cpus; vms->bootinfo.board_id =3D -1; - vms->bootinfo.loader_start =3D vms->memmap[VIRT_MEM].base; vms->bootinfo.get_dtb =3D machvirt_dtb; vms->bootinfo.firmware_loaded =3D firmware_loaded; =20 @@ -1559,7 +1801,7 @@ static void virt_dimm_plug(HotplugHandler *hotplug_de= v, PCDIMMDevice *dimm =3D PC_DIMM(dev); PCDIMMDeviceClass *ddc =3D PC_DIMM_GET_CLASS(dimm); MemoryRegion *mr; - uint64_t align; + uint64_t align, addr; Error *local_err =3D NULL; =20 mr =3D ddc->get_memory_region(dimm, &local_err); @@ -1573,6 +1815,15 @@ static void virt_dimm_plug(HotplugHandler *hotplug_d= ev, goto out; } =20 + addr =3D object_property_get_uint(OBJECT(dimm), PC_DIMM_ADDR_PROP, + &error_fatal); + /* Assign the node for pc-dimm initial ram */ + if (vms->bootinfo.dimm_mem && (addr =3D=3D vms->bootinfo.dimm_mem->bas= e) + && (nb_numa_nodes > 0)) { + vms->bootinfo.dimm_mem->node =3D object_property_get_uint(OBJECT(d= ev), + PC_DIMM_NODE_PROP, &error_fatal= ); + } + out: error_propagate(errp, local_err); } --=20 2.7.4