From patchwork Tue Feb 5 17:32:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Auger X-Patchwork-Id: 1036990 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43vBxZ2ylvz9s7T for ; Wed, 6 Feb 2019 04:52:49 +1100 (AEDT) Received: from localhost ([127.0.0.1]:35979 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gr4tq-0006bx-Rq for incoming@patchwork.ozlabs.org; Tue, 05 Feb 2019 12:52:46 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46747) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gr4bk-0000I6-L1 for qemu-devel@nongnu.org; Tue, 05 Feb 2019 12:34:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gr4bj-0004Mk-Ic for qemu-devel@nongnu.org; Tue, 05 Feb 2019 12:34:04 -0500 Received: from mx1.redhat.com ([209.132.183.28]:40654) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gr4bf-0004JR-MG; Tue, 05 Feb 2019 12:33:59 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7F3E57F6C7; Tue, 5 Feb 2019 17:33:58 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-102.ams2.redhat.com [10.36.116.102]) by smtp.corp.redhat.com (Postfix) with ESMTP id D9F5A17988; Tue, 5 Feb 2019 17:33:55 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, qemu-devel@nongnu.org, qemu-arm@nongnu.org, peter.maydell@linaro.org, shameerali.kolothum.thodi@huawei.com, imammedo@redhat.com, david@redhat.com Date: Tue, 5 Feb 2019 18:32:57 +0100 Message-Id: <20190205173306.20483-10-eric.auger@redhat.com> In-Reply-To: <20190205173306.20483-1-eric.auger@redhat.com> References: <20190205173306.20483-1-eric.auger@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Tue, 05 Feb 2019 17:33:58 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v6 09/18] hw/arm/virt: Implement kvm_type function for 4.0 machine 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: drjones@redhat.com, dgilbert@redhat.com, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch implements the machine class kvm_type() callback. It returns the max IPA shift needed to implement the whole GPA range including the RAM and IO regions located beyond. The returned value in passed though the KVM_CREATE_VM ioctl and this allows KVM to set the stage2 tables dynamically. At this stage the RAM limit still is limited to 255GB. Setting all the existing highmem IO regions beyond the RAM allows to have a single contiguous RAM region (initial RAM and possible hotpluggable device memory). That way we do not need to do invasive changes in the EDK2 FW to support a dynamic RAM base. Signed-off-by: Eric Auger --- v5 -> v6: - add some comments - high IO region cannot start before 256GiB --- hw/arm/virt.c | 52 +++++++++++++++++++++++++++++++++++++++++-- include/hw/arm/virt.h | 2 ++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 2b15839d0b..b90ffc2e5d 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1366,6 +1366,7 @@ static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx) static void virt_set_memmap(VirtMachineState *vms) { + MachineState *ms = MACHINE(vms); hwaddr base; int i; @@ -1375,7 +1376,17 @@ static void virt_set_memmap(VirtMachineState *vms) vms->memmap[i] = a15memmap[i]; } - vms->high_io_base = 256 * GiB; /* Top of the legacy initial RAM region */ + /* + * We now compute the base of the high IO region depending on the + * amount of initial and device memory. The device memory start/size + * is aligned on 1GiB. We never put the high IO region below 256GiB + * so that if maxram_size is < 255GiB we keep the legacy memory map + */ + vms->high_io_base = ROUND_UP(GiB + ms->ram_size, GiB) + + ROUND_UP(ms->maxram_size - ms->ram_size, GiB); + if (vms->high_io_base < 256 * GiB) { + vms->high_io_base = 256 * GiB; + } base = vms->high_io_base; for (i = VIRT_LOWMEMMAP_LAST; i < ARRAY_SIZE(extended_memmap); i++) { @@ -1386,6 +1397,7 @@ static void virt_set_memmap(VirtMachineState *vms) vms->memmap[i].size = size; base += size; } + vms->highest_gpa = base - 1; } static void machvirt_init(MachineState *machine) @@ -1402,7 +1414,9 @@ static void machvirt_init(MachineState *machine) bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0); bool aarch64 = true; - virt_set_memmap(vms); + if (!vms->extended_memmap) { + virt_set_memmap(vms); + } /* We can probe only here because during property set * KVM is not available yet @@ -1784,6 +1798,36 @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine, return NULL; } +/* + * for arm64 kvm_type [7-0] encodes the IPA size shift + */ +static int virt_kvm_type(MachineState *ms, const char *type_str) +{ + VirtMachineState *vms = VIRT_MACHINE(ms); + int max_vm_phys_shift = kvm_arm_get_max_vm_phys_shift(ms); + int max_pa_shift; + + vms->extended_memmap = true; + + virt_set_memmap(vms); + + max_pa_shift = 64 - clz64(vms->highest_gpa); + + if (max_pa_shift > max_vm_phys_shift) { + error_report("-m and ,maxmem option values " + "require an IPA range (%d bits) larger than " + "the one supported by the host (%d bits)", + max_pa_shift, max_vm_phys_shift); + exit(1); + } + /* + * By default we return 0 which corresponds to an implicit legacy + * 40b IPA setting. Otherwise we return the actual requested IPA + * logsize + */ + return max_pa_shift > 40 ? max_pa_shift : 0; +} + static void virt_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -1808,6 +1852,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) mc->cpu_index_to_instance_props = virt_cpu_index_to_props; mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15"); mc->get_default_cpu_node_id = virt_get_default_cpu_node_id; + mc->kvm_type = virt_kvm_type; assert(!mc->get_hotplug_handler); mc->get_hotplug_handler = virt_machine_get_hotplug_handler; hc->plug = virt_machine_device_plug_cb; @@ -1911,6 +1956,9 @@ static void virt_machine_3_1_options(MachineClass *mc) { virt_machine_4_0_options(mc); compat_props_add(mc->compat_props, hw_compat_3_1, hw_compat_3_1_len); + + /* extended memory map is enabled from 4.0 onwards */ + mc->kvm_type = NULL; } DEFINE_VIRT_MACHINE(3, 1) diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index 3dc7a6c5d5..c88f67a492 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -132,6 +132,8 @@ typedef struct { uint32_t iommu_phandle; int psci_conduit; hwaddr high_io_base; + hwaddr highest_gpa; + bool extended_memmap; } VirtMachineState; #define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)