From nobody Mon Nov 25 04:44:23 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1718322034; cv=none; d=zohomail.com; s=zohoarc; b=VT3W7FL1kYn0NRxo/QE99UeBWFzk6aLVNHVENvV1d7NtOUk/l+sgcND1E/dmniA8vcMi4qHAAm52wo1r/8SSeIRJQptilTFMqOjO8bTc5OVMzCRvG0AStcvH0kVXX5Pb8GszAYy/qnC/II6z1q9sAY6xS0vDQDy5Pass186bojE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1718322034; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=OuAc7gPDb9j9AAW9MX/zRRYP4FVz3MMLXg8xrjKi47U=; b=Q10YhE2Lx0cITUyVNGCRFywCzLervJE5BwkT07gR5ODnH481LDW1NFOvhtGZY2Nnu4y820McSJ6ZzAw7HRHXpWZ1AdvIkLkxOzTK/b3kjlpFEEOOucovRfCc2G/R+XpH5VQC0ZmGlRBV8/36l9oiaetL2F3jy/2wpcFBE4sV6fo= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1718322034444690.9806980935592; Thu, 13 Jun 2024 16:40:34 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sHu37-0007Mm-4G; Thu, 13 Jun 2024 19:40:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sHu2u-0006qz-NV; Thu, 13 Jun 2024 19:39:58 -0400 Received: from frasgout.his.huawei.com ([185.176.79.56]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sHu2r-00035V-T9; Thu, 13 Jun 2024 19:39:56 -0400 Received: from mail.maildlp.com (unknown [172.18.186.231]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4W0f402bDPz6H7Gh; Fri, 14 Jun 2024 07:38:24 +0800 (CST) Received: from lhrpeml500001.china.huawei.com (unknown [7.191.163.213]) by mail.maildlp.com (Postfix) with ESMTPS id CB992140AE5; Fri, 14 Jun 2024 07:39:47 +0800 (CST) Received: from 00293818-MRGF.china.huawei.com (10.195.245.24) by lhrpeml500001.china.huawei.com (7.191.163.213) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.39; Fri, 14 Jun 2024 00:39:25 +0100 To: , , CC: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , Subject: [PATCH RFC V3 05/29] arm/virt, target/arm: Machine init time change common to vCPU {cold|hot}-plug Date: Fri, 14 Jun 2024 00:36:15 +0100 Message-ID: <20240613233639.202896-6-salil.mehta@huawei.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240613233639.202896-1-salil.mehta@huawei.com> References: <20240613233639.202896-1-salil.mehta@huawei.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Originating-IP: [10.195.245.24] X-ClientProxiedBy: dggems703-chm.china.huawei.com (10.3.19.180) To lhrpeml500001.china.huawei.com (7.191.163.213) Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=185.176.79.56; envelope-from=salil.mehta@huawei.com; helo=frasgout.his.huawei.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Salil Mehta From: Salil Mehta via Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1718322035043100001 Content-Type: text/plain; charset="utf-8" Introduce the common logic required during the initialization of both cold = and hot-plugged vCPUs. Additionally, initialize the *disabled* state of the vCP= Us, which will be used further during the initialization phases of various other components like GIC, PMU, ACPI, etc., as part of the virtual machine initialization. KVM vCPUs corresponding to unplugged or yet-to-be-plugged QOM CPUs are kept= in a powered-off state in the KVM Host and do not run the guest code. Plugged vC= PUs are also kept in a powered-off state, but vCPU threads exist and remain in a sleeping state. TBD: For cold-booted vCPUs, this change also exists in the `arm_load_kernel()` function in `boot.c`. However, for hot-plugged CPUs, this change should rem= ain part of the pre-plug phase. We are duplicating the powering-off of the cold-booted CPUs. Should we remove the duplicate change from `boot.c`? Co-developed-by: Keqian Zhu Signed-off-by: Keqian Zhu Signed-off-by: Salil Mehta Reported-by: Gavin Shan [GS: pointed the assertion due to wrong range check] --- hw/arm/virt.c | 94 +++++++++++++++++++++++++++++++++++++++++++++- target/arm/cpu.c | 7 ++++ target/arm/cpu64.c | 14 +++++++ 3 files changed, 114 insertions(+), 1 deletion(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 2e0ec7d869..a285139165 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -2817,6 +2817,26 @@ static int64_t virt_get_default_cpu_node_id(const Ma= chineState *ms, int idx) return socket_id % ms->numa_state->num_nodes; } =20 +static int +virt_get_cpu_id_from_cpu_topo(const MachineState *ms, DeviceState *dev) +{ + int cpu_id, sock_vcpu_num, clus_vcpu_num, core_vcpu_num; + ARMCPU *cpu =3D ARM_CPU(dev); + + /* calculate total logical cpus across socket/cluster/core */ + sock_vcpu_num =3D cpu->socket_id * (ms->smp.threads * ms->smp.cores * + ms->smp.clusters); + clus_vcpu_num =3D cpu->cluster_id * (ms->smp.threads * ms->smp.cores); + core_vcpu_num =3D cpu->core_id * ms->smp.threads; + + /* get vcpu-id(logical cpu index) for this vcpu from this topology */ + cpu_id =3D (sock_vcpu_num + clus_vcpu_num + core_vcpu_num) + cpu->thre= ad_id; + + assert(cpu_id >=3D 0 && cpu_id < ms->possible_cpus->len); + + return cpu_id; +} + static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms) { int n; @@ -2899,6 +2919,72 @@ static void virt_memory_plug(HotplugHandler *hotplug= _dev, dev, &error_abort); } =20 +static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev, DeviceState *de= v, + Error **errp) +{ + MachineState *ms =3D MACHINE(hotplug_dev); + ARMCPU *cpu =3D ARM_CPU(dev); + CPUState *cs =3D CPU(dev); + CPUArchId *cpu_slot; + + /* sanity check the cpu */ + if (!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) { + error_setg(errp, "Invalid CPU type, expected cpu type: '%s'", + ms->cpu_type); + return; + } + + if ((cpu->thread_id < 0) || (cpu->thread_id >=3D ms->smp.threads)) { + error_setg(errp, "Invalid thread-id %u specified, correct range 0:= %u", + cpu->thread_id, ms->smp.threads - 1); + return; + } + + if ((cpu->core_id < 0) || (cpu->core_id >=3D ms->smp.cores)) { + error_setg(errp, "Invalid core-id %d specified, correct range 0:%u= ", + cpu->core_id, ms->smp.cores - 1); + return; + } + + if ((cpu->cluster_id < 0) || (cpu->cluster_id >=3D ms->smp.clusters)) { + error_setg(errp, "Invalid cluster-id %u specified, correct range 0= :%u", + cpu->cluster_id, ms->smp.clusters - 1); + return; + } + + if ((cpu->socket_id < 0) || (cpu->socket_id >=3D ms->smp.sockets)) { + error_setg(errp, "Invalid socket-id %u specified, correct range 0:= %u", + cpu->socket_id, ms->smp.sockets - 1); + return; + } + + cs->cpu_index =3D virt_get_cpu_id_from_cpu_topo(ms, dev); + + cpu_slot =3D virt_find_cpu_slot(ms, cs->cpu_index); + if (qemu_present_cpu(CPU(cpu_slot->cpu))) { + error_setg(errp, "cpu(id%d=3D%d:%d:%d:%d) with arch-id %" PRIu64 "= exist", + cs->cpu_index, cpu->socket_id, cpu->cluster_id, cpu->co= re_id, + cpu->thread_id, cpu_slot->arch_id); + return; + } + virt_cpu_set_properties(OBJECT(cs), cpu_slot, errp); +} + +static void virt_cpu_plug(HotplugHandler *hotplug_dev, DeviceState *dev, + Error **errp) +{ + MachineState *ms =3D MACHINE(hotplug_dev); + CPUState *cs =3D CPU(dev); + CPUArchId *cpu_slot; + + /* insert the cold/hot-plugged vcpu in the slot */ + cpu_slot =3D virt_find_cpu_slot(ms, cs->cpu_index); + cpu_slot->cpu =3D CPU(dev); + + cs->disabled =3D false; + return; +} + static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { @@ -2906,6 +2992,8 @@ static void virt_machine_device_pre_plug_cb(HotplugHa= ndler *hotplug_dev, =20 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { virt_memory_pre_plug(hotplug_dev, dev, errp); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { + virt_cpu_pre_plug(hotplug_dev, dev, errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) { virtio_md_pci_pre_plug(VIRTIO_MD_PCI(dev), MACHINE(hotplug_dev), e= rrp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) { @@ -2962,6 +3050,8 @@ static void virt_machine_device_plug_cb(HotplugHandle= r *hotplug_dev, virt_memory_plug(hotplug_dev, dev, errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) { virtio_md_pci_plug(VIRTIO_MD_PCI(dev), MACHINE(hotplug_dev), errp); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { + virt_cpu_plug(hotplug_dev, dev, errp); } =20 if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) { @@ -3046,7 +3136,8 @@ static HotplugHandler *virt_machine_get_hotplug_handl= er(MachineState *machine, if (device_is_dynamic_sysbus(mc, dev) || object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) || object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI) || - object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) { + object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI) || + object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { return HOTPLUG_HANDLER(machine); } return NULL; @@ -3150,6 +3241,7 @@ static void virt_machine_class_init(ObjectClass *oc, = void *data) mc->valid_cpu_types =3D valid_cpu_types; mc->get_default_cpu_node_id =3D virt_get_default_cpu_node_id; mc->kvm_type =3D virt_kvm_type; + mc->has_hotpluggable_cpus =3D true; assert(!mc->get_hotplug_handler); mc->get_hotplug_handler =3D virt_machine_get_hotplug_handler; hc->pre_plug =3D virt_machine_device_pre_plug_cb; diff --git a/target/arm/cpu.c b/target/arm/cpu.c index abc4ed0842..c92162fa97 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -2639,6 +2639,12 @@ static const TCGCPUOps arm_tcg_ops =3D { }; #endif /* CONFIG_TCG */ =20 +static int64_t arm_cpu_get_arch_id(CPUState *cs) +{ + ARMCPU *cpu =3D ARM_CPU(cs); + return cpu->mp_affinity; +} + static void arm_cpu_class_init(ObjectClass *oc, void *data) { ARMCPUClass *acc =3D ARM_CPU_CLASS(oc); @@ -2658,6 +2664,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void = *data) cc->has_work =3D arm_cpu_has_work; cc->mmu_index =3D arm_cpu_mmu_index; cc->dump_state =3D arm_cpu_dump_state; + cc->get_arch_id =3D arm_cpu_get_arch_id; cc->set_pc =3D arm_cpu_set_pc; cc->get_pc =3D arm_cpu_get_pc; cc->gdb_read_register =3D arm_cpu_gdb_read_register; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index c15d086049..d6b48b3424 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -780,6 +780,17 @@ static void aarch64_cpu_set_aarch64(Object *obj, bool = value, Error **errp) } } =20 +static void aarch64_cpu_initfn(Object *obj) +{ + CPUState *cs =3D CPU(obj); + + /* + * we start every ARM64 vcpu as disabled possible vCPU. It needs to be + * enabled explicitly + */ + cs->disabled =3D true; +} + static void aarch64_cpu_finalizefn(Object *obj) { } @@ -792,7 +803,9 @@ static const gchar *aarch64_gdb_arch_name(CPUState *cs) static void aarch64_cpu_class_init(ObjectClass *oc, void *data) { CPUClass *cc =3D CPU_CLASS(oc); + DeviceClass *dc =3D DEVICE_CLASS(oc); =20 + dc->user_creatable =3D true; cc->gdb_read_register =3D aarch64_cpu_gdb_read_register; cc->gdb_write_register =3D aarch64_cpu_gdb_write_register; cc->gdb_core_xml_file =3D "aarch64-core.xml"; @@ -837,6 +850,7 @@ void aarch64_cpu_register(const ARMCPUInfo *info) static const TypeInfo aarch64_cpu_type_info =3D { .name =3D TYPE_AARCH64_CPU, .parent =3D TYPE_ARM_CPU, + .instance_init =3D aarch64_cpu_initfn, .instance_finalize =3D aarch64_cpu_finalizefn, .abstract =3D true, .class_init =3D aarch64_cpu_class_init, --=20 2.34.1