From patchwork Thu Sep 19 01:55:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhao Liu X-Patchwork-Id: 13807286 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A627E1CFB9 for ; Thu, 19 Sep 2024 01:39:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726709993; cv=none; b=hpWykxrtPkuxBcYz3KSz2iCAZsSSZNwbZCAoxwDRGT1g4rMX2UMUg2I55iRyOggO4xafLWJm0UiPHF4PS/Uh3cZsxwmWCacJPRIPWk38QPrGFJ7YEEiO30s1Zn/gxbUP9Uo+tT946qYAtIiymk1tjGBqh3Cz8yWlGkWG1D+ynYE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726709993; c=relaxed/simple; bh=boVKc/SUSgKzZVCNXF6Ki7YN9fmGZ9ZYevKMMyl1qEI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=nH5JPheNfZtnFCT9X+RuclDV9Uq6rPVF9oY8BM2jl5SIsZEMtUZ+Y7J+zMIMYdRiCnAy4apkSUNfmB63DNiuLX/9uTKTajUdMeHYZ13t6a5n+u8PC3VYC5y2iwZ0yIqMHDwz15zZagUR9oGaFtqDdDEEJmml3zWwvr9jR6xHjYg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=KFFHvW50; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="KFFHvW50" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1726709992; x=1758245992; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=boVKc/SUSgKzZVCNXF6Ki7YN9fmGZ9ZYevKMMyl1qEI=; b=KFFHvW50ytBPb16grqB0nGxdhp4WmWgsNEzdxW5AXuqJxqnIRa/XCiLY 04LyGPyyqBEXsoCIKwYhYpcJEIzo+Lv9oFb0uHmMHjXaJVDv1OzvKJi0g qrVIc+eb2YnjWfMYgkk9N/W9lzdtaZnefs3I742EsCOa4IbAvqbk33Bb4 29OzQpe1WAzX00PvaMEtbSAmaY7WANCCG0bdKmSlkN3CDOETsQAnelngZ Rn+hzkhDZxEz+9jDAoWpv49LUZWalQD8yOjqyXovFN8gerG3GFwqM9cFR 9KufRXoHRLtbnO4uPIo+UXfFd3/Dm81+Po1+axY9O2cpuTs6yOyyOgeUQ Q==; X-CSE-ConnectionGUID: eaRxGHlcRjm8sD3NKBs9KQ== X-CSE-MsgGUID: C5UmaiutTKqVH9rkj0euTw== X-IronPort-AV: E=McAfee;i="6700,10204,11199"; a="25797809" X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="25797809" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2024 18:39:51 -0700 X-CSE-ConnectionGUID: j2QDLduuRda1guYfMEBzhA== X-CSE-MsgGUID: g9MJhIXaQNWqXtJKo1PT6w== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="70058475" Received: from liuzhao-optiplex-7080.sh.intel.com ([10.239.160.36]) by orviesa006.jf.intel.com with ESMTP; 18 Sep 2024 18:39:45 -0700 From: Zhao Liu To: =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , Igor Mammedov , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , "Michael S . Tsirkin" , Paolo Bonzini , Richard Henderson , =?utf-8?q?C=C3=A9dric_Le_?= =?utf-8?q?Goater?= , Nicholas Piggin , =?utf-8?b?RnLDqWTDqXJpYyBCYXJyYXQ=?= , Daniel Henrique Barboza , David Gibson , Harsh Prateek Bora , Markus Armbruster , Marcelo Tosatti , =?utf-8?q?Alex_Benn=C3=A9e?= , Peter Maydell Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, qemu-ppc@nongnu.org, qemu-arm@nongnu.org, Zhenyu Wang , Dapeng Mi , Yongwei Ma , Zhao Liu Subject: [RFC v2 01/15] qdev: Add pointer to BusChild in DeviceState Date: Thu, 19 Sep 2024 09:55:19 +0800 Message-Id: <20240919015533.766754-2-zhao1.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240919015533.766754-1-zhao1.liu@intel.com> References: <20240919015533.766754-1-zhao1.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The device topology structures based on buses are unidirectional: the parent device can access the child device through the BusChild within the bus, but not vice versa. For the CPU topology tree constructed on the device-bus, it is necessary for the child device to be able to access the parent device via the parent bus. To address this, introduce a pointer to the BusChild, named bus_node. This pointer also simplifies the logic of bus_remove_child(). Instead of the parent bus needing to traverse the children list to locate the corresponding BusChild, it can now directly find it using the bus_node pointer. Signed-off-by: Zhao Liu --- hw/core/qdev.c | 29 ++++++++++++++--------------- include/hw/qdev-core.h | 4 ++++ include/qemu/typedefs.h | 1 + 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index db36f54d914a..4429856eaddd 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -57,25 +57,23 @@ static void bus_free_bus_child(BusChild *kid) static void bus_remove_child(BusState *bus, DeviceState *child) { - BusChild *kid; - - QTAILQ_FOREACH(kid, &bus->children, sibling) { - if (kid->child == child) { - char name[32]; + BusChild *kid = child->bus_node; + char name[32]; - snprintf(name, sizeof(name), "child[%d]", kid->index); - QTAILQ_REMOVE_RCU(&bus->children, kid, sibling); + if (!kid) { + return; + } - bus->num_children--; + snprintf(name, sizeof(name), "child[%d]", kid->index); + QTAILQ_REMOVE_RCU(&bus->children, kid, sibling); + child->bus_node = NULL; + bus->num_children--; - /* This gives back ownership of kid->child back to us. */ - object_property_del(OBJECT(bus), name); + /* This gives back ownership of kid->child back to us. */ + object_property_del(OBJECT(bus), name); - /* free the bus kid, when it is safe to do so*/ - call_rcu(kid, bus_free_bus_child, rcu); - break; - } - } + /* free the bus kid, when it is safe to do so*/ + call_rcu(kid, bus_free_bus_child, rcu); } static void bus_add_child(BusState *bus, DeviceState *child) @@ -86,6 +84,7 @@ static void bus_add_child(BusState *bus, DeviceState *child) bus->num_children++; kid->index = bus->max_index++; kid->child = child; + child->bus_node = kid; object_ref(OBJECT(kid->child)); QTAILQ_INSERT_HEAD_RCU(&bus->children, kid, sibling); diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index aa97c34a4be7..85c7d462dfba 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -253,6 +253,10 @@ struct DeviceState { * @parent_bus: bus this device belongs to */ BusState *parent_bus; + /** + * @bus_node: bus node inserted in parent bus + */ + BusChild *bus_node; /** * @gpios: QLIST of named GPIOs the device provides. */ diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index 9d222dc37628..aef41c4e67ce 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -32,6 +32,7 @@ typedef struct BdrvDirtyBitmapIter BdrvDirtyBitmapIter; typedef struct BlockBackend BlockBackend; typedef struct BlockBackendRootState BlockBackendRootState; typedef struct BlockDriverState BlockDriverState; +typedef struct BusChild BusChild; typedef struct BusClass BusClass; typedef struct BusState BusState; typedef struct Chardev Chardev; From patchwork Thu Sep 19 01:55:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Zhao Liu X-Patchwork-Id: 13807287 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0D2261DFF8 for ; Thu, 19 Sep 2024 01:39:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726709999; cv=none; b=Wz7dnBVjG5UGAcdNgPeOFYpI64VQEwM3hn8ZyK/dvnc5ntIBgZxA4cq15ojuywE02cghqvfvEDwtLHpiFd9yCsBcxb2/BOmKRFAgNndCXIE8lnr80Al6yaLgUzJbidwsNr0t9Os8zk1t55y4UQT8rr2cq3fNbZyXljbbHUQ6z6s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726709999; c=relaxed/simple; bh=GTUQ019BfwQpkrJFj+VNn+W9sPDXxvfUxmbaNbsBlZw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=QLCyrkswh0ESOBVW+pBn/C5KHGSzQuLiFthESt4WFpNnI+zhQffRNWjGNaGLxKWHekEGyL7io4kXwwLYkkf+wBs1mrTSjUan64OLZLdoqmQmlMNPvAwDqzg6ny/f91QzZvvk3ETEXbcOIHqXMbnLAUDx2euinLYnOKa1fsCB1BM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=Ft7OQuCR; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Ft7OQuCR" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1726709998; x=1758245998; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=GTUQ019BfwQpkrJFj+VNn+W9sPDXxvfUxmbaNbsBlZw=; b=Ft7OQuCRbsSQTg+WAVyUE7DQ3Xdn2PJ0MUVrM7uDeDPmz5HQnPY7WGzl svOMhEdZTRyxLAl7XpeiMnaHHtnZkfiPgbaPivCQrpO7+5r929xt5DP1G /24Y+GjfPBKDKt4ziHCDnIpRRalpnljltiHdKSYX7CbYlPDqCxAMWCziR E+TBNpNJrHR1GTfMHoMcllzSouzO6WrfA3QIPTtw/hLuDD6uSA2PmxGAZ 62ZPdtTDnbOpiQo7yFrNG2CBmCdLZ2eIWa8gtN+o9uNcRVNJ/cOKAQtIj UACQUZqEsix/ZZYNtmRufUgg3JX9W+Fdi6n9ewURWr9hX4JQXCM6MwNOt g==; X-CSE-ConnectionGUID: U8daUpQZRpejEQf+lccyiQ== X-CSE-MsgGUID: pi4GYTZyTQC8gXC7v0gCIA== X-IronPort-AV: E=McAfee;i="6700,10204,11199"; a="25797819" X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="25797819" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2024 18:39:58 -0700 X-CSE-ConnectionGUID: I3knkL/jSee7aLywlolMUQ== X-CSE-MsgGUID: yWAY1M6kTXWufBZ8mK+FLw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="70058495" Received: from liuzhao-optiplex-7080.sh.intel.com ([10.239.160.36]) by orviesa006.jf.intel.com with ESMTP; 18 Sep 2024 18:39:52 -0700 From: Zhao Liu To: =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , Igor Mammedov , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , "Michael S . Tsirkin" , Paolo Bonzini , Richard Henderson , =?utf-8?q?C=C3=A9dric_Le_?= =?utf-8?q?Goater?= , Nicholas Piggin , =?utf-8?b?RnLDqWTDqXJpYyBCYXJyYXQ=?= , Daniel Henrique Barboza , David Gibson , Harsh Prateek Bora , Markus Armbruster , Marcelo Tosatti , =?utf-8?q?Alex_Benn=C3=A9e?= , Peter Maydell Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, qemu-ppc@nongnu.org, qemu-arm@nongnu.org, Zhenyu Wang , Dapeng Mi , Yongwei Ma , Zhao Liu Subject: [RFC v2 02/15] qdev: Add the interface to reparent the device Date: Thu, 19 Sep 2024 09:55:20 +0800 Message-Id: <20240919015533.766754-3-zhao1.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240919015533.766754-1-zhao1.liu@intel.com> References: <20240919015533.766754-1-zhao1.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User created devices may need to adjust their default object parent or parent bus. User created devices are QOM parented to one of the peripheral containers ("/peripheral" or "/peripheral-anon") in qdev_set_id() by default. Sometimes, it is necessary to reparent a device to another object to express the more accurate child<> relationship, as in the cases of the PnvPHBRootPort device or subsequent topology devices. The current pnv_phb_user_get_parent() implements such reparenting logic. To allow it to be used by topology devices as well, transform it into a generic qdev interface with custom device id ("default_id" parameter). And add the code to handle the failure of object_property_add_child(). Signed-off-by: Zhao Liu --- hw/core/qdev.c | 52 +++++++++++++++++++++++++++++++++++++ hw/pci-host/pnv_phb.c | 59 +++++++++--------------------------------- include/hw/qdev-core.h | 3 +++ 3 files changed, 67 insertions(+), 47 deletions(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 4429856eaddd..ff073cbff56d 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -143,6 +143,58 @@ bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, Error **errp) return true; } +/* + * Set the QOM parent and parent bus of an object child. If the device + * state associated with the child has an id, use it as QOM id. + * Otherwise use default_id as QOM id. + * + * This helper does both operations at the same time because setting + * a new QOM child will erase the bus parent of the device. This happens + * because object_unparent() will call object_property_del_child(), + * which in turn calls the property release callback prop->release if + * it's defined. In our case this callback is set to + * object_finalize_child_property(), which was assigned during the + * first object_property_add_child() call. This callback will end up + * calling device_unparent(), and this function removes the device + * from its parent bus. + * + * The QOM and parent bus to be set aren't necessarily related, so + * let's receive both as arguments. + */ +bool qdev_set_parent(DeviceState *dev, BusState *bus, Object *parent, + char *default_id, Error **errp) +{ + Object *child = OBJECT(dev); + ObjectProperty *prop; + + if (!dev->id && !default_id) { + error_setg(errp, "unknown device id"); + return false; + } + + if (child->parent == parent) { + return true; + } + + object_ref(child); + object_unparent(child); + prop = object_property_add_child(parent, + dev->id ? dev->id : default_id, + child); + object_unref(child); + + if (!prop) { + error_setg(errp, "couldn't change parent"); + return false; + } + + if (!qdev_set_parent_bus(dev, bus, errp)) { + return false; + } + + return true; +} + DeviceState *qdev_new(const char *name) { ObjectClass *oc = object_class_by_name(name); diff --git a/hw/pci-host/pnv_phb.c b/hw/pci-host/pnv_phb.c index d4c118d44362..a26e7b7aec5c 100644 --- a/hw/pci-host/pnv_phb.c +++ b/hw/pci-host/pnv_phb.c @@ -19,49 +19,6 @@ #include "qom/object.h" #include "sysemu/sysemu.h" - -/* - * Set the QOM parent and parent bus of an object child. If the device - * state associated with the child has an id, use it as QOM id. - * Otherwise use object_typename[index] as QOM id. - * - * This helper does both operations at the same time because setting - * a new QOM child will erase the bus parent of the device. This happens - * because object_unparent() will call object_property_del_child(), - * which in turn calls the property release callback prop->release if - * it's defined. In our case this callback is set to - * object_finalize_child_property(), which was assigned during the - * first object_property_add_child() call. This callback will end up - * calling device_unparent(), and this function removes the device - * from its parent bus. - * - * The QOM and parent bus to be set arenĀ“t necessarily related, so - * let's receive both as arguments. - */ -static bool pnv_parent_fixup(Object *parent, BusState *parent_bus, - Object *child, int index, - Error **errp) -{ - g_autofree char *default_id = - g_strdup_printf("%s[%d]", object_get_typename(child), index); - const char *dev_id = DEVICE(child)->id; - - if (child->parent == parent) { - return true; - } - - object_ref(child); - object_unparent(child); - object_property_add_child(parent, dev_id ? dev_id : default_id, child); - object_unref(child); - - if (!qdev_set_parent_bus(DEVICE(child), parent_bus, errp)) { - return false; - } - - return true; -} - static Object *pnv_phb_user_get_parent(PnvChip *chip, PnvPHB *phb, Error **errp) { if (phb->version == 3) { @@ -82,6 +39,7 @@ static bool pnv_phb_user_device_init(PnvPHB *phb, Error **errp) PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine()); PnvChip *chip = pnv_get_chip(pnv, phb->chip_id); Object *parent = NULL; + g_autofree char *default_id = NULL; if (!chip) { error_setg(errp, "invalid chip id: %d", phb->chip_id); @@ -98,8 +56,11 @@ static bool pnv_phb_user_device_init(PnvPHB *phb, Error **errp) * correctly the device tree. pnv_xscom_dt() needs every * PHB to be a child of the chip to build the DT correctly. */ - if (!pnv_parent_fixup(parent, qdev_get_parent_bus(DEVICE(chip)), - OBJECT(phb), phb->phb_id, errp)) { + default_id = g_strdup_printf("%s[%d]", + object_get_typename(OBJECT(phb)), + phb->phb_id); + if (!qdev_set_parent(DEVICE(phb), qdev_get_parent_bus(DEVICE(chip)), + parent, default_id, errp)) { return false; } @@ -246,6 +207,7 @@ static void pnv_phb_root_port_realize(DeviceState *dev, Error **errp) uint16_t device_id = 0; Error *local_err = NULL; int chip_id, index; + g_autofree char *default_id = NULL; /* * 'index' will be used both as a PCIE slot value and to calculate @@ -273,8 +235,11 @@ static void pnv_phb_root_port_realize(DeviceState *dev, Error **errp) * parent bus. Change the QOM parent to be the same as the * parent bus it's already assigned to. */ - if (!pnv_parent_fixup(OBJECT(bus), BUS(bus), OBJECT(dev), - index, errp)) { + default_id = g_strdup_printf("%s[%d]", + object_get_typename(OBJECT(dev)), + index); + if (!qdev_set_parent(dev, BUS(bus), OBJECT(bus), + default_id, errp)) { return; } diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 85c7d462dfba..7cbc5fb97298 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -1011,6 +1011,9 @@ char *qdev_get_human_name(DeviceState *dev); /* FIXME: make this a link<> */ bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, Error **errp); +bool qdev_set_parent(DeviceState *dev, BusState *bus, Object *parent, + char *default_id, Error **errp); + extern bool qdev_hot_removed; char *qdev_get_dev_path(DeviceState *dev); From patchwork Thu Sep 19 01:55:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhao Liu X-Patchwork-Id: 13807288 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 012931DA4C for ; Thu, 19 Sep 2024 01:40:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710006; cv=none; b=LF/u0rIU/K3Gu6ld4YVviLqTdt85b8ANk0NtPh1Bu2qEtiCa5j7ZF6jWRHWO6H0ZI/sSqXvuGwmISLnDqvjAa7cbLv/duZiEQ0o577sY/dlfet+TL3uQ1s2KbS2Ij3iCTTzpDm8IlWZ/+Pv3cvuq92H7YeC/Tj5EGiVvGQVb6FI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710006; c=relaxed/simple; bh=pjDCYfWGmtcfHCeQzycylmOPTR/6NQwIB6dWf4c73R0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=GK5xdP5pL/yhhln7052jLWABaQ/DrfbvgwpdYAgVMDTzv9L9tSoHVouHUQjizOejLrMp8T67RNRkr/Ah/NcrvzvuqnqV0c+0b0vo6MVkh2mKgKeVhbpWCNOdjzPD+gKGargkG1DxlmPSusUYku4JwJ594lSqvtSBiitpxcRKIvk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=e00vo+xj; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="e00vo+xj" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1726710005; x=1758246005; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=pjDCYfWGmtcfHCeQzycylmOPTR/6NQwIB6dWf4c73R0=; b=e00vo+xjLaDpC54+UUL4Kzi9zPeijJAwklmFDkd+YeUiUzAqVWvZjkk6 fipU4zoCeA8jwg0OvXvSpwhWg2XI+4Cv7+Q1q+C4GwVHf39yspAi4h8AF M4WlTVjpLN2qPvf5DIWIZfZLSpgA/TKnEX97voLDvFmIqoziA1RcvKwdB E+qF8coRxRu+0XBLmNydmazesqOUqlh9XE5eckeS0VCq2EeMeIttLqoLC Vd9e1qe8bq8IcDMK5eYJ+zI5Y/zxptwD4Zof9dbg6TCzPkxZzt3MbWWq4 5w1h40RAsuU1K4LDPlEPMUp+97knmNsTFNycxF+WOD0UIcr5nFjZmxfek w==; X-CSE-ConnectionGUID: Y+eMeCuYQCibTtIUD6V0tA== X-CSE-MsgGUID: /TwQZXp4Siq+9xdaW6W4Jw== X-IronPort-AV: E=McAfee;i="6700,10204,11199"; a="25797835" X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="25797835" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2024 18:40:05 -0700 X-CSE-ConnectionGUID: XUKsPmtXTHeJZs8nwwQdZA== X-CSE-MsgGUID: 3BLglI8fRXKMxyszbBq4aA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="70058586" Received: from liuzhao-optiplex-7080.sh.intel.com ([10.239.160.36]) by orviesa006.jf.intel.com with ESMTP; 18 Sep 2024 18:39:58 -0700 From: Zhao Liu To: =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , Igor Mammedov , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , "Michael S . Tsirkin" , Paolo Bonzini , Richard Henderson , =?utf-8?q?C=C3=A9dric_Le_?= =?utf-8?q?Goater?= , Nicholas Piggin , =?utf-8?b?RnLDqWTDqXJpYyBCYXJyYXQ=?= , Daniel Henrique Barboza , David Gibson , Harsh Prateek Bora , Markus Armbruster , Marcelo Tosatti , =?utf-8?q?Alex_Benn=C3=A9e?= , Peter Maydell Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, qemu-ppc@nongnu.org, qemu-arm@nongnu.org, Zhenyu Wang , Dapeng Mi , Yongwei Ma , Zhao Liu Subject: [RFC v2 03/15] hw/cpu: Introduce CPU topology device and CPU bus Date: Thu, 19 Sep 2024 09:55:21 +0800 Message-Id: <20240919015533.766754-4-zhao1.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240919015533.766754-1-zhao1.liu@intel.com> References: <20240919015533.766754-1-zhao1.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Hybrid (or heterogeneous) CPU topology needs to be expressed as a topology tree, which requires to abstract all the CPU topology level as the objects. At present, QEMU already has the CPU device, core device and cluster device (for TCG), so that it's natual to introduce more topology related devices instead of abstractong native QEMU objects. To make it easier to deal with topological relationships, introduce the general and abstract CPU topology device, and also introduce the CPU bus to connect such CPU topology devices. With the underlying CPU topology device abstraction, all the CPU topology levels could be derived from it as subclasses. Then the specific devices, such as CPU, core, or future module/die/socket devices etc, don't have to care about topology relationship, and the underlying CPU topology abstraction and CPU bus will take care of everything and build the topology tree. Note, for the user created topology devices, they are specified the default object parent (one of the peripheral containers: "/peripheral" or "/peripheral-anon"). It's necessary to fixup their parent object to correct topology parent, so that it can make their canonical path in qtree match the actual topological hierarchies relationship. This is done by cpu_topo_set_parent() when topology device realizes. Signed-off-by: Zhao Liu --- MAINTAINERS | 2 + hw/cpu/cpu-topology.c | 179 ++++++++++++++++++++++++++++++++++ hw/cpu/meson.build | 2 + include/hw/cpu/cpu-topology.h | 68 +++++++++++++ include/qemu/typedefs.h | 2 + stubs/hotplug-stubs.c | 5 + 6 files changed, 258 insertions(+) create mode 100644 hw/cpu/cpu-topology.c create mode 100644 include/hw/cpu/cpu-topology.h diff --git a/MAINTAINERS b/MAINTAINERS index ffacd60f4075..230267597b5f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1884,12 +1884,14 @@ F: hw/core/machine-smp.c F: hw/core/null-machine.c F: hw/core/numa.c F: hw/cpu/cluster.c +F: hw/cpu/cpu-topology.c F: qapi/machine.json F: qapi/machine-common.json F: qapi/machine-target.json F: include/hw/boards.h F: include/hw/core/cpu.h F: include/hw/cpu/cluster.h +F: include/hw/cpu/cpu-topology.h F: include/sysemu/numa.h F: tests/functional/test_cpu_queries.py F: tests/functional/test_empty_cpu_model.py diff --git a/hw/cpu/cpu-topology.c b/hw/cpu/cpu-topology.c new file mode 100644 index 000000000000..e68c06132e7d --- /dev/null +++ b/hw/cpu/cpu-topology.c @@ -0,0 +1,179 @@ +/* + * General CPU topology device abstraction + * + * Copyright (C) 2024 Intel Corporation. + * + * Author: Zhao Liu + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" + +#include "hw/cpu/cpu-topology.h" +#include "hw/qdev-core.h" +#include "hw/qdev-properties.h" +#include "hw/sysbus.h" +#include "qapi/error.h" + +/* Roll up until topology root to check. */ +static bool cpu_parent_check_topology(DeviceState *parent, + DeviceState *dev, + Error **errp) +{ + BusClass *bc; + + if (!parent || !parent->parent_bus || + object_dynamic_cast(OBJECT(parent->parent_bus), TYPE_CPU_BUS)) { + return true; + } + + bc = BUS_GET_CLASS(parent->parent_bus); + if (bc->check_address) { + return bc->check_address(parent->parent_bus, dev, errp); + } + + return true; +} + +static bool cpu_bus_check_address(BusState *bus, DeviceState *dev, + Error **errp) +{ + CPUBusState *cbus = CPU_BUS(bus); + + if (cbus->check_topology) { + return cbus->check_topology(CPU_BUS(bus), CPU_TOPO(dev), errp); + } + + return cpu_parent_check_topology(bus->parent, dev, errp); +} + +static void cpu_bus_class_init(ObjectClass *oc, void *data) +{ + BusClass *bc = BUS_CLASS(oc); + + bc->check_address = cpu_bus_check_address; +} + +static const TypeInfo cpu_bus_type_info = { + .name = TYPE_CPU_BUS, + .parent = TYPE_BUS, + .class_init = cpu_bus_class_init, + .instance_size = sizeof(CPUBusState), +}; + +static bool cpu_topo_set_parent(CPUTopoState *topo, Error **errp) +{ + DeviceState *dev = DEVICE(topo); + BusState *bus = dev->parent_bus; + CPUTopoState *parent_topo = NULL; + Object *parent; + + if (!bus || !bus->parent) { + return true; + } + + if (topo->parent) { + error_setg(errp, "cpu topo: %s already have the parent?", + object_get_typename(OBJECT(topo))); + return false; + } + + parent = OBJECT(bus->parent); + if (object_dynamic_cast(parent, TYPE_CPU_TOPO)) { + parent_topo = CPU_TOPO(parent); + + if (GET_CPU_TOPO_LEVEL(topo) >= GET_CPU_TOPO_LEVEL(parent_topo)) { + error_setg(errp, "cpu topo: current level (%s) should be " + "lower than parent (%s) level", + object_get_typename(OBJECT(topo)), + object_get_typename(parent)); + return false; + } + } + + if (dev->id) { + /* + * Reparent topology device to make child<> match topological + * relationship. + */ + if (!qdev_set_parent(dev, bus, parent, NULL, errp)) { + return false; + } + } + + topo->parent = parent_topo; + return true; +} + +static void cpu_topo_realize(DeviceState *dev, Error **errp) +{ + CPUTopoState *topo = CPU_TOPO(dev); + CPUTopoClass *tc = CPU_TOPO_GET_CLASS(topo); + HotplugHandler *hotplug_handler; + + if (tc->level == CPU_TOPOLOGY_LEVEL_INVALID) { + error_setg(errp, "cpu topo: no level specified type: %s", + object_get_typename(OBJECT(dev))); + return; + } + + if (!cpu_topo_set_parent(topo, errp)) { + return; + } + + topo->bus = CPU_BUS(qbus_new(TYPE_CPU_BUS, dev, dev->id)); + hotplug_handler = qdev_get_bus_hotplug_handler(dev); + if (hotplug_handler) { + qbus_set_hotplug_handler(BUS(topo->bus), OBJECT(hotplug_handler)); + } +} + +static void cpu_topo_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + CPUTopoClass *tc = CPU_TOPO_CLASS(oc); + + set_bit(DEVICE_CATEGORY_CPU, dc->categories); + dc->realize = cpu_topo_realize; + + /* + * If people doesn't want a topology tree, it's necessary to + * derive a child class and override this as NULL. + */ + dc->bus_type = TYPE_CPU_BUS; + + /* + * The general topo device is not hotpluggable by default. + * If any topo device needs hotplug support, this flag must be + * overridden. + */ + dc->hotpluggable = false; + + tc->level = CPU_TOPOLOGY_LEVEL_INVALID; +} + +static const TypeInfo cpu_topo_type_info = { + .name = TYPE_CPU_TOPO, + .parent = TYPE_DEVICE, + .abstract = true, + .class_size = sizeof(CPUTopoClass), + .class_init = cpu_topo_class_init, + .instance_size = sizeof(CPUTopoState), +}; + +static void cpu_topo_register_types(void) +{ + type_register_static(&cpu_bus_type_info); + type_register_static(&cpu_topo_type_info); +} + +type_init(cpu_topo_register_types) + +int cpu_topo_get_instances_num(CPUTopoState *topo) +{ + BusState *bus = DEVICE(topo)->parent_bus; + + return bus ? bus->num_children : 1; +} diff --git a/hw/cpu/meson.build b/hw/cpu/meson.build index 9d36bf8ae2c1..6c6546646608 100644 --- a/hw/cpu/meson.build +++ b/hw/cpu/meson.build @@ -1,3 +1,5 @@ +common_ss.add(files('cpu-topology.c')) + system_ss.add(files('core.c')) system_ss.add(when: 'CONFIG_CPU_CLUSTER', if_true: files('cluster.c')) diff --git a/include/hw/cpu/cpu-topology.h b/include/hw/cpu/cpu-topology.h new file mode 100644 index 000000000000..7a447ad16ee7 --- /dev/null +++ b/include/hw/cpu/cpu-topology.h @@ -0,0 +1,68 @@ +/* + * General CPU topology device abstraction + * + * Copyright (C) 2024 Intel Corporation. + * + * Author: Zhao Liu + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + */ + +#ifndef CPU_TOPO_H +#define CPU_TOPO_H + +#include "hw/qdev-core.h" +#include "qapi/qapi-types-machine-common.h" +#include "qom/object.h" + +#define TYPE_CPU_BUS "cpu-bus" +OBJECT_DECLARE_SIMPLE_TYPE(CPUBusState, CPU_BUS) + +/** + * CPUBusState: + * @check_topology: Method to check if @topo is supported by @cbus. + */ +struct CPUBusState { + /*< private >*/ + BusState parent_obj; + + /*< public >*/ + bool (*check_topology)(CPUBusState *cbus, CPUTopoState *topo, + Error **errp); +}; + +#define TYPE_CPU_TOPO "cpu-topo" +OBJECT_DECLARE_TYPE(CPUTopoState, CPUTopoClass, CPU_TOPO) + +/** + * CPUTopoClass: + * @level: Topology level for this CPUTopoClass. + */ +struct CPUTopoClass { + /*< private >*/ + DeviceClass parent_class; + + /*< public >*/ + CpuTopologyLevel level; +}; + +/** + * CPUTopoState: + * @parent: Topology parent of this topology device. + * @bus: The CPU bus to add the children device. + */ +struct CPUTopoState { + /*< private >*/ + DeviceState parent_obj; + + /*< public >*/ + struct CPUTopoState *parent; + CPUBusState *bus; +}; + +#define GET_CPU_TOPO_LEVEL(topo) (CPU_TOPO_GET_CLASS(topo)->level) + +int cpu_topo_get_instances_num(CPUTopoState *topo); + +#endif /* CPU_TOPO_H */ diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index aef41c4e67ce..d62d8687403f 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -39,8 +39,10 @@ typedef struct Chardev Chardev; typedef struct Clock Clock; typedef struct ConfidentialGuestSupport ConfidentialGuestSupport; typedef struct CPUArchState CPUArchState; +typedef struct CPUBusState CPUBusState; typedef struct CPUPluginState CPUPluginState; typedef struct CPUState CPUState; +typedef struct CPUTopoState CPUTopoState; typedef struct DeviceState DeviceState; typedef struct DirtyBitmapSnapshot DirtyBitmapSnapshot; typedef struct DisasContextBase DisasContextBase; diff --git a/stubs/hotplug-stubs.c b/stubs/hotplug-stubs.c index 7aadaa29bd57..791fae079d6d 100644 --- a/stubs/hotplug-stubs.c +++ b/stubs/hotplug-stubs.c @@ -19,6 +19,11 @@ HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev) return NULL; } +HotplugHandler *qdev_get_bus_hotplug_handler(DeviceState *dev) +{ + return NULL; +} + void hotplug_handler_pre_plug(HotplugHandler *plug_handler, DeviceState *plugged_dev, Error **errp) From patchwork Thu Sep 19 01:55:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhao Liu X-Patchwork-Id: 13807289 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BF0E31E89C for ; Thu, 19 Sep 2024 01:40:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710014; cv=none; b=XzkxgIjOXtfZqLIfJZ5HhA899+ccQSiaEc3w/KwOKX7L3ShC+Yvp+htAlO2GAC/rnMIi3rQaZaUf/+X106hfos5Z4dXMa2O6m7domNQzkBN0kWvEgkazGHgLHi0UVjxwLd8rLM6i1uEOx2VPf3BZuoNkm/0dx/02LucTmM2CMEM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710014; c=relaxed/simple; bh=F7jWrurI1XVWfEeDSjk70sFPKqku+j5BACGGdK6zY9w=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=P+gSieDNZwcTYIVXj6ZzF9h2YdbSzkdW08ce2MvcOUvkV5qx3/R7tmtUrp2V52BlefQkhIKpUfPe1n6JUFNsWPpNPWIBB4abpmvRmtFETRyQxORjtmehqJFknjn2nHvkxSbbM919kDK2KIqpjLfpmhVR3Q/3DwSlHj3JiKvh47k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=SGYN6AiL; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="SGYN6AiL" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1726710013; x=1758246013; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=F7jWrurI1XVWfEeDSjk70sFPKqku+j5BACGGdK6zY9w=; b=SGYN6AiLCpPYJk4bOzreSTEiSLVq6N10hNBE7ExH+3bqGPrYz+TpvhmL JPAFllCuLT+RR25/eMHpp66/Pnq8eJClehlU698EFBhrK/aSSs6HMrUx4 CW8ztl6qMRlTNerSmgtiEvW1wFjafH9BRduIkkG51X8fCOLxTXj3V3fzP NZIc7jSiFMK4s3GZ/1Aksalp4L6xEVIUaUYr8eRD6bTfmZR5kowCF2q/8 VD1+jn17CxOZFGnPMQYLYvEfbwtfMO5XbAyi+vrF/QKYZPMjY/sd7hbxy MT0AlFB3B7NJoSx2IlaUzL9tgcwQI5J5pWQlNeaDhhwnzTl1t4pZAppPb g==; X-CSE-ConnectionGUID: 4dHoOVmeSLKdn/mghFDN+g== X-CSE-MsgGUID: lXAsgejeR1yltEDXkNbgkw== X-IronPort-AV: E=McAfee;i="6700,10204,11199"; a="25797853" X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="25797853" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2024 18:40:12 -0700 X-CSE-ConnectionGUID: VQKFuNgeQburcx//Eizfqw== X-CSE-MsgGUID: 5cDjh2NdT+qSFPCfiK9wyw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="70058644" Received: from liuzhao-optiplex-7080.sh.intel.com ([10.239.160.36]) by orviesa006.jf.intel.com with ESMTP; 18 Sep 2024 18:40:05 -0700 From: Zhao Liu To: =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , Igor Mammedov , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , "Michael S . Tsirkin" , Paolo Bonzini , Richard Henderson , =?utf-8?q?C=C3=A9dric_Le_?= =?utf-8?q?Goater?= , Nicholas Piggin , =?utf-8?b?RnLDqWTDqXJpYyBCYXJyYXQ=?= , Daniel Henrique Barboza , David Gibson , Harsh Prateek Bora , Markus Armbruster , Marcelo Tosatti , =?utf-8?q?Alex_Benn=C3=A9e?= , Peter Maydell Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, qemu-ppc@nongnu.org, qemu-arm@nongnu.org, Zhenyu Wang , Dapeng Mi , Yongwei Ma , Zhao Liu Subject: [RFC v2 04/15] hw/cpu: Introduce CPU slot to manage CPU topology Date: Thu, 19 Sep 2024 09:55:22 +0800 Message-Id: <20240919015533.766754-5-zhao1.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240919015533.766754-1-zhao1.liu@intel.com> References: <20240919015533.766754-1-zhao1.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 When there's a CPU topology tree, original MachineState.smp (CpuTopology structure) is not enough to dynamically monitor changes of the tree or update topology information in time. To address this, introduce the CPU slot, as the root of CPU topology tree, which is used to update and maintain global topological statistics by listening any changes of topology device (realize() and unrealize()). Signed-off-by: Zhao Liu --- MAINTAINERS | 2 + hw/cpu/cpu-slot.c | 140 ++++++++++++++++++++++++++++++++++++++ hw/cpu/meson.build | 1 + include/hw/cpu/cpu-slot.h | 72 ++++++++++++++++++++ 4 files changed, 215 insertions(+) create mode 100644 hw/cpu/cpu-slot.c create mode 100644 include/hw/cpu/cpu-slot.h diff --git a/MAINTAINERS b/MAINTAINERS index 230267597b5f..8e5b2cd91dca 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1884,6 +1884,7 @@ F: hw/core/machine-smp.c F: hw/core/null-machine.c F: hw/core/numa.c F: hw/cpu/cluster.c +F: hw/cpu/cpu-slot.c F: hw/cpu/cpu-topology.c F: qapi/machine.json F: qapi/machine-common.json @@ -1891,6 +1892,7 @@ F: qapi/machine-target.json F: include/hw/boards.h F: include/hw/core/cpu.h F: include/hw/cpu/cluster.h +F: include/hw/cpu/cpu-slot.h F: include/hw/cpu/cpu-topology.h F: include/sysemu/numa.h F: tests/functional/test_cpu_queries.py diff --git a/hw/cpu/cpu-slot.c b/hw/cpu/cpu-slot.c new file mode 100644 index 000000000000..66ef8d9faa97 --- /dev/null +++ b/hw/cpu/cpu-slot.c @@ -0,0 +1,140 @@ +/* + * CPU slot abstraction - manage CPU topology + * + * Copyright (C) 2024 Intel Corporation. + * + * Author: Zhao Liu + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" + +#include "hw/boards.h" +#include "hw/cpu/cpu-slot.h" +#include "hw/cpu/cpu-topology.h" +#include "hw/qdev-core.h" +#include "hw/qdev-properties.h" +#include "hw/sysbus.h" +#include "qapi/error.h" + +static void cpu_slot_add_topo_info(CPUSlot *slot, CPUTopoState *topo) +{ + CpuTopologyLevel level = GET_CPU_TOPO_LEVEL(topo); + CPUTopoStatEntry *entry; + int instances_num; + + entry = &slot->stat.entries[level]; + entry->total_instances++; + + instances_num = cpu_topo_get_instances_num(topo); + if (instances_num > entry->max_instances) { + entry->max_instances = instances_num; + } + + set_bit(level, slot->stat.curr_levels); + + return; +} + +static void cpu_slot_device_realize(DeviceListener *listener, + DeviceState *dev) +{ + CPUSlot *slot = container_of(listener, CPUSlot, listener); + CPUTopoState *topo; + + if (!object_dynamic_cast(OBJECT(dev), TYPE_CPU_TOPO)) { + return; + } + + topo = CPU_TOPO(dev); + cpu_slot_add_topo_info(slot, topo); +} + +static void cpu_slot_del_topo_info(CPUSlot *slot, CPUTopoState *topo) +{ + CpuTopologyLevel level = GET_CPU_TOPO_LEVEL(topo); + CPUTopoStatEntry *entry; + + entry = &slot->stat.entries[level]; + entry->total_instances--; + + return; +} + +static void cpu_slot_device_unrealize(DeviceListener *listener, + DeviceState *dev) +{ + CPUSlot *slot = container_of(listener, CPUSlot, listener); + CPUTopoState *topo; + + if (!object_dynamic_cast(OBJECT(dev), TYPE_CPU_TOPO)) { + return; + } + + topo = CPU_TOPO(dev); + cpu_slot_del_topo_info(slot, topo); +} + +DeviceListener cpu_slot_device_listener = { + .realize = cpu_slot_device_realize, + .unrealize = cpu_slot_device_unrealize, +}; + +static bool slot_bus_check_topology(CPUBusState *cbus, + CPUTopoState *topo, + Error **errp) +{ + CPUSlot *slot = CPU_SLOT(BUS(cbus)->parent); + CpuTopologyLevel level = GET_CPU_TOPO_LEVEL(topo); + + if (!test_bit(level, slot->supported_levels)) { + error_setg(errp, "cpu topo: level %s is not supported", + CpuTopologyLevel_str(level)); + return false; + } + return true; +} + +static void cpu_slot_realize(DeviceState *dev, Error **errp) +{ + CPUSlot *slot = CPU_SLOT(dev); + + slot->listener = cpu_slot_device_listener; + device_listener_register(&slot->listener); + + qbus_init(&slot->bus, sizeof(CPUBusState), + TYPE_CPU_BUS, dev, "cpu-slot"); + slot->bus.check_topology = slot_bus_check_topology; +} + +static void cpu_slot_unrealize(DeviceState *dev) +{ + CPUSlot *slot = CPU_SLOT(dev); + + device_listener_unregister(&slot->listener); +} + +static void cpu_slot_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + + set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); + dc->realize = cpu_slot_realize; + dc->unrealize = cpu_slot_unrealize; +} + +static const TypeInfo cpu_slot_type_info = { + .name = TYPE_CPU_SLOT, + .parent = TYPE_SYS_BUS_DEVICE, + .class_init = cpu_slot_class_init, + .instance_size = sizeof(CPUSlot), +}; + +static void cpu_slot_register_types(void) +{ + type_register_static(&cpu_slot_type_info); +} + +type_init(cpu_slot_register_types) diff --git a/hw/cpu/meson.build b/hw/cpu/meson.build index 6c6546646608..358e2b3960fa 100644 --- a/hw/cpu/meson.build +++ b/hw/cpu/meson.build @@ -1,6 +1,7 @@ common_ss.add(files('cpu-topology.c')) system_ss.add(files('core.c')) +system_ss.add(files('cpu-slot.c')) system_ss.add(when: 'CONFIG_CPU_CLUSTER', if_true: files('cluster.c')) system_ss.add(when: 'CONFIG_ARM11MPCORE', if_true: files('arm11mpcore.c')) diff --git a/include/hw/cpu/cpu-slot.h b/include/hw/cpu/cpu-slot.h new file mode 100644 index 000000000000..9d02d5de578e --- /dev/null +++ b/include/hw/cpu/cpu-slot.h @@ -0,0 +1,72 @@ +/* + * CPU slot abstraction header + * + * Copyright (C) 2024 Intel Corporation. + * + * Author: Zhao Liu + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + */ + +#ifndef CPU_SLOT_H +#define CPU_SLOT_H + +#include "hw/cpu/cpu-topology.h" +#include "hw/qdev-core.h" +#include "hw/sysbus.h" +#include "qapi/qapi-types-machine-common.h" +#include "qom/object.h" + +/** + * CPUTopoStatEntry: + * @total_instances: Total number of topological instances at the same level + * that are currently inserted in CPU slot + * @max_instances: Maximum number of topological instances at the same level + * under the parent topological container + */ +typedef struct CPUTopoStatEntry { + int total_instances; + int max_instances; +} CPUTopoStatEntry; + +/** + * CPUTopoStat: + * @entries: Detail count information for valid topology levels under + * CPU slot + * @curr_levels: Current CPU topology levels inserted in CPU slot + */ +typedef struct CPUTopoStat { + /* TODO: Exclude invalid and default levels. */ + CPUTopoStatEntry entries[CPU_TOPOLOGY_LEVEL__MAX]; + DECLARE_BITMAP(curr_levels, CPU_TOPOLOGY_LEVEL__MAX); +} CPUTopoStat; + +#define TYPE_CPU_SLOT "cpu-slot" +OBJECT_DECLARE_SIMPLE_TYPE(CPUSlot, CPU_SLOT) + +/** + * CPUSlot: + * @cores: Queue consisting of all the cores in the topology tree + * where the cpu-slot is the root. cpu-slot can maintain similar + * queues for other topology levels to facilitate traversal + * when necessary. + * @stat: Topological statistics for topology tree. + * @bus: CPU bus to add the children topology device. + * @supported_levels: Supported topology levels for topology tree. + * @listener: Hooks to listen realize() and unrealize() of topology + * device. + */ +struct CPUSlot { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + CPUBusState bus; + CPUTopoStat stat; + DECLARE_BITMAP(supported_levels, CPU_TOPOLOGY_LEVEL__MAX); + + DeviceListener listener; +}; + +#endif /* CPU_SLOT_H */ From patchwork Thu Sep 19 01:55:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhao Liu X-Patchwork-Id: 13807290 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8961E1CFB9 for ; Thu, 19 Sep 2024 01:40:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710020; cv=none; b=UcQ8EruAK+1EpOgn5OJhfJQuz2f+ZQRycGfGfXIuE0jjXThq8+mLj5ut1qt651DFTeOBc5OfQ7D04c6cLzFWw8nLwxeMbIcNsnaSbt7e+uIZjvlNEbXOnw4NzC3byEKyGflv60lWisOa259r2lRaP0XPcsu6fdHGflJ0KFsTUJg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710020; c=relaxed/simple; bh=573w2DHmYSHZ5HLG8xM/Ws3MSekemg/qhlyIWizCQb0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=fO6KD1sevXk5Dx5eZqloEgvoSAm1buAH3TpNVyk4VcwkjiOUUKxZsvA3ik1g5EdgO4thhNtS+VXH/HVUE/HVfL7Ou0vm8Q5+HT8jgf3CqzpxQGJAm6mvWxQeAmNFGpXwybyCUUYyeazXeILsAGk55KpWK2kQHaVyK3ulF53YgxM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=JDegS0+7; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="JDegS0+7" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1726710019; x=1758246019; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=573w2DHmYSHZ5HLG8xM/Ws3MSekemg/qhlyIWizCQb0=; b=JDegS0+7UCsU9NHVN4M8SUUHyj+msUWItm/edgEpeXk/4+MohMt6QT+7 dfZ8WdWCR/C5p2Eu1hmdpNvsHIV6iai4ucoDAZuF86C8+YTVh5gg8lLEY 0uxZ0uWqm4CbVqwyvjCFjVpI/RHtG/S6UvDLfswprRen2/+FBWHG7xGKv iQv3/x83YigDMZT6j02d1dI/ZrOVgibuP70VG4ukmpzi0MJoTG2X2qu0q eBgPUYvVyjX/NuOKdPbJI68ZKkuur5f2Apcx8dDH6FjT6V3F+2QUeJPEr SgYOY9NE10YIx51FbXQdQ5s242TY9M4pe9WQZSZp0WDOOWonDD7TcIHfU g==; X-CSE-ConnectionGUID: exJMhU+PSX6Ze/6LdDX9Fw== X-CSE-MsgGUID: sZFo4IaZS0O5WfibxJQmBg== X-IronPort-AV: E=McAfee;i="6700,10204,11199"; a="25797867" X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="25797867" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2024 18:40:18 -0700 X-CSE-ConnectionGUID: VTAf9j9wSdmPPMQUWsdetg== X-CSE-MsgGUID: O69kmvrZS0GmljFMm/GWdA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="70058690" Received: from liuzhao-optiplex-7080.sh.intel.com ([10.239.160.36]) by orviesa006.jf.intel.com with ESMTP; 18 Sep 2024 18:40:12 -0700 From: Zhao Liu To: =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , Igor Mammedov , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , "Michael S . Tsirkin" , Paolo Bonzini , Richard Henderson , =?utf-8?q?C=C3=A9dric_Le_?= =?utf-8?q?Goater?= , Nicholas Piggin , =?utf-8?b?RnLDqWTDqXJpYyBCYXJyYXQ=?= , Daniel Henrique Barboza , David Gibson , Harsh Prateek Bora , Markus Armbruster , Marcelo Tosatti , =?utf-8?q?Alex_Benn=C3=A9e?= , Peter Maydell Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, qemu-ppc@nongnu.org, qemu-arm@nongnu.org, Zhenyu Wang , Dapeng Mi , Yongwei Ma , Zhao Liu Subject: [RFC v2 05/15] qdev: Add method in BusClass to customize device index Date: Thu, 19 Sep 2024 09:55:23 +0800 Message-Id: <20240919015533.766754-6-zhao1.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240919015533.766754-1-zhao1.liu@intel.com> References: <20240919015533.766754-1-zhao1.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Currently, when the bus assigns an index to a child device, it relies on a monotonically increasing max_index. However, when a device is removed from the bus, its index is not reassigned to new devices, leading to "holes" in child indices. For topology devices, such as CPUs/cores, arches define custom sub-topology IDs. Some of these IDs are global (e.g., core-id for core devices), while others are local (e.g., thread-id/core-id/module-id for x86 CPUs). Local IDs are indexes under the same parent device and align with BusChild's index meaning. Therefore, local IDs in a topology context should use BusChild.index. Considering that topology devices support hot-plug and local IDs often have range constraints, add a new method (BusClass.assign_free_index) to allow the bus to customize index assignment. Based on this method, the CPU bus will search for free index "holes" created by unplugging and assign these free indices to newly inserted devices. Signed-off-by: Zhao Liu --- hw/core/qdev.c | 8 +++++++- hw/cpu/cpu-topology.c | 37 +++++++++++++++++++++++++++++++++++ include/hw/cpu/cpu-topology.h | 1 + include/hw/qdev-core.h | 2 ++ 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index ff073cbff56d..e3e9f0f303d6 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -78,11 +78,17 @@ static void bus_remove_child(BusState *bus, DeviceState *child) static void bus_add_child(BusState *bus, DeviceState *child) { + BusClass *bc = BUS_GET_CLASS(bus); char name[32]; BusChild *kid = g_malloc0(sizeof(*kid)); + if (bc->assign_free_index) { + kid->index = bc->assign_free_index(bus); + } else { + kid->index = bus->max_index++; + } + bus->num_children++; - kid->index = bus->max_index++; kid->child = child; child->bus_node = kid; object_ref(OBJECT(kid->child)); diff --git a/hw/cpu/cpu-topology.c b/hw/cpu/cpu-topology.c index e68c06132e7d..3e8982ff7e6c 100644 --- a/hw/cpu/cpu-topology.c +++ b/hw/cpu/cpu-topology.c @@ -49,11 +49,40 @@ static bool cpu_bus_check_address(BusState *bus, DeviceState *dev, return cpu_parent_check_topology(bus->parent, dev, errp); } +static int cpu_bus_assign_free_index(BusState *bus) +{ + BusChild *kid; + int index; + + if (bus->num_children == bus->max_index) { + return bus->max_index++; + } + + assert(bus->num_children < bus->max_index); + /* TODO: Introduce the list sorted by index */ + for (index = 0; index < bus->num_children; index++) { + bool existed = false; + + QTAILQ_FOREACH(kid, &bus->children, sibling) { + if (kid->index == index) { + existed = true; + break; + } + } + + if (!existed) { + break; + } + } + return index; +} + static void cpu_bus_class_init(ObjectClass *oc, void *data) { BusClass *bc = BUS_CLASS(oc); bc->check_address = cpu_bus_check_address; + bc->assign_free_index = cpu_bus_assign_free_index; } static const TypeInfo cpu_bus_type_info = { @@ -177,3 +206,11 @@ int cpu_topo_get_instances_num(CPUTopoState *topo) return bus ? bus->num_children : 1; } + +int cpu_topo_get_index(CPUTopoState *topo) +{ + BusChild *node = DEVICE(topo)->bus_node; + + assert(node); + return node->index; +} diff --git a/include/hw/cpu/cpu-topology.h b/include/hw/cpu/cpu-topology.h index 7a447ad16ee7..80aeff18baa3 100644 --- a/include/hw/cpu/cpu-topology.h +++ b/include/hw/cpu/cpu-topology.h @@ -64,5 +64,6 @@ struct CPUTopoState { #define GET_CPU_TOPO_LEVEL(topo) (CPU_TOPO_GET_CLASS(topo)->level) int cpu_topo_get_instances_num(CPUTopoState *topo); +int cpu_topo_get_index(CPUTopoState *topo); #endif /* CPU_TOPO_H */ diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 7cbc5fb97298..77223b28c788 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -342,6 +342,8 @@ struct BusClass { */ bool (*check_address)(BusState *bus, DeviceState *dev, Error **errp); + int (*assign_free_index)(BusState *bus); + BusRealize realize; BusUnrealize unrealize; From patchwork Thu Sep 19 01:55:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhao Liu X-Patchwork-Id: 13807291 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4DD4B1CFB9 for ; Thu, 19 Sep 2024 01:40:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710026; cv=none; b=AfD8GZmBturgFEeiKhgs1ZNbJUg98vxUf7shdq4sINlTn4+DU2MZBFHKXgcni6S/B9Zyfit+jbM4RwzR/+skkpFhevyBeJHsk+8cstpNy4HfOjkwpVg6KwD+4R6mGUk4dup5FKj5uXzLbMjPz/CdbnC/5WYVuIXqn4QnC/RA+Rg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710026; c=relaxed/simple; bh=+kEYgTEqzxM7Ze52eMLk4clqkl8mXjIJEkgs/jlv98A=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=mT7acOUkPKCAJfuB7gKuWZ8farvopNEFJ0Q1MrgXWJK7rrkL38CnGWTO43vtjTB5n6iLyHhDI64vpPmRLNdIbUN6NXjjjtJu/3VsFowQWUOSdjkVKP6gPZ/ZYzgwpdMWSgmWvizCyx21T2D5yq/B3uuF1Dx9jxT/yjmRt8VXBds= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=PUwFbrQW; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="PUwFbrQW" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1726710025; x=1758246025; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=+kEYgTEqzxM7Ze52eMLk4clqkl8mXjIJEkgs/jlv98A=; b=PUwFbrQWt/7ErKYUG/2LZ0ar++JWc4NkUm0Iv8trfaLo2jgxRv9rBZIP TXm/3oO5TMUaSv4h1RPGeQP66gGvzHS6TGaYLJ7yBDNpvXh9SLqBh5LNv iSXkQ0g5+2qaSUcKeraSIVYXcdgW6Ev0/gNXXwvVZXJjqxU/r+gEfBbQ/ CKgdWTdgGt+YREX08MdERhj4VeWuJxViaN5FBrdkWTJeeEJDdBxP5Hrmy UHfjUChfeFWl6KbhTToOZ8nFZJjiGX94Tav1yxCuyTbSAUe2juhnpAfn4 0GJ7EIb7umaW4IVJ8FKz3Dggirn/V9MzsE7O+e4C0rjHrW+TPKycAa+U2 Q==; X-CSE-ConnectionGUID: Lh9NtVtDRnKFW16vdvZ45g== X-CSE-MsgGUID: RDgH4FfARCqbBMK/UQoP+Q== X-IronPort-AV: E=McAfee;i="6700,10204,11199"; a="25797883" X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="25797883" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2024 18:40:25 -0700 X-CSE-ConnectionGUID: /WO5kkQtTAmAANN0ooMDVw== X-CSE-MsgGUID: Z1ZnLU9xQpuscAGPUNlugQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="70058743" Received: from liuzhao-optiplex-7080.sh.intel.com ([10.239.160.36]) by orviesa006.jf.intel.com with ESMTP; 18 Sep 2024 18:40:19 -0700 From: Zhao Liu To: =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , Igor Mammedov , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , "Michael S . Tsirkin" , Paolo Bonzini , Richard Henderson , =?utf-8?q?C=C3=A9dric_Le_?= =?utf-8?q?Goater?= , Nicholas Piggin , =?utf-8?b?RnLDqWTDqXJpYyBCYXJyYXQ=?= , Daniel Henrique Barboza , David Gibson , Harsh Prateek Bora , Markus Armbruster , Marcelo Tosatti , =?utf-8?q?Alex_Benn=C3=A9e?= , Peter Maydell Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, qemu-ppc@nongnu.org, qemu-arm@nongnu.org, Zhenyu Wang , Dapeng Mi , Yongwei Ma , Zhao Liu Subject: [RFC v2 06/15] hw/core: Create CPU slot in MachineState to manage CPU topology tree Date: Thu, 19 Sep 2024 09:55:24 +0800 Message-Id: <20240919015533.766754-7-zhao1.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240919015533.766754-1-zhao1.liu@intel.com> References: <20240919015533.766754-1-zhao1.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 With CPU slot support, the machine can manage the CPU topology tree. To enable hot-plug support for topology devices, use the machine as the hotplug handler for the CPU bus. Additionally, since not all machines support the topology tree from the start, add a "topo_tree_supported" flag to indicate whether a machine supports the topology tree. And create the CPU slot as the topology root only for machines that support it. Signed-off-by: Zhao Liu --- hw/core/machine.c | 2 ++ hw/cpu/cpu-slot.c | 34 ++++++++++++++++++++++++++++++++++ include/hw/boards.h | 9 +++++++++ include/hw/cpu/cpu-slot.h | 2 ++ system/vl.c | 4 ++++ 5 files changed, 51 insertions(+) diff --git a/hw/core/machine.c b/hw/core/machine.c index 518beb9f883a..b6258d95b1e8 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -1239,6 +1239,8 @@ static void machine_initfn(Object *obj) ms->smp_cache.props[i].topology = CPU_TOPOLOGY_LEVEL_DEFAULT; } + ms->topo = NULL; + machine_copy_boot_config(ms, &(BootConfiguration){ 0 }); } diff --git a/hw/cpu/cpu-slot.c b/hw/cpu/cpu-slot.c index 66ef8d9faa97..4dbd5b7b7e00 100644 --- a/hw/cpu/cpu-slot.c +++ b/hw/cpu/cpu-slot.c @@ -138,3 +138,37 @@ static void cpu_slot_register_types(void) } type_init(cpu_slot_register_types) + +void machine_plug_cpu_slot(MachineState *ms) +{ + MachineClass *mc = MACHINE_GET_CLASS(ms); + CPUSlot *slot; + + slot = CPU_SLOT(qdev_new(TYPE_CPU_SLOT)); + set_bit(CPU_TOPOLOGY_LEVEL_THREAD, slot->supported_levels); + set_bit(CPU_TOPOLOGY_LEVEL_CORE, slot->supported_levels); + set_bit(CPU_TOPOLOGY_LEVEL_SOCKET, slot->supported_levels); + + /* + * Now just consider the levels that x86 supports. + * TODO: Supports other levels. + */ + if (mc->smp_props.modules_supported) { + set_bit(CPU_TOPOLOGY_LEVEL_MODULE, slot->supported_levels); + } + + if (mc->smp_props.dies_supported) { + set_bit(CPU_TOPOLOGY_LEVEL_DIE, slot->supported_levels); + } + + ms->topo = slot; + object_property_add_child(container_get(OBJECT(ms), "/peripheral"), + "cpu-slot", OBJECT(ms->topo)); + DEVICE(ms->topo)->id = g_strdup_printf("%s", "cpu-slot"); + + sysbus_realize(SYS_BUS_DEVICE(slot), &error_abort); + + if (mc->get_hotplug_handler) { + qbus_set_hotplug_handler(BUS(&slot->bus), OBJECT(ms)); + } +} diff --git a/include/hw/boards.h b/include/hw/boards.h index 2dd8decf640a..eeb4e7e2ce9f 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -10,6 +10,7 @@ #include "qemu/module.h" #include "qom/object.h" #include "hw/core/cpu.h" +#include "hw/cpu/cpu-slot.h" #define TYPE_MACHINE_SUFFIX "-machine" @@ -152,6 +153,8 @@ typedef struct { * @modules_supported - whether modules are supported by the machine * @cache_supported - whether cache topologies (l1d, l1i, l2 and l3) are * supported by the machine + * @topo_tree_supported - whether QOM topology tree is supported by the + * machine */ typedef struct { bool prefer_sockets; @@ -162,6 +165,7 @@ typedef struct { bool drawers_supported; bool modules_supported; bool cache_supported[CACHE_LEVEL_AND_TYPE__MAX]; + bool topo_tree_supported; } SMPCompatProps; /** @@ -431,6 +435,11 @@ struct MachineState { CPUArchIdList *possible_cpus; CpuTopology smp; SmpCache smp_cache; + /* + * TODO: get rid of "smp" and merge it into "topo" when all arches + * support QOM topology. + */ + CPUSlot *topo; struct NVDIMMState *nvdimms_state; struct NumaState *numa_state; }; diff --git a/include/hw/cpu/cpu-slot.h b/include/hw/cpu/cpu-slot.h index 9d02d5de578e..24e122013bf7 100644 --- a/include/hw/cpu/cpu-slot.h +++ b/include/hw/cpu/cpu-slot.h @@ -69,4 +69,6 @@ struct CPUSlot { DeviceListener listener; }; +void machine_plug_cpu_slot(MachineState *ms); + #endif /* CPU_SLOT_H */ diff --git a/system/vl.c b/system/vl.c index fe547ca47c27..193e7049ccbe 100644 --- a/system/vl.c +++ b/system/vl.c @@ -2151,6 +2151,10 @@ static void qemu_create_machine(QDict *qdict) false, &error_abort); qobject_unref(default_opts); } + + if (machine_class->smp_props.topo_tree_supported) { + machine_plug_cpu_slot(current_machine); + } } static int global_init_func(void *opaque, QemuOpts *opts, Error **errp) From patchwork Thu Sep 19 01:55:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhao Liu X-Patchwork-Id: 13807292 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7EC1F1DA23 for ; Thu, 19 Sep 2024 01:40:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710034; cv=none; b=HRTHWUlvY1gd+fd+rgdRRjQOWddlljHHPLPBjrTIfuEQmLw7EDz2pP8Qdc1XxjOkkuoqW7lGhrSIVPEH4NxbkBxN1acxagUGQ3huTA5QIddjIzTzRuFkik6tLfz12jL6Qlqu3ghM77uDDf2VQA2MQkoSOrUmkI590U0X9kiUlvc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710034; c=relaxed/simple; bh=GsWICJ5+g1+q1v0KglBy1lWu3UY61FHqayyy9q2Rqsk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Ku9dhIHEmEWcxTCYhDKEoQ+q60sDLcdOOAvxiOJEJOHGUbxFS88Y79UUft2d5wJ+dFc0/2VWdg7WuJtwV0WZxIYVhxbf0k8JUjk/XelP4YY8tU1ZAlhQT34jHD18ZuT3qp5SNpJ9+/sSW03l3DiRJpe7I6enZP4iAXNmc5Q6mH8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=jAyV+GEl; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="jAyV+GEl" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1726710033; x=1758246033; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=GsWICJ5+g1+q1v0KglBy1lWu3UY61FHqayyy9q2Rqsk=; b=jAyV+GElpZchTCz5wRtKmy0OsD6ubtEHOR0nP0GcrejOhlUHCC/OUfM0 CZg/cST3+j6OdHF1YrXUVKuy+j/vE9N+G/BExbyxK9fisknKYGP1q6vAW z70BVpyR6jUyqMXdWBZR/gVZ5i0PzWdoo9QMbEKpLiKKRq4OicbxvQMYn oNwXnSlO7enMB6VLNccMmYPc0Lk0Jc11MzRBluxgBmN7ZoMRsw6kl1/P4 26QkN4CJUDPvZmj0wwrxFVZztyAM93VwDPl4JbxclWuiF6VtDJLVxLnvW quNxjU66fW9RgajXxB4Q2jCbRP69o5TqnGDKghjJCbeSgxaGy7WYo/CNk w==; X-CSE-ConnectionGUID: lEXTSLawTsmE7FAULLQl3Q== X-CSE-MsgGUID: 8rjsVyd5SQqKzmrrflzZrQ== X-IronPort-AV: E=McAfee;i="6700,10204,11199"; a="25797905" X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="25797905" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2024 18:40:32 -0700 X-CSE-ConnectionGUID: BVbtC0uyT5+cD6+BxlQqYA== X-CSE-MsgGUID: ZRQq89eASbGRoUgWB8SFRw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="70058791" Received: from liuzhao-optiplex-7080.sh.intel.com ([10.239.160.36]) by orviesa006.jf.intel.com with ESMTP; 18 Sep 2024 18:40:25 -0700 From: Zhao Liu To: =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , Igor Mammedov , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , "Michael S . Tsirkin" , Paolo Bonzini , Richard Henderson , =?utf-8?q?C=C3=A9dric_Le_?= =?utf-8?q?Goater?= , Nicholas Piggin , =?utf-8?b?RnLDqWTDqXJpYyBCYXJyYXQ=?= , Daniel Henrique Barboza , David Gibson , Harsh Prateek Bora , Markus Armbruster , Marcelo Tosatti , =?utf-8?q?Alex_Benn=C3=A9e?= , Peter Maydell Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, qemu-ppc@nongnu.org, qemu-arm@nongnu.org, Zhenyu Wang , Dapeng Mi , Yongwei Ma , Zhao Liu Subject: [RFC v2 07/15] hw/core/cpu: Convert CPU from general device to topology device Date: Thu, 19 Sep 2024 09:55:25 +0800 Message-Id: <20240919015533.766754-8-zhao1.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240919015533.766754-1-zhao1.liu@intel.com> References: <20240919015533.766754-1-zhao1.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Convert CPU to topology device then it can be added into topology tree. Because CPU then inherits properties and settings of topology device, make the following changes to take into account the special case for CPU: * Omit setting category since topology device has already set. * Make realize() of topology device as the parent realize(). * Clean up some cases that assume parent obj is DeviceState and access parent_obj directly. * Set CPU's topology level as thread. * And one complex change: mask bus_type as NULL. - This is because for the arches don't support topology tree, there's no CPU bus bridge so that CPUs of these arches can't be created. So, only the CPU with arch supporting topology tree should override the bus_type field. * Further, support cpu_create() for the CPU with bus_type. - This is a corner case, some arch CPUs may set bus_type, and cpu_create() would be called in system emulation case (e.g., none machine). To handle such case, try to find the machine's CPU bus in cpu_create(). Signed-off-by: Zhao Liu --- accel/kvm/kvm-all.c | 4 ++-- hw/core/cpu-common.c | 42 +++++++++++++++++++++++++++++++++++++----- include/hw/core/cpu.h | 7 +++++-- target/ppc/kvm.c | 2 +- 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index beb1988d12cf..48c040f6861d 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -4173,7 +4173,7 @@ static void query_stats(StatsResultList **result, StatsTarget target, break; case STATS_TARGET_VCPU: add_stats_entry(result, STATS_PROVIDER_KVM, - cpu->parent_obj.canonical_path, + DEVICE(cpu)->canonical_path, stats_list); break; default: @@ -4265,7 +4265,7 @@ static void query_stats_cb(StatsResultList **result, StatsTarget target, stats_args.names = names; stats_args.errp = errp; CPU_FOREACH(cpu) { - if (!apply_str_list_filter(cpu->parent_obj.canonical_path, targets)) { + if (!apply_str_list_filter(DEVICE(cpu)->canonical_path, targets)) { continue; } query_stats_vcpu(cpu, &stats_args); diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c index 7982ecd39a53..08f2d536ff6d 100644 --- a/hw/core/cpu-common.c +++ b/hw/core/cpu-common.c @@ -57,7 +57,19 @@ CPUState *cpu_create(const char *typename) { Error *err = NULL; CPUState *cpu = CPU(object_new(typename)); - if (!qdev_realize(DEVICE(cpu), NULL, &err)) { + BusState *bus = NULL; + + if (DEVICE_GET_CLASS(cpu)->bus_type) { + MachineState *ms; + + ms = (MachineState *)object_dynamic_cast(qdev_get_machine(), + TYPE_MACHINE); + if (ms) { + bus = BUS(&ms->topo->bus); + } + } + + if (!qdev_realize(DEVICE(cpu), bus, &err)) { error_report_err(err); object_unref(OBJECT(cpu)); exit(EXIT_FAILURE); @@ -196,6 +208,12 @@ static void cpu_common_realizefn(DeviceState *dev, Error **errp) { CPUState *cpu = CPU(dev); Object *machine = qdev_get_machine(); + CPUClass *cc = CPU_GET_CLASS(cpu); + + cc->parent_realize(dev, errp); + if (*errp) { + return; + } /* qdev_get_machine() can return something that's not TYPE_MACHINE * if this is one of the user-only emulators; in that case there's @@ -302,6 +320,7 @@ static void cpu_common_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); + CPUTopoClass *tc = CPU_TOPO_CLASS(klass); CPUClass *k = CPU_CLASS(klass); k->parse_features = cpu_common_parse_features; @@ -309,9 +328,6 @@ static void cpu_common_class_init(ObjectClass *klass, void *data) k->has_work = cpu_common_has_work; k->gdb_read_register = cpu_common_gdb_read_register; k->gdb_write_register = cpu_common_gdb_write_register; - set_bit(DEVICE_CATEGORY_CPU, dc->categories); - dc->realize = cpu_common_realizefn; - dc->unrealize = cpu_common_unrealizefn; rc->phases.hold = cpu_common_reset_hold; cpu_class_init_props(dc); /* @@ -319,11 +335,27 @@ static void cpu_common_class_init(ObjectClass *klass, void *data) * IRQs, adding reset handlers, halting non-first CPUs, ... */ dc->user_creatable = false; + /* + * CPU is the minimum granularity for hotplug in most case, and + * often its hotplug handler is ultimately decided by the machine. + * For generality, set this flag to avoid blocking possible hotplug + * support. + */ + dc->hotpluggable = true; + device_class_set_parent_realize(dc, cpu_common_realizefn, + &k->parent_realize); + dc->unrealize = cpu_common_unrealizefn; + /* + * Avoid archs that do not support topology device trees from + * encountering error when creating CPUs. + */ + dc->bus_type = NULL; + tc->level = CPU_TOPOLOGY_LEVEL_THREAD; } static const TypeInfo cpu_type_info = { .name = TYPE_CPU, - .parent = TYPE_DEVICE, + .parent = TYPE_CPU_TOPO, .instance_size = sizeof(CPUState), .instance_init = cpu_common_initfn, .instance_finalize = cpu_common_finalize, diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index 1c9c775df658..d7268bcb48cb 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -20,6 +20,7 @@ #ifndef QEMU_CPU_H #define QEMU_CPU_H +#include "hw/cpu/cpu-topology.h" #include "hw/qdev-core.h" #include "disas/dis-asm.h" #include "exec/breakpoint.h" @@ -144,7 +145,7 @@ struct SysemuCPUOps; */ struct CPUClass { /*< private >*/ - DeviceClass parent_class; + CPUTopoClass parent_class; /*< public >*/ ObjectClass *(*class_by_name)(const char *cpu_model); @@ -189,6 +190,8 @@ struct CPUClass { int reset_dump_flags; int gdb_num_core_regs; bool gdb_stop_before_watchpoint; + + DeviceRealize parent_realize; }; /* @@ -456,7 +459,7 @@ struct qemu_work_item; */ struct CPUState { /*< private >*/ - DeviceState parent_obj; + CPUTopoState parent_obj; /* cache to avoid expensive CPU_GET_CLASS */ CPUClass *cc; /*< public >*/ diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 907dba60d1b5..b3cc42e545af 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -2351,7 +2351,7 @@ static void alter_insns(uint64_t *word, uint64_t flags, bool on) static bool kvmppc_cpu_realize(CPUState *cs, Error **errp) { int ret; - const char *vcpu_str = (cs->parent_obj.hotplugged == true) ? + const char *vcpu_str = (DEVICE(cs)->hotplugged == true) ? "hotplug" : "create"; cs->cpu_index = cpu_get_free_index(); From patchwork Thu Sep 19 01:55:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhao Liu X-Patchwork-Id: 13807293 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 997751CFBE for ; Thu, 19 Sep 2024 01:40:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710040; cv=none; b=BL2Q+Bmr9jG89LNVQjy/DfGHOrkig9/3Ho14V8pFyIZwFR7UgVqp/JUSnQ9DVoDpQ9PWk+rj5EHy5DkNH7FkAQpjIW3iWoyGW1J16KQWLugch+RxmZa++fq9QeTKlXiX5e3SW/OABZwx8RKncPzYManbG/BJxOYPqwbfXErOJtc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710040; c=relaxed/simple; bh=l1vQdeQ4queUGmdOva+Swsyp/QTxpMCGhTY2FBOIVyU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=tiTMao5O3agXkxY4JUardmmMnqewEha9r2OFIChyRpdvCDM9BdkyVsb62BwflcUjSniQRC8YGMxZi6tm4MFVHWXOK/d8gIVtC6Z3vwAB4/ndMvcfOimfaYjzE79ynUWW4heVKx9rdWRZNgNJC+0lgPtngnPz6EwPZIZl1cL2twc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=ma1un0rI; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="ma1un0rI" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1726710039; x=1758246039; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=l1vQdeQ4queUGmdOva+Swsyp/QTxpMCGhTY2FBOIVyU=; b=ma1un0rITrvAObWhymG8Pmk3+AbdoAFEiy2j7C8Cb5fbT0kIEuUPaIiF Kt1eaT11h8pN6goV+9MslCQjfF7x/PvOnaG27D4Apr2HaiD1qYeY6VPeF oEytiefdMsNEQAiurJRSM7VlvVgOnQwDJDOAMuUWfXKQ6vkfWxd7QgS1L fS+YLXdrflJwmWy6e2tieLIK3CV9utXkSPDjV3PM3LzVXBUXgjetrrMVF MNZMHFyQo9ektVJ21LW5hRt0Bd1Jr5YUjZMiIhmCPcq/gq9w7vlOZVxZC akTm9CvpTTLuUvCACO671cTmY+p8Q+ez2t+0bOYofZb1FHP0A+d9lByls A==; X-CSE-ConnectionGUID: Ru8WMYwzS0KsxvfhVBPaOQ== X-CSE-MsgGUID: KUF7LsvxTFCcBzrI4Kxejw== X-IronPort-AV: E=McAfee;i="6700,10204,11199"; a="25797923" X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="25797923" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2024 18:40:38 -0700 X-CSE-ConnectionGUID: YVSPOQ2tQWuH1my/Tb60Fw== X-CSE-MsgGUID: DeBF+64uSSydM/DHzEmxhw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="70058834" Received: from liuzhao-optiplex-7080.sh.intel.com ([10.239.160.36]) by orviesa006.jf.intel.com with ESMTP; 18 Sep 2024 18:40:32 -0700 From: Zhao Liu To: =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , Igor Mammedov , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , "Michael S . Tsirkin" , Paolo Bonzini , Richard Henderson , =?utf-8?q?C=C3=A9dric_Le_?= =?utf-8?q?Goater?= , Nicholas Piggin , =?utf-8?b?RnLDqWTDqXJpYyBCYXJyYXQ=?= , Daniel Henrique Barboza , David Gibson , Harsh Prateek Bora , Markus Armbruster , Marcelo Tosatti , =?utf-8?q?Alex_Benn=C3=A9e?= , Peter Maydell Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, qemu-ppc@nongnu.org, qemu-arm@nongnu.org, Zhenyu Wang , Dapeng Mi , Yongwei Ma , Zhao Liu Subject: [RFC v2 08/15] hw/cpu/core: Convert cpu-core from general device to topology device Date: Thu, 19 Sep 2024 09:55:26 +0800 Message-Id: <20240919015533.766754-9-zhao1.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240919015533.766754-1-zhao1.liu@intel.com> References: <20240919015533.766754-1-zhao1.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Convert cpu-core to topology device then it can be added into topology tree. At present, only PPC is using cpu-core device. For topology tree, it's necessary to add cpu-core in the tree as one of the topology hierarchies. The generic cpu-core is sufficient to express the core layer in a topology tree without needing to consider any arch-specific feature, so to reduce the support complexity of the topology tree and allow arch to be able to use the abstract cpu-core directly, without further derivation of the arch-specific core, remove the "abstract" restriction from TypeInfo. Because cpu-core then inherits properties and settings of topology device, also make the following changes to take into account the special case for cpu-core: * Omit setting category since topology device has already set. * Make realize() of topology device as the parent realize() for PPC cores. * Set cpu-core's topology level as core. * Mask bus_type for PPC cores as NULL to avoid PPC cores' creation failure since PPC currently doesn't support topology tree. Signed-off-by: Zhao Liu --- hw/cpu/core.c | 9 +++++---- hw/ppc/pnv_core.c | 11 ++++++++++- hw/ppc/spapr_cpu_core.c | 12 +++++++++++- include/hw/cpu/core.h | 3 ++- include/hw/ppc/pnv_core.h | 3 ++- include/hw/ppc/spapr_cpu_core.h | 4 +++- 6 files changed, 33 insertions(+), 9 deletions(-) diff --git a/hw/cpu/core.c b/hw/cpu/core.c index 495a5c30ffe1..bf1cbceea21b 100644 --- a/hw/cpu/core.c +++ b/hw/cpu/core.c @@ -79,19 +79,20 @@ static void cpu_core_instance_init(Object *obj) static void cpu_core_class_init(ObjectClass *oc, void *data) { - DeviceClass *dc = DEVICE_CLASS(oc); + CPUTopoClass *tc = CPU_TOPO_CLASS(oc); - set_bit(DEVICE_CATEGORY_CPU, dc->categories); + /* TODO: Offload "core-id" and "nr-threads" to ppc-specific core. */ object_class_property_add(oc, "core-id", "int", core_prop_get_core_id, core_prop_set_core_id, NULL, NULL); object_class_property_add(oc, "nr-threads", "int", core_prop_get_nr_threads, core_prop_set_nr_threads, NULL, NULL); + + tc->level = CPU_TOPOLOGY_LEVEL_CORE; } static const TypeInfo cpu_core_type_info = { .name = TYPE_CPU_CORE, - .parent = TYPE_DEVICE, - .abstract = true, + .parent = TYPE_CPU_TOPO, .class_init = cpu_core_class_init, .instance_size = sizeof(CPUCore), .instance_init = cpu_core_instance_init, diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index a30693990b25..9be7a4b6c1a9 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -356,6 +356,8 @@ static void pnv_core_realize(DeviceState *dev, Error **errp) assert(pc->chip); + pcc->parent_realize(dev, errp); + pc->threads = g_new(PowerPCCPU *, cc->nr_threads); for (i = 0; i < cc->nr_threads; i++) { PowerPCCPU *cpu; @@ -466,11 +468,18 @@ static void pnv_core_power10_class_init(ObjectClass *oc, void *data) static void pnv_core_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); + PnvCoreClass *pcc = PNV_CORE_CLASS(oc); - dc->realize = pnv_core_realize; dc->unrealize = pnv_core_unrealize; device_class_set_props(dc, pnv_core_properties); dc->user_creatable = false; + device_class_set_parent_realize(dc, pnv_core_realize, + &pcc->parent_realize); + /* + * Avoid ppc that do not support topology device trees from + * encountering error when creating cores. + */ + dc->bus_type = NULL; } #define DEFINE_PNV_CORE_TYPE(family, cpu_model) \ diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index 464224516881..49c440fc0e09 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -338,6 +338,7 @@ static void spapr_cpu_core_realize(DeviceState *dev, Error **errp) (SpaprMachineState *) object_dynamic_cast(qdev_get_machine(), TYPE_SPAPR_MACHINE); SpaprCpuCore *sc = SPAPR_CPU_CORE(OBJECT(dev)); + SpaprCpuCoreClass *scc = SPAPR_CPU_CORE_GET_CLASS(sc); CPUCore *cc = CPU_CORE(OBJECT(dev)); int i; @@ -346,6 +347,8 @@ static void spapr_cpu_core_realize(DeviceState *dev, Error **errp) return; } + scc->parent_realize(dev, errp); + qemu_register_reset(spapr_cpu_core_reset_handler, sc); sc->threads = g_new0(PowerPCCPU *, cc->nr_threads); for (i = 0; i < cc->nr_threads; i++) { @@ -376,11 +379,18 @@ static void spapr_cpu_core_class_init(ObjectClass *oc, void *data) DeviceClass *dc = DEVICE_CLASS(oc); SpaprCpuCoreClass *scc = SPAPR_CPU_CORE_CLASS(oc); - dc->realize = spapr_cpu_core_realize; dc->unrealize = spapr_cpu_core_unrealize; device_class_set_legacy_reset(dc, spapr_cpu_core_reset); device_class_set_props(dc, spapr_cpu_core_properties); + dc->hotpluggable = true; scc->cpu_type = data; + device_class_set_parent_realize(dc, spapr_cpu_core_realize, + &scc->parent_realize); + /* + * Avoid ppc that do not support topology device trees from + * encountering error when creating cores. + */ + dc->bus_type = NULL; } #define DEFINE_SPAPR_CPU_CORE_TYPE(cpu_model) \ diff --git a/include/hw/cpu/core.h b/include/hw/cpu/core.h index 98ab91647eb2..a451dcd2e4d8 100644 --- a/include/hw/cpu/core.h +++ b/include/hw/cpu/core.h @@ -9,6 +9,7 @@ #ifndef HW_CPU_CORE_H #define HW_CPU_CORE_H +#include "hw/cpu/cpu-topology.h" #include "hw/qdev-core.h" #include "qom/object.h" @@ -18,7 +19,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(CPUCore, CPU_CORE) struct CPUCore { /*< private >*/ - DeviceState parent_obj; + CPUTopoState parent_obj; /*< public >*/ int core_id; diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h index d8afb4f95f92..252b98ae20f9 100644 --- a/include/hw/ppc/pnv_core.h +++ b/include/hw/ppc/pnv_core.h @@ -71,10 +71,11 @@ struct PnvCore { }; struct PnvCoreClass { - DeviceClass parent_class; + CPUTopoClass parent_class; const MemoryRegionOps *xscom_ops; uint64_t xscom_size; + DeviceRealize parent_realize; }; #define PNV_CORE_TYPE_SUFFIX "-" TYPE_PNV_CORE diff --git a/include/hw/ppc/spapr_cpu_core.h b/include/hw/ppc/spapr_cpu_core.h index 69a52e39b850..fc6c15747a88 100644 --- a/include/hw/ppc/spapr_cpu_core.h +++ b/include/hw/ppc/spapr_cpu_core.h @@ -32,8 +32,10 @@ struct SpaprCpuCore { }; struct SpaprCpuCoreClass { - DeviceClass parent_class; + CPUTopoClass parent_class; + const char *cpu_type; + DeviceRealize parent_realize; }; const char *spapr_get_cpu_core_type(const char *cpu_type); From patchwork Thu Sep 19 01:55:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhao Liu X-Patchwork-Id: 13807294 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2793B1DFF0 for ; Thu, 19 Sep 2024 01:40:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710046; cv=none; b=oIym8a6K636bnxK6V5nzaSeIWzsQT2dPwN+4EfexYp1OcJhe1K/v74JL/AWKQg+rAER5LntqIjdycThVPAqR3LLIqdoeeCpwDjzN0tNoanQNhTl8QhN5hicQitU69AuWSXTpcMwuylCBJjHVg9QbtRA8LJMMpz6mNNOgYGX/qss= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710046; c=relaxed/simple; bh=4Lv6y5pVsU6DtDjzxhv1VCs53XCauucInvDj9vyaeKw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=I/AUyEKFyRg9T2wBA8fkU8gKtMI7a0dwtBf9RCPv41ygcYTeldo1+Vh9JX/p+dinO6VTJOqFNyN6Jq+e0QLCgktcv8rrnyCtSpwtgo1Miw6Zp8OzUA9fSrNs4zLrDDu9rdzT5EOZiL6n4uSBstHC+MuJdNfQA7h1jA6CXcDKpY8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=flfbCvxm; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="flfbCvxm" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1726710045; x=1758246045; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=4Lv6y5pVsU6DtDjzxhv1VCs53XCauucInvDj9vyaeKw=; b=flfbCvxmoDA1WbA5lhtJA2duvjUtH8bQajRXW9no0Cmv3Mm1M3PgsSBh kHplKt3z1QSuUQRzNLGIJU7ulkcj6R+7pnlgbKjrSPcafjFClBIEgHBvV gqUeFfhniKcVzX7PJhRsWLLjjkuJQPg8iJitOftUp9pHlaxqIUJJ+mpgp rIRAfXaDsZEV71C6n2b0p8tCx9mdlyegkWIR5XjyPlFrb1TtNT4nhrt7q ZQ8U/TqZsfQcllmG9bKBY1fltfTP1FtweZGNfDXv8QSATCRXzhpc2I5P4 J+NtaMMLVdkVCUurDiQuNXeXTDQopF9EKz7rh+9AftKf4emKtcxGeHnQB A==; X-CSE-ConnectionGUID: vrWEOGJnRXqBnL12cr0dYA== X-CSE-MsgGUID: KT3RS1TPRuCMgXu9NzNwyw== X-IronPort-AV: E=McAfee;i="6700,10204,11199"; a="25797984" X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="25797984" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2024 18:40:45 -0700 X-CSE-ConnectionGUID: oRBjSbnIQmSIHRcM58FHEg== X-CSE-MsgGUID: BCnW7jNJTSGl38Hi7C4luQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="70058880" Received: from liuzhao-optiplex-7080.sh.intel.com ([10.239.160.36]) by orviesa006.jf.intel.com with ESMTP; 18 Sep 2024 18:40:39 -0700 From: Zhao Liu To: =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , Igor Mammedov , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , "Michael S . Tsirkin" , Paolo Bonzini , Richard Henderson , =?utf-8?q?C=C3=A9dric_Le_?= =?utf-8?q?Goater?= , Nicholas Piggin , =?utf-8?b?RnLDqWTDqXJpYyBCYXJyYXQ=?= , Daniel Henrique Barboza , David Gibson , Harsh Prateek Bora , Markus Armbruster , Marcelo Tosatti , =?utf-8?q?Alex_Benn=C3=A9e?= , Peter Maydell Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, qemu-ppc@nongnu.org, qemu-arm@nongnu.org, Zhenyu Wang , Dapeng Mi , Yongwei Ma , Zhao Liu Subject: [RFC v2 09/15] hw/cpu: Abstract module/die/socket levels as topology devices Date: Thu, 19 Sep 2024 09:55:27 +0800 Message-Id: <20240919015533.766754-10-zhao1.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240919015533.766754-1-zhao1.liu@intel.com> References: <20240919015533.766754-1-zhao1.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Abstract module/die/socket levels as the cpu-module/cpu-die/cpu-socket topology devices then they can be inserted into topology tree. Signed-off-by: Zhao Liu --- MAINTAINERS | 6 ++++++ hw/cpu/die.c | 34 ++++++++++++++++++++++++++++++++++ hw/cpu/meson.build | 3 +++ hw/cpu/module.c | 34 ++++++++++++++++++++++++++++++++++ hw/cpu/socket.c | 34 ++++++++++++++++++++++++++++++++++ include/hw/cpu/die.h | 29 +++++++++++++++++++++++++++++ include/hw/cpu/module.h | 29 +++++++++++++++++++++++++++++ include/hw/cpu/socket.h | 29 +++++++++++++++++++++++++++++ 8 files changed, 198 insertions(+) create mode 100644 hw/cpu/die.c create mode 100644 hw/cpu/module.c create mode 100644 hw/cpu/socket.c create mode 100644 include/hw/cpu/die.h create mode 100644 include/hw/cpu/module.h create mode 100644 include/hw/cpu/socket.h diff --git a/MAINTAINERS b/MAINTAINERS index 8e5b2cd91dca..03c1a13de074 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1886,6 +1886,9 @@ F: hw/core/numa.c F: hw/cpu/cluster.c F: hw/cpu/cpu-slot.c F: hw/cpu/cpu-topology.c +F: hw/cpu/die.c +F: hw/cpu/module.c +F: hw/cpu/socket.c F: qapi/machine.json F: qapi/machine-common.json F: qapi/machine-target.json @@ -1894,6 +1897,9 @@ F: include/hw/core/cpu.h F: include/hw/cpu/cluster.h F: include/hw/cpu/cpu-slot.h F: include/hw/cpu/cpu-topology.h +F: include/hw/cpu/die.h +F: include/hw/cpu/module.h +F: include/hw/cpu/socket.h F: include/sysemu/numa.h F: tests/functional/test_cpu_queries.py F: tests/functional/test_empty_cpu_model.py diff --git a/hw/cpu/die.c b/hw/cpu/die.c new file mode 100644 index 000000000000..f00907ffd78b --- /dev/null +++ b/hw/cpu/die.c @@ -0,0 +1,34 @@ +/* + * CPU die abstract device + * + * Copyright (C) 2024 Intel Corporation. + * + * Author: Zhao Liu + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "hw/cpu/die.h" + +static void cpu_die_class_init(ObjectClass *oc, void *data) +{ + CPUTopoClass *tc = CPU_TOPO_CLASS(oc); + + tc->level = CPU_TOPOLOGY_LEVEL_DIE; +} + +static const TypeInfo cpu_die_type_info = { + .name = TYPE_CPU_DIE, + .parent = TYPE_CPU_TOPO, + .class_init = cpu_die_class_init, + .instance_size = sizeof(CPUDie), +}; + +static void cpu_die_register_types(void) +{ + type_register_static(&cpu_die_type_info); +} + +type_init(cpu_die_register_types) diff --git a/hw/cpu/meson.build b/hw/cpu/meson.build index 358e2b3960fa..c64eec4460d8 100644 --- a/hw/cpu/meson.build +++ b/hw/cpu/meson.build @@ -3,6 +3,9 @@ common_ss.add(files('cpu-topology.c')) system_ss.add(files('core.c')) system_ss.add(files('cpu-slot.c')) system_ss.add(when: 'CONFIG_CPU_CLUSTER', if_true: files('cluster.c')) +system_ss.add(files('die.c')) +system_ss.add(files('module.c')) +system_ss.add(files('socket.c')) system_ss.add(when: 'CONFIG_ARM11MPCORE', if_true: files('arm11mpcore.c')) system_ss.add(when: 'CONFIG_REALVIEW', if_true: files('realview_mpcore.c')) diff --git a/hw/cpu/module.c b/hw/cpu/module.c new file mode 100644 index 000000000000..b6f50a2ba588 --- /dev/null +++ b/hw/cpu/module.c @@ -0,0 +1,34 @@ +/* + * CPU module abstract device + * + * Copyright (C) 2024 Intel Corporation. + * + * Author: Zhao Liu + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "hw/cpu/module.h" + +static void cpu_module_class_init(ObjectClass *oc, void *data) +{ + CPUTopoClass *tc = CPU_TOPO_CLASS(oc); + + tc->level = CPU_TOPOLOGY_LEVEL_MODULE; +} + +static const TypeInfo cpu_module_type_info = { + .name = TYPE_CPU_MODULE, + .parent = TYPE_CPU_TOPO, + .class_init = cpu_module_class_init, + .instance_size = sizeof(CPUModule), +}; + +static void cpu_module_register_types(void) +{ + type_register_static(&cpu_module_type_info); +} + +type_init(cpu_module_register_types) diff --git a/hw/cpu/socket.c b/hw/cpu/socket.c new file mode 100644 index 000000000000..516e93389e11 --- /dev/null +++ b/hw/cpu/socket.c @@ -0,0 +1,34 @@ +/* + * CPU socket abstract device + * + * Copyright (C) 2024 Intel Corporation. + * + * Author: Zhao Liu + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "hw/cpu/socket.h" + +static void cpu_socket_class_init(ObjectClass *oc, void *data) +{ + CPUTopoClass *tc = CPU_TOPO_CLASS(oc); + + tc->level = CPU_TOPOLOGY_LEVEL_SOCKET; +} + +static const TypeInfo cpu_socket_type_info = { + .name = TYPE_CPU_SOCKET, + .parent = TYPE_CPU_TOPO, + .class_init = cpu_socket_class_init, + .instance_size = sizeof(CPUSocket), +}; + +static void cpu_socket_register_types(void) +{ + type_register_static(&cpu_socket_type_info); +} + +type_init(cpu_socket_register_types) diff --git a/include/hw/cpu/die.h b/include/hw/cpu/die.h new file mode 100644 index 000000000000..682e226ac569 --- /dev/null +++ b/include/hw/cpu/die.h @@ -0,0 +1,29 @@ +/* + * CPU die abstract device + * + * Copyright (C) 2024 Intel Corporation. + * + * Author: Zhao Liu + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + */ + +#ifndef HW_CPU_DIE_H +#define HW_CPU_DIE_H + +#include "hw/cpu/cpu-topology.h" +#include "hw/qdev-core.h" + +#define TYPE_CPU_DIE "cpu-die" + +OBJECT_DECLARE_SIMPLE_TYPE(CPUDie, CPU_DIE) + +struct CPUDie { + /*< private >*/ + CPUTopoState obj; + + /*< public >*/ +}; + +#endif /* HW_CPU_DIE_H */ diff --git a/include/hw/cpu/module.h b/include/hw/cpu/module.h new file mode 100644 index 000000000000..242cd623a3b3 --- /dev/null +++ b/include/hw/cpu/module.h @@ -0,0 +1,29 @@ +/* + * CPU module abstract device + * + * Copyright (C) 2024 Intel Corporation. + * + * Author: Zhao Liu + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + */ + +#ifndef HW_CPU_MODULE_H +#define HW_CPU_MODULE_H + +#include "hw/cpu/cpu-topology.h" +#include "hw/qdev-core.h" + +#define TYPE_CPU_MODULE "cpu-module" + +OBJECT_DECLARE_SIMPLE_TYPE(CPUModule, CPU_MODULE) + +struct CPUModule { + /*< private >*/ + CPUTopoState obj; + + /*< public >*/ +}; + +#endif /* HW_CPU_MODULE_H */ diff --git a/include/hw/cpu/socket.h b/include/hw/cpu/socket.h new file mode 100644 index 000000000000..a25bf8727a22 --- /dev/null +++ b/include/hw/cpu/socket.h @@ -0,0 +1,29 @@ +/* + * CPU socket abstract device + * + * Copyright (C) 2024 Intel Corporation. + * + * Author: Zhao Liu + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + */ + +#ifndef HW_CPU_SOCKET_H +#define HW_CPU_SOCKET_H + +#include "hw/cpu/cpu-topology.h" +#include "hw/qdev-core.h" + +#define TYPE_CPU_SOCKET "cpu-socket" + +OBJECT_DECLARE_SIMPLE_TYPE(CPUSocket, CPU_SOCKET) + +struct CPUSocket { + /*< private >*/ + CPUTopoState parent_obj; + + /*< public >*/ +}; + +#endif /* HW_CPU_SOCKET_H */ From patchwork Thu Sep 19 01:55:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhao Liu X-Patchwork-Id: 13807295 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DA1461CFB9 for ; Thu, 19 Sep 2024 01:40:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710053; cv=none; b=RGAKjJjZHjLs+qwycF4r8wuhlpVjCFcYuoT44NrGw3a5pTzEYSToHaPtCxYh4k+F2O97BpLn9eiCsrLg9KuxSIUARnCb6laDDv5Tgj57xB7CGiOEqso78DQ1OnPJcPbsRhucbNXhQwsEBTpYwB5tAHd2Lfn++SGctMOSaXZ3sNU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710053; c=relaxed/simple; bh=0niF0vf3jvEyp2QjdR6nFcp3M1J547cnSvpKpCorKyw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=phi0fVh0+viF8sAkgn09ijhmHb+CrEEhnkOmVp/ujcPqx+NAV5+dDJl59BjDHYfGanESEdQfIUqA/BWHI8rZ0Wo849hwdZIe2KeY+jeAHK/vdDA9TNQsJxtYbX4G0IjFnYGug6HGLxQJaimbLOH6SGBwmjEpKfgZ/h6ZVwILRuc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=Eaa3asew; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Eaa3asew" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1726710052; x=1758246052; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=0niF0vf3jvEyp2QjdR6nFcp3M1J547cnSvpKpCorKyw=; b=Eaa3asewOD6RSwhJTAnvaC9Q9VR+jPW+TGnsWjU0274ucQcbUvZJ/+DW QITvd4n6VoZoVKXLaD0H8AK79E3UtPffbHZxENWOQykePWJHhAaOQBAXf +9dBYC2mQ1yGz6730i1A2YLGLMI5xxwXManenZrfacgbtS5whhs6Nd/lB lGWsAktlix9WPc1F6bLLJTzdzugktcD1bk/gD4DNGtuVwv8yd45HUevWB dW5yYwydDoAGoQQTyygxxpTOjNuHdq5uu3N/nIvtRPGyNt4+Ft1Ut2jc7 VybUbpzSkoHx1iMVZTJqUkYiqy6LHlR2cOdvCn+fsTsw9be0SR6uhRaC3 g==; X-CSE-ConnectionGUID: c7FnXLBRSxiffe5KmU3jhg== X-CSE-MsgGUID: RBLxqwkZSs25czzyTT0C+g== X-IronPort-AV: E=McAfee;i="6700,10204,11199"; a="25797999" X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="25797999" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2024 18:40:52 -0700 X-CSE-ConnectionGUID: sCN0Ehe4SeiW9m26BTN/FA== X-CSE-MsgGUID: e7DxLiX3SxWuG72VcaXdmQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="70058928" Received: from liuzhao-optiplex-7080.sh.intel.com ([10.239.160.36]) by orviesa006.jf.intel.com with ESMTP; 18 Sep 2024 18:40:45 -0700 From: Zhao Liu To: =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , Igor Mammedov , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , "Michael S . Tsirkin" , Paolo Bonzini , Richard Henderson , =?utf-8?q?C=C3=A9dric_Le_?= =?utf-8?q?Goater?= , Nicholas Piggin , =?utf-8?b?RnLDqWTDqXJpYyBCYXJyYXQ=?= , Daniel Henrique Barboza , David Gibson , Harsh Prateek Bora , Markus Armbruster , Marcelo Tosatti , =?utf-8?q?Alex_Benn=C3=A9e?= , Peter Maydell Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, qemu-ppc@nongnu.org, qemu-arm@nongnu.org, Zhenyu Wang , Dapeng Mi , Yongwei Ma , Zhao Liu Subject: [RFC v2 10/15] hw/machine: Build smp topology tree from -smp Date: Thu, 19 Sep 2024 09:55:28 +0800 Message-Id: <20240919015533.766754-11-zhao1.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240919015533.766754-1-zhao1.liu@intel.com> References: <20240919015533.766754-1-zhao1.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 For architectures supports QOM topology (indicated by the MachineClass. topo_tree_supported field), implement smp QOM topology tree from MachineState.smp. The topology tree is created before MachineClass.init(), where arch will initialize CPUs or cores, corresponding to the MachineState.possible_cpus[]. To avoid conflicts with CPU/core generation in the arch machine, create_smp_topo_children() will only create topology levels which are higher than the granularity of possible_cpus[]. The remaining topology parts will be completed by the arch machine during machine init(). There's a new field, arch_id_topo_level, to indicate the granularity of possible_cpus[]. While this field is set, CPU slot can create the topology tree level by level. Without this field, any topology device will be collect at the CPU bus of the CPU slot and will not be organized into a tree structure. Signed-off-by: Zhao Liu --- hw/core/machine.c | 5 ++ hw/cpu/cpu-slot.c | 153 ++++++++++++++++++++++++++++++++++++++ include/hw/boards.h | 2 + include/hw/cpu/cpu-slot.h | 5 ++ include/qemu/bitops.h | 5 ++ 5 files changed, 170 insertions(+) diff --git a/hw/core/machine.c b/hw/core/machine.c index b6258d95b1e8..076bd365197b 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -1638,6 +1638,11 @@ void machine_run_board_init(MachineState *machine, const char *mem_path, Error * "on", false); } + if (machine_class->smp_props.topo_tree_supported && + !machine_create_topo_tree(machine, errp)) { + return; + } + accel_init_interfaces(ACCEL_GET_CLASS(machine->accelerator)); machine_class->init(machine); phase_advance(PHASE_MACHINE_INITIALIZED); diff --git a/hw/cpu/cpu-slot.c b/hw/cpu/cpu-slot.c index 4dbd5b7b7e00..1cc3b32ed675 100644 --- a/hw/cpu/cpu-slot.c +++ b/hw/cpu/cpu-slot.c @@ -12,8 +12,12 @@ #include "qemu/osdep.h" #include "hw/boards.h" +#include "hw/cpu/core.h" #include "hw/cpu/cpu-slot.h" #include "hw/cpu/cpu-topology.h" +#include "hw/cpu/die.h" +#include "hw/cpu/module.h" +#include "hw/cpu/socket.h" #include "hw/qdev-core.h" #include "hw/qdev-properties.h" #include "hw/sysbus.h" @@ -172,3 +176,152 @@ void machine_plug_cpu_slot(MachineState *ms) qbus_set_hotplug_handler(BUS(&slot->bus), OBJECT(ms)); } } + +static int get_smp_info_by_level(const CpuTopology *smp_info, + CpuTopologyLevel child_level) +{ + switch (child_level) { + case CPU_TOPOLOGY_LEVEL_THREAD: + return smp_info->threads; + case CPU_TOPOLOGY_LEVEL_CORE: + return smp_info->cores; + case CPU_TOPOLOGY_LEVEL_MODULE: + return smp_info->modules; + case CPU_TOPOLOGY_LEVEL_DIE: + return smp_info->dies; + case CPU_TOPOLOGY_LEVEL_SOCKET: + return smp_info->sockets; + default: + /* TODO: Add support for other levels. */ + g_assert_not_reached(); + } + + return 0; +} + +static const char *get_topo_typename_by_level(CpuTopologyLevel level) +{ + switch (level) { + case CPU_TOPOLOGY_LEVEL_CORE: + return TYPE_CPU_CORE; + case CPU_TOPOLOGY_LEVEL_MODULE: + return TYPE_CPU_MODULE; + case CPU_TOPOLOGY_LEVEL_DIE: + return TYPE_CPU_DIE; + case CPU_TOPOLOGY_LEVEL_SOCKET: + return TYPE_CPU_SOCKET; + default: + /* TODO: Add support for other levels. */ + g_assert_not_reached(); + } + + return NULL; +} + +typedef struct SMPBuildCbData { + DECLARE_BITMAP(create_levels, CPU_TOPOLOGY_LEVEL__MAX); + const CpuTopology *smp_info; + CPUTopoStat *stat; + Error **errp; +} SMPBuildCbData; + +static int create_smp_topo_children(DeviceState *dev, void *opaque) +{ + Object *parent = OBJECT(dev); + CpuTopologyLevel child_level; + SMPBuildCbData *cb = opaque; + CPUTopoState *topo = NULL; + BusState *qbus; + CPUBusState *cbus; + Error **errp = cb->errp; + int max_children; + + if (object_dynamic_cast(parent, TYPE_CPU_TOPO)) { + topo = CPU_TOPO(parent); + CpuTopologyLevel parent_level; + + parent_level = GET_CPU_TOPO_LEVEL(topo); + child_level = find_last_bit(cb->create_levels, parent_level); + + if (child_level == parent_level) { + return TOPO_FOREACH_CONTINUE; + } + + cbus = topo->bus; + } else if (object_dynamic_cast(parent, TYPE_CPU_SLOT)) { + child_level = find_last_bit(cb->create_levels, CPU_TOPOLOGY_LEVEL__MAX); + cbus = &CPU_SLOT(parent)->bus; + } else { + return TOPO_FOREACH_ERR; + } + + qbus = BUS(cbus); + max_children = get_smp_info_by_level(cb->smp_info, child_level); + for (int i = 0; i < max_children; i++) { + DeviceState *child; + + child = qdev_new(get_topo_typename_by_level(child_level)); + + /* + * Bus inserts child device at head (QTAILQ_INSERT_HEAD_RCU), This + * could result in the device IDs in the created topology having a + * zig-zag arrangement. + * + * TODO: Remove obstacles preventing the use of QTAILQ_INSERT_HEAD_RCU + * for bus to insert kid device. + */ + child->id = g_strdup_printf("%s[%d]", + CpuTopologyLevel_str(child_level), + cb->stat->entries[child_level].total_instances); + + if (!qdev_realize_and_unref(child, qbus, errp)) { + return TOPO_FOREACH_ERR; + } + } + + return TOPO_FOREACH_CONTINUE; +} + +bool machine_create_topo_tree(MachineState *ms, Error **errp) +{ + MachineClass *mc = MACHINE_GET_CLASS(ms); + CPUSlot *slot = ms->topo; + CpuTopologyLevel level; + SMPBuildCbData cb; + + if (!slot) { + error_setg(errp, "Invalid machine: " + "the cpu-slot of machine is not initialized."); + return false; + } + + /* + * Don't support full topology tree. + * Just use slot to collect topology device. + */ + if (!mc->smp_props.arch_id_topo_level) { + return true; + } + + bitmap_copy(cb.create_levels, slot->supported_levels, + CPU_TOPOLOGY_LEVEL__MAX); + cb.smp_info = &ms->smp; + cb.stat = &slot->stat; + cb.errp = errp; + + /* + * Topology objects at arch_id_topo_level and lower levels will be + * created by MachineClass.possible_cpu_arch_ids(). + */ + FOR_EACH_SET_BIT(level, slot->supported_levels, + mc->smp_props.arch_id_topo_level + 1) { + clear_bit(level, cb.create_levels); + } + + if (qdev_walk_children(DEVICE(slot), create_smp_topo_children, + NULL, NULL, NULL, &cb) < 0) { + return false; + } + + return true; +} diff --git a/include/hw/boards.h b/include/hw/boards.h index eeb4e7e2ce9f..a49677466ef6 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -155,6 +155,7 @@ typedef struct { * supported by the machine * @topo_tree_supported - whether QOM topology tree is supported by the * machine + * @arch_id_topo_level - topology granularity for possible_cpus[] */ typedef struct { bool prefer_sockets; @@ -166,6 +167,7 @@ typedef struct { bool modules_supported; bool cache_supported[CACHE_LEVEL_AND_TYPE__MAX]; bool topo_tree_supported; + CpuTopologyLevel arch_id_topo_level; } SMPCompatProps; /** diff --git a/include/hw/cpu/cpu-slot.h b/include/hw/cpu/cpu-slot.h index 24e122013bf7..1838e8c0c3f9 100644 --- a/include/hw/cpu/cpu-slot.h +++ b/include/hw/cpu/cpu-slot.h @@ -69,6 +69,11 @@ struct CPUSlot { DeviceListener listener; }; +#define TOPO_FOREACH_END 1 +#define TOPO_FOREACH_CONTINUE 0 +#define TOPO_FOREACH_ERR -1 + void machine_plug_cpu_slot(MachineState *ms); +bool machine_create_topo_tree(MachineState *ms, Error **errp); #endif /* CPU_SLOT_H */ diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h index 2c0a2fe7512d..d1c0e52219de 100644 --- a/include/qemu/bitops.h +++ b/include/qemu/bitops.h @@ -631,4 +631,9 @@ static inline uint64_t half_unshuffle64(uint64_t x) return x; } +#define FOR_EACH_SET_BIT(bit, addr, size) \ + for ((bit) = find_first_bit((addr), (size)); \ + (bit) < (size); \ + (bit) = find_next_bit((addr), (size), (bit) + 1)) + #endif From patchwork Thu Sep 19 01:55:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhao Liu X-Patchwork-Id: 13807296 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 26FE512E75 for ; Thu, 19 Sep 2024 01:40:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710059; cv=none; b=D/bPhXOhYTr7qjzlDcQuKzKHmR5fqU4RlDT/BJtON5bFSKo/GBHSLhsAio99Lhq15XWS2nYaMkcmdsnWZtPZw6SIB6ZH6RS2s1P9iERADQPH8tubEPhq94VdbzU1VZtCZx8is/HQe41mc0mu0WrpHMTCsdQGsViEsxkdm8O+vYw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710059; c=relaxed/simple; bh=yof4pkElgDw/rHKl12O9snBHTn5fw7x3AIk3IaZiwVQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=DT4Ac54507VCjtUiyZPBQ/gvIDK/FPJhMuviyRI7cyZcB68nJ9lv4OfASa00cEnyU+M/AqZ5AOq5bqZWqCDHtUpN5Dj7zTTaxCseBAUp1TOMViIbcXb7EYowGfgGKVYDQbpKMlPIkpyC7PIykkalsEv2rVhXb+eyQf16B39QoVk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=QEvkQmzC; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="QEvkQmzC" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1726710058; x=1758246058; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=yof4pkElgDw/rHKl12O9snBHTn5fw7x3AIk3IaZiwVQ=; b=QEvkQmzCSXQLIzMCI3SpJUWWEDgqMufrLdjMfLmMaU7bcjwX3hzLg9sr vPHLSx6UJs2p+qFkjECCuv2R4umaiq9mcHRerye8njJ+Rm+rzSSbOgdA1 NsgF7uzfxXvhJAA7CtUl2JMvtY1amApI9IxzuOiGEE3rJRyK7mbsVVyvZ iScRFqSw8/sY5J3NoWCdMdTTvFwdvHJoS+1NtElevKKlDayXCt4aUG+Bz 93e99Es5/dvl71W8xlDK/av8IjIe1kM2X24Xn1kw+QcVRfnbnz6ayohG0 qGvQ8YLQpc2fMkcW2wywv6pLM5Nulem66F4QRC10mYWFYs7EPKsRls6S2 Q==; X-CSE-ConnectionGUID: VcCBLL2pR+KXHZc0U5c5Xw== X-CSE-MsgGUID: O4npQ0yqQmS4aME34IK0WA== X-IronPort-AV: E=McAfee;i="6700,10204,11199"; a="25798039" X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="25798039" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2024 18:40:58 -0700 X-CSE-ConnectionGUID: nl6/vbvKRUyF+/RLJLKJoA== X-CSE-MsgGUID: zZt2sOthQ+SFZ3bJiPNv0Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="70058946" Received: from liuzhao-optiplex-7080.sh.intel.com ([10.239.160.36]) by orviesa006.jf.intel.com with ESMTP; 18 Sep 2024 18:40:52 -0700 From: Zhao Liu To: =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , Igor Mammedov , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , "Michael S . Tsirkin" , Paolo Bonzini , Richard Henderson , =?utf-8?q?C=C3=A9dric_Le_?= =?utf-8?q?Goater?= , Nicholas Piggin , =?utf-8?b?RnLDqWTDqXJpYyBCYXJyYXQ=?= , Daniel Henrique Barboza , David Gibson , Harsh Prateek Bora , Markus Armbruster , Marcelo Tosatti , =?utf-8?q?Alex_Benn=C3=A9e?= , Peter Maydell Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, qemu-ppc@nongnu.org, qemu-arm@nongnu.org, Zhenyu Wang , Dapeng Mi , Yongwei Ma , Zhao Liu Subject: [RFC v2 11/15] hw/core: Support topology tree in none machine for compatibility Date: Thu, 19 Sep 2024 09:55:29 +0800 Message-Id: <20240919015533.766754-12-zhao1.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240919015533.766754-1-zhao1.liu@intel.com> References: <20240919015533.766754-1-zhao1.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 None machine accepts any CPU types, even some CPUs may have the bus_type. To address this, set topo_tree_supported as true for none machine, then none machine will have a CPU slot with CPU bus to collect any topology device with bus_type specified. And since arch_id_topo_level is not set, the topology devices will be directly inserted under the CPU slot without being organized into a tree structure. For the CPUs without bus_type, topo_tree_supported will not affect them. Signed-off-by: Zhao Liu --- hw/core/null-machine.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/core/null-machine.c b/hw/core/null-machine.c index f586a4bef543..101649f3e8c1 100644 --- a/hw/core/null-machine.c +++ b/hw/core/null-machine.c @@ -54,6 +54,11 @@ static void machine_none_machine_init(MachineClass *mc) mc->no_floppy = 1; mc->no_cdrom = 1; mc->no_sdcard = 1; + /* + * For compatibility with arches and CPUs that already + * support topology tree. + */ + mc->smp_props.topo_tree_supported = true; } DEFINE_MACHINE("none", machine_none_machine_init) From patchwork Thu Sep 19 01:55:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhao Liu X-Patchwork-Id: 13807297 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9E75E12E48 for ; Thu, 19 Sep 2024 01:41:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710066; cv=none; b=ratvZkpVhHVBd4uJurWHTMHy8YnFl3WxqJttyWjvi2cklL2Wh5w1aI0YJ9/fSsIx0iC/nm3nDSeW2G703InNJ6feMKOyb2Wv+5j8X7PpGL2yEG47lDm1czsZeqy+xd5PqBSzxTs5cNN+HnWI/2w/d1use1UlwGe32FOENzDR8LI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710066; c=relaxed/simple; bh=wx8cdMXy87jbp3iDhkGcf2ZrKApAXiC+ip9Awek7e04=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=XgDipk2aSaw2nDn3BdPeGF2kjeQJp85CazAAjrvii6VUv6kElsoLFreBOLvsOKy+28sWlxb78DEEjtvKYrrcvDmyjcb8aVFIsTr0VYhjJIJXSAFnDMtNylth25yWBcgQdj8yMeygdJarDtOq5tSSMZJXgPoxWbbmoIll402KTT4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=gVt8drsX; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="gVt8drsX" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1726710065; x=1758246065; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=wx8cdMXy87jbp3iDhkGcf2ZrKApAXiC+ip9Awek7e04=; b=gVt8drsXqmRkbo6+GQea83+KmLahDIpqehv2HzPvc19pppwlKKhbO+yZ bTuaR0npy3D5FzUh4cFwO49OIsiDBZKKBXNhXEBfSgzDgTpaWaT/9WtGO Ug+DqlgG/E05M1VlJj/VGzoomR9QN0XzJZDx58EOaZI7Cv9gI/G96bxXg qRyn5VNz+a7ep0MjLY9+IDJAyCWvYEGXh0M5sWkqB+789lkT2zSQcbB2W 5GwtSkkSMGNtIU7aZpBRXeEHlfrU5IWhXZ53n8EVwQsB6TV11aKw4Cemc E1YmRBkqMWtY7WFft2kaxkhGlJQwdJOC/SRQUXp9rLcQjxESbrj7O3O94 A==; X-CSE-ConnectionGUID: JOgoJLSVRMGpLvrTX8mnPw== X-CSE-MsgGUID: G4jZ0ZriTy+2jxaj/cSfdg== X-IronPort-AV: E=McAfee;i="6700,10204,11199"; a="25798067" X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="25798067" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2024 18:41:04 -0700 X-CSE-ConnectionGUID: /9zU/3CdSJut5CeCqd6www== X-CSE-MsgGUID: 6BJoj00JRPy92lBgaz2/QQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="70058955" Received: from liuzhao-optiplex-7080.sh.intel.com ([10.239.160.36]) by orviesa006.jf.intel.com with ESMTP; 18 Sep 2024 18:40:58 -0700 From: Zhao Liu To: =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , Igor Mammedov , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , "Michael S . Tsirkin" , Paolo Bonzini , Richard Henderson , =?utf-8?q?C=C3=A9dric_Le_?= =?utf-8?q?Goater?= , Nicholas Piggin , =?utf-8?b?RnLDqWTDqXJpYyBCYXJyYXQ=?= , Daniel Henrique Barboza , David Gibson , Harsh Prateek Bora , Markus Armbruster , Marcelo Tosatti , =?utf-8?q?Alex_Benn=C3=A9e?= , Peter Maydell Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, qemu-ppc@nongnu.org, qemu-arm@nongnu.org, Zhenyu Wang , Dapeng Mi , Yongwei Ma , Zhao Liu Subject: [RFC v2 12/15] hw/i386: Allow i386 to create new CPUs in topology tree Date: Thu, 19 Sep 2024 09:55:30 +0800 Message-Id: <20240919015533.766754-13-zhao1.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240919015533.766754-1-zhao1.liu@intel.com> References: <20240919015533.766754-1-zhao1.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 For x86, CPU's apic ID represent its topology path and is the combination of topology sub IDs in each leavl. When x86 machine creates CPUs, to insert the CPU into topology tree, use apic ID to get topology sub IDs. Then search the topology tree for the corresponding parent topology device and insert the CPU into the CPU bus of the parent device. Signed-off-by: Zhao Liu --- hw/i386/x86-common.c | 101 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 97 insertions(+), 4 deletions(-) diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c index b21d2ab97349..a7f082b0a90b 100644 --- a/hw/i386/x86-common.c +++ b/hw/i386/x86-common.c @@ -53,14 +53,107 @@ /* Physical Address of PVH entry point read from kernel ELF NOTE */ static size_t pvh_start_addr; -static void x86_cpu_new(X86MachineState *x86ms, int64_t apic_id, Error **errp) +static int x86_cpu_get_topo_id(const X86CPUTopoIDs *topo_ids, + CpuTopologyLevel level) { - Object *cpu = object_new(MACHINE(x86ms)->cpu_type); + switch (level) { + case CPU_TOPOLOGY_LEVEL_THREAD: + return topo_ids->smt_id; + case CPU_TOPOLOGY_LEVEL_CORE: + return topo_ids->core_id; + case CPU_TOPOLOGY_LEVEL_MODULE: + return topo_ids->module_id; + case CPU_TOPOLOGY_LEVEL_DIE: + return topo_ids->die_id; + case CPU_TOPOLOGY_LEVEL_SOCKET: + return topo_ids->pkg_id; + default: + g_assert_not_reached(); + } + + return -1; +} + +typedef struct SearchCoreCb { + const X86CPUTopoIDs *topo_ids; + const CPUTopoState *parent; +} SearchCoreCb; + +static int x86_search_topo_parent(DeviceState *dev, void *opaque) +{ + CPUTopoState *topo = CPU_TOPO(dev); + CpuTopologyLevel level = GET_CPU_TOPO_LEVEL(topo); + SearchCoreCb *cb = opaque; + int topo_id, index; + + topo_id = x86_cpu_get_topo_id(cb->topo_ids, level); + index = cpu_topo_get_index(topo); + + if (topo_id < 0) { + error_report("Invalid %s-id: %d", + CpuTopologyLevel_str(level), topo_id); + error_printf("Try to set the %s-id in [0-%d].\n", + CpuTopologyLevel_str(level), + cpu_topo_get_instances_num(topo) - 1); + return TOPO_FOREACH_ERR; + } + + if (topo_id == index) { + if (level == CPU_TOPOLOGY_LEVEL_CORE) { + cb->parent = topo; + /* The error result could exit directly. */ + return TOPO_FOREACH_ERR; + } + return TOPO_FOREACH_CONTINUE; + } + return TOPO_FOREACH_END; +} + +static BusState *x86_find_topo_bus(MachineState *ms, X86CPUTopoIDs *topo_ids) +{ + SearchCoreCb cb; + + cb.topo_ids = topo_ids; + cb.parent = NULL; + qbus_walk_children(BUS(&ms->topo->bus), x86_search_topo_parent, + NULL, NULL, NULL, &cb); + + if (!cb.parent) { + return NULL; + } + + return BUS(cb.parent->bus); +} + +static void x86_cpu_new(X86MachineState *x86ms, int index, + int64_t apic_id, Error **errp) +{ + MachineState *ms = MACHINE(x86ms); + MachineClass *mc = MACHINE_GET_CLASS(ms); + Object *cpu = object_new(ms->cpu_type); + DeviceState *dev = DEVICE(cpu); + BusState *bus = NULL; + + /* + * Once x86 machine supports topo_tree_supported, x86 CPU would + * also have bus_type. + */ + if (mc->smp_props.topo_tree_supported) { + X86CPUTopoIDs topo_ids; + X86CPUTopoInfo topo_info; + + init_topo_info(&topo_info, x86ms); + x86_topo_ids_from_apicid(apic_id, &topo_info, &topo_ids); + bus = x86_find_topo_bus(ms, &topo_ids); + + /* Only with dev->id, CPU can be inserted into topology tree. */ + dev->id = g_strdup_printf("%s[%d]", ms->cpu_type, index); + } if (!object_property_set_uint(cpu, "apic-id", apic_id, errp)) { goto out; } - qdev_realize(DEVICE(cpu), NULL, errp); + qdev_realize(dev, bus, errp); out: object_unref(cpu); @@ -111,7 +204,7 @@ void x86_cpus_init(X86MachineState *x86ms, int default_cpu_version) possible_cpus = mc->possible_cpu_arch_ids(ms); for (i = 0; i < ms->smp.cpus; i++) { - x86_cpu_new(x86ms, possible_cpus->cpus[i].arch_id, &error_fatal); + x86_cpu_new(x86ms, i, possible_cpus->cpus[i].arch_id, &error_fatal); } } From patchwork Thu Sep 19 01:55:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhao Liu X-Patchwork-Id: 13807298 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 36FD81DFD1 for ; Thu, 19 Sep 2024 01:41:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710072; cv=none; b=o0wredrxrCc3BCiXqgQqDEjy+wtstl6XJVoqfVawllOIZfWJWSz1GxbXHZLzMeBwl+n6TNUz6ztz3prqYAZUfFRa80Q9p+VJHsByrFB1zFxcAReePQDC4v3Ua4SOgoV1sUycBnvyKSl0BnshXg5hmCXVd6zIUkFmJ9DbK9YhPfU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710072; c=relaxed/simple; bh=XSgqmMkHJizZc4N1izUEEkjh5Xf8Kwzu+lddFS/lH2U=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=IaZdO4dV+2RNvYqfhVAPvqsQz5DgCtQfnFKBATR67O/Nxyx6F/KKr9iaQ/CpWvCpexOGbf1XAAeH+3gM/OVgsqhGPZWh6N1LdG+VpGta00aheRY+s1DKy90e3XTCqBW0UXo99Y6jw2/Pf/rcoG0F7pBEm0eOAo1XCKLpTTlh0vU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=IO/vTmAn; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="IO/vTmAn" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1726710071; x=1758246071; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=XSgqmMkHJizZc4N1izUEEkjh5Xf8Kwzu+lddFS/lH2U=; b=IO/vTmAn/gDiz9mEpXuzBTOoetWarwaCDm7K1G0o5T8ALYsKTsOyjInr CWIf9dryMdzKbvPjniGmR6nFJhBN20/Q/5YCoKoMLzXHGN5Ia4decVVza mh+bPtNoebl4RUNYkAG+raT5r21mSisnNNhchRwCKgrkMG3wv9gkXerVQ sMZMTbqieMjcdrWQ/EKhtjVnbi2SfUf9+MGeU4/bFQoOJHA0ULdBY+gM0 pbxuyvgnAI6mBbHeWoegRSrVjJ6ma/+qWkU8C2ykvlVt3lBISQQ01Fwmq xz0Gqsz8Iy7g1ZmrS8FhvEyDAW7ezJ/PWjdERRmulmmX11Ujc6rufayUn A==; X-CSE-ConnectionGUID: cfjMxhugTcarzIdUSwCXQw== X-CSE-MsgGUID: XEQD3gDDQ6qD1RSq3G6Puw== X-IronPort-AV: E=McAfee;i="6700,10204,11199"; a="25798074" X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="25798074" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2024 18:41:11 -0700 X-CSE-ConnectionGUID: S1ZKAEwsS6+xTFUMRz/CIg== X-CSE-MsgGUID: 8BpNMzORS9K4jxsU5BqXGQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="70058972" Received: from liuzhao-optiplex-7080.sh.intel.com ([10.239.160.36]) by orviesa006.jf.intel.com with ESMTP; 18 Sep 2024 18:41:05 -0700 From: Zhao Liu To: =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , Igor Mammedov , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , "Michael S . Tsirkin" , Paolo Bonzini , Richard Henderson , =?utf-8?q?C=C3=A9dric_Le_?= =?utf-8?q?Goater?= , Nicholas Piggin , =?utf-8?b?RnLDqWTDqXJpYyBCYXJyYXQ=?= , Daniel Henrique Barboza , David Gibson , Harsh Prateek Bora , Markus Armbruster , Marcelo Tosatti , =?utf-8?q?Alex_Benn=C3=A9e?= , Peter Maydell Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, qemu-ppc@nongnu.org, qemu-arm@nongnu.org, Zhenyu Wang , Dapeng Mi , Yongwei Ma , Zhao Liu Subject: [RFC v2 13/15] system/qdev-monitor: Introduce bus-finder interface for compatibility with bus-less plug behavior Date: Thu, 19 Sep 2024 09:55:31 +0800 Message-Id: <20240919015533.766754-14-zhao1.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240919015533.766754-1-zhao1.liu@intel.com> References: <20240919015533.766754-1-zhao1.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Currently, cpu and core is located by topology IDs when plugging. On a topology tree, each topology device will has a CPU bus. Once cpu and core specify the bus_type, it's necessary to find accurate buses for them based on topology IDs (if bus=* is not set in -device). Therefore, we need a way to use traditional topology IDs for locating specific bus in the topology tree. This is the bus-finder interface. With bus-finder, qdev-monitor can locate the bus based on device properties when "bus=*" is not specified. Signed-off-by: Zhao Liu --- MAINTAINERS | 2 ++ include/monitor/bus-finder.h | 41 ++++++++++++++++++++++++++++++++ system/bus-finder.c | 46 ++++++++++++++++++++++++++++++++++++ system/meson.build | 1 + system/qdev-monitor.c | 41 ++++++++++++++++++++++++++++---- 5 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 include/monitor/bus-finder.h create mode 100644 system/bus-finder.c diff --git a/MAINTAINERS b/MAINTAINERS index 03c1a13de074..4608c3c6db8c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3281,12 +3281,14 @@ F: hw/core/qdev* F: hw/core/bus.c F: hw/core/sysbus.c F: include/hw/qdev* +F: include/monitor/bus-finder.h F: include/monitor/qdev.h F: include/qom/ F: qapi/qom.json F: qapi/qdev.json F: scripts/coccinelle/qom-parent-type.cocci F: scripts/qom-cast-macro-clean-cocci-gen.py +F: system/bus-finder.c F: system/qdev-monitor.c F: stubs/qdev.c F: qom/ diff --git a/include/monitor/bus-finder.h b/include/monitor/bus-finder.h new file mode 100644 index 000000000000..56f1e4791b66 --- /dev/null +++ b/include/monitor/bus-finder.h @@ -0,0 +1,41 @@ +/* + * Bus finder interface header + * + * Copyright (C) 2024 Intel Corporation. + * + * Author: Zhao Liu + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + */ + +#ifndef BUS_FINDER_H +#define BUS_FINDER_H + +#include "hw/qdev-core.h" +#include "qom/object.h" + +#define TYPE_BUS_FINDER "bus-finder" + +typedef struct BusFinderClass BusFinderClass; +DECLARE_CLASS_CHECKERS(BusFinderClass, BUS_FINDER, TYPE_BUS_FINDER) +#define BUS_FINDER(obj) INTERFACE_CHECK(BusFinder, (obj), TYPE_BUS_FINDER) + +typedef struct BusFinder BusFinder; + +/** + * BusFinderClass: + * @find_bus: Method to find bus. + */ +struct BusFinderClass { + /* */ + InterfaceClass parent_class; + + /* */ + BusState *(*find_bus)(DeviceState *dev); +}; + +bool is_bus_finder_type(DeviceClass *dc); +BusState *bus_finder_select_bus(DeviceState *dev); + +#endif /* BUS_FINDER_H */ diff --git a/system/bus-finder.c b/system/bus-finder.c new file mode 100644 index 000000000000..097291a96bf3 --- /dev/null +++ b/system/bus-finder.c @@ -0,0 +1,46 @@ +/* + * Bus finder interface + * + * Copyright (C) 2024 Intel Corporation. + * + * Author: Zhao Liu + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" + +#include "hw/qdev-core.h" +#include "monitor/bus-finder.h" +#include "qom/object.h" + +bool is_bus_finder_type(DeviceClass *dc) +{ + return !!object_class_dynamic_cast(OBJECT_CLASS(dc), TYPE_BUS_FINDER); +} + +BusState *bus_finder_select_bus(DeviceState *dev) +{ + BusFinder *bf = BUS_FINDER(dev); + BusFinderClass *bfc = BUS_FINDER_GET_CLASS(bf); + + if (bfc->find_bus) { + return bfc->find_bus(dev); + } + + return NULL; +} + +static const TypeInfo bus_finder_interface_info = { + .name = TYPE_BUS_FINDER, + .parent = TYPE_INTERFACE, + .class_size = sizeof(BusFinderClass), +}; + +static void bus_finder_register_types(void) +{ + type_register_static(&bus_finder_interface_info); +} + +type_init(bus_finder_register_types) diff --git a/system/meson.build b/system/meson.build index a296270cb005..090716b81abd 100644 --- a/system/meson.build +++ b/system/meson.build @@ -9,6 +9,7 @@ specific_ss.add(when: 'CONFIG_SYSTEM_ONLY', if_true: [files( system_ss.add(files( 'balloon.c', 'bootdevice.c', + 'bus-finder.c', 'cpus.c', 'cpu-throttle.c', 'cpu-timers.c', diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c index 44994ea0e160..457dfd05115e 100644 --- a/system/qdev-monitor.c +++ b/system/qdev-monitor.c @@ -19,6 +19,7 @@ #include "qemu/osdep.h" #include "hw/sysbus.h" +#include "monitor/bus-finder.h" #include "monitor/hmp.h" #include "monitor/monitor.h" #include "monitor/qdev.h" @@ -589,6 +590,16 @@ static BusState *qbus_find(const char *path, Error **errp) return bus; } +static inline bool qdev_post_find_bus(DeviceClass *dc) +{ + return is_bus_finder_type(dc); +} + +static inline BusState *qdev_find_bus_post_device(DeviceState *dev) +{ + return bus_finder_select_bus(dev); +} + /* Takes ownership of @id, will be freed when deleting the device */ const char *qdev_set_id(DeviceState *dev, char *id, Error **errp) { @@ -630,6 +641,7 @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts, char *id; DeviceState *dev = NULL; BusState *bus = NULL; + bool post_bus = false; driver = qdict_get_try_str(opts, "driver"); if (!driver) { @@ -656,11 +668,15 @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts, return NULL; } } else if (dc->bus_type != NULL) { - bus = qbus_find_recursive(sysbus_get_default(), NULL, dc->bus_type); - if (!bus || qbus_is_full(bus)) { - error_setg(errp, "No '%s' bus found for device '%s'", - dc->bus_type, driver); - return NULL; + if (qdev_post_find_bus(dc)) { + post_bus = true; /* Wait for bus-finder to arbitrate. */ + } else { + bus = qbus_find_recursive(sysbus_get_default(), NULL, dc->bus_type); + if (!bus || qbus_is_full(bus)) { + error_setg(errp, "No '%s' bus found for device '%s'", + dc->bus_type, driver); + return NULL; + } } } @@ -722,6 +738,21 @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts, goto err_del_dev; } + if (post_bus) { + bus = qdev_find_bus_post_device(dev); + if (!bus) { + error_setg(errp, "No proper '%s' bus found for device '%s'", + dc->bus_type, driver); + goto err_del_dev; + } + + if (phase_check(PHASE_MACHINE_READY) && !qbus_is_hotpluggable(bus)) { + error_setg(errp, "Bus '%s' does not support hotplugging", + bus->name); + goto err_del_dev; + } + } + if (!qdev_realize(dev, bus, errp)) { goto err_del_dev; } From patchwork Thu Sep 19 01:55:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhao Liu X-Patchwork-Id: 13807299 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9EAEC1DFD1 for ; Thu, 19 Sep 2024 01:41:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710079; cv=none; b=iPNtsPnlGtmdYn0ivFDL+XtuxuRUa9NlyPvTL2Rx5RMKhvHajt/B3qLB87IO3yX9DR65Kuvkjcdrvi7I/p2wD2Pt7Vygt11bh46sGeOJgHxnAg7DYgfJ4aW9RC3jzSxqQuDfrB6vkV+hwF6DWLkz+V9JFMMP/yaTHM2+kJV4ie0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710079; c=relaxed/simple; bh=e8uNe2XyBy//pc+Jdrf2eDU6ylT8TdayHazakj6xvUI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=gZ+Mv0UhXFFG5UIOgI4msitEQgJsmve014UD0kebNJnW5pZOgIzdjqiXRD2X37oBaTOinyGfMuIFwLji7Sz4GGP80q6zkyH9aFUuNBJI+A9HGtKQ0jlOYq7snK5GA5I3JflEpNnCTJYiBHN/2/KUFUd8NZeZkRxU3vFrIYUVmKk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=cFftb/0n; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="cFftb/0n" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1726710078; x=1758246078; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=e8uNe2XyBy//pc+Jdrf2eDU6ylT8TdayHazakj6xvUI=; b=cFftb/0ne249EziHhOfrZL8RwPwQl5BZ9AxyZVgkHbJ0MAprWHKIDZtQ AivRqW3QAHU9pC2x2zaob8zFOsOeAHxLfl9msqFPTApKjHv+A+37ZZK7J Hl9xG6SxWbBRhaYLX0jUErrG5EJzWd02zjinpe5o3XjWbcUKs3Eg19mJu mjXN49Gk6zb9+gw1FHDNPfl3oO2QFf65D4yVH7lK1abI8u+AEuGfvBadx COo28Rr/IxUExx+JqXMuntRjjif6b5uGFrogm6u5NDi7DaKN1oZNfMOeP vCzXY0tWXKdkP9pvFdpyhnP+TAMKIh9vQqAgpUJzwbZ/nGXsXSupGXKS+ w==; X-CSE-ConnectionGUID: k95Mw5zATd6AsJP2JBduAQ== X-CSE-MsgGUID: 3YeYXqsJT72SIUq7Ez5+tg== X-IronPort-AV: E=McAfee;i="6700,10204,11199"; a="25798104" X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="25798104" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2024 18:41:17 -0700 X-CSE-ConnectionGUID: FdACOWMXSMOp94R+MXOELA== X-CSE-MsgGUID: Wk9cMGQHQpOW5if6nrEZ5A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="70058986" Received: from liuzhao-optiplex-7080.sh.intel.com ([10.239.160.36]) by orviesa006.jf.intel.com with ESMTP; 18 Sep 2024 18:41:11 -0700 From: Zhao Liu To: =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , Igor Mammedov , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , "Michael S . Tsirkin" , Paolo Bonzini , Richard Henderson , =?utf-8?q?C=C3=A9dric_Le_?= =?utf-8?q?Goater?= , Nicholas Piggin , =?utf-8?b?RnLDqWTDqXJpYyBCYXJyYXQ=?= , Daniel Henrique Barboza , David Gibson , Harsh Prateek Bora , Markus Armbruster , Marcelo Tosatti , =?utf-8?q?Alex_Benn=C3=A9e?= , Peter Maydell Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, qemu-ppc@nongnu.org, qemu-arm@nongnu.org, Zhenyu Wang , Dapeng Mi , Yongwei Ma , Zhao Liu Subject: [RFC v2 14/15] i386/cpu: Support CPU plugged in topology tree via bus-finder Date: Thu, 19 Sep 2024 09:55:32 +0800 Message-Id: <20240919015533.766754-15-zhao1.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240919015533.766754-1-zhao1.liu@intel.com> References: <20240919015533.766754-1-zhao1.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Use topology sub IDs or APIC ID to locate parent topology device and bus. This process naturally verifies the correctness of topology-related IDs, making it possible to drop the existing topology ID sanity checks once x86 machine supports topology tree. Signed-off-by: Zhao Liu --- hw/i386/x86-common.c | 99 ++++++++++++++++++++++++++++++++++--------- include/hw/i386/x86.h | 2 + target/i386/cpu.c | 11 +++++ 3 files changed, 91 insertions(+), 21 deletions(-) diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c index a7f082b0a90b..d837aadc9dea 100644 --- a/hw/i386/x86-common.c +++ b/hw/i386/x86-common.c @@ -208,6 +208,65 @@ void x86_cpus_init(X86MachineState *x86ms, int default_cpu_version) } } +static void x86_fixup_topo_ids(MachineState *ms, X86CPU *cpu) +{ + /* + * die-id was optional in QEMU 4.0 and older, so keep it optional + * if there's only one die per socket. + */ + if (cpu->module_id < 0 && ms->smp.modules == 1) { + cpu->module_id = 0; + } + + /* + * module-id was optional in QEMU 9.0 and older, so keep it optional + * if there's only one module per die. + */ + if (cpu->die_id < 0 && ms->smp.dies == 1) { + cpu->die_id = 0; + } +} + +BusState *x86_cpu_get_parent_bus(DeviceState *dev) +{ + MachineState *ms = MACHINE(qdev_get_machine()); + X86MachineState *x86ms = X86_MACHINE(ms); + X86CPU *cpu = X86_CPU(dev); + X86CPUTopoIDs topo_ids; + X86CPUTopoInfo topo_info; + BusState *bus; + + x86_fixup_topo_ids(ms, cpu); + init_topo_info(&topo_info, x86ms); + + if (cpu->apic_id == UNASSIGNED_APIC_ID) { + /* TODO: Make the thread_id and bus index of CPU the same. */ + topo_ids.smt_id = cpu->thread_id; + topo_ids.core_id = cpu->core_id; + topo_ids.module_id = cpu->module_id; + topo_ids.die_id = cpu->die_id; + topo_ids.pkg_id = cpu->socket_id; + } else { + x86_topo_ids_from_apicid(cpu->apic_id, &topo_info, &topo_ids); + } + + bus = x86_find_topo_bus(ms, &topo_ids); + + /* + * If APIC ID is not set, + * set it based on socket/die/module/core/thread properties. + * + * The children walking result proves topo ids are valid. + * Though module and die are optional, topology tree will create + * at least 1 instance by default if the machine supports. + */ + if (bus && cpu->apic_id == UNASSIGNED_APIC_ID) { + cpu->apic_id = x86_apicid_from_topo_ids(&topo_info, &topo_ids); + } + + return bus; +} + void x86_rtc_set_cpus_count(ISADevice *s, uint16_t cpus_count) { MC146818RtcState *rtc = MC146818_RTC(s); @@ -340,6 +399,7 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev, X86CPU *cpu = X86_CPU(dev); CPUX86State *env = &cpu->env; MachineState *ms = MACHINE(hotplug_dev); + MachineClass *mc = MACHINE_GET_CLASS(ms); X86MachineState *x86ms = X86_MACHINE(hotplug_dev); unsigned int smp_cores = ms->smp.cores; unsigned int smp_threads = ms->smp.threads; @@ -374,26 +434,9 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev, set_bit(CPU_TOPOLOGY_LEVEL_DIE, env->avail_cpu_topo); } - /* - * If APIC ID is not set, - * set it based on socket/die/module/core/thread properties. - */ - if (cpu->apic_id == UNASSIGNED_APIC_ID) { - /* - * die-id was optional in QEMU 4.0 and older, so keep it optional - * if there's only one die per socket. - */ - if (cpu->die_id < 0 && ms->smp.dies == 1) { - cpu->die_id = 0; - } - - /* - * module-id was optional in QEMU 9.0 and older, so keep it optional - * if there's only one module per die. - */ - if (cpu->module_id < 0 && ms->smp.modules == 1) { - cpu->module_id = 0; - } + if (cpu->apic_id == UNASSIGNED_APIC_ID && + !mc->smp_props.topo_tree_supported) { + x86_fixup_topo_ids(ms, cpu); if (cpu->socket_id < 0) { error_setg(errp, "CPU socket-id is not set"); @@ -409,7 +452,6 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev, } else if (cpu->die_id > ms->smp.dies - 1) { error_setg(errp, "Invalid CPU die-id: %u must be in range 0:%u", cpu->die_id, ms->smp.dies - 1); - return; } if (cpu->module_id < 0) { error_setg(errp, "CPU module-id is not set"); @@ -442,6 +484,21 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev, topo_ids.core_id = cpu->core_id; topo_ids.smt_id = cpu->thread_id; cpu->apic_id = x86_apicid_from_topo_ids(&topo_info, &topo_ids); + } else if (cpu->apic_id == UNASSIGNED_APIC_ID && + mc->smp_props.topo_tree_supported) { + /* + * For this case, CPU is added by specifying the bus. Under the + * topology tree, specifying only the bus should be feasible, but + * the topology represented by the bus, topo ids, or apic id must + * be consistent. + * + * To simplify, the case with only the bus specified is not supported + * at this time. + */ + if (x86_cpu_get_parent_bus(dev) != dev->parent_bus) { + error_setg(errp, "Invalid CPU topology ids"); + return; + } } cpu_slot = x86_find_cpu_slot(MACHINE(x86ms), cpu->apic_id, &idx); diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h index d43cb3908e65..2a62b4b8d08c 100644 --- a/include/hw/i386/x86.h +++ b/include/hw/i386/x86.h @@ -138,6 +138,8 @@ void x86_load_linux(X86MachineState *x86ms, bool x86_machine_is_smm_enabled(const X86MachineState *x86ms); bool x86_machine_is_acpi_enabled(const X86MachineState *x86ms); +BusState *x86_cpu_get_parent_bus(DeviceState *dev); + /* Global System Interrupts */ #define ACPI_BUILD_PCI_IRQS ((1<<5) | (1<<9) | (1<<10) | (1<<11)) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 6d9f7dc0872a..90221ceb7313 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -35,12 +35,14 @@ #include "standard-headers/asm-x86/kvm_para.h" #include "hw/qdev-properties.h" #include "hw/i386/topology.h" +#include "monitor/bus-finder.h" #ifndef CONFIG_USER_ONLY #include "sysemu/reset.h" #include "qapi/qapi-commands-machine-target.h" #include "exec/address-spaces.h" #include "hw/boards.h" #include "hw/i386/sgx-epc.h" +#include "hw/i386/x86.h" #endif #include "disas/capstone.h" @@ -8468,6 +8470,11 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) dc->user_creatable = true; +#ifndef CONFIG_USER_ONLY + BusFinderClass *bfc = BUS_FINDER_CLASS(oc); + bfc->find_bus = x86_cpu_get_parent_bus; +#endif + object_class_property_add(oc, "family", "int", x86_cpuid_version_get_family, x86_cpuid_version_set_family, NULL, NULL); @@ -8520,6 +8527,10 @@ static const TypeInfo x86_cpu_type_info = { .abstract = true, .class_size = sizeof(X86CPUClass), .class_init = x86_cpu_common_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_BUS_FINDER }, + { } + } }; /* "base" CPU model, used by query-cpu-model-expansion */ From patchwork Thu Sep 19 01:55:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhao Liu X-Patchwork-Id: 13807300 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4460C1DA4C for ; Thu, 19 Sep 2024 01:41:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710086; cv=none; b=FYE3HlFa4y5jQh+oTSRTB93z09XO0hpWiIXMrz0VFxD9QdQ5pM4/UDs8hiM7Q6/xLvU5WhT0RCIODhbHyOloMWycoeZjDxbhFKf1E0ARDAR+HPG0bnJmTarmaFDTiGkFOHxe7h88lR6TOKB9BmjKB8UC7cajVYxXvL7EZreemOI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726710086; c=relaxed/simple; bh=R/RyqBpSFLfGANKmP2zWrU5SVWm2/qn58wOc7/+Iwms=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=llMwzbrhgcGpTHHtygrys4OrQtdjGNNILhi9/IMtWsHABRI2HhQHoqoiw5h1aGgPPa/hHq6JVjXtZfVLzNvOTwZv3j9AM7MSmvnYZX1uHIUdqGsItyWD7xfBXY9kqp5ZF1saP5hYT/YiwsqydPAzaGsJ4cEARA0FtLvWRRflrho= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=nalXFsSb; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="nalXFsSb" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1726710085; x=1758246085; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=R/RyqBpSFLfGANKmP2zWrU5SVWm2/qn58wOc7/+Iwms=; b=nalXFsSbHip+jzCewXtj5JAy9egUpwezkWn/9k7VhKHWA8/acQQaNb/Y /dzR+k02dgl22aZA4VrHLH1l1jzN3tfUzlz18cnxcxmmHwpYhalnzeJmK lN71DsS8P9dSNlKS16IQrgDeQtudofYoQTG8Axx/S+Cqt7/UgevGCNd5d eS6wuKMQUxpdl7cXRDRdZUf5piC5Whl1qFCekt5iTT4fg0RwGPQX/9GTM tGTjtuMGFjwEJ/m3mWhMsAS5wYo6rknvTpuQlKyom1TLfIr3dNzX8C4Tx G1SSMF1IfHOxddiuQwRh/3Lp1YDvjpeFRO52evhmjaS1vKwQL2Bn81HQP A==; X-CSE-ConnectionGUID: 4Jt5BYqGTwm3wmsDvfvkOw== X-CSE-MsgGUID: DaD6967QRZCpiiLmNpJalA== X-IronPort-AV: E=McAfee;i="6700,10204,11199"; a="25798132" X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="25798132" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Sep 2024 18:41:24 -0700 X-CSE-ConnectionGUID: szNCjQVpTIWjD4Z0T6eu4A== X-CSE-MsgGUID: 4gQNKxRUT0GdnsrB0gseZg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,240,1719903600"; d="scan'208";a="70059004" Received: from liuzhao-optiplex-7080.sh.intel.com ([10.239.160.36]) by orviesa006.jf.intel.com with ESMTP; 18 Sep 2024 18:41:18 -0700 From: Zhao Liu To: =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , Igor Mammedov , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , "Michael S . Tsirkin" , Paolo Bonzini , Richard Henderson , =?utf-8?q?C=C3=A9dric_Le_?= =?utf-8?q?Goater?= , Nicholas Piggin , =?utf-8?b?RnLDqWTDqXJpYyBCYXJyYXQ=?= , Daniel Henrique Barboza , David Gibson , Harsh Prateek Bora , Markus Armbruster , Marcelo Tosatti , =?utf-8?q?Alex_Benn=C3=A9e?= , Peter Maydell Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, qemu-ppc@nongnu.org, qemu-arm@nongnu.org, Zhenyu Wang , Dapeng Mi , Yongwei Ma , Zhao Liu Subject: [RFC v2 15/15] i386: Support topology device tree Date: Thu, 19 Sep 2024 09:55:33 +0800 Message-Id: <20240919015533.766754-16-zhao1.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240919015533.766754-1-zhao1.liu@intel.com> References: <20240919015533.766754-1-zhao1.liu@intel.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Support complete QOM CPu topology tree for x86 machine, and specify bus_type for x86 CPU so that all x86 CPUs will be added in the topology tree. Since the CPU slot make the machine as the hotplug handler for all topology devices, hotplug related hooks may used to handle other topology devices besides the CPU. Thus, make microvm not assume that the device is only a CPU when implementing the relevant hooks. Additionally, drop code paths that are not needed by the topology tree implementation. Signed-off-by: Zhao Liu --- hw/i386/microvm.c | 13 +++++--- hw/i386/x86-common.c | 78 +++++--------------------------------------- hw/i386/x86.c | 2 ++ target/i386/cpu.c | 2 ++ 4 files changed, 21 insertions(+), 74 deletions(-) diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c index 40edcee7af29..49a897db50fc 100644 --- a/hw/i386/microvm.c +++ b/hw/i386/microvm.c @@ -417,16 +417,21 @@ static void microvm_fix_kernel_cmdline(MachineState *machine) static void microvm_device_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - X86CPU *cpu = X86_CPU(dev); + if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { + X86CPU *cpu; + cpu = X86_CPU(dev); - cpu->host_phys_bits = true; /* need reliable phys-bits */ - x86_cpu_pre_plug(hotplug_dev, dev, errp); + cpu->host_phys_bits = true; /* need reliable phys-bits */ + x86_cpu_pre_plug(hotplug_dev, dev, errp); + } } static void microvm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - x86_cpu_plug(hotplug_dev, dev, errp); + if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { + x86_cpu_plug(hotplug_dev, dev, errp); + } } static void microvm_device_unplug_request_cb(HotplugHandler *hotplug_dev, diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c index d837aadc9dea..75d4b2f3d43a 100644 --- a/hw/i386/x86-common.c +++ b/hw/i386/x86-common.c @@ -129,26 +129,18 @@ static void x86_cpu_new(X86MachineState *x86ms, int index, int64_t apic_id, Error **errp) { MachineState *ms = MACHINE(x86ms); - MachineClass *mc = MACHINE_GET_CLASS(ms); Object *cpu = object_new(ms->cpu_type); DeviceState *dev = DEVICE(cpu); BusState *bus = NULL; + X86CPUTopoIDs topo_ids; + X86CPUTopoInfo topo_info; - /* - * Once x86 machine supports topo_tree_supported, x86 CPU would - * also have bus_type. - */ - if (mc->smp_props.topo_tree_supported) { - X86CPUTopoIDs topo_ids; - X86CPUTopoInfo topo_info; - - init_topo_info(&topo_info, x86ms); - x86_topo_ids_from_apicid(apic_id, &topo_info, &topo_ids); - bus = x86_find_topo_bus(ms, &topo_ids); + init_topo_info(&topo_info, x86ms); + x86_topo_ids_from_apicid(apic_id, &topo_info, &topo_ids); + bus = x86_find_topo_bus(ms, &topo_ids); - /* Only with dev->id, CPU can be inserted into topology tree. */ - dev->id = g_strdup_printf("%s[%d]", ms->cpu_type, index); - } + /* Only with dev->id, CPU can be inserted into topology tree. */ + dev->id = g_strdup_printf("%s[%d]", ms->cpu_type, index); if (!object_property_set_uint(cpu, "apic-id", apic_id, errp)) { goto out; @@ -399,10 +391,7 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev, X86CPU *cpu = X86_CPU(dev); CPUX86State *env = &cpu->env; MachineState *ms = MACHINE(hotplug_dev); - MachineClass *mc = MACHINE_GET_CLASS(ms); X86MachineState *x86ms = X86_MACHINE(hotplug_dev); - unsigned int smp_cores = ms->smp.cores; - unsigned int smp_threads = ms->smp.threads; X86CPUTopoInfo topo_info; if (!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) { @@ -434,58 +423,7 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev, set_bit(CPU_TOPOLOGY_LEVEL_DIE, env->avail_cpu_topo); } - if (cpu->apic_id == UNASSIGNED_APIC_ID && - !mc->smp_props.topo_tree_supported) { - x86_fixup_topo_ids(ms, cpu); - - if (cpu->socket_id < 0) { - error_setg(errp, "CPU socket-id is not set"); - return; - } else if (cpu->socket_id > ms->smp.sockets - 1) { - error_setg(errp, "Invalid CPU socket-id: %u must be in range 0:%u", - cpu->socket_id, ms->smp.sockets - 1); - return; - } - if (cpu->die_id < 0) { - error_setg(errp, "CPU die-id is not set"); - return; - } else if (cpu->die_id > ms->smp.dies - 1) { - error_setg(errp, "Invalid CPU die-id: %u must be in range 0:%u", - cpu->die_id, ms->smp.dies - 1); - } - if (cpu->module_id < 0) { - error_setg(errp, "CPU module-id is not set"); - return; - } else if (cpu->module_id > ms->smp.modules - 1) { - error_setg(errp, "Invalid CPU module-id: %u must be in range 0:%u", - cpu->module_id, ms->smp.modules - 1); - return; - } - if (cpu->core_id < 0) { - error_setg(errp, "CPU core-id is not set"); - return; - } else if (cpu->core_id > (smp_cores - 1)) { - error_setg(errp, "Invalid CPU core-id: %u must be in range 0:%u", - cpu->core_id, smp_cores - 1); - return; - } - if (cpu->thread_id < 0) { - error_setg(errp, "CPU thread-id is not set"); - return; - } else if (cpu->thread_id > (smp_threads - 1)) { - error_setg(errp, "Invalid CPU thread-id: %u must be in range 0:%u", - cpu->thread_id, smp_threads - 1); - return; - } - - topo_ids.pkg_id = cpu->socket_id; - topo_ids.die_id = cpu->die_id; - topo_ids.module_id = cpu->module_id; - topo_ids.core_id = cpu->core_id; - topo_ids.smt_id = cpu->thread_id; - cpu->apic_id = x86_apicid_from_topo_ids(&topo_info, &topo_ids); - } else if (cpu->apic_id == UNASSIGNED_APIC_ID && - mc->smp_props.topo_tree_supported) { + if (cpu->apic_id == UNASSIGNED_APIC_ID) { /* * For this case, CPU is added by specifying the bus. Under the * topology tree, specifying only the bus should be feasible, but diff --git a/hw/i386/x86.c b/hw/i386/x86.c index 01fc5e656272..cdf7b81ad0e3 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -381,6 +381,8 @@ static void x86_machine_class_init(ObjectClass *oc, void *data) mc->cpu_index_to_instance_props = x86_cpu_index_to_props; mc->get_default_cpu_node_id = x86_get_default_cpu_node_id; mc->possible_cpu_arch_ids = x86_possible_cpu_arch_ids; + mc->smp_props.arch_id_topo_level = CPU_TOPOLOGY_LEVEL_THREAD; + mc->smp_props.topo_tree_supported = true; mc->kvm_type = x86_kvm_type; x86mc->save_tsc_khz = true; x86mc->fwcfg_dma_enabled = true; diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 90221ceb7313..fb54c2c100a0 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -8473,6 +8473,8 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) #ifndef CONFIG_USER_ONLY BusFinderClass *bfc = BUS_FINDER_CLASS(oc); bfc->find_bus = x86_cpu_get_parent_bus; + + dc->bus_type = TYPE_CPU_BUS; #endif object_class_property_add(oc, "family", "int",